system_update_committer/metadata/
commit.rs1use super::configuration_without_recovery::ConfigurationWithoutRecovery;
6use super::errors::{BootManagerError, BootManagerResultExt};
7use fidl_fuchsia_paver as paver;
8
9pub async fn do_commit(
11 boot_manager: &paver::BootManagerProxy,
12 current_config: &ConfigurationWithoutRecovery,
13) -> Result<(), BootManagerError> {
14 async fn internal_write(
16 boot_manager: &paver::BootManagerProxy,
17 current_config: &ConfigurationWithoutRecovery,
18 ) -> Result<(), BootManagerError> {
19 let alternate_config = current_config.to_alternate().into();
20
21 let () = boot_manager
22 .set_configuration_healthy(current_config.into())
23 .await
24 .into_boot_manager_result("set_configuration_healthy")?;
25 let () = boot_manager
26 .set_configuration_unbootable(alternate_config)
27 .await
28 .into_boot_manager_result("set_configuration_unbootable")?;
29 Ok(())
30 }
31
32 let write_result = internal_write(boot_manager, current_config).await;
34
35 let () = boot_manager.flush().await.into_boot_manager_result("flush")?;
36
37 write_result
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use assert_matches::assert_matches;
44 use mock_paver::{MockPaverServiceBuilder, PaverEvent, hooks as mphooks};
45 use std::sync::Arc;
46 use zx::Status;
47
48 async fn run_success_test(current_config: &ConfigurationWithoutRecovery) {
50 let paver = Arc::new(MockPaverServiceBuilder::new().build());
51 let () = do_commit(&paver.spawn_boot_manager_service(), current_config).await.unwrap();
52
53 assert_eq!(
54 paver.take_events(),
55 vec![
56 PaverEvent::SetConfigurationHealthy { configuration: current_config.into() },
57 PaverEvent::SetConfigurationUnbootable {
58 configuration: current_config.to_alternate().into()
59 },
60 PaverEvent::BootManagerFlush,
61 ]
62 );
63 }
64
65 #[fuchsia::test]
66 async fn test_success_current_a() {
67 run_success_test(&ConfigurationWithoutRecovery::A).await;
68 }
69
70 #[fuchsia::test]
71 async fn test_success_current_b() {
72 run_success_test(&ConfigurationWithoutRecovery::B).await;
73 }
74
75 #[fuchsia::test]
76 async fn test_fails_when_set_healthy_fails() {
77 let paver = Arc::new(
78 MockPaverServiceBuilder::new()
79 .insert_hook(mphooks::return_error(|e| match e {
80 PaverEvent::SetConfigurationHealthy { .. } => Err(Status::OUT_OF_RANGE),
81 _ => Ok(()),
82 }))
83 .build(),
84 );
85
86 assert_matches!(
87 do_commit(&paver.spawn_boot_manager_service(), &ConfigurationWithoutRecovery::A).await,
88 Err(BootManagerError::Status {
89 method_name: "set_configuration_healthy",
90 status: Status::OUT_OF_RANGE
91 })
92 );
93
94 assert_eq!(
95 paver.take_events(),
96 vec![
97 PaverEvent::SetConfigurationHealthy { configuration: paver::Configuration::A },
98 PaverEvent::BootManagerFlush,
99 ]
100 );
101 }
102}