| OLD | NEW |
| (Empty) |
| 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 "components/metrics/metrics_log.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/base64.h" | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/command_line.h" | |
| 12 #include "base/port.h" | |
| 13 #include "base/prefs/pref_service.h" | |
| 14 #include "base/prefs/testing_pref_service.h" | |
| 15 #include "base/strings/string_number_conversions.h" | |
| 16 #include "base/strings/string_util.h" | |
| 17 #include "base/strings/stringprintf.h" | |
| 18 #include "base/threading/sequenced_worker_pool.h" | |
| 19 #include "base/time/time.h" | |
| 20 #include "components/metrics/metrics_hashes.h" | |
| 21 #include "components/metrics/metrics_pref_names.h" | |
| 22 #include "components/metrics/metrics_provider.h" | |
| 23 #include "components/metrics/metrics_state_manager.h" | |
| 24 #include "components/metrics/proto/profiler_event.pb.h" | |
| 25 #include "components/metrics/proto/system_profile.pb.h" | |
| 26 #include "components/metrics/test_metrics_service_client.h" | |
| 27 #include "components/variations/active_field_trials.h" | |
| 28 #include "testing/gtest/include/gtest/gtest.h" | |
| 29 #include "url/gurl.h" | |
| 30 | |
| 31 using base::TimeDelta; | |
| 32 | |
| 33 namespace { | |
| 34 | |
| 35 const char kClientId[] = "bogus client ID"; | |
| 36 const int64 kInstallDate = 1373051956; | |
| 37 const int64 kInstallDateExpected = 1373050800; // Computed from kInstallDate. | |
| 38 const int64 kEnabledDate = 1373001211; | |
| 39 const int64 kEnabledDateExpected = 1373000400; // Computed from kEnabledDate. | |
| 40 const int kSessionId = 127; | |
| 41 const variations::ActiveGroupId kFieldTrialIds[] = { | |
| 42 {37, 43}, | |
| 43 {13, 47}, | |
| 44 {23, 17} | |
| 45 }; | |
| 46 const variations::ActiveGroupId kSyntheticTrials[] = { | |
| 47 {55, 15}, | |
| 48 {66, 16} | |
| 49 }; | |
| 50 | |
| 51 class TestMetricsLog : public MetricsLog { | |
| 52 public: | |
| 53 TestMetricsLog(const std::string& client_id, | |
| 54 int session_id, | |
| 55 LogType log_type, | |
| 56 metrics::MetricsServiceClient* client, | |
| 57 TestingPrefServiceSimple* prefs) | |
| 58 : MetricsLog(client_id, session_id, log_type, client, prefs), | |
| 59 prefs_(prefs) { | |
| 60 InitPrefs(); | |
| 61 } | |
| 62 | |
| 63 virtual ~TestMetricsLog() {} | |
| 64 | |
| 65 const metrics::ChromeUserMetricsExtension& uma_proto() const { | |
| 66 return *MetricsLog::uma_proto(); | |
| 67 } | |
| 68 | |
| 69 const metrics::SystemProfileProto& system_profile() const { | |
| 70 return uma_proto().system_profile(); | |
| 71 } | |
| 72 | |
| 73 private: | |
| 74 void InitPrefs() { | |
| 75 prefs_->SetString(metrics::prefs::kMetricsReportingEnabledTimestamp, | |
| 76 base::Int64ToString(kEnabledDate)); | |
| 77 } | |
| 78 | |
| 79 virtual void GetFieldTrialIds( | |
| 80 std::vector<variations::ActiveGroupId>* field_trial_ids) const | |
| 81 OVERRIDE { | |
| 82 ASSERT_TRUE(field_trial_ids->empty()); | |
| 83 | |
| 84 for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { | |
| 85 field_trial_ids->push_back(kFieldTrialIds[i]); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 // Weak pointer to the PrefsService used by this log. | |
| 90 TestingPrefServiceSimple* prefs_; | |
| 91 | |
| 92 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog); | |
| 93 }; | |
| 94 | |
| 95 } // namespace | |
| 96 | |
| 97 class MetricsLogTest : public testing::Test { | |
| 98 public: | |
| 99 MetricsLogTest() { | |
| 100 MetricsLog::RegisterPrefs(prefs_.registry()); | |
| 101 metrics::MetricsStateManager::RegisterPrefs(prefs_.registry()); | |
| 102 } | |
| 103 | |
| 104 virtual ~MetricsLogTest() { | |
| 105 } | |
| 106 | |
| 107 protected: | |
| 108 // Check that the values in |system_values| correspond to the test data | |
| 109 // defined at the top of this file. | |
| 110 void CheckSystemProfile(const metrics::SystemProfileProto& system_profile) { | |
| 111 EXPECT_EQ(kInstallDateExpected, system_profile.install_date()); | |
| 112 EXPECT_EQ(kEnabledDateExpected, system_profile.uma_enabled_date()); | |
| 113 | |
| 114 ASSERT_EQ(arraysize(kFieldTrialIds) + arraysize(kSyntheticTrials), | |
| 115 static_cast<size_t>(system_profile.field_trial_size())); | |
| 116 for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { | |
| 117 const metrics::SystemProfileProto::FieldTrial& field_trial = | |
| 118 system_profile.field_trial(i); | |
| 119 EXPECT_EQ(kFieldTrialIds[i].name, field_trial.name_id()); | |
| 120 EXPECT_EQ(kFieldTrialIds[i].group, field_trial.group_id()); | |
| 121 } | |
| 122 // Verify the right data is present for the synthetic trials. | |
| 123 for (size_t i = 0; i < arraysize(kSyntheticTrials); ++i) { | |
| 124 const metrics::SystemProfileProto::FieldTrial& field_trial = | |
| 125 system_profile.field_trial(i + arraysize(kFieldTrialIds)); | |
| 126 EXPECT_EQ(kSyntheticTrials[i].name, field_trial.name_id()); | |
| 127 EXPECT_EQ(kSyntheticTrials[i].group, field_trial.group_id()); | |
| 128 } | |
| 129 | |
| 130 EXPECT_EQ(metrics::TestMetricsServiceClient::kBrandForTesting, | |
| 131 system_profile.brand_code()); | |
| 132 | |
| 133 const metrics::SystemProfileProto::Hardware& hardware = | |
| 134 system_profile.hardware(); | |
| 135 | |
| 136 EXPECT_TRUE(hardware.has_cpu()); | |
| 137 EXPECT_TRUE(hardware.cpu().has_vendor_name()); | |
| 138 EXPECT_TRUE(hardware.cpu().has_signature()); | |
| 139 | |
| 140 // TODO(isherman): Verify other data written into the protobuf as a result | |
| 141 // of this call. | |
| 142 } | |
| 143 | |
| 144 protected: | |
| 145 TestingPrefServiceSimple prefs_; | |
| 146 | |
| 147 private: | |
| 148 DISALLOW_COPY_AND_ASSIGN(MetricsLogTest); | |
| 149 }; | |
| 150 | |
| 151 TEST_F(MetricsLogTest, RecordEnvironment) { | |
| 152 metrics::TestMetricsServiceClient client; | |
| 153 client.set_install_date(kInstallDate); | |
| 154 TestMetricsLog log( | |
| 155 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 156 | |
| 157 std::vector<variations::ActiveGroupId> synthetic_trials; | |
| 158 // Add two synthetic trials. | |
| 159 synthetic_trials.push_back(kSyntheticTrials[0]); | |
| 160 synthetic_trials.push_back(kSyntheticTrials[1]); | |
| 161 | |
| 162 log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(), | |
| 163 synthetic_trials); | |
| 164 // Check that the system profile on the log has the correct values set. | |
| 165 CheckSystemProfile(log.system_profile()); | |
| 166 | |
| 167 // Check that the system profile has also been written to prefs. | |
| 168 const std::string base64_system_profile = | |
| 169 prefs_.GetString(metrics::prefs::kStabilitySavedSystemProfile); | |
| 170 EXPECT_FALSE(base64_system_profile.empty()); | |
| 171 std::string serialied_system_profile; | |
| 172 EXPECT_TRUE(base::Base64Decode(base64_system_profile, | |
| 173 &serialied_system_profile)); | |
| 174 metrics::SystemProfileProto decoded_system_profile; | |
| 175 EXPECT_TRUE(decoded_system_profile.ParseFromString(serialied_system_profile)); | |
| 176 CheckSystemProfile(decoded_system_profile); | |
| 177 } | |
| 178 | |
| 179 TEST_F(MetricsLogTest, LoadSavedEnvironmentFromPrefs) { | |
| 180 const char* kSystemProfilePref = metrics::prefs::kStabilitySavedSystemProfile; | |
| 181 const char* kSystemProfileHashPref = | |
| 182 metrics::prefs::kStabilitySavedSystemProfileHash; | |
| 183 | |
| 184 metrics::TestMetricsServiceClient client; | |
| 185 client.set_install_date(kInstallDate); | |
| 186 | |
| 187 // The pref value is empty, so loading it from prefs should fail. | |
| 188 { | |
| 189 TestMetricsLog log( | |
| 190 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 191 EXPECT_FALSE(log.LoadSavedEnvironmentFromPrefs()); | |
| 192 } | |
| 193 | |
| 194 // Do a RecordEnvironment() call and check whether the pref is recorded. | |
| 195 { | |
| 196 TestMetricsLog log( | |
| 197 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 198 log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(), | |
| 199 std::vector<variations::ActiveGroupId>()); | |
| 200 EXPECT_FALSE(prefs_.GetString(kSystemProfilePref).empty()); | |
| 201 EXPECT_FALSE(prefs_.GetString(kSystemProfileHashPref).empty()); | |
| 202 } | |
| 203 | |
| 204 { | |
| 205 TestMetricsLog log( | |
| 206 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 207 EXPECT_TRUE(log.LoadSavedEnvironmentFromPrefs()); | |
| 208 // Check some values in the system profile. | |
| 209 EXPECT_EQ(kInstallDateExpected, log.system_profile().install_date()); | |
| 210 EXPECT_EQ(kEnabledDateExpected, log.system_profile().uma_enabled_date()); | |
| 211 // Ensure that the call cleared the prefs. | |
| 212 EXPECT_TRUE(prefs_.GetString(kSystemProfilePref).empty()); | |
| 213 EXPECT_TRUE(prefs_.GetString(kSystemProfileHashPref).empty()); | |
| 214 } | |
| 215 | |
| 216 // Ensure that a non-matching hash results in the pref being invalid. | |
| 217 { | |
| 218 TestMetricsLog log( | |
| 219 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 220 // Call RecordEnvironment() to record the pref again. | |
| 221 log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(), | |
| 222 std::vector<variations::ActiveGroupId>()); | |
| 223 } | |
| 224 | |
| 225 { | |
| 226 // Set the hash to a bad value. | |
| 227 prefs_.SetString(kSystemProfileHashPref, "deadbeef"); | |
| 228 TestMetricsLog log( | |
| 229 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 230 EXPECT_FALSE(log.LoadSavedEnvironmentFromPrefs()); | |
| 231 // Ensure that the prefs are cleared, even if the call failed. | |
| 232 EXPECT_TRUE(prefs_.GetString(kSystemProfilePref).empty()); | |
| 233 EXPECT_TRUE(prefs_.GetString(kSystemProfileHashPref).empty()); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 TEST_F(MetricsLogTest, InitialLogStabilityMetrics) { | |
| 238 metrics::TestMetricsServiceClient client; | |
| 239 TestMetricsLog log(kClientId, | |
| 240 kSessionId, | |
| 241 MetricsLog::INITIAL_STABILITY_LOG, | |
| 242 &client, | |
| 243 &prefs_); | |
| 244 std::vector<metrics::MetricsProvider*> metrics_providers; | |
| 245 log.RecordEnvironment(metrics_providers, | |
| 246 std::vector<variations::ActiveGroupId>()); | |
| 247 log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), | |
| 248 base::TimeDelta()); | |
| 249 const metrics::SystemProfileProto_Stability& stability = | |
| 250 log.system_profile().stability(); | |
| 251 // Required metrics: | |
| 252 EXPECT_TRUE(stability.has_launch_count()); | |
| 253 EXPECT_TRUE(stability.has_crash_count()); | |
| 254 // Initial log metrics: | |
| 255 EXPECT_TRUE(stability.has_incomplete_shutdown_count()); | |
| 256 EXPECT_TRUE(stability.has_breakpad_registration_success_count()); | |
| 257 EXPECT_TRUE(stability.has_breakpad_registration_failure_count()); | |
| 258 EXPECT_TRUE(stability.has_debugger_present_count()); | |
| 259 EXPECT_TRUE(stability.has_debugger_not_present_count()); | |
| 260 } | |
| 261 | |
| 262 TEST_F(MetricsLogTest, OngoingLogStabilityMetrics) { | |
| 263 metrics::TestMetricsServiceClient client; | |
| 264 TestMetricsLog log( | |
| 265 kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 266 std::vector<metrics::MetricsProvider*> metrics_providers; | |
| 267 log.RecordEnvironment(metrics_providers, | |
| 268 std::vector<variations::ActiveGroupId>()); | |
| 269 log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), | |
| 270 base::TimeDelta()); | |
| 271 const metrics::SystemProfileProto_Stability& stability = | |
| 272 log.system_profile().stability(); | |
| 273 // Required metrics: | |
| 274 EXPECT_TRUE(stability.has_launch_count()); | |
| 275 EXPECT_TRUE(stability.has_crash_count()); | |
| 276 // Initial log metrics: | |
| 277 EXPECT_FALSE(stability.has_incomplete_shutdown_count()); | |
| 278 EXPECT_FALSE(stability.has_breakpad_registration_success_count()); | |
| 279 EXPECT_FALSE(stability.has_breakpad_registration_failure_count()); | |
| 280 EXPECT_FALSE(stability.has_debugger_present_count()); | |
| 281 EXPECT_FALSE(stability.has_debugger_not_present_count()); | |
| 282 } | |
| 283 | |
| 284 TEST_F(MetricsLogTest, ChromeChannelWrittenToProtobuf) { | |
| 285 metrics::TestMetricsServiceClient client; | |
| 286 TestMetricsLog log( | |
| 287 "user@test.com", kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); | |
| 288 EXPECT_TRUE(log.uma_proto().system_profile().has_channel()); | |
| 289 } | |
| OLD | NEW |