need to properly step this..
This commit is contained in:
+128
-181
@@ -86,14 +86,12 @@ impl SequenceExecutionHelper {
|
||||
pub fn load(
|
||||
&mut self,
|
||||
mode: ModeRaw,
|
||||
request_id: RequestId,
|
||||
sequence_tables: &SequenceModeTables,
|
||||
) -> Result<(), ModeDoesNotExistError> {
|
||||
if !sequence_tables.0.contains_key(&mode) {
|
||||
return Err(ModeDoesNotExistError(mode));
|
||||
}
|
||||
self.target_mode = Some(mode);
|
||||
self.request_id = Some(request_id);
|
||||
self.state = SequenceExecutionHelperState::Busy;
|
||||
self.current_sequence_index = None;
|
||||
Ok(())
|
||||
@@ -204,6 +202,7 @@ impl SequenceExecutionHelper {
|
||||
self.state
|
||||
}
|
||||
|
||||
/*
|
||||
#[inline]
|
||||
pub fn request_id(&self) -> Option<RequestId> {
|
||||
self.request_id
|
||||
@@ -213,6 +212,7 @@ impl SequenceExecutionHelper {
|
||||
pub fn set_request_id(&mut self, request_id: RequestId) {
|
||||
self.request_id = Some(request_id);
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
pub fn awaiting_success_check(&self) -> bool {
|
||||
@@ -351,8 +351,8 @@ pub struct SubsystemCommandingHelper {
|
||||
pub children_mode_store: ModeStoreVec,
|
||||
/// Sequence counter used to generate unique request IDs.
|
||||
sequence_counter: u24,
|
||||
/// Active internal request ID, whic his built from the sequence counter and sequence index.
|
||||
active_internal_request_id: Option<RequestId>,
|
||||
// Active internal request ID, whic his built from the sequence counter and sequence index.
|
||||
//active_internal_request_id: Option<RequestId>,
|
||||
/// The primary data structure to keep the target state information for subsystem
|
||||
/// [modes][ModeRaw]. it specifies the mode each child should have for a certain subsystem mode
|
||||
/// and is relevant for target keeping.
|
||||
@@ -372,7 +372,6 @@ impl Default for SubsystemCommandingHelper {
|
||||
sequence_counter: u24::ZERO,
|
||||
state: Default::default(),
|
||||
children_mode_store: Default::default(),
|
||||
active_internal_request_id: None,
|
||||
target_tables: Default::default(),
|
||||
sequence_tables: Default::default(),
|
||||
seq_exec_helper: Default::default(),
|
||||
@@ -409,7 +408,6 @@ impl SubsystemCommandingHelper {
|
||||
current_mode: 0,
|
||||
state: ModeTreeHelperState::Idle,
|
||||
children_mode_store,
|
||||
active_internal_request_id: None,
|
||||
sequence_counter: u24::ZERO,
|
||||
target_tables,
|
||||
sequence_tables,
|
||||
@@ -425,16 +423,6 @@ impl SubsystemCommandingHelper {
|
||||
self.current_mode
|
||||
}
|
||||
|
||||
/// This returns the internal request ID, which is an internal 24-bit sequence counter
|
||||
/// shifted 8 to the right and then increment with the current sequence commanding
|
||||
/// step. The value can still be retrieved because it might be required for reply verification.
|
||||
///
|
||||
/// The state machine specifies this request ID for all mode commands related to the
|
||||
/// current step of sequence commanding.
|
||||
fn internal_request_id(&self, sequence_index: u8) -> RequestId {
|
||||
(self.sequence_counter.as_u32() << 8) | sequence_index as u32
|
||||
}
|
||||
|
||||
/// Retrieve the fallback mode for the current mode of the subsystem by trying to retrieve
|
||||
/// it from the target table.
|
||||
///
|
||||
@@ -475,12 +463,24 @@ impl SubsystemCommandingHelper {
|
||||
/// - `mode` - The mode to command
|
||||
pub fn start_command_sequence(&mut self, mode: ModeRaw) -> Result<(), StartSequenceError> {
|
||||
self.sequence_counter = self.sequence_counter.wrapping_add(u24::new(1));
|
||||
self.seq_exec_helper
|
||||
.load(mode, self.internal_request_id(0), &self.sequence_tables)?;
|
||||
self.seq_exec_helper.load(mode, &self.sequence_tables)?;
|
||||
self.state = ModeTreeHelperState::ModeCommanding;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// In mode commanding mode, returns the current sequence index.
|
||||
pub fn current_sequence_index(&self) -> Option<u8> {
|
||||
if self.state != ModeTreeHelperState::ModeCommanding {
|
||||
return None;
|
||||
}
|
||||
self.seq_exec_helper.current_sequence_index()
|
||||
}
|
||||
|
||||
/// State machine which can be used to drive the susbystem helper.
|
||||
///
|
||||
/// During mode commanding, it is the responsibility of the user to discard mode responses
|
||||
/// not related to the current transition. One way to do this is to assign unique IDs to all
|
||||
/// requests sent to the device and only handle responses related to those IDs.
|
||||
pub fn state_machine<F: FnMut(ModeSetRequest)>(
|
||||
&mut self,
|
||||
opt_mode_reponse: Option<ModeResponse>,
|
||||
@@ -536,7 +536,7 @@ impl SubsystemCommandingHelper {
|
||||
// Normally, this step is done after all replies were received, but if no
|
||||
// reply checking is required for a command sequence, the step would never
|
||||
// be performed, so this function needs to be called here as well.
|
||||
self.update_internal_req_id();
|
||||
//self.update_internal_req_id();
|
||||
}
|
||||
ModeCommandingResult::AwaitingSuccessCheck => (),
|
||||
}
|
||||
@@ -580,14 +580,12 @@ impl SubsystemCommandingHelper {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_internal_req_id(&mut self) {
|
||||
self.seq_exec_helper.set_request_id(
|
||||
self.internal_request_id(self.seq_exec_helper.current_sequence_index().unwrap() as u8),
|
||||
);
|
||||
}
|
||||
|
||||
// Handles a mode reply message and returns whether the reply completes a step of sequence
|
||||
// commanding.
|
||||
//
|
||||
// During mode commanding, it is the responsibility of the user to discard mode responses
|
||||
// not related to the current transition. One way to do this is to assigned unique IDs to all
|
||||
// requests sent to the device and only handle responses related to those IDs.
|
||||
fn handle_children_mode_changed(
|
||||
&mut self,
|
||||
mode_response: ModeResponse,
|
||||
@@ -599,14 +597,8 @@ impl SubsystemCommandingHelper {
|
||||
return Ok(false);
|
||||
}
|
||||
let mut partial_step_done = false;
|
||||
// Tying the reply awaition to the request ID ensures that something like replies
|
||||
// belonging to older requests do not interfere with the completion handling of
|
||||
// the mode commanding. This is important for forced mode commands.
|
||||
let mut handle_awaition = false;
|
||||
if self.state == ModeTreeHelperState::ModeCommanding
|
||||
&& self.active_internal_request_id.is_some()
|
||||
&& mode_response.request_id == self.active_internal_request_id.unwrap()
|
||||
{
|
||||
if self.state == ModeTreeHelperState::ModeCommanding {
|
||||
handle_awaition = true;
|
||||
}
|
||||
let still_awating_replies = self.children_mode_store.mode_reply_handler(
|
||||
@@ -619,7 +611,6 @@ impl SubsystemCommandingHelper {
|
||||
&& !still_awating_replies.unwrap_or(false)
|
||||
{
|
||||
self.seq_exec_helper.confirm_sequence_done();
|
||||
self.update_internal_req_id();
|
||||
partial_step_done = true;
|
||||
}
|
||||
if !mode_response.success && self.state == ModeTreeHelperState::ModeCommanding {
|
||||
@@ -775,9 +766,15 @@ mod tests {
|
||||
|
||||
fn create_default_mode_store() -> ModeStoreVec {
|
||||
let mut mode_store = ModeStoreVec::default();
|
||||
mode_store.add_component(ExampleTargetId::Target0 as ComponentId, 0);
|
||||
mode_store.add_component(ExampleTargetId::Target1 as ComponentId, 0);
|
||||
mode_store.add_component(ExampleTargetId::Target2 as ComponentId, 0);
|
||||
mode_store
|
||||
.add_component(ExampleTargetId::Target0 as ComponentId, 0)
|
||||
.unwrap();
|
||||
mode_store
|
||||
.add_component(ExampleTargetId::Target1 as ComponentId, 0)
|
||||
.unwrap();
|
||||
mode_store
|
||||
.add_component(ExampleTargetId::Target2 as ComponentId, 0)
|
||||
.unwrap();
|
||||
mode_store
|
||||
}
|
||||
|
||||
@@ -864,6 +861,7 @@ mod tests {
|
||||
self.helper.start_command_sequence(mode as ModeRaw)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_sequence_tables(&mut self, mode: ExampleMode) -> &mut SequenceTablesMapValue {
|
||||
self.helper
|
||||
.sequence_tables
|
||||
@@ -920,13 +918,11 @@ mod tests {
|
||||
assert!(execution_helper.current_sequence_index().is_none());
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_sequence_execution_helper_no_success_check() {
|
||||
let mut tb = SequenceExecutorTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.execution_helper
|
||||
.load(ExampleMode::Mode0 as u32, expected_req_id, &tb.seq_tables)
|
||||
.load(ExampleMode::Mode0 as u32, &tb.seq_tables)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
tb.execution_helper.state(),
|
||||
@@ -935,10 +931,12 @@ mod tests {
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
assert_eq!(
|
||||
tb.execution_helper.target_mode().unwrap(),
|
||||
ExampleMode::Mode0 as Mode
|
||||
ExampleMode::Mode0 as ModeRaw
|
||||
);
|
||||
let mut list = Vec::new();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence exeecution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence exeecution helper run failure"),
|
||||
ModeCommandingResult::Done
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -946,7 +944,7 @@ mod tests {
|
||||
SequenceExecutionHelperState::Idle
|
||||
);
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
tb.generic_checks_subsystem_md0(expected_req_id);
|
||||
tb.generic_checks_subsystem_md0(&list);
|
||||
tb.check_run_is_no_op();
|
||||
}
|
||||
|
||||
@@ -956,9 +954,8 @@ mod tests {
|
||||
let mode0_table = tb.get_mode_table(ExampleMode::Mode0);
|
||||
mode0_table.entries[0].entries[0].check_success = true;
|
||||
mode0_table.entries[0].entries[1].check_success = true;
|
||||
let expected_req_id = 1;
|
||||
tb.execution_helper
|
||||
.load(ExampleMode::Mode0 as u32, expected_req_id, &tb.seq_tables)
|
||||
.load(ExampleMode::Mode0 as u32, &tb.seq_tables)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -968,10 +965,12 @@ mod tests {
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
assert_eq!(
|
||||
tb.execution_helper.target_mode().unwrap(),
|
||||
ExampleMode::Mode0 as Mode
|
||||
ExampleMode::Mode0 as ModeRaw
|
||||
);
|
||||
let mut list = Vec::new();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence exeecution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence exeecution helper run failure"),
|
||||
ModeCommandingResult::AwaitingSuccessCheck
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -981,7 +980,7 @@ mod tests {
|
||||
// These are not cleared, even if the execution helper is already IDLE. This is okay for
|
||||
// now.
|
||||
assert!(tb.execution_helper.awaiting_success_check());
|
||||
tb.generic_checks_subsystem_md0(expected_req_id);
|
||||
tb.generic_checks_subsystem_md0(&list);
|
||||
tb.execution_helper.confirm_sequence_done();
|
||||
assert_eq!(
|
||||
tb.execution_helper.state(),
|
||||
@@ -996,9 +995,8 @@ mod tests {
|
||||
let mut tb = SequenceExecutorTestbench::new();
|
||||
let mode0_table = tb.get_mode_table(ExampleMode::Mode0);
|
||||
mode0_table.entries[0].entries[0].check_success = true;
|
||||
let expected_req_id = 1;
|
||||
tb.execution_helper
|
||||
.load(ExampleMode::Mode0 as u32, expected_req_id, &tb.seq_tables)
|
||||
.load(ExampleMode::Mode0 as u32, &tb.seq_tables)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -1006,8 +1004,10 @@ mod tests {
|
||||
SequenceExecutionHelperState::Busy
|
||||
);
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
let mut list = Vec::new();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence execution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence execution helper run failure"),
|
||||
ModeCommandingResult::AwaitingSuccessCheck
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1017,7 +1017,7 @@ mod tests {
|
||||
// These are not cleared, even if the execution helper is already IDLE. This is okay for
|
||||
// now.
|
||||
assert!(tb.execution_helper.awaiting_success_check());
|
||||
tb.generic_checks_subsystem_md0(expected_req_id);
|
||||
tb.generic_checks_subsystem_md0(&list);
|
||||
tb.execution_helper.confirm_sequence_done();
|
||||
assert_eq!(
|
||||
tb.execution_helper.state(),
|
||||
@@ -1029,9 +1029,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_sequence_execution_helper_multi_step_no_success_check() {
|
||||
let mut tb = SequenceExecutorTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.execution_helper
|
||||
.load(ExampleMode::Mode1 as u32, expected_req_id, &tb.seq_tables)
|
||||
.load(ExampleMode::Mode1 as u32, &tb.seq_tables)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
tb.execution_helper.state(),
|
||||
@@ -1040,10 +1039,12 @@ mod tests {
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
assert_eq!(
|
||||
tb.execution_helper.target_mode().unwrap(),
|
||||
ExampleMode::Mode1 as Mode
|
||||
ExampleMode::Mode1 as ModeRaw
|
||||
);
|
||||
let mut list = Vec::new();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence execution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence execution helper run failure"),
|
||||
ModeCommandingResult::StepDone
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1051,14 +1052,16 @@ mod tests {
|
||||
SequenceExecutionHelperState::Busy
|
||||
);
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
tb.generic_checks_subsystem_md1_step0(expected_req_id);
|
||||
tb.generic_checks_subsystem_md1_step0(&list);
|
||||
assert_eq!(tb.execution_helper.current_sequence_index().unwrap(), 1);
|
||||
|
||||
list.clear();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence execution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence execution helper run failure"),
|
||||
ModeCommandingResult::Done
|
||||
);
|
||||
tb.generic_checks_subsystem_md1_step1(expected_req_id);
|
||||
tb.generic_checks_subsystem_md1_step1(&list);
|
||||
assert_eq!(
|
||||
tb.execution_helper.state(),
|
||||
SequenceExecutionHelperState::Idle
|
||||
@@ -1069,9 +1072,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_sequence_execution_helper_multi_step_full_success_check() {
|
||||
let mut tb = SequenceExecutorTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.execution_helper
|
||||
.load(ExampleMode::Mode1 as u32, expected_req_id, &tb.seq_tables)
|
||||
.load(ExampleMode::Mode1 as u32, &tb.seq_tables)
|
||||
.unwrap();
|
||||
let mode1_table = tb.get_mode_table(ExampleMode::Mode1);
|
||||
mode1_table.entries[0].entries[0].check_success = true;
|
||||
@@ -1085,10 +1087,12 @@ mod tests {
|
||||
assert!(!tb.execution_helper.awaiting_success_check());
|
||||
assert_eq!(
|
||||
tb.execution_helper.target_mode().unwrap(),
|
||||
ExampleMode::Mode1 as Mode
|
||||
ExampleMode::Mode1 as ModeRaw
|
||||
);
|
||||
let mut list = Vec::new();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence execution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence execution helper run failure"),
|
||||
ModeCommandingResult::AwaitingSuccessCheck
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1096,12 +1100,14 @@ mod tests {
|
||||
SequenceExecutionHelperState::AwaitingSuccessCheck
|
||||
);
|
||||
assert!(tb.execution_helper.awaiting_success_check());
|
||||
tb.generic_checks_subsystem_md1_step0(expected_req_id);
|
||||
tb.generic_checks_subsystem_md1_step0(&list);
|
||||
assert_eq!(tb.execution_helper.current_sequence_index().unwrap(), 0);
|
||||
tb.execution_helper.confirm_sequence_done();
|
||||
|
||||
list.clear();
|
||||
assert_eq!(
|
||||
tb.run().expect("sequence execution helper run failure"),
|
||||
tb.run(&mut list)
|
||||
.expect("sequence execution helper run failure"),
|
||||
ModeCommandingResult::AwaitingSuccessCheck
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1110,117 +1116,66 @@ mod tests {
|
||||
);
|
||||
assert!(tb.execution_helper.awaiting_success_check());
|
||||
assert_eq!(tb.execution_helper.current_sequence_index().unwrap(), 1);
|
||||
tb.generic_checks_subsystem_md1_step1(expected_req_id);
|
||||
tb.generic_checks_subsystem_md1_step1(&list);
|
||||
tb.execution_helper.confirm_sequence_done();
|
||||
tb.check_run_is_no_op();
|
||||
}
|
||||
|
||||
// TODO: Test subsystem commanding helper
|
||||
#[test]
|
||||
fn test_subsystem_helper_basic_state() {
|
||||
let tb = SubsystemHelperTestbench::new();
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::Idle);
|
||||
assert!(tb.helper.active_internal_request_id.is_none());
|
||||
assert_eq!(tb.helper.mode(), UNKNOWN_MODE_VAL);
|
||||
assert!(tb.helper.request_id().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subsystem_helper_announce_recursive() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.send_announce_mode_cmd_to_children(expected_req_id, true)
|
||||
.unwrap();
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 3);
|
||||
let check_req = |req: ModeReqWrapper, target_id: ComponentId| {
|
||||
assert_eq!(req.target_id, target_id);
|
||||
assert_eq!(req.request_id, expected_req_id);
|
||||
assert_eq!(req.request, ModeRequest::AnnounceModeRecursive);
|
||||
};
|
||||
let req0 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req0, ExampleTargetId::Target0 as ComponentId);
|
||||
let req1 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req1, ExampleTargetId::Target1 as ComponentId);
|
||||
let req2 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req2, ExampleTargetId::Target2 as ComponentId);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subsystem_helper_announce() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.send_announce_mode_cmd_to_children(expected_req_id, false)
|
||||
.unwrap();
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 3);
|
||||
let check_req = |req: ModeReqWrapper, target_id: ComponentId| {
|
||||
assert_eq!(req.target_id, target_id);
|
||||
assert_eq!(req.request_id, expected_req_id);
|
||||
assert_eq!(req.request, ModeRequest::AnnounceMode);
|
||||
};
|
||||
let req0 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req0, ExampleTargetId::Target0 as ComponentId);
|
||||
let req1 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req1, ExampleTargetId::Target1 as ComponentId);
|
||||
let req2 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req2, ExampleTargetId::Target2 as ComponentId);
|
||||
//assert!(tb.helper.active_internal_request_id.is_none());
|
||||
assert_eq!(tb.helper.mode(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subsystem_helper_cmd_mode0_no_success_checks() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.start_command_sequence(ExampleMode::Mode0, expected_req_id)
|
||||
.unwrap();
|
||||
assert_eq!(tb.helper.request_id().unwrap(), 1);
|
||||
tb.start_command_sequence(ExampleMode::Mode0).unwrap();
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 0);
|
||||
assert_eq!(tb.mode_request_queue.len(), 0);
|
||||
assert_eq!(
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::Done)
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::TargetKeeping);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode0 as Mode);
|
||||
tb.generic_checks_subsystem_md0(tb.helper.internal_request_id().unwrap());
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode0 as ModeRaw);
|
||||
tb.generic_checks_subsystem_md0();
|
||||
// FSM call should be a no-op.
|
||||
assert_eq!(
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::TargetKeeping
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::TargetKeeping);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode0 as Mode);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode0 as ModeRaw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subsystem_helper_cmd_mode1_no_success_checks() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
tb.start_command_sequence(ExampleMode::Mode1, expected_req_id)
|
||||
.unwrap();
|
||||
tb.start_command_sequence(ExampleMode::Mode1).unwrap();
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 0);
|
||||
assert!(tb.mode_request_queue.is_empty());
|
||||
// Need to cache this before it is incremented, because it is incremented
|
||||
// immediately in the state machine (no reply checking)
|
||||
let expected_req_id = tb.helper.internal_request_id().unwrap();
|
||||
//let expected_req_id = tb.helper.internal_request_id().unwrap();
|
||||
assert_eq!(
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::StepDone)
|
||||
);
|
||||
// Assert that this was already incremented because no reply checking is necessary.
|
||||
assert_eq!(
|
||||
tb.helper.internal_request_id().unwrap(),
|
||||
expected_req_id + 1
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.helper.mode(), UNKNOWN_MODE_VAL);
|
||||
tb.generic_checks_subsystem_md1_step0(expected_req_id);
|
||||
assert_eq!(tb.helper.mode(), 0);
|
||||
tb.generic_checks_subsystem_md1_step0();
|
||||
// Second commanding step.
|
||||
assert_eq!(
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::Done)
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::TargetKeeping);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode1 as Mode);
|
||||
tb.generic_checks_subsystem_md1_step1(tb.helper.internal_request_id().unwrap());
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode1 as ModeRaw);
|
||||
tb.generic_checks_subsystem_md1_step1();
|
||||
|
||||
// FSM call should be a no-op.
|
||||
assert_eq!(
|
||||
@@ -1228,41 +1183,37 @@ mod tests {
|
||||
SubsystemHelperResult::TargetKeeping
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::TargetKeeping);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode1 as Mode);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode1 as ModeRaw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subsystem_helper_cmd_mode0_with_success_checks() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
let seq_tables = tb.get_sequence_tables(ExampleMode::Mode0);
|
||||
seq_tables.entries[0].entries[0].check_success = true;
|
||||
seq_tables.entries[0].entries[1].check_success = true;
|
||||
tb.start_command_sequence(ExampleMode::Mode0, expected_req_id)
|
||||
.unwrap();
|
||||
tb.start_command_sequence(ExampleMode::Mode0).unwrap();
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 0);
|
||||
assert!(tb.mode_request_queue.is_empty());
|
||||
assert_eq!(
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::AwaitingSuccessCheck)
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.helper.mode(), UNKNOWN_MODE_VAL);
|
||||
tb.generic_checks_subsystem_md0(tb.helper.internal_request_id().unwrap());
|
||||
let mode_reply_ok_0 = GenericMessage::new(
|
||||
MessageMetadata::new(
|
||||
tb.helper.internal_request_id().unwrap(),
|
||||
ExampleTargetId::Target0 as ComponentId,
|
||||
),
|
||||
ModeReply::ModeInfo(SUBSYSTEM_MD0_TGT0_MODE),
|
||||
);
|
||||
let mode_reply_ok_1 = GenericMessage::new(
|
||||
MessageMetadata::new(
|
||||
tb.helper.internal_request_id().unwrap(),
|
||||
ExampleTargetId::Target1 as ComponentId,
|
||||
),
|
||||
ModeReply::ModeInfo(SUBSYSTEM_MD0_TGT1_MODE),
|
||||
);
|
||||
assert_eq!(tb.helper.mode(), 0);
|
||||
tb.generic_checks_subsystem_md0();
|
||||
let mode_reply_ok_0 = ModeResponse {
|
||||
request_id: 0,
|
||||
sender_id: ExampleTargetId::Target0 as ComponentId,
|
||||
reported_mode: SUBSYSTEM_MD0_TGT0_MODE,
|
||||
success: true,
|
||||
};
|
||||
let mode_reply_ok_1 = ModeResponse {
|
||||
request_id: 1,
|
||||
sender_id: ExampleTargetId::Target1 as ComponentId,
|
||||
reported_mode: SUBSYSTEM_MD0_TGT1_MODE,
|
||||
success: true,
|
||||
};
|
||||
// One success reply still expected.
|
||||
assert_eq!(
|
||||
tb.state_machine(Some(mode_reply_ok_0)).unwrap(),
|
||||
@@ -1279,42 +1230,38 @@ mod tests {
|
||||
SubsystemHelperResult::TargetKeeping
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::TargetKeeping);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode0 as Mode);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode0 as ModeRaw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subsystem_helper_cmd_mode1_with_success_checks() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
let expected_req_id = 1;
|
||||
let seq_tables = tb.get_sequence_tables(ExampleMode::Mode1);
|
||||
seq_tables.entries[0].entries[0].check_success = true;
|
||||
seq_tables.entries[0].entries[1].check_success = true;
|
||||
seq_tables.entries[1].entries[0].check_success = true;
|
||||
tb.start_command_sequence(ExampleMode::Mode1, expected_req_id)
|
||||
.unwrap();
|
||||
tb.start_command_sequence(ExampleMode::Mode1).unwrap();
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 0);
|
||||
assert!(tb.mode_request_queue.is_empty());
|
||||
assert_eq!(
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::AwaitingSuccessCheck)
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.helper.mode(), UNKNOWN_MODE_VAL);
|
||||
tb.generic_checks_subsystem_md1_step0(tb.helper.internal_request_id().unwrap());
|
||||
let mode_reply_ok_0 = GenericMessage::new(
|
||||
MessageMetadata::new(
|
||||
tb.helper.internal_request_id().unwrap(),
|
||||
ExampleTargetId::Target0 as ComponentId,
|
||||
),
|
||||
ModeReply::ModeInfo(SUBSYSTEM_MD0_TGT0_MODE),
|
||||
);
|
||||
let mode_reply_ok_1 = GenericMessage::new(
|
||||
MessageMetadata::new(
|
||||
tb.helper.internal_request_id().unwrap(),
|
||||
ExampleTargetId::Target1 as ComponentId,
|
||||
),
|
||||
ModeReply::ModeInfo(SUBSYSTEM_MD0_TGT1_MODE),
|
||||
);
|
||||
assert_eq!(tb.helper.mode(), 0);
|
||||
tb.generic_checks_subsystem_md1_step0();
|
||||
let mode_reply_ok_0 = ModeResponse {
|
||||
request_id: 0,
|
||||
sender_id: ExampleTargetId::Target0 as ComponentId,
|
||||
reported_mode: SUBSYSTEM_MD0_TGT0_MODE,
|
||||
success: true,
|
||||
};
|
||||
let mode_reply_ok_1 = ModeResponse {
|
||||
request_id: 1,
|
||||
sender_id: ExampleTargetId::Target1 as ComponentId,
|
||||
reported_mode: SUBSYSTEM_MD0_TGT1_MODE,
|
||||
success: true,
|
||||
};
|
||||
// One success reply still expected.
|
||||
assert_eq!(
|
||||
tb.state_machine(Some(mode_reply_ok_0)).unwrap(),
|
||||
@@ -1329,13 +1276,12 @@ mod tests {
|
||||
tb.state_machine(None).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::AwaitingSuccessCheck)
|
||||
);
|
||||
let mode_reply_ok = GenericMessage::new(
|
||||
MessageMetadata::new(
|
||||
tb.helper.internal_request_id().unwrap(),
|
||||
ExampleTargetId::Target2 as ComponentId,
|
||||
),
|
||||
ModeReply::ModeInfo(SUBSYSTEM_MD1_ST1_TGT2_MODE),
|
||||
);
|
||||
let mode_reply_ok = ModeResponse {
|
||||
request_id: 2,
|
||||
sender_id: ExampleTargetId::Target2 as ComponentId,
|
||||
reported_mode: SUBSYSTEM_MD1_ST1_TGT2_MODE,
|
||||
success: true,
|
||||
};
|
||||
assert_eq!(
|
||||
tb.state_machine(Some(mode_reply_ok)).unwrap(),
|
||||
SubsystemHelperResult::ModeCommanding(ModeCommandingResult::Done)
|
||||
@@ -1347,9 +1293,10 @@ mod tests {
|
||||
SubsystemHelperResult::TargetKeeping
|
||||
);
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::TargetKeeping);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode1 as Mode);
|
||||
assert_eq!(tb.helper.mode(), ExampleMode::Mode1 as ModeRaw);
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_subsystem_helper_cmd_mode1_with_partial_success_checks_0() {
|
||||
let mut tb = SubsystemHelperTestbench::new();
|
||||
@@ -1358,7 +1305,7 @@ mod tests {
|
||||
seq_tables.entries[0].entries[0].check_success = true;
|
||||
seq_tables.entries[0].entries[1].check_success = false;
|
||||
seq_tables.entries[1].entries[0].check_success = false;
|
||||
tb.start_command_sequence(ExampleMode::Mode1, expected_req_id)
|
||||
tb.start_command_sequence(ExampleMode::Mode1)
|
||||
.unwrap();
|
||||
assert_eq!(tb.helper.state(), ModeTreeHelperState::ModeCommanding);
|
||||
assert_eq!(tb.sender.requests.borrow().len(), 0);
|
||||
|
||||
Reference in New Issue
Block a user