blob: 6f8e4b88dbcae1ba11a5522a53f9146fcdcd1b58 [file] [log] [blame]
/* Copyright 2021 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/hw_verification_report_getter_impl.h"
#include <memory>
#include <utility>
#include <base/files/file_path.h>
#include <base/optional.h>
#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/hw_verification_report_getter.h"
#include "hardware_verifier/hw_verification_spec_getter.h"
#include "hardware_verifier/observer.h"
#include "hardware_verifier/probe_result_getter.h"
#include "hardware_verifier/verifier.h"
namespace hardware_verifier {
namespace {
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;
using ReportGetterErrorCode = HwVerificationReportGetter::ErrorCode;
class MockProbeResultGetter : public ProbeResultGetter {
public:
MOCK_METHOD(base::Optional<runtime_probe::ProbeResult>,
GetFromRuntimeProbe,
(),
(const, override));
MOCK_METHOD(base::Optional<runtime_probe::ProbeResult>,
GetFromFile,
(const base::FilePath& file_path),
(const, override));
};
class MockHwVerificationSpecGetter : public HwVerificationSpecGetter {
public:
MOCK_METHOD(base::Optional<HwVerificationSpec>,
GetDefault,
(),
(const, override));
MOCK_METHOD(base::Optional<HwVerificationSpec>,
GetFromFile,
(const base::FilePath& file_path),
(const, override));
};
class MockVerifier : public Verifier {
public:
MOCK_METHOD(base::Optional<HwVerificationReport>,
Verify,
(const runtime_probe::ProbeResult& probe_result,
const HwVerificationSpec& hw_verification_spec),
(const, override));
};
class HwVerificationReportGetterImplForTesting
: public HwVerificationReportGetterImpl {
public:
explicit HwVerificationReportGetterImplForTesting(
std::unique_ptr<ProbeResultGetter> pr_getter,
std::unique_ptr<HwVerificationSpecGetter> vs_getter,
std::unique_ptr<Verifier> verifier)
: HwVerificationReportGetterImpl(
std::move(pr_getter), std::move(vs_getter), std::move(verifier)) {}
};
class HwVerificationReportGetterImplTest : public testing::Test {
protected:
void SetUp() override {
auto mock_pr_getter = std::make_unique<NiceMock<MockProbeResultGetter>>();
auto mock_vs_getter =
std::make_unique<NiceMock<MockHwVerificationSpecGetter>>();
auto mock_verifier = std::make_unique<NiceMock<MockVerifier>>();
auto mock_metrics = std::make_unique<NiceMock<MetricsLibraryMock>>();
mock_pr_getter_ = mock_pr_getter.get();
mock_vs_getter_ = mock_vs_getter.get();
mock_verifier_ = mock_verifier.get();
mock_metrics_ = mock_metrics.get();
vr_getter_.reset(new HwVerificationReportGetterImplForTesting(
std::move(mock_pr_getter), std::move(mock_vs_getter),
std::move(mock_verifier)));
Observer::GetInstance()->SetMetricsLibrary(std::move(mock_metrics));
// set everything works by default.
HwVerificationReport positive_report;
positive_report.set_is_compliant(true);
ON_CALL(*mock_pr_getter_, GetFromRuntimeProbe())
.WillByDefault(Return(runtime_probe::ProbeResult()));
ON_CALL(*mock_vs_getter_, GetDefault())
.WillByDefault(Return(HwVerificationSpec()));
ON_CALL(*mock_verifier_, Verify(_, _))
.WillByDefault(Return(positive_report));
}
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);
}
std::unique_ptr<HwVerificationReportGetterImplForTesting> vr_getter_;
MockProbeResultGetter* mock_pr_getter_;
MockHwVerificationSpecGetter* mock_vs_getter_;
MockVerifier* mock_verifier_;
MetricsLibraryMock* mock_metrics_;
};
TEST_F(HwVerificationReportGetterImplTest, TestBasicFlow) {
HwVerificationReport vr;
vr.set_is_compliant(true);
ON_CALL(*mock_verifier_, Verify(_, _)).WillByDefault(Return(vr));
ReportGetterErrorCode error_code;
EXPECT_CALL(*mock_metrics_, SendToUMA(_, _, _, _, _)).Times(1);
auto result = vr_getter_->Get("", "", &error_code);
EXPECT_TRUE(result);
EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(*result, vr));
EXPECT_EQ(error_code, ReportGetterErrorCode::kErrorCodeNoError);
EXPECT_CALL(*mock_metrics_, SendToUMA(_, _, _, _, _)).Times(1);
result = vr_getter_->Get("", "", nullptr);
EXPECT_TRUE(result);
EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(*result, vr));
}
TEST_F(HwVerificationReportGetterImplTest, TestHandleWaysToGetProbeResults) {
ReportGetterErrorCode error_code;
ON_CALL(*mock_pr_getter_, GetFromRuntimeProbe())
.WillByDefault(Return(base::nullopt));
EXPECT_CALL(*mock_metrics_, SendToUMA(_, _, _, _, _)).Times(1);
EXPECT_FALSE(vr_getter_->Get("", "", &error_code));
EXPECT_EQ(error_code, ReportGetterErrorCode::kErrorCodeProbeFail);
ON_CALL(*mock_pr_getter_, GetFromFile(_))
.WillByDefault(Return(runtime_probe::ProbeResult()));
EXPECT_CALL(*mock_metrics_, SendToUMA(_, _, _, _, _)).Times(0);
EXPECT_TRUE(vr_getter_->Get("path", "", &error_code));
EXPECT_EQ(error_code, ReportGetterErrorCode::kErrorCodeNoError);
ON_CALL(*mock_pr_getter_, GetFromFile(_))
.WillByDefault(Return(base::nullopt));
EXPECT_CALL(*mock_metrics_, SendToUMA(_, _, _, _, _)).Times(0);
EXPECT_FALSE(vr_getter_->Get("path2", "", &error_code));
EXPECT_EQ(error_code,
ReportGetterErrorCode::kErrorCodeInvalidProbeResultFile);
}
TEST_F(HwVerificationReportGetterImplTest,
TestHandleWaysToGetHwVerificationSpec) {
ReportGetterErrorCode error_code;
ON_CALL(*mock_vs_getter_, GetDefault()).WillByDefault(Return(base::nullopt));
EXPECT_FALSE(vr_getter_->Get("", "", &error_code));
EXPECT_EQ(
error_code,
ReportGetterErrorCode::kErrorCodeMissingDefaultHwVerificationSpecFile);
ON_CALL(*mock_vs_getter_, GetFromFile(_))
.WillByDefault(Return(HwVerificationSpec()));
EXPECT_TRUE(vr_getter_->Get("", "path", &error_code));
EXPECT_EQ(error_code, ReportGetterErrorCode::kErrorCodeNoError);
ON_CALL(*mock_vs_getter_, GetFromFile(_))
.WillByDefault(Return(base::nullopt));
EXPECT_FALSE(vr_getter_->Get("", "path2", &error_code));
EXPECT_EQ(error_code,
ReportGetterErrorCode::kErrorCodeInvalidHwVerificationSpecFile);
}
TEST_F(HwVerificationReportGetterImplTest, TestVerifyFail) {
ReportGetterErrorCode error_code;
ON_CALL(*mock_verifier_, Verify(_, _)).WillByDefault(Return(base::nullopt));
EXPECT_FALSE(vr_getter_->Get("", "", &error_code));
EXPECT_EQ(error_code,
ReportGetterErrorCode::
kErrorCodeProbeResultHwVerificationSpecMisalignment);
HwVerificationReport positive_report;
positive_report.set_is_compliant(true);
ON_CALL(*mock_verifier_, Verify(_, _)).WillByDefault(Return(positive_report));
auto result = vr_getter_->Get("", "", &error_code);
EXPECT_TRUE(result);
EXPECT_EQ(error_code, ReportGetterErrorCode::kErrorCodeNoError);
EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
*result, positive_report));
HwVerificationReport negative_report;
negative_report.set_is_compliant(false);
ON_CALL(*mock_verifier_, Verify(_, _)).WillByDefault(Return(negative_report));
result = vr_getter_->Get("", "", &error_code);
EXPECT_TRUE(result);
EXPECT_EQ(error_code, ReportGetterErrorCode::kErrorCodeNoError);
EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
*result, negative_report));
}
} // namespace
} // namespace hardware_verifier