blob: 75da64bcf8808327e0ade8686dfbbfbece6fcfd8 [file] [log] [blame]
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "login_manager/resilient_policy_store.h"
#include <memory>
#include <string>
#include <utility>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <brillo/files/file_util.h>
#include <gtest/gtest.h>
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/device_management_backend.pb.h"
#include "login_manager/mock_metrics.h"
#include "login_manager/system_utils_impl.h"
namespace em = enterprise_management;
namespace login_manager {
class ResilientPolicyStoreTest : public ::testing::Test {
public:
ResilientPolicyStoreTest() {}
ResilientPolicyStoreTest(const ResilientPolicyStoreTest&) = delete;
ResilientPolicyStoreTest& operator=(const ResilientPolicyStoreTest&) = delete;
virtual ~ResilientPolicyStoreTest() {}
virtual void SetUp() {
ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
// Create a temporary filename that's guaranteed to not exist, but is
// inside our scoped directory so it'll get deleted later.
ASSERT_TRUE(base::CreateTemporaryFileInDir(tmpdir_.GetPath(), &tmpfile_));
ASSERT_TRUE(brillo::DeleteFile(tmpfile_));
}
virtual void TearDown() {}
void CheckExpectedPolicy(PolicyStore* store,
const em::PolicyFetchResponse& policy) {
std::string serialized;
ASSERT_TRUE(policy.SerializeToString(&serialized));
std::string serialized_from;
ASSERT_TRUE(store->Get().SerializeToString(&serialized_from));
EXPECT_EQ(serialized, serialized_from);
}
base::ScopedTempDir tmpdir_;
base::FilePath tmpfile_;
};
TEST_F(ResilientPolicyStoreTest, LoadResilientMissingPolicy) {
MockMetrics metrics;
ResilientPolicyStore store(tmpfile_, &metrics);
ASSERT_TRUE(store.EnsureLoadedOrCreated());
}
TEST_F(ResilientPolicyStoreTest, CheckDeleteAtLoadResilient) {
MockMetrics metrics;
ResilientPolicyStore store(tmpfile_, &metrics);
std::unique_ptr<policy::DevicePolicyImpl> device_policy =
std::make_unique<policy::DevicePolicyImpl>();
device_policy->set_policy_path_for_testing(tmpfile_);
device_policy->set_verify_policy_for_testing(false);
store.set_device_policy_for_testing(std::move(device_policy));
enterprise_management::PolicyFetchResponse policy;
enterprise_management::PolicyData policy_data;
enterprise_management::ChromeDeviceSettingsProto settings;
policy_data.set_username("test_user");
policy_data.set_request_token("secret_token");
std::string settings_str;
settings.SerializeToString(&settings_str);
policy_data.set_policy_value(settings_str);
policy.set_policy_data(policy_data.SerializeAsString());
store.Set(policy);
ASSERT_TRUE(store.Persist());
CheckExpectedPolicy(&store, policy);
// Create the file with next index, containing some invalid data.
base::FilePath policy_path2 = base::FilePath(tmpfile_.value() + ".2");
SystemUtilsImpl utils;
utils.AtomicFileWrite(policy_path2, "invalid_data");
// Check that LoadResilient succeeds and ignores the last file.
ASSERT_TRUE(store.EnsureLoadedOrCreated());
CheckExpectedPolicy(&store, policy);
// Check that the last file was deleted.
ASSERT_FALSE(base::PathExists(policy_path2));
}
TEST_F(ResilientPolicyStoreTest, CheckCleanupFromPersistResilient) {
MockMetrics metrics;
ResilientPolicyStore store(tmpfile_, &metrics);
enterprise_management::PolicyFetchResponse policy;
policy.set_error_message("foo");
store.Set(policy);
base::FilePath policy_path1(tmpfile_.value() + ".1");
base::FilePath policy_path2(tmpfile_.value() + ".2");
base::FilePath policy_path3(tmpfile_.value() + ".3");
base::FilePath policy_path4(tmpfile_.value() + ".4");
ASSERT_TRUE(store.Persist());
CheckExpectedPolicy(&store, policy);
ASSERT_TRUE(base::PathExists(policy_path1));
// Change the policy data and store again, expecting to have a new file
// because cleanup temporary file fails to be created in testing environment.
policy.set_error_message("foo2");
store.Set(policy);
ASSERT_TRUE(store.Persist());
ASSERT_TRUE(base::PathExists(policy_path2));
// Create the file with next index, containing some invalid data.
SystemUtilsImpl utils;
utils.AtomicFileWrite(policy_path3, "invalid_data");
// Change the policy data and store again, having a new file.
policy.set_error_message("foo");
store.Set(policy);
ASSERT_TRUE(store.Persist());
ASSERT_TRUE(base::PathExists(policy_path4));
// The last Persist resilient should have done the cleanup and removed the
// oldest file since the limit was reached.
ASSERT_FALSE(base::PathExists(policy_path1));
ASSERT_TRUE(base::PathExists(policy_path2));
ASSERT_TRUE(base::PathExists(policy_path3));
}
} // namespace login_manager