OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
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 "chrome/browser/metrics/subprocess_metrics_provider.h" | |
6 | |
7 #include "base/memory/shared_memory.h" | |
8 #include "base/metrics/histogram.h" | |
9 #include "base/metrics/histogram_flattener.h" | |
10 #include "base/metrics/histogram_snapshot_manager.h" | |
11 #include "base/metrics/persistent_histogram_allocator.h" | |
12 #include "base/metrics/persistent_memory_allocator.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 namespace { | |
16 | |
17 const uint32_t TEST_MEMORY_SIZE = 64 << 10; // 64 KiB | |
18 | |
19 class HistogramFlattenerDeltaRecorder : public base::HistogramFlattener { | |
20 public: | |
21 HistogramFlattenerDeltaRecorder() {} | |
22 | |
23 void RecordDelta(const base::HistogramBase& histogram, | |
24 const base::HistogramSamples& snapshot) override { | |
25 recorded_delta_histogram_names_.push_back(histogram.histogram_name()); | |
26 } | |
27 | |
28 void InconsistencyDetected( | |
29 base::HistogramBase::Inconsistency problem) override { | |
30 ASSERT_TRUE(false); | |
31 } | |
32 | |
33 void UniqueInconsistencyDetected( | |
34 base::HistogramBase::Inconsistency problem) override { | |
35 ASSERT_TRUE(false); | |
36 } | |
37 | |
38 void InconsistencyDetectedInLoggedCount(int amount) override { | |
39 ASSERT_TRUE(false); | |
40 } | |
41 | |
42 std::vector<std::string> GetRecordedDeltaHistogramNames() { | |
43 return recorded_delta_histogram_names_; | |
44 } | |
45 | |
46 private: | |
47 std::vector<std::string> recorded_delta_histogram_names_; | |
48 | |
49 DISALLOW_COPY_AND_ASSIGN(HistogramFlattenerDeltaRecorder); | |
50 }; | |
51 | |
52 } // namespace | |
53 | |
54 class SubprocessMetricsProviderTest : public testing::Test { | |
55 protected: | |
56 SubprocessMetricsProviderTest() { | |
57 // Get this first so it isn't created inside a persistent allocator. | |
58 base::PersistentHistogramAllocator::GetCreateHistogramResultHistogram(); | |
59 | |
60 // RecordHistogramSnapshots needs to becalled beause it uses a histogram | |
Will Harris
2016/04/07 00:29:41
nit: space
bcwhite
2016/04/07 01:15:55
Done.
| |
61 // macro which caches a pointer to a histogram. If not done before setting | |
62 // a persistent global allocator, then it would point into memory that | |
63 // will go away. The easiest way to call it is through an existing utility | |
64 // method. | |
65 GetSnapshotHistogramCount(); | |
66 | |
67 // Create some shared-memory to pass between global allocator and provider. | |
68 scoped_ptr<base::SharedMemory> shmem(new base::SharedMemory()); | |
69 DCHECK(shmem->CreateAndMapAnonymous(TEST_MEMORY_SIZE)); | |
70 | |
71 // Keep a weak-pointer to the shared memory since it will be hidden once | |
72 // made part of the global histogram allocator. | |
73 shared_memory_ = shmem.get(); | |
74 | |
75 // Use the shared memory for all histograms created by this process. | |
76 base::GlobalHistogramAllocator::CreateWithSharedMemory( | |
77 std::move(shmem), TEST_MEMORY_SIZE, 0, ""); | |
78 | |
79 // Enable metrics reporting by default. | |
80 provider_.OnRecordingEnabled(); | |
81 } | |
82 | |
83 ~SubprocessMetricsProviderTest() override { | |
84 base::GlobalHistogramAllocator::ReleaseForTesting(); | |
85 } | |
86 | |
87 SubprocessMetricsProvider* provider() { return &provider_; } | |
88 | |
89 base::SharedMemory* shared_memory() { return shared_memory_; } | |
90 | |
91 scoped_ptr<base::PersistentHistogramAllocator> GetDuplicateAllocator() { | |
92 base::SharedMemoryHandle memory_handle; | |
93 DCHECK(shared_memory_->ShareToProcess(base::GetCurrentProcessHandle(), | |
94 &memory_handle)); | |
95 | |
96 scoped_ptr<base::SharedMemory> shmem( | |
97 new base::SharedMemory(memory_handle, /*readonly=*/false)); | |
98 DCHECK(shmem->Map(TEST_MEMORY_SIZE)); | |
99 | |
100 return make_scoped_ptr(new base::PersistentHistogramAllocator( | |
101 make_scoped_ptr(new base::SharedPersistentMemoryAllocator( | |
102 std::move(shmem), 0, "", false)))); | |
103 } | |
104 | |
105 size_t GetSnapshotHistogramCount() { | |
106 HistogramFlattenerDeltaRecorder flattener; | |
107 base::HistogramSnapshotManager snapshot_manager(&flattener); | |
108 snapshot_manager.StartDeltas(); | |
109 provider_.RecordHistogramSnapshots(&snapshot_manager); | |
110 snapshot_manager.FinishDeltas(); | |
111 return flattener.GetRecordedDeltaHistogramNames().size(); | |
112 } | |
113 | |
114 void EnableRecording() { provider_.OnRecordingEnabled(); } | |
115 void DisableRecording() { provider_.OnRecordingDisabled(); } | |
116 | |
117 void RegisterSubprocessAllocator( | |
118 int id, | |
119 scoped_ptr<base::PersistentHistogramAllocator> allocator) { | |
120 provider_.RegisterSubprocessAllocator(id, std::move(allocator)); | |
121 } | |
122 | |
123 void DeregisterSubprocessAllocator(int id) { | |
124 provider_.DeregisterSubprocessAllocator(id); | |
125 } | |
126 | |
127 private: | |
128 SubprocessMetricsProvider provider_; | |
129 base::SharedMemory* shared_memory_; | |
130 | |
131 DISALLOW_COPY_AND_ASSIGN(SubprocessMetricsProviderTest); | |
132 }; | |
133 | |
134 TEST_F(SubprocessMetricsProviderTest, SnapshotMetrics) { | |
135 base::HistogramBase* foo = base::Histogram::FactoryGet("foo", 1, 100, 10, 0); | |
136 base::HistogramBase* bar = base::Histogram::FactoryGet("bar", 1, 100, 10, 0); | |
137 foo->Add(42); | |
138 bar->Add(84); | |
139 | |
140 // Register an allocator that duplicates the global allocator. | |
141 RegisterSubprocessAllocator(123, GetDuplicateAllocator()); | |
142 | |
143 // Recording should find the two histograms created in persistent memory. | |
144 EXPECT_EQ(2U, GetSnapshotHistogramCount()); | |
145 | |
146 // A second run should have nothing to produce. | |
147 EXPECT_EQ(0U, GetSnapshotHistogramCount()); | |
148 | |
149 // Create a new histogram and update existing ones. Should now report 3 items. | |
150 base::HistogramBase* baz = base::Histogram::FactoryGet("baz", 1, 100, 10, 0); | |
151 baz->Add(1969); | |
152 foo->Add(10); | |
153 bar->Add(20); | |
154 EXPECT_EQ(3U, GetSnapshotHistogramCount()); | |
155 | |
156 // Ensure that deregistering still keeps allocator around for final report. | |
157 foo->Add(10); | |
158 bar->Add(20); | |
159 DeregisterSubprocessAllocator(123); | |
160 EXPECT_EQ(2U, GetSnapshotHistogramCount()); | |
161 | |
162 // Further snapshots should be empty even if things have changed. | |
163 foo->Add(10); | |
164 bar->Add(20); | |
165 EXPECT_EQ(0U, GetSnapshotHistogramCount()); | |
166 } | |
167 | |
168 TEST_F(SubprocessMetricsProviderTest, EnableDisable) { | |
169 base::HistogramBase* foo = base::Histogram::FactoryGet("foo", 1, 100, 10, 0); | |
170 base::HistogramBase* bar = base::Histogram::FactoryGet("bar", 1, 100, 10, 0); | |
171 | |
172 // Simulate some "normal" operation... | |
173 RegisterSubprocessAllocator(123, GetDuplicateAllocator()); | |
174 foo->Add(42); | |
175 bar->Add(84); | |
176 EXPECT_EQ(2U, GetSnapshotHistogramCount()); | |
177 foo->Add(42); | |
178 bar->Add(84); | |
179 EXPECT_EQ(2U, GetSnapshotHistogramCount()); | |
180 | |
181 // Ensure that disable/enable reporting won't affect "live" allocators. | |
182 DisableRecording(); | |
183 EnableRecording(); | |
184 foo->Add(42); | |
185 bar->Add(84); | |
186 EXPECT_EQ(2U, GetSnapshotHistogramCount()); | |
187 | |
188 // Ensure that allocators are released when reporting is disabled. | |
189 DisableRecording(); | |
190 DeregisterSubprocessAllocator(123); | |
191 EnableRecording(); | |
192 foo->Add(42); | |
193 bar->Add(84); | |
194 EXPECT_EQ(0U, GetSnapshotHistogramCount()); | |
195 | |
196 // Ensure that allocators added when reporting disabled will work if enabled. | |
197 DisableRecording(); | |
198 RegisterSubprocessAllocator(123, GetDuplicateAllocator()); | |
199 EnableRecording(); | |
200 foo->Add(42); | |
201 bar->Add(84); | |
202 EXPECT_EQ(2U, GetSnapshotHistogramCount()); | |
203 | |
204 // Ensure that last-chance allocators are released if reporting is disabled. | |
205 DeregisterSubprocessAllocator(123); | |
206 DisableRecording(); | |
207 EnableRecording(); | |
208 foo->Add(42); | |
209 bar->Add(84); | |
210 EXPECT_EQ(0U, GetSnapshotHistogramCount()); | |
211 } | |
OLD | NEW |