blob: 77a55bdbef3c6ee954a415107959e92663a047c5 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/component_updater/tpcd_metadata_component_installer.h"
#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/notreached.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "components/component_updater/mock_component_updater_service.h"
#include "components/tpcd/metadata/parser_test_helper.h"
#include "content/public/test/browser_task_environment.h"
#include "net/base/features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace component_updater {
namespace {
using ::testing::_;
const base::FilePath::CharType kComponentFileName[] =
FILE_PATH_LITERAL("metadata.pb");
const char* kTpcdMetadataInstallationResult =
"Navigation.TpcdMitigations.MetadataInstallationResult";
} // namespace
class TpcdMetadataComponentInstallerTest
: public ::testing::Test,
public ::testing::WithParamInterface<bool> {
public:
TpcdMetadataComponentInstallerTest() {
CHECK(install_dir_.CreateUniqueTempDir());
CHECK(install_dir_.IsValid());
path_ = install_dir().Append(kComponentFileName);
CHECK(!path_.empty());
if (GetParam()) {
scoped_list_.InitAndEnableFeature(net::features::kTpcdMetadataGrants);
} else {
scoped_list_.InitAndDisableFeature(net::features::kTpcdMetadataGrants);
}
}
~TpcdMetadataComponentInstallerTest() override = default;
protected:
const base::FilePath& install_dir() { return install_dir_.GetPath(); }
const base::FilePath path() { return path_; }
void ExecFakeComponentInstallation(base::StringPiece contents) {
CHECK(base::WriteFile(path(), contents));
CHECK(base::PathExists(path()));
}
content::BrowserTaskEnvironment& task_env() { return task_env_; }
auto* policy() { return policy_.get(); }
private:
base::ScopedTempDir install_dir_;
base::FilePath path_;
content::BrowserTaskEnvironment task_env_;
base::test::ScopedFeatureList scoped_list_;
std::unique_ptr<component_updater::ComponentInstallerPolicy> policy_ =
std::make_unique<TpcdMetadataComponentInstaller>(base::DoNothing());
};
TEST_P(TpcdMetadataComponentInstallerTest, ComponentRegistered) {
auto service =
std::make_unique<component_updater::MockComponentUpdateService>();
EXPECT_CALL(*service, RegisterComponent(_)).Times(1);
RegisterTpcdMetadataComponent(service.get());
task_env().RunUntilIdle();
}
TEST_P(TpcdMetadataComponentInstallerTest,
VerifyInstallation_InvalidInstallDir) {
base::HistogramTester histogram_tester;
EXPECT_FALSE(policy()->VerifyInstallation(
base::Value::Dict(), install_dir().Append(FILE_PATH_LITERAL("x"))));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kMissingMetadataFile, 1);
}
TEST_P(TpcdMetadataComponentInstallerTest,
VerifyInstallation_RejectsMissingFile) {
base::HistogramTester histogram_tester;
EXPECT_FALSE(
policy()->VerifyInstallation(base::Value::Dict(), install_dir()));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kMissingMetadataFile, 1);
}
TEST_P(TpcdMetadataComponentInstallerTest,
VerifyInstallation_RejectsNotProtoFile) {
ExecFakeComponentInstallation("clearly not a proto");
base::HistogramTester histogram_tester;
EXPECT_FALSE(
policy()->VerifyInstallation(base::Value::Dict(), install_dir()));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kParsingToProtoFailed, 1);
}
TEST_P(TpcdMetadataComponentInstallerTest,
FeatureEnabled_ComponentReady_ErroneousPrimarySpec) {
if (!GetParam()) {
GTEST_SKIP_("Reason: Test parameter instance N/A");
}
const std::string primary_pattern_spec = "[*]bar.com";
const std::string secondary_pattern_spec = "[*.]foo.com";
std::vector<tpcd::metadata::MetadataPair> metadata_pairs;
metadata_pairs.emplace_back(primary_pattern_spec, secondary_pattern_spec);
tpcd::metadata::Metadata metadata =
tpcd::metadata::MakeMetadataProtoFromVectorOfPair(metadata_pairs);
ASSERT_EQ(metadata.metadata_entries_size(), 1);
ExecFakeComponentInstallation(metadata.SerializeAsString());
base::HistogramTester histogram_tester;
ASSERT_FALSE(
policy()->VerifyInstallation(base::Value::Dict(), install_dir()));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kErroneousSpec, 1);
}
TEST_P(TpcdMetadataComponentInstallerTest,
FeatureEnabled_ComponentReady_ErroneousSecondarySpec) {
if (!GetParam()) {
GTEST_SKIP_("Reason: Test parameter instance N/A");
}
const std::string primary_pattern_spec = "[*.]bar.com";
const std::string secondary_pattern_spec = "[*]foo.com";
std::vector<tpcd::metadata::MetadataPair> metadata_pairs;
metadata_pairs.emplace_back(primary_pattern_spec, secondary_pattern_spec);
tpcd::metadata::Metadata metadata =
tpcd::metadata::MakeMetadataProtoFromVectorOfPair(metadata_pairs);
ASSERT_EQ(metadata.metadata_entries_size(), 1);
ExecFakeComponentInstallation(metadata.SerializeAsString());
base::HistogramTester histogram_tester;
ASSERT_FALSE(
policy()->VerifyInstallation(base::Value::Dict(), install_dir()));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kErroneousSpec, 1);
}
TEST_P(TpcdMetadataComponentInstallerTest,
FeatureEnabled_ComponentReady_FiresCallback) {
if (!GetParam()) {
GTEST_SKIP_("Reason: Test parameter instance N/A");
}
const std::string primary_pattern_spec = "[*.]bar.com";
const std::string secondary_pattern_spec = "[*.]foo.com";
std::vector<tpcd::metadata::MetadataPair> metadata_pairs;
metadata_pairs.emplace_back(primary_pattern_spec, secondary_pattern_spec);
tpcd::metadata::Metadata metadata =
tpcd::metadata::MakeMetadataProtoFromVectorOfPair(metadata_pairs);
ASSERT_EQ(metadata.metadata_entries_size(), 1);
ExecFakeComponentInstallation(metadata.SerializeAsString());
base::RunLoop run_loop;
std::unique_ptr<component_updater::ComponentInstallerPolicy> policy =
std::make_unique<TpcdMetadataComponentInstaller>(
base::BindLambdaForTesting([&](std::string raw_metadata) {
EXPECT_EQ(raw_metadata, metadata.SerializeAsString());
run_loop.Quit();
}));
base::HistogramTester histogram_tester;
ASSERT_TRUE(policy->VerifyInstallation(base::Value::Dict(), install_dir()));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kSuccessful, 1);
policy->ComponentReady(base::Version(), install_dir(), base::Value::Dict());
run_loop.Run();
}
TEST_P(TpcdMetadataComponentInstallerTest,
FeatureDisabled_ComponentReady_DoesNotFireCallback) {
if (GetParam()) {
GTEST_SKIP_("Reason: Test parameter instance N/A");
}
const std::string primary_pattern_spec = "[*.]bar.com";
const std::string secondary_pattern_spec = "[*.]foo.com";
std::vector<tpcd::metadata::MetadataPair> metadata_pairs;
metadata_pairs.emplace_back(primary_pattern_spec, secondary_pattern_spec);
tpcd::metadata::Metadata metadata =
tpcd::metadata::MakeMetadataProtoFromVectorOfPair(metadata_pairs);
ASSERT_EQ(metadata.metadata_entries_size(), 1);
ExecFakeComponentInstallation(metadata.SerializeAsString());
base::RunLoop run_loop;
std::unique_ptr<component_updater::ComponentInstallerPolicy> policy =
std::make_unique<TpcdMetadataComponentInstaller>(
base::BindLambdaForTesting(
[&](std::string raw_metadata) { NOTREACHED_NORETURN(); }));
base::HistogramTester histogram_tester;
ASSERT_TRUE(policy->VerifyInstallation(base::Value::Dict(), install_dir()));
histogram_tester.ExpectBucketCount(
kTpcdMetadataInstallationResult,
TpcdMetadataInstallationResult::kSuccessful, 1);
policy->ComponentReady(base::Version(), install_dir(), base::Value::Dict());
run_loop.RunUntilIdle();
}
INSTANTIATE_TEST_SUITE_P(
/* no label */,
TpcdMetadataComponentInstallerTest,
::testing::Bool());
} // namespace component_updater