blob: a09d8f997ffd02577fd670c3195f6232095edf66 [file] [log] [blame]
// Copyright 2021 The Chromium 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 "android_webview/nonembedded/component_updater/aw_component_installer_policy_delegate.h"
#include <stdint.h>
#include <iterator>
#include <memory>
#include <utility>
#include "android_webview/common/aw_paths.h"
#include "base/android/path_utils.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/test/scoped_path_override.h"
#include "base/values.h"
#include "base/version.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace android_webview {
namespace {
constexpr char kComponentId[] = "jebgalgnebhfojomionfpkfelancnnkf";
// This hash corresponds to kComponentId.
constexpr uint8_t kSha256Hash[] = {
0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, 0x8e, 0xd5, 0xfa,
0x54, 0xb0, 0xd2, 0xdd, 0xa5, 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47,
0xf6, 0xc4, 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40};
std::unique_ptr<base::DictionaryValue> test_manifest(
const base::Version& version) {
auto manifest = std::make_unique<base::DictionaryValue>();
manifest->SetString("version", version.GetString());
return manifest;
}
void CreateTestFiles(const base::FilePath& install_dir) {
base::CreateDirectory(install_dir);
ASSERT_TRUE(base::WriteFile(install_dir.AppendASCII("file1.txt"), "1"));
ASSERT_TRUE(base::WriteFile(install_dir.AppendASCII("file2.txt"), "2"));
ASSERT_TRUE(base::CreateDirectory(install_dir.AppendASCII("sub_dir")));
ASSERT_TRUE(base::WriteFile(
install_dir.AppendASCII("sub_dir").AppendASCII("file3.txt"), "3"));
}
void AssertTestFiles(const base::FilePath& install_dir) {
EXPECT_TRUE(base::PathExists(install_dir.AppendASCII("file1.txt")));
EXPECT_TRUE(base::PathExists(install_dir.AppendASCII("file2.txt")));
EXPECT_TRUE(base::DirectoryExists(install_dir.AppendASCII("sub_dir")));
EXPECT_TRUE(base::PathExists(
install_dir.AppendASCII("sub_dir").AppendASCII("file3.txt")));
}
} // namespace
class TestAwComponentInstallerPolicyDelegate
: public AwComponentInstallerPolicyDelegate {
public:
TestAwComponentInstallerPolicyDelegate(const std::vector<uint8_t>& hash)
: AwComponentInstallerPolicyDelegate(hash) {}
~TestAwComponentInstallerPolicyDelegate() override = default;
private:
void IncrementComponentsUpdatedCount() override { /* noop */
}
};
class AwComponentInstallerPolicyDelegateTest : public testing::Test {
public:
AwComponentInstallerPolicyDelegateTest() = default;
~AwComponentInstallerPolicyDelegateTest() override = default;
AwComponentInstallerPolicyDelegateTest(
const AwComponentInstallerPolicyDelegateTest&) = delete;
AwComponentInstallerPolicyDelegateTest& operator=(
const AwComponentInstallerPolicyDelegateTest&) = delete;
// Override from testing::Test
void SetUp() override {
scoped_path_override_ =
std::make_unique<base::ScopedPathOverride>(DIR_COMPONENTS_TEMP);
ASSERT_TRUE(base::android::GetDataDirectory(&cps_component_path_));
cps_component_path_ = cps_component_path_.AppendASCII("components")
.AppendASCII("cps")
.AppendASCII(kComponentId);
ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
CreateTestFiles(GetTestInstallPath());
std::vector<uint8_t> hash;
hash.assign(std::begin(kSha256Hash), std::end(kSha256Hash));
delegate_ = std::make_unique<TestAwComponentInstallerPolicyDelegate>(hash);
}
void TearDown() override {
ASSERT_TRUE(base::DeletePathRecursively(cps_component_path_));
}
base::FilePath GetTestInstallPath() const {
return scoped_temp_dir_.GetPath();
}
protected:
base::FilePath cps_component_path_;
std::unique_ptr<TestAwComponentInstallerPolicyDelegate> delegate_;
private:
base::ScopedTempDir scoped_temp_dir_;
std::unique_ptr<base::ScopedPathOverride> scoped_path_override_;
};
TEST_F(AwComponentInstallerPolicyDelegateTest, TestNoExistingVersions) {
const base::Version testVersion("1.2.3.4");
delegate_->ComponentReady(testVersion, GetTestInstallPath(),
test_manifest(testVersion));
// Check that the original install path still has files.
AssertTestFiles(GetTestInstallPath());
AssertTestFiles(
cps_component_path_.AppendASCII("1_" + testVersion.GetString()));
}
TEST_F(AwComponentInstallerPolicyDelegateTest, TestExistingOtherVersions) {
const base::Version testVersion("1.2.3.4");
CreateTestFiles(cps_component_path_.AppendASCII("1_4.3.2.1"));
CreateTestFiles(cps_component_path_.AppendASCII("10_2.3.4.1"));
delegate_->ComponentReady(testVersion, GetTestInstallPath(),
test_manifest(testVersion));
// Check that the original install path still has files.
AssertTestFiles(GetTestInstallPath());
AssertTestFiles(
cps_component_path_.AppendASCII("11_" + testVersion.GetString()));
}
TEST_F(AwComponentInstallerPolicyDelegateTest, TestExistingSameVersion) {
const base::Version testVersion("1.2.3.4");
CreateTestFiles(
cps_component_path_.AppendASCII("5_" + testVersion.GetString()));
delegate_->ComponentReady(testVersion, GetTestInstallPath(),
test_manifest(testVersion));
// Check that the original install path still has files.
AssertTestFiles(GetTestInstallPath());
// Directory should only contain "<component-id>/5/1.2.3.4/", no other files
// or directories should exist.
base::FileEnumerator file_enumerator(
cps_component_path_, /* recursive= */ false,
base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
path = file_enumerator.Next()) {
EXPECT_EQ(path.BaseName().MaybeAsASCII(), "5_" + testVersion.GetString());
AssertTestFiles(path);
}
}
} // namespace android_webview