need to properly step this..

This commit is contained in:
2026-07-27 17:43:31 +02:00
parent b290430703
commit 3b20bf793a
+128 -181
View File
@@ -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);