power_manager_integration_test_lib/mocks/
admin.rs1use fidl::endpoints::ServerEnd;
6use fidl_fuchsia_hardware_power_statecontrol::{self as fpower, ShutdownOptions};
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<ShutdownOptions>>,
20 shutdown_received_receiver: Mutex<mpsc::Receiver<ShutdownOptions>>,
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(request) = stream.try_next().await.unwrap() {
67 match request {
68 fpower::AdminRequest::Shutdown { options, responder: _ } => {
69 info!("MockStateControlAdminService: received Shutdown request");
70 this.shutdown_received_sender
71 .lock()
72 .await
73 .try_send(options)
74 .expect("Failed to notify shutdown");
75 }
76 _ => {
77 unimplemented!();
78 }
79 }
80 }
81 })
82 .detach();
83 });
84
85 fs.serve_connection(outgoing_dir).unwrap();
86 fs.collect::<()>().await;
87
88 Ok(())
89 }
90
91 pub async fn wait_for_shutdown_request(&self) -> ShutdownOptions {
93 self.shutdown_received_receiver
94 .lock()
95 .await
96 .next()
97 .await
98 .expect("Failed to wait for shutdown request")
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105 use fuchsia_component::client::connect_to_protocol_at_dir_svc;
106
107 #[fuchsia::test]
108 async fn test_shutdown() {
109 let (dir, outgoing_dir) = fidl::endpoints::create_proxy::<DirectoryMarker>();
111 let mock = MockStateControlAdminService::new();
112 let _task = fasync::Task::local(mock.clone().run_inner(outgoing_dir));
113
114 let controller_client =
116 connect_to_protocol_at_dir_svc::<fpower::AdminMarker>(&dir).unwrap();
117
118 let _task = fuchsia_async::Task::local(controller_client.shutdown(&ShutdownOptions {
120 action: Some(fpower::ShutdownAction::Reboot),
121 reasons: Some(vec![fpower::ShutdownReason::HighTemperature]),
122 ..Default::default()
123 }));
124 mock.wait_for_shutdown_request().await;
125 }
126}