-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcli.cc
156 lines (135 loc) · 5.47 KB
/
cli.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* Copyright 2019 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "hardware_verifier/cli.h"
#include <iostream>
#include <sstream>
#include <string>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/optional.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/json_util.h>
#include <runtime_probe/proto_bindings/runtime_probe.pb.h>
#include "hardware_verifier/hardware_verifier.pb.h"
#include "hardware_verifier/hw_verification_spec_getter_impl.h"
#include "hardware_verifier/observer.h"
#include "hardware_verifier/probe_result_getter_impl.h"
#include "hardware_verifier/verifier_impl.h"
namespace hardware_verifier {
namespace {
base::Optional<std::string> OutputInTextFormat(
HwVerificationReport hw_verification_report, bool pii) {
std::stringstream ss;
const auto generic_device_info = hw_verification_report.generic_device_info();
hw_verification_report.clear_generic_device_info();
// Output the AVL qualification status in JSON format.
auto json_print_opts = google::protobuf::util::JsonPrintOptions();
json_print_opts.add_whitespace = true;
json_print_opts.always_print_primitive_fields = true;
std::string json_output_data;
const auto convert_status = google::protobuf::util::MessageToJsonString(
hw_verification_report, &json_output_data, json_print_opts);
if (!convert_status.ok()) {
LOG(ERROR) << "Failed to output the qualification report in JSON: "
<< convert_status.ToString() << ".";
return base::nullopt;
}
ss << "[Component Qualification Status]\n" << json_output_data;
if (pii) {
// Output the generic device info in prototxt format.
ss << "\n[Generic Device Info]\n";
// Enclose google::protobuf::io::OstreamOutputStream in another nested
// scope so that its data will be flushed while being destroyed.
google::protobuf::io::OstreamOutputStream ostream_output_stream{&ss};
if (!google::protobuf::TextFormat::Print(generic_device_info,
&ostream_output_stream)) {
LOG(ERROR)
<< "Failed to output the generic device info in prototxt format.";
return base::nullopt;
}
}
return ss.str();
}
} // namespace
CLI::CLI()
: pr_getter_(std::make_unique<ProbeResultGetterImpl>()),
vp_getter_(std::make_unique<HwVerificationSpecGetterImpl>()),
verifier_(std::make_unique<VerifierImpl>()),
output_stream_(&std::cout) {}
CLIVerificationResult CLI::Run(const std::string& probe_result_file,
const std::string& hw_verification_spec_file,
const CLIOutputFormat output_format,
bool pii) {
LOG(INFO) << "Get the verification payload.";
base::Optional<HwVerificationSpec> hw_verification_spec;
if (hw_verification_spec_file.empty()) {
hw_verification_spec = vp_getter_->GetDefault();
} else {
hw_verification_spec =
vp_getter_->GetFromFile(base::FilePath(hw_verification_spec_file));
}
if (!hw_verification_spec) {
return CLIVerificationResult::kInvalidHwVerificationSpecFile;
}
LOG(INFO) << "Get the probe result.";
base::Optional<runtime_probe::ProbeResult> probe_result;
auto observer = Observer::GetInstance();
if (probe_result_file.empty()) {
observer->StartTimer(hardware_verifier::kMetricTimeToProbe);
probe_result = pr_getter_->GetFromRuntimeProbe();
observer->StopTimer(hardware_verifier::kMetricTimeToProbe);
if (!probe_result) {
return CLIVerificationResult::kProbeFail;
}
} else {
probe_result = pr_getter_->GetFromFile(base::FilePath(probe_result_file));
if (!probe_result) {
return CLIVerificationResult::kInvalidProbeResultFile;
}
}
LOG(INFO) << "Verify the probe result by the verification payload.";
const auto verifier_result =
verifier_->Verify(probe_result.value(), hw_verification_spec.value());
if (!verifier_result) {
return CLIVerificationResult::kProbeResultHwVerificationSpecMisalignment;
}
auto hw_verification_report = verifier_result.value();
if (!pii) {
// Remove PII data.
for (auto& mutable_component :
*(hw_verification_report.mutable_found_component_infos())) {
mutable_component.clear_component_uuid();
}
hw_verification_report.clear_generic_device_info();
}
LOG(INFO) << "Output the report.";
switch (output_format) {
case CLIOutputFormat::kProtoBin: {
std::string s;
if (!hw_verification_report.SerializeToString(&s)) {
return CLIVerificationResult::kUnknownError;
}
LOG(INFO) << "Output the report in protobuf binary format, " << s.size()
<< "bytes.";
*output_stream_ << s;
break;
}
case CLIOutputFormat::kText: {
auto output_data = OutputInTextFormat(hw_verification_report, pii);
if (!output_data.has_value()) {
return CLIVerificationResult::kUnknownError;
}
LOG(INFO) << "Output the report in text format:";
LOG(INFO) << output_data.value();
*output_stream_ << output_data.value();
}
}
LOG(INFO) << "Send to Observer.";
observer->RecordHwVerificationReport(hw_verification_report);
return (hw_verification_report.is_compliant() ? CLIVerificationResult::kPass
: CLIVerificationResult::kFail);
}
} // namespace hardware_verifier