diff --git a/src/orchestration/src/api/design.rs b/src/orchestration/src/api/design.rs index 9a2e739..7f222e0 100644 --- a/src/orchestration/src/api/design.rs +++ b/src/orchestration/src/api/design.rs @@ -169,7 +169,7 @@ impl Design { shutdown_events: &GrowableVec, container: &mut GrowableVec, ) -> Result<(), CommonErrors> { - while let Some(program_data) = self.programs.pop() { + while let Some(program_data) = self.programs.remove(0) { let mut builder = ProgramBuilder::new(program_data.0); (program_data.1)(&mut self, &mut builder)?; container.push(builder.build(shutdown_events, self.config())?); @@ -191,6 +191,7 @@ impl ProgramData { } #[cfg(test)] +#[cfg(not(loom))] mod tests { // Tests are disabled in Miri due to limitations of using OS calls that are done in Iceroxy2 backend. // Currently we do not have any constructor that can inject IPC provider (subject to change in the near future). @@ -277,5 +278,41 @@ mod tests { assert!(orchestration_tag.is_err()); } + #[test] + fn into_programs_preserves_insertion_order() { + use crate::prelude::Invoke; + + let id = Tag::from_str_static("design1"); + let config = DesignConfig::default(); + let mut design = Design::new(id, config); + + let run_tag = design + .register_invoke_fn(Tag::from_str_static("run_action"), action) + .unwrap(); + + let tag = run_tag.clone(); + design.add_program("first", move |design, builder| { + builder.with_run_action(Invoke::from_tag(&tag, design.config())); + Ok(()) + }); + let tag = run_tag.clone(); + design.add_program("second", move |design, builder| { + builder.with_run_action(Invoke::from_tag(&tag, design.config())); + Ok(()) + }); + design.add_program("third", move |design, builder| { + builder.with_run_action(Invoke::from_tag(&run_tag, design.config())); + Ok(()) + }); + + let mut container = GrowableVec::default(); + design.into_programs(&GrowableVec::default(), &mut container).unwrap(); + + assert_eq!(container.len(), 3); + assert_eq!(container[0].name(), "first"); + assert_eq!(container[1].name(), "second"); + assert_eq!(container[2].name(), "third"); + } + // TODO add more tests once new Program skeleton is created } diff --git a/src/orchestration/src/api/mod.rs b/src/orchestration/src/api/mod.rs index 220e0ae..1b3eef2 100644 --- a/src/orchestration/src/api/mod.rs +++ b/src/orchestration/src/api/mod.rs @@ -166,7 +166,7 @@ impl OrchestrationApi<_DesignTag> { /// Returns an error if there is an issue while creating the programs, such as a design not being valid. pub fn into_program_manager(mut self) -> Result { let mut programs = GrowableVec::default(); - while let Some(design) = self.designs.pop() { + while let Some(design) = self.designs.remove(0) { design.into_programs(&self.shutdown_events, &mut programs)? }