fake_archive_accessor/fake_archive_accessor/
archivist_server.rs
1use fidl::prelude::*;
9use fidl_fuchsia_diagnostics::{
10 BatchIteratorControlHandle, BatchIteratorRequest, BatchIteratorRequestStream, FormattedContent,
11};
12
13use futures::prelude::*;
14use log::warn;
15use thiserror::Error;
16use zx_status::Status as ZxStatus;
17
18pub struct AccessorServer {
19 requests: BatchIteratorRequestStream,
20}
21
22impl AccessorServer {
23 pub fn new(requests: BatchIteratorRequestStream) -> Self {
24 Self { requests }
25 }
26
27 fn build_vmo(&self, data: &str) -> Result<Vec<FormattedContent>, ServerError> {
29 let size = data.len() as u64;
30 if size > 1024 * 1024 {
31 return Err(ServerError::DataTooBig);
32 }
33 let vmo = zx::Vmo::create(size).map_err(ServerError::VmoCreate)?;
34 vmo.write(data.as_bytes(), 0).map_err(ServerError::VmoWrite)?;
35 Ok(vec![FormattedContent::Json(fidl_fuchsia_mem::Buffer { vmo, size })])
36 }
37
38 pub async fn send(mut self, data: &str) -> Result<(), ServerError> {
39 if let Some(res) = self.requests.next().await {
40 match res? {
41 BatchIteratorRequest::GetNext { responder } => {
42 let response = self.build_vmo(data)?;
43 responder.send(Ok(response))?;
44 }
45 BatchIteratorRequest::WaitForReady { responder } => responder.send()?,
46 BatchIteratorRequest::_UnknownMethod { .. } => {
47 unreachable!("Unexpected method call");
48 }
49 };
50 if let Some(res) = self.requests.next().await {
51 match res? {
52 BatchIteratorRequest::GetNext { responder } => responder.send(Ok(vec![]))?,
53 BatchIteratorRequest::WaitForReady { responder } => responder.send()?,
54 BatchIteratorRequest::_UnknownMethod { .. } => {
55 unreachable!("Unexpected method call");
56 }
57 };
58 } else {
59 return Err(ServerError::TooFewBatchRequests);
60 }
61 } else {
62 return Err(ServerError::TooFewBatchRequests);
63 }
64 Ok(())
65 }
66}
67
68#[derive(Debug, Error)]
69pub enum ServerError {
70 #[error("Inspect data for test must be <1 MB")]
71 DataTooBig,
72
73 #[error("The client closed the batch connection early")]
74 TooFewBatchRequests,
75
76 #[error("data_type must be set")]
77 MissingDataType,
78
79 #[error("client_selector_configuration must be set")]
80 MissingSelectors,
81
82 #[error("no selectors were provided")]
83 EmptySelectors,
84
85 #[error("requested selectors are unsupported: {}", .0)]
86 InvalidSelectors(&'static str),
87
88 #[error("couldn't parse/validate the provided selectors")]
89 ParseSelectors(#[from] selectors::Error),
90
91 #[error("format must be set")]
92 MissingFormat,
93
94 #[error("Only Inspect supported right now")]
95 UnsupportedType,
96
97 #[error("only JSON supported right now")]
98 UnsupportedFormat,
99
100 #[error("stream_mode must be set")]
101 MissingMode,
102
103 #[error("only snapshot supported right now")]
104 UnsupportedMode,
105
106 #[error("IPC failure")]
107 Ipc {
108 #[from]
109 source: fidl::Error,
110 },
111
112 #[error("Unable to create a VMO -- extremely unusual!")]
113 VmoCreate(#[source] ZxStatus),
114
115 #[error("Unable to write to VMO -- we may be OOMing")]
116 VmoWrite(#[source] ZxStatus),
117}
118
119impl ServerError {
120 pub fn close(self, control: BatchIteratorControlHandle) {
121 warn!("Closing BatchIterator: {}", &self);
122 let epitaph = match self {
123 ServerError::MissingDataType | ServerError::DataTooBig => ZxStatus::INVALID_ARGS,
124 ServerError::EmptySelectors
125 | ServerError::MissingSelectors
126 | ServerError::InvalidSelectors(_)
127 | ServerError::ParseSelectors(_) => ZxStatus::INVALID_ARGS,
128 ServerError::VmoCreate(status) | ServerError::VmoWrite(status) => status,
129 ServerError::MissingFormat | ServerError::MissingMode => ZxStatus::INVALID_ARGS,
130 ServerError::UnsupportedFormat
131 | ServerError::UnsupportedMode
132 | ServerError::UnsupportedType => ZxStatus::WRONG_TYPE,
133 ServerError::Ipc { .. } | ServerError::TooFewBatchRequests => ZxStatus::IO,
134 };
135 control.shutdown_with_epitaph(epitaph);
136 }
137}