// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/metrics/file_metrics_provider.h"

#include <array>
#include <memory>

#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_flattener.h"
#include "base/metrics/histogram_snapshot_manager.h"
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/metrics/persistent_memory_allocator.h"
#include "base/metrics/sparse_histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/metrics/fre_source_trial.h"
#include "components/metrics/metrics_log.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/persistent_system_profile.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/variations/variations_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "third_party/metrics_proto/system_profile.pb.h"

namespace {
const char kMetricsName[] = "TestMetrics";
const char kMergedCountHistogramName[] =
    "UMA.FileMetricsProvider.TestMetrics.MergedHistogramsCount";
const char kMetricsFilename[] = "file.metrics";

void WriteSystemProfileToAllocator(
    base::PersistentHistogramAllocator* allocator) {
  metrics::SystemProfileProto profile_proto;
  // Add a field trial to verify that FileMetricsProvider will produce an
  // independent log with the written system profile. Similarly for the session
  // hash.
  metrics::SystemProfileProto::FieldTrial* trial =
      profile_proto.add_field_trial();
  trial->set_name_id(123);
  trial->set_group_id(456);
  profile_proto.set_session_hash(789);
  metrics::PersistentSystemProfile persistent_profile;
  persistent_profile.RegisterPersistentAllocator(allocator->memory_allocator());
  persistent_profile.SetSystemProfile(profile_proto, /*complete=*/true);
}
}  // namespace

namespace metrics {

class HistogramFlattenerDeltaRecorder : public base::HistogramFlattener {
 public:
  HistogramFlattenerDeltaRecorder() = default;

  HistogramFlattenerDeltaRecorder(const HistogramFlattenerDeltaRecorder&) =
      delete;
  HistogramFlattenerDeltaRecorder& operator=(
      const HistogramFlattenerDeltaRecorder&) = delete;

  void RecordDelta(const base::HistogramBase& histogram,
                   const base::HistogramSamples& snapshot) override {
    // Only remember locally created histograms; they have exactly 2 chars.
    if (histogram.histogram_name().length() == 2) {
      recorded_delta_histogram_names_.emplace_back(histogram.histogram_name());
    }
  }

  std::vector<std::string> GetRecordedDeltaHistogramNames() {
    return recorded_delta_histogram_names_;
  }

 private:
  std::vector<std::string> recorded_delta_histogram_names_;
};

// Exactly the same as FileMetricsProvider, but provides a way to "hook" into
// RecordSourcesChecked() and run a callback each time it is called so that it
// is easier to individually verify the sources being merged.
class TestFileMetricsProvider : public FileMetricsProvider {
 public:
  using FileMetricsProvider::FileMetricsProvider;

  TestFileMetricsProvider(const TestFileMetricsProvider&) = delete;
  TestFileMetricsProvider& operator=(const TestFileMetricsProvider&) = delete;

  ~TestFileMetricsProvider() override = default;

  // Sets the callback to run after RecordSourcesChecked() is called. Used to
  // individually verify the sources being merged.
  void SetSourcesCheckedCallback(base::RepeatingClosure callback) {
    callback_ = std::move(callback);
  }

 private:
  // FileMetricsProvider:
  void RecordSourcesChecked(SourceInfoList* checked,
                            std::vector<size_t> samples_counts) override {
    if (!callback_.is_null()) {
      callback_.Run();
    }

    FileMetricsProvider::RecordSourcesChecked(checked, samples_counts);
  }

  // A callback to run after a call to RecordSourcesChecked().
  base::RepeatingClosure callback_;
};

class FileMetricsProviderTestBase : public testing::Test {
 public:
  FileMetricsProviderTestBase(const FileMetricsProviderTestBase&) = delete;
  FileMetricsProviderTestBase& operator=(const FileMetricsProviderTestBase&) =
      delete;

 protected:
  const size_t kSmallFileSize = 64 << 10;  // 64 KiB
  const size_t kLargeFileSize = 2 << 20;   //  2 MiB

  enum : int { kMaxCreateHistograms = 10 };

  explicit FileMetricsProviderTestBase(bool create_large_files = false,
                                       bool is_fre = false)
      : create_large_files_(create_large_files),
        is_fre_(is_fre),
        statistics_recorder_(
            base::StatisticsRecorder::CreateTemporaryForTesting()),
        prefs_(new TestingPrefServiceSimple) {
    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
    FileMetricsProvider::RegisterSourcePrefs(prefs_->registry(), kMetricsName);
  }

  ~FileMetricsProviderTestBase() override {
    // Clear out any final remaining tasks.
    task_environment_.RunUntilIdle();
    DCHECK_EQ(0U, filter_actions_remaining_);
    // If a global histogram allocator exists at this point then it likely
    // acquired histograms that will continue to point to the released
    // memory and potentially cause use-after-free memory corruption.
    DCHECK(!base::GlobalHistogramAllocator::Get());
  }

  base::test::TaskEnvironment* task_environment() { return &task_environment_; }
  TestingPrefServiceSimple* prefs() { return prefs_.get(); }
  base::FilePath temp_dir() { return temp_dir_.GetPath(); }
  base::FilePath metrics_file() {
    return temp_dir_.GetPath().AppendASCII(kMetricsFilename);
  }

  TestFileMetricsProvider* provider() {
    if (!provider_) {
      provider_ = std::make_unique<TestFileMetricsProvider>(prefs(), is_fre_);
    }
    return provider_.get();
  }

  void OnDidCreateMetricsLog() { provider()->OnDidCreateMetricsLog(); }

  bool HasPreviousSessionData() { return provider()->HasPreviousSessionData(); }

  void MergeHistogramDeltas() {
    provider()->MergeHistogramDeltas(/*async=*/false,
                                     /*done_callback=*/base::DoNothing());
  }

  bool HasIndependentMetrics() { return provider()->HasIndependentMetrics(); }

  bool ProvideIndependentMetrics(
      ChromeUserMetricsExtension* uma_proto,
      base::HistogramSnapshotManager* snapshot_manager) {
    bool success = false;
    bool success_set = false;
    provider()->ProvideIndependentMetrics(
        base::DoNothing(),
        base::BindOnce(
            [](bool* success_ptr, bool* set_ptr, bool s) {
              *success_ptr = s;
              *set_ptr = true;
            },
            &success, &success_set),
        uma_proto, snapshot_manager);

    task_environment()->RunUntilIdle();
    CHECK(success_set);
    return success;
  }

  void RecordInitialHistogramSnapshots(
      base::HistogramSnapshotManager* snapshot_manager) {
    provider()->RecordInitialHistogramSnapshots(snapshot_manager);
  }

