blob: 5a9774c8e712b4443c935393cc6407ede5beab5b [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/metrics/structured/key_data_provider_ash.h"
#include <memory>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/callback_helpers.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/metrics/structured/lib/key_data_provider.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace metrics::structured {
namespace {
using testing::Eq;
using testing::IsNull;
using testing::NotNull;
constexpr char kProfileProjectName[] = "TestProjectOne";
constexpr char kDeviceProjectName[] = "TestProjectFour";
constexpr char kCrOSEventsProjectName[] = "CrOSEvents";
class KeyDataProviderAshTest : public testing::Test, KeyDataProvider::Observer {
protected:
KeyDataProviderAshTest()
: profile_manager_(TestingBrowserProcess::GetGlobal()) {}
KeyDataProviderAshTest(const KeyDataProviderAshTest&) = delete;
KeyDataProviderAshTest& operator=(const KeyDataProviderAshTest&) = delete;
void SetUp() override {
CHECK(temp_dir_.CreateUniqueTempDir());
ASSERT_TRUE(profile_manager_.SetUp());
run_loop_ = std::make_unique<base::RunLoop>();
key_data_provider_ = std::make_unique<KeyDataProviderAsh>(
DeviceKeyFilePath(), /*write_delay=*/base::Milliseconds(0));
key_data_provider_->AddObserver(this);
Wait();
run_loop_->Run();
}
void TearDown() override { key_data_provider_->RemoveObserver(this); }
void OnKeyReady() override { run_loop_->Quit(); }
void Wait() { task_environment_.RunUntilIdle(); }
void SetUpProfileKeys() {
run_loop_ = std::make_unique<base::RunLoop>();
profile_manager_.CreateTestingProfile("p1");
Wait();
run_loop_->Run();
}
KeyData* GetCurrentKeyData(const std::string& project_name) {
return key_data_provider_->GetKeyData(project_name);
}
KeyData* GetDeviceKeyData() {
return key_data_provider_->GetKeyData(kDeviceProjectName);
}
KeyData* GetProfileKeyData() {
return key_data_provider_->GetKeyData(kProfileProjectName);
}
base::FilePath DeviceKeyFilePath() {
return temp_dir_.GetPath()
.Append("structured_metrics")
.Append("device_keys");
}
base::FilePath ProfileKeyFilePath() {
return GetProfilePath().Append("structured_metrics").Append("profile_keys");
}
base::FilePath GetProfilePath() { return profile_manager_.profiles_dir(); }
private:
content::BrowserTaskEnvironment task_environment_;
TestingProfileManager profile_manager_;
base::ScopedTempDir temp_dir_;
// Used to wait for keys.
std::unique_ptr<base::RunLoop> run_loop_;
protected:
std::unique_ptr<KeyDataProviderAsh> key_data_provider_;
};
} // namespace
TEST_F(KeyDataProviderAshTest, UseDeviceKeyForDeviceProject) {
auto* key_data = GetCurrentKeyData(kDeviceProjectName);
EXPECT_NE(key_data, nullptr);
// Ensure that the pointers are not the same.
EXPECT_NE(key_data, GetProfileKeyData());
EXPECT_EQ(key_data, GetDeviceKeyData());
}
TEST_F(KeyDataProviderAshTest, UseProfileKeyForProfileProject) {
SetUpProfileKeys();
auto* key_data = GetCurrentKeyData(kProfileProjectName);
EXPECT_NE(key_data, nullptr);
// Ensure that the pointers are not the same.
EXPECT_EQ(key_data, GetProfileKeyData());
EXPECT_NE(key_data, GetDeviceKeyData());
}
TEST_F(KeyDataProviderAshTest, ReturnNullIfProfileProjectBeforeProfileKey) {
auto* key_data = GetCurrentKeyData(kProfileProjectName);
EXPECT_EQ(key_data, nullptr);
}
TEST_F(KeyDataProviderAshTest, ReturnProfileKeyForCrOSEvent) {
SetUpProfileKeys();
auto* key_data = GetCurrentKeyData(kCrOSEventsProjectName);
EXPECT_NE(key_data, nullptr);
EXPECT_EQ(key_data, GetProfileKeyData());
}
TEST_F(KeyDataProviderAshTest, ReturnsAppropriateSequenceIds) {
SetUpProfileKeys();
auto* key_data = GetCurrentKeyData(kCrOSEventsProjectName);
EXPECT_NE(key_data, nullptr);
EXPECT_EQ(key_data, GetProfileKeyData());
}
TEST_F(KeyDataProviderAshTest, SequenceEvents_ReturnsDifferentSequenceIds) {
SetUpProfileKeys();
std::optional<uint64_t> device_id =
key_data_provider_->GetSecondaryId(kCrOSEventsProjectName);
std::optional<uint64_t> profile_id =
key_data_provider_->GetId(kCrOSEventsProjectName);
EXPECT_TRUE(device_id.has_value());
EXPECT_TRUE(profile_id.has_value());
// Ids generated should be different.
EXPECT_NE(device_id.value(), profile_id.value());
}
TEST_F(KeyDataProviderAshTest, SequenceEvents_PrimaryIdEmptyOnNoProfileSetup) {
std::optional<uint64_t> device_id =
key_data_provider_->GetSecondaryId(kCrOSEventsProjectName);
std::optional<uint64_t> profile_id =
key_data_provider_->GetId(kCrOSEventsProjectName);
EXPECT_TRUE(device_id.has_value());
EXPECT_FALSE(profile_id.has_value());
}
} // namespace metrics::structured