Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / components / metrics / metrics_service_unittest.cc
blob2ee7e1d753dcd01454f19a9a4137801594998322
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/prefs/testing_pref_service.h"
13 #include "base/threading/platform_thread.h"
14 #include "components/metrics/client_info.h"
15 #include "components/metrics/compression_utils.h"
16 #include "components/metrics/metrics_log.h"
17 #include "components/metrics/metrics_pref_names.h"
18 #include "components/metrics/metrics_service_observer.h"
19 #include "components/metrics/metrics_state_manager.h"
20 #include "components/metrics/test_metrics_service_client.h"
21 #include "components/variations/metrics_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace metrics {
26 namespace {
28 void StoreNoClientInfoBackup(const ClientInfo& /* client_info */) {
31 scoped_ptr<ClientInfo> ReturnNoBackup() {
32 return scoped_ptr<ClientInfo>();
35 class TestMetricsService : public MetricsService {
36 public:
37 TestMetricsService(MetricsStateManager* state_manager,
38 MetricsServiceClient* client,
39 PrefService* local_state)
40 : MetricsService(state_manager, client, local_state) {}
41 virtual ~TestMetricsService() {}
43 using MetricsService::log_manager;
45 private:
46 DISALLOW_COPY_AND_ASSIGN(TestMetricsService);
49 class TestMetricsLog : public MetricsLog {
50 public:
51 TestMetricsLog(const std::string& client_id,
52 int session_id,
53 MetricsServiceClient* client,
54 PrefService* local_state)
55 : MetricsLog(client_id,
56 session_id,
57 MetricsLog::ONGOING_LOG,
58 client,
59 local_state) {}
61 virtual ~TestMetricsLog() {}
63 private:
64 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog);
67 class MetricsServiceTest : public testing::Test {
68 public:
69 MetricsServiceTest() : is_metrics_reporting_enabled_(false) {
70 MetricsService::RegisterPrefs(testing_local_state_.registry());
71 metrics_state_manager_ = MetricsStateManager::Create(
72 GetLocalState(),
73 base::Bind(&MetricsServiceTest::is_metrics_reporting_enabled,
74 base::Unretained(this)),
75 base::Bind(&StoreNoClientInfoBackup),
76 base::Bind(&ReturnNoBackup));
79 virtual ~MetricsServiceTest() {
80 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE,
81 GetLocalState());
84 MetricsStateManager* GetMetricsStateManager() {
85 return metrics_state_manager_.get();
88 PrefService* GetLocalState() { return &testing_local_state_; }
90 // Sets metrics reporting as enabled for testing.
91 void EnableMetricsReporting() {
92 is_metrics_reporting_enabled_ = true;
95 // Waits until base::TimeTicks::Now() no longer equals |value|. This should
96 // take between 1-15ms per the documented resolution of base::TimeTicks.
97 void WaitUntilTimeChanges(const base::TimeTicks& value) {
98 while (base::TimeTicks::Now() == value) {
99 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
103 // Returns true if there is a synthetic trial in the given vector that matches
104 // the given trial name and trial group; returns false otherwise.
105 bool HasSyntheticTrial(
106 const std::vector<variations::ActiveGroupId>& synthetic_trials,
107 const std::string& trial_name,
108 const std::string& trial_group) {
109 uint32 trial_name_hash = HashName(trial_name);
110 uint32 trial_group_hash = HashName(trial_group);
111 for (std::vector<variations::ActiveGroupId>::const_iterator it =
112 synthetic_trials.begin();
113 it != synthetic_trials.end(); ++it) {
114 if ((*it).name == trial_name_hash && (*it).group == trial_group_hash)
115 return true;
117 return false;
120 private:
121 bool is_metrics_reporting_enabled() const {
122 return is_metrics_reporting_enabled_;
125 bool is_metrics_reporting_enabled_;
126 TestingPrefServiceSimple testing_local_state_;
127 scoped_ptr<MetricsStateManager> metrics_state_manager_;
128 base::MessageLoop message_loop;
130 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest);
133 class TestMetricsServiceObserver : public MetricsServiceObserver {
134 public:
135 TestMetricsServiceObserver(): observed_(0) {}
136 virtual ~TestMetricsServiceObserver() {}
138 virtual void OnDidCreateMetricsLog() OVERRIDE {
139 ++observed_;
141 int observed() const { return observed_; }
143 private:
144 int observed_;
146 DISALLOW_COPY_AND_ASSIGN(TestMetricsServiceObserver);
149 } // namespace
151 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) {
152 EnableMetricsReporting();
153 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true);
155 TestMetricsServiceClient client;
156 TestMetricsService service(
157 GetMetricsStateManager(), &client, GetLocalState());
158 service.InitializeMetricsRecordingState();
159 // No initial stability log should be generated.
160 EXPECT_FALSE(service.log_manager()->has_unsent_logs());
161 EXPECT_FALSE(service.log_manager()->has_staged_log());
164 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) {
165 EnableMetricsReporting();
166 GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly);
168 // Set up prefs to simulate restarting after a crash.
170 // Save an existing system profile to prefs, to correspond to what would be
171 // saved from a previous session.
172 TestMetricsServiceClient client;
173 TestMetricsLog log("client", 1, &client, GetLocalState());
174 log.RecordEnvironment(std::vector<MetricsProvider*>(),
175 std::vector<variations::ActiveGroupId>(),
178 // Record stability build time and version from previous session, so that
179 // stability metrics (including exited cleanly flag) won't be cleared.
180 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime,
181 MetricsLog::GetBuildTime());
182 GetLocalState()->SetString(prefs::kStabilityStatsVersion,
183 client.GetVersionString());
185 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false);
187 TestMetricsService service(
188 GetMetricsStateManager(), &client, GetLocalState());
189 service.InitializeMetricsRecordingState();
191 // The initial stability log should be generated and persisted in unsent logs.
192 MetricsLogManager* log_manager = service.log_manager();
193 EXPECT_TRUE(log_manager->has_unsent_logs());
194 EXPECT_FALSE(log_manager->has_staged_log());
196 // Stage the log and retrieve it.
197 log_manager->StageNextLogForUpload();
198 EXPECT_TRUE(log_manager->has_staged_log());
200 std::string uncompressed_log;
201 EXPECT_TRUE(metrics::GzipUncompress(log_manager->staged_log(),
202 &uncompressed_log));
204 metrics::ChromeUserMetricsExtension uma_log;
205 EXPECT_TRUE(uma_log.ParseFromString(uncompressed_log));
207 EXPECT_TRUE(uma_log.has_client_id());
208 EXPECT_TRUE(uma_log.has_session_id());
209 EXPECT_TRUE(uma_log.has_system_profile());
210 EXPECT_EQ(0, uma_log.user_action_event_size());
211 EXPECT_EQ(0, uma_log.omnibox_event_size());
212 EXPECT_EQ(0, uma_log.histogram_event_size());
213 EXPECT_EQ(0, uma_log.profiler_event_size());
214 EXPECT_EQ(0, uma_log.perf_data_size());
216 EXPECT_EQ(1, uma_log.system_profile().stability().crash_count());
219 TEST_F(MetricsServiceTest, RegisterSyntheticTrial) {
220 metrics::TestMetricsServiceClient client;
221 MetricsService service(GetMetricsStateManager(), &client, GetLocalState());
223 // Add two synthetic trials and confirm that they show up in the list.
224 SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
225 metrics::HashName("Group1"));
226 service.RegisterSyntheticFieldTrial(trial1);
228 SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"),
229 metrics::HashName("Group2"));
230 service.RegisterSyntheticFieldTrial(trial2);
231 // Ensure that time has advanced by at least a tick before proceeding.
232 WaitUntilTimeChanges(base::TimeTicks::Now());
234 service.log_manager_.BeginLoggingWithLog(scoped_ptr<MetricsLog>(
235 new MetricsLog("clientID",
237 MetricsLog::INITIAL_STABILITY_LOG,
238 &client,
239 GetLocalState())));
240 // Save the time when the log was started (it's okay for this to be greater
241 // than the time recorded by the above call since it's used to ensure the
242 // value changes).
243 const base::TimeTicks begin_log_time = base::TimeTicks::Now();
245 std::vector<variations::ActiveGroupId> synthetic_trials;
246 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
247 EXPECT_EQ(2U, synthetic_trials.size());
248 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group1"));
249 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
251 // Ensure that time has advanced by at least a tick before proceeding.
252 WaitUntilTimeChanges(begin_log_time);
254 // Change the group for the first trial after the log started.
255 SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"),
256 metrics::HashName("Group2"));
257 service.RegisterSyntheticFieldTrial(trial3);
258 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
259 EXPECT_EQ(1U, synthetic_trials.size());
260 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
262 // Add a new trial after the log started and confirm that it doesn't show up.
263 SyntheticTrialGroup trial4(metrics::HashName("TestTrial3"),
264 metrics::HashName("Group3"));
265 service.RegisterSyntheticFieldTrial(trial4);
266 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
267 EXPECT_EQ(1U, synthetic_trials.size());
268 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
270 // Ensure that time has advanced by at least a tick before proceeding.
271 WaitUntilTimeChanges(base::TimeTicks::Now());
273 // Start a new log and ensure all three trials appear in it.
274 service.log_manager_.FinishCurrentLog();
275 service.log_manager_.BeginLoggingWithLog(
276 scoped_ptr<MetricsLog>(new MetricsLog(
277 "clientID", 1, MetricsLog::ONGOING_LOG, &client, GetLocalState())));
278 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
279 EXPECT_EQ(3U, synthetic_trials.size());
280 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group2"));
281 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
282 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial3", "Group3"));
283 service.log_manager_.FinishCurrentLog();
286 TEST_F(MetricsServiceTest, MetricsServiceObserver) {
287 metrics::TestMetricsServiceClient client;
288 MetricsService service(GetMetricsStateManager(), &client, GetLocalState());
289 TestMetricsServiceObserver observer1;
290 TestMetricsServiceObserver observer2;
292 service.AddObserver(&observer1);
293 EXPECT_EQ(0, observer1.observed());
294 EXPECT_EQ(0, observer2.observed());
296 service.OpenNewLog();
297 EXPECT_EQ(1, observer1.observed());
298 EXPECT_EQ(0, observer2.observed());
299 service.log_manager_.FinishCurrentLog();
301 service.AddObserver(&observer2);
303 service.OpenNewLog();
304 EXPECT_EQ(2, observer1.observed());
305 EXPECT_EQ(1, observer2.observed());
306 service.log_manager_.FinishCurrentLog();
308 service.RemoveObserver(&observer1);
310 service.OpenNewLog();
311 EXPECT_EQ(2, observer1.observed());
312 EXPECT_EQ(2, observer2.observed());
313 service.log_manager_.FinishCurrentLog();
315 service.RemoveObserver(&observer2);
318 } // namespace metrics