blob: 0f947788835e875a8fa387647c335d7550a5b9c2 [file] [log] [blame]
Yong Hongcb45e082019-01-30 18:55:16 +08001/* Copyright 2019 The Chromium OS 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 */
5
6#include "hardware_verifier/cli.h"
7
8#include <iostream>
Yong Hong8d168b02019-05-23 19:54:23 +08009#include <string>
Yong Hongcb45e082019-01-30 18:55:16 +080010
11#include <base/files/file_path.h>
12#include <base/logging.h>
13#include <base/optional.h>
14#include <google/protobuf/io/zero_copy_stream_impl.h>
Yong Hong8d168b02019-05-23 19:54:23 +080015#include <google/protobuf/util/json_util.h>
Yong Hongcb45e082019-01-30 18:55:16 +080016#include <runtime_probe/proto_bindings/runtime_probe.pb.h>
17
18#include "hardware_verifier/hardware_verifier.pb.h"
Yong Hongf4872de2019-01-30 19:04:18 +080019#include "hardware_verifier/hw_verification_spec_getter_impl.h"
Yong Hong5d7d6d92019-01-30 19:07:36 +080020#include "hardware_verifier/probe_result_getter_impl.h"
Yong Hongcc481892019-05-16 20:26:05 +080021#include "hardware_verifier/verifier_impl.h"
Yong Hongcb45e082019-01-30 18:55:16 +080022
23namespace hardware_verifier {
24
25// TODO(yhong): Link to the correct class once they are implemented.
26CLI::CLI()
Yong Hong5d7d6d92019-01-30 19:07:36 +080027 : pr_getter_(std::make_unique<ProbeResultGetterImpl>()),
Yong Hongf4872de2019-01-30 19:04:18 +080028 vp_getter_(std::make_unique<HwVerificationSpecGetterImpl>()),
Yong Hongcc481892019-05-16 20:26:05 +080029 verifier_(std::make_unique<VerifierImpl>()),
Yong Hongcb45e082019-01-30 18:55:16 +080030 output_stream_(&std::cout) {}
31
32CLIVerificationResult CLI::Run(const std::string& probe_result_file,
33 const std::string& hw_verification_spec_file,
34 const CLIOutputFormat output_format) {
35 LOG(INFO) << "Get the probe result.";
36 base::Optional<runtime_probe::ProbeResult> probe_result;
37 if (probe_result_file.empty()) {
38 probe_result = pr_getter_->GetFromRuntimeProbe();
39 if (!probe_result) {
40 return CLIVerificationResult::kProbeFail;
41 }
42 } else {
43 probe_result = pr_getter_->GetFromFile(base::FilePath(probe_result_file));
44 if (!probe_result) {
45 return CLIVerificationResult::kInvalidProbeResultFile;
46 }
47 }
48
49 LOG(INFO) << "Get the verification payload.";
50 base::Optional<HwVerificationSpec> hw_verification_spec;
51 if (hw_verification_spec_file.empty()) {
52 hw_verification_spec = vp_getter_->GetDefault();
53 } else {
54 hw_verification_spec =
55 vp_getter_->GetFromFile(base::FilePath(hw_verification_spec_file));
56 }
57 if (!hw_verification_spec) {
58 return CLIVerificationResult::kInvalidHwVerificationSpecFile;
59 }
60
61 LOG(INFO) << "Verify the probe result by the verification payload.";
62 const auto verifier_result =
63 verifier_->Verify(probe_result.value(), hw_verification_spec.value());
64 if (!verifier_result) {
65 return CLIVerificationResult::kProbeResultHwVerificationSpecMisalignment;
66 }
67 const auto hw_verification_report = verifier_result.value();
68
69 LOG(INFO) << "Output the report.";
70 switch (output_format) {
71 case CLIOutputFormat::kProtoBin:
72 if (!hw_verification_report.SerializeToOstream(output_stream_)) {
73 return CLIVerificationResult::kUnknownError;
74 }
75 break;
Yong Hong8d168b02019-05-23 19:54:23 +080076 case CLIOutputFormat::kJSON:
77 auto json_print_opts = google::protobuf::util::JsonPrintOptions();
78 json_print_opts.add_whitespace = true;
79 json_print_opts.always_print_primitive_fields = true;
80 std::string output_data;
81 const auto convert_status = google::protobuf::util::MessageToJsonString(
82 hw_verification_report, &output_data, json_print_opts);
83 if (!convert_status.ok()) {
84 LOG(ERROR) << "Failed to transform the report into JSON format: "
85 << convert_status.ToString() << ".";
Yong Hongcb45e082019-01-30 18:55:16 +080086 return CLIVerificationResult::kUnknownError;
87 }
Yong Hong8d168b02019-05-23 19:54:23 +080088 *output_stream_ << output_data;
Yong Hongcb45e082019-01-30 18:55:16 +080089 break;
90 }
91
92 return (hw_verification_report.is_compliant() ? CLIVerificationResult::kPass
93 : CLIVerificationResult::kFail);
94}
95
96} // namespace hardware_verifier