#include "components/metrics/clean_exit_beacon.h"
#include <memory>
#include <optional>
#include <string>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/field_trial.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/testing_pref_service.h"
#include "components/prefs/testing_pref_store.h"
#include "components/variations/pref_names.h"
#include "components/variations/variations_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace metrics {
namespace {
const wchar_t kDummyWindowsRegistryKey[] = …;
}
class TestCleanExitBeacon : public CleanExitBeacon { … };
class CleanExitBeaconTest : public ::testing::Test { … };
struct BadBeaconTestParams { … };
class BadBeaconFileTest
: public testing::WithParamInterface<BadBeaconTestParams>,
public CleanExitBeaconTest { … };
struct BeaconConsistencyTestParams { … };
#if BUILDFLAG(IS_IOS)
class BeaconFileAndPlatformBeaconConsistencyTest
: public testing::WithParamInterface<BeaconConsistencyTestParams>,
public CleanExitBeaconTest {};
#endif
TEST_F(CleanExitBeaconTest, CrashStreakMetricWithDefaultPrefs) { … }
TEST_F(CleanExitBeaconTest, CrashStreakMetricWithNoCrashes) { … }
TEST_F(CleanExitBeaconTest, CrashStreakMetricWithSomeCrashes) { … }
TEST_F(CleanExitBeaconTest, CrashIncrementsCrashStreak) { … }
TEST_F(CleanExitBeaconTest,
CrashIncrementsCrashStreakWithDefaultCrashStreakPref) { … }
TEST_F(CleanExitBeaconTest, InitWithoutUserDataDir) { … }
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(BadBeaconFileTest, InitWithUnusableBeaconFile) { … }
TEST_F(CleanExitBeaconTest, InitWithBeaconFile) { … }
TEST_F(CleanExitBeaconTest, InitWithCrashAndBeaconFile) { … }
TEST_F(CleanExitBeaconTest, WriteBeaconValueWhenNotExitingCleanly) { … }
TEST_F(CleanExitBeaconTest, WriteBeaconValueWhenExitingCleanly) { … }
TEST_F(CleanExitBeaconTest, InvalidWriteBeaconValueArgsTriggerDcheck) { … }
#if BUILDFLAG(IS_IOS)
INSTANTIATE_TEST_SUITE_P(
All,
BeaconFileAndPlatformBeaconConsistencyTest,
::testing::Values(
BeaconConsistencyTestParams{
.test_name = "MissingMissing",
.expected_consistency =
CleanExitBeaconConsistency::kMissingMissing},
BeaconConsistencyTestParams{
.test_name = "MissingClean",
.platform_specific_beacon_value = true,
.expected_consistency = CleanExitBeaconConsistency::kMissingClean},
BeaconConsistencyTestParams{
.test_name = "MissingDirty",
.platform_specific_beacon_value = false,
.expected_consistency = CleanExitBeaconConsistency::kMissingDirty},
BeaconConsistencyTestParams{
.test_name = "CleanMissing",
.beacon_file_beacon_value = true,
.expected_consistency = CleanExitBeaconConsistency::kCleanMissing},
BeaconConsistencyTestParams{
.test_name = "DirtyMissing",
.beacon_file_beacon_value = false,
.expected_consistency = CleanExitBeaconConsistency::kDirtyMissing},
BeaconConsistencyTestParams{
.test_name = "CleanClean",
.beacon_file_beacon_value = true,
.platform_specific_beacon_value = true,
.expected_consistency = CleanExitBeaconConsistency::kCleanClean},
BeaconConsistencyTestParams{
.test_name = "CleanDirty",
.beacon_file_beacon_value = true,
.platform_specific_beacon_value = false,
.expected_consistency = CleanExitBeaconConsistency::kCleanDirty},
BeaconConsistencyTestParams{
.test_name = "DirtyClean",
.beacon_file_beacon_value = false,
.platform_specific_beacon_value = true,
.expected_consistency = CleanExitBeaconConsistency::kDirtyClean},
BeaconConsistencyTestParams{
.test_name = "DirtyDirty",
.beacon_file_beacon_value = false,
.platform_specific_beacon_value = false,
.expected_consistency = CleanExitBeaconConsistency::kDirtyDirty}),
[](const ::testing::TestParamInfo<BeaconConsistencyTestParams>& params) {
return params.param.test_name;
});
TEST_P(BeaconFileAndPlatformBeaconConsistencyTest, BeaconConsistency) {
const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
const base::FilePath temp_beacon_file_path =
user_data_dir_path.Append(kCleanExitBeaconFilename);
ASSERT_FALSE(base::PathExists(temp_beacon_file_path));
CleanExitBeacon::ResetStabilityExitedCleanlyForTesting(&prefs_);
BeaconConsistencyTestParams params = GetParam();
if (params.beacon_file_beacon_value) {
ASSERT_TRUE(base::WriteFile(
temp_beacon_file_path,
CleanExitBeacon::CreateBeaconFileContentsForTesting(
params.beacon_file_beacon_value.value(),
0)));
}
if (params.platform_specific_beacon_value) {
CleanExitBeacon::SetUserDefaultsBeacon(
params.platform_specific_beacon_value.value());
}
TestCleanExitBeacon clean_exit_beacon(&prefs_, user_data_dir_path);
histogram_tester_.ExpectUniqueSample("UMA.CleanExitBeaconConsistency3",
params.expected_consistency, 1);
}
#endif
}