blob: 6543458952e027bfe9e68a83c9651fdd92468b3b [file] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdlib.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <deque>
#include <string>
#include <utility>
#include <vector>
#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/values.h>
#include <gtest/gtest.h>
#include "init/crossystem.h"
#include "init/crossystem_fake.h"
#include "init/startup/chromeos_startup.h"
#include "init/startup/constants.h"
#include "init/startup/factory_mode_mount_helper.h"
#include "init/startup/fake_platform_impl.h"
#include "init/startup/flags.h"
#include "init/startup/mock_platform_impl.h"
#include "init/startup/mount_helper.h"
#include "init/startup/mount_helper_factory.h"
#include "init/startup/platform_impl.h"
#include "init/startup/standard_mount_helper.h"
#include "init/startup/test_mode_mount_helper.h"
using testing::_;
using testing::AnyNumber;
using testing::ByMove;
using testing::Return;
using testing::StrictMock;
namespace startup {
namespace {
constexpr char kTpmFirmwareUpdateCleanup[] =
"usr/sbin/tpm-firmware-update-cleanup";
constexpr char kTpmFirmwareUpdateRequestFlagFile[] =
"unencrypted/preserve/tpm_firmware_update_request";
constexpr char kLsbRelease[] = "lsb-release";
constexpr char kStatefulPartition[] = "mnt/stateful_partition";
constexpr char kProcCmdLine[] = "proc/cmdline";
constexpr char kSysKeyLog[] = "run/create_system_key.log";
constexpr char kMntOptionsFile[] =
"dev_image/factory/init/encstateful_mount_option";
// Helper function to create directory and write to file.
bool CreateDirAndWriteFile(const base::FilePath& path,
const std::string& contents) {
return base::CreateDirectory(path.DirName()) &&
base::WriteFile(path, contents.c_str(), contents.length()) ==
contents.length();
}
void CreateBaseAndSetNames(base::FilePath* base_dir,
base::FilePath* lsb_file,
base::FilePath* stateful) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
*base_dir = temp_dir.GetPath();
*lsb_file = base_dir->Append(kLsbRelease);
*stateful = base_dir->Append(kStatefulPartition);
}
void RestoreconTestFunc(const base::FilePath& path,
const std::vector<base::FilePath>& exclude,
bool is_recursive,
bool set_digests) {
for (auto excl : exclude) {
base::FilePath ex_file = excl.Append("exclude");
CreateDirAndWriteFile(ex_file, "exclude");
}
base::FilePath restore = path.Append("restore");
CreateDirAndWriteFile(restore, "restore");
}
} // namespace
class CrosSystemFakeTest : public ::testing::Test {
protected:
CrosSystemFakeTest() : cros_system_(new CrosSystemFake()) {}
CrosSystemFake* cros_system_;
};
class EarlySetupTest : public ::testing::Test {
protected:
EarlySetupTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir_ = temp_dir_.GetPath();
kernel_debug_ = base_dir_.Append("sys/kernel/debug");
kernel_config_ = base_dir_.Append("sys/kernel/config");
kernel_tracing_ = base_dir_.Append("sys/kernel/tracing");
security_hardening_ = base_dir_.Append(
"usr/share/cros/startup/disable_stateful_security_hardening");
kernel_security_ = base_dir_.Append("sys/kernel/security");
namespaces_ = base_dir_.Append("run/namespaces");
platform_ = new startup::FakePlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir_, base_dir_,
base_dir_, base_dir_, std::unique_ptr<startup::FakePlatform>(platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir_,
base_dir_, true));
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
startup::FakePlatform* platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir_;
base::FilePath kernel_debug_;
base::FilePath kernel_tracing_;
base::FilePath dev_pts_;
base::FilePath dev_shm_;
base::FilePath kernel_config_;
base::FilePath security_hardening_;
base::FilePath kernel_security_;
base::FilePath namespaces_;
};
TEST_F(EarlySetupTest, EarlySetup) {
platform_->SetMountResultForPath(kernel_debug_, "debugfs");
platform_->SetMountResultForPath(kernel_tracing_, "tracefs");
platform_->SetMountResultForPath(kernel_config_, "configfs");
platform_->SetMountResultForPath(kernel_security_, "securityfs");
platform_->SetMountResultForPath(namespaces_, "");
startup_->EarlySetup();
}
class DevCheckBlockTest : public ::testing::Test {
protected:
DevCheckBlockTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
vpd_dir = base_dir.Append("sys/firmware/vpd/rw");
vpd_file = vpd_dir.Append("block_devmode");
dev_mode_file = base_dir.Append(".developer_mode");
platform_ = new startup::FakePlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir, std::unique_ptr<startup::FakePlatform>(platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, true));
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 1));
base::CreateDirectory(dev_mode_file.DirName());
startup_->SetDevMode(true);
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
base::FilePath vpd_dir;
base::FilePath vpd_file;
base::FilePath dev_mode_file;
startup::FakePlatform* platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
};
TEST_F(DevCheckBlockTest, DevSWBoot) {
ASSERT_TRUE(cros_system_->SetInt("devsw_boot", 0));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(cros_system_->SetInt("recovery_reason", 0));
ASSERT_TRUE(CreateDirAndWriteFile(vpd_file, "1"));
struct stat st;
st.st_mode = S_IFREG;
platform_->SetStatResultForPath(vpd_file, st);
startup_->DevCheckBlockDevMode(dev_mode_file);
EXPECT_EQ(PathExists(dev_mode_file), false);
}
TEST_F(DevCheckBlockTest, SysFsVpdSlow) {
ASSERT_TRUE(cros_system_->SetInt("devsw_boot", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(cros_system_->SetInt("recovery_reason", 0));
ASSERT_TRUE(CreateDirAndWriteFile(vpd_file, "1"));
struct stat st;
st.st_mode = S_IFREG;
platform_->SetStatResultForPath(vpd_file, st);
startup_->DevCheckBlockDevMode(dev_mode_file);
EXPECT_EQ(PathExists(dev_mode_file), true);
}
TEST_F(DevCheckBlockTest, CrosSysBlockDev) {
ASSERT_TRUE(cros_system_->SetInt("devsw_boot", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(cros_system_->SetInt("recovery_reason", 0));
ASSERT_TRUE(cros_system_->SetInt("block_devmode", 1));
startup_->DevCheckBlockDevMode(dev_mode_file);
EXPECT_EQ(PathExists(dev_mode_file), true);
}
TEST_F(DevCheckBlockTest, ReadVpdSlowFail) {
ASSERT_TRUE(cros_system_->SetInt("devsw_boot", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(cros_system_->SetInt("recovery_reason", 0));
ASSERT_TRUE(cros_system_->SetInt("block_devmode", 0));
ASSERT_TRUE(cros_system_->SetInt("nvram_cleared", 1));
platform_->SetVpdResult(-1);
startup_->DevCheckBlockDevMode(dev_mode_file);
EXPECT_EQ(PathExists(dev_mode_file), false);
}
TEST_F(DevCheckBlockTest, ReadVpdSlowPass) {
ASSERT_TRUE(cros_system_->SetInt("devsw_boot", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(cros_system_->SetInt("recovery_reason", 0));
ASSERT_TRUE(cros_system_->SetInt("block_devmode", 0));
ASSERT_TRUE(cros_system_->SetInt("nvram_cleared", 1));
platform_->SetVpdResult(1);
std::string res;
std::vector<std::string> args = {"args"};
platform_->VpdSlow(args, &res);
EXPECT_EQ(res, "1");
startup_->DevCheckBlockDevMode(dev_mode_file);
EXPECT_EQ(PathExists(dev_mode_file), true);
EXPECT_EQ(platform_->GetBootAlertForArg("block_devmode"), 1);
}
class MaybeMountEfivarfsTest : public ::testing::Test {
protected:
MaybeMountEfivarfsTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir_ = temp_dir_.GetPath();
efivars_dir_ = base_dir_.Append("sys/firmware/efi/efivars");
filesystems_file_ = base_dir_.Append("proc/filesystems");
mock_platform_ = std::make_unique<StrictMock<startup::MockPlatform>>();
}
// Extra layer of safety to ensure all tests call `MakeStartup`.
void TearDown() override { startup_.reset(); }
// Move `ChromeosStartup` creation out of SetUp to give access to the
// `MockPlatform`. After calling this function `mock_platform_` will no longer
// be usable.
void MakeStartup() {
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir_, base_dir_,
base_dir_, base_dir_, std::move(mock_platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir_,
base_dir_, true));
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
std::unique_ptr<startup::MockPlatform> mock_platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir_;
base::FilePath efivars_dir_;
base::FilePath filesystems_file_;
};
TEST_F(MaybeMountEfivarfsTest, Supported) {
ASSERT_TRUE(CreateDirAndWriteFile(filesystems_file_, ("nodev\tsysfs\n"
"nodev\tefivarfs\n"
"\text4\n")));
EXPECT_CALL(*mock_platform_, Mount("efivarfs", efivars_dir_, "efivarfs",
kCommonMountFlags, _));
MakeStartup();
startup_->MaybeMountEfivarfs();
}
TEST_F(MaybeMountEfivarfsTest, NotSupported) {
ASSERT_TRUE(CreateDirAndWriteFile(filesystems_file_, ("nodev\tsysfs\n"
"\text4\n")));
// Expect that we mount nothing.
// Typed Matcher supplied to disambiguate between Mount calls for complier.
// Somewhat brittle, as a new version of the mount call could be introduced
// and used without breaking this, but seems like the best gTest gives us?
EXPECT_CALL(*mock_platform_,
Mount(testing::Matcher<const std::string&>(_), _, _, _, _))
.Times(0);
EXPECT_CALL(*mock_platform_,
Mount(testing::Matcher<const base::FilePath&>(_), _, _, _, _))
.Times(0);
MakeStartup();
startup_->MaybeMountEfivarfs();
}
class TPMTest : public ::testing::Test {
protected:
TPMTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
platform_ = new startup::FakePlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir, std::unique_ptr<startup::FakePlatform>(platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, false));
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
startup::FakePlatform* platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
};
TEST_F(TPMTest, OwnedFileTrue) {
base::FilePath tpm_file = base_dir.Append(kTPMOwnedPath);
ASSERT_TRUE(CreateDirAndWriteFile(tpm_file, "1"));
EXPECT_EQ(startup_->IsTPMOwned(), true);
}
TEST_F(TPMTest, OwnedFileFalse) {
base::FilePath tpm_file = base_dir.Append(kTPMOwnedPath);
ASSERT_TRUE(CreateDirAndWriteFile(tpm_file, "0"));
EXPECT_EQ(startup_->IsTPMOwned(), false);
}
TEST_F(TPMTest, NeedsClobberTPMOwned) {
base::FilePath tpm_file = base_dir.Append(kTPMOwnedPath);
ASSERT_TRUE(CreateDirAndWriteFile(tpm_file, "1"));
EXPECT_EQ(startup_->IsTPMOwned(), true);
EXPECT_EQ(startup_->NeedsClobberWithoutDevModeFile(), false);
}
TEST_F(TPMTest, NeedsClobberPreservationFile) {
base::FilePath tpm_file = base_dir.Append(kTPMOwnedPath);
ASSERT_TRUE(CreateDirAndWriteFile(tpm_file, "0"));
EXPECT_EQ(startup_->IsTPMOwned(), false);
base::FilePath preservation_file = base_dir.Append("preservation_request");
ASSERT_TRUE(CreateDirAndWriteFile(preservation_file, "0"));
struct stat st;
st.st_uid = -1;
platform_->SetStatResultForPath(preservation_file, st);
EXPECT_EQ(startup_->NeedsClobberWithoutDevModeFile(), false);
}
TEST_F(TPMTest, NeedsClobberInstallFile) {
base::FilePath tpm_file = base_dir.Append(kTPMOwnedPath);
ASSERT_TRUE(CreateDirAndWriteFile(tpm_file, "0"));
EXPECT_EQ(startup_->IsTPMOwned(), false);
base::FilePath preservation_file = base_dir.Append("preservation_request");
ASSERT_TRUE(CreateDirAndWriteFile(preservation_file, "0"));
struct stat st;
st.st_uid = -1;
platform_->SetStatResultForPath(preservation_file, st);
base::FilePath install_file =
base_dir.Append("home/.shadow/install_attributes.pb");
ASSERT_TRUE(CreateDirAndWriteFile(install_file, "0"));
LOG(INFO) << "test getuid " << getuid();
st.st_uid = getuid();
platform_->SetStatResultForPath(install_file, st);
EXPECT_EQ(startup_->NeedsClobberWithoutDevModeFile(), true);
}
class TpmCleanupTest : public ::testing::Test {
protected:
TpmCleanupTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
mock_platform_ = new startup::MockPlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir,
std::unique_ptr<startup::MockPlatform>(mock_platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, true));
flag_file_ = base_dir.Append(kTpmFirmwareUpdateRequestFlagFile);
tpm_cleanup_ = base_dir.Append(kTpmFirmwareUpdateCleanup);
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
startup::MockPlatform* mock_platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
base::FilePath flag_file_;
base::FilePath tpm_cleanup_;
};
TEST_F(TpmCleanupTest, TpmCleanupNoFlagFile) {
EXPECT_CALL(*mock_platform_, RunProcess(tpm_cleanup_)).Times(0);
startup_->CleanupTpm();
}
TEST_F(TpmCleanupTest, TpmCleanupNoCmdPath) {
CreateDirAndWriteFile(flag_file_, "exists");
EXPECT_CALL(*mock_platform_, RunProcess(tpm_cleanup_)).Times(0);
startup_->CleanupTpm();
}
TEST_F(TpmCleanupTest, TpmCleanupSuccess) {
CreateDirAndWriteFile(flag_file_, "exists");
CreateDirAndWriteFile(tpm_cleanup_, "exists");
EXPECT_CALL(*mock_platform_, RunProcess(tpm_cleanup_)).Times(1);
startup_->CleanupTpm();
}
class ConfigTest : public ::testing::Test {
protected:
ConfigTest() {}
void SetUp() override {
cros_system_ = std::make_unique<CrosSystemFake>();
CreateBaseAndSetNames(&base_dir_, &lsb_file_, &stateful_);
platform_ = std::make_unique<startup::FakePlatform>();
}
std::unique_ptr<startup::MountHelper> GenerateMountHelper() {
startup::Flags flags;
startup::ChromeosStartup::ParseFlags(&flags);
startup::MountHelperFactory factory(std::move(platform_),
cros_system_.get(), flags, base_dir_,
stateful_, lsb_file_);
return factory.Generate();
}
std::unique_ptr<CrosSystemFake> cros_system_;
base::FilePath base_dir_;
base::FilePath lsb_file_;
base::FilePath stateful_;
std::unique_ptr<startup::FakePlatform> platform_;
};
TEST_F(ConfigTest, NoDevMode) {
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 0));
ASSERT_TRUE(CreateDirAndWriteFile(lsb_file_,
"CHROMEOS_RELEASE_TRACK=stable-channel\n"));
std::unique_ptr<startup::MountHelper> helper = GenerateMountHelper();
EXPECT_EQ(helper->GetMountHelperType(),
startup::MountHelperType::kStandardMode);
}
TEST_F(ConfigTest, DevMode) {
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 1));
ASSERT_TRUE(CreateDirAndWriteFile(lsb_file_,
"CHROMEOS_RELEASE_TRACK=stable-channel\n"));
std::unique_ptr<startup::MountHelper> helper = GenerateMountHelper();
EXPECT_EQ(helper->GetMountHelperType(),
startup::MountHelperType::kStandardMode);
}
TEST_F(ConfigTest, DevModeTest) {
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(CreateDirAndWriteFile(
lsb_file_, "CHROMEOS_RELEASE_TRACK=testimage-channel\n"));
std::unique_ptr<startup::MountHelper> helper = GenerateMountHelper();
EXPECT_EQ(helper->GetMountHelperType(), startup::MountHelperType::kTestMode);
}
TEST_F(ConfigTest, DevModeTestFactoryTest) {
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 1));
ASSERT_TRUE(CreateDirAndWriteFile(
lsb_file_, "CHROMEOS_RELEASE_TRACK=testimage-channel\n"));
base::FilePath factory_en = stateful_.Append("dev_image/factory/enabled");
ASSERT_TRUE(CreateDirAndWriteFile(factory_en, "Enabled"));
std::unique_ptr<startup::MountHelper> helper = GenerateMountHelper();
EXPECT_EQ(helper->GetMountHelperType(),
startup::MountHelperType::kFactoryMode);
}
TEST_F(ConfigTest, DevModeTestFactoryInstaller) {
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(CreateDirAndWriteFile(
lsb_file_, "CHROMEOS_RELEASE_TRACK=testimage-channel\n"));
base::FilePath cmdline = base_dir_.Append(kProcCmdLine);
ASSERT_TRUE(CreateDirAndWriteFile(cmdline, "cros_factory_install"));
std::unique_ptr<startup::MountHelper> helper = GenerateMountHelper();
EXPECT_EQ(helper->GetMountHelperType(),
startup::MountHelperType::kFactoryMode);
}
TEST_F(ConfigTest, DevModeTestFactoryInstallerUsingFile) {
ASSERT_TRUE(cros_system_->SetInt("cros_debug", 1));
ASSERT_TRUE(cros_system_->SetInt("debug_build", 0));
ASSERT_TRUE(CreateDirAndWriteFile(
lsb_file_, "CHROMEOS_RELEASE_TRACK=testimage-channel\n"));
base::FilePath cmdline = base_dir_.Append(kProcCmdLine);
ASSERT_TRUE(CreateDirAndWriteFile(cmdline, "not_factory_install"));
base::FilePath installer = base_dir_.Append("root/.factory_installer");
ASSERT_TRUE(CreateDirAndWriteFile(installer, "factory"));
std::unique_ptr<startup::MountHelper> helper = GenerateMountHelper();
EXPECT_EQ(helper->GetMountHelperType(),
startup::MountHelperType::kFactoryMode);
}
class MountStackTest : public ::testing::Test {
protected:
MountStackTest()
: base_dir_(base::FilePath("")),
platform_(new startup::FakePlatform()),
mount_helper_(std::unique_ptr<startup::FakePlatform>(platform_),
flags_,
base_dir_,
base_dir_,
true) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir_ = temp_dir_.GetPath();
}
startup::Flags flags_;
base::FilePath base_dir_;
base::ScopedTempDir temp_dir_;
startup::FakePlatform* platform_;
startup::StandardMountHelper mount_helper_;
};
TEST_F(MountStackTest, RememberMount) {
std::stack<base::FilePath> mount_stack = {};
std::deque<base::FilePath> end = {base::FilePath("/home"),
base::FilePath("/root")};
std::stack<base::FilePath> end_stack(end);
base::FilePath mount("/home");
mount_helper_.RememberMount(mount);
base::FilePath mnt("/root");
mount_helper_.RememberMount(mnt);
std::stack<base::FilePath> res_stack = mount_helper_.GetMountStackForTest();
EXPECT_EQ(res_stack, end_stack);
}
TEST_F(MountStackTest, CleanupMountsNoEncrypt) {
std::stack<base::FilePath> end_stack = {};
std::deque<base::FilePath> mount = {base::FilePath("/home"),
base::FilePath("/root")};
std::stack<base::FilePath> mount_stack(mount);
mount_helper_.SetMountStackForTest(mount_stack);
std::vector<base::FilePath> mounts;
mount_helper_.CleanupMountsStack(&mounts);
std::stack<base::FilePath> res_stack = mount_helper_.GetMountStackForTest();
EXPECT_EQ(res_stack, end_stack);
}
TEST(MountVarAndHomeChronosEncrypted, MountEncrypted) {
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath base_dir_ = temp_dir_.GetPath();
std::unique_ptr<startup::FakePlatform> platform_ =
std::make_unique<startup::FakePlatform>();
platform_->SetMountEncOutputForArg("", "1");
std::unique_ptr<startup::StandardMountHelper> mount_helper_ =
std::make_unique<startup::StandardMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->MountVarAndHomeChronosEncrypted();
EXPECT_EQ(res, true);
}
TEST(MountVarAndHomeChronosEncrypted, MountEncryptedFail) {
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath base_dir_ = temp_dir_.GetPath();
std::unique_ptr<startup::FakePlatform> platform_ =
std::make_unique<startup::FakePlatform>();
std::unique_ptr<startup::StandardMountHelper> mount_helper_ =
std::make_unique<startup::StandardMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->MountVarAndHomeChronosEncrypted();
EXPECT_EQ(res, false);
}
class DoMountTest : public ::testing::Test {
protected:
DoMountTest() {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir_ = temp_dir_.GetPath();
platform_ = std::make_unique<startup::FakePlatform>();
}
startup::Flags flags_;
base::FilePath base_dir_;
base::ScopedTempDir temp_dir_;
std::unique_ptr<startup::FakePlatform> platform_;
};
TEST_F(DoMountTest, StandardMountHelper) {
flags_.encstateful = true;
platform_->SetMountEncOutputForArg("", "1");
std::unique_ptr<startup::StandardMountHelper> mount_helper_ =
std::make_unique<startup::StandardMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, true);
}
TEST_F(DoMountTest, TestModeMountHelperCreateSystemKey) {
flags_.sys_key_util = true;
flags_.encstateful = true;
base::FilePath no_early = base_dir_.Append(".no_early_system_key");
base::FilePath log_file = base_dir_.Append(kSysKeyLog);
ASSERT_TRUE(CreateDirAndWriteFile(no_early, "1"));
ASSERT_TRUE(CreateDirAndWriteFile(log_file, "1"));
struct stat st;
st.st_mode = S_IFREG;
platform_->SetStatResultForPath(no_early, st);
platform_->SetMountEncOutputForArg("", "1");
std::unique_ptr<startup::TestModeMountHelper> mount_helper_ =
std::make_unique<startup::TestModeMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, true);
std::string sys_key_log_out;
base::ReadFileToString(log_file, &sys_key_log_out);
EXPECT_EQ(sys_key_log_out, "Opt not to create a system key in advance.");
}
TEST_F(DoMountTest, TestModeMountHelperMountEncryptFailed) {
flags_.sys_key_util = false;
flags_.encstateful = true;
base::FilePath mnt_encrypt_fail = base_dir_.Append("mount_encrypted_failed");
struct stat st;
st.st_uid = -1;
platform_->SetStatResultForPath(mnt_encrypt_fail, st);
platform_->SetMountEncOutputForArg("", "1");
std::unique_ptr<startup::TestModeMountHelper> mount_helper_ =
std::make_unique<startup::TestModeMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, true);
}
TEST_F(DoMountTest, TestModeMountHelperMountVarSuccess) {
flags_.sys_key_util = false;
flags_.encstateful = true;
base::FilePath clobber_log_ = base_dir_.Append("clobber_test_log");
platform_->SetClobberLogFile(clobber_log_);
platform_->SetMountEncOutputForArg("", "1");
std::unique_ptr<startup::TestModeMountHelper> mount_helper_ =
std::make_unique<startup::TestModeMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, true);
std::string clobber_log_out;
base::ReadFileToString(clobber_log_, &clobber_log_out);
EXPECT_EQ(clobber_log_out, "");
}
TEST_F(DoMountTest, TestModeMountHelperMountVarFail) {
flags_.sys_key_util = false;
flags_.encstateful = true;
base::FilePath clobber_log_ = base_dir_.Append("clobber_test_log");
platform_->SetClobberLogFile(clobber_log_);
base::FilePath mnt_encrypt_fail = base_dir_.Append("mount_encrypted_failed");
struct stat st;
st.st_uid = getuid();
platform_->SetStatResultForPath(mnt_encrypt_fail, st);
base::FilePath corrupted_enc = base_dir_.Append("corrupted_encryption");
base::FilePath encrypted_test = base_dir_.Append("encrypted.test1");
base::FilePath encrypted_test2 = base_dir_.Append("encrypted.test2");
ASSERT_TRUE(CreateDirAndWriteFile(encrypted_test, "1"));
ASSERT_TRUE(CreateDirAndWriteFile(encrypted_test2, "1"));
std::unique_ptr<startup::TestModeMountHelper> mount_helper_ =
std::make_unique<startup::TestModeMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, false);
std::string clobber_log_out;
base::ReadFileToString(clobber_log_, &clobber_log_out);
EXPECT_EQ(clobber_log_out,
"Failed mounting var and home/chronos; re-created.");
EXPECT_EQ(base::PathExists(corrupted_enc.Append("encrypted.test1")), true);
EXPECT_EQ(base::PathExists(corrupted_enc.Append("encrypted.test2")), true);
}
TEST_F(DoMountTest, FactoryModeMountHelperTmpfsFailMntVar) {
flags_.encstateful = true;
base::FilePath options_file = base_dir_.Append(kMntOptionsFile);
ASSERT_TRUE(CreateDirAndWriteFile(options_file, "tmpfs"));
std::unique_ptr<startup::FactoryModeMountHelper> mount_helper_ =
std::make_unique<startup::FactoryModeMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, false);
}
TEST_F(DoMountTest, FactoryModeMountHelperTmpfsFailMntHomeChronos) {
flags_.encstateful = true;
base::FilePath options_file = base_dir_.Append(kMntOptionsFile);
ASSERT_TRUE(CreateDirAndWriteFile(options_file, "tmpfs"));
base::FilePath tmpfs_var = base::FilePath("tmpfs_var");
base::FilePath var = base_dir_.Append("var");
platform_->SetMountResultForPath(var, tmpfs_var.value());
base::FilePath stateful_home_chronos = base_dir_.Append("home/chronos");
platform_->SetMountResultForPath(stateful_home_chronos, "fail");
std::unique_ptr<startup::FactoryModeMountHelper> mount_helper_ =
std::make_unique<startup::FactoryModeMountHelper>(
std::move(platform_), flags_, base_dir_, base_dir_, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, false);
}
TEST_F(DoMountTest, FactoryModeMountHelperTmpfsSuccess) {
flags_.encstateful = true;
base::FilePath stateful = base_dir_.Append("mnt/stateful_partition");
base::FilePath options_file = stateful.Append(kMntOptionsFile);
ASSERT_TRUE(CreateDirAndWriteFile(options_file, "tmpfs"));
base::FilePath tmpfs_var = base::FilePath("tmpfs_var");
base::FilePath var = base_dir_.Append("var");
platform_->SetMountResultForPath(var, tmpfs_var.value());
base::FilePath stateful_home_chronos = stateful.Append("home/chronos");
base::FilePath home_chronos = base_dir_.Append("home/chronos");
platform_->SetMountResultForPath(home_chronos, stateful_home_chronos.value());
std::unique_ptr<startup::FactoryModeMountHelper> mount_helper_ =
std::make_unique<startup::FactoryModeMountHelper>(
std::move(platform_), flags_, base_dir_, stateful, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, true);
}
TEST_F(DoMountTest, FactoryModeMountHelperUnencryptFailMntVar) {
flags_.encstateful = true;
base::FilePath stateful = base_dir_.Append("mnt/stateful_partition");
// base::FilePath stateful_var = stateful.Append("var");
// platform_->SetMountResultForPath(stateful_var, "fail");
std::unique_ptr<startup::FactoryModeMountHelper> mount_helper_ =
std::make_unique<startup::FactoryModeMountHelper>(
std::move(platform_), flags_, base_dir_, stateful, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, false);
}
TEST_F(DoMountTest, FactoryModeMountHelperUnencryptFailMntHomeChronos) {
flags_.encstateful = true;
base::FilePath stateful = base_dir_.Append("mnt/stateful_partition");
base::FilePath stateful_var = stateful.Append("var");
base::FilePath var = base_dir_.Append("var");
platform_->SetMountResultForPath(var, stateful_var.value());
// base::FilePath stateful_home_chronos = stateful.Append("home/chronos");
// platform_->SetMountResultForPath(stateful_home_chronos, "fail");
std::unique_ptr<startup::FactoryModeMountHelper> mount_helper_ =
std::make_unique<startup::FactoryModeMountHelper>(
std::move(platform_), flags_, base_dir_, stateful, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, false);
}
TEST_F(DoMountTest, FactoryModeMountHelperUnencryptSuccess) {
flags_.encstateful = true;
base::FilePath stateful = base_dir_.Append("mnt/stateful_partition");
base::FilePath stateful_var = stateful.Append("var");
base::FilePath var = base_dir_.Append("var");
platform_->SetMountResultForPath(var, stateful_var.value());
base::FilePath stateful_home_chronos = stateful.Append("home/chronos");
base::FilePath home_chronos = base_dir_.Append("home/chronos");
platform_->SetMountResultForPath(home_chronos, stateful_home_chronos.value());
std::unique_ptr<startup::FactoryModeMountHelper> mount_helper_ =
std::make_unique<startup::FactoryModeMountHelper>(
std::move(platform_), flags_, base_dir_, stateful, true);
bool res = mount_helper_->DoMountVarAndHomeChronos();
EXPECT_EQ(res, true);
}
class IsVarFullTest : public ::testing::Test {
protected:
IsVarFullTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
platform_ = new startup::FakePlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir, std::unique_ptr<startup::FakePlatform>(platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, false));
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
startup::FakePlatform* platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
};
TEST_F(IsVarFullTest, StatvfsFailure) {
bool res = startup_->IsVarFull();
EXPECT_EQ(res, false);
}
TEST_F(IsVarFullTest, Failure) {
base::FilePath var = base_dir.Append("var");
struct statvfs st;
st.f_bavail = 2600;
st.f_favail = 110;
st.f_bsize = 4096;
platform_->SetStatvfsResultForPath(var, st);
bool res = startup_->IsVarFull();
EXPECT_EQ(res, false);
}
TEST_F(IsVarFullTest, TrueBavail) {
base::FilePath var = base_dir.Append("var");
struct statvfs st;
st.f_bavail = 1000;
st.f_favail = 110;
st.f_bsize = 4096;
platform_->SetStatvfsResultForPath(var, st);
bool res = startup_->IsVarFull();
EXPECT_EQ(res, true);
}
TEST_F(IsVarFullTest, TrueFavail) {
base::FilePath var = base_dir.Append("var");
struct statvfs st;
st.f_bavail = 11000;
st.f_favail = 90;
st.f_bsize = 4096;
platform_->SetStatvfsResultForPath(var, st);
bool res = startup_->IsVarFull();
EXPECT_EQ(res, true);
}
class DeviceSettingsTest : public ::testing::Test {
protected:
DeviceSettingsTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
platform_ = new startup::FakePlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir, std::unique_ptr<startup::FakePlatform>(platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, false));
base::FilePath var_lib = base_dir.Append("var/lib");
whitelist_ = var_lib.Append("whitelist");
devicesettings_ = var_lib.Append("devicesettings");
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
startup::FakePlatform* platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
base::FilePath whitelist_;
base::FilePath devicesettings_;
};
TEST_F(DeviceSettingsTest, OldPathEmpty) {
ASSERT_TRUE(base::CreateDirectory(whitelist_));
base::FilePath devicesettings_test = devicesettings_.Append("test");
ASSERT_TRUE(CreateDirAndWriteFile(devicesettings_test, "test"));
startup_->MoveToLibDeviceSettings();
EXPECT_EQ(base::DirectoryExists(whitelist_), false);
EXPECT_EQ(base::PathExists(devicesettings_test), true);
}
TEST_F(DeviceSettingsTest, NewPathEmpty) {
ASSERT_TRUE(base::CreateDirectory(whitelist_));
ASSERT_TRUE(base::CreateDirectory(devicesettings_));
base::FilePath whitelist_test = whitelist_.Append("test");
ASSERT_TRUE(CreateDirAndWriteFile(whitelist_test, "test"));
base::FilePath devicesettings_test = devicesettings_.Append("test");
startup_->MoveToLibDeviceSettings();
EXPECT_EQ(base::DirectoryExists(whitelist_), false);
EXPECT_EQ(base::PathExists(whitelist_test), false);
EXPECT_EQ(base::PathExists(devicesettings_test), true);
}
TEST_F(DeviceSettingsTest, NeitherPathEmpty) {
ASSERT_TRUE(base::CreateDirectory(whitelist_));
ASSERT_TRUE(base::CreateDirectory(devicesettings_));
base::FilePath whitelist_test = whitelist_.Append("test_w");
ASSERT_TRUE(CreateDirAndWriteFile(whitelist_test, "test_w"));
base::FilePath devicesettings_test = devicesettings_.Append("test_d");
ASSERT_TRUE(CreateDirAndWriteFile(devicesettings_test, "test_d"));
startup_->MoveToLibDeviceSettings();
EXPECT_EQ(base::DirectoryExists(whitelist_), true);
EXPECT_EQ(base::PathExists(whitelist_test), true);
EXPECT_EQ(base::PathExists(devicesettings_test), true);
}
class DaemonStoreTest : public CrosSystemFakeTest {
protected:
DaemonStoreTest() {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
platform_ = new startup::FakePlatform();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir, std::unique_ptr<startup::FakePlatform>(platform_),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, true));
}
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
startup::FakePlatform* platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
};
TEST_F(DaemonStoreTest, NonEmptyEtc) {
base::FilePath run = base_dir.Append("run");
base::FilePath etc = base_dir.Append("etc");
base::FilePath run_daemon = run.Append("daemon-store");
base::FilePath etc_daemon = etc.Append("daemon-store");
base::FilePath etc_file = etc_daemon.Append("test_file");
base::FilePath etc_file_not_ds = etc.Append("test/not_incl");
ASSERT_TRUE(CreateDirAndWriteFile(etc_file, "1"));
ASSERT_TRUE(CreateDirAndWriteFile(etc_file_not_ds, "exclude"));
base::FilePath subdir = etc_daemon.Append("subdir");
base::FilePath sub_file = subdir.Append("test_file");
ASSERT_TRUE(CreateDirAndWriteFile(sub_file, "1"));
base::FilePath run_subdir = run_daemon.Append("subdir");
base::FilePath run_test_exclude = run.Append("test/not_incl");
base::FilePath run_ds_exclude = run_daemon.Append("test/not_incl");
platform_->SetMountResultForPath(run_subdir, run_subdir.value());
struct stat st_dir;
st_dir.st_mode = S_IFDIR;
platform_->SetStatResultForPath(subdir, st_dir);
startup_->CreateDaemonStore();
EXPECT_TRUE(base::DirectoryExists(run_subdir));
EXPECT_FALSE(base::PathExists(run_test_exclude));
EXPECT_FALSE(base::PathExists(run_ds_exclude));
}
class RemoveVarEmptyTest : public ::testing::Test {
protected:
RemoveVarEmptyTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir, std::make_unique<startup::FakePlatform>(),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, true));
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
std::unique_ptr<startup::ChromeosStartup> startup_;
};
TEST_F(RemoveVarEmptyTest, NonEmpty) {
base::FilePath var_empty = base_dir.Append("var/empty");
base::FilePath file1 = var_empty.Append("test_file");
ASSERT_TRUE(CreateDirAndWriteFile(file1, "1"));
base::FilePath file2 = var_empty.Append("test_file_2");
ASSERT_TRUE(CreateDirAndWriteFile(file2, "1"));
startup_->RemoveVarEmpty();
EXPECT_TRUE(!base::PathExists(file1));
EXPECT_TRUE(!base::PathExists(file2));
EXPECT_TRUE(!base::PathExists(var_empty));
}
class CheckVarLogTest : public ::testing::Test {
protected:
CheckVarLogTest() {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::make_unique<CrosSystemFake>(), flags_, base_dir, base_dir,
base_dir, base_dir, std::make_unique<startup::FakePlatform>(),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, true));
var_log_ = base_dir.Append("var/log");
base::CreateDirectory(var_log_);
}
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
std::unique_ptr<startup::ChromeosStartup> startup_;
base::FilePath var_log_;
};
TEST_F(CheckVarLogTest, NoSymLinks) {
base::FilePath test_file = var_log_.Append("test_file");
base::FilePath test_dir = var_log_.Append("test_dir");
base::FilePath test_test = test_dir.Append("test");
ASSERT_TRUE(CreateDirAndWriteFile(test_file, "test1"));
ASSERT_TRUE(CreateDirAndWriteFile(test_test, "test2"));
startup_->CheckVarLog();
EXPECT_TRUE(base::PathExists(test_file));
EXPECT_TRUE(base::PathExists(test_test));
}
TEST_F(CheckVarLogTest, SymLinkInsideVarLog) {
base::FilePath test_file = var_log_.Append("test_file");
base::FilePath test_dir = var_log_.Append("test_dir");
base::FilePath test_test = test_dir.Append("test");
base::FilePath test_link = var_log_.Append("test_link");
base::FilePath test_sub_link = test_dir.Append("link");
ASSERT_TRUE(CreateDirAndWriteFile(test_file, "test1"));
ASSERT_TRUE(CreateDirAndWriteFile(test_test, "test2"));
ASSERT_TRUE(base::CreateSymbolicLink(test_file, test_link));
ASSERT_TRUE(base::CreateSymbolicLink(test_test, test_sub_link));
startup_->CheckVarLog();
EXPECT_TRUE(base::PathExists(test_file));
EXPECT_TRUE(base::PathExists(test_test));
EXPECT_TRUE(base::PathExists(test_link));
EXPECT_TRUE(base::PathExists(test_sub_link));
}
TEST_F(CheckVarLogTest, SymLinkOutsideVarLog) {
base::FilePath test_file = var_log_.Append("test_file");
base::FilePath test_dir = var_log_.Append("test_dir");
base::FilePath test_test = test_dir.Append("test");
base::FilePath test_link = var_log_.Append("test_link");
base::FilePath test_sub_link = test_dir.Append("link");
base::FilePath outside = base_dir.Append("outside");
ASSERT_TRUE(CreateDirAndWriteFile(outside, "out"));
ASSERT_TRUE(CreateDirAndWriteFile(test_file, "test1"));
ASSERT_TRUE(CreateDirAndWriteFile(test_test, "test2"));
ASSERT_TRUE(base::CreateSymbolicLink(outside, test_link));
ASSERT_TRUE(base::CreateSymbolicLink(outside, test_sub_link));
startup_->CheckVarLog();
EXPECT_TRUE(base::PathExists(test_file));
EXPECT_TRUE(base::PathExists(test_test));
EXPECT_FALSE(base::PathExists(test_link));
EXPECT_FALSE(base::PathExists(test_sub_link));
}
class RestoreContextsForVarTest : public ::testing::Test {
protected:
RestoreContextsForVarTest() : cros_system_(new CrosSystemFake()) {}
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_dir = temp_dir_.GetPath();
platform_ = std::make_unique<startup::FakePlatform>();
startup_ = std::make_unique<startup::ChromeosStartup>(
std::unique_ptr<CrosSystem>(cros_system_), flags_, base_dir, base_dir,
base_dir, base_dir,
std::make_unique<startup::FakePlatform>(*platform_.get()),
std::make_unique<startup::StandardMountHelper>(
std::make_unique<startup::FakePlatform>(), flags_, base_dir,
base_dir, true));
}
CrosSystemFake* cros_system_;
startup::Flags flags_;
base::ScopedTempDir temp_dir_;
base::FilePath base_dir;
std::unique_ptr<startup::FakePlatform> platform_;
std::unique_ptr<startup::ChromeosStartup> startup_;
};
TEST_F(RestoreContextsForVarTest, Restorecon) {
base::FilePath var = base_dir.Append("var");
ASSERT_TRUE(base::CreateDirectory(var));
base::FilePath debug = base_dir.Append("sys/kernel/debug");
ASSERT_TRUE(base::CreateDirectory(debug));
base::FilePath shadow = base_dir.Append("home/.shadow");
ASSERT_TRUE(base::CreateDirectory(shadow));
base::FilePath selinux = base_dir.Append("sys/fs/selinux/enforce");
ASSERT_TRUE(CreateDirAndWriteFile(selinux, "1"));
startup_->RestoreContextsForVar(&RestoreconTestFunc);
EXPECT_TRUE(base::PathExists(var.Append("restore")));
EXPECT_TRUE(base::PathExists(shadow.Append("restore")));
EXPECT_TRUE(base::PathExists(debug.Append("exclude")));
}
} // namespace startup