Revert of ui: Clean up damaged rects and clear them after painting. (patchset #2...
[chromium-blink-merge.git] / components / metrics / metrics_service_unittest.cc
blob81e834118905b209592f22fc4858c863a8cbee05
1 // Copyright 2014 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.
5 #include "components/metrics/metrics_service.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/statistics_recorder.h"
13 #include "base/prefs/testing_pref_service.h"
14 #include "base/threading/platform_thread.h"
15 #include "components/metrics/client_info.h"
16 #include "components/metrics/compression_utils.h"
17 #include "components/metrics/metrics_hashes.h"
18 #include "components/metrics/metrics_log.h"
19 #include "components/metrics/metrics_pref_names.h"
20 #include "components/metrics/metrics_state_manager.h"
21 #include "components/metrics/test_metrics_service_client.h"
22 #include "components/variations/metrics_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace metrics {
27 namespace {
29 void StoreNoClientInfoBackup(const ClientInfo& /* client_info */) {
32 scoped_ptr<ClientInfo> ReturnNoBackup() {
33 return scoped_ptr<ClientInfo>();
36 class TestMetricsProvider : public MetricsProvider {
37 public:
38 explicit TestMetricsProvider(bool has_stability_metrics) :
39 has_stability_metrics_(has_stability_metrics),
40 provide_stability_metrics_called_(false) {
43 bool HasStabilityMetrics() override { return has_stability_metrics_; }
44 void ProvideStabilityMetrics(
45 SystemProfileProto* system_profile_proto) override {
46 UMA_STABILITY_HISTOGRAM_ENUMERATION("TestMetricsProvider.Metric", 1, 2);
47 provide_stability_metrics_called_ = true;
50 bool provide_stability_metrics_called() const {
51 return provide_stability_metrics_called_;
54 private:
55 bool has_stability_metrics_;
56 bool provide_stability_metrics_called_;
58 DISALLOW_COPY_AND_ASSIGN(TestMetricsProvider);
61 class TestMetricsService : public MetricsService {
62 public:
63 TestMetricsService(MetricsStateManager* state_manager,
64 MetricsServiceClient* client,
65 PrefService* local_state)
66 : MetricsService(state_manager, client, local_state) {}
67 ~TestMetricsService() override {}
69 using MetricsService::log_manager;
71 private:
72 DISALLOW_COPY_AND_ASSIGN(TestMetricsService);
75 class TestMetricsLog : public MetricsLog {
76 public:
77 TestMetricsLog(const std::string& client_id,
78 int session_id,
79 MetricsServiceClient* client,
80 PrefService* local_state)
81 : MetricsLog(client_id,
82 session_id,
83 MetricsLog::ONGOING_LOG,
84 client,
85 local_state) {}
87 ~TestMetricsLog() override {}
89 private:
90 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog);
93 class MetricsServiceTest : public testing::Test {
94 public:
95 MetricsServiceTest() : is_metrics_reporting_enabled_(false) {
96 MetricsService::RegisterPrefs(testing_local_state_.registry());
97 metrics_state_manager_ = MetricsStateManager::Create(
98 GetLocalState(),
99 base::Bind(&MetricsServiceTest::is_metrics_reporting_enabled,
100 base::Unretained(this)),
101 base::Bind(&StoreNoClientInfoBackup),
102 base::Bind(&ReturnNoBackup));
105 ~MetricsServiceTest() override {
106 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE,
107 GetLocalState());
110 MetricsStateManager* GetMetricsStateManager() {
111 return metrics_state_manager_.get();
114 PrefService* GetLocalState() { return &testing_local_state_; }
116 // Sets metrics reporting as enabled for testing.
117 void EnableMetricsReporting() {
118 is_metrics_reporting_enabled_ = true;
121 // Waits until base::TimeTicks::Now() no longer equals |value|. This should
122 // take between 1-15ms per the documented resolution of base::TimeTicks.
123 void WaitUntilTimeChanges(const base::TimeTicks& value) {
124 while (base::TimeTicks::Now() == value) {
125 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
129 // Returns true if there is a synthetic trial in the given vector that matches
130 // the given trial name and trial group; returns false otherwise.
131 bool HasSyntheticTrial(
132 const std::vector<variations::ActiveGroupId>& synthetic_trials,
133 const std::string& trial_name,
134 const std::string& trial_group) {
135 uint32 trial_name_hash = HashName(trial_name);
136 uint32 trial_group_hash = HashName(trial_group);
137 for (const variations::ActiveGroupId& trial : synthetic_trials) {
138 if (trial.name == trial_name_hash && trial.group == trial_group_hash)
139 return true;
141 return false;
144 // Finds a histogram with the specified |name_hash| in |histograms|.
145 const base::HistogramBase* FindHistogram(
146 const base::StatisticsRecorder::Histograms& histograms,
147 uint64 name_hash) {
148 for (const base::HistogramBase* histogram : histograms) {
149 if (name_hash == HashMetricName(histogram->histogram_name()))
150 return histogram;
152 return nullptr;
155 // Checks whether |uma_log| contains any histograms that are not flagged
156 // with kUmaStabilityHistogramFlag. Stability logs should only contain such
157 // histograms.
158 void CheckForNonStabilityHistograms(
159 const ChromeUserMetricsExtension& uma_log) {
160 const int kStabilityFlags = base::HistogramBase::kUmaStabilityHistogramFlag;
161 base::StatisticsRecorder::Histograms histograms;
162 base::StatisticsRecorder::GetHistograms(&histograms);
163 for (int i = 0; i < uma_log.histogram_event_size(); ++i) {
164 const uint64 hash = uma_log.histogram_event(i).name_hash();
166 const base::HistogramBase* histogram = FindHistogram(histograms, hash);
167 EXPECT_TRUE(histogram) << hash;
169 EXPECT_EQ(kStabilityFlags, histogram->flags() & kStabilityFlags) << hash;
173 private:
174 bool is_metrics_reporting_enabled() const {
175 return is_metrics_reporting_enabled_;
178 bool is_metrics_reporting_enabled_;
179 TestingPrefServiceSimple testing_local_state_;
180 scoped_ptr<MetricsStateManager> metrics_state_manager_;
181 base::MessageLoop message_loop;
183 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest);
186 } // namespace
188 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) {
189 EnableMetricsReporting();
190 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true);
192 TestMetricsServiceClient client;
193 TestMetricsService service(
194 GetMetricsStateManager(), &client, GetLocalState());
196 TestMetricsProvider* test_provider = new TestMetricsProvider(false);
197 service.RegisterMetricsProvider(scoped_ptr<MetricsProvider>(test_provider));
199 service.InitializeMetricsRecordingState();
200 // No initial stability log should be generated.
201 EXPECT_FALSE(service.log_manager()->has_unsent_logs());
202 EXPECT_FALSE(service.log_manager()->has_staged_log());
204 // The test provider should not have been called upon to provide stability
205 // metrics.
206 EXPECT_FALSE(test_provider->provide_stability_metrics_called());
209 TEST_F(MetricsServiceTest, InitialStabilityLogAtProviderRequest) {
210 EnableMetricsReporting();
212 // Save an existing system profile to prefs, to correspond to what would be
213 // saved from a previous session.
214 TestMetricsServiceClient client;
215 TestMetricsLog log("client", 1, &client, GetLocalState());
216 log.RecordEnvironment(std::vector<MetricsProvider*>(),
217 std::vector<variations::ActiveGroupId>(), 0, 0);
219 // Record stability build time and version from previous session, so that
220 // stability metrics (including exited cleanly flag) won't be cleared.
221 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime,
222 MetricsLog::GetBuildTime());
223 GetLocalState()->SetString(prefs::kStabilityStatsVersion,
224 client.GetVersionString());
226 // Set the clean exit flag, as that will otherwise cause a stabilty
227 // log to be produced, irrespective provider requests.
228 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true);
230 TestMetricsService service(
231 GetMetricsStateManager(), &client, GetLocalState());
232 // Add a metrics provider that requests a stability log.
233 TestMetricsProvider* test_provider = new TestMetricsProvider(true);
234 service.RegisterMetricsProvider(
235 scoped_ptr<MetricsProvider>(test_provider));
237 service.InitializeMetricsRecordingState();
239 // The initial stability log should be generated and persisted in unsent logs.
240 MetricsLogManager* log_manager = service.log_manager();
241 EXPECT_TRUE(log_manager->has_unsent_logs());
242 EXPECT_FALSE(log_manager->has_staged_log());
244 // The test provider should have been called upon to provide stability
245 // metrics.
246 EXPECT_TRUE(test_provider->provide_stability_metrics_called());
248 // Stage the log and retrieve it.
249 log_manager->StageNextLogForUpload();
250 EXPECT_TRUE(log_manager->has_staged_log());
252 std::string uncompressed_log;
253 EXPECT_TRUE(GzipUncompress(log_manager->staged_log(), &uncompressed_log));
255 ChromeUserMetricsExtension uma_log;
256 EXPECT_TRUE(uma_log.ParseFromString(uncompressed_log));
258 EXPECT_TRUE(uma_log.has_client_id());
259 EXPECT_TRUE(uma_log.has_session_id());
260 EXPECT_TRUE(uma_log.has_system_profile());
261 EXPECT_EQ(0, uma_log.user_action_event_size());
262 EXPECT_EQ(0, uma_log.omnibox_event_size());
263 EXPECT_EQ(0, uma_log.profiler_event_size());
264 EXPECT_EQ(0, uma_log.perf_data_size());
265 CheckForNonStabilityHistograms(uma_log);
267 // As there wasn't an unclean shutdown, this log has zero crash count.
268 EXPECT_EQ(0, uma_log.system_profile().stability().crash_count());
271 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) {
272 EnableMetricsReporting();
273 GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly);
275 // Set up prefs to simulate restarting after a crash.
277 // Save an existing system profile to prefs, to correspond to what would be
278 // saved from a previous session.
279 TestMetricsServiceClient client;
280 TestMetricsLog log("client", 1, &client, GetLocalState());
281 log.RecordEnvironment(std::vector<MetricsProvider*>(),
282 std::vector<variations::ActiveGroupId>(), 0, 0);
284 // Record stability build time and version from previous session, so that
285 // stability metrics (including exited cleanly flag) won't be cleared.
286 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime,
287 MetricsLog::GetBuildTime());
288 GetLocalState()->SetString(prefs::kStabilityStatsVersion,
289 client.GetVersionString());
291 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false);
293 TestMetricsService service(
294 GetMetricsStateManager(), &client, GetLocalState());
295 service.InitializeMetricsRecordingState();
297 // The initial stability log should be generated and persisted in unsent logs.
298 MetricsLogManager* log_manager = service.log_manager();
299 EXPECT_TRUE(log_manager->has_unsent_logs());
300 EXPECT_FALSE(log_manager->has_staged_log());
302 // Stage the log and retrieve it.
303 log_manager->StageNextLogForUpload();
304 EXPECT_TRUE(log_manager->has_staged_log());
306 std::string uncompressed_log;
307 EXPECT_TRUE(GzipUncompress(log_manager->staged_log(), &uncompressed_log));
309 ChromeUserMetricsExtension uma_log;
310 EXPECT_TRUE(uma_log.ParseFromString(uncompressed_log));
312 EXPECT_TRUE(uma_log.has_client_id());
313 EXPECT_TRUE(uma_log.has_session_id());
314 EXPECT_TRUE(uma_log.has_system_profile());
315 EXPECT_EQ(0, uma_log.user_action_event_size());
316 EXPECT_EQ(0, uma_log.omnibox_event_size());
317 EXPECT_EQ(0, uma_log.profiler_event_size());
318 EXPECT_EQ(0, uma_log.perf_data_size());
319 CheckForNonStabilityHistograms(uma_log);
321 EXPECT_EQ(1, uma_log.system_profile().stability().crash_count());
324 TEST_F(MetricsServiceTest, RegisterSyntheticTrial) {
325 TestMetricsServiceClient client;
326 MetricsService service(GetMetricsStateManager(), &client, GetLocalState());
328 // Add two synthetic trials and confirm that they show up in the list.
329 SyntheticTrialGroup trial1(HashName("TestTrial1"), HashName("Group1"));
330 service.RegisterSyntheticFieldTrial(trial1);
332 SyntheticTrialGroup trial2(HashName("TestTrial2"), HashName("Group2"));
333 service.RegisterSyntheticFieldTrial(trial2);
334 // Ensure that time has advanced by at least a tick before proceeding.
335 WaitUntilTimeChanges(base::TimeTicks::Now());
337 service.log_manager_.BeginLoggingWithLog(scoped_ptr<MetricsLog>(
338 new MetricsLog("clientID",
340 MetricsLog::INITIAL_STABILITY_LOG,
341 &client,
342 GetLocalState())));
343 // Save the time when the log was started (it's okay for this to be greater
344 // than the time recorded by the above call since it's used to ensure the
345 // value changes).
346 const base::TimeTicks begin_log_time = base::TimeTicks::Now();
348 std::vector<variations::ActiveGroupId> synthetic_trials;
349 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
350 EXPECT_EQ(2U, synthetic_trials.size());
351 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group1"));
352 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
354 // Ensure that time has advanced by at least a tick before proceeding.
355 WaitUntilTimeChanges(begin_log_time);
357 // Change the group for the first trial after the log started.
358 SyntheticTrialGroup trial3(HashName("TestTrial1"), HashName("Group2"));
359 service.RegisterSyntheticFieldTrial(trial3);
360 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
361 EXPECT_EQ(1U, synthetic_trials.size());
362 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
364 // Add a new trial after the log started and confirm that it doesn't show up.
365 SyntheticTrialGroup trial4(HashName("TestTrial3"), HashName("Group3"));
366 service.RegisterSyntheticFieldTrial(trial4);
367 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
368 EXPECT_EQ(1U, synthetic_trials.size());
369 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
371 // Ensure that time has advanced by at least a tick before proceeding.
372 WaitUntilTimeChanges(base::TimeTicks::Now());
374 // Start a new log and ensure all three trials appear in it.
375 service.log_manager_.FinishCurrentLog();
376 service.log_manager_.BeginLoggingWithLog(
377 scoped_ptr<MetricsLog>(new MetricsLog(
378 "clientID", 1, MetricsLog::ONGOING_LOG, &client, GetLocalState())));
379 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
380 EXPECT_EQ(3U, synthetic_trials.size());
381 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group2"));
382 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
383 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial3", "Group3"));
384 service.log_manager_.FinishCurrentLog();
387 } // namespace metrics