blob: ee281540ecd12fb42cb45824b13d25ec9fb7dc34 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "oobe_config/rollback_cleanup.h"
#include <memory>
#include <string>
#include <utility>
#include <base/test/scoped_chromeos_version_info.h>
#include <base/version.h>
#include <gtest/gtest.h>
#include <libhwsec/backend/mock_backend.h>
#include <libhwsec/factory/tpm2_simulator_factory_for_test.h>
#include <libhwsec/structures/space.h>
#include <metrics/structured/event_base.h>
#include <metrics/structured/mock_recorder.h>
#include <metrics/structured/recorder_singleton.h>
#include <metrics/structured_events.h>
#include "oobe_config/filesystem/file_handler_for_testing.h"
#include "oobe_config/metrics/enterprise_rollback_metrics_handler_for_testing.h"
namespace oobe_config {
namespace {
const char kDeviceVersionM108LsbRelease[] = "15183.1.2";
const base::Version kDeviceVersionM108("15183.1.2");
const base::Version kTargetVersionM107("15117.0.0");
constexpr uint32_t kRollbackSpaceIndex = 0x100e;
constexpr uint32_t kRollbackSpaceSize = 32;
// Random data to write to rollback files.
const std::string data(128, 0x66);
} // namespace
class RollbackCleanupTest : public testing::Test {
protected:
void SetUp() override {
file_handler_.CreateDefaultExistingPaths();
hwsec_oobe_config_ = hwsec_factory_.GetOobeConfigFrontend();
// Set mock recorder for structured metrics.
auto recorder = std::make_unique<metrics::structured::MockRecorder>();
recorder_ = recorder.get();
metrics::structured::RecorderSingleton::GetInstance()->SetRecorderForTest(
std::move(recorder));
}
void TearDown() override {
// Free recorder to ensure the expectations are run and avoid leaks.
metrics::structured::RecorderSingleton::GetInstance()
->DestroyRecorderForTest();
}
bool CreateRollbackSpace() {
return hwsec_factory_.GetFakeTpmNvramForTest().DefinePlatformCreateSpace(
kRollbackSpaceIndex, kRollbackSpaceSize) &&
hwsec_oobe_config_->IsRollbackSpaceReady().ok();
}
void ExpectRollbackCompletedMetricRecord(int times) {
EXPECT_CALL(*recorder_,
Record(testing::Property(
&metrics::structured::EventBase::name_hash,
metrics::structured::events::rollback_enterprise::
RollbackCompleted::kEventNameHash)))
.Times(times);
}
FileHandlerForTesting file_handler_;
EnterpriseRollbackMetricsHandlerForTesting metrics_handler_;
metrics::structured::MockRecorder* recorder_;
hwsec::Tpm2SimulatorFactoryForTest hwsec_factory_;
std::unique_ptr<const hwsec::OobeConfigFrontend> hwsec_oobe_config_;
// Need to keep the variable around for the test version to be read. These
// tests do not verify the version is read because the reporting works anyway
// but this is the way.
base::test::ScopedChromeOSVersionInfo version_info_{
base::StringPrintf("CHROMEOS_RELEASE_VERSION=%s",
kDeviceVersionM108LsbRelease),
base::Time()};
};
TEST_F(RollbackCleanupTest, DoNotRemoveAnyRollbackDataIfOobeIsNotCompleted) {
EXPECT_TRUE(file_handler_.WriteOpensslEncryptedRollbackData(data));
EXPECT_TRUE(file_handler_.WriteTpmEncryptedRollbackData(data));
EXPECT_TRUE(file_handler_.WriteDecryptedRollbackData(data));
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
EXPECT_TRUE(file_handler_.HasOpensslEncryptedRollbackData());
EXPECT_TRUE(file_handler_.HasTpmEncryptedRollbackData());
EXPECT_TRUE(file_handler_.HasDecryptedRollbackData());
}
TEST_F(RollbackCleanupTest, RemoveRollbackDataIfOobeIsCompleted) {
EXPECT_TRUE(file_handler_.CreateOobeCompletedFlag());
EXPECT_TRUE(file_handler_.WriteOpensslEncryptedRollbackData(data));
EXPECT_TRUE(file_handler_.WriteTpmEncryptedRollbackData(data));
EXPECT_TRUE(file_handler_.WriteDecryptedRollbackData(data));
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
EXPECT_FALSE(file_handler_.HasOpensslEncryptedRollbackData());
EXPECT_FALSE(file_handler_.HasTpmEncryptedRollbackData());
EXPECT_FALSE(file_handler_.HasDecryptedRollbackData());
}
TEST_F(RollbackCleanupTest, ClearTpmSpaceIfOobeIsCompleted) {
EXPECT_TRUE(CreateRollbackSpace());
EXPECT_TRUE(file_handler_.CreateOobeCompletedFlag());
const brillo::Blob zero(kRollbackSpaceSize);
EXPECT_CALL(hwsec_factory_.GetMockBackend().GetMock().storage,
Store(hwsec::Space::kEnterpriseRollback, zero))
.Times(1);
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
}
TEST_F(RollbackCleanupTest, DoNotClearTpmSpaceIfOobeIsNotCompleted) {
EXPECT_TRUE(CreateRollbackSpace());
const brillo::Blob zero(kRollbackSpaceSize);
EXPECT_CALL(hwsec_factory_.GetMockBackend().GetMock().storage,
Store(hwsec::Space::kEnterpriseRollback, zero))
.Times(0);
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
}
TEST_F(RollbackCleanupTest,
DoNotCleanupNonStaleMetricsFileIfOobeIsNotCompleted) {
ExpectRollbackCompletedMetricRecord(/*times=*/0);
EXPECT_TRUE(metrics_handler_.EnableMetrics());
EXPECT_TRUE(metrics_handler_.StartTrackingRollback(kDeviceVersionM108,
kTargetVersionM107));
EXPECT_TRUE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
EXPECT_TRUE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
}
TEST_F(RollbackCleanupTest,
DoNotRemoveMetricsFileIfOobeIsCompletedButNoPrecedingRollback) {
ExpectRollbackCompletedMetricRecord(/*times=*/0);
EXPECT_TRUE(metrics_handler_.EnableMetrics());
EXPECT_TRUE(metrics_handler_.StartTrackingRollback(kDeviceVersionM108,
kTargetVersionM107));
EXPECT_TRUE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
EXPECT_TRUE(file_handler_.CreateOobeCompletedFlag());
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
EXPECT_TRUE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
}
TEST_F(RollbackCleanupTest,
RemoveMetricsFileIfOobeIsCompletedAndPrecedingOpensslRollback) {
ExpectRollbackCompletedMetricRecord(/*times=*/1);
EXPECT_TRUE(metrics_handler_.EnableMetrics());
EXPECT_TRUE(metrics_handler_.StartTrackingRollback(kDeviceVersionM108,
kTargetVersionM107));
EXPECT_TRUE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
EXPECT_TRUE(file_handler_.CreateOobeCompletedFlag());
EXPECT_TRUE(file_handler_.WriteOpensslEncryptedRollbackData(data));
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
EXPECT_FALSE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
}
TEST_F(RollbackCleanupTest,
RemoveMetricsFileIfOobeIsCompletedAndPrecedingTpmRollback) {
ExpectRollbackCompletedMetricRecord(/*times=*/1);
EXPECT_TRUE(metrics_handler_.EnableMetrics());
EXPECT_TRUE(metrics_handler_.StartTrackingRollback(kDeviceVersionM108,
kTargetVersionM107));
EXPECT_TRUE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
EXPECT_TRUE(file_handler_.CreateOobeCompletedFlag());
EXPECT_TRUE(file_handler_.WriteTpmEncryptedRollbackData(data));
RollbackCleanup(&file_handler_, &metrics_handler_, &hwsec_factory_);
EXPECT_FALSE(metrics_handler_.IsTrackingForDeviceVersion(kDeviceVersionM108));
}
} // namespace oobe_config