1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/metrics/persistent_histogram_storage.h"
6
7 #include <memory>
8
9 #include "base/files/file_enumerator.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/metrics/histogram_functions.h"
14 #include "base/metrics/persistent_histogram_allocator.h"
15 #include "base/time/time.h"
16 #include "build/build_config.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace base {
20
21 namespace {
22
23 // Name of the allocator for storing histograms.
24 constexpr char kTestHistogramAllocatorName[] = "TestMetrics";
25
26 } // namespace
27
28 class PersistentHistogramStorageTest : public testing::Test {
29 public:
30 PersistentHistogramStorageTest(const PersistentHistogramStorageTest&) =
31 delete;
32 PersistentHistogramStorageTest& operator=(
33 const PersistentHistogramStorageTest&) = delete;
34
35 protected:
36 PersistentHistogramStorageTest() = default;
37 ~PersistentHistogramStorageTest() override = default;
38
39 // Creates a unique temporary directory, and sets the test storage directory.
SetUp()40 void SetUp() override {
41 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
42 test_storage_dir_ =
43 temp_dir_path().AppendASCII(kTestHistogramAllocatorName);
44 }
45
TearDown()46 void TearDown() override {
47 // Clean up for subsequent tests.
48 GlobalHistogramAllocator::ReleaseForTesting();
49 }
50
51 // Gets the path to the temporary directory.
temp_dir_path()52 const FilePath& temp_dir_path() { return temp_dir_.GetPath(); }
53
test_storage_dir()54 const FilePath& test_storage_dir() { return test_storage_dir_; }
55
56 private:
57 // A temporary directory where all file IO operations take place.
58 ScopedTempDir temp_dir_;
59
60 // The directory into which metrics files are written.
61 FilePath test_storage_dir_;
62 };
63
64 #if !BUILDFLAG(IS_NACL)
TEST_F(PersistentHistogramStorageTest,HistogramWriteTest)65 TEST_F(PersistentHistogramStorageTest, HistogramWriteTest) {
66 auto persistent_histogram_storage =
67 std::make_unique<PersistentHistogramStorage>(
68 kTestHistogramAllocatorName,
69 PersistentHistogramStorage::StorageDirManagement::kCreate);
70
71 persistent_histogram_storage->set_storage_base_dir(temp_dir_path());
72
73 // Log some random data.
74 UmaHistogramBoolean("Some.Test.Metric", true);
75
76 // Deleting the object causes the data to be written to the disk.
77 persistent_histogram_storage.reset();
78
79 // The storage directory and the histogram file are created during the
80 // destruction of the PersistentHistogramStorage instance.
81 EXPECT_TRUE(DirectoryExists(test_storage_dir()));
82 EXPECT_FALSE(IsDirectoryEmpty(test_storage_dir()));
83 }
84
TEST_F(PersistentHistogramStorageTest,TimeCreationTest)85 TEST_F(PersistentHistogramStorageTest, TimeCreationTest) {
86 // Tests that we can create several PersistentHistogramStorage instances in
87 // close time proximity and correctly end with several different files.
88 constexpr int kNumStorageInstances = 3;
89 for (int i = 0; i < kNumStorageInstances; ++i) {
90 auto persistent_histogram_storage =
91 std::make_unique<PersistentHistogramStorage>(
92 kTestHistogramAllocatorName,
93 PersistentHistogramStorage::StorageDirManagement::kCreate);
94
95 persistent_histogram_storage->set_storage_base_dir(temp_dir_path());
96
97 // Log some random data.
98 UmaHistogramBoolean("Some.Test.Metric", true);
99
100 // Deleting the object causes the data to be written to the disk.
101 persistent_histogram_storage.reset();
102
103 // We need the global allocator to allow us to create a new instance.
104 GlobalHistogramAllocator::ReleaseForTesting();
105 }
106
107 // The storage directory and the histogram file are created during the
108 // destruction of the PersistentHistogramStorage instance.
109 EXPECT_TRUE(DirectoryExists(test_storage_dir()));
110 EXPECT_FALSE(IsDirectoryEmpty(test_storage_dir()));
111
112 // We should have |kNumStorageInstances| histogram files in the directory.
113 FileEnumerator enumerator(
114 test_storage_dir(), /*recursive=*/false, FileEnumerator::FILES,
115 FilePath(FILE_PATH_LITERAL("*"))
116 .AddExtension(PersistentMemoryAllocator::kFileExtension)
117 .value());
118 int num_files = 0;
119 for (auto file = enumerator.Next(); !file.empty(); file = enumerator.Next()) {
120 ++num_files;
121 }
122 EXPECT_EQ(num_files, kNumStorageInstances);
123 }
124 #endif // !BUILDFLAG(IS_NACL)
125
126 } // namespace base
127