| // Copyright 2020 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "dlcservice/test_utils.h" |
| |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include <base/check.h> |
| #include <base/files/file_path.h> |
| #include <base/files/file_util.h> |
| #include <base/files/scoped_temp_dir.h> |
| #include <base/logging.h> |
| #include <dbus/dlcservice/dbus-constants.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include <imageloader/proto_bindings/imageloader.pb.h> |
| #include <imageloader/dbus-proxy-mocks.h> |
| #if USE_LVM_STATEFUL_PARTITION |
| #include <lvmd/proto_bindings/lvmd.pb.h> |
| // NOLINTNEXTLINE(build/include_alpha) |
| #include <lvmd/dbus-proxy-mocks.h> |
| #endif // USE_LVM_STATEFUL_PARTITION |
| #include <metrics/metrics_library_mock.h> |
| #include <update_engine/dbus-constants.h> |
| #include <update_engine/dbus-proxy-mocks.h> |
| |
| #include "dlcservice/boot/boot_slot.h" |
| #include "dlcservice/dlc.h" |
| #include "dlcservice/metrics.h" |
| #if USE_LVM_STATEFUL_PARTITION |
| #include "dlcservice/lvm/mock_lvmd_proxy_wrapper.h" |
| #endif // USE_LVM_STATEFUL_PARTITION |
| #include "dlcservice/system_state.h" |
| #include "dlcservice/utils.h" |
| |
| using std::string; |
| using std::vector; |
| using testing::_; |
| using testing::DoAll; |
| using testing::Return; |
| using testing::SetArgPointee; |
| using testing::StrictMock; |
| |
| namespace dlcservice { |
| |
| const char kFirstDlc[] = "first-dlc"; |
| const char kSecondDlc[] = "second-dlc"; |
| const char kThirdDlc[] = "third-dlc"; |
| const char kFourthDlc[] = "fourth-dlc"; |
| const char kPackage[] = "package"; |
| const char kDefaultOmahaUrl[] = "http://foo-url"; |
| |
| BaseTest::BaseTest() { |
| // Create mocks with default behaviors. |
| #if USE_LVM_STATEFUL_PARTITION |
| mock_lvmd_proxy_wrapper_ = |
| std::make_unique<StrictMock<MockLvmdProxyWrapper>>(); |
| mock_lvmd_proxy_wrapper_ptr_ = mock_lvmd_proxy_wrapper_.get(); |
| #endif // USE_LVM_STATEFUL_PARTITION |
| |
| mock_image_loader_proxy_ = |
| std::make_unique<StrictMock<ImageLoaderProxyMock>>(); |
| mock_image_loader_proxy_ptr_ = mock_image_loader_proxy_.get(); |
| |
| mock_bus_ = new dbus::MockBus(dbus::Bus::Options{}); |
| mock_update_engine_object_proxy_ = new dbus::MockObjectProxy( |
| mock_bus_.get(), update_engine::kUpdateEngineServiceName, |
| dbus::ObjectPath(update_engine::kUpdateEngineServicePath)); |
| |
| mock_update_engine_proxy_ = |
| std::make_unique<StrictMock<UpdateEngineProxyMock>>(); |
| mock_update_engine_proxy_ptr_ = mock_update_engine_proxy_.get(); |
| |
| mock_boot_slot_ = std::make_unique<MockBootSlot>(); |
| mock_boot_slot_ptr_ = mock_boot_slot_.get(); |
| } |
| |
| void BaseTest::SetUp() { |
| loop_.SetAsCurrent(); |
| |
| SetUpFilesAndDirectories(); |
| |
| auto mock_metrics = std::make_unique<testing::StrictMock<MockMetrics>>(); |
| mock_metrics_ = mock_metrics.get(); |
| |
| auto mock_system_properties = |
| std::make_unique<testing::StrictMock<MockSystemProperties>>(); |
| mock_system_properties_ = mock_system_properties.get(); |
| |
| SystemState::Initialize( |
| #if USE_LVM_STATEFUL_PARTITION |
| std::move(mock_lvmd_proxy_wrapper_), |
| #endif // USE_LVM_STATEFUL_PARTITION |
| std::move(mock_image_loader_proxy_), std::move(mock_update_engine_proxy_), |
| &mock_state_change_reporter_, std::move(mock_boot_slot_), |
| std::move(mock_metrics), std::move(mock_system_properties), |
| manifest_path_, preloaded_content_path_, factory_install_path_, |
| content_path_, prefs_path_, users_path_, verification_file_path_, &clock_, |
| /*for_test=*/true); |
| SystemState::Get()->set_update_engine_service_available(true); |
| } |
| |
| void BaseTest::SetUpFilesAndDirectories() { |
| // Initialize DLC path. |
| CHECK(scoped_temp_dir_.CreateUniqueTempDir()); |
| manifest_path_ = JoinPaths(scoped_temp_dir_.GetPath(), "rootfs"); |
| preloaded_content_path_ = |
| JoinPaths(scoped_temp_dir_.GetPath(), "preloaded_stateful"); |
| factory_install_path_ = |
| JoinPaths(scoped_temp_dir_.GetPath(), "factory_install"); |
| content_path_ = JoinPaths(scoped_temp_dir_.GetPath(), "stateful"); |
| prefs_path_ = JoinPaths(scoped_temp_dir_.GetPath(), "var_lib_dlcservice"); |
| users_path_ = JoinPaths(scoped_temp_dir_.GetPath(), "users"); |
| verification_file_path_ = |
| JoinPaths(scoped_temp_dir_.GetPath(), "verification_file"); |
| mount_path_ = JoinPaths(scoped_temp_dir_.GetPath(), "mount"); |
| base::FilePath mount_root_path = JoinPaths(mount_path_, "root"); |
| base::CreateDirectory(manifest_path_); |
| base::CreateDirectory(preloaded_content_path_); |
| base::CreateDirectory(factory_install_path_); |
| base::CreateDirectory(content_path_); |
| base::CreateDirectory(prefs_path_); |
| base::CreateDirectory(users_path_); |
| base::CreateDirectory(mount_root_path); |
| testdata_path_ = JoinPaths(getenv("SRC"), "testdata"); |
| |
| CHECK(base::WriteFile(verification_file_path_, "verification-value")); |
| |
| // Create DLC manifest sub-directories. |
| for (auto&& id : {kFirstDlc, kSecondDlc, kThirdDlc, kFourthDlc}) { |
| base::CreateDirectory(JoinPaths(manifest_path_, id, kPackage)); |
| base::CopyFile(JoinPaths(testdata_path_, id, kPackage, kManifestName), |
| JoinPaths(manifest_path_, id, kPackage, kManifestName)); |
| } |
| } |
| |
| int64_t GetFileSize(const base::FilePath& path) { |
| int64_t file_size; |
| EXPECT_TRUE(base::GetFileSize(path, &file_size)); |
| return file_size; |
| } |
| |
| base::FilePath BaseTest::SetUpImage(const base::FilePath& root, |
| const DlcId& id) { |
| auto manifest = dlcservice::GetDlcManifest(manifest_path_, id, kPackage); |
| base::FilePath image_path = JoinPaths(root, id, kPackage, kDlcImageFileName); |
| CreateFile(image_path, manifest->size()); |
| EXPECT_TRUE(base::PathExists(image_path)); |
| |
| string data(manifest->size(), '1'); |
| WriteToImage(image_path, data); |
| |
| return image_path; |
| } |
| |
| base::FilePath BaseTest::SetUpDlcPreloadedImage(const DlcId& id) { |
| return SetUpImage(preloaded_content_path_, id); |
| } |
| |
| base::FilePath BaseTest::SetUpDlcFactoryImage(const DlcId& id) { |
| return SetUpImage(factory_install_path_, id); |
| } |
| |
| // Will create |path/|id|/|package|/dlc_[a|b]/dlc.img files. |
| void BaseTest::SetUpDlcWithSlots(const DlcId& id) { |
| auto manifest = dlcservice::GetDlcManifest(manifest_path_, id, kPackage); |
| // Create DLC content sub-directories and empty images. |
| for (const auto& slot : {BootSlot::Slot::A, BootSlot::Slot::B}) { |
| base::FilePath image_path = |
| GetDlcImagePath(content_path_, id, kPackage, slot); |
| CreateFile(image_path, manifest->preallocated_size()); |
| LOG(INFO) << manifest->preallocated_size(); |
| } |
| } |
| |
| void BaseTest::InstallWithUpdateEngine(const vector<string>& ids) { |
| for (const auto& id : ids) { |
| auto manifest = dlcservice::GetDlcManifest(manifest_path_, id, kPackage); |
| base::FilePath image_path = GetDlcImagePath( |
| content_path_, id, kPackage, SystemState::Get()->active_boot_slot()); |
| |
| string data(manifest->size(), '1'); |
| WriteToImage(image_path, data); |
| } |
| } |
| |
| void BaseTest::SetMountPath(const string& mount_path_expected) { |
| ON_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _)) |
| .WillByDefault( |
| DoAll(SetArgPointee<3>(mount_path_expected), Return(true))); |
| } |
| |
| } // namespace dlcservice |