blob: 56197a72bef708024f458a9c7bf1c055e0c91b78 [file] [log] [blame]
/* 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 <memory>
#include <optional>
#include <sstream>
#include <utility>
#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>
#include <runtime_probe/proto_bindings/runtime_probe.pb.h>
#include "hardware_verifier/cli.h"
#include "hardware_verifier/hardware_verifier.pb.h"
#include "hardware_verifier/hw_verification_report_getter.h"
#include "hardware_verifier/mock_hw_verification_report_getter.h"
#include "hardware_verifier/observer.h"
#include "hardware_verifier/test_utils.h"
namespace hardware_verifier {
namespace {
using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;
using ReportGetterErrorCode = HwVerificationReportGetter::ErrorCode;
class CLIForTesting : public CLI {
public:
CLIForTesting(std::unique_ptr<HwVerificationReportGetter> vr_getter,
std::ostream* output_stream)
: CLI(std::move(vr_getter), output_stream) {}
};
class CLITest : public testing::Test {
protected:
void SetUp() override {
auto mock_vr_getter =
std::make_unique<NiceMock<MockHwVerificationReportGetter>>();
auto mock_metrics = std::make_unique<NiceMock<MetricsLibraryMock>>();
mock_vr_getter_ = mock_vr_getter.get();
output_stream_.reset(new std::ostringstream());
mock_metrics_ = mock_metrics.get();
cli_.reset(
new CLIForTesting(std::move(mock_vr_getter), output_stream_.get()));
Observer::GetInstance()->SetMetricsLibrary(std::move(mock_metrics));
// Set everything works by default.
HwVerificationReport vr;
vr.set_is_compliant(true);
ON_CALL(*mock_vr_getter_, Get(_, _, _))
.WillByDefault(
DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
Return(vr)));
}
void TearDown() override {
// We have to clear the MetricsLibraryMock manually, because
// Observer::GetInstance() object is a singleton, which won't be destroyed
// across the tests.
Observer::GetInstance()->SetMetricsLibrary(nullptr);
}
MockHwVerificationReportGetter* mock_vr_getter_;
std::unique_ptr<std::ostringstream> output_stream_;
MetricsLibraryMock* mock_metrics_;
// The object to be tested.
std::unique_ptr<CLIForTesting> cli_;
};
TEST_F(CLITest, TestOutput) {
HwVerificationReport vr;
vr.set_is_compliant(true);
ON_CALL(*mock_vr_getter_, Get(_, _, _))
.WillByDefault(
DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
Return(vr)));
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kProtoBin, true),
CLIVerificationResult::kPass);
HwVerificationReport result;
EXPECT_TRUE(result.ParseFromString(output_stream_->str()));
EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(result, vr));
// For human readable format, only check if there's something printed.
*output_stream_ = std::ostringstream();
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, false),
CLIVerificationResult::kPass);
EXPECT_FALSE(output_stream_->str().empty());
*output_stream_ = std::ostringstream();
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, true),
CLIVerificationResult::kPass);
EXPECT_FALSE(output_stream_->str().empty());
}
TEST_F(CLITest, TestGetReportFailed) {
ON_CALL(*mock_vr_getter_, Get(_, _, _))
.WillByDefault(
DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeProbeFail),
Return(std::nullopt)));
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kProtoBin, true),
CLIVerificationResult::kProbeFail);
}
TEST_F(CLITest, TestMissingPayloads) {
ON_CALL(*mock_vr_getter_, Get(_, _, _))
.WillByDefault(DoAll(
SetArgPointee<2>(ReportGetterErrorCode::
kErrorCodeMissingDefaultHwVerificationSpecFile),
Return(std::nullopt)));
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kProtoBin, true),
CLIVerificationResult::kSkippedVerification);
}
TEST_F(CLITest, TestVerifyReportSample1) {
const auto& path = GetTestDataPath()
.Append("verifier_impl_sample_data")
.Append("expect_hw_verification_report_1.prototxt");
const auto& vr = LoadHwVerificationReport(path);
ON_CALL(*mock_vr_getter_, Get(_, _, _))
.WillByDefault(
DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
Return(vr)));
// This is for recording running time.
EXPECT_CALL(
*mock_metrics_,
SendBoolToUMA("ChromeOS.HardwareVerifier.Report.IsCompliant", true));
// This is for recording qualification status of each components.
EXPECT_CALL(*mock_metrics_, SendEnumToUMA(_, _, _)).Times(AtLeast(3));
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, false),
CLIVerificationResult::kPass);
}
TEST_F(CLITest, TestVerifyReportSample2) {
const auto& path = GetTestDataPath()
.Append("verifier_impl_sample_data")
.Append("expect_hw_verification_report_2.prototxt");
const auto& vr = LoadHwVerificationReport(path);
ON_CALL(*mock_vr_getter_, Get(_, _, _))
.WillByDefault(
DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
Return(vr)));
// This is for recording running time.
EXPECT_CALL(
*mock_metrics_,
SendBoolToUMA("ChromeOS.HardwareVerifier.Report.IsCompliant", false));
// This is for recording qualification status of each components.
EXPECT_CALL(*mock_metrics_, SendEnumToUMA(_, _, _)).Times(AtLeast(2));
EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, false),
CLIVerificationResult::kFail);
}
} // namespace
} // namespace hardware_verifier