run_test_suite_lib/output/
memory.rs1use crate::output::{
6 ArtifactType, DirectoryArtifactType, DirectoryWrite, DynArtifact, DynDirectoryArtifact,
7 EntityId, EntityInfo, ReportedOutcome, Reporter, Timestamp,
8};
9use fuchsia_sync::Mutex;
10use std::collections::HashMap;
11use std::io::{Error, Write};
12use std::path::{Path, PathBuf};
13use std::sync::Arc;
14
15#[derive(Clone)]
19pub struct InMemoryReporter {
20 pub entities: Arc<Mutex<HashMap<EntityId, EntityReport>>>,
21}
22
23#[derive(Clone)]
24pub struct InMemoryReport {
25 pub id: EntityId,
26 pub report: EntityReport,
27}
28
29impl InMemoryReporter {
30 pub fn new() -> Self {
31 Self { entities: Arc::new(Mutex::new(HashMap::new())) }
32 }
33
34 pub fn get_reports(&self) -> Vec<InMemoryReport> {
35 self.entities
36 .lock()
37 .iter()
38 .map(|(key, value)| InMemoryReport { id: key.clone(), report: value.clone() })
39 .collect::<Vec<_>>()
40 }
41}
42
43#[derive(Clone)]
44pub struct InMemoryDirectoryWriter {
45 pub moniker: Option<String>,
46 pub files: Arc<Mutex<Vec<(PathBuf, InMemoryArtifact)>>>,
47}
48
49impl Default for InMemoryDirectoryWriter {
50 fn default() -> Self {
51 Self { moniker: None, files: Arc::new(Mutex::new(vec![])) }
52 }
53}
54
55#[derive(Default, Clone)]
56pub struct EntityReport {
57 pub name: String,
58 pub started_time: Option<Timestamp>,
59 pub stopped_time: Option<Timestamp>,
60 pub outcome: Option<ReportedOutcome>,
61 pub is_finished: bool,
62 pub artifacts: Vec<(ArtifactType, InMemoryArtifact)>,
63 pub directories: Vec<(DirectoryArtifactType, InMemoryDirectoryWriter)>,
64}
65
66#[derive(Clone)]
67pub struct InMemoryArtifact {
68 contents: Arc<Mutex<Vec<u8>>>,
69}
70
71impl InMemoryArtifact {
72 pub fn new() -> Self {
73 Self { contents: Arc::new(Mutex::new(Vec::new())) }
74 }
75
76 pub fn get_contents(&self) -> Vec<u8> {
78 self.contents.lock().clone()
79 }
80}
81
82impl Write for InMemoryArtifact {
83 fn write(&mut self, val: &[u8]) -> Result<usize, std::io::Error> {
84 self.contents.lock().write(val)
85 }
86 fn flush(&mut self) -> Result<(), std::io::Error> {
87 self.contents.lock().flush()
88 }
89}
90
91impl Reporter for InMemoryReporter {
92 fn new_entity(&self, id: &EntityId, name: &str) -> Result<(), Error> {
93 self.entities.lock().entry(*id).or_default().name = name.to_string();
94 Ok(())
95 }
96
97 fn set_entity_info(&self, _entity: &EntityId, _info: &EntityInfo) {}
98
99 fn entity_started(&self, id: &EntityId, timestamp: Timestamp) -> Result<(), Error> {
100 self.entities.lock().entry(*id).or_default().started_time = Some(timestamp);
101 Ok(())
102 }
103
104 fn entity_stopped(
105 &self,
106 id: &EntityId,
107 outcome: &ReportedOutcome,
108 timestamp: Timestamp,
109 ) -> Result<(), Error> {
110 let mut entities = self.entities.lock();
111 let e = entities.entry(*id).or_default();
112 e.stopped_time = Some(timestamp);
113 e.outcome = Some(*outcome);
114 Ok(())
115 }
116
117 fn entity_finished(&self, id: &EntityId) -> Result<(), Error> {
118 let mut entities = self.entities.lock();
119 let e = entities.entry(*id).or_default();
120 e.is_finished = true;
121 Ok(())
122 }
123
124 fn new_artifact(
125 &self,
126 id: &EntityId,
127 artifact_type: &ArtifactType,
128 ) -> Result<Box<DynArtifact>, Error> {
129 let mut entities = self.entities.lock();
130 let e = entities.entry(*id).or_default();
131 let artifact = InMemoryArtifact::new();
132 e.artifacts.push((*artifact_type, artifact.clone()));
133
134 Ok(Box::new(artifact))
135 }
136
137 fn new_directory_artifact(
138 &self,
139 id: &EntityId,
140 artifact_type: &DirectoryArtifactType,
141 moniker: Option<String>,
142 ) -> Result<Box<DynDirectoryArtifact>, Error> {
143 let mut entities = self.entities.lock();
144 let e = entities.entry(*id).or_default();
145 let mut dir = InMemoryDirectoryWriter::default();
146 dir.moniker = moniker;
147
148 e.directories.push((*artifact_type, dir.clone()));
149
150 Ok(Box::new(dir))
151 }
152}
153
154impl DirectoryWrite for InMemoryDirectoryWriter {
155 fn new_file(&self, path: &Path) -> Result<Box<DynArtifact>, Error> {
156 let artifact = InMemoryArtifact::new();
157 self.files.lock().push((path.to_owned(), artifact.clone()));
158
159 Ok(Box::new(artifact))
160 }
161}