fuchsia_triage/plugins/
routing.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use super::helpers::analyze_logs;
6use super::Plugin;
7use crate::act::Action;
8use crate::metrics::fetch::FileDataFetcher;
9use regex::Regex;
10
11pub struct RoutingErrorsPlugin {}
12
13impl Plugin for RoutingErrorsPlugin {
14    fn name(&self) -> &'static str {
15        "routing_errors"
16    }
17
18    fn display_name(&self) -> &'static str {
19        "Routing Errors"
20    }
21
22    fn run_structured(&self, inputs: &FileDataFetcher<'_>) -> Vec<Action> {
23        let mut results = Vec::new();
24
25        let re = Regex::new(r".*\[([^:]+):[0-9]+\] ERROR.*Required protocol `([^`]+)` was not available for target component `([^`]+)`.*").expect("regex compilation failed");
26        analyze_logs(inputs, re, |mut pattern_match| {
27            let (moniker, protocol, name): (&str, &str, &str) =
28                match (pattern_match.pop(), pattern_match.pop(), pattern_match.pop()) {
29                    (Some(moniker), Some(protocol), Some(name)) => {
30                        (moniker.into(), protocol.into(), name.into())
31                    }
32                    _ => {
33                        results.push(Action::new_synthetic_error(
34                            "[DEBUG: BAD DATA] Routing Errors plugin encountered a bug analyzing \
35                             log line, capture group missing"
36                                .to_string(),
37                            "Diagnostics>Triage".to_string(),
38                        ));
39                        return;
40                    }
41                };
42            if pattern_match.is_empty() {
43                results.push(Action::new_synthetic_error(
44                    "[DEBUG: BAD DATA] Routing Errors plugin encountered a bug analyzing log \
45                     line, capture group missing"
46                        .to_string(),
47                    "Diagnostics>Triage".to_string(),
48                ));
49                return;
50            }
51            let log_line: &str = pattern_match.remove(0).into();
52            results.push(Action::new_synthetic_warning(format!(
53                "[WARNING]: Error routing capability \"{}\" to component identified as \"{}\" \
54                 with moniker \"{}\". Original error log:\n{}",
55                protocol, name, moniker, log_line
56            )));
57        });
58        results
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::RoutingErrorsPlugin;
65    use crate::metrics::fetch::{FileDataFetcher, TextFetcher};
66    use crate::plugins::Plugin;
67
68    #[fuchsia::test]
69    fn test_routing_errors() {
70        let expected_output = vec![
71            "[WARNING]: Error routing capability \
72        \"fidl.examples.routing.echo.Echo\" to component identified as \"echo_client\" \
73        with moniker \"/bootstrap/echo/echo_client\". Original error log:\n[00017.480623]\
74        [1150][1253][echo_client:0] ERROR: Required protocol `fidl.examples.routing.echo.Echo` \
75        was not available for target component `/bootstrap/echo/echo_client`\
76        : A `use from parent` declaration was found at `/bootstrap/echo/echo_client` for \
77        `fidl.examples.routing.echo.Echo`, but no matching `offer` declaration was found in the \
78        parent"
79                .to_string(),
80            "[WARNING]: Error routing capability \
81        \"foo.bar.Baz\" to component identified as \"foobar\" \
82        with moniker \"/bootstrap/foobar\". Original error log:\n[12471.623480]\
83        [782][9443][foobar:345] ERROR: Required protocol `foo.bar.Baz` \
84        was not available for target component `/bootstrap/foobar`: A `use from parent` \
85        declaration was found at `/bootstrap/foobar` for `foo.bar.Baz`, but no matching \
86        `offer` declaration was found in the parent"
87                .to_string(),
88        ];
89
90        let fetcher: TextFetcher = r#"
91[00017.480623][1150][1253][echo_client:0] ERROR: Required protocol `fidl.examples.routing.echo.Echo` was not available for target component `/bootstrap/echo/echo_client`: A `use from parent` declaration was found at `/bootstrap/echo/echo_client` for `fidl.examples.routing.echo.Echo`, but no matching `offer` declaration was found in the parent
92[12471.623480][782][9443][foobar:345] ERROR: Required protocol `foo.bar.Baz` was not available for target component `/bootstrap/foobar`: A `use from parent` declaration was found at `/bootstrap/foobar` for `foo.bar.Baz`, but no matching `offer` declaration was found in the parent
93"#.into();
94
95        let diagnostics_data = Vec::new();
96        let mut plugin_input = FileDataFetcher::new(&diagnostics_data);
97        plugin_input.syslog = &fetcher;
98        assert_eq!(RoutingErrorsPlugin {}.run(&plugin_input).warnings, expected_output);
99    }
100
101    #[fuchsia::test]
102    fn test_no_match_routing_error() {
103        let expected_output: Vec<String> = vec![];
104
105        let fetcher: TextFetcher = r#"
106[00017.480623][1150][1253][component manager] ERROR: Required protocol `fidl.examples.routing.echo.Echo` was not available for target component `/bootstrap/echo/echo_client`: A `use from parent` declaration was found at `/bootstrap/echo/echo_client` for `fidl.examples.routing.echo.Echo`, but no matching `offer` declaration was found in the parent
107"#.into();
108
109        let diagnostics_data = Vec::new();
110        let mut plugin_input = FileDataFetcher::new(&diagnostics_data);
111        plugin_input.syslog = &fetcher;
112        assert_eq!(RoutingErrorsPlugin {}.run(&plugin_input).warnings, expected_output);
113    }
114}