xref: /aosp_15_r20/external/cronet/components/metrics/metrics_service_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_service.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <algorithm>
10*6777b538SAndroid Build Coastguard Worker #include <memory>
11*6777b538SAndroid Build Coastguard Worker #include <string>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/metrics/field_trial.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_functions.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_snapshot_manager.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/metrics/metrics_hashes.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/metrics/statistics_recorder.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/metrics/user_metrics.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
31*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
32*6777b538SAndroid Build Coastguard Worker #include "components/metrics/clean_exit_beacon.h"
33*6777b538SAndroid Build Coastguard Worker #include "components/metrics/client_info.h"
34*6777b538SAndroid Build Coastguard Worker #include "components/metrics/cloned_install_detector.h"
35*6777b538SAndroid Build Coastguard Worker #include "components/metrics/environment_recorder.h"
36*6777b538SAndroid Build Coastguard Worker #include "components/metrics/log_decoder.h"
37*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_features.h"
38*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_log.h"
39*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_pref_names.h"
40*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_scheduler.h"
41*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_state_manager.h"
42*6777b538SAndroid Build Coastguard Worker #include "components/metrics/metrics_upload_scheduler.h"
43*6777b538SAndroid Build Coastguard Worker #include "components/metrics/stability_metrics_helper.h"
44*6777b538SAndroid Build Coastguard Worker #include "components/metrics/test/test_enabled_state_provider.h"
45*6777b538SAndroid Build Coastguard Worker #include "components/metrics/test/test_metrics_provider.h"
46*6777b538SAndroid Build Coastguard Worker #include "components/metrics/test/test_metrics_service_client.h"
47*6777b538SAndroid Build Coastguard Worker #include "components/metrics/unsent_log_store_metrics_impl.h"
48*6777b538SAndroid Build Coastguard Worker #include "components/prefs/testing_pref_service.h"
49*6777b538SAndroid Build Coastguard Worker #include "components/variations/active_field_trials.h"
50*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
51*6777b538SAndroid Build Coastguard Worker #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
52*6777b538SAndroid Build Coastguard Worker #include "third_party/metrics_proto/system_profile.pb.h"
53*6777b538SAndroid Build Coastguard Worker #include "third_party/zlib/google/compression_utils.h"
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker namespace metrics {
56*6777b538SAndroid Build Coastguard Worker namespace {
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker const char kTestPrefName[] = "TestPref";
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker class TestUnsentLogStore : public UnsentLogStore {
61*6777b538SAndroid Build Coastguard Worker  public:
TestUnsentLogStore(PrefService * service)62*6777b538SAndroid Build Coastguard Worker   explicit TestUnsentLogStore(PrefService* service)
63*6777b538SAndroid Build Coastguard Worker       : UnsentLogStore(std::make_unique<UnsentLogStoreMetricsImpl>(),
64*6777b538SAndroid Build Coastguard Worker                        service,
65*6777b538SAndroid Build Coastguard Worker                        kTestPrefName,
66*6777b538SAndroid Build Coastguard Worker                        nullptr,
67*6777b538SAndroid Build Coastguard Worker                        // Set to 3 so logs are not dropped in the test.
68*6777b538SAndroid Build Coastguard Worker                        UnsentLogStore::UnsentLogStoreLimits{
69*6777b538SAndroid Build Coastguard Worker                            .min_log_count = 3,
70*6777b538SAndroid Build Coastguard Worker                        },
71*6777b538SAndroid Build Coastguard Worker                        /*signing_key=*/std::string(),
72*6777b538SAndroid Build Coastguard Worker                        /*logs_event_manager=*/nullptr) {}
73*6777b538SAndroid Build Coastguard Worker   ~TestUnsentLogStore() override = default;
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   TestUnsentLogStore(const TestUnsentLogStore&) = delete;
76*6777b538SAndroid Build Coastguard Worker   TestUnsentLogStore& operator=(const TestUnsentLogStore&) = delete;
77*6777b538SAndroid Build Coastguard Worker 
RegisterPrefs(PrefRegistrySimple * registry)78*6777b538SAndroid Build Coastguard Worker   static void RegisterPrefs(PrefRegistrySimple* registry) {
79*6777b538SAndroid Build Coastguard Worker     registry->RegisterListPref(kTestPrefName);
80*6777b538SAndroid Build Coastguard Worker   }
81*6777b538SAndroid Build Coastguard Worker };
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker // Returns true if |id| is present in |proto|'s collection of FieldTrials.
IsFieldTrialPresent(const SystemProfileProto & proto,const std::string & trial_name,const std::string & group_name)84*6777b538SAndroid Build Coastguard Worker bool IsFieldTrialPresent(const SystemProfileProto& proto,
85*6777b538SAndroid Build Coastguard Worker                          const std::string& trial_name,
86*6777b538SAndroid Build Coastguard Worker                          const std::string& group_name) {
87*6777b538SAndroid Build Coastguard Worker   const variations::ActiveGroupId id =
88*6777b538SAndroid Build Coastguard Worker       variations::MakeActiveGroupId(trial_name, group_name);
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   for (const auto& trial : proto.field_trial()) {
91*6777b538SAndroid Build Coastguard Worker     if (trial.name_id() == id.name && trial.group_id() == id.group)
92*6777b538SAndroid Build Coastguard Worker       return true;
93*6777b538SAndroid Build Coastguard Worker   }
94*6777b538SAndroid Build Coastguard Worker   return false;
95*6777b538SAndroid Build Coastguard Worker }
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker class TestMetricsService : public MetricsService {
98*6777b538SAndroid Build Coastguard Worker  public:
TestMetricsService(MetricsStateManager * state_manager,MetricsServiceClient * client,PrefService * local_state)99*6777b538SAndroid Build Coastguard Worker   TestMetricsService(MetricsStateManager* state_manager,
100*6777b538SAndroid Build Coastguard Worker                      MetricsServiceClient* client,
101*6777b538SAndroid Build Coastguard Worker                      PrefService* local_state)
102*6777b538SAndroid Build Coastguard Worker       : MetricsService(state_manager, client, local_state) {}
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker   TestMetricsService(const TestMetricsService&) = delete;
105*6777b538SAndroid Build Coastguard Worker   TestMetricsService& operator=(const TestMetricsService&) = delete;
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   ~TestMetricsService() override = default;
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker   using MetricsService::INIT_TASK_DONE;
110*6777b538SAndroid Build Coastguard Worker   using MetricsService::INIT_TASK_SCHEDULED;
111*6777b538SAndroid Build Coastguard Worker   using MetricsService::RecordCurrentEnvironmentHelper;
112*6777b538SAndroid Build Coastguard Worker   using MetricsService::SENDING_LOGS;
113*6777b538SAndroid Build Coastguard Worker   using MetricsService::state;
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   // MetricsService:
SetPersistentSystemProfile(const std::string & serialized_proto,bool complete)116*6777b538SAndroid Build Coastguard Worker   void SetPersistentSystemProfile(const std::string& serialized_proto,
117*6777b538SAndroid Build Coastguard Worker                                   bool complete) override {
118*6777b538SAndroid Build Coastguard Worker     persistent_system_profile_provided_ = true;
119*6777b538SAndroid Build Coastguard Worker     persistent_system_profile_complete_ = complete;
120*6777b538SAndroid Build Coastguard Worker   }
121*6777b538SAndroid Build Coastguard Worker 
persistent_system_profile_provided() const122*6777b538SAndroid Build Coastguard Worker   bool persistent_system_profile_provided() const {
123*6777b538SAndroid Build Coastguard Worker     return persistent_system_profile_provided_;
124*6777b538SAndroid Build Coastguard Worker   }
persistent_system_profile_complete() const125*6777b538SAndroid Build Coastguard Worker   bool persistent_system_profile_complete() const {
126*6777b538SAndroid Build Coastguard Worker     return persistent_system_profile_complete_;
127*6777b538SAndroid Build Coastguard Worker   }
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker  private:
130*6777b538SAndroid Build Coastguard Worker   bool persistent_system_profile_provided_ = false;
131*6777b538SAndroid Build Coastguard Worker   bool persistent_system_profile_complete_ = false;
132*6777b538SAndroid Build Coastguard Worker };
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker class TestMetricsLog : public MetricsLog {
135*6777b538SAndroid Build Coastguard Worker  public:
TestMetricsLog(const std::string & client_id,int session_id,MetricsServiceClient * client)136*6777b538SAndroid Build Coastguard Worker   TestMetricsLog(const std::string& client_id,
137*6777b538SAndroid Build Coastguard Worker                  int session_id,
138*6777b538SAndroid Build Coastguard Worker                  MetricsServiceClient* client)
139*6777b538SAndroid Build Coastguard Worker       : MetricsLog(client_id, session_id, MetricsLog::ONGOING_LOG, client) {}
140*6777b538SAndroid Build Coastguard Worker 
141*6777b538SAndroid Build Coastguard Worker   TestMetricsLog(const TestMetricsLog&) = delete;
142*6777b538SAndroid Build Coastguard Worker   TestMetricsLog& operator=(const TestMetricsLog&) = delete;
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker   ~TestMetricsLog() override = default;
145*6777b538SAndroid Build Coastguard Worker };
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker const char kOnDidCreateMetricsLogHistogramName[] = "Test.OnDidCreateMetricsLog";
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker class TestMetricsProviderForOnDidCreateMetricsLog : public TestMetricsProvider {
150*6777b538SAndroid Build Coastguard Worker  public:
151*6777b538SAndroid Build Coastguard Worker   TestMetricsProviderForOnDidCreateMetricsLog() = default;
152*6777b538SAndroid Build Coastguard Worker   ~TestMetricsProviderForOnDidCreateMetricsLog() override = default;
153*6777b538SAndroid Build Coastguard Worker 
OnDidCreateMetricsLog()154*6777b538SAndroid Build Coastguard Worker   void OnDidCreateMetricsLog() override {
155*6777b538SAndroid Build Coastguard Worker     base::UmaHistogramBoolean(kOnDidCreateMetricsLogHistogramName, true);
156*6777b538SAndroid Build Coastguard Worker   }
157*6777b538SAndroid Build Coastguard Worker };
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker const char kProvideHistogramsHistogramName[] = "Test.ProvideHistograms";
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker class TestMetricsProviderForProvideHistograms : public TestMetricsProvider {
162*6777b538SAndroid Build Coastguard Worker  public:
163*6777b538SAndroid Build Coastguard Worker   TestMetricsProviderForProvideHistograms() = default;
164*6777b538SAndroid Build Coastguard Worker   ~TestMetricsProviderForProvideHistograms() override = default;
165*6777b538SAndroid Build Coastguard Worker 
ProvideHistograms()166*6777b538SAndroid Build Coastguard Worker   bool ProvideHistograms() override {
167*6777b538SAndroid Build Coastguard Worker     base::UmaHistogramBoolean(kProvideHistogramsHistogramName, true);
168*6777b538SAndroid Build Coastguard Worker     return true;
169*6777b538SAndroid Build Coastguard Worker   }
170*6777b538SAndroid Build Coastguard Worker 
ProvideCurrentSessionData(ChromeUserMetricsExtension * uma_proto)171*6777b538SAndroid Build Coastguard Worker   void ProvideCurrentSessionData(
172*6777b538SAndroid Build Coastguard Worker       ChromeUserMetricsExtension* uma_proto) override {
173*6777b538SAndroid Build Coastguard Worker     MetricsProvider::ProvideCurrentSessionData(uma_proto);
174*6777b538SAndroid Build Coastguard Worker   }
175*6777b538SAndroid Build Coastguard Worker };
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker class TestMetricsProviderForProvideHistogramsEarlyReturn
178*6777b538SAndroid Build Coastguard Worker     : public TestMetricsProviderForProvideHistograms {
179*6777b538SAndroid Build Coastguard Worker  public:
180*6777b538SAndroid Build Coastguard Worker   TestMetricsProviderForProvideHistogramsEarlyReturn() = default;
181*6777b538SAndroid Build Coastguard Worker   ~TestMetricsProviderForProvideHistogramsEarlyReturn() override = default;
182*6777b538SAndroid Build Coastguard Worker 
OnDidCreateMetricsLog()183*6777b538SAndroid Build Coastguard Worker   void OnDidCreateMetricsLog() override {}
184*6777b538SAndroid Build Coastguard Worker };
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker class TestIndependentMetricsProvider : public MetricsProvider {
187*6777b538SAndroid Build Coastguard Worker  public:
188*6777b538SAndroid Build Coastguard Worker   TestIndependentMetricsProvider() = default;
189*6777b538SAndroid Build Coastguard Worker   ~TestIndependentMetricsProvider() override = default;
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker   // MetricsProvider:
HasIndependentMetrics()192*6777b538SAndroid Build Coastguard Worker   bool HasIndependentMetrics() override {
193*6777b538SAndroid Build Coastguard Worker     // Only return true the first time this is called (i.e., we only have one
194*6777b538SAndroid Build Coastguard Worker     // independent log to provide).
195*6777b538SAndroid Build Coastguard Worker     if (!has_independent_metrics_called_) {
196*6777b538SAndroid Build Coastguard Worker       has_independent_metrics_called_ = true;
197*6777b538SAndroid Build Coastguard Worker       return true;
198*6777b538SAndroid Build Coastguard Worker     }
199*6777b538SAndroid Build Coastguard Worker     return false;
200*6777b538SAndroid Build Coastguard Worker   }
ProvideIndependentMetrics(base::OnceClosure serialize_log_callback,base::OnceCallback<void (bool)> done_callback,ChromeUserMetricsExtension * uma_proto,base::HistogramSnapshotManager * snapshot_manager)201*6777b538SAndroid Build Coastguard Worker   void ProvideIndependentMetrics(
202*6777b538SAndroid Build Coastguard Worker       base::OnceClosure serialize_log_callback,
203*6777b538SAndroid Build Coastguard Worker       base::OnceCallback<void(bool)> done_callback,
204*6777b538SAndroid Build Coastguard Worker       ChromeUserMetricsExtension* uma_proto,
205*6777b538SAndroid Build Coastguard Worker       base::HistogramSnapshotManager* snapshot_manager) override {
206*6777b538SAndroid Build Coastguard Worker     provide_independent_metrics_called_ = true;
207*6777b538SAndroid Build Coastguard Worker     uma_proto->set_client_id(123);
208*6777b538SAndroid Build Coastguard Worker     std::move(done_callback).Run(true);
209*6777b538SAndroid Build Coastguard Worker   }
210*6777b538SAndroid Build Coastguard Worker 
has_independent_metrics_called() const211*6777b538SAndroid Build Coastguard Worker   bool has_independent_metrics_called() const {
212*6777b538SAndroid Build Coastguard Worker     return has_independent_metrics_called_;
213*6777b538SAndroid Build Coastguard Worker   }
214*6777b538SAndroid Build Coastguard Worker 
provide_independent_metrics_called() const215*6777b538SAndroid Build Coastguard Worker   bool provide_independent_metrics_called() const {
216*6777b538SAndroid Build Coastguard Worker     return provide_independent_metrics_called_;
217*6777b538SAndroid Build Coastguard Worker   }
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker  private:
220*6777b538SAndroid Build Coastguard Worker   bool has_independent_metrics_called_ = false;
221*6777b538SAndroid Build Coastguard Worker   bool provide_independent_metrics_called_ = false;
222*6777b538SAndroid Build Coastguard Worker };
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker class MetricsServiceTest : public testing::Test {
225*6777b538SAndroid Build Coastguard Worker  public:
MetricsServiceTest()226*6777b538SAndroid Build Coastguard Worker   MetricsServiceTest()
227*6777b538SAndroid Build Coastguard Worker       : enabled_state_provider_(new TestEnabledStateProvider(false, false)) {
228*6777b538SAndroid Build Coastguard Worker     base::SetRecordActionTaskRunner(
229*6777b538SAndroid Build Coastguard Worker         task_environment_.GetMainThreadTaskRunner());
230*6777b538SAndroid Build Coastguard Worker     MetricsService::RegisterPrefs(testing_local_state_.registry());
231*6777b538SAndroid Build Coastguard Worker   }
232*6777b538SAndroid Build Coastguard Worker 
233*6777b538SAndroid Build Coastguard Worker   MetricsServiceTest(const MetricsServiceTest&) = delete;
234*6777b538SAndroid Build Coastguard Worker   MetricsServiceTest& operator=(const MetricsServiceTest&) = delete;
235*6777b538SAndroid Build Coastguard Worker 
236*6777b538SAndroid Build Coastguard Worker   ~MetricsServiceTest() override = default;
237*6777b538SAndroid Build Coastguard Worker 
SetUp()238*6777b538SAndroid Build Coastguard Worker   void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
239*6777b538SAndroid Build Coastguard Worker 
GetMetricsStateManager(const base::FilePath & user_data_dir=base::FilePath (),StartupVisibility startup_visibility=StartupVisibility::kUnknown)240*6777b538SAndroid Build Coastguard Worker   MetricsStateManager* GetMetricsStateManager(
241*6777b538SAndroid Build Coastguard Worker       const base::FilePath& user_data_dir = base::FilePath(),
242*6777b538SAndroid Build Coastguard Worker       StartupVisibility startup_visibility = StartupVisibility::kUnknown) {
243*6777b538SAndroid Build Coastguard Worker     // Lazy-initialize the metrics_state_manager so that it correctly reads the
244*6777b538SAndroid Build Coastguard Worker     // stability state from prefs after tests have a chance to initialize it.
245*6777b538SAndroid Build Coastguard Worker     if (!metrics_state_manager_) {
246*6777b538SAndroid Build Coastguard Worker       metrics_state_manager_ = MetricsStateManager::Create(
247*6777b538SAndroid Build Coastguard Worker           GetLocalState(), enabled_state_provider_.get(), std::wstring(),
248*6777b538SAndroid Build Coastguard Worker           user_data_dir, startup_visibility);
249*6777b538SAndroid Build Coastguard Worker       metrics_state_manager_->InstantiateFieldTrialList();
250*6777b538SAndroid Build Coastguard Worker     }
251*6777b538SAndroid Build Coastguard Worker     return metrics_state_manager_.get();
252*6777b538SAndroid Build Coastguard Worker   }
253*6777b538SAndroid Build Coastguard Worker 
InitializeTestLogStoreAndGet()254*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestUnsentLogStore> InitializeTestLogStoreAndGet() {
255*6777b538SAndroid Build Coastguard Worker     TestUnsentLogStore::RegisterPrefs(testing_local_state_.registry());
256*6777b538SAndroid Build Coastguard Worker     return std::make_unique<TestUnsentLogStore>(GetLocalState());
257*6777b538SAndroid Build Coastguard Worker   }
258*6777b538SAndroid Build Coastguard Worker 
GetLocalState()259*6777b538SAndroid Build Coastguard Worker   PrefService* GetLocalState() { return &testing_local_state_; }
260*6777b538SAndroid Build Coastguard Worker 
261*6777b538SAndroid Build Coastguard Worker   // Sets metrics reporting as enabled for testing.
EnableMetricsReporting()262*6777b538SAndroid Build Coastguard Worker   void EnableMetricsReporting() { SetMetricsReporting(true); }
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker   // Sets metrics reporting for testing.
SetMetricsReporting(bool enabled)265*6777b538SAndroid Build Coastguard Worker   void SetMetricsReporting(bool enabled) {
266*6777b538SAndroid Build Coastguard Worker     enabled_state_provider_->set_consent(enabled);
267*6777b538SAndroid Build Coastguard Worker     enabled_state_provider_->set_enabled(enabled);
268*6777b538SAndroid Build Coastguard Worker   }
269*6777b538SAndroid Build Coastguard Worker 
270*6777b538SAndroid Build Coastguard Worker   // Finds a histogram with the specified |name_hash| in |histograms|.
FindHistogram(const base::StatisticsRecorder::Histograms & histograms,uint64_t name_hash)271*6777b538SAndroid Build Coastguard Worker   const base::HistogramBase* FindHistogram(
272*6777b538SAndroid Build Coastguard Worker       const base::StatisticsRecorder::Histograms& histograms,
273*6777b538SAndroid Build Coastguard Worker       uint64_t name_hash) {
274*6777b538SAndroid Build Coastguard Worker     for (const base::HistogramBase* histogram : histograms) {
275*6777b538SAndroid Build Coastguard Worker       if (name_hash == base::HashMetricName(histogram->histogram_name()))
276*6777b538SAndroid Build Coastguard Worker         return histogram;
277*6777b538SAndroid Build Coastguard Worker     }
278*6777b538SAndroid Build Coastguard Worker     return nullptr;
279*6777b538SAndroid Build Coastguard Worker   }
280*6777b538SAndroid Build Coastguard Worker 
281*6777b538SAndroid Build Coastguard Worker   // Checks whether |uma_log| contains any histograms that are not flagged
282*6777b538SAndroid Build Coastguard Worker   // with kUmaStabilityHistogramFlag. Stability logs should only contain such
283*6777b538SAndroid Build Coastguard Worker   // histograms.
CheckForNonStabilityHistograms(const ChromeUserMetricsExtension & uma_log)284*6777b538SAndroid Build Coastguard Worker   void CheckForNonStabilityHistograms(
285*6777b538SAndroid Build Coastguard Worker       const ChromeUserMetricsExtension& uma_log) {
286*6777b538SAndroid Build Coastguard Worker     const int kStabilityFlags = base::HistogramBase::kUmaStabilityHistogramFlag;
287*6777b538SAndroid Build Coastguard Worker     const base::StatisticsRecorder::Histograms histograms =
288*6777b538SAndroid Build Coastguard Worker         base::StatisticsRecorder::GetHistograms();
289*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < uma_log.histogram_event_size(); ++i) {
290*6777b538SAndroid Build Coastguard Worker       const uint64_t hash = uma_log.histogram_event(i).name_hash();
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker       const base::HistogramBase* histogram = FindHistogram(histograms, hash);
293*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(histogram) << hash;
294*6777b538SAndroid Build Coastguard Worker 
295*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(histogram->HasFlags(kStabilityFlags)) << hash;
296*6777b538SAndroid Build Coastguard Worker     }
297*6777b538SAndroid Build Coastguard Worker   }
298*6777b538SAndroid Build Coastguard Worker 
299*6777b538SAndroid Build Coastguard Worker   // Returns the number of samples logged to the specified histogram or 0 if
300*6777b538SAndroid Build Coastguard Worker   // the histogram was not found.
GetHistogramSampleCount(const ChromeUserMetricsExtension & uma_log,base::StringPiece histogram_name)301*6777b538SAndroid Build Coastguard Worker   int GetHistogramSampleCount(const ChromeUserMetricsExtension& uma_log,
302*6777b538SAndroid Build Coastguard Worker                               base::StringPiece histogram_name) {
303*6777b538SAndroid Build Coastguard Worker     const auto histogram_name_hash = base::HashMetricName(histogram_name);
304*6777b538SAndroid Build Coastguard Worker     int samples = 0;
305*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < uma_log.histogram_event_size(); ++i) {
306*6777b538SAndroid Build Coastguard Worker       const auto& histogram = uma_log.histogram_event(i);
307*6777b538SAndroid Build Coastguard Worker       if (histogram.name_hash() == histogram_name_hash) {
308*6777b538SAndroid Build Coastguard Worker         for (int j = 0; j < histogram.bucket_size(); ++j) {
309*6777b538SAndroid Build Coastguard Worker           const auto& bucket = histogram.bucket(j);
310*6777b538SAndroid Build Coastguard Worker           // Per proto comments, count field not being set means 1 sample.
311*6777b538SAndroid Build Coastguard Worker           samples += (!bucket.has_count() ? 1 : bucket.count());
312*6777b538SAndroid Build Coastguard Worker         }
313*6777b538SAndroid Build Coastguard Worker       }
314*6777b538SAndroid Build Coastguard Worker     }
315*6777b538SAndroid Build Coastguard Worker     return samples;
316*6777b538SAndroid Build Coastguard Worker   }
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker   // Returns the sampled count of the |kOnDidCreateMetricsLogHistogramName|
319*6777b538SAndroid Build Coastguard Worker   // histogram in the currently staged log in |test_log_store|.
GetSampleCountOfOnDidCreateLogHistogram(MetricsLogStore * test_log_store)320*6777b538SAndroid Build Coastguard Worker   int GetSampleCountOfOnDidCreateLogHistogram(MetricsLogStore* test_log_store) {
321*6777b538SAndroid Build Coastguard Worker     ChromeUserMetricsExtension log;
322*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &log));
323*6777b538SAndroid Build Coastguard Worker     return GetHistogramSampleCount(log, kOnDidCreateMetricsLogHistogramName);
324*6777b538SAndroid Build Coastguard Worker   }
325*6777b538SAndroid Build Coastguard Worker 
GetNumberOfUserActions(MetricsLogStore * test_log_store)326*6777b538SAndroid Build Coastguard Worker   int GetNumberOfUserActions(MetricsLogStore* test_log_store) {
327*6777b538SAndroid Build Coastguard Worker     ChromeUserMetricsExtension log;
328*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &log));
329*6777b538SAndroid Build Coastguard Worker     return log.user_action_event_size();
330*6777b538SAndroid Build Coastguard Worker   }
331*6777b538SAndroid Build Coastguard Worker 
user_data_dir_path()332*6777b538SAndroid Build Coastguard Worker   const base::FilePath user_data_dir_path() { return temp_dir_.GetPath(); }
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker  protected:
335*6777b538SAndroid Build Coastguard Worker   base::test::TaskEnvironment task_environment_{
336*6777b538SAndroid Build Coastguard Worker       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
337*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list_;
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker  private:
340*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestEnabledStateProvider> enabled_state_provider_;
341*6777b538SAndroid Build Coastguard Worker   TestingPrefServiceSimple testing_local_state_;
342*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<MetricsStateManager> metrics_state_manager_;
343*6777b538SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir_;
344*6777b538SAndroid Build Coastguard Worker };
345*6777b538SAndroid Build Coastguard Worker 
346*6777b538SAndroid Build Coastguard Worker class MetricsServiceTestWithFeatures
347*6777b538SAndroid Build Coastguard Worker     : public MetricsServiceTest,
348*6777b538SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<std::tuple<bool>> {
349*6777b538SAndroid Build Coastguard Worker  public:
350*6777b538SAndroid Build Coastguard Worker   MetricsServiceTestWithFeatures() = default;
351*6777b538SAndroid Build Coastguard Worker   ~MetricsServiceTestWithFeatures() override = default;
352*6777b538SAndroid Build Coastguard Worker 
ShouldSnapshotInBg()353*6777b538SAndroid Build Coastguard Worker   bool ShouldSnapshotInBg() { return std::get<0>(GetParam()); }
354*6777b538SAndroid Build Coastguard Worker 
SetUp()355*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
356*6777b538SAndroid Build Coastguard Worker     MetricsServiceTest::SetUp();
357*6777b538SAndroid Build Coastguard Worker     std::vector<base::test::FeatureRefAndParams> enabled_features;
358*6777b538SAndroid Build Coastguard Worker     std::vector<base::test::FeatureRef> disabled_features;
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker     if (ShouldSnapshotInBg()) {
361*6777b538SAndroid Build Coastguard Worker       enabled_features.emplace_back(features::kMetricsServiceDeltaSnapshotInBg,
362*6777b538SAndroid Build Coastguard Worker                                     base::FieldTrialParams());
363*6777b538SAndroid Build Coastguard Worker     } else {
364*6777b538SAndroid Build Coastguard Worker       disabled_features.emplace_back(
365*6777b538SAndroid Build Coastguard Worker           features::kMetricsServiceDeltaSnapshotInBg);
366*6777b538SAndroid Build Coastguard Worker     }
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker     feature_list_.InitWithFeaturesAndParameters(enabled_features,
369*6777b538SAndroid Build Coastguard Worker                                                 disabled_features);
370*6777b538SAndroid Build Coastguard Worker   }
371*6777b538SAndroid Build Coastguard Worker 
372*6777b538SAndroid Build Coastguard Worker  private:
373*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list_;
374*6777b538SAndroid Build Coastguard Worker };
375*6777b538SAndroid Build Coastguard Worker 
376*6777b538SAndroid Build Coastguard Worker struct StartupVisibilityTestParams {
377*6777b538SAndroid Build Coastguard Worker   metrics::StartupVisibility startup_visibility;
378*6777b538SAndroid Build Coastguard Worker   bool expected_beacon_value;
379*6777b538SAndroid Build Coastguard Worker };
380*6777b538SAndroid Build Coastguard Worker 
381*6777b538SAndroid Build Coastguard Worker class MetricsServiceTestWithStartupVisibility
382*6777b538SAndroid Build Coastguard Worker     : public MetricsServiceTest,
383*6777b538SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<
384*6777b538SAndroid Build Coastguard Worker           std::tuple<StartupVisibilityTestParams, bool>> {
385*6777b538SAndroid Build Coastguard Worker  public:
386*6777b538SAndroid Build Coastguard Worker   MetricsServiceTestWithStartupVisibility() = default;
387*6777b538SAndroid Build Coastguard Worker   ~MetricsServiceTestWithStartupVisibility() override = default;
388*6777b538SAndroid Build Coastguard Worker 
ShouldSnapshotInBg()389*6777b538SAndroid Build Coastguard Worker   bool ShouldSnapshotInBg() { return std::get<1>(GetParam()); }
390*6777b538SAndroid Build Coastguard Worker 
SetUp()391*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
392*6777b538SAndroid Build Coastguard Worker     MetricsServiceTest::SetUp();
393*6777b538SAndroid Build Coastguard Worker     std::vector<base::test::FeatureRefAndParams> enabled_features;
394*6777b538SAndroid Build Coastguard Worker     std::vector<base::test::FeatureRef> disabled_features;
395*6777b538SAndroid Build Coastguard Worker 
396*6777b538SAndroid Build Coastguard Worker     if (ShouldSnapshotInBg()) {
397*6777b538SAndroid Build Coastguard Worker       enabled_features.emplace_back(features::kMetricsServiceDeltaSnapshotInBg,
398*6777b538SAndroid Build Coastguard Worker                                     base::FieldTrialParams());
399*6777b538SAndroid Build Coastguard Worker     } else {
400*6777b538SAndroid Build Coastguard Worker       disabled_features.emplace_back(
401*6777b538SAndroid Build Coastguard Worker           features::kMetricsServiceDeltaSnapshotInBg);
402*6777b538SAndroid Build Coastguard Worker     }
403*6777b538SAndroid Build Coastguard Worker 
404*6777b538SAndroid Build Coastguard Worker     feature_list_.InitWithFeaturesAndParameters(enabled_features,
405*6777b538SAndroid Build Coastguard Worker                                                 disabled_features);
406*6777b538SAndroid Build Coastguard Worker   }
407*6777b538SAndroid Build Coastguard Worker 
408*6777b538SAndroid Build Coastguard Worker  private:
409*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list_;
410*6777b538SAndroid Build Coastguard Worker };
411*6777b538SAndroid Build Coastguard Worker 
412*6777b538SAndroid Build Coastguard Worker class ExperimentTestMetricsProvider : public TestMetricsProvider {
413*6777b538SAndroid Build Coastguard Worker  public:
ExperimentTestMetricsProvider(base::FieldTrial * profile_metrics_trial,base::FieldTrial * session_data_trial)414*6777b538SAndroid Build Coastguard Worker   explicit ExperimentTestMetricsProvider(
415*6777b538SAndroid Build Coastguard Worker       base::FieldTrial* profile_metrics_trial,
416*6777b538SAndroid Build Coastguard Worker       base::FieldTrial* session_data_trial)
417*6777b538SAndroid Build Coastguard Worker       : profile_metrics_trial_(profile_metrics_trial),
418*6777b538SAndroid Build Coastguard Worker         session_data_trial_(session_data_trial) {}
419*6777b538SAndroid Build Coastguard Worker 
420*6777b538SAndroid Build Coastguard Worker   ~ExperimentTestMetricsProvider() override = default;
421*6777b538SAndroid Build Coastguard Worker 
ProvideSystemProfileMetrics(SystemProfileProto * system_profile_proto)422*6777b538SAndroid Build Coastguard Worker   void ProvideSystemProfileMetrics(
423*6777b538SAndroid Build Coastguard Worker       SystemProfileProto* system_profile_proto) override {
424*6777b538SAndroid Build Coastguard Worker     TestMetricsProvider::ProvideSystemProfileMetrics(system_profile_proto);
425*6777b538SAndroid Build Coastguard Worker     profile_metrics_trial_->Activate();
426*6777b538SAndroid Build Coastguard Worker   }
427*6777b538SAndroid Build Coastguard Worker 
ProvideCurrentSessionData(ChromeUserMetricsExtension * uma_proto)428*6777b538SAndroid Build Coastguard Worker   void ProvideCurrentSessionData(
429*6777b538SAndroid Build Coastguard Worker       ChromeUserMetricsExtension* uma_proto) override {
430*6777b538SAndroid Build Coastguard Worker     TestMetricsProvider::ProvideCurrentSessionData(uma_proto);
431*6777b538SAndroid Build Coastguard Worker     session_data_trial_->Activate();
432*6777b538SAndroid Build Coastguard Worker   }
433*6777b538SAndroid Build Coastguard Worker 
434*6777b538SAndroid Build Coastguard Worker  private:
435*6777b538SAndroid Build Coastguard Worker   raw_ptr<base::FieldTrial> profile_metrics_trial_;
436*6777b538SAndroid Build Coastguard Worker   raw_ptr<base::FieldTrial> session_data_trial_;
437*6777b538SAndroid Build Coastguard Worker };
438*6777b538SAndroid Build Coastguard Worker 
HistogramExists(base::StringPiece name)439*6777b538SAndroid Build Coastguard Worker bool HistogramExists(base::StringPiece name) {
440*6777b538SAndroid Build Coastguard Worker   return base::StatisticsRecorder::FindHistogram(name) != nullptr;
441*6777b538SAndroid Build Coastguard Worker }
442*6777b538SAndroid Build Coastguard Worker 
GetHistogramDeltaTotalCount(base::StringPiece name)443*6777b538SAndroid Build Coastguard Worker base::HistogramBase::Count GetHistogramDeltaTotalCount(base::StringPiece name) {
444*6777b538SAndroid Build Coastguard Worker   return base::StatisticsRecorder::FindHistogram(name)
445*6777b538SAndroid Build Coastguard Worker       ->SnapshotDelta()
446*6777b538SAndroid Build Coastguard Worker       ->TotalCount();
447*6777b538SAndroid Build Coastguard Worker }
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker }  // namespace
450*6777b538SAndroid Build Coastguard Worker 
451*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
452*6777b538SAndroid Build Coastguard Worker                          MetricsServiceTestWithFeatures,
453*6777b538SAndroid Build Coastguard Worker                          ::testing::Combine(::testing::Bool()));
454*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,RecordId)455*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, RecordId) {
456*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
457*6777b538SAndroid Build Coastguard Worker   GetMetricsStateManager(user_data_dir_path())->ForceClientIdCreation();
458*6777b538SAndroid Build Coastguard Worker 
459*6777b538SAndroid Build Coastguard Worker   // Set an initial value for the record-ids, to make them predictable.
460*6777b538SAndroid Build Coastguard Worker   GetLocalState()->SetInteger(prefs::kMetricsLogRecordId, 1000);
461*6777b538SAndroid Build Coastguard Worker 
462*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
463*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(user_data_dir_path()),
464*6777b538SAndroid Build Coastguard Worker                              &client, GetLocalState());
465*6777b538SAndroid Build Coastguard Worker 
466*6777b538SAndroid Build Coastguard Worker   auto log1 = service.CreateLogForTesting(MetricsLog::ONGOING_LOG);
467*6777b538SAndroid Build Coastguard Worker   auto log2 = service.CreateLogForTesting(MetricsLog::INITIAL_STABILITY_LOG);
468*6777b538SAndroid Build Coastguard Worker   auto log3 = service.CreateLogForTesting(MetricsLog::INDEPENDENT_LOG);
469*6777b538SAndroid Build Coastguard Worker 
470*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1001, log1->uma_proto()->record_id());
471*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1002, log2->uma_proto()->record_id());
472*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1003, log3->uma_proto()->record_id());
473*6777b538SAndroid Build Coastguard Worker }
474*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,InitialStabilityLogAfterCleanShutDown)475*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, InitialStabilityLogAfterCleanShutDown) {
476*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
477*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
478*6777b538SAndroid Build Coastguard Worker   // Write a beacon file indicating that Chrome exited cleanly. Note that the
479*6777b538SAndroid Build Coastguard Worker   // crash streak value is arbitrary.
480*6777b538SAndroid Build Coastguard Worker   const base::FilePath beacon_file_path =
481*6777b538SAndroid Build Coastguard Worker       user_data_dir_path().Append(kCleanExitBeaconFilename);
482*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(
483*6777b538SAndroid Build Coastguard Worker       beacon_file_path, CleanExitBeacon::CreateBeaconFileContentsForTesting(
484*6777b538SAndroid Build Coastguard Worker                             /*exited_cleanly=*/true, /*crash_streak=*/1)));
485*6777b538SAndroid Build Coastguard Worker 
486*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
487*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(user_data_dir_path()),
488*6777b538SAndroid Build Coastguard Worker                              &client, GetLocalState());
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker   TestMetricsProvider* test_provider = new TestMetricsProvider();
491*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
492*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
493*6777b538SAndroid Build Coastguard Worker 
494*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
495*6777b538SAndroid Build Coastguard Worker 
496*6777b538SAndroid Build Coastguard Worker   // No initial stability log should be generated.
497*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(service.has_unsent_logs());
498*6777b538SAndroid Build Coastguard Worker 
499*6777b538SAndroid Build Coastguard Worker   // Ensure that HasPreviousSessionData() is always called on providers,
500*6777b538SAndroid Build Coastguard Worker   // for consistency, even if other conditions already indicate their presence.
501*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->has_initial_stability_metrics_called());
502*6777b538SAndroid Build Coastguard Worker 
503*6777b538SAndroid Build Coastguard Worker   // The test provider should not have been called upon to provide initial
504*6777b538SAndroid Build Coastguard Worker   // stability nor regular stability metrics.
505*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_provider->provide_initial_stability_metrics_called());
506*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_provider->provide_stability_metrics_called());
507*6777b538SAndroid Build Coastguard Worker 
508*6777b538SAndroid Build Coastguard Worker   // As there wasn't an unclean shutdown, no browser crash samples should have
509*6777b538SAndroid Build Coastguard Worker   // been emitted.
510*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount("Stability.Counts2",
511*6777b538SAndroid Build Coastguard Worker                                      StabilityEventType::kBrowserCrash, 0);
512*6777b538SAndroid Build Coastguard Worker }
513*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,InitialStabilityLogAtProviderRequest)514*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, InitialStabilityLogAtProviderRequest) {
515*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
516*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
517*6777b538SAndroid Build Coastguard Worker 
518*6777b538SAndroid Build Coastguard Worker   // Save an existing system profile to prefs, to correspond to what would be
519*6777b538SAndroid Build Coastguard Worker   // saved from a previous session.
520*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
521*6777b538SAndroid Build Coastguard Worker   TestMetricsLog log("0a94430b-18e5-43c8-a657-580f7e855ce1", 1, &client);
522*6777b538SAndroid Build Coastguard Worker   // Manually override the log's session hash to something else to verify that
523*6777b538SAndroid Build Coastguard Worker   // stability logs created later on using this environment will contain that
524*6777b538SAndroid Build Coastguard Worker   // session hash.
525*6777b538SAndroid Build Coastguard Worker   uint64_t modified_session_hash =
526*6777b538SAndroid Build Coastguard Worker       log.uma_proto()->system_profile().session_hash() + 1;
527*6777b538SAndroid Build Coastguard Worker   log.uma_proto()->mutable_system_profile()->set_session_hash(
528*6777b538SAndroid Build Coastguard Worker       modified_session_hash);
529*6777b538SAndroid Build Coastguard Worker   DelegatingProvider delegating_provider;
530*6777b538SAndroid Build Coastguard Worker   TestMetricsService::RecordCurrentEnvironmentHelper(&log, GetLocalState(),
531*6777b538SAndroid Build Coastguard Worker                                                      &delegating_provider);
532*6777b538SAndroid Build Coastguard Worker 
533*6777b538SAndroid Build Coastguard Worker   // Record stability build time and version from previous session, so that
534*6777b538SAndroid Build Coastguard Worker   // stability metrics (including exited cleanly flag) won't be cleared.
535*6777b538SAndroid Build Coastguard Worker   EnvironmentRecorder(GetLocalState())
536*6777b538SAndroid Build Coastguard Worker       .SetBuildtimeAndVersion(MetricsLog::GetBuildTime(),
537*6777b538SAndroid Build Coastguard Worker                               client.GetVersionString());
538*6777b538SAndroid Build Coastguard Worker 
539*6777b538SAndroid Build Coastguard Worker   // Write a beacon file indicating that Chrome exited cleanly. Note that the
540*6777b538SAndroid Build Coastguard Worker   // crash streak value is arbitrary.
541*6777b538SAndroid Build Coastguard Worker   const base::FilePath beacon_file_path =
542*6777b538SAndroid Build Coastguard Worker       user_data_dir_path().Append(kCleanExitBeaconFilename);
543*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(
544*6777b538SAndroid Build Coastguard Worker       beacon_file_path, CleanExitBeacon::CreateBeaconFileContentsForTesting(
545*6777b538SAndroid Build Coastguard Worker                             /*exited_cleanly=*/true, /*crash_streak=*/1)));
546*6777b538SAndroid Build Coastguard Worker 
547*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(user_data_dir_path()),
548*6777b538SAndroid Build Coastguard Worker                              &client, GetLocalState());
549*6777b538SAndroid Build Coastguard Worker   // Add a metrics provider that requests a stability log.
550*6777b538SAndroid Build Coastguard Worker   TestMetricsProvider* test_provider = new TestMetricsProvider();
551*6777b538SAndroid Build Coastguard Worker   test_provider->set_has_initial_stability_metrics(true);
552*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
553*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
554*6777b538SAndroid Build Coastguard Worker 
555*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker   // The initial stability log should be generated and persisted in unsent logs.
558*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
559*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_unsent_logs());
560*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_log_store->has_staged_log());
561*6777b538SAndroid Build Coastguard Worker 
562*6777b538SAndroid Build Coastguard Worker   // Ensure that HasPreviousSessionData() is always called on providers,
563*6777b538SAndroid Build Coastguard Worker   // for consistency, even if other conditions already indicate their presence.
564*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->has_initial_stability_metrics_called());
565*6777b538SAndroid Build Coastguard Worker 
566*6777b538SAndroid Build Coastguard Worker   // The test provider should have been called upon to provide initial
567*6777b538SAndroid Build Coastguard Worker   // stability and regular stability metrics.
568*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->provide_initial_stability_metrics_called());
569*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->provide_stability_metrics_called());
570*6777b538SAndroid Build Coastguard Worker 
571*6777b538SAndroid Build Coastguard Worker   // Stage the log and retrieve it.
572*6777b538SAndroid Build Coastguard Worker   test_log_store->StageNextLog();
573*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_staged_log());
574*6777b538SAndroid Build Coastguard Worker 
575*6777b538SAndroid Build Coastguard Worker   ChromeUserMetricsExtension uma_log;
576*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &uma_log));
577*6777b538SAndroid Build Coastguard Worker 
578*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.has_client_id());
579*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.has_session_id());
580*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.has_system_profile());
581*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.system_profile().has_session_hash());
582*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(modified_session_hash, uma_log.system_profile().session_hash());
583*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, uma_log.user_action_event_size());
584*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, uma_log.omnibox_event_size());
585*6777b538SAndroid Build Coastguard Worker   CheckForNonStabilityHistograms(uma_log);
586*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
587*6777b538SAndroid Build Coastguard Worker       1, GetHistogramSampleCount(uma_log, "UMA.InitialStabilityRecordBeacon"));
588*6777b538SAndroid Build Coastguard Worker 
589*6777b538SAndroid Build Coastguard Worker   // As there wasn't an unclean shutdown, no browser crash samples should have
590*6777b538SAndroid Build Coastguard Worker   // been emitted.
591*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount("Stability.Counts2",
592*6777b538SAndroid Build Coastguard Worker                                      StabilityEventType::kBrowserCrash, 0);
593*6777b538SAndroid Build Coastguard Worker }
594*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,IndependentLogAtProviderRequest)595*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, IndependentLogAtProviderRequest) {
596*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
597*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
598*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
599*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
600*6777b538SAndroid Build Coastguard Worker 
601*6777b538SAndroid Build Coastguard Worker   // Create a a provider that will have one independent log to provide.
602*6777b538SAndroid Build Coastguard Worker   auto* test_provider = new TestIndependentMetricsProvider();
603*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
604*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
605*6777b538SAndroid Build Coastguard Worker 
606*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
607*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
608*6777b538SAndroid Build Coastguard Worker   service.Start();
609*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
610*6777b538SAndroid Build Coastguard Worker 
611*6777b538SAndroid Build Coastguard Worker   // Verify that the independent log provider has not yet been called, and emit
612*6777b538SAndroid Build Coastguard Worker   // a histogram. This histogram should not be put into the independent log.
613*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_provider->has_independent_metrics_called());
614*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_provider->provide_independent_metrics_called());
615*6777b538SAndroid Build Coastguard Worker   const std::string test_histogram = "Test.Histogram";
616*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramBoolean(test_histogram, true);
617*6777b538SAndroid Build Coastguard Worker 
618*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
619*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
620*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
621*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
622*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
623*6777b538SAndroid Build Coastguard Worker 
624*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by another |initialization_delay|, which is when
625*6777b538SAndroid Build Coastguard Worker   // metrics providers are called to provide independent logs.
626*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
627*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->has_independent_metrics_called());
628*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->provide_independent_metrics_called());
629*6777b538SAndroid Build Coastguard Worker 
630*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
631*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log.
632*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
633*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
634*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| twice, we only need to fast forward by
635*6777b538SAndroid Build Coastguard Worker   // N - 2 * |initialization_delay|.
636*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
637*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
638*6777b538SAndroid Build Coastguard Worker       2 * initialization_delay);
639*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::SENDING_LOGS, service.state());
640*6777b538SAndroid Build Coastguard Worker 
641*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
642*6777b538SAndroid Build Coastguard Worker 
643*6777b538SAndroid Build Coastguard Worker   // The currently staged log should be the independent log created by the
644*6777b538SAndroid Build Coastguard Worker   // independent log provider. The log should have a client id of 123. It should
645*6777b538SAndroid Build Coastguard Worker   // also not contain |test_histogram|.
646*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(test_log_store->has_staged_log());
647*6777b538SAndroid Build Coastguard Worker   ChromeUserMetricsExtension uma_log;
648*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &uma_log));
649*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(uma_log.client_id(), 123UL);
650*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetHistogramSampleCount(uma_log, test_histogram), 0);
651*6777b538SAndroid Build Coastguard Worker 
652*6777b538SAndroid Build Coastguard Worker   // Discard the staged log and stage the next one. It should be the first
653*6777b538SAndroid Build Coastguard Worker   // ongoing log.
654*6777b538SAndroid Build Coastguard Worker   test_log_store->DiscardStagedLog();
655*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(test_log_store->has_unsent_logs());
656*6777b538SAndroid Build Coastguard Worker   test_log_store->StageNextLog();
657*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(test_log_store->has_staged_log());
658*6777b538SAndroid Build Coastguard Worker 
659*6777b538SAndroid Build Coastguard Worker   // Verify that the first ongoing log contains |test_histogram| (it should not
660*6777b538SAndroid Build Coastguard Worker   // have been put into the independent log).
661*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &uma_log));
662*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetHistogramSampleCount(uma_log, test_histogram), 1);
663*6777b538SAndroid Build Coastguard Worker }
664*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,OnDidCreateMetricsLogAtShutdown)665*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, OnDidCreateMetricsLogAtShutdown) {
666*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
667*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
668*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
669*6777b538SAndroid Build Coastguard Worker 
670*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
671*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
672*6777b538SAndroid Build Coastguard Worker 
673*6777b538SAndroid Build Coastguard Worker   // Create a provider that will log to |kOnDidCreateMetricsLogHistogramName|
674*6777b538SAndroid Build Coastguard Worker   // in OnDidCreateMetricsLog().
675*6777b538SAndroid Build Coastguard Worker   auto* test_provider = new TestMetricsProviderForOnDidCreateMetricsLog();
676*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
677*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
678*6777b538SAndroid Build Coastguard Worker 
679*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
680*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
681*6777b538SAndroid Build Coastguard Worker   service.Start();
682*6777b538SAndroid Build Coastguard Worker 
683*6777b538SAndroid Build Coastguard Worker   // OnDidCreateMetricsLog() is called once when the first ongoing log is
684*6777b538SAndroid Build Coastguard Worker   // created.
685*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kOnDidCreateMetricsLogHistogramName, true,
686*6777b538SAndroid Build Coastguard Worker                                      1);
687*6777b538SAndroid Build Coastguard Worker   service.Stop();
688*6777b538SAndroid Build Coastguard Worker 
689*6777b538SAndroid Build Coastguard Worker   // OnDidCreateMetricsLog() will be called during shutdown to emit histograms.
690*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kOnDidCreateMetricsLogHistogramName, true,
691*6777b538SAndroid Build Coastguard Worker                                      2);
692*6777b538SAndroid Build Coastguard Worker 
693*6777b538SAndroid Build Coastguard Worker   // Clean up histograms.
694*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting(
695*6777b538SAndroid Build Coastguard Worker       kOnDidCreateMetricsLogHistogramName);
696*6777b538SAndroid Build Coastguard Worker }
697*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,ProvideHistograms)698*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, ProvideHistograms) {
699*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
700*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
701*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
702*6777b538SAndroid Build Coastguard Worker 
703*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
704*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
705*6777b538SAndroid Build Coastguard Worker 
706*6777b538SAndroid Build Coastguard Worker   // Create a provider that will log to |kProvideHistogramsHistogramName|
707*6777b538SAndroid Build Coastguard Worker   // in ProvideHistograms().
708*6777b538SAndroid Build Coastguard Worker   auto* test_provider = new TestMetricsProviderForProvideHistograms();
709*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
710*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
711*6777b538SAndroid Build Coastguard Worker 
712*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
713*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
714*6777b538SAndroid Build Coastguard Worker   service.Start();
715*6777b538SAndroid Build Coastguard Worker 
716*6777b538SAndroid Build Coastguard Worker   // ProvideHistograms() is called in OnDidCreateMetricsLog().
717*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kProvideHistogramsHistogramName, true, 1);
718*6777b538SAndroid Build Coastguard Worker 
719*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
720*6777b538SAndroid Build Coastguard Worker 
721*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kProvideHistogramsHistogramName, true, 2);
722*6777b538SAndroid Build Coastguard Worker 
723*6777b538SAndroid Build Coastguard Worker   service.Stop();
724*6777b538SAndroid Build Coastguard Worker 
725*6777b538SAndroid Build Coastguard Worker   // Clean up histograms.
726*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting(
727*6777b538SAndroid Build Coastguard Worker       kProvideHistogramsHistogramName);
728*6777b538SAndroid Build Coastguard Worker }
729*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,ProvideHistogramsEarlyReturn)730*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, ProvideHistogramsEarlyReturn) {
731*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
732*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
733*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
734*6777b538SAndroid Build Coastguard Worker 
735*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
736*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
737*6777b538SAndroid Build Coastguard Worker 
738*6777b538SAndroid Build Coastguard Worker   // Create a provider that will log to |kOnDidCreateMetricsLogHistogramName|
739*6777b538SAndroid Build Coastguard Worker   // in OnDidCreateMetricsLog().
740*6777b538SAndroid Build Coastguard Worker   auto* test_provider =
741*6777b538SAndroid Build Coastguard Worker       new TestMetricsProviderForProvideHistogramsEarlyReturn();
742*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
743*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
744*6777b538SAndroid Build Coastguard Worker 
745*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
746*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
747*6777b538SAndroid Build Coastguard Worker   service.Start();
748*6777b538SAndroid Build Coastguard Worker 
749*6777b538SAndroid Build Coastguard Worker   // Make sure no histogram is emitted when having an early return.
750*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kProvideHistogramsHistogramName, true, 0);
751*6777b538SAndroid Build Coastguard Worker 
752*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
753*6777b538SAndroid Build Coastguard Worker   // ProvideHistograms() should be called in ProvideCurrentSessionData() if
754*6777b538SAndroid Build Coastguard Worker   // histograms haven't been emitted.
755*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kProvideHistogramsHistogramName, true, 1);
756*6777b538SAndroid Build Coastguard Worker 
757*6777b538SAndroid Build Coastguard Worker   // Try another log to make sure emission status is reset between logs.
758*6777b538SAndroid Build Coastguard Worker   service.LogStoreForTest()->DiscardStagedLog();
759*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
760*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount(kProvideHistogramsHistogramName, true, 2);
761*6777b538SAndroid Build Coastguard Worker 
762*6777b538SAndroid Build Coastguard Worker   service.Stop();
763*6777b538SAndroid Build Coastguard Worker 
764*6777b538SAndroid Build Coastguard Worker   // Clean up histograms.
765*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting(
766*6777b538SAndroid Build Coastguard Worker       kProvideHistogramsHistogramName);
767*6777b538SAndroid Build Coastguard Worker }
768*6777b538SAndroid Build Coastguard Worker 
769*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
770*6777b538SAndroid Build Coastguard Worker     All,
771*6777b538SAndroid Build Coastguard Worker     MetricsServiceTestWithStartupVisibility,
772*6777b538SAndroid Build Coastguard Worker     ::testing::Combine(
773*6777b538SAndroid Build Coastguard Worker         ::testing::Values(
774*6777b538SAndroid Build Coastguard Worker             StartupVisibilityTestParams{
775*6777b538SAndroid Build Coastguard Worker                 .startup_visibility = StartupVisibility::kUnknown,
776*6777b538SAndroid Build Coastguard Worker                 .expected_beacon_value = true},
777*6777b538SAndroid Build Coastguard Worker             StartupVisibilityTestParams{
778*6777b538SAndroid Build Coastguard Worker                 .startup_visibility = StartupVisibility::kBackground,
779*6777b538SAndroid Build Coastguard Worker                 .expected_beacon_value = true},
780*6777b538SAndroid Build Coastguard Worker             StartupVisibilityTestParams{
781*6777b538SAndroid Build Coastguard Worker                 .startup_visibility = StartupVisibility::kForeground,
782*6777b538SAndroid Build Coastguard Worker                 .expected_beacon_value = false}),
783*6777b538SAndroid Build Coastguard Worker         ::testing::Bool()));
784*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithStartupVisibility,InitialStabilityLogAfterCrash)785*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithStartupVisibility, InitialStabilityLogAfterCrash) {
786*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
787*6777b538SAndroid Build Coastguard Worker   PrefService* local_state = GetLocalState();
788*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
789*6777b538SAndroid Build Coastguard Worker 
790*6777b538SAndroid Build Coastguard Worker   // Write a beacon file indicating that Chrome exited uncleanly. Note that the
791*6777b538SAndroid Build Coastguard Worker   // crash streak value is arbitrary.
792*6777b538SAndroid Build Coastguard Worker   const base::FilePath beacon_file_path =
793*6777b538SAndroid Build Coastguard Worker       user_data_dir_path().Append(kCleanExitBeaconFilename);
794*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(
795*6777b538SAndroid Build Coastguard Worker       beacon_file_path, CleanExitBeacon::CreateBeaconFileContentsForTesting(
796*6777b538SAndroid Build Coastguard Worker                             /*exited_cleanly=*/false, /*crash_streak=*/1)));
797*6777b538SAndroid Build Coastguard Worker 
798*6777b538SAndroid Build Coastguard Worker   // Set up prefs to simulate restarting after a crash.
799*6777b538SAndroid Build Coastguard Worker 
800*6777b538SAndroid Build Coastguard Worker   // Save an existing system profile to prefs, to correspond to what would be
801*6777b538SAndroid Build Coastguard Worker   // saved from a previous session.
802*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
803*6777b538SAndroid Build Coastguard Worker   const std::string kCrashedVersion = "4.0.321.0-64-devel";
804*6777b538SAndroid Build Coastguard Worker   client.set_version_string(kCrashedVersion);
805*6777b538SAndroid Build Coastguard Worker   TestMetricsLog log("0a94430b-18e5-43c8-a657-580f7e855ce1", 1, &client);
806*6777b538SAndroid Build Coastguard Worker   DelegatingProvider delegating_provider;
807*6777b538SAndroid Build Coastguard Worker   TestMetricsService::RecordCurrentEnvironmentHelper(&log, local_state,
808*6777b538SAndroid Build Coastguard Worker                                                      &delegating_provider);
809*6777b538SAndroid Build Coastguard Worker 
810*6777b538SAndroid Build Coastguard Worker   // Record stability build time and version from previous session, so that
811*6777b538SAndroid Build Coastguard Worker   // stability metrics (including exited cleanly flag) won't be cleared.
812*6777b538SAndroid Build Coastguard Worker   EnvironmentRecorder(local_state)
813*6777b538SAndroid Build Coastguard Worker       .SetBuildtimeAndVersion(MetricsLog::GetBuildTime(),
814*6777b538SAndroid Build Coastguard Worker                               client.GetVersionString());
815*6777b538SAndroid Build Coastguard Worker 
816*6777b538SAndroid Build Coastguard Worker   const std::string kCurrentVersion = "5.0.322.0-64-devel";
817*6777b538SAndroid Build Coastguard Worker   client.set_version_string(kCurrentVersion);
818*6777b538SAndroid Build Coastguard Worker 
819*6777b538SAndroid Build Coastguard Worker   StartupVisibilityTestParams params = std::get<0>(GetParam());
820*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(
821*6777b538SAndroid Build Coastguard Worker       GetMetricsStateManager(user_data_dir_path(), params.startup_visibility),
822*6777b538SAndroid Build Coastguard Worker       &client, local_state);
823*6777b538SAndroid Build Coastguard Worker   // Add a provider.
824*6777b538SAndroid Build Coastguard Worker   TestMetricsProvider* test_provider = new TestMetricsProvider();
825*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
826*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
827*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
828*6777b538SAndroid Build Coastguard Worker 
829*6777b538SAndroid Build Coastguard Worker   // Verify that Chrome is (or is not) watching for crashes by checking the
830*6777b538SAndroid Build Coastguard Worker   // beacon value.
831*6777b538SAndroid Build Coastguard Worker   std::string beacon_file_contents;
832*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::ReadFileToString(beacon_file_path, &beacon_file_contents));
833*6777b538SAndroid Build Coastguard Worker   std::string partial_expected_contents;
834*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
835*6777b538SAndroid Build Coastguard Worker   // Whether Chrome is watching for crashes after
836*6777b538SAndroid Build Coastguard Worker   // InitializeMetricsRecordingState() depends on the type of Android Chrome
837*6777b538SAndroid Build Coastguard Worker   // session. See the comments in MetricsService::InitializeMetricsState() for
838*6777b538SAndroid Build Coastguard Worker   // more details.
839*6777b538SAndroid Build Coastguard Worker   const std::string beacon_value =
840*6777b538SAndroid Build Coastguard Worker       params.expected_beacon_value ? "true" : "false";
841*6777b538SAndroid Build Coastguard Worker   partial_expected_contents = "exited_cleanly\":" + beacon_value;
842*6777b538SAndroid Build Coastguard Worker #else
843*6777b538SAndroid Build Coastguard Worker   partial_expected_contents = "exited_cleanly\":false";
844*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_ANDROID)
845*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::Contains(beacon_file_contents, partial_expected_contents));
846*6777b538SAndroid Build Coastguard Worker 
847*6777b538SAndroid Build Coastguard Worker   // The initial stability log should be generated and persisted in unsent logs.
848*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
849*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_unsent_logs());
850*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_log_store->has_staged_log());
851*6777b538SAndroid Build Coastguard Worker 
852*6777b538SAndroid Build Coastguard Worker   // Ensure that HasPreviousSessionData() is always called on providers,
853*6777b538SAndroid Build Coastguard Worker   // for consistency, even if other conditions already indicate their presence.
854*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->has_initial_stability_metrics_called());
855*6777b538SAndroid Build Coastguard Worker 
856*6777b538SAndroid Build Coastguard Worker   // The test provider should have been called upon to provide initial
857*6777b538SAndroid Build Coastguard Worker   // stability and regular stability metrics.
858*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->provide_initial_stability_metrics_called());
859*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->provide_stability_metrics_called());
860*6777b538SAndroid Build Coastguard Worker 
861*6777b538SAndroid Build Coastguard Worker   // The test provider should have been called when the initial stability log
862*6777b538SAndroid Build Coastguard Worker   // was closed.
863*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->record_initial_histogram_snapshots_called());
864*6777b538SAndroid Build Coastguard Worker 
865*6777b538SAndroid Build Coastguard Worker   // Stage the log and retrieve it.
866*6777b538SAndroid Build Coastguard Worker   test_log_store->StageNextLog();
867*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_staged_log());
868*6777b538SAndroid Build Coastguard Worker 
869*6777b538SAndroid Build Coastguard Worker   ChromeUserMetricsExtension uma_log;
870*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &uma_log));
871*6777b538SAndroid Build Coastguard Worker 
872*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.has_client_id());
873*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.has_session_id());
874*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(uma_log.has_system_profile());
875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, uma_log.user_action_event_size());
876*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, uma_log.omnibox_event_size());
877*6777b538SAndroid Build Coastguard Worker   CheckForNonStabilityHistograms(uma_log);
878*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
879*6777b538SAndroid Build Coastguard Worker       1, GetHistogramSampleCount(uma_log, "UMA.InitialStabilityRecordBeacon"));
880*6777b538SAndroid Build Coastguard Worker 
881*6777b538SAndroid Build Coastguard Worker   // Verify that the histograms emitted by the test provider made it into the
882*6777b538SAndroid Build Coastguard Worker   // log.
883*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetHistogramSampleCount(uma_log, "TestMetricsProvider.Initial"), 1);
884*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetHistogramSampleCount(uma_log, "TestMetricsProvider.Regular"), 1);
885*6777b538SAndroid Build Coastguard Worker 
886*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kCrashedVersion, uma_log.system_profile().app_version());
887*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kCurrentVersion,
888*6777b538SAndroid Build Coastguard Worker             uma_log.system_profile().log_written_by_app_version());
889*6777b538SAndroid Build Coastguard Worker 
890*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectBucketCount("Stability.Counts2",
891*6777b538SAndroid Build Coastguard Worker                                      StabilityEventType::kBrowserCrash, 1);
892*6777b538SAndroid Build Coastguard Worker }
893*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,InitialLogsHaveOnDidCreateMetricsLogHistograms)894*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures,
895*6777b538SAndroid Build Coastguard Worker        InitialLogsHaveOnDidCreateMetricsLogHistograms) {
896*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
897*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
898*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
899*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
900*6777b538SAndroid Build Coastguard Worker 
901*6777b538SAndroid Build Coastguard Worker   // Create a provider that will log to |kOnDidCreateMetricsLogHistogramName|
902*6777b538SAndroid Build Coastguard Worker   // in OnDidCreateMetricsLog()
903*6777b538SAndroid Build Coastguard Worker   auto* test_provider = new TestMetricsProviderForOnDidCreateMetricsLog();
904*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
905*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
906*6777b538SAndroid Build Coastguard Worker 
907*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
908*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
909*6777b538SAndroid Build Coastguard Worker   service.Start();
910*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
911*6777b538SAndroid Build Coastguard Worker 
912*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
913*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
914*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
915*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
916*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
917*6777b538SAndroid Build Coastguard Worker 
918*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
919*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log. Also verify that the test provider
920*6777b538SAndroid Build Coastguard Worker   // was called when closing the log.
921*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
922*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
923*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
924*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
925*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
926*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
927*6777b538SAndroid Build Coastguard Worker       initialization_delay);
928*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
929*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->record_histogram_snapshots_called());
930*6777b538SAndroid Build Coastguard Worker 
931*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
932*6777b538SAndroid Build Coastguard Worker 
933*6777b538SAndroid Build Coastguard Worker   // Stage the next log, which should be the first ongoing log.
934*6777b538SAndroid Build Coastguard Worker   // Check that it has one sample in |kOnDidCreateMetricsLogHistogramName|.
935*6777b538SAndroid Build Coastguard Worker   test_log_store->StageNextLog();
936*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, GetSampleCountOfOnDidCreateLogHistogram(test_log_store));
937*6777b538SAndroid Build Coastguard Worker 
938*6777b538SAndroid Build Coastguard Worker   // Discard the staged log and close and stage the next log, which is the
939*6777b538SAndroid Build Coastguard Worker   // second "ongoing log".
940*6777b538SAndroid Build Coastguard Worker   // Check that it has one sample in |kOnDidCreateMetricsLogHistogramName|.
941*6777b538SAndroid Build Coastguard Worker   // Also verify that the test provider was called when closing the new log.
942*6777b538SAndroid Build Coastguard Worker   test_provider->set_record_histogram_snapshots_called(false);
943*6777b538SAndroid Build Coastguard Worker   test_log_store->DiscardStagedLog();
944*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
945*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, GetSampleCountOfOnDidCreateLogHistogram(test_log_store));
946*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->record_histogram_snapshots_called());
947*6777b538SAndroid Build Coastguard Worker 
948*6777b538SAndroid Build Coastguard Worker   // Check one more log for good measure.
949*6777b538SAndroid Build Coastguard Worker   test_provider->set_record_histogram_snapshots_called(false);
950*6777b538SAndroid Build Coastguard Worker   test_log_store->DiscardStagedLog();
951*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
952*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, GetSampleCountOfOnDidCreateLogHistogram(test_log_store));
953*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->record_histogram_snapshots_called());
954*6777b538SAndroid Build Coastguard Worker 
955*6777b538SAndroid Build Coastguard Worker   service.Stop();
956*6777b538SAndroid Build Coastguard Worker 
957*6777b538SAndroid Build Coastguard Worker   // Clean up histograms.
958*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting(
959*6777b538SAndroid Build Coastguard Worker       kOnDidCreateMetricsLogHistogramName);
960*6777b538SAndroid Build Coastguard Worker }
961*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,MarkCurrentHistogramsAsReported)962*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, MarkCurrentHistogramsAsReported) {
963*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
964*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
965*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
966*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
967*6777b538SAndroid Build Coastguard Worker 
968*6777b538SAndroid Build Coastguard Worker   // Emit to histogram |Test.Before.Histogram|.
969*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(HistogramExists("Test.Before.Histogram"));
970*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramBoolean("Test.Before.Histogram", true);
971*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(HistogramExists("Test.Before.Histogram"));
972*6777b538SAndroid Build Coastguard Worker 
973*6777b538SAndroid Build Coastguard Worker   // Mark histogram data that has been collected until now (in particular, the
974*6777b538SAndroid Build Coastguard Worker   // |Test.Before.Histogram| sample) as reported.
975*6777b538SAndroid Build Coastguard Worker   service.MarkCurrentHistogramsAsReported();
976*6777b538SAndroid Build Coastguard Worker 
977*6777b538SAndroid Build Coastguard Worker   // Emit to histogram |Test.After.Histogram|.
978*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(HistogramExists("Test.After.Histogram"));
979*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramBoolean("Test.After.Histogram", true);
980*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(HistogramExists("Test.After.Histogram"));
981*6777b538SAndroid Build Coastguard Worker 
982*6777b538SAndroid Build Coastguard Worker   // Verify that the |Test.Before.Histogram| sample was marked as reported, and
983*6777b538SAndroid Build Coastguard Worker   // is not included in the next snapshot.
984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, GetHistogramDeltaTotalCount("Test.Before.Histogram"));
985*6777b538SAndroid Build Coastguard Worker   // Verify that the |Test.After.Histogram| sample was not marked as reported,
986*6777b538SAndroid Build Coastguard Worker   // and is included in the next snapshot.
987*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, GetHistogramDeltaTotalCount("Test.After.Histogram"));
988*6777b538SAndroid Build Coastguard Worker 
989*6777b538SAndroid Build Coastguard Worker   // Clean up histograms.
990*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting("Test.Before.Histogram");
991*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting("Test.After.Histogram");
992*6777b538SAndroid Build Coastguard Worker }
993*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,LogHasUserActions)994*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, LogHasUserActions) {
995*6777b538SAndroid Build Coastguard Worker   // This test verifies that user actions are properly captured in UMA logs.
996*6777b538SAndroid Build Coastguard Worker   // In particular, it checks that the first log has actions, a behavior that
997*6777b538SAndroid Build Coastguard Worker   // was buggy in the past, plus additional checks for subsequent logs with
998*6777b538SAndroid Build Coastguard Worker   // different numbers of actions.
999*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1000*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1001*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1002*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1003*6777b538SAndroid Build Coastguard Worker 
1004*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1005*6777b538SAndroid Build Coastguard Worker 
1006*6777b538SAndroid Build Coastguard Worker   // Start() will create an initial log.
1007*6777b538SAndroid Build Coastguard Worker   service.Start();
1008*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1009*6777b538SAndroid Build Coastguard Worker 
1010*6777b538SAndroid Build Coastguard Worker   base::RecordAction(base::UserMetricsAction("TestAction"));
1011*6777b538SAndroid Build Coastguard Worker   base::RecordAction(base::UserMetricsAction("TestAction"));
1012*6777b538SAndroid Build Coastguard Worker   base::RecordAction(base::UserMetricsAction("DifferentAction"));
1013*6777b538SAndroid Build Coastguard Worker 
1014*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
1015*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
1016*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
1017*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
1018*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
1019*6777b538SAndroid Build Coastguard Worker 
1020*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
1021*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log.
1022*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
1023*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
1024*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
1025*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
1026*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
1027*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
1028*6777b538SAndroid Build Coastguard Worker       initialization_delay);
1029*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
1030*6777b538SAndroid Build Coastguard Worker 
1031*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1032*6777b538SAndroid Build Coastguard Worker 
1033*6777b538SAndroid Build Coastguard Worker   // Stage the next log, which should be the initial metrics log.
1034*6777b538SAndroid Build Coastguard Worker   test_log_store->StageNextLog();
1035*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, GetNumberOfUserActions(test_log_store));
1036*6777b538SAndroid Build Coastguard Worker 
1037*6777b538SAndroid Build Coastguard Worker   // Log another action.
1038*6777b538SAndroid Build Coastguard Worker   base::RecordAction(base::UserMetricsAction("TestAction"));
1039*6777b538SAndroid Build Coastguard Worker   test_log_store->DiscardStagedLog();
1040*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
1041*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, GetNumberOfUserActions(test_log_store));
1042*6777b538SAndroid Build Coastguard Worker 
1043*6777b538SAndroid Build Coastguard Worker   // Check a log with no actions.
1044*6777b538SAndroid Build Coastguard Worker   test_log_store->DiscardStagedLog();
1045*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
1046*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, GetNumberOfUserActions(test_log_store));
1047*6777b538SAndroid Build Coastguard Worker 
1048*6777b538SAndroid Build Coastguard Worker   // And another one with a couple.
1049*6777b538SAndroid Build Coastguard Worker   base::RecordAction(base::UserMetricsAction("TestAction"));
1050*6777b538SAndroid Build Coastguard Worker   base::RecordAction(base::UserMetricsAction("TestAction"));
1051*6777b538SAndroid Build Coastguard Worker   test_log_store->DiscardStagedLog();
1052*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
1053*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, GetNumberOfUserActions(test_log_store));
1054*6777b538SAndroid Build Coastguard Worker }
1055*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,FirstLogCreatedBeforeUnsentLogsSent)1056*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, FirstLogCreatedBeforeUnsentLogsSent) {
1057*6777b538SAndroid Build Coastguard Worker   // This test checks that we will create and serialize the first ongoing log
1058*6777b538SAndroid Build Coastguard Worker   // before starting to send unsent logs from the past session. The latter is
1059*6777b538SAndroid Build Coastguard Worker   // simulated by injecting some fake ongoing logs into the MetricsLogStore.
1060*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1061*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1062*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1063*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1064*6777b538SAndroid Build Coastguard Worker 
1065*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1066*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
1067*6777b538SAndroid Build Coastguard Worker   service.Start();
1068*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1069*6777b538SAndroid Build Coastguard Worker 
1070*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1071*6777b538SAndroid Build Coastguard Worker 
1072*6777b538SAndroid Build Coastguard Worker   // Set up the log store with an existing fake log entry. The string content
1073*6777b538SAndroid Build Coastguard Worker   // is never deserialized to proto, so we're just passing some dummy content.
1074*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1075*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->ongoing_log_count());
1076*6777b538SAndroid Build Coastguard Worker   test_log_store->StoreLog("blah_blah", MetricsLog::ONGOING_LOG, LogMetadata(),
1077*6777b538SAndroid Build Coastguard Worker                            MetricsLogsEventManager::CreateReason::kUnknown);
1078*6777b538SAndroid Build Coastguard Worker   // Note: |initial_log_count()| refers to initial stability logs, so the above
1079*6777b538SAndroid Build Coastguard Worker   // log is counted an ongoing log (per its type).
1080*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1081*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, test_log_store->ongoing_log_count());
1082*6777b538SAndroid Build Coastguard Worker 
1083*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
1084*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
1085*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
1086*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
1087*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
1088*6777b538SAndroid Build Coastguard Worker 
1089*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
1090*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log.
1091*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
1092*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
1093*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
1094*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
1095*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
1096*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
1097*6777b538SAndroid Build Coastguard Worker       initialization_delay);
1098*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
1099*6777b538SAndroid Build Coastguard Worker   // When the init task is complete, the first ongoing log should be created
1100*6777b538SAndroid Build Coastguard Worker   // and added to the ongoing logs.
1101*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, test_log_store->initial_log_count());
1102*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, test_log_store->ongoing_log_count());
1103*6777b538SAndroid Build Coastguard Worker }
1104*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,MetricsProviderOnRecordingDisabledCalledOnInitialStop)1105*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures,
1106*6777b538SAndroid Build Coastguard Worker        MetricsProviderOnRecordingDisabledCalledOnInitialStop) {
1107*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1108*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1109*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1110*6777b538SAndroid Build Coastguard Worker 
1111*6777b538SAndroid Build Coastguard Worker   TestMetricsProvider* test_provider = new TestMetricsProvider();
1112*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
1113*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
1114*6777b538SAndroid Build Coastguard Worker 
1115*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1116*6777b538SAndroid Build Coastguard Worker   service.Stop();
1117*6777b538SAndroid Build Coastguard Worker 
1118*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->on_recording_disabled_called());
1119*6777b538SAndroid Build Coastguard Worker }
1120*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,MetricsProvidersInitialized)1121*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, MetricsProvidersInitialized) {
1122*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1123*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1124*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1125*6777b538SAndroid Build Coastguard Worker 
1126*6777b538SAndroid Build Coastguard Worker   TestMetricsProvider* test_provider = new TestMetricsProvider();
1127*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
1128*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
1129*6777b538SAndroid Build Coastguard Worker 
1130*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1131*6777b538SAndroid Build Coastguard Worker 
1132*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->init_called());
1133*6777b538SAndroid Build Coastguard Worker }
1134*6777b538SAndroid Build Coastguard Worker 
1135*6777b538SAndroid Build Coastguard Worker // Verify that FieldTrials activated by a MetricsProvider are reported by the
1136*6777b538SAndroid Build Coastguard Worker // FieldTrialsProvider.
TEST_P(MetricsServiceTestWithFeatures,ActiveFieldTrialsReported)1137*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, ActiveFieldTrialsReported) {
1138*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1139*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1140*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1141*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1142*6777b538SAndroid Build Coastguard Worker 
1143*6777b538SAndroid Build Coastguard Worker   // Set up FieldTrials.
1144*6777b538SAndroid Build Coastguard Worker   const std::string trial_name1 = "CoffeeExperiment";
1145*6777b538SAndroid Build Coastguard Worker   const std::string group_name1 = "Free";
1146*6777b538SAndroid Build Coastguard Worker   base::FieldTrial* trial1 =
1147*6777b538SAndroid Build Coastguard Worker       base::FieldTrialList::CreateFieldTrial(trial_name1, group_name1);
1148*6777b538SAndroid Build Coastguard Worker 
1149*6777b538SAndroid Build Coastguard Worker   const std::string trial_name2 = "DonutExperiment";
1150*6777b538SAndroid Build Coastguard Worker   const std::string group_name2 = "MapleBacon";
1151*6777b538SAndroid Build Coastguard Worker   base::FieldTrial* trial2 =
1152*6777b538SAndroid Build Coastguard Worker       base::FieldTrialList::CreateFieldTrial(trial_name2, group_name2);
1153*6777b538SAndroid Build Coastguard Worker 
1154*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
1155*6777b538SAndroid Build Coastguard Worker       std::make_unique<ExperimentTestMetricsProvider>(trial1, trial2));
1156*6777b538SAndroid Build Coastguard Worker 
1157*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1158*6777b538SAndroid Build Coastguard Worker   service.Start();
1159*6777b538SAndroid Build Coastguard Worker   service.StageCurrentLogForTest();
1160*6777b538SAndroid Build Coastguard Worker 
1161*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1162*6777b538SAndroid Build Coastguard Worker   ChromeUserMetricsExtension uma_log;
1163*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DecodeLogDataToProto(test_log_store->staged_log(), &uma_log));
1164*6777b538SAndroid Build Coastguard Worker 
1165*6777b538SAndroid Build Coastguard Worker   // Verify that the reported FieldTrial IDs are for the trial set up by this
1166*6777b538SAndroid Build Coastguard Worker   // test.
1167*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1168*6777b538SAndroid Build Coastguard Worker       IsFieldTrialPresent(uma_log.system_profile(), trial_name1, group_name1));
1169*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1170*6777b538SAndroid Build Coastguard Worker       IsFieldTrialPresent(uma_log.system_profile(), trial_name2, group_name2));
1171*6777b538SAndroid Build Coastguard Worker }
1172*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,SystemProfileDataProvidedOnEnableRecording)1173*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures,
1174*6777b538SAndroid Build Coastguard Worker        SystemProfileDataProvidedOnEnableRecording) {
1175*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1176*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1177*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1178*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1179*6777b538SAndroid Build Coastguard Worker 
1180*6777b538SAndroid Build Coastguard Worker   TestMetricsProvider* test_provider = new TestMetricsProvider();
1181*6777b538SAndroid Build Coastguard Worker   service.RegisterMetricsProvider(
1182*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<MetricsProvider>(test_provider));
1183*6777b538SAndroid Build Coastguard Worker 
1184*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1185*6777b538SAndroid Build Coastguard Worker 
1186*6777b538SAndroid Build Coastguard Worker   // ProvideSystemProfileMetrics() shouldn't be called initially.
1187*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_provider->provide_system_profile_metrics_called());
1188*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(service.persistent_system_profile_provided());
1189*6777b538SAndroid Build Coastguard Worker 
1190*6777b538SAndroid Build Coastguard Worker   service.Start();
1191*6777b538SAndroid Build Coastguard Worker 
1192*6777b538SAndroid Build Coastguard Worker   // Start should call ProvideSystemProfileMetrics().
1193*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_provider->provide_system_profile_metrics_called());
1194*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(service.persistent_system_profile_provided());
1195*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(service.persistent_system_profile_complete());
1196*6777b538SAndroid Build Coastguard Worker }
1197*6777b538SAndroid Build Coastguard Worker 
1198*6777b538SAndroid Build Coastguard Worker // Verify that the two separate MetricsSchedulers (MetricsRotationScheduler and
1199*6777b538SAndroid Build Coastguard Worker // MetricsUploadScheduler) function together properly.
TEST_P(MetricsServiceTestWithFeatures,SplitRotation)1200*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, SplitRotation) {
1201*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1202*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1203*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1204*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1205*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1206*6777b538SAndroid Build Coastguard Worker   service.Start();
1207*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1208*6777b538SAndroid Build Coastguard Worker 
1209*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
1210*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
1211*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
1212*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
1213*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
1214*6777b538SAndroid Build Coastguard Worker 
1215*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
1216*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log. The independent-metrics upload job
1217*6777b538SAndroid Build Coastguard Worker   // will be started and always be a task. This should also mark the rotation
1218*6777b538SAndroid Build Coastguard Worker   // scheduler as idle, so that the next time we attempt to create a log, we
1219*6777b538SAndroid Build Coastguard Worker   // return early (and don't create a log).
1220*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
1221*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
1222*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
1223*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
1224*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* log_store = service.LogStoreForTest();
1225*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(log_store->has_unsent_logs());
1226*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
1227*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
1228*6777b538SAndroid Build Coastguard Worker       initialization_delay);
1229*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
1230*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(log_store->has_unsent_logs());
1231*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, log_store->ongoing_log_count());
1232*6777b538SAndroid Build Coastguard Worker 
1233*6777b538SAndroid Build Coastguard Worker   // There should be three (delayed) tasks: one for querying independent logs
1234*6777b538SAndroid Build Coastguard Worker   // from metrics providers, one for uploading the unsent log, and one for
1235*6777b538SAndroid Build Coastguard Worker   // creating the next log.
1236*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, task_environment_.GetPendingMainThreadTaskCount());
1237*6777b538SAndroid Build Coastguard Worker 
1238*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the upload loop starts uploading logs.
1239*6777b538SAndroid Build Coastguard Worker   base::TimeDelta unsent_log_interval =
1240*6777b538SAndroid Build Coastguard Worker       MetricsUploadScheduler::GetUnsentLogsInterval();
1241*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(unsent_log_interval);
1242*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(client.uploader()->is_uploading());
1243*6777b538SAndroid Build Coastguard Worker   // There should be two (delayed) tasks: one for querying independent logs from
1244*6777b538SAndroid Build Coastguard Worker   // metrics providers, and one for creating the next log. I.e., the task to
1245*6777b538SAndroid Build Coastguard Worker   // upload a log should be running, and should not be in the task queue
1246*6777b538SAndroid Build Coastguard Worker   // anymore. The uploading of this log will only be completed later on in order
1247*6777b538SAndroid Build Coastguard Worker   // to simulate an edge case here.
1248*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, task_environment_.GetPendingMainThreadTaskCount());
1249*6777b538SAndroid Build Coastguard Worker 
1250*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the task to create another log is run. This
1251*6777b538SAndroid Build Coastguard Worker   // time, however, it should return early due to being idle (i.e., not create a
1252*6777b538SAndroid Build Coastguard Worker   // log), and it should not post another task to create another log. I.e.,
1253*6777b538SAndroid Build Coastguard Worker   // there should only be one (delayed) task: one for querying independent logs
1254*6777b538SAndroid Build Coastguard Worker   // from metrics providers.
1255*6777b538SAndroid Build Coastguard Worker   // Note: The log is only created after |rotation_scheduler_interval| seconds,
1256*6777b538SAndroid Build Coastguard Worker   // and since we already fast forwarded by |unsent_log_interval| once, we only
1257*6777b538SAndroid Build Coastguard Worker   // need to fast forward by
1258*6777b538SAndroid Build Coastguard Worker   // |rotation_scheduler_interval| - |unsent_log_interval|.
1259*6777b538SAndroid Build Coastguard Worker   base::TimeDelta rotation_scheduler_interval = client.GetUploadInterval();
1260*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(rotation_scheduler_interval -
1261*6777b538SAndroid Build Coastguard Worker                                   unsent_log_interval);
1262*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, log_store->ongoing_log_count());
1263*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, task_environment_.GetPendingMainThreadTaskCount());
1264*6777b538SAndroid Build Coastguard Worker 
1265*6777b538SAndroid Build Coastguard Worker   // Simulate completing the upload. Since there is no other log to be uploaded,
1266*6777b538SAndroid Build Coastguard Worker   // no task should be re-posted. I.e., there should only be one (delayed)
1267*6777b538SAndroid Build Coastguard Worker   // task: one for querying independent logs from metrics providers.
1268*6777b538SAndroid Build Coastguard Worker   client.uploader()->CompleteUpload(200);
1269*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(client.uploader()->is_uploading());
1270*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(log_store->has_unsent_logs());
1271*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, task_environment_.GetPendingMainThreadTaskCount());
1272*6777b538SAndroid Build Coastguard Worker 
1273*6777b538SAndroid Build Coastguard Worker   // Simulate interacting with the browser, which should 1) set the rotation
1274*6777b538SAndroid Build Coastguard Worker   // scheduler to not idle, 2) queue a task to upload the next log (if there is
1275*6777b538SAndroid Build Coastguard Worker   // one), and 3) queue a task to create the next log. I.e., there should be
1276*6777b538SAndroid Build Coastguard Worker   // three (delayed) tasks: one for querying independent logs from metrics
1277*6777b538SAndroid Build Coastguard Worker   // providers, one for uploading an unsent log, and one for creating the next
1278*6777b538SAndroid Build Coastguard Worker   // log.
1279*6777b538SAndroid Build Coastguard Worker   service.OnApplicationNotIdle();
1280*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, task_environment_.GetPendingMainThreadTaskCount());
1281*6777b538SAndroid Build Coastguard Worker 
1282*6777b538SAndroid Build Coastguard Worker   // We now simulate a more common scenario.
1283*6777b538SAndroid Build Coastguard Worker 
1284*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the task to upload a log runs. Since there
1285*6777b538SAndroid Build Coastguard Worker   // should be no logs, it should return early, and not re-post a task. I.e.,
1286*6777b538SAndroid Build Coastguard Worker   // there should be two tasks: one for querying independent logs from metrics
1287*6777b538SAndroid Build Coastguard Worker   // providers, and one for creating the next log.
1288*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(unsent_log_interval);
1289*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(client.uploader()->is_uploading());
1290*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(log_store->has_unsent_logs());
1291*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, task_environment_.GetPendingMainThreadTaskCount());
1292*6777b538SAndroid Build Coastguard Worker 
1293*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the next log is created. It should re-post
1294*6777b538SAndroid Build Coastguard Worker   // a task to create a new log, and should also re-start the upload scheduler.
1295*6777b538SAndroid Build Coastguard Worker   // I.e., there should be three (delayed) tasks: one for querying independent
1296*6777b538SAndroid Build Coastguard Worker   // logs from metrics providers, one for uploading an unsent log, and one for
1297*6777b538SAndroid Build Coastguard Worker   // creating the next log.
1298*6777b538SAndroid Build Coastguard Worker   // Note: The log is only created after |rotation_scheduler_interval| seconds,
1299*6777b538SAndroid Build Coastguard Worker   // and since we already fast forwarded by |unsent_log_interval| once, we only
1300*6777b538SAndroid Build Coastguard Worker   // need to fast forward by
1301*6777b538SAndroid Build Coastguard Worker   // |rotation_scheduler_interval| - |unsent_log_interval|.
1302*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(rotation_scheduler_interval -
1303*6777b538SAndroid Build Coastguard Worker                                   unsent_log_interval);
1304*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(log_store->has_unsent_logs());
1305*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, task_environment_.GetPendingMainThreadTaskCount());
1306*6777b538SAndroid Build Coastguard Worker 
1307*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the task to upload a log runs.
1308*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(unsent_log_interval);
1309*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(client.uploader()->is_uploading());
1310*6777b538SAndroid Build Coastguard Worker   // There should be two (delayed) tasks: one for querying independent logs from
1311*6777b538SAndroid Build Coastguard Worker   // metrics providers, and one for creating the next log. I.e., the task to
1312*6777b538SAndroid Build Coastguard Worker   // upload a log should be running, and should not be in the task queue
1313*6777b538SAndroid Build Coastguard Worker   // anymore.
1314*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, task_environment_.GetPendingMainThreadTaskCount());
1315*6777b538SAndroid Build Coastguard Worker 
1316*6777b538SAndroid Build Coastguard Worker   // Simulate completing the upload. However, before doing so, add a dummy log
1317*6777b538SAndroid Build Coastguard Worker   // in order to test that when the upload task completes, if it detects another
1318*6777b538SAndroid Build Coastguard Worker   // log, it will re-post a task to upload the next log. I.e., after uploading
1319*6777b538SAndroid Build Coastguard Worker   // the log, there should be three (delayed) tasks: one for querying
1320*6777b538SAndroid Build Coastguard Worker   // independent logs from metrics providers, one for uploading an unsent log,
1321*6777b538SAndroid Build Coastguard Worker   // and one for creating the next log.
1322*6777b538SAndroid Build Coastguard Worker   log_store->StoreLog("dummy log", MetricsLog::LogType::ONGOING_LOG,
1323*6777b538SAndroid Build Coastguard Worker                       LogMetadata(),
1324*6777b538SAndroid Build Coastguard Worker                       MetricsLogsEventManager::CreateReason::kUnknown);
1325*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, log_store->ongoing_log_count());
1326*6777b538SAndroid Build Coastguard Worker   client.uploader()->CompleteUpload(200);
1327*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(client.uploader()->is_uploading());
1328*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, log_store->ongoing_log_count());
1329*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, task_environment_.GetPendingMainThreadTaskCount());
1330*6777b538SAndroid Build Coastguard Worker 
1331*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the task to upload a log runs.
1332*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(unsent_log_interval);
1333*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(client.uploader()->is_uploading());
1334*6777b538SAndroid Build Coastguard Worker   // There should be two (delayed) tasks: one for querying independent logs from
1335*6777b538SAndroid Build Coastguard Worker   // metrics providers, and one for creating the next log. I.e., the task to
1336*6777b538SAndroid Build Coastguard Worker   // upload a log should be running, and should not be in the task queue
1337*6777b538SAndroid Build Coastguard Worker   // anymore.
1338*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, task_environment_.GetPendingMainThreadTaskCount());
1339*6777b538SAndroid Build Coastguard Worker 
1340*6777b538SAndroid Build Coastguard Worker   // Simulate completing the upload. Since there is no other log to be uploaded,
1341*6777b538SAndroid Build Coastguard Worker   // no task should be posted. I.e., there should only be two (delayed) tasks:
1342*6777b538SAndroid Build Coastguard Worker   // one for querying independent logs from metrics providers, and one.
1343*6777b538SAndroid Build Coastguard Worker   client.uploader()->CompleteUpload(200);
1344*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(client.uploader()->is_uploading());
1345*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(log_store->has_unsent_logs());
1346*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, task_environment_.GetPendingMainThreadTaskCount());
1347*6777b538SAndroid Build Coastguard Worker 
1348*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the task to create another log is run. It
1349*6777b538SAndroid Build Coastguard Worker   // should return early due to being idle (i.e., not create a log), and it
1350*6777b538SAndroid Build Coastguard Worker   // should not post another task to create another log. I.e., there should only
1351*6777b538SAndroid Build Coastguard Worker   // be one (delayed) task: one for querying independent logs from metrics
1352*6777b538SAndroid Build Coastguard Worker   // providers.
1353*6777b538SAndroid Build Coastguard Worker   // Note: The log is only created after |rotation_scheduler_interval| seconds,
1354*6777b538SAndroid Build Coastguard Worker   // and since we already fast forwarded by |unsent_log_interval| twice, we only
1355*6777b538SAndroid Build Coastguard Worker   // need to fast forward by
1356*6777b538SAndroid Build Coastguard Worker   // |rotation_scheduler_interval| - 2 * |unsent_log_interval|.
1357*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(rotation_scheduler_interval -
1358*6777b538SAndroid Build Coastguard Worker                                   2 * unsent_log_interval);
1359*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(log_store->has_unsent_logs());
1360*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, task_environment_.GetPendingMainThreadTaskCount());
1361*6777b538SAndroid Build Coastguard Worker }
1362*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,LastLiveTimestamp)1363*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, LastLiveTimestamp) {
1364*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1365*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1366*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1367*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1368*6777b538SAndroid Build Coastguard Worker 
1369*6777b538SAndroid Build Coastguard Worker   base::Time initial_last_live_time =
1370*6777b538SAndroid Build Coastguard Worker       GetLocalState()->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp);
1371*6777b538SAndroid Build Coastguard Worker 
1372*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1373*6777b538SAndroid Build Coastguard Worker   service.Start();
1374*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1375*6777b538SAndroid Build Coastguard Worker 
1376*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
1377*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
1378*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
1379*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
1380*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
1381*6777b538SAndroid Build Coastguard Worker 
1382*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
1383*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log. Also verify that the test provider
1384*6777b538SAndroid Build Coastguard Worker   // was called when closing the log.
1385*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
1386*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
1387*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
1388*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
1389*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
1390*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
1391*6777b538SAndroid Build Coastguard Worker       initialization_delay);
1392*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
1393*6777b538SAndroid Build Coastguard Worker   size_t num_pending_tasks = task_environment_.GetPendingMainThreadTaskCount();
1394*6777b538SAndroid Build Coastguard Worker 
1395*6777b538SAndroid Build Coastguard Worker   service.StartUpdatingLastLiveTimestamp();
1396*6777b538SAndroid Build Coastguard Worker 
1397*6777b538SAndroid Build Coastguard Worker   // Starting the update sequence should not write anything, but should
1398*6777b538SAndroid Build Coastguard Worker   // set up for a later write.
1399*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
1400*6777b538SAndroid Build Coastguard Worker       initial_last_live_time,
1401*6777b538SAndroid Build Coastguard Worker       GetLocalState()->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp));
1402*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(num_pending_tasks + 1,
1403*6777b538SAndroid Build Coastguard Worker             task_environment_.GetPendingMainThreadTaskCount());
1404*6777b538SAndroid Build Coastguard Worker 
1405*6777b538SAndroid Build Coastguard Worker   // Fast forward the time so that the task to update the "last alive timestamp"
1406*6777b538SAndroid Build Coastguard Worker   // runs.
1407*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(service.GetUpdateLastAliveTimestampDelay());
1408*6777b538SAndroid Build Coastguard Worker 
1409*6777b538SAndroid Build Coastguard Worker   // Verify that the time has updated in local state.
1410*6777b538SAndroid Build Coastguard Worker   base::Time updated_last_live_time =
1411*6777b538SAndroid Build Coastguard Worker       GetLocalState()->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp);
1412*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(initial_last_live_time, updated_last_live_time);
1413*6777b538SAndroid Build Coastguard Worker 
1414*6777b538SAndroid Build Coastguard Worker   // Double check that an update was scheduled again.
1415*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(service.GetUpdateLastAliveTimestampDelay());
1416*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(
1417*6777b538SAndroid Build Coastguard Worker       updated_last_live_time,
1418*6777b538SAndroid Build Coastguard Worker       GetLocalState()->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp));
1419*6777b538SAndroid Build Coastguard Worker }
1420*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,EnablementObserverNotification)1421*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, EnablementObserverNotification) {
1422*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1423*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1424*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1425*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1426*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1427*6777b538SAndroid Build Coastguard Worker 
1428*6777b538SAndroid Build Coastguard Worker   std::optional<bool> enabled;
1429*6777b538SAndroid Build Coastguard Worker   auto observer = [&enabled](bool notification) { enabled = notification; };
1430*6777b538SAndroid Build Coastguard Worker 
1431*6777b538SAndroid Build Coastguard Worker   auto subscription =
1432*6777b538SAndroid Build Coastguard Worker       service.AddEnablementObserver(base::BindLambdaForTesting(observer));
1433*6777b538SAndroid Build Coastguard Worker 
1434*6777b538SAndroid Build Coastguard Worker   service.Start();
1435*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(enabled.has_value());
1436*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(enabled.value());
1437*6777b538SAndroid Build Coastguard Worker 
1438*6777b538SAndroid Build Coastguard Worker   enabled.reset();
1439*6777b538SAndroid Build Coastguard Worker 
1440*6777b538SAndroid Build Coastguard Worker   service.Stop();
1441*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(enabled.has_value());
1442*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(enabled.value());
1443*6777b538SAndroid Build Coastguard Worker }
1444*6777b538SAndroid Build Coastguard Worker 
1445*6777b538SAndroid Build Coastguard Worker // Verifies that when a cloned install is detected, logs are purged.
TEST_P(MetricsServiceTestWithFeatures,PurgeLogsOnClonedInstallDetected)1446*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, PurgeLogsOnClonedInstallDetected) {
1447*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1448*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1449*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1450*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1451*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1452*6777b538SAndroid Build Coastguard Worker 
1453*6777b538SAndroid Build Coastguard Worker   // Store various logs.
1454*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1455*6777b538SAndroid Build Coastguard Worker   test_log_store->StoreLog("dummy log data", MetricsLog::ONGOING_LOG,
1456*6777b538SAndroid Build Coastguard Worker                            LogMetadata(),
1457*6777b538SAndroid Build Coastguard Worker                            MetricsLogsEventManager::CreateReason::kUnknown);
1458*6777b538SAndroid Build Coastguard Worker   test_log_store->StageNextLog();
1459*6777b538SAndroid Build Coastguard Worker   test_log_store->StoreLog("more dummy log data", MetricsLog::ONGOING_LOG,
1460*6777b538SAndroid Build Coastguard Worker                            LogMetadata(),
1461*6777b538SAndroid Build Coastguard Worker                            MetricsLogsEventManager::CreateReason::kUnknown);
1462*6777b538SAndroid Build Coastguard Worker   test_log_store->StoreLog("dummy stability log",
1463*6777b538SAndroid Build Coastguard Worker                            MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
1464*6777b538SAndroid Build Coastguard Worker                            MetricsLogsEventManager::CreateReason::kUnknown);
1465*6777b538SAndroid Build Coastguard Worker   test_log_store->SetAlternateOngoingLogStore(InitializeTestLogStoreAndGet());
1466*6777b538SAndroid Build Coastguard Worker   test_log_store->StoreLog("dummy log for alternate ongoing log store",
1467*6777b538SAndroid Build Coastguard Worker                            MetricsLog::ONGOING_LOG, LogMetadata(),
1468*6777b538SAndroid Build Coastguard Worker                            MetricsLogsEventManager::CreateReason::kUnknown);
1469*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_staged_log());
1470*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_unsent_logs());
1471*6777b538SAndroid Build Coastguard Worker 
1472*6777b538SAndroid Build Coastguard Worker   ClonedInstallDetector* cloned_install_detector =
1473*6777b538SAndroid Build Coastguard Worker       GetMetricsStateManager()->cloned_install_detector_for_testing();
1474*6777b538SAndroid Build Coastguard Worker 
1475*6777b538SAndroid Build Coastguard Worker   static constexpr char kTestRawId[] = "test";
1476*6777b538SAndroid Build Coastguard Worker   // Hashed machine id for |kTestRawId|.
1477*6777b538SAndroid Build Coastguard Worker   static constexpr int kTestHashedId = 2216819;
1478*6777b538SAndroid Build Coastguard Worker 
1479*6777b538SAndroid Build Coastguard Worker   // Save a machine id that will not cause a clone to be detected.
1480*6777b538SAndroid Build Coastguard Worker   GetLocalState()->SetInteger(prefs::kMetricsMachineId, kTestHashedId);
1481*6777b538SAndroid Build Coastguard Worker   cloned_install_detector->SaveMachineId(GetLocalState(), kTestRawId);
1482*6777b538SAndroid Build Coastguard Worker   // Verify that the logs are still present.
1483*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_staged_log());
1484*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(test_log_store->has_unsent_logs());
1485*6777b538SAndroid Build Coastguard Worker 
1486*6777b538SAndroid Build Coastguard Worker   // Save a machine id that will cause a clone to be detected.
1487*6777b538SAndroid Build Coastguard Worker   GetLocalState()->SetInteger(prefs::kMetricsMachineId, kTestHashedId + 1);
1488*6777b538SAndroid Build Coastguard Worker   cloned_install_detector->SaveMachineId(GetLocalState(), kTestRawId);
1489*6777b538SAndroid Build Coastguard Worker   // Verify that the logs were purged.
1490*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_log_store->has_staged_log());
1491*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(test_log_store->has_unsent_logs());
1492*6777b538SAndroid Build Coastguard Worker }
1493*6777b538SAndroid Build Coastguard Worker 
1494*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_LACROS)
1495*6777b538SAndroid Build Coastguard Worker // ResetClientId is only enabled on certain targets.
TEST_P(MetricsServiceTestWithFeatures,SetClientIdToExternalId)1496*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures, SetClientIdToExternalId) {
1497*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1498*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1499*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1500*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1501*6777b538SAndroid Build Coastguard Worker 
1502*6777b538SAndroid Build Coastguard Worker   const std::string client_id = "d92ad666-a420-4c73-8718-94311ae2ff5f";
1503*6777b538SAndroid Build Coastguard Worker 
1504*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(service.GetClientId(), client_id);
1505*6777b538SAndroid Build Coastguard Worker 
1506*6777b538SAndroid Build Coastguard Worker   service.SetExternalClientId(client_id);
1507*6777b538SAndroid Build Coastguard Worker   // Reset will cause the client id to be regenerated. If an external client id
1508*6777b538SAndroid Build Coastguard Worker   // is provided, it should defer to using that id instead of creating its own.
1509*6777b538SAndroid Build Coastguard Worker   service.ResetClientId();
1510*6777b538SAndroid Build Coastguard Worker 
1511*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(service.GetClientId(), client_id);
1512*6777b538SAndroid Build Coastguard Worker }
1513*6777b538SAndroid Build Coastguard Worker #endif  //  BUILDFLAG(IS_CHROMEOS_LACROS)
1514*6777b538SAndroid Build Coastguard Worker 
1515*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_P(MetricsServiceTestWithFeatures,OngoingLogNotFlushedBeforeInitialLogWhenUserLogStoreSet)1516*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures,
1517*6777b538SAndroid Build Coastguard Worker        OngoingLogNotFlushedBeforeInitialLogWhenUserLogStoreSet) {
1518*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1519*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1520*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1521*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1522*6777b538SAndroid Build Coastguard Worker 
1523*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1524*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
1525*6777b538SAndroid Build Coastguard Worker   service.Start();
1526*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1527*6777b538SAndroid Build Coastguard Worker 
1528*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1529*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
1530*6777b538SAndroid Build Coastguard Worker       InitializeTestLogStoreAndGet();
1531*6777b538SAndroid Build Coastguard Worker   TestUnsentLogStore* alternate_ongoing_log_store_ptr =
1532*6777b538SAndroid Build Coastguard Worker       alternate_ongoing_log_store.get();
1533*6777b538SAndroid Build Coastguard Worker 
1534*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1535*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->ongoing_log_count());
1536*6777b538SAndroid Build Coastguard Worker 
1537*6777b538SAndroid Build Coastguard Worker   service.SetUserLogStore(std::move(alternate_ongoing_log_store));
1538*6777b538SAndroid Build Coastguard Worker 
1539*6777b538SAndroid Build Coastguard Worker   // Initial logs should not have been collected so the ongoing log being
1540*6777b538SAndroid Build Coastguard Worker   // recorded should not be flushed when a user log store is mounted.
1541*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1542*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->ongoing_log_count());
1543*6777b538SAndroid Build Coastguard Worker 
1544*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
1545*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
1546*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
1547*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
1548*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
1549*6777b538SAndroid Build Coastguard Worker 
1550*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
1551*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log.
1552*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
1553*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
1554*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
1555*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
1556*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
1557*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
1558*6777b538SAndroid Build Coastguard Worker       initialization_delay);
1559*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
1560*6777b538SAndroid Build Coastguard Worker   // When the init task is complete, the first ongoing log should be created
1561*6777b538SAndroid Build Coastguard Worker   // in the alternate ongoing log store.
1562*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, test_log_store->initial_log_count());
1563*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, test_log_store->ongoing_log_count());
1564*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, alternate_ongoing_log_store_ptr->size());
1565*6777b538SAndroid Build Coastguard Worker }
1566*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,OngoingLogFlushedAfterInitialLogWhenUserLogStoreSet)1567*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures,
1568*6777b538SAndroid Build Coastguard Worker        OngoingLogFlushedAfterInitialLogWhenUserLogStoreSet) {
1569*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1570*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1571*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1572*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1573*6777b538SAndroid Build Coastguard Worker 
1574*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1575*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
1576*6777b538SAndroid Build Coastguard Worker   service.Start();
1577*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1578*6777b538SAndroid Build Coastguard Worker 
1579*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1580*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
1581*6777b538SAndroid Build Coastguard Worker       InitializeTestLogStoreAndGet();
1582*6777b538SAndroid Build Coastguard Worker 
1583*6777b538SAndroid Build Coastguard Worker   // Init state.
1584*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1585*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->ongoing_log_count());
1586*6777b538SAndroid Build Coastguard Worker 
1587*6777b538SAndroid Build Coastguard Worker   // Fast forward the time by |initialization_delay|, which is when the pending
1588*6777b538SAndroid Build Coastguard Worker   // init tasks will run.
1589*6777b538SAndroid Build Coastguard Worker   base::TimeDelta initialization_delay = service.GetInitializationDelay();
1590*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(initialization_delay);
1591*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TestMetricsService::INIT_TASK_DONE, service.state());
1592*6777b538SAndroid Build Coastguard Worker 
1593*6777b538SAndroid Build Coastguard Worker   // Fast forward the time until the MetricsRotationScheduler first runs, which
1594*6777b538SAndroid Build Coastguard Worker   // should complete the first ongoing log.
1595*6777b538SAndroid Build Coastguard Worker   // Note: The first log is only created after N = GetInitialIntervalSeconds()
1596*6777b538SAndroid Build Coastguard Worker   // seconds since the start, and since we already fast forwarded by
1597*6777b538SAndroid Build Coastguard Worker   // |initialization_delay| once, we only need to fast forward by
1598*6777b538SAndroid Build Coastguard Worker   // N - |initialization_delay|.
1599*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(
1600*6777b538SAndroid Build Coastguard Worker       base::Seconds(MetricsScheduler::GetInitialIntervalSeconds()) -
1601*6777b538SAndroid Build Coastguard Worker       initialization_delay);
1602*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::SENDING_LOGS, service.state());
1603*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1604*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, test_log_store->ongoing_log_count());
1605*6777b538SAndroid Build Coastguard Worker 
1606*6777b538SAndroid Build Coastguard Worker   // User log store set post-init.
1607*6777b538SAndroid Build Coastguard Worker   service.SetUserLogStore(std::move(alternate_ongoing_log_store));
1608*6777b538SAndroid Build Coastguard Worker 
1609*6777b538SAndroid Build Coastguard Worker   // Another log should have been flushed from setting the user log store.
1610*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1611*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, test_log_store->ongoing_log_count());
1612*6777b538SAndroid Build Coastguard Worker }
1613*6777b538SAndroid Build Coastguard Worker 
TEST_P(MetricsServiceTestWithFeatures,OngoingLogDiscardedAfterEarlyUnsetUserLogStore)1614*6777b538SAndroid Build Coastguard Worker TEST_P(MetricsServiceTestWithFeatures,
1615*6777b538SAndroid Build Coastguard Worker        OngoingLogDiscardedAfterEarlyUnsetUserLogStore) {
1616*6777b538SAndroid Build Coastguard Worker   EnableMetricsReporting();
1617*6777b538SAndroid Build Coastguard Worker   TestMetricsServiceClient client;
1618*6777b538SAndroid Build Coastguard Worker   TestMetricsService service(GetMetricsStateManager(), &client,
1619*6777b538SAndroid Build Coastguard Worker                              GetLocalState());
1620*6777b538SAndroid Build Coastguard Worker 
1621*6777b538SAndroid Build Coastguard Worker   service.InitializeMetricsRecordingState();
1622*6777b538SAndroid Build Coastguard Worker   // Start() will create the first ongoing log.
1623*6777b538SAndroid Build Coastguard Worker   service.Start();
1624*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(TestMetricsService::INIT_TASK_SCHEDULED, service.state());
1625*6777b538SAndroid Build Coastguard Worker 
1626*6777b538SAndroid Build Coastguard Worker   MetricsLogStore* test_log_store = service.LogStoreForTest();
1627*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
1628*6777b538SAndroid Build Coastguard Worker       InitializeTestLogStoreAndGet();
1629*6777b538SAndroid Build Coastguard Worker 
1630*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->initial_log_count());
1631*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, test_log_store->ongoing_log_count());
1632*6777b538SAndroid Build Coastguard Worker 
1633*6777b538SAndroid Build Coastguard Worker   service.SetUserLogStore(std::move(alternate_ongoing_log_store));
1634*6777b538SAndroid Build Coastguard Worker 
1635*6777b538SAndroid Build Coastguard Worker   // Unset the user log store before we started sending logs.
1636*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramBoolean("Test.Before.Histogram", true);
1637*6777b538SAndroid Build Coastguard Worker   service.UnsetUserLogStore();
1638*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramBoolean("Test.After.Histogram", true);
1639*6777b538SAndroid Build Coastguard Worker 
1640*6777b538SAndroid Build Coastguard Worker   // Verify that the current log was discarded.
1641*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(service.GetCurrentLogForTest());
1642*6777b538SAndroid Build Coastguard Worker 
1643*6777b538SAndroid Build Coastguard Worker   // Verify that histograms from before unsetting the user log store were
1644*6777b538SAndroid Build Coastguard Worker   // flushed.
1645*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, GetHistogramDeltaTotalCount("Test.Before.Histogram"));
1646*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, GetHistogramDeltaTotalCount("Test.After.Histogram"));
1647*6777b538SAndroid Build Coastguard Worker 
1648*6777b538SAndroid Build Coastguard Worker   // Clean up histograms.
1649*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting("Test.Before.Histogram");
1650*6777b538SAndroid Build Coastguard Worker   base::StatisticsRecorder::ForgetHistogramForTesting("Test.After.Histogram");
1651*6777b538SAndroid Build Coastguard Worker }
1652*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
1653*6777b538SAndroid Build Coastguard Worker 
1654*6777b538SAndroid Build Coastguard Worker }  // namespace metrics
1655