blob: f8acb7ed155922fed8718acddd2d6ed353ce18fe [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
mod archivist_accessor;
mod archivist_server;
use {
super::{DoneSignaler, TestData, TestEvent, TestEventSender},
anyhow::{bail, format_err, Error},
archivist_accessor::ArchiveAccessor,
async_trait::async_trait,
fidl_fuchsia_diagnostics as diagnostics,
futures::{SinkExt, StreamExt},
log::*,
std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
test_utils_lib::injectors::ProtocolInjector,
};
/// FakeArchiveAccessor can be injected to provide test Inspect data to Detect.
pub struct FakeArchiveAccessor {
event_sender: TestEventSender,
done_signaler: DoneSignaler,
inspect_data: Vec<String>,
next_data: AtomicUsize,
}
impl FakeArchiveAccessor {
pub fn new(
test_data: &TestData,
event_sender: TestEventSender,
done_signaler: DoneSignaler,
) -> Arc<FakeArchiveAccessor> {
Arc::new(FakeArchiveAccessor {
inspect_data: test_data.inspect_data.clone(),
event_sender,
done_signaler,
next_data: AtomicUsize::new(0),
})
}
// Handles an Ok(request) from the FIDL channel, including all input-checking, internal
// signaling, and data-replying. Return Ok(()) as long as nothing went wrong.
async fn handle_fidl_request(
&self,
request: diagnostics::ArchiveAccessorRequest,
) -> Result<(), Error> {
let mut event_sender = self.event_sender.clone();
let diagnostics::ArchiveAccessorRequest::StreamDiagnostics {
stream_parameters,
result_stream,
control_handle: _,
} = request;
ArchiveAccessor::validate_stream_request(stream_parameters)?;
event_sender.send(Ok(TestEvent::DiagnosticFetch)).await.unwrap();
let data_index = self.next_data.fetch_add(1, Ordering::Relaxed);
if data_index >= self.inspect_data.len() {
// We've run out of data to send. The test is done. Signal that it's time
// to evaluate the data. Don't even respond to the Detect program.
self.done_signaler.signal_done().await;
} else {
if let Err(problem) =
ArchiveAccessor::send(result_stream, &self.inspect_data[data_index]).await
{
self.done_signaler.signal_done().await;
error!("Problem in request: {}", problem);
event_sender.send(Err(format_err!("{}", problem))).await.unwrap();
return Err(problem);
}
}
Ok(())
}
}
#[async_trait]
impl ProtocolInjector for FakeArchiveAccessor {
type Marker = diagnostics::ArchiveAccessorMarker;
async fn serve(
self: Arc<Self>,
mut request_stream: diagnostics::ArchiveAccessorRequestStream,
) -> Result<(), Error> {
loop {
match request_stream.next().await {
Some(Ok(request)) => self.handle_fidl_request(request).await?,
Some(Err(e)) => {
self.done_signaler.signal_done().await;
bail!("{}", e);
}
None => break,
}
}
Ok(())
}
}