12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082 |
- // Copyright 2016 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 "components/metrics/file_metrics_provider.h"
- #include <memory>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/files/file_util.h"
- #include "base/files/memory_mapped_file.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/logging.h"
- #include "base/memory/raw_ptr.h"
- #include "base/metrics/histogram.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/test_simple_task_runner.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/time.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 "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 kMetricsFilename[] = "file.metrics";
- } // namespace
- namespace metrics {
- class HistogramFlattenerDeltaRecorder : public base::HistogramFlattener {
- public:
- HistogramFlattenerDeltaRecorder() {}
- 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 (strlen(histogram.histogram_name()) == 2)
- recorded_delta_histogram_names_.push_back(histogram.histogram_name());
- }
- std::vector<std::string> GetRecordedDeltaHistogramNames() {
- return recorded_delta_histogram_names_;
- }
- private:
- std::vector<std::string> recorded_delta_histogram_names_;
- };
- class FileMetricsProviderTest : public testing::TestWithParam<bool> {
- public:
- FileMetricsProviderTest(const FileMetricsProviderTest&) = delete;
- FileMetricsProviderTest& operator=(const FileMetricsProviderTest&) = delete;
- protected:
- const size_t kSmallFileSize = 64 << 10; // 64 KiB
- const size_t kLargeFileSize = 2 << 20; // 2 MiB
- enum : int { kMaxCreateHistograms = 10 };
- FileMetricsProviderTest()
- : create_large_files_(GetParam()),
- task_runner_(new base::TestSimpleTaskRunner()),
- thread_task_runner_handle_(task_runner_),
- statistics_recorder_(
- base::StatisticsRecorder::CreateTemporaryForTesting()),
- prefs_(new TestingPrefServiceSimple) {
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- FileMetricsProvider::RegisterSourcePrefs(prefs_->registry(), kMetricsName);
- FileMetricsProvider::SetTaskRunnerForTesting(task_runner_);
- }
- ~FileMetricsProviderTest() override {
- // Clear out any final remaining tasks.
- task_runner_->RunUntilIdle();
- FileMetricsProvider::SetTaskRunnerForTesting(nullptr);
- 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());
- }
- TestingPrefServiceSimple* prefs() { return prefs_.get(); }
- base::FilePath temp_dir() { return temp_dir_.GetPath(); }
- base::FilePath metrics_file() {
- return temp_dir_.GetPath().AppendASCII(kMetricsFilename);
- }
- FileMetricsProvider* provider() {
- if (!provider_)
- provider_ = std::make_unique<FileMetricsProvider>(prefs());
- return provider_.get();
- }
- void OnDidCreateMetricsLog() {
- provider()->OnDidCreateMetricsLog();
- }
- bool HasPreviousSessionData() { return provider()->HasPreviousSessionData(); }
- void MergeHistogramDeltas() {
- provider()->MergeHistogramDeltas();
- }
- bool HasIndependentMetrics() { return provider()->HasIndependentMetrics(); }
- bool ProvideIndependentMetrics(
- ChromeUserMetricsExtension* uma_proto,
- base::HistogramSnapshotManager* snapshot_manager) {
- bool success = false;
- bool success_set = false;
- provider()->ProvideIndependentMetrics(
- base::BindOnce(
- [](bool* success_ptr, bool* set_ptr, bool s) {
- *success_ptr = s;
- *set_ptr = true;
- },
- &success, &success_set),
- uma_proto, snapshot_manager);
- RunTasks();
- 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.
- provider()->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::BindOnce([](bool success) {}),
- &uma_proto, &snapshot_manager);
- RunTasks();
- return flattener.GetRecordedDeltaHistogramNames().size();
- }
- void CreateGlobalHistograms(int histogram_count) {
- DCHECK_GT(kMaxCreateHistograms, histogram_count);
- // Create both sparse and normal histograms in the allocator.
- created_histograms_[0] = base::SparseHistogram::FactoryGet("h0", 0);
- 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, 0);
- created_histograms_[i]->Add(i);
- }
- }
- void RunTasks() {
- // Run pending tasks twice: Once for IPC calls, once for replies. Don't
- // use RunUntilIdle() because that can do more work than desired.
- task_runner_->RunPendingTasks();
- task_runner_->RunPendingTasks();
- }
- 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.value();
- size_t file_size = create_large_files_ ? metrics->size() : metrics->used();
- int written = 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);
- }
- std::unique_ptr<base::PersistentHistogramAllocator>
- 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);
- std::unique_ptr<base::PersistentHistogramAllocator> histogram_allocator =
- base::GlobalHistogramAllocator::ReleaseForTesting();
- std::move(callback).Run(histogram_allocator.get());
- WriteMetricsFileAtTime(file_path, histogram_allocator.get(), write_time);
- return histogram_allocator;
- }
- std::unique_ptr<base::PersistentHistogramAllocator>
- 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(
- &FileMetricsProviderTest::FilterSourcePath, base::Unretained(this));
- }
- const bool create_large_files_;
- private:
- FileMetricsProvider::FilterAction FilterSourcePath(
- const base::FilePath& path) {
- DCHECK_LT(0U, filter_actions_remaining_);
- --filter_actions_remaining_;
- return *filter_actions_++;
- }
- scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
- base::ThreadTaskRunnerHandle thread_task_runner_handle_;
- std::unique_ptr<base::StatisticsRecorder> statistics_recorder_;
- base::ScopedTempDir temp_dir_;
- std::unique_ptr<TestingPrefServiceSimple> prefs_;
- std::unique_ptr<FileMetricsProvider> provider_;
- base::HistogramBase* created_histograms_[kMaxCreateHistograms];
- raw_ptr<const FileMetricsProvider::FilterAction> filter_actions_ = nullptr;
- size_t filter_actions_remaining_ = 0;
- };
- // 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::Time metrics_time = base::Time::Now() - base::Minutes(5);
- std::unique_ptr<base::PersistentHistogramAllocator> 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));
- // Record embedded snapshots via snapshot-manager.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(2U, GetSnapshotHistogramCount());
- EXPECT_FALSE(base::PathExists(metrics_file()));
- // Make sure a second call to the snapshot-recorder doesn't break anything.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(0U, GetSnapshotHistogramCount());
- // File should have been deleted but recreate it to test behavior should
- // the file not be deleteable by this process.
- WriteMetricsFileAtTime(metrics_file(), histogram_allocator.get(),
- metrics_time);
- // Second full run on the same file should produce nothing.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(0U, GetSnapshotHistogramCount());
- 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.get(),
- metrics_time);
- // This run should again have "new" histograms.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(2U, GetSnapshotHistogramCount());
- 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);
- std::unique_ptr<base::PersistentHistogramAllocator> 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.
- FileMetricsProvider::Params params(
- metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
- FileMetricsProvider::ASSOCIATE_CURRENT_RUN, kMetricsName);
- params.max_age = base::Hours(1);
- provider()->RegisterSource(params);
- // Attempt to access the file should return nothing.
- OnDidCreateMetricsLog();
- RunTasks();
- 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);
- std::unique_ptr<base::PersistentHistogramAllocator> histogram_allocator =
- 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(¶ms, actions, std::size(actions));
- provider()->RegisterSource(params);
- // 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();
- RunTasks();
- 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();
- RunTasks();
- 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);
- std::unique_ptr<base::PersistentHistogramAllocator> histogram_allocator =
- 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(¶ms, actions, std::size(actions));
- provider()->RegisterSource(params);
- // Processing the file should delete it.
- OnDidCreateMetricsLog();
- RunTasks();
- 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 = 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));
- // Files could come out in the order: a1, c2, d4, b3. They are recognizeable
- // by the number of histograms contained within each.
- const uint32_t expect_order[] = {1, 2, 4, 3, 0};
- for (size_t i = 0; i < std::size(expect_order); ++i) {
- // Record embedded snapshots via snapshot-manager.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(expect_order[i], GetSnapshotHistogramCount()) << i;
- }
- 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());
- CreateMetricsFileWithHistograms(
- metrics_files.GetPath().AppendASCII("h1.pma"),
- base_time + base::Minutes(1), 1,
- base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
- allocator->memory_allocator()->SetMemoryState(
- base::PersistentMemoryAllocator::MEMORY_DELETED);
- }));
- CreateMetricsFileWithHistograms(
- metrics_files.GetPath().AppendASCII("h2.pma"),
- base_time + base::Minutes(2), 2,
- base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
- SystemProfileProto profile_proto;
- SystemProfileProto::FieldTrial* trial = profile_proto.add_field_trial();
- trial->set_name_id(123);
- trial->set_group_id(456);
- PersistentSystemProfile persistent_profile;
- persistent_profile.RegisterPersistentAllocator(
- allocator->memory_allocator());
- persistent_profile.SetSystemProfile(profile_proto, true);
- }));
- CreateMetricsFileWithHistograms(
- metrics_files.GetPath().AppendASCII("h3.pma"),
- base_time + base::Minutes(3), 3,
- base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
- allocator->memory_allocator()->SetMemoryState(
- base::PersistentMemoryAllocator::MEMORY_DELETED);
- }));
- {
- base::File empty(metrics_files.GetPath().AppendASCII("h4.pma"),
- base::File::FLAG_CREATE | base::File::FLAG_WRITE);
- }
- base::TouchFile(metrics_files.GetPath().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(
- metrics_files.GetPath(),
- FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR,
- FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName));
- // No files yet.
- EXPECT_EQ(0U, GetIndependentHistogramCount());
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h1.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h2.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h3.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h4.pma")));
- // H1 should be skipped and H2 available.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("h1.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h2.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h3.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().AppendASCII("h4.pma")));
- // H2 should be read and the file deleted.
- EXPECT_EQ(2U, GetIndependentHistogramCount());
- RunTasks();
- EXPECT_FALSE(base::PathExists(metrics_files.GetPath().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());
- RunTasks();
- EXPECT_FALSE(base::PathExists(metrics_files.GetPath().AppendASCII("h3.pma")));
- EXPECT_TRUE(base::PathExists(metrics_files.GetPath().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.
- 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);
- // Only b2, with 2 histograms, should be read.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(2U, GetSnapshotHistogramCount());
- OnDidCreateMetricsLog();
- RunTasks();
- 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.
- 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);
- // Only b2, with 2 histograms, should be read.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(2U, GetSnapshotHistogramCount());
- OnDidCreateMetricsLog();
- RunTasks();
- 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.
- 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);
- // Only b2, with 2 histograms, should be read.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(2U, GetSnapshotHistogramCount());
- OnDidCreateMetricsLog();
- RunTasks();
- 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 = 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(¶ms, actions, std::size(actions));
- provider()->RegisterSource(params);
- // Files could come out in the order: a1, b3, c2. They are recognizeable
- // by the number of histograms contained within each.
- const uint32_t expect_order[] = {1, 3, 2, 0};
- for (size_t i = 0; i < std::size(expect_order); ++i) {
- // Record embedded snapshots via snapshot-manager.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(expect_order[i], GetSnapshotHistogramCount()) << i;
- }
- 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);
- std::unique_ptr<base::PersistentHistogramAllocator> histogram_allocator =
- 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));
- // Record embedded snapshots via snapshot-manager.
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(2U, GetSnapshotHistogramCount());
- EXPECT_TRUE(base::PathExists(metrics_file()));
- // Make sure a second call to the snapshot-recorder doesn't break anything.
- OnDidCreateMetricsLog();
- RunTasks();
- 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));
- // Record embedded snapshots via snapshot-manager.
- ASSERT_TRUE(HasPreviousSessionData());
- RunTasks();
- {
- HistogramFlattenerDeltaRecorder flattener;
- base::HistogramSnapshotManager snapshot_manager(&flattener);
- RecordInitialHistogramSnapshots(&snapshot_manager);
- EXPECT_EQ(2U, flattener.GetRecordedDeltaHistogramNames().size());
- }
- EXPECT_TRUE(base::PathExists(metrics_file()));
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_FALSE(base::PathExists(metrics_file()));
- // A run for normal histograms should produce nothing.
- CreateMetricsFileWithHistograms(2);
- OnDidCreateMetricsLog();
- RunTasks();
- EXPECT_EQ(0U, GetSnapshotHistogramCount());
- EXPECT_TRUE(base::PathExists(metrics_file()));
- OnDidCreateMetricsLog();
- RunTasks();
- 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));
- // Record embedded snapshots via snapshot-manager.
- OnDidCreateMetricsLog();
- RunTasks();
- {
- 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();
- RunTasks();
- EXPECT_FALSE(base::PathExists(metrics_file()));
- }
- TEST_P(FileMetricsProviderTest, AccessEmbeddedProfileMetricsWithProfile) {
- ASSERT_FALSE(PathExists(metrics_file()));
- CreateMetricsFileWithHistograms(
- metrics_file(), base::Time::Now(), 2,
- base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
- SystemProfileProto profile_proto;
- SystemProfileProto::FieldTrial* trial = profile_proto.add_field_trial();
- trial->set_name_id(123);
- trial->set_group_id(456);
- PersistentSystemProfile persistent_profile;
- persistent_profile.RegisterPersistentAllocator(
- allocator->memory_allocator());
- persistent_profile.SetSystemProfile(profile_proto, 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));
- // Record embedded snapshots via snapshot-manager.
- OnDidCreateMetricsLog();
- RunTasks();
- {
- 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));
- }
- RunTasks();
- 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));
- // Record embedded snapshots via snapshot-manager.
- ASSERT_TRUE(HasPreviousSessionData());
- RunTasks();
- {
- 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();
- RunTasks();
- EXPECT_FALSE(base::PathExists(metrics_file()));
- }
- TEST_P(FileMetricsProviderTest, AccessEmbeddedFallbackMetricsWithProfile) {
- ASSERT_FALSE(PathExists(metrics_file()));
- CreateMetricsFileWithHistograms(
- metrics_file(), base::Time::Now(), 2,
- base::BindOnce([](base::PersistentHistogramAllocator* allocator) {
- SystemProfileProto profile_proto;
- SystemProfileProto::FieldTrial* trial = profile_proto.add_field_trial();
- trial->set_name_id(123);
- trial->set_group_id(456);
- PersistentSystemProfile persistent_profile;
- persistent_profile.RegisterPersistentAllocator(
- allocator->memory_allocator());
- persistent_profile.SetSystemProfile(profile_proto, 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_OR_PREVIOUS_RUN,
- kMetricsName));
- // Record embedded snapshots via snapshot-manager.
- EXPECT_FALSE(HasPreviousSessionData());
- RunTasks();
- {
- 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));
- }
- RunTasks();
- 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([](base::PersistentHistogramAllocator* allocator) {
- SystemProfileProto profile_proto;
- SystemProfileProto::FieldTrial* trial =
- profile_proto.add_field_trial();
- trial->set_name_id(123);
- trial->set_group_id(456);
- PersistentSystemProfile persistent_profile;
- persistent_profile.RegisterPersistentAllocator(
- allocator->memory_allocator());
- persistent_profile.SetSystemProfile(profile_proto, true);
- }));
- 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));
- OnDidCreateMetricsLog();
- RunTasks();
- // 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;
- RunTasks();
- }
- EXPECT_FALSE(HasIndependentMetrics());
- EXPECT_FALSE(ProvideIndependentMetrics(&uma_proto, &snapshot_manager));
- OnDidCreateMetricsLog();
- RunTasks();
- for (const auto& file_name : file_names)
- EXPECT_FALSE(base::PathExists(file_name));
- }
- } // namespace metrics
|