power_manager_integration_test_lib/mocks/
admin.rs1use fidl::endpoints::ServerEnd;
6use fidl_fuchsia_hardware_power_statecontrol::{self as fpower, RebootOptions};
7use fidl_fuchsia_io::DirectoryMarker;
8use fuchsia_async as fasync;
9use fuchsia_component::server::ServiceFs;
10use fuchsia_component_test::LocalComponentHandles;
11use futures::channel::mpsc;
12use futures::lock::Mutex;
13use futures::{StreamExt, TryStreamExt};
14use log::*;
15use std::sync::Arc;
16
17pub struct MockStateControlAdminService {
19 shutdown_received_sender: Mutex<mpsc::Sender<RebootOptions>>,
20 shutdown_received_receiver: Mutex<mpsc::Receiver<RebootOptions>>,
21}
22
23impl MockStateControlAdminService {
24 pub fn new() -> Arc<MockStateControlAdminService> {
25 let (sender, receiver) = mpsc::channel(1);
26 Arc::new(Self {
27 shutdown_received_sender: Mutex::new(sender),
28 shutdown_received_receiver: Mutex::new(receiver),
29 })
30 }
31
32 pub async fn run(self: Arc<Self>, handles: LocalComponentHandles) -> Result<(), anyhow::Error> {
54 self.run_inner(handles.outgoing_dir).await
55 }
56
57 async fn run_inner(
58 self: Arc<Self>,
59 outgoing_dir: ServerEnd<DirectoryMarker>,
60 ) -> Result<(), anyhow::Error> {
61 let mut fs = ServiceFs::new();
62 fs.dir("svc").add_fidl_service(move |mut stream: fpower::AdminRequestStream| {
63 let this = self.clone();
64 fasync::Task::local(async move {
65 info!("MockStateControlAdminService: new connection Admin");
66 while let Some(fpower::AdminRequest::PerformReboot { responder: _, options }) =
67 stream.try_next().await.unwrap()
68 {
69 info!("MockStateControlAdminService: received Reboot request");
70 this.shutdown_received_sender
71 .lock()
72 .await
73 .try_send(options)
74 .expect("Failed to notify shutdown");
75 }
76 })
77 .detach();
78 });
79
80 fs.serve_connection(outgoing_dir).unwrap();
81 fs.collect::<()>().await;
82
83 Ok(())
84 }
85
86 pub async fn wait_for_shutdown_request(&self) -> RebootOptions {
88 self.shutdown_received_receiver
89 .lock()
90 .await
91 .next()
92 .await
93 .expect("Failed to wait for shutdown request")
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use fuchsia_component::client::connect_to_protocol_at_dir_svc;
101
102 #[fuchsia::test]
103 async fn test_shutdown() {
104 let (dir, outgoing_dir) = fidl::endpoints::create_proxy::<DirectoryMarker>();
106 let mock = MockStateControlAdminService::new();
107 let _task = fasync::Task::local(mock.clone().run_inner(outgoing_dir));
108
109 let controller_client =
111 connect_to_protocol_at_dir_svc::<fpower::AdminMarker>(&dir).unwrap();
112
113 let _task = fuchsia_async::Task::local(controller_client.perform_reboot(&RebootOptions {
115 reasons: Some(vec![fpower::RebootReason2::HighTemperature]),
116 ..Default::default()
117 }));
118 mock.wait_for_shutdown_request().await;
119 }
120}