blob: 2df46ac7187ac1e8bf2090eb06b16a5878d016fc [file]
// 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.
use tracing::info;
use {
diagnostics_data::Logs, diagnostics_reader::ArchiveReader, fuchsia_async as fasync,
futures::stream::StreamExt, std::collections::HashMap, std::vec::Vec,
};
#[fasync::run_singlethreaded]
async fn main() {
diagnostics_log::init!(
&["archive-reader"],
diagnostics_log::Interest {
min_severity: Some(diagnostics_log::Severity::Info),
..diagnostics_log::Interest::EMPTY
}
);
let reader = ArchiveReader::new();
let mut non_matching_logs = vec![];
type Fingerprint = Vec<&'static str>;
let mut treasure = HashMap::<String, Vec<Fingerprint>>::new();
treasure.insert(
"routing-tests/offers-to-children-unavailable/child-for-offer-from-parent".to_string(),
vec![vec![
"Required",
"protocol `fidl.test.components.Trigger`",
"not available for target component \
`/root/routing-tests/offers-to-children-unavailable/child-for-offer-from-parent`",
"`/root/routing-tests/offers-to-children-unavailable` tried to offer \
`fidl.test.components.Trigger` from its parent",
"but the parent does not offer",
]],
);
treasure.insert(
"routing-tests/offers-to-children-unavailable-but-optional/child-for-offer-from-parent".to_string(),
vec![vec![
"Optional",
"protocol `fidl.test.components.Trigger`",
"not available for target component \
`/root/routing-tests/offers-to-children-unavailable-but-optional/child-for-offer-from-parent`",
"Target optionally uses capability that was not available",
"`/root/routing-tests/offers-to-children-unavailable-but-optional` tried to offer \
`fidl.test.components.Trigger` from its parent",
"but the parent does not offer",
]],
);
treasure.insert(
"routing-tests/child".to_string(),
vec![vec![
"Required",
"protocol `fidl.test.components.Trigger`",
"not available for target component \
`/root/routing-tests/child`",
"`/root/routing-tests/child` tried to use `fidl.test.components.Trigger` from its parent",
"but the parent does not offer",
]],
);
treasure.insert(
"routing-tests/child-with-optional-use".to_string(),
vec![vec![
"Optional",
"protocol `fidl.test.components.Trigger`",
"not available for target component \
`/root/routing-tests/child-with-optional-use`",
"Target optionally uses capability that was not available",
"`/root/routing-tests/child-with-optional-use` tried to use \
`fidl.test.components.Trigger` from its parent",
"but the parent does not offer",
]],
);
treasure.insert(
"routing-tests/offers-to-children-unavailable/child-for-offer-from-sibling".to_string(),
vec![vec![
"Required",
"protocol `fidl.test.components.Trigger`",
"not available for target component \
`/root/routing-tests/offers-to-children-unavailable/child-for-offer-from-sibling`",
"`/root/routing-tests/offers-to-children-unavailable` tried to offer",
"from its child `#child-that-doesnt-expose`",
"`#child-that-doesnt-expose` does not expose `fidl.test.components.Trigger`",
]],
);
treasure.insert(
"routing-tests/offers-to-children-unavailable-but-optional/child-for-offer-from-sibling".to_string(),
vec![vec![
"Optional",
"protocol `fidl.test.components.Trigger`",
"not available for target component \
`/root/routing-tests/offers-to-children-unavailable-but-optional/child-for-offer-from-sibling`",
"Target optionally uses capability that was not available",
"`/root/routing-tests/offers-to-children-unavailable-but-optional` tried to offer",
"from its child `#child-that-doesnt-expose`",
"`#child-that-doesnt-expose` does not expose `fidl.test.components.Trigger`",
]],
);
treasure.insert(
"routing-tests/offers-to-children-unavailable/child-open-unrequested".to_string(),
vec![vec![
"No capability available",
"fidl.test.components.Trigger",
"/root/routing-tests/offers-to-children-unavailable/child-open-unrequested",
"`use` declaration",
]],
);
treasure.insert(
"routing-tests/offers-to-children-unavailable-but-optional/child-open-unrequested".to_string(),
vec![vec![
"No capability available",
"fidl.test.components.Trigger",
"/root/routing-tests/offers-to-children-unavailable-but-optional/child-open-unrequested",
"`use` declaration",
]],
);
if let Ok(mut results) = reader.snapshot_then_subscribe::<Logs>() {
while let Some(Ok(log_record)) = results.next().await {
if let Some(log_str) = log_record.msg() {
info!("Log from {}: {}", log_record.moniker, log_str);
match treasure.get_mut(&log_record.moniker) {
None => non_matching_logs.push(log_record),
Some(log_fingerprints) => {
let removed = {
let print_count = log_fingerprints.len();
log_fingerprints.retain(|fingerprint| {
// If all the part of the fingerprint match, remove
// the fingerprint, otherwise keep it.
let has_all_features =
fingerprint.iter().all(|feature| log_str.contains(feature));
!has_all_features
});
print_count != log_fingerprints.len()
};
// If there are no more fingerprint sets for this
// component, remove it
if log_fingerprints.is_empty() {
treasure.remove(&log_record.moniker);
}
// If we didn't remove any fingerprints, this log didn't
// match anything, so push it into the non-matching logs.
if !removed {
non_matching_logs.push(log_record);
}
if treasure.is_empty() {
return;
}
}
}
}
}
}
panic!(
"One or more logs were not found, remaining fingerprints: {:?}\n\n
These log records were read, but did not match any fingerprints: {:?}",
treasure, non_matching_logs
);
}