1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/metrics_service.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/message_loop/message_loop.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/prefs/testing_pref_service.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/threading/platform_thread.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/metrics/client_info.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/compression_utils.h" 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/metrics_log.h" 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/metrics_pref_names.h" 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/metrics_state_manager.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/metrics/test_metrics_service_client.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/variations/metrics_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace metrics { 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid StoreNoClientInfoBackup(const ClientInfo& /* client_info */) { 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<ClientInfo> ReturnNoBackup() { 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return scoped_ptr<ClientInfo>(); 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestMetricsProvider : public metrics::MetricsProvider { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci explicit TestMetricsProvider(bool has_stability_metrics) : 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci has_stability_metrics_(has_stability_metrics), 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci provide_stability_metrics_called_(false) { 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool HasStabilityMetrics() OVERRIDE { return has_stability_metrics_; } 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void ProvideStabilityMetrics( 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SystemProfileProto* system_profile_proto) OVERRIDE { 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci provide_stability_metrics_called_ = true; 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool provide_stability_metrics_called() const { 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return provide_stability_metrics_called_; 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool has_stability_metrics_; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool provide_stability_metrics_called_; 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(TestMetricsProvider); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestMetricsService : public MetricsService { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsService(MetricsStateManager* state_manager, 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsServiceClient* client, 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state) 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : MetricsService(state_manager, client, local_state) {} 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~TestMetricsService() {} 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) using MetricsService::log_manager; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestMetricsService); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestMetricsLog : public MetricsLog { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestMetricsLog(const std::string& client_id, 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int session_id, 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsServiceClient* client, 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state) 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : MetricsLog(client_id, 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_id, 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsLog::ONGOING_LOG, 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client, 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) local_state) {} 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~TestMetricsLog() {} 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestMetricsLog); 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class MetricsServiceTest : public testing::Test { 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public: 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsServiceTest() : is_metrics_reporting_enabled_(false) { 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsService::RegisterPrefs(testing_local_state_.registry()); 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci metrics_state_manager_ = MetricsStateManager::Create( 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetLocalState(), 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&MetricsServiceTest::is_metrics_reporting_enabled, 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this)), 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&StoreNoClientInfoBackup), 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&ReturnNoBackup)); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MetricsServiceTest() { 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE, 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetLocalState()); 105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsStateManager* GetMetricsStateManager() { 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return metrics_state_manager_.get(); 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* GetLocalState() { return &testing_local_state_; } 112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Sets metrics reporting as enabled for testing. 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void EnableMetricsReporting() { 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_metrics_reporting_enabled_ = true; 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Waits until base::TimeTicks::Now() no longer equals |value|. This should 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // take between 1-15ms per the documented resolution of base::TimeTicks. 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void WaitUntilTimeChanges(const base::TimeTicks& value) { 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (base::TimeTicks::Now() == value) { 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns true if there is a synthetic trial in the given vector that matches 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the given trial name and trial group; returns false otherwise. 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool HasSyntheticTrial( 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<variations::ActiveGroupId>& synthetic_trials, 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& trial_name, 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& trial_group) { 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 trial_name_hash = HashName(trial_name); 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 trial_group_hash = HashName(trial_group); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::vector<variations::ActiveGroupId>::const_iterator it = 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) synthetic_trials.begin(); 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != synthetic_trials.end(); ++it) { 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if ((*it).name == trial_name_hash && (*it).group == trial_group_hash) 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private: 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_metrics_reporting_enabled() const { 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return is_metrics_reporting_enabled_; 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_metrics_reporting_enabled_; 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestingPrefServiceSimple testing_local_state_; 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<MetricsStateManager> metrics_state_manager_; 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop message_loop; 152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest); 154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}; 155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) { 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EnableMetricsReporting(); 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsServiceClient client; 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestMetricsService service( 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetMetricsStateManager(), &client, GetLocalState()); 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsProvider* test_provider = new TestMetricsProvider(false); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service.RegisterMetricsProvider( 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<metrics::MetricsProvider>(test_provider)); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) service.InitializeMetricsRecordingState(); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No initial stability log should be generated. 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(service.log_manager()->has_unsent_logs()); 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(service.log_manager()->has_staged_log()); 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The test provider should not have been called upon to provide stability 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // metrics. 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(test_provider->provide_stability_metrics_called()); 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(MetricsServiceTest, InitialStabilityLogAtProviderRequest) { 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EnableMetricsReporting(); 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Save an existing system profile to prefs, to correspond to what would be 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // saved from a previous session. 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsServiceClient client; 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsLog log("client", 1, &client, GetLocalState()); 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(), 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<variations::ActiveGroupId>(), 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0); 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Record stability build time and version from previous session, so that 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // stability metrics (including exited cleanly flag) won't be cleared. 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsLog::GetBuildTime()); 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetString(prefs::kStabilityStatsVersion, 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client.GetVersionString()); 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Set the clean exit flag, as that will otherwise cause a stabilty 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // log to be produced, irrespective provider requests. 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true); 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsService service( 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMetricsStateManager(), &client, GetLocalState()); 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Add a metrics provider that requests a stability log. 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsProvider* test_provider = new TestMetricsProvider(true); 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service.RegisterMetricsProvider( 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<MetricsProvider>(test_provider)); 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service.InitializeMetricsRecordingState(); 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The initial stability log should be generated and persisted in unsent logs. 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsLogManager* log_manager = service.log_manager(); 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(log_manager->has_unsent_logs()); 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(log_manager->has_staged_log()); 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The test provider should have been called upon to provide stability 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // metrics. 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(test_provider->provide_stability_metrics_called()); 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Stage the log and retrieve it. 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_manager->StageNextLogForUpload(); 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(log_manager->has_staged_log()); 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string uncompressed_log; 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(GzipUncompress(log_manager->staged_log(), 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &uncompressed_log)); 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ChromeUserMetricsExtension uma_log; 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(uma_log.ParseFromString(uncompressed_log)); 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(uma_log.has_client_id()); 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(uma_log.has_session_id()); 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(uma_log.has_system_profile()); 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, uma_log.user_action_event_size()); 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, uma_log.omnibox_event_size()); 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, uma_log.histogram_event_size()); 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, uma_log.profiler_event_size()); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, uma_log.perf_data_size()); 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // As there wasn't an unclean shutdown, this log has zero crash count. 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, uma_log.system_profile().stability().crash_count()); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) { 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EnableMetricsReporting(); 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set up prefs to simulate restarting after a crash. 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Save an existing system profile to prefs, to correspond to what would be 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // saved from a previous session. 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TestMetricsServiceClient client; 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TestMetricsLog log("client", 1, &client, GetLocalState()); 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log.RecordEnvironment(std::vector<MetricsProvider*>(), 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<variations::ActiveGroupId>(), 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 0); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Record stability build time and version from previous session, so that 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // stability metrics (including exited cleanly flag) won't be cleared. 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsLog::GetBuildTime()); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetString(prefs::kStabilityStatsVersion, 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client.GetVersionString()); 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TestMetricsService service( 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetMetricsStateManager(), &client, GetLocalState()); 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) service.InitializeMetricsRecordingState(); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The initial stability log should be generated and persisted in unsent logs. 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MetricsLogManager* log_manager = service.log_manager(); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(log_manager->has_unsent_logs()); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(log_manager->has_staged_log()); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Stage the log and retrieve it. 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_manager->StageNextLogForUpload(); 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(log_manager->has_staged_log()); 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string uncompressed_log; 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(metrics::GzipUncompress(log_manager->staged_log(), 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &uncompressed_log)); 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metrics::ChromeUserMetricsExtension uma_log; 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(uma_log.ParseFromString(uncompressed_log)); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(uma_log.has_client_id()); 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(uma_log.has_session_id()); 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(uma_log.has_system_profile()); 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, uma_log.user_action_event_size()); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, uma_log.omnibox_event_size()); 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, uma_log.histogram_event_size()); 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, uma_log.profiler_event_size()); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, uma_log.perf_data_size()); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, uma_log.system_profile().stability().crash_count()); 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MetricsServiceTest, RegisterSyntheticTrial) { 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metrics::TestMetricsServiceClient client; 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsService service(GetMetricsStateManager(), &client, GetLocalState()); 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add two synthetic trials and confirm that they show up in the list. 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"), 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) metrics::HashName("Group1")); 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.RegisterSyntheticFieldTrial(trial1); 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"), 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) metrics::HashName("Group2")); 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.RegisterSyntheticFieldTrial(trial2); 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Ensure that time has advanced by at least a tick before proceeding. 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WaitUntilTimeChanges(base::TimeTicks::Now()); 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) service.log_manager_.BeginLoggingWithLog(scoped_ptr<MetricsLog>( 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MetricsLog("clientID", 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1, 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsLog::INITIAL_STABILITY_LOG, 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &client, 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetLocalState()))); 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Save the time when the log was started (it's okay for this to be greater 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // than the time recorded by the above call since it's used to ensure the 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // value changes). 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::TimeTicks begin_log_time = base::TimeTicks::Now(); 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<variations::ActiveGroupId> synthetic_trials; 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.GetCurrentSyntheticFieldTrials(&synthetic_trials); 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(2U, synthetic_trials.size()); 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group1")); 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2")); 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Ensure that time has advanced by at least a tick before proceeding. 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WaitUntilTimeChanges(begin_log_time); 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Change the group for the first trial after the log started. 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"), 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) metrics::HashName("Group2")); 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.RegisterSyntheticFieldTrial(trial3); 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.GetCurrentSyntheticFieldTrials(&synthetic_trials); 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(1U, synthetic_trials.size()); 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2")); 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add a new trial after the log started and confirm that it doesn't show up. 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SyntheticTrialGroup trial4(metrics::HashName("TestTrial3"), 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) metrics::HashName("Group3")); 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.RegisterSyntheticFieldTrial(trial4); 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.GetCurrentSyntheticFieldTrials(&synthetic_trials); 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(1U, synthetic_trials.size()); 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2")); 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Ensure that time has advanced by at least a tick before proceeding. 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WaitUntilTimeChanges(base::TimeTicks::Now()); 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start a new log and ensure all three trials appear in it. 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.log_manager_.FinishCurrentLog(); 355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch service.log_manager_.BeginLoggingWithLog( 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<MetricsLog>(new MetricsLog( 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "clientID", 1, MetricsLog::ONGOING_LOG, &client, GetLocalState()))); 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.GetCurrentSyntheticFieldTrials(&synthetic_trials); 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(3U, synthetic_trials.size()); 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "Group2")); 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2")); 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial3", "Group3")); 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) service.log_manager_.FinishCurrentLog(); 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace metrics 367