sim: Return exit status from sim run
Instead of just printing a message, return an exit status so that
scripts running the sim can more easily tell if the tests passed.
Jira: MCUB-45
diff --git a/sim/src/main.rs b/sim/src/main.rs
index 8b08a81..fd9f664 100644
--- a/sim/src/main.rs
+++ b/sim/src/main.rs
@@ -12,6 +12,7 @@
use rand::{Rng, SeedableRng, XorShiftRng};
use rustc_serialize::{Decodable, Decoder};
use std::mem;
+use std::process;
use std::slice;
mod area;
@@ -79,128 +80,181 @@
return;
}
+ let mut status = RunStatus::new();
+
let align = args.flag_align.map(|x| x.0).unwrap_or(1);
- let (mut flash, areadesc) = match args.flag_device {
- None => panic!("Missing mandatory argument"),
- Some(DeviceName::Stm32f4) => {
- // STM style flash. Large sectors, with a large scratch area.
- let flash = Flash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 16 * 1024,
- 64 * 1024,
- 128 * 1024, 128 * 1024, 128 * 1024],
- align as usize);
- let mut areadesc = AreaDesc::new(&flash);
- areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
- areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
- areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch);
- (flash, areadesc)
- }
- Some(DeviceName::K64f) => {
- // NXP style flash. Small sectors, one small sector for scratch.
- let flash = Flash::new(vec![4096; 128], align as usize);
-
- let mut areadesc = AreaDesc::new(&flash);
- areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
- areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
- areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch);
- (flash, areadesc)
- }
- Some(DeviceName::K64fBig) => {
- // Simulating an STM style flash on top of an NXP style flash. Underlying flash device
- // uses small sectors, but we tell the bootloader they are large.
- let flash = Flash::new(vec![4096; 128], align as usize);
-
- let mut areadesc = AreaDesc::new(&flash);
- areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0);
- areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1);
- areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch);
- (flash, areadesc)
- }
- Some(DeviceName::Nrf52840) => {
- // Simulating the flash on the nrf52840 with partitions set up so that the scratch size
- // does not divide into the image size.
- let flash = Flash::new(vec![4096; 128], align as usize);
-
- let mut areadesc = AreaDesc::new(&flash);
- areadesc.add_image(0x008000, 0x034000, FlashId::Image0);
- areadesc.add_image(0x03c000, 0x034000, FlashId::Image1);
- areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch);
- (flash, areadesc)
- }
+ let device = match args.flag_device {
+ None => panic!("Missing mandatory device argument"),
+ Some(dev) => dev,
};
- let (slot0_base, slot0_len) = areadesc.find(FlashId::Image0);
- let (slot1_base, slot1_len) = areadesc.find(FlashId::Image1);
- let (scratch_base, _) = areadesc.find(FlashId::ImageScratch);
+ status.run_single(device, align);
- // Code below assumes that the slots are consecutive.
- assert_eq!(slot1_base, slot0_base + slot0_len);
- assert_eq!(scratch_base, slot1_base + slot1_len);
+ if status.failures > 0 {
+ warn!("{} Tests ran with {} failures", status.failures + status.passes, status.failures);
+ process::exit(1);
+ } else {
+ warn!("{} Tests ran successfully", status.passes);
+ process::exit(0);
+ }
+}
- // println!("Areas: {:#?}", areadesc.get_c());
+struct RunStatus {
+ failures: usize,
+ passes: usize,
+}
- // Install the boot trailer signature, so that the code will start an upgrade.
- // TODO: This must be a multiple of flash alignment, add support for an image that is smaller,
- // and just gets padded.
- let primary = install_image(&mut flash, slot0_base, 32784);
-
- // Install an upgrade image.
- let upgrade = install_image(&mut flash, slot1_base, 41928);
-
- // Set an alignment, and position the magic value.
- c::set_sim_flash_align(align);
- let trailer_size = c::boot_trailer_sz();
-
- // Mark the upgrade as ready to install. (This looks like it might be a bug in the code,
- // however.)
- mark_upgrade(&mut flash, scratch_base - trailer_size as usize);
-
- let (fl2, total_count) = try_upgrade(&flash, &areadesc, None);
- info!("First boot, count={}", total_count);
- assert!(verify_image(&fl2, slot0_base, &upgrade));
-
- let mut bad = 0;
- // Let's try an image halfway through.
- for i in 1 .. total_count {
- info!("Try interruption at {}", i);
- let (fl3, total_count) = try_upgrade(&flash, &areadesc, Some(i));
- info!("Second boot, count={}", total_count);
- if !verify_image(&fl3, slot0_base, &upgrade) {
- warn!("FAIL at step {} of {}", i, total_count);
- bad += 1;
- }
- if !verify_image(&fl3, slot1_base, &primary) {
- warn!("Slot 1 FAIL at step {} of {}", i, total_count);
- bad += 1;
+impl RunStatus {
+ fn new() -> RunStatus {
+ RunStatus {
+ failures: 0,
+ passes: 0,
}
}
- error!("{} out of {} failed {:.2}%",
- bad, total_count,
- bad as f32 * 100.0 / total_count as f32);
- for count in 2 .. 5 {
- info!("Try revert: {}", count);
- let fl2 = try_revert(&flash, &areadesc, count);
- assert!(verify_image(&fl2, slot0_base, &primary));
+ fn run_single(&mut self, device: DeviceName, align: u8) {
+ let mut failed = false;
+
+ let (mut flash, areadesc) = match device {
+ DeviceName::Stm32f4 => {
+ // STM style flash. Large sectors, with a large scratch area.
+ let flash = Flash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 16 * 1024,
+ 64 * 1024,
+ 128 * 1024, 128 * 1024, 128 * 1024],
+ align as usize);
+ let mut areadesc = AreaDesc::new(&flash);
+ areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
+ areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
+ areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch);
+ (flash, areadesc)
+ }
+ DeviceName::K64f => {
+ // NXP style flash. Small sectors, one small sector for scratch.
+ let flash = Flash::new(vec![4096; 128], align as usize);
+
+ let mut areadesc = AreaDesc::new(&flash);
+ areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
+ areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
+ areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch);
+ (flash, areadesc)
+ }
+ DeviceName::K64fBig => {
+ // Simulating an STM style flash on top of an NXP style flash. Underlying flash device
+ // uses small sectors, but we tell the bootloader they are large.
+ let flash = Flash::new(vec![4096; 128], align as usize);
+
+ let mut areadesc = AreaDesc::new(&flash);
+ areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0);
+ areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1);
+ areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch);
+ (flash, areadesc)
+ }
+ DeviceName::Nrf52840 => {
+ // Simulating the flash on the nrf52840 with partitions set up so that the scratch size
+ // does not divide into the image size.
+ let flash = Flash::new(vec![4096; 128], align as usize);
+
+ let mut areadesc = AreaDesc::new(&flash);
+ areadesc.add_image(0x008000, 0x034000, FlashId::Image0);
+ areadesc.add_image(0x03c000, 0x034000, FlashId::Image1);
+ areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch);
+ (flash, areadesc)
+ }
+ };
+
+ let (slot0_base, slot0_len) = areadesc.find(FlashId::Image0);
+ let (slot1_base, slot1_len) = areadesc.find(FlashId::Image1);
+ let (scratch_base, _) = areadesc.find(FlashId::ImageScratch);
+
+ // Code below assumes that the slots are consecutive.
+ assert_eq!(slot1_base, slot0_base + slot0_len);
+ assert_eq!(scratch_base, slot1_base + slot1_len);
+
+ // println!("Areas: {:#?}", areadesc.get_c());
+
+ // Install the boot trailer signature, so that the code will start an upgrade.
+ // TODO: This must be a multiple of flash alignment, add support for an image that is smaller,
+ // and just gets padded.
+ let primary = install_image(&mut flash, slot0_base, 32784);
+
+ // Install an upgrade image.
+ let upgrade = install_image(&mut flash, slot1_base, 41928);
+
+ // Set an alignment, and position the magic value.
+ c::set_sim_flash_align(align);
+ let trailer_size = c::boot_trailer_sz();
+
+ // Mark the upgrade as ready to install. (This looks like it might be a bug in the code,
+ // however.)
+ mark_upgrade(&mut flash, scratch_base - trailer_size as usize);
+
+ let (fl2, total_count) = try_upgrade(&flash, &areadesc, None);
+ info!("First boot, count={}", total_count);
+ if !verify_image(&fl2, slot0_base, &upgrade) {
+ error!("Image mismatch after first boot");
+ // This isn't really recoverable, and more tests aren't likely to reveal much.
+ self.failures += 1;
+ return;
+ }
+
+ let mut bad = 0;
+ // Let's try an image halfway through.
+ for i in 1 .. total_count {
+ info!("Try interruption at {}", i);
+ let (fl3, total_count) = try_upgrade(&flash, &areadesc, Some(i));
+ info!("Second boot, count={}", total_count);
+ if !verify_image(&fl3, slot0_base, &upgrade) {
+ warn!("FAIL at step {} of {}", i, total_count);
+ bad += 1;
+ }
+ if !verify_image(&fl3, slot1_base, &primary) {
+ warn!("Slot 1 FAIL at step {} of {}", i, total_count);
+ bad += 1;
+ }
+ }
+ error!("{} out of {} failed {:.2}%",
+ bad, total_count,
+ bad as f32 * 100.0 / total_count as f32);
+ if bad > 0 {
+ failed = true;
+ }
+
+ for count in 2 .. 5 {
+ info!("Try revert: {}", count);
+ let fl2 = try_revert(&flash, &areadesc, count);
+ if !verify_image(&fl2, slot0_base, &primary) {
+ warn!("Revert failure on count {}", count);
+ failed = true;
+ }
+ }
+
+ info!("Try norevert");
+ let fl2 = try_norevert(&flash, &areadesc);
+ if !verify_image(&fl2, slot0_base, &upgrade) {
+ warn!("No revert failed");
+ failed = true;
+ }
+
+ /*
+ // show_flash(&flash);
+
+ println!("First boot for upgrade");
+ // c::set_flash_counter(570);
+ c::boot_go(&mut flash, &areadesc);
+ // println!("{} flash ops", c::get_flash_counter());
+
+ verify_image(&flash, slot0_base, &upgrade);
+
+ println!("\n------------------\nSecond boot");
+ c::boot_go(&mut flash, &areadesc);
+ */
+ if failed {
+ self.failures += 1;
+ } else {
+ self.passes += 1;
+ }
}
-
- info!("Try norevert");
- let fl2 = try_norevert(&flash, &areadesc);
- assert!(verify_image(&fl2, slot0_base, &upgrade));
-
- /*
- // show_flash(&flash);
-
- println!("First boot for upgrade");
- // c::set_flash_counter(570);
- c::boot_go(&mut flash, &areadesc);
- // println!("{} flash ops", c::get_flash_counter());
-
- verify_image(&flash, slot0_base, &upgrade);
-
- println!("\n------------------\nSecond boot");
- c::boot_go(&mut flash, &areadesc);
- */
}
/// Test a boot, optionally stopping after 'n' flash options. Returns a count of the number of