Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / metrics / metrics_service_unittest.cc
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.
4
5 #include "chrome/browser/metrics/metrics_service.h"
6
7 #include <ctype.h>
8 #include <string>
9
10 #include "base/command_line.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/pref_names.h"
13 #include "chrome/test/base/scoped_testing_local_state.h"
14 #include "chrome/test/base/testing_browser_process.h"
15 #include "components/variations/metrics_util.h"
16 #include "content/public/common/process_type.h"
17 #include "content/public/common/webplugininfo.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/gfx/size.h"
21
22 #if defined(OS_CHROMEOS)
23 #include "chrome/browser/metrics/metrics_log_chromeos.h"
24 #endif  // OS_CHROMEOS
25
26 namespace {
27
28 class TestMetricsService : public MetricsService {
29  public:
30   TestMetricsService() {}
31   virtual ~TestMetricsService() {}
32
33   MetricsLogManager* log_manager() {
34     return &log_manager_;
35   }
36
37  private:
38   DISALLOW_COPY_AND_ASSIGN(TestMetricsService);
39 };
40
41 #if defined(OS_CHROMEOS)
42 class TestMetricsLogChromeOS : public MetricsLogChromeOS {
43  public:
44   explicit TestMetricsLogChromeOS(
45       metrics::ChromeUserMetricsExtension* uma_proto)
46       : MetricsLogChromeOS(uma_proto) {
47   }
48
49  protected:
50   // Don't touch bluetooth information, as it won't be correctly initialized.
51   virtual void WriteBluetoothProto() OVERRIDE {
52   }
53 };
54 #endif  // OS_CHROMEOS
55
56 class TestMetricsLog : public MetricsLog {
57  public:
58   TestMetricsLog(const std::string& client_id, int session_id)
59       : MetricsLog(client_id, session_id) {
60 #if defined(OS_CHROMEOS)
61     metrics_log_chromeos_.reset(new TestMetricsLogChromeOS(
62         MetricsLog::uma_proto()));
63 #endif  // OS_CHROMEOS
64   }
65   virtual ~TestMetricsLog() {}
66
67  private:
68   virtual gfx::Size GetScreenSize() const OVERRIDE {
69     return gfx::Size(1024, 768);
70   }
71
72   virtual float GetScreenDeviceScaleFactor() const OVERRIDE {
73     return 1.0f;
74   }
75
76   virtual int GetScreenCount() const OVERRIDE {
77     return 1;
78   }
79
80   DISALLOW_COPY_AND_ASSIGN(TestMetricsLog);
81 };
82
83 class MetricsServiceTest : public testing::Test {
84  public:
85   MetricsServiceTest()
86       : testing_local_state_(TestingBrowserProcess::GetGlobal()) {
87   }
88
89   virtual ~MetricsServiceTest() {
90     MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
91   }
92
93   PrefService* GetLocalState() {
94     return testing_local_state_.Get();
95   }
96
97   // Returns true if there is a synthetic trial in the given vector that matches
98   // the given trial name and trial group; returns false otherwise.
99   bool HasSyntheticTrial(
100       const std::vector<chrome_variations::ActiveGroupId>& synthetic_trials,
101       const std::string& trial_name,
102       const std::string& trial_group) {
103     uint32 trial_name_hash = metrics::HashName(trial_name);
104     uint32 trial_group_hash = metrics::HashName(trial_group);
105     for (std::vector<chrome_variations::ActiveGroupId>::const_iterator it =
106              synthetic_trials.begin();
107          it != synthetic_trials.end(); ++it) {
108       if ((*it).name == trial_name_hash && (*it).group == trial_group_hash)
109         return true;
110     }
111     return false;
112   }
113
114  private:
115   content::TestBrowserThreadBundle thread_bundle_;
116   ScopedTestingLocalState testing_local_state_;
117
118   DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest);
119 };
120
121 }  // namespace
122
123 // Ensure the ClientId is formatted as expected.
124 TEST_F(MetricsServiceTest, ClientIdCorrectlyFormatted) {
125   std::string clientid = MetricsService::GenerateClientID();
126   EXPECT_EQ(36U, clientid.length());
127
128   for (size_t i = 0; i < clientid.length(); ++i) {
129     char current = clientid[i];
130     if (i == 8 || i == 13 || i == 18 || i == 23)
131       EXPECT_EQ('-', current);
132     else
133       EXPECT_TRUE(isxdigit(current));
134   }
135 }
136
137 TEST_F(MetricsServiceTest, IsPluginProcess) {
138   EXPECT_TRUE(
139       MetricsService::IsPluginProcess(content::PROCESS_TYPE_PLUGIN));
140   EXPECT_TRUE(
141       MetricsService::IsPluginProcess(content::PROCESS_TYPE_PPAPI_PLUGIN));
142   EXPECT_FALSE(
143       MetricsService::IsPluginProcess(content::PROCESS_TYPE_GPU));
144 }
145
146 TEST_F(MetricsServiceTest, LowEntropySource0NotReset) {
147   MetricsService service;
148
149   // Get the low entropy source once, to initialize it.
150   service.GetLowEntropySource();
151
152   // Now, set it to 0 and ensure it doesn't get reset.
153   service.low_entropy_source_ = 0;
154   EXPECT_EQ(0, service.GetLowEntropySource());
155   // Call it another time, just to make sure.
156   EXPECT_EQ(0, service.GetLowEntropySource());
157 }
158
159 TEST_F(MetricsServiceTest, PermutedEntropyCacheClearedWhenLowEntropyReset) {
160   const PrefService::Preference* low_entropy_pref =
161       GetLocalState()->FindPreference(prefs::kMetricsLowEntropySource);
162   const char* kCachePrefName = prefs::kMetricsPermutedEntropyCache;
163   int low_entropy_value = -1;
164
165   // First, generate an initial low entropy source value.
166   {
167     EXPECT_TRUE(low_entropy_pref->IsDefaultValue());
168
169     MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
170     MetricsService service;
171     service.GetLowEntropySource();
172
173     EXPECT_FALSE(low_entropy_pref->IsDefaultValue());
174     EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value));
175   }
176
177   // Now, set a dummy value in the permuted entropy cache pref and verify that
178   // another call to GetLowEntropySource() doesn't clobber it when
179   // --reset-variation-state wasn't specified.
180   {
181     GetLocalState()->SetString(kCachePrefName, "test");
182
183     MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
184     MetricsService service;
185     service.GetLowEntropySource();
186
187     EXPECT_EQ("test", GetLocalState()->GetString(kCachePrefName));
188     EXPECT_EQ(low_entropy_value,
189               GetLocalState()->GetInteger(prefs::kMetricsLowEntropySource));
190   }
191
192   // Verify that the cache does get reset if --reset-variations-state is passed.
193   {
194     CommandLine::ForCurrentProcess()->AppendSwitch(
195         switches::kResetVariationState);
196
197     MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
198     MetricsService service;
199     service.GetLowEntropySource();
200
201     EXPECT_TRUE(GetLocalState()->GetString(kCachePrefName).empty());
202   }
203 }
204
205 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) {
206   base::FieldTrialList field_trial_list(NULL);
207   base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog");
208
209   GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true);
210
211   TestMetricsService service;
212   service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED);
213   // No initial stability log should be generated.
214   EXPECT_FALSE(service.log_manager()->has_unsent_logs());
215   EXPECT_FALSE(service.log_manager()->has_staged_log());
216 }
217
218 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) {
219   base::FieldTrialList field_trial_list(NULL);
220   base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog");
221
222   GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly);
223
224   // Set up prefs to simulate restarting after a crash.
225
226   // Save an existing system profile to prefs, to correspond to what would be
227   // saved from a previous session.
228   TestMetricsLog log("client", 1);
229   log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
230                         GoogleUpdateMetrics(),
231                         std::vector<chrome_variations::ActiveGroupId>());
232
233   // Record stability build time and version from previous session, so that
234   // stability metrics (including exited cleanly flag) won't be cleared.
235   GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime,
236                             MetricsLog::GetBuildTime());
237   GetLocalState()->SetString(prefs::kStabilityStatsVersion,
238                              MetricsLog::GetVersionString());
239
240   GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false);
241
242   TestMetricsService service;
243   service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED);
244
245   // The initial stability log should be generated and persisted in unsent logs.
246   MetricsLogManager* log_manager = service.log_manager();
247   EXPECT_TRUE(log_manager->has_unsent_logs());
248   EXPECT_FALSE(log_manager->has_staged_log());
249
250   // Stage the log and retrieve it.
251   log_manager->StageNextLogForUpload();
252   EXPECT_TRUE(log_manager->has_staged_log());
253
254   metrics::ChromeUserMetricsExtension uma_log;
255   EXPECT_TRUE(uma_log.ParseFromString(log_manager->staged_log_text()));
256
257   EXPECT_TRUE(uma_log.has_client_id());
258   EXPECT_TRUE(uma_log.has_session_id());
259   EXPECT_TRUE(uma_log.has_system_profile());
260   EXPECT_EQ(0, uma_log.user_action_event_size());
261   EXPECT_EQ(0, uma_log.omnibox_event_size());
262   EXPECT_EQ(0, uma_log.histogram_event_size());
263   EXPECT_EQ(0, uma_log.profiler_event_size());
264   EXPECT_EQ(0, uma_log.perf_data_size());
265
266   EXPECT_EQ(1, uma_log.system_profile().stability().crash_count());
267 }
268
269 // Crashes on at least Mac and Linux.  http://crbug.com/320433
270 TEST_F(MetricsServiceTest, DISABLED_RegisterSyntheticTrial) {
271   MetricsService service;
272
273   // Add two synthetic trials and confirm that they show up in the list.
274   SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
275                              metrics::HashName("Group1"),
276                              base::TimeTicks::Now());
277   service.RegisterSyntheticFieldTrial(trial1);
278
279   SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"),
280                              metrics::HashName("Group2"),
281                              base::TimeTicks::Now());
282   service.RegisterSyntheticFieldTrial(trial2);
283
284   service.log_manager_.BeginLoggingWithLog(new MetricsLog("clientID", 1),
285                                            MetricsLog::INITIAL_LOG);
286
287   std::vector<chrome_variations::ActiveGroupId> synthetic_trials;
288   service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
289   EXPECT_EQ(2U, synthetic_trials.size());
290   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group1"));
291   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
292
293   // Change the group for the first trial after the log started.
294   SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"),
295                              metrics::HashName("Group2"),
296                              base::TimeTicks::Now());
297   service.RegisterSyntheticFieldTrial(trial3);
298   service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
299   EXPECT_EQ(1U, synthetic_trials.size());
300   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
301
302   // Add a new trial after the log started and confirm that it doesn't show up.
303   SyntheticTrialGroup trial4(metrics::HashName("TestTrial3"),
304                              metrics::HashName("Group3"),
305                              base::TimeTicks::Now());
306   service.RegisterSyntheticFieldTrial(trial4);
307   service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
308   EXPECT_EQ(1U, synthetic_trials.size());
309   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
310
311   // Start a new log.
312   service.log_manager_.FinishCurrentLog();
313   service.log_manager_.BeginLoggingWithLog(new MetricsLog("clientID", 1),
314                                            MetricsLog::ONGOING_LOG);
315   service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
316   EXPECT_EQ(3U, synthetic_trials.size());
317   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group2"));
318   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
319   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial3", "Group3"));
320   service.log_manager_.FinishCurrentLog();
321 }