  size_t GetSnapshotHistogramCount() {
    // Merge the data from the allocator into the StatisticsRecorder.
    MergeHistogramDeltas();

    // Flatten what is known to see what has changed since the last time.
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    // "true" to the begin() includes histograms held in persistent storage.
    base::StatisticsRecorder::PrepareDeltas(true, base::Histogram::kNoFlags,
                                            base::Histogram::kNoFlags,
                                            &snapshot_manager);
    return flattener.GetRecordedDeltaHistogramNames().size();
  }

  size_t GetIndependentHistogramCount() {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    ChromeUserMetricsExtension uma_proto;
    provider()->ProvideIndependentMetrics(base::DoNothing(),
                                          base::BindOnce([](bool success) {}),
                                          &uma_proto, &snapshot_manager);

    task_environment()->RunUntilIdle();
    return flattener.GetRecordedDeltaHistogramNames().size();
  }

  void CreateGlobalHistograms(int histogram_count) {
    DCHECK_GT(kMaxCreateHistograms, histogram_count);

    // Create both sparse and normal histograms in the allocator. Make them
    // stability histograms to ensure that the histograms are snapshotted (in
    // the case of stability logs) or are put into independent logs. Histogram
    // names must be 2 characters (see HistogramFlattenerDeltaRecorder).
    created_histograms_[0] = base::SparseHistogram::FactoryGet(
        "h0", /*flags=*/base::HistogramBase::Flags::kUmaStabilityHistogramFlag);
    created_histograms_[0]->Add(0);
    for (int i = 1; i < histogram_count; ++i) {
      created_histograms_[i] = base::Histogram::FactoryGet(
          base::StringPrintf("h%d", i), 1, 100, 10,
          /*flags=*/base::HistogramBase::Flags::kUmaStabilityHistogramFlag);
      created_histograms_[i]->Add(i);
    }
  }

  void WriteMetricsFile(const base::FilePath& path,
                        base::PersistentHistogramAllocator* metrics) {
    base::File writer(path,
                      base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
    // Use DCHECK so the stack-trace will indicate where this was called.
    DCHECK(writer.IsValid()) << path;
    size_t file_size = create_large_files_ ? metrics->size() : metrics->used();
    int written =
        UNSAFE_TODO(writer.Write(0, (const char*)metrics->data(), file_size));
    DCHECK_EQ(static_cast<int>(file_size), written);
  }

  void WriteMetricsFileAtTime(const base::FilePath& path,
                              base::PersistentHistogramAllocator* metrics,
                              base::Time write_time) {
    WriteMetricsFile(path, metrics);
    base::TouchFile(path, write_time, write_time);
  }

  base::GlobalHistogramAllocator* CreateMetricsFileWithHistograms(
      const base::FilePath& file_path,
      base::Time write_time,
      int histogram_count,
      base::OnceCallback<void(base::PersistentHistogramAllocator*)> callback) {
    base::GlobalHistogramAllocator::CreateWithLocalMemory(
        create_large_files_ ? kLargeFileSize : kSmallFileSize, 0, kMetricsName);

    CreateGlobalHistograms(histogram_count);

    base::GlobalHistogramAllocator* histogram_allocator =
        base::GlobalHistogramAllocator::ReleaseForTesting();
    std::move(callback).Run(histogram_allocator);

    WriteMetricsFileAtTime(file_path, histogram_allocator, write_time);
    return histogram_allocator;
  }

  void CreateEmptyFile(const base::FilePath& file_path) {
    base::File empty(file_path,
                     base::File::FLAG_CREATE | base::File::FLAG_WRITE);
  }

  void CreateEmptyFileAtTime(const base::FilePath& file_path,
                             base::Time write_time) {
    base::File empty(file_path,
                     base::File::FLAG_CREATE | base::File::FLAG_WRITE);
    base::TouchFile(file_path,
                    /*last_accessed=*/write_time,
                    /*last_modified=*/write_time);
  }

  base::GlobalHistogramAllocator* CreateMetricsFileWithHistograms(
      int histogram_count) {
    return CreateMetricsFileWithHistograms(
        metrics_file(), base::Time::Now(), histogram_count,
        base::BindOnce([](base::PersistentHistogramAllocator* allocator) {}));
  }

  base::HistogramBase* GetCreatedHistogram(int index) {
    DCHECK_GT(kMaxCreateHistograms, index);
    return created_histograms_[index];
  }

  void SetFilterActions(FileMetricsProvider::Params* params,
                        const FileMetricsProvider::FilterAction* actions,
                        size_t count) {
    filter_actions_ = actions;
    filter_actions_remaining_ = count;
    params->filter = base::BindRepeating(
        &FileMetricsProviderTestBase::FilterSourcePath, base::Unretained(this));
  }

  const bool create_large_files_;
  const bool is_fre_ = false;

 private:
  FileMetricsProvider::FilterAction FilterSourcePath(
      const base::FilePath& path) {
    DCHECK_LT(0U, filter_actions_remaining_);
    --filter_actions_remaining_;
    return UNSAFE_TODO(*filter_actions_++);
  }

  base::test::TaskEnvironment task_environment_;
  std::unique_ptr<base::StatisticsRecorder> statistics_recorder_;
  base::ScopedTempDir temp_dir_;
  std::unique_ptr<TestingPrefServiceSimple> prefs_;
  std::unique_ptr<TestFileMetricsProvider> provider_;
  std::array<base::HistogramBase*, kMaxCreateHistograms> created_histograms_;

  raw_ptr<const FileMetricsProvider::FilterAction, AllowPtrArithmetic>
      filter_actions_ = nullptr;
  size_t filter_actions_remaining_ = 0;
};

class FileMetricsProviderTest : public FileMetricsProviderTestBase,
                                public testing::WithParamInterface<bool> {
 public:
  FileMetricsProviderTest() : FileMetricsProviderTestBase(GetParam()) {}
};

// Run all test cases with both small and large files.
INSTANTIATE_TEST_SUITE_P(SmallAndLargeFiles,
                         FileMetricsProviderTest,
                         testing::Bool());

TEST_P(FileMetricsProviderTest, AccessMetrics) {
  ASSERT_FALSE(PathExists(metrics_file()));
  base::HistogramTester histogram_tester;

  base::Time metrics_time = base::Time::Now() - base::Minutes(5);
  base::GlobalHistogramAllocator* histogram_allocator =
      CreateMetricsFileWithHistograms(2);
  ASSERT_TRUE(PathExists(metrics_file()));
  base::TouchFile(metrics_file(), metrics_time, metrics_time);

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName),
      /*metrics_reporting_enabled=*/true);
  histogram_tester.ExpectTotalCount(kMergedCountHistogramName,
                                    /*expected_count=*/0);

