Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / chrome / browser / metrics / metrics_service_unittest.cc
blob6c5bcd45880b1f936169a3876a1a6e2a3ac0fb6c
1 // Copyright (c) 2012 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 "chrome/browser/metrics/metrics_service.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/threading/platform_thread.h"
12 #include "chrome/browser/google/google_util.h"
13 #include "chrome/browser/metrics/metrics_state_manager.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/scoped_testing_local_state.h"
16 #include "chrome/test/base/testing_browser_process.h"
17 #include "components/metrics/metrics_log_base.h"
18 #include "components/metrics/metrics_service_observer.h"
19 #include "components/metrics/test_metrics_service_client.h"
20 #include "components/variations/metrics_util.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 #if defined(OS_CHROMEOS)
25 #include "chromeos/login/login_state.h"
26 #endif // defined(OS_CHROMEOS)
28 namespace {
30 using metrics::MetricsLogManager;
32 class TestMetricsService : public MetricsService {
33 public:
34 TestMetricsService(metrics::MetricsStateManager* state_manager,
35 metrics::MetricsServiceClient* client,
36 PrefService* local_state)
37 : MetricsService(state_manager, client, local_state) {}
38 virtual ~TestMetricsService() {}
40 using MetricsService::log_manager;
42 private:
43 DISALLOW_COPY_AND_ASSIGN(TestMetricsService);
46 class TestMetricsLog : public MetricsLog {
47 public:
48 TestMetricsLog(const std::string& client_id,
49 int session_id,
50 metrics::MetricsServiceClient* client,
51 PrefService* local_state)
52 : MetricsLog(client_id,
53 session_id,
54 MetricsLog::ONGOING_LOG,
55 client,
56 local_state) {}
58 virtual ~TestMetricsLog() {}
60 private:
61 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog);
64 class MetricsServiceTest : public testing::Test {
65 public:
66 MetricsServiceTest() : is_metrics_reporting_enabled_(false) {
67 MetricsService::RegisterPrefs(testing_local_state_.registry());
68 metrics_state_manager_ = metrics::MetricsStateManager::Create(
69 GetLocalState(),
70 base::Bind(&MetricsServiceTest::is_metrics_reporting_enabled,
71 base::Unretained(this)));
72 #if defined(OS_CHROMEOS)
73 // TODO(blundell): Remove this code once MetricsService no longer creates
74 // ChromeOSMetricsProvider. Also remove the #include of login_state.h.
75 // (http://crbug.com/375776)
76 if (!chromeos::LoginState::IsInitialized())
77 chromeos::LoginState::Initialize();
78 #endif // defined(OS_CHROMEOS)
81 virtual ~MetricsServiceTest() {
82 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE,
83 GetLocalState());
84 #if defined(OS_CHROMEOS)
85 // TODO(blundell): Remove this code once MetricsService no longer creates
86 // ChromeOSMetricsProvider.
87 chromeos::LoginState::Shutdown();
88 #endif // defined(OS_CHROMEOS)
91 metrics::MetricsStateManager* GetMetricsStateManager() {
92 return metrics_state_manager_.get();
95 PrefService* GetLocalState() { return &testing_local_state_; }
97 // Sets metrics reporting as enabled for testing.
98 void EnableMetricsReporting() {
99 is_metrics_reporting_enabled_ = true;
102 // Waits until base::TimeTicks::Now() no longer equals |value|. This should
103 // take between 1-15ms per the documented resolution of base::TimeTicks.
104 void WaitUntilTimeChanges(const base::TimeTicks& value) {
105 while (base::TimeTicks::Now() == value) {
106 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
110 // Returns true if there is a synthetic trial in the given vector that matches
111 // the given trial name and trial group; returns false otherwise.
112 bool HasSyntheticTrial(
113 const std::vector<variations::ActiveGroupId>& synthetic_trials,
114 const std::string& trial_name,
115 const std::string& trial_group) {
116 uint32 trial_name_hash = metrics::HashName(trial_name);
117 uint32 trial_group_hash = metrics::HashName(trial_group);
118 for (std::vector<variations::ActiveGroupId>::const_iterator it =
119 synthetic_trials.begin();
120 it != synthetic_trials.end(); ++it) {
121 if ((*it).name == trial_name_hash && (*it).group == trial_group_hash)
122 return true;
124 return false;
127 private:
128 bool is_metrics_reporting_enabled() const {
129 return is_metrics_reporting_enabled_;
132 content::TestBrowserThreadBundle thread_bundle_;
133 bool is_metrics_reporting_enabled_;
134 TestingPrefServiceSimple testing_local_state_;
135 scoped_ptr<metrics::MetricsStateManager> metrics_state_manager_;
137 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest);
140 class TestMetricsServiceObserver : public MetricsServiceObserver {
141 public:
142 TestMetricsServiceObserver(): observed_(0) {}
143 virtual ~TestMetricsServiceObserver() {}
145 virtual void OnDidCreateMetricsLog() OVERRIDE {
146 ++observed_;
148 int observed() const { return observed_; }
150 private:
151 int observed_;
153 DISALLOW_COPY_AND_ASSIGN(TestMetricsServiceObserver);
156 } // namespace
158 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) {
159 EnableMetricsReporting();
160 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true);
162 metrics::TestMetricsServiceClient client;
163 TestMetricsService service(
164 GetMetricsStateManager(), &client, GetLocalState());
165 service.InitializeMetricsRecordingState();
166 // No initial stability log should be generated.
167 EXPECT_FALSE(service.log_manager()->has_unsent_logs());
168 EXPECT_FALSE(service.log_manager()->has_staged_log());
171 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) {
172 // TODO(asvitkine): Eliminate using |testing_local_state| in favor of using
173 // |GetLocalState()| once MetricsService no longer internally creates metrics
174 // providers that rely on g_browser_process->local_state() being correctly
175 // set up. crbug.com/375776.
176 ScopedTestingLocalState testing_local_state(
177 TestingBrowserProcess::GetGlobal());
178 TestingPrefServiceSimple* local_state = testing_local_state.Get();
179 EnableMetricsReporting();
180 local_state->ClearPref(prefs::kStabilityExitedCleanly);
182 // Set up prefs to simulate restarting after a crash.
184 // Save an existing system profile to prefs, to correspond to what would be
185 // saved from a previous session.
186 metrics::TestMetricsServiceClient client;
187 TestMetricsLog log("client", 1, &client, local_state);
188 log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
189 std::vector<variations::ActiveGroupId>());
191 // Record stability build time and version from previous session, so that
192 // stability metrics (including exited cleanly flag) won't be cleared.
193 local_state->SetInt64(prefs::kStabilityStatsBuildTime,
194 MetricsLog::GetBuildTime());
195 local_state->SetString(prefs::kStabilityStatsVersion,
196 client.GetVersionString());
198 local_state->SetBoolean(prefs::kStabilityExitedCleanly, false);
200 TestMetricsService service(GetMetricsStateManager(), &client, local_state);
201 service.InitializeMetricsRecordingState();
203 // The initial stability log should be generated and persisted in unsent logs.
204 MetricsLogManager* log_manager = service.log_manager();
205 EXPECT_TRUE(log_manager->has_unsent_logs());
206 EXPECT_FALSE(log_manager->has_staged_log());
208 // Stage the log and retrieve it.
209 log_manager->StageNextLogForUpload();
210 EXPECT_TRUE(log_manager->has_staged_log());
212 metrics::ChromeUserMetricsExtension uma_log;
213 EXPECT_TRUE(uma_log.ParseFromString(log_manager->staged_log()));
215 EXPECT_TRUE(uma_log.has_client_id());
216 EXPECT_TRUE(uma_log.has_session_id());
217 EXPECT_TRUE(uma_log.has_system_profile());
218 EXPECT_EQ(0, uma_log.user_action_event_size());
219 EXPECT_EQ(0, uma_log.omnibox_event_size());
220 EXPECT_EQ(0, uma_log.histogram_event_size());
221 EXPECT_EQ(0, uma_log.profiler_event_size());
222 EXPECT_EQ(0, uma_log.perf_data_size());
224 EXPECT_EQ(1, uma_log.system_profile().stability().crash_count());
227 TEST_F(MetricsServiceTest, RegisterSyntheticTrial) {
228 metrics::TestMetricsServiceClient client;
229 MetricsService service(GetMetricsStateManager(), &client, GetLocalState());
231 // Add two synthetic trials and confirm that they show up in the list.
232 SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
233 metrics::HashName("Group1"));
234 service.RegisterSyntheticFieldTrial(trial1);
236 SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"),
237 metrics::HashName("Group2"));
238 service.RegisterSyntheticFieldTrial(trial2);
239 // Ensure that time has advanced by at least a tick before proceeding.
240 WaitUntilTimeChanges(base::TimeTicks::Now());
242 service.log_manager_.BeginLoggingWithLog(scoped_ptr<metrics::MetricsLogBase>(
243 new MetricsLog("clientID",
245 MetricsLog::INITIAL_STABILITY_LOG,
246 &client,
247 GetLocalState())));
248 // Save the time when the log was started (it's okay for this to be greater
249 // than the time recorded by the above call since it's used to ensure the
250 // value changes).
251 const base::TimeTicks begin_log_time = base::TimeTicks::Now();
253 std::vector<variations::ActiveGroupId> synthetic_trials;
254 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
255 EXPECT_EQ(2U, synthetic_trials.size());
256 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group1"));
257 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
259 // Ensure that time has advanced by at least a tick before proceeding.
260 WaitUntilTimeChanges(begin_log_time);
262 // Change the group for the first trial after the log started.
263 SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"),
264 metrics::HashName("Group2"));
265 service.RegisterSyntheticFieldTrial(trial3);
266 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
267 EXPECT_EQ(1U, synthetic_trials.size());
268 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
270 // Add a new trial after the log started and confirm that it doesn't show up.
271 SyntheticTrialGroup trial4(metrics::HashName("TestTrial3"),
272 metrics::HashName("Group3"));
273 service.RegisterSyntheticFieldTrial(trial4);
274 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
275 EXPECT_EQ(1U, synthetic_trials.size());
276 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
278 // Ensure that time has advanced by at least a tick before proceeding.
279 WaitUntilTimeChanges(base::TimeTicks::Now());
281 // Start a new log and ensure all three trials appear in it.
282 service.log_manager_.FinishCurrentLog();
283 service.log_manager_.BeginLoggingWithLog(
284 scoped_ptr<metrics::MetricsLogBase>(new MetricsLog(
285 "clientID", 1, MetricsLog::ONGOING_LOG, &client, GetLocalState())));
286 service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
287 EXPECT_EQ(3U, synthetic_trials.size());
288 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group2"));
289 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
290 EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial3", "Group3"));
291 service.log_manager_.FinishCurrentLog();
294 TEST_F(MetricsServiceTest, MetricsServiceObserver) {
295 metrics::TestMetricsServiceClient client;
296 MetricsService service(GetMetricsStateManager(), &client, GetLocalState());
297 TestMetricsServiceObserver observer1;
298 TestMetricsServiceObserver observer2;
300 service.AddObserver(&observer1);
301 EXPECT_EQ(0, observer1.observed());
302 EXPECT_EQ(0, observer2.observed());
304 service.OpenNewLog();
305 EXPECT_EQ(1, observer1.observed());
306 EXPECT_EQ(0, observer2.observed());
307 service.log_manager_.FinishCurrentLog();
309 service.AddObserver(&observer2);
311 service.OpenNewLog();
312 EXPECT_EQ(2, observer1.observed());
313 EXPECT_EQ(1, observer2.observed());
314 service.log_manager_.FinishCurrentLog();
316 service.RemoveObserver(&observer1);
318 service.OpenNewLog();
319 EXPECT_EQ(2, observer1.observed());
320 EXPECT_EQ(2, observer2.observed());
321 service.log_manager_.FinishCurrentLog();
323 service.RemoveObserver(&observer2);