  // Record embedded snapshots via snapshot-manager.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  histogram_tester.ExpectUniqueSample(kMergedCountHistogramName, /*sample=*/2,
                                      /*expected_bucket_count=*/1);
  EXPECT_FALSE(base::PathExists(metrics_file()));

  // Make sure a second call to the snapshot-recorder doesn't break anything.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());

  // File should have been deleted but recreate it to test behavior should
  // the file not be deletable by this process.
  WriteMetricsFileAtTime(metrics_file(), histogram_allocator, metrics_time);

  // Second full run on the same file should produce nothing.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());
  histogram_tester.ExpectUniqueSample(kMergedCountHistogramName, /*sample=*/2,
                                      /*expected_bucket_count=*/1);
  EXPECT_FALSE(base::PathExists(metrics_file()));

  // Recreate the file to indicate that it is "new" and must be recorded.
  metrics_time = metrics_time + base::Minutes(1);
  WriteMetricsFileAtTime(metrics_file(), histogram_allocator, metrics_time);

  // This run should again have "new" histograms.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  histogram_tester.ExpectUniqueSample(kMergedCountHistogramName, /*sample=*/2,
                                      /*expected_bucket_count=*/2);
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessTimeLimitedFile) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::Time metrics_time = base::Time::Now() - base::Hours(5);
  CreateMetricsFileWithHistograms(2);
  ASSERT_TRUE(PathExists(metrics_file()));
  base::TouchFile(metrics_file(), metrics_time, metrics_time);

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  params.max_age = base::Hours(1);
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Attempt to access the file should return nothing.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, FilterDelaysFile) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::Time now_time = base::Time::Now();
  base::Time metrics_time = now_time - base::Minutes(5);
  CreateMetricsFileWithHistograms(2);
  ASSERT_TRUE(PathExists(metrics_file()));
  base::TouchFile(metrics_file(), metrics_time, metrics_time);
  base::File::Info fileinfo;
  ASSERT_TRUE(base::GetFileInfo(metrics_file(), &fileinfo));
  EXPECT_GT(base::Time::Now(), fileinfo.last_modified);

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  const FileMetricsProvider::FilterAction actions[] = {
      FileMetricsProvider::FILTER_TRY_LATER,
      FileMetricsProvider::FILTER_PROCESS_FILE};
  SetFilterActions(&params, actions, std::size(actions));
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Processing the file should touch it but yield no results. File timestamp
  // accuracy is limited so compare the touched time to a couple seconds past.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());
  EXPECT_TRUE(base::PathExists(metrics_file()));
  ASSERT_TRUE(base::GetFileInfo(metrics_file(), &fileinfo));
  EXPECT_LT(metrics_time, fileinfo.last_modified);
  EXPECT_LE(now_time - base::Seconds(2), fileinfo.last_modified);

  // Second full run on the same file should process the file.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, FilterSkipsFile) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::Time now_time = base::Time::Now();
  base::Time metrics_time = now_time - base::Minutes(5);
  CreateMetricsFileWithHistograms(2);
  ASSERT_TRUE(PathExists(metrics_file()));
  base::TouchFile(metrics_file(), metrics_time, metrics_time);
  base::File::Info fileinfo;
  ASSERT_TRUE(base::GetFileInfo(metrics_file(), &fileinfo));
  EXPECT_GT(base::Time::Now(), fileinfo.last_modified);

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  const FileMetricsProvider::FilterAction actions[] = {
      FileMetricsProvider::FILTER_SKIP_FILE};
  SetFilterActions(&params, actions, std::size(actions));
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Processing the file should delete it.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessDirectory) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::GlobalHistogramAllocator::CreateWithLocalMemory(
      64 << 10, 0, kMetricsName);
  base::GlobalHistogramAllocator* allocator =
      base::GlobalHistogramAllocator::Get();
  base::HistogramBase* histogram;

  // Create files starting with a timestamp a few minutes back.
  base::Time base_time = base::Time::Now() - base::Minutes(10);

  // Create some files in an odd order. The files are "touched" back in time to
  // ensure that each file has a later timestamp on disk than the previous one.
  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII(".foo.pma"),
                         allocator, base_time);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("_bar.pma"),
                         allocator, base_time);
  // Histogram names must be 2 characters (see HistogramFlattenerDeltaRecorder).
  histogram = base::Histogram::FactoryGet("h1", 1, 100, 10, 0);
  histogram->Add(1);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("a1.pma"),
                         allocator, base_time + base::Minutes(1));

  histogram = base::Histogram::FactoryGet("h2", 1, 100, 10, 0);
  histogram->Add(2);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("c2.pma"),
                         allocator, base_time + base::Minutes(2));

  histogram = base::Histogram::FactoryGet("h3", 1, 100, 10, 0);
  histogram->Add(3);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("b3.pma"),
                         allocator, base_time + base::Minutes(3));

  histogram = base::Histogram::FactoryGet("h4", 1, 100, 10, 0);
  histogram->Add(3);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("d4.pma"),
                         allocator, base_time + base::Minutes(4));

  base::TouchFile(metrics_files.GetPath().AppendASCII("b3.pma"),
                  base_time + base::Minutes(5), base_time + base::Minutes(5));

  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("baz"), allocator,
                         base_time + base::Minutes(6));

  // The global allocator has to be detached here so that no metrics created
  // by code called below get stored in it as that would make for potential
  // use-after-free operations if that code is called again.
  base::GlobalHistogramAllocator::ReleaseForTesting();

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_files.GetPath(),
          FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
          FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  std::vector<uint32_t> actual_order;
  provider()->SetSourcesCheckedCallback(base::BindLambdaForTesting(
      [&] { actual_order.push_back(GetSnapshotHistogramCount()); }));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();

  // Files could come out in the order: a1, c2, d4, b3. They are recognizable by
  // the number of histograms contained within each. The "0" is the last merge
  // done, which detects that there are no more files to merge.
  EXPECT_THAT(actual_order, testing::ElementsAre(1, 2, 4, 3, 0));

  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("a1.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("c2.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("b3.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("d4.pma")));
  EXPECT_TRUE(
      base::PathExists(metrics_files.GetPath().AppendASCII(".foo.pma")));
  EXPECT_TRUE(
      base::PathExists(metrics_files.GetPath().AppendASCII("_bar.pma")));
  EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("baz")));
}

TEST_P(FileMetricsProviderTest, AccessDirectoryWithInvalidFiles) {
  ASSERT_FALSE(PathExists(metrics_file()));

  // Create files starting with a timestamp a few minutes back.
  base::Time base_time = base::Time::Now() - base::Minutes(10);

  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  base::FilePath dir = metrics_files.GetPath();

  CreateMetricsFileWithHistograms(
      dir.AppendASCII("h1.pma"),
      base_time + base::Minutes(1), 1,
      base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
        allocator->memory_allocator()->SetMemoryState(
            base::PersistentMemoryAllocator::MEMORY_DELETED);
      }));

  CreateMetricsFileWithHistograms(
      dir.AppendASCII("h2.pma"),
      base_time + base::Minutes(2), 2,
      base::BindOnce(&WriteSystemProfileToAllocator));

  CreateMetricsFileWithHistograms(
      dir.AppendASCII("h3.pma"),
      base_time + base::Minutes(3), 3,
      base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
        allocator->memory_allocator()->SetMemoryState(
            base::PersistentMemoryAllocator::MEMORY_DELETED);
      }));

  CreateEmptyFile(dir.AppendASCII("h4.pma"));
  base::TouchFile(dir.AppendASCII("h4.pma"),
                  base_time + base::Minutes(4), base_time + base::Minutes(4));

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          dir,
          FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // No files yet.
  EXPECT_EQ(0U, GetIndependentHistogramCount());
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h1.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h2.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h3.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h4.pma")));

  // H1 should be skipped and H2 available.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(dir.AppendASCII("h1.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h2.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h3.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h4.pma")));

  // H2 should be read and the file deleted.
  EXPECT_EQ(2U, GetIndependentHistogramCount());
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(dir.AppendASCII("h2.pma")));

  // Nothing else should be found but the last (valid but empty) file will
  // stick around to be processed later (should it get expanded).
  EXPECT_EQ(0U, GetIndependentHistogramCount());
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(dir.AppendASCII("h3.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h4.pma")));
}

TEST_P(FileMetricsProviderTest, AccessTimeLimitedDirectory) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::GlobalHistogramAllocator::CreateWithLocalMemory(64 << 10, 0,
                                                        kMetricsName);
  base::GlobalHistogramAllocator* allocator =
      base::GlobalHistogramAllocator::Get();
  base::HistogramBase* histogram;

  // Create one old file and one new file. Histogram names must be 2 characters
  // (see HistogramFlattenerDeltaRecorder).
  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  histogram = base::Histogram::FactoryGet("h1", 1, 100, 10, 0);
  histogram->Add(1);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("a1.pma"),
                         allocator, base::Time::Now() - base::Hours(1));

  histogram = base::Histogram::FactoryGet("h2", 1, 100, 10, 0);
  histogram->Add(2);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("b2.pma"),
                         allocator, base::Time::Now());

  // The global allocator has to be detached here so that no metrics created
  // by code called below get stored in it as that would make for potential
  // use-after-free operations if that code is called again.
  base::GlobalHistogramAllocator::ReleaseForTesting();

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_files.GetPath(),
      FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  params.max_age = base::Minutes(30);
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Only b2, with 2 histograms, should be read.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());

  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("a1.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("b2.pma")));
}

TEST_P(FileMetricsProviderTest, AccessCountLimitedDirectory) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::GlobalHistogramAllocator::CreateWithLocalMemory(64 << 10, 0,
                                                        kMetricsName);
  base::GlobalHistogramAllocator* allocator =
      base::GlobalHistogramAllocator::Get();
  base::HistogramBase* histogram;

  // Create one old file and one new file. Histogram names must be 2 characters
  // (see HistogramFlattenerDeltaRecorder).
  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  histogram = base::Histogram::FactoryGet("h1", 1, 100, 10, 0);
  histogram->Add(1);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("a1.pma"),
                         allocator, base::Time::Now() - base::Hours(1));

  histogram = base::Histogram::FactoryGet("h2", 1, 100, 10, 0);
  histogram->Add(2);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("b2.pma"),
                         allocator, base::Time::Now());

  // The global allocator has to be detached here so that no metrics created
  // by code called below get stored in it as that would make for potential
  // use-after-free operations if that code is called again.
  base::GlobalHistogramAllocator::ReleaseForTesting();

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_files.GetPath(),
      FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  params.max_dir_files = 1;
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Only b2, with 2 histograms, should be read.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());

  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("a1.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("b2.pma")));
}

TEST_P(FileMetricsProviderTest, AccessSizeLimitedDirectory) {
  // This only works with large files that are big enough to count.
  if (!create_large_files_)
    return;

  ASSERT_FALSE(PathExists(metrics_file()));

  size_t file_size_kib = 64;
  base::GlobalHistogramAllocator::CreateWithLocalMemory(file_size_kib << 10, 0,
                                                        kMetricsName);
  base::GlobalHistogramAllocator* allocator =
      base::GlobalHistogramAllocator::Get();
  base::HistogramBase* histogram;

  // Create one old file and one new file. Histogram names must be 2 characters
  // (see HistogramFlattenerDeltaRecorder).
  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  histogram = base::Histogram::FactoryGet("h1", 1, 100, 10, 0);
  histogram->Add(1);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("a1.pma"),
                         allocator, base::Time::Now() - base::Hours(1));

  histogram = base::Histogram::FactoryGet("h2", 1, 100, 10, 0);
  histogram->Add(2);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("b2.pma"),
                         allocator, base::Time::Now());

  // The global allocator has to be detached here so that no metrics created
  // by code called below get stored in it as that would make for potential
  // use-after-free operations if that code is called again.
  base::GlobalHistogramAllocator::ReleaseForTesting();

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_files.GetPath(),
      FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  params.max_dir_kib = file_size_kib + 1;
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Only b2, with 2 histograms, should be read.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());

  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("a1.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("b2.pma")));
}

TEST_P(FileMetricsProviderTest, AccessFilteredDirectory) {
  ASSERT_FALSE(PathExists(metrics_file()));

  base::GlobalHistogramAllocator::CreateWithLocalMemory(64 << 10, 0,
                                                        kMetricsName);
  base::GlobalHistogramAllocator* allocator =
      base::GlobalHistogramAllocator::Get();
  base::HistogramBase* histogram;

  // Create files starting with a timestamp a few minutes back.
  base::Time base_time = base::Time::Now() - base::Minutes(10);

  // Create some files in an odd order. The files are "touched" back in time to
  // ensure that each file has a later timestamp on disk than the previous one.
  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  // Histogram names must be 2 characters (see HistogramFlattenerDeltaRecorder).
  histogram = base::Histogram::FactoryGet("h1", 1, 100, 10, 0);
  histogram->Add(1);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("a1.pma"),
                         allocator, base_time + base::Minutes(1));

  histogram = base::Histogram::FactoryGet("h2", 1, 100, 10, 0);
  histogram->Add(2);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("c2.pma"),
                         allocator, base_time + base::Minutes(2));

  histogram = base::Histogram::FactoryGet("h3", 1, 100, 10, 0);
  histogram->Add(3);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("b3.pma"),
                         allocator, base_time + base::Minutes(3));

  histogram = base::Histogram::FactoryGet("h4", 1, 100, 10, 0);
  histogram->Add(3);
  WriteMetricsFileAtTime(metrics_files.GetPath().AppendASCII("d4.pma"),
                         allocator, base_time + base::Minutes(4));

  base::TouchFile(metrics_files.GetPath().AppendASCII("b3.pma"),
                  base_time + base::Minutes(5), base_time + base::Minutes(5));

  // The global allocator has to be detached here so that no metrics created
  // by code called below get stored in it as that would make for potential
  // use-after-free operations if that code is called again.
  base::GlobalHistogramAllocator::ReleaseForTesting();

  // Register the file and allow the "checker" task to run.
  FileMetricsProvider::Params params(
      metrics_files.GetPath(),
      FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
  const FileMetricsProvider::FilterAction actions[] = {
      FileMetricsProvider::FILTER_PROCESS_FILE,   // a1
      FileMetricsProvider::FILTER_TRY_LATER,      // c2
      FileMetricsProvider::FILTER_SKIP_FILE,      // d4
      FileMetricsProvider::FILTER_PROCESS_FILE,   // b3
      FileMetricsProvider::FILTER_PROCESS_FILE};  // c2 (again)
  SetFilterActions(&params, actions, std::size(actions));
  provider()->RegisterSource(params, /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  std::vector<uint32_t> actual_order;
  provider()->SetSourcesCheckedCallback(base::BindLambdaForTesting(
      [&] { actual_order.push_back(GetSnapshotHistogramCount()); }));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();

  // Files could come out in the order: a1, b3, c2. They are recognizable by the
  // number of histograms contained within each. The "0" is the last merge done,
  // which detects that there are no more files to merge.
  EXPECT_THAT(actual_order, testing::ElementsAre(1, 3, 2, 0));

  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("a1.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("c2.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("b3.pma")));
  EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("d4.pma")));
}

TEST_P(FileMetricsProviderTest, AccessReadWriteMetrics) {
  // Create a global histogram allocator that maps to a file.
  ASSERT_FALSE(PathExists(metrics_file()));
  base::GlobalHistogramAllocator::CreateWithFile(
      metrics_file(),
      create_large_files_ ? kLargeFileSize : kSmallFileSize,
      0, kMetricsName);
  CreateGlobalHistograms(2);
  ASSERT_TRUE(PathExists(metrics_file()));
  base::HistogramBase* h0 = GetCreatedHistogram(0);
  base::HistogramBase* h1 = GetCreatedHistogram(1);
  DCHECK(h0);
  DCHECK(h1);
  base::GlobalHistogramAllocator::ReleaseForTesting();

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ACTIVE_FILE,
          FileMetricsProvider::ASSOCIATE_CURRENT_RUN),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(2U, GetSnapshotHistogramCount());
  EXPECT_TRUE(base::PathExists(metrics_file()));

  // Make sure a second call to the snapshot-recorder doesn't break anything.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());
  EXPECT_TRUE(base::PathExists(metrics_file()));

  // Change a histogram and ensure that it's counted.
  h0->Add(0);
  EXPECT_EQ(1U, GetSnapshotHistogramCount());
  EXPECT_TRUE(base::PathExists(metrics_file()));

  // Change the other histogram and verify.
  h1->Add(11);
  EXPECT_EQ(1U, GetSnapshotHistogramCount());
  EXPECT_TRUE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessInitialMetrics) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(2);

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_PREVIOUS_RUN, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  ASSERT_TRUE(HasPreviousSessionData());
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    RecordInitialHistogramSnapshots(&snapshot_manager);
    EXPECT_EQ(2U, flattener.GetRecordedDeltaHistogramNames().size());
  }
  EXPECT_TRUE(base::PathExists(metrics_file()));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));

  // A run for normal histograms should produce nothing.
  CreateMetricsFileWithHistograms(2);
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_EQ(0U, GetSnapshotHistogramCount());
  EXPECT_TRUE(base::PathExists(metrics_file()));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_TRUE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessEmbeddedProfileMetricsWithoutProfile) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(2);

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    ChromeUserMetricsExtension uma_proto;

    // A read of metrics with internal profiles should return nothing.
    EXPECT_FALSE(HasIndependentMetrics());
    EXPECT_FALSE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
  }
  EXPECT_TRUE(base::PathExists(metrics_file()));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessEmbeddedProfileMetricsWithProfile) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(
      metrics_file(), base::Time::Now(), 2,
      base::BindOnce(&WriteSystemProfileToAllocator));

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    RecordInitialHistogramSnapshots(&snapshot_manager);
    EXPECT_EQ(0U, flattener.GetRecordedDeltaHistogramNames().size());

    // A read of metrics with internal profiles should return one result, and
    // the independent log generated should have the embedded system profile.
    ChromeUserMetricsExtension uma_proto;
    EXPECT_TRUE(HasIndependentMetrics());
    EXPECT_TRUE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
    ASSERT_TRUE(uma_proto.has_system_profile());
    ASSERT_EQ(1, uma_proto.system_profile().field_trial_size());
    EXPECT_EQ(123U, uma_proto.system_profile().field_trial(0).name_id());
    EXPECT_EQ(456U, uma_proto.system_profile().field_trial(0).group_id());
    EXPECT_EQ(789U, uma_proto.system_profile().session_hash());
    EXPECT_FALSE(HasIndependentMetrics());
    EXPECT_FALSE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
  }
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessEmbeddedFallbackMetricsWithoutProfile) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(2);

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN,
          kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  ASSERT_TRUE(HasPreviousSessionData());
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    RecordInitialHistogramSnapshots(&snapshot_manager);
    EXPECT_EQ(2U, flattener.GetRecordedDeltaHistogramNames().size());

    // A read of metrics with internal profiles should return nothing.
    ChromeUserMetricsExtension uma_proto;
    EXPECT_FALSE(HasIndependentMetrics());
    EXPECT_FALSE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
  }
  EXPECT_TRUE(base::PathExists(metrics_file()));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessEmbeddedFallbackMetricsWithProfile) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(
      metrics_file(), base::Time::Now(), 2,
      base::BindOnce(&WriteSystemProfileToAllocator));

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN,
          kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  EXPECT_FALSE(HasPreviousSessionData());
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);
    RecordInitialHistogramSnapshots(&snapshot_manager);
    EXPECT_EQ(0U, flattener.GetRecordedDeltaHistogramNames().size());

    // A read of metrics with internal profiles should return one result.
    ChromeUserMetricsExtension uma_proto;
    EXPECT_TRUE(HasIndependentMetrics());
    EXPECT_TRUE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
    EXPECT_FALSE(HasIndependentMetrics());
    EXPECT_FALSE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
  }
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, AccessEmbeddedProfileMetricsFromDir) {
  const int file_count = 3;
  base::Time file_base_time = base::Time::Now();
  std::vector<base::FilePath> file_names;
  for (int i = 0; i < file_count; ++i) {
    CreateMetricsFileWithHistograms(
        metrics_file(), base::Time::Now(), 2,
        base::BindOnce(&WriteSystemProfileToAllocator));
    ASSERT_TRUE(PathExists(metrics_file()));
    char new_name[] = "hX";
    new_name[1] = '1' + i;
    base::FilePath file_name = temp_dir().AppendASCII(new_name).AddExtension(
        base::PersistentMemoryAllocator::kFileExtension);
    base::Time file_time = file_base_time - base::Minutes(file_count - i);
    base::TouchFile(metrics_file(), file_time, file_time);
    base::Move(metrics_file(), file_name);
    file_names.push_back(std::move(file_name));
  }

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          temp_dir(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE),
      /*metrics_reporting_enabled=*/true);

  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();

  // A read of metrics with internal profiles should return one result.
  HistogramFlattenerDeltaRecorder flattener;
  base::HistogramSnapshotManager snapshot_manager(&flattener);
  ChromeUserMetricsExtension uma_proto;
  for (int i = 0; i < file_count; ++i) {
    EXPECT_TRUE(HasIndependentMetrics()) << i;
    EXPECT_TRUE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager)) << i;
    task_environment()->RunUntilIdle();
  }
  EXPECT_FALSE(HasIndependentMetrics());
  EXPECT_FALSE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));

  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  for (const auto& file_name : file_names)
    EXPECT_FALSE(base::PathExists(file_name));
}

TEST_P(FileMetricsProviderTest,
       RecordInitialHistogramSnapshotsStabilityHistograms) {
  // Create a metrics file with 2 non-stability histograms and 2 stability
  // histograms. Histogram names must be 2 characters (see
  // HistogramFlattenerDeltaRecorder).
  ASSERT_FALSE(PathExists(metrics_file()));
  base::GlobalHistogramAllocator::CreateWithLocalMemory(
      create_large_files_ ? kLargeFileSize : kSmallFileSize, 0, kMetricsName);
  base::HistogramBase* h0 = base::SparseHistogram::FactoryGet(
      "h0", /*flags=*/base::HistogramBase::Flags::kUmaStabilityHistogramFlag);
  h0->Add(0);
  base::HistogramBase* h1 = base::SparseHistogram::FactoryGet(
      "h1", /*flags=*/base::HistogramBase::Flags::kUmaTargetedHistogramFlag);
  h1->Add(0);
  base::HistogramBase* h2 = base::Histogram::FactoryGet(
      "h2", 1, 100, 10,
      /*flags=*/base::HistogramBase::Flags::kUmaStabilityHistogramFlag);
  h2->Add(0);
  base::HistogramBase* h3 = base::Histogram::FactoryGet(
      "h3", 1, 100, 10,
      /*flags=*/base::HistogramBase::Flags::kUmaTargetedHistogramFlag);
  h3->Add(0);
  base::GlobalHistogramAllocator* histogram_allocator =
      base::GlobalHistogramAllocator::ReleaseForTesting();
  WriteMetricsFileAtTime(metrics_file(), histogram_allocator,
                         base::Time::Now());
  ASSERT_TRUE(PathExists(metrics_file()));

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_PREVIOUS_RUN, kMetricsName),
      /*metrics_reporting_enabled=*/true);
  ASSERT_TRUE(HasPreviousSessionData());
  task_environment()->RunUntilIdle();

  // Record embedded snapshots via snapshot-manager.
  HistogramFlattenerDeltaRecorder flattener;
  base::HistogramSnapshotManager snapshot_manager(&flattener);
  RecordInitialHistogramSnapshots(&snapshot_manager);

  // Verify that only the stability histograms were snapshotted.
  EXPECT_THAT(flattener.GetRecordedDeltaHistogramNames(),
              testing::ElementsAre("h0", "h2"));

  // The metrics file should eventually be deleted.
  EXPECT_TRUE(base::PathExists(metrics_file()));
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, IndependentLogContainsUmaHistograms) {
  ASSERT_FALSE(PathExists(metrics_file()));
  // Create a metrics file with 2 UMA histograms and 2 non-UMA histograms.
  // Histogram names must be 2 characters (see HistogramFlattenerDeltaRecorder).
  base::GlobalHistogramAllocator::CreateWithLocalMemory(
      create_large_files_ ? kLargeFileSize : kSmallFileSize, 0, kMetricsName);
  base::HistogramBase* h0 = base::SparseHistogram::FactoryGet(
      "h0", /*flags=*/base::HistogramBase::Flags::kUmaTargetedHistogramFlag);
  h0->Add(0);
  base::HistogramBase* h1 = base::SparseHistogram::FactoryGet(
      "h1", /*flags=*/base::HistogramBase::Flags::kNoFlags);
  h1->Add(0);
  base::HistogramBase* h2 = base::Histogram::FactoryGet(
      "h2", 1, 100, 10,
      /*flags=*/base::HistogramBase::Flags::kUmaStabilityHistogramFlag);
  h2->Add(0);
  base::HistogramBase* h3 = base::Histogram::FactoryGet(
      "h3", 1, 100, 10,
      /*flags=*/base::HistogramBase::Flags::kNoFlags);
  h3->Add(0);
  base::GlobalHistogramAllocator* histogram_allocator =
      base::GlobalHistogramAllocator::ReleaseForTesting();
  // Write a system profile so that an independent log can successfully be
  // created from the metrics file.
  WriteSystemProfileToAllocator(histogram_allocator);
  WriteMetricsFileAtTime(metrics_file(), histogram_allocator,
                         base::Time::Now());
  ASSERT_TRUE(PathExists(metrics_file()));

  // Register the file and allow the "checker" task to run.
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/true);
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();

  // Verify that the independent log provided only contains UMA histograms (both
  // stability and non-stability).
  ChromeUserMetricsExtension uma_proto;
  HistogramFlattenerDeltaRecorder flattener;
  base::HistogramSnapshotManager snapshot_manager(&flattener);
  EXPECT_TRUE(HasIndependentMetrics());
  EXPECT_TRUE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
  EXPECT_THAT(flattener.GetRecordedDeltaHistogramNames(),
              testing::ElementsAre("h0", "h2"));

  // The metrics file should eventually be deleted.
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

// Verifies that if the embedded system profile in the file does not contain
// a client UUID, the generated independent log's client ID is not overwritten.
TEST_P(FileMetricsProviderTest, EmbeddedProfileWithoutClientUuid) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(
      metrics_file(), base::Time::Now(), 2,
      base::BindOnce(&WriteSystemProfileToAllocator));

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);

    // Since the embedded system profile has no client_uuid set (see
    // WriteSystemProfileToAllocator()), the client ID written in |uma_proto|
    // should be kept.
    ChromeUserMetricsExtension uma_proto;
    uma_proto.set_client_id(1);
    EXPECT_TRUE(HasIndependentMetrics());
    EXPECT_TRUE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
    EXPECT_EQ(uma_proto.client_id(), 1U);
  }
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

// Verifies that if the embedded system profile in the file contains a client
// UUID, it is used as the generated independent log's client ID.
TEST_P(FileMetricsProviderTest, EmbeddedProfileWithClientUuid) {
  ASSERT_FALSE(PathExists(metrics_file()));
  static constexpr char kProfileClientUuid[] = "abc";
  CreateMetricsFileWithHistograms(
      metrics_file(), base::Time::Now(), 2,
      base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
        metrics::SystemProfileProto profile_proto;
        profile_proto.set_client_uuid(kProfileClientUuid);

        metrics::PersistentSystemProfile persistent_profile;
        persistent_profile.RegisterPersistentAllocator(
            allocator->memory_allocator());
        persistent_profile.SetSystemProfile(profile_proto, /*complete=*/true);
      }));

  // Register the file and allow the "checker" task to run.
  ASSERT_TRUE(PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/true);

  // Record embedded snapshots via snapshot-manager.
  OnDidCreateMetricsLog();
  task_environment()->RunUntilIdle();
  {
    HistogramFlattenerDeltaRecorder flattener;
    base::HistogramSnapshotManager snapshot_manager(&flattener);

    // Since the embedded system profile contains a client_uuid, the client ID
    // in |uma_proto| should be overwritten.
    ChromeUserMetricsExtension uma_proto;
    uma_proto.set_client_id(1);
    EXPECT_TRUE(HasIndependentMetrics());
    EXPECT_TRUE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
    EXPECT_NE(uma_proto.client_id(), 1U);
    EXPECT_EQ(uma_proto.client_id(), MetricsLog::Hash(kProfileClientUuid));
  }
  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, MetricsDisabledRegisterAtomicFile) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(
      metrics_file(), base::Time::Now() - base::Minutes(10), 1,
      base::BindOnce(&WriteSystemProfileToAllocator));
  EXPECT_TRUE(base::PathExists(metrics_file()));

  EXPECT_TRUE(base::PathExists(metrics_file()));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
          FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName),
      /*metrics_reporting_enabled=*/false);

  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(metrics_file()));
}

TEST_P(FileMetricsProviderTest, MetricsDisabledRegisterAtomicDir) {
  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  base::FilePath dir = metrics_files.GetPath();

  CreateMetricsFileWithHistograms(
      dir.AppendASCII("h1.pma"), base::Time::Now() - base::Minutes(10), 1,
      base::BindOnce(&WriteSystemProfileToAllocator));
  // Also create an empty file there to test the multiple-files in dir case.
  CreateEmptyFile(dir.AppendASCII("h2.pma"));

  EXPECT_TRUE(base::PathExists(dir));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h1.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h2.pma")));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_files.GetPath(),
          FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/false);

  task_environment()->RunUntilIdle();
  EXPECT_FALSE(base::PathExists(dir));
}

TEST_P(FileMetricsProviderTest, MetricsDisabledRegisterActiveFile) {
  ASSERT_FALSE(PathExists(metrics_file()));
  CreateMetricsFileWithHistograms(
      metrics_file(), base::Time::Now() - base::Minutes(10), 1,
      base::BindOnce(&WriteSystemProfileToAllocator));
  EXPECT_TRUE(base::PathExists(metrics_file()));

  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ACTIVE_FILE,
          FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName),
      /*metrics_reporting_enabled=*/false);

  task_environment()->RunUntilIdle();
  // Active file should not be deleted.
  EXPECT_TRUE(base::PathExists(metrics_file()));
}

class FileMetricsProviderFRETrialTest : public FileMetricsProviderTestBase {
 public:
  explicit FileMetricsProviderFRETrialTest(bool is_fre = false)
      : FileMetricsProviderTestBase(/*create_large_files=*/false, is_fre),
        entropy_providers_(
            std::make_unique<const variations::MockEntropyProviders>(
                variations::MockEntropyProviders::Results{
                    .low_entropy = variations::kAlwaysUseLastGroup})) {}

 protected:
  void SetUp() override {
    scoped_feature_list_.InitWithEmptyFeatureAndFieldTrialLists();
    fre_source_trial::RegisterLocalStatePrefs(local_state_.registry());
    ASSERT_FALSE(
        base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
  }

  base::test::ScopedFeatureList scoped_feature_list_;
  TestingPrefServiceSimple local_state_;
  std::unique_ptr<const variations::MockEntropyProviders> entropy_providers_;
};

TEST_F(FileMetricsProviderFRETrialTest, DoNotParticipateInExperiment) {
  fre_source_trial::Create(&local_state_, entropy_providers_->default_entropy(),
                           version_info::Channel::DEV, /*is_fre=*/false);
  EXPECT_FALSE(
      base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
}

class FileMetricsProviderFRETrialFirstRunTest
    : public FileMetricsProviderFRETrialTest {
 public:
  FileMetricsProviderFRETrialFirstRunTest()
      : FileMetricsProviderFRETrialTest(/*is_fre=*/true) {}
};

TEST_F(FileMetricsProviderFRETrialFirstRunTest, FirstRunAssignTrialGroup) {
  fre_source_trial::Create(&local_state_, entropy_providers_->default_entropy(),
                           version_info::Channel::DEV, /*is_fre=*/true);
  EXPECT_TRUE(
      base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
}

TEST_F(FileMetricsProviderFRETrialFirstRunTest, FREFilesLimit) {
  local_state_.SetString(fre_source_trial::kFRESourceTrial,
                         fre_source_trial::kEnabledGroup);
  fre_source_trial::Create(&local_state_,
                           entropy_providers_.get()->default_entropy(),
                           version_info::Channel::DEV, /*is_fre=*/true);
  ASSERT_TRUE(
      base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
  ASSERT_EQ(
      base::FieldTrialList::FindFullName(fre_source_trial::kFRESourceTrial),
      fre_source_trial::kEnabledGroup);

  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  base::FilePath dir = metrics_files.GetPath();

  for (size_t i = 0; i < FileMetricsProvider::kMaxSourceFilesInFRE * 2; i++) {
    CreateEmptyFileAtTime(dir.AppendASCII(base::StringPrintf("h%d.pma", i)),
                          base::Time::Now() - base::Minutes(i));
  }

  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_files.GetPath(),
          FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/false);

  task_environment()->RunUntilIdle();

  for (size_t i = 0; i < FileMetricsProvider::kMaxSourceFilesInFRE; i++) {
    EXPECT_TRUE(
        base::PathExists(dir.AppendASCII(base::StringPrintf("h%d.pma", i))));
  }
  for (size_t i = FileMetricsProvider::kMaxSourceFilesInFRE;
       i < FileMetricsProvider::kMaxSourceFilesInFRE * 2; i++) {
    EXPECT_FALSE(
        base::PathExists(dir.AppendASCII(base::StringPrintf("h%d.pma", i))));
  }
}

class FileMetricsProviderFRETrialFirstRunGroupsTest
    : public FileMetricsProviderFRETrialFirstRunTest,
      public testing::WithParamInterface<std::string> {};

INSTANTIATE_TEST_SUITE_P(FRETrialFirstRunGroups,
                         FileMetricsProviderFRETrialFirstRunGroupsTest,
                         testing::Values(fre_source_trial::kDefaultGroup,
                                         fre_source_trial::kControlGroup,
                                         fre_source_trial::kEnabledGroup));

TEST_P(FileMetricsProviderFRETrialFirstRunGroupsTest, FRETrialKeepTrialGroup) {
  const std::string_view trial_group = GetParam();
  local_state_.SetString(fre_source_trial::kFRESourceTrial, trial_group);
  fre_source_trial::Create(&local_state_, entropy_providers_->default_entropy(),
                           version_info::Channel::DEV, /*is_fre=*/true);
  EXPECT_TRUE(
      base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
  EXPECT_EQ(
      base::FieldTrialList::FindFullName(fre_source_trial::kFRESourceTrial),
      trial_group);
}

TEST_P(FileMetricsProviderFRETrialFirstRunGroupsTest,
       FRETrialFirstRunExperience) {
  const std::string_view trial_group = GetParam();
  local_state_.SetString(fre_source_trial::kFRESourceTrial, trial_group);
  fre_source_trial::Create(&local_state_, entropy_providers_->default_entropy(),
                           version_info::Channel::DEV, /*is_fre=*/true);
  ASSERT_TRUE(
      base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
  ASSERT_EQ(
      base::FieldTrialList::FindFullName(fre_source_trial::kFRESourceTrial),
      trial_group);

  base::ScopedTempDir metrics_files;
  ASSERT_TRUE(metrics_files.CreateUniqueTempDir());
  base::FilePath dir = metrics_files.GetPath();

  CreateMetricsFileWithHistograms(
      dir.AppendASCII("h1.pma"), base::Time::Now() - base::Minutes(10), 1,
      base::BindOnce(&WriteSystemProfileToAllocator));
  // Also create an empty file there to test the multiple-files in dir case.
  CreateEmptyFile(dir.AppendASCII("h2.pma"));

  ASSERT_TRUE(base::PathExists(dir));
  ASSERT_TRUE(base::PathExists(dir.AppendASCII("h1.pma")));
  ASSERT_TRUE(base::PathExists(dir.AppendASCII("h2.pma")));
  provider()
      ->RegisterSource(
          FileMetricsProvider::Params(
              metrics_files.GetPath(),
              FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
              FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
          /*metrics_reporting_enabled=*/false);

  task_environment()->RunUntilIdle();

  bool should_keep_dir = trial_group == fre_source_trial::kEnabledGroup;
  EXPECT_EQ(base::PathExists(dir), should_keep_dir);
}

class FileMetricsProviderFRETrialSubsequentRunGroupsTest
    : public FileMetricsProviderFRETrialTest,
      public testing::WithParamInterface<std::string> {};

INSTANTIATE_TEST_SUITE_P(FRETrialSubsequentRunGroups,
                         FileMetricsProviderFRETrialSubsequentRunGroupsTest,
                         testing::Values(fre_source_trial::kDefaultGroup,
                                         fre_source_trial::kControlGroup,
                                         fre_source_trial::kEnabledGroup));

TEST_P(FileMetricsProviderFRETrialSubsequentRunGroupsTest, FRETrialPostFRERun) {
  const std::string_view trial_group = GetParam();
  local_state_.SetString(fre_source_trial::kFRESourceTrial, trial_group);
  fre_source_trial::Create(&local_state_, entropy_providers_->default_entropy(),
                           version_info::Channel::DEV, /*is_fre=*/false);
  ASSERT_TRUE(
      base::FieldTrialList::TrialExists(fre_source_trial::kFRESourceTrial));
  ASSERT_EQ(
      base::FieldTrialList::FindFullName(fre_source_trial::kFRESourceTrial),
      trial_group);

  base::ScopedTempDir metrics_files;
  EXPECT_TRUE(metrics_files.CreateUniqueTempDir());
  base::FilePath dir = metrics_files.GetPath();

  CreateMetricsFileWithHistograms(
      dir.AppendASCII("h1.pma"), base::Time::Now() - base::Minutes(10), 1,
      base::BindOnce(&WriteSystemProfileToAllocator));
  // Also create an empty file there to test the multiple-files in dir case.
  CreateEmptyFile(dir.AppendASCII("h2.pma"));

  EXPECT_TRUE(base::PathExists(dir));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h1.pma")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("h2.pma")));
  provider()->RegisterSource(
      FileMetricsProvider::Params(
          metrics_files.GetPath(),
          FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
          FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName),
      /*metrics_reporting_enabled=*/false);

  task_environment()->RunUntilIdle();

  EXPECT_FALSE(base::PathExists(dir));
}

}  // namespace metrics
