Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / components / metrics / call_stack_profile_metrics_provider_unittest.cc
blob9ffaf573b486fa5e7b6fc7bc9245d519a488dd40
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/metrics/call_stack_profile_metrics_provider.h"
7 #include "base/metrics/field_trial.h"
8 #include "base/profiler/stack_sampling_profiler.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "components/metrics/proto/chrome_user_metrics_extension.pb.h"
12 #include "components/variations/entropy_provider.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 using base::StackSamplingProfiler;
16 using Frame = StackSamplingProfiler::Frame;
17 using Module = StackSamplingProfiler::Module;
18 using Profile = StackSamplingProfiler::CallStackProfile;
19 using Profiles = StackSamplingProfiler::CallStackProfiles;
20 using Sample = StackSamplingProfiler::Sample;
22 namespace metrics {
24 using Params = CallStackProfileMetricsProvider::Params;
26 // This test fixture enables the field trial that
27 // CallStackProfileMetricsProvider depends on to report profiles.
28 class CallStackProfileMetricsProviderTest : public testing::Test {
29 public:
30 CallStackProfileMetricsProviderTest()
31 : field_trial_list_(nullptr) {
32 base::FieldTrialList::CreateFieldTrial(
33 TestState::kFieldTrialName,
34 TestState::kReportProfilesGroupName);
35 TestState::ResetStaticStateForTesting();
38 ~CallStackProfileMetricsProviderTest() override {}
40 // Utility function to append profiles to the metrics provider.
41 void AppendProfiles(const Params& params, const Profiles& profiles) {
42 CallStackProfileMetricsProvider::GetProfilerCallback(params).Run(profiles);
45 private:
46 // Exposes field trial/group names from the CallStackProfileMetricsProvider.
47 class TestState : public CallStackProfileMetricsProvider {
48 public:
49 using CallStackProfileMetricsProvider::kFieldTrialName;
50 using CallStackProfileMetricsProvider::kReportProfilesGroupName;
51 using CallStackProfileMetricsProvider::ResetStaticStateForTesting;
54 base::FieldTrialList field_trial_list_;
56 DISALLOW_COPY_AND_ASSIGN(CallStackProfileMetricsProviderTest);
59 // Checks that all properties from multiple profiles are filled as expected.
60 TEST_F(CallStackProfileMetricsProviderTest, MultipleProfiles) {
61 const uintptr_t module1_base_address = 0x1000;
62 const uintptr_t module2_base_address = 0x2000;
63 const uintptr_t module3_base_address = 0x3000;
65 const Module profile_modules[][2] = {
67 Module(
68 module1_base_address,
69 "ABCD",
70 #if defined(OS_WIN)
71 base::FilePath(L"c:\\some\\path\\to\\chrome.exe")
72 #else
73 base::FilePath("/some/path/to/chrome")
74 #endif
76 Module(
77 module2_base_address,
78 "EFGH",
79 #if defined(OS_WIN)
80 base::FilePath(L"c:\\some\\path\\to\\third_party.dll")
81 #else
82 base::FilePath("/some/path/to/third_party.so")
83 #endif
87 Module(
88 module3_base_address,
89 "MNOP",
90 #if defined(OS_WIN)
91 base::FilePath(L"c:\\some\\path\\to\\third_party2.dll")
92 #else
93 base::FilePath("/some/path/to/third_party2.so")
94 #endif
96 Module( // Repeated from the first profile.
97 module1_base_address,
98 "ABCD",
99 #if defined(OS_WIN)
100 base::FilePath(L"c:\\some\\path\\to\\chrome.exe")
101 #else
102 base::FilePath("/some/path/to/chrome")
103 #endif
108 // Values for Windows generated with:
109 // perl -MDigest::MD5=md5 -MEncode=encode
110 // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 encode "UTF-16LE", $_}'
111 // chrome.exe third_party.dll third_party2.dll
113 // Values for Linux generated with:
114 // perl -MDigest::MD5=md5
115 // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 $_}'
116 // chrome third_party.so third_party2.so
117 const uint64 profile_expected_name_md5_prefixes[][2] = {
119 #if defined(OS_WIN)
120 0x46c3e4166659ac02ULL,
121 0x7e2b8bfddeae1abaULL
122 #else
123 0x554838a8451ac36cUL,
124 0x843661148659c9f8UL
125 #endif
128 #if defined(OS_WIN)
129 0x87b66f4573a4d5caULL,
130 0x46c3e4166659ac02ULL
131 #else
132 0xb4647e539fa6ec9eUL,
133 0x554838a8451ac36cUL
134 #endif
138 // Represents two stack samples for each of two profiles, where each stack
139 // contains three frames. Each frame contains an instruction pointer and a
140 // module index corresponding to the module for the profile in
141 // profile_modules.
143 // So, the first stack sample below has its top frame in module 0 at an offset
144 // of 0x10 from the module's base address, the next-to-top frame in module 1
145 // at an offset of 0x20 from the module's base address, and the bottom frame
146 // in module 0 at an offset of 0x30 from the module's base address
147 const Frame profile_sample_frames[][2][3] = {
150 Frame(module1_base_address + 0x10, 0),
151 Frame(module2_base_address + 0x20, 1),
152 Frame(module1_base_address + 0x30, 0)
155 Frame(module2_base_address + 0x10, 1),
156 Frame(module1_base_address + 0x20, 0),
157 Frame(module2_base_address + 0x30, 1)
162 Frame(module3_base_address + 0x10, 0),
163 Frame(module1_base_address + 0x20, 1),
164 Frame(module3_base_address + 0x30, 0)
167 Frame(module1_base_address + 0x10, 1),
168 Frame(module3_base_address + 0x20, 0),
169 Frame(module1_base_address + 0x30, 1)
174 base::TimeDelta profile_durations[2] = {
175 base::TimeDelta::FromMilliseconds(100),
176 base::TimeDelta::FromMilliseconds(200)
179 base::TimeDelta profile_sampling_periods[2] = {
180 base::TimeDelta::FromMilliseconds(10),
181 base::TimeDelta::FromMilliseconds(20)
184 std::vector<Profile> profiles;
185 for (size_t i = 0; i < arraysize(profile_sample_frames); ++i) {
186 Profile profile;
187 profile.modules.insert(
188 profile.modules.end(), &profile_modules[i][0],
189 &profile_modules[i][0] + arraysize(profile_modules[i]));
191 for (size_t j = 0; j < arraysize(profile_sample_frames[i]); ++j) {
192 profile.samples.push_back(Sample());
193 Sample& sample = profile.samples.back();
194 sample.insert(sample.end(), &profile_sample_frames[i][j][0],
195 &profile_sample_frames[i][j][0] +
196 arraysize(profile_sample_frames[i][j]));
199 profile.profile_duration = profile_durations[i];
200 profile.sampling_period = profile_sampling_periods[i];
202 profiles.push_back(profile);
205 CallStackProfileMetricsProvider provider;
206 provider.OnRecordingEnabled();
207 AppendProfiles(
208 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false),
209 profiles);
210 ChromeUserMetricsExtension uma_proto;
211 provider.ProvideGeneralMetrics(&uma_proto);
213 ASSERT_EQ(static_cast<int>(arraysize(profile_sample_frames)),
214 uma_proto.sampled_profile().size());
215 for (size_t i = 0; i < arraysize(profile_sample_frames); ++i) {
216 SCOPED_TRACE("profile " + base::IntToString(i));
217 const SampledProfile& sampled_profile = uma_proto.sampled_profile().Get(i);
218 ASSERT_TRUE(sampled_profile.has_call_stack_profile());
219 const CallStackProfile& call_stack_profile =
220 sampled_profile.call_stack_profile();
222 ASSERT_EQ(static_cast<int>(arraysize(profile_sample_frames[i])),
223 call_stack_profile.sample().size());
224 for (size_t j = 0; j < arraysize(profile_sample_frames[i]); ++j) {
225 SCOPED_TRACE("sample " + base::IntToString(j));
226 const CallStackProfile::Sample& proto_sample =
227 call_stack_profile.sample().Get(j);
228 ASSERT_EQ(static_cast<int>(arraysize(profile_sample_frames[i][j])),
229 proto_sample.entry().size());
230 ASSERT_TRUE(proto_sample.has_count());
231 EXPECT_EQ(1u, proto_sample.count());
232 for (size_t k = 0; k < arraysize(profile_sample_frames[i][j]); ++k) {
233 SCOPED_TRACE("frame " + base::IntToString(k));
234 const CallStackProfile::Entry& entry = proto_sample.entry().Get(k);
235 ASSERT_TRUE(entry.has_address());
236 const char* instruction_pointer = reinterpret_cast<const char*>(
237 profile_sample_frames[i][j][k].instruction_pointer);
238 const char* module_base_address = reinterpret_cast<const char*>(
239 profile_modules[i][profile_sample_frames[i][j][k].module_index]
240 .base_address);
241 EXPECT_EQ(static_cast<uint64>(instruction_pointer -
242 module_base_address), entry.address());
243 ASSERT_TRUE(entry.has_module_id_index());
244 EXPECT_EQ(profile_sample_frames[i][j][k].module_index,
245 static_cast<size_t>(entry.module_id_index()));
249 ASSERT_EQ(static_cast<int>(arraysize(profile_modules[i])),
250 call_stack_profile.module_id().size());
251 for (size_t j = 0; j < arraysize(profile_modules[i]); ++j) {
252 SCOPED_TRACE("module " + base::IntToString(j));
253 const CallStackProfile::ModuleIdentifier& module_identifier =
254 call_stack_profile.module_id().Get(j);
255 ASSERT_TRUE(module_identifier.has_build_id());
256 EXPECT_EQ(profile_modules[i][j].id, module_identifier.build_id());
257 ASSERT_TRUE(module_identifier.has_name_md5_prefix());
258 EXPECT_EQ(profile_expected_name_md5_prefixes[i][j],
259 module_identifier.name_md5_prefix());
262 ASSERT_TRUE(call_stack_profile.has_profile_duration_ms());
263 EXPECT_EQ(profile_durations[i].InMilliseconds(),
264 call_stack_profile.profile_duration_ms());
265 ASSERT_TRUE(call_stack_profile.has_sampling_period_ms());
266 EXPECT_EQ(profile_sampling_periods[i].InMilliseconds(),
267 call_stack_profile.sampling_period_ms());
268 ASSERT_TRUE(sampled_profile.has_trigger_event());
269 EXPECT_EQ(SampledProfile::PROCESS_STARTUP, sampled_profile.trigger_event());
273 // Checks that all duplicate samples are collapsed with
274 // preserve_sample_ordering = false.
275 TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) {
276 const uintptr_t module_base_address = 0x1000;
278 const Module modules[] = {
279 Module(
280 module_base_address,
281 "ABCD",
282 #if defined(OS_WIN)
283 base::FilePath(L"c:\\some\\path\\to\\chrome.exe")
284 #else
285 base::FilePath("/some/path/to/chrome")
286 #endif
290 // Duplicate samples in slots 0, 2, and 3.
291 const Frame sample_frames[][1] = {
292 { Frame(module_base_address + 0x10, 0), },
293 { Frame(module_base_address + 0x20, 0), },
294 { Frame(module_base_address + 0x10, 0), },
295 { Frame(module_base_address + 0x10, 0) }
298 Profile profile;
299 profile.modules.insert(profile.modules.end(), &modules[0],
300 &modules[0] + arraysize(modules));
302 for (size_t i = 0; i < arraysize(sample_frames); ++i) {
303 profile.samples.push_back(Sample());
304 Sample& sample = profile.samples.back();
305 sample.insert(sample.end(), &sample_frames[i][0],
306 &sample_frames[i][0] + arraysize(sample_frames[i]));
309 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
310 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
312 CallStackProfileMetricsProvider provider;
313 provider.OnRecordingEnabled();
314 AppendProfiles(
315 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false),
316 std::vector<Profile>(1, profile));
317 ChromeUserMetricsExtension uma_proto;
318 provider.ProvideGeneralMetrics(&uma_proto);
320 ASSERT_EQ(1, uma_proto.sampled_profile().size());
321 const SampledProfile& sampled_profile = uma_proto.sampled_profile().Get(0);
322 ASSERT_TRUE(sampled_profile.has_call_stack_profile());
323 const CallStackProfile& call_stack_profile =
324 sampled_profile.call_stack_profile();
326 ASSERT_EQ(2, call_stack_profile.sample().size());
327 for (int i = 0; i < 2; ++i) {
328 SCOPED_TRACE("sample " + base::IntToString(i));
329 const CallStackProfile::Sample& proto_sample =
330 call_stack_profile.sample().Get(i);
331 ASSERT_EQ(static_cast<int>(arraysize(sample_frames[i])),
332 proto_sample.entry().size());
333 ASSERT_TRUE(proto_sample.has_count());
334 EXPECT_EQ(i == 0 ? 3u : 1u, proto_sample.count());
335 for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) {
336 SCOPED_TRACE("frame " + base::IntToString(j));
337 const CallStackProfile::Entry& entry = proto_sample.entry().Get(j);
338 ASSERT_TRUE(entry.has_address());
339 const char* instruction_pointer = reinterpret_cast<const char*>(
340 sample_frames[i][j].instruction_pointer);
341 const char* module_base_address = reinterpret_cast<const char*>(
342 modules[sample_frames[i][j].module_index].base_address);
343 EXPECT_EQ(static_cast<uint64>(instruction_pointer - module_base_address),
344 entry.address());
345 ASSERT_TRUE(entry.has_module_id_index());
346 EXPECT_EQ(sample_frames[i][j].module_index,
347 static_cast<size_t>(entry.module_id_index()));
352 // Checks that only contiguous duplicate samples are collapsed with
353 // preserve_sample_ordering = true.
354 TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) {
355 const uintptr_t module_base_address = 0x1000;
357 const Module modules[] = {
358 Module(
359 module_base_address,
360 "ABCD",
361 #if defined(OS_WIN)
362 base::FilePath(L"c:\\some\\path\\to\\chrome.exe")
363 #else
364 base::FilePath("/some/path/to/chrome")
365 #endif
369 // Duplicate samples in slots 0, 2, and 3.
370 const Frame sample_frames[][1] = {
371 { Frame(module_base_address + 0x10, 0), },
372 { Frame(module_base_address + 0x20, 0), },
373 { Frame(module_base_address + 0x10, 0), },
374 { Frame(module_base_address + 0x10, 0) }
377 Profile profile;
378 profile.modules.insert(profile.modules.end(), &modules[0],
379 &modules[0] + arraysize(modules));
381 for (size_t i = 0; i < arraysize(sample_frames); ++i) {
382 profile.samples.push_back(Sample());
383 Sample& sample = profile.samples.back();
384 sample.insert(sample.end(), &sample_frames[i][0],
385 &sample_frames[i][0] + arraysize(sample_frames[i]));
388 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
389 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
391 CallStackProfileMetricsProvider provider;
392 provider.OnRecordingEnabled();
393 AppendProfiles(Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, true),
394 std::vector<Profile>(1, profile));
395 ChromeUserMetricsExtension uma_proto;
396 provider.ProvideGeneralMetrics(&uma_proto);
398 ASSERT_EQ(1, uma_proto.sampled_profile().size());
399 const SampledProfile& sampled_profile = uma_proto.sampled_profile().Get(0);
400 ASSERT_TRUE(sampled_profile.has_call_stack_profile());
401 const CallStackProfile& call_stack_profile =
402 sampled_profile.call_stack_profile();
404 ASSERT_EQ(3, call_stack_profile.sample().size());
405 for (int i = 0; i < 3; ++i) {
406 SCOPED_TRACE("sample " + base::IntToString(i));
407 const CallStackProfile::Sample& proto_sample =
408 call_stack_profile.sample().Get(i);
409 ASSERT_EQ(static_cast<int>(arraysize(sample_frames[i])),
410 proto_sample.entry().size());
411 ASSERT_TRUE(proto_sample.has_count());
412 EXPECT_EQ(i == 2 ? 2u : 1u, proto_sample.count());
413 for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) {
414 SCOPED_TRACE("frame " + base::IntToString(j));
415 const CallStackProfile::Entry& entry = proto_sample.entry().Get(j);
416 ASSERT_TRUE(entry.has_address());
417 const char* instruction_pointer = reinterpret_cast<const char*>(
418 sample_frames[i][j].instruction_pointer);
419 const char* module_base_address = reinterpret_cast<const char*>(
420 modules[sample_frames[i][j].module_index].base_address);
421 EXPECT_EQ(static_cast<uint64>(instruction_pointer - module_base_address),
422 entry.address());
423 ASSERT_TRUE(entry.has_module_id_index());
424 EXPECT_EQ(sample_frames[i][j].module_index,
425 static_cast<size_t>(entry.module_id_index()));
430 // Checks that unknown modules produce an empty Entry.
431 TEST_F(CallStackProfileMetricsProviderTest, UnknownModule) {
432 const Frame frame(0x1000, Frame::kUnknownModuleIndex);
434 Profile profile;
436 profile.samples.push_back(Sample(1, frame));
438 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
439 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
441 CallStackProfileMetricsProvider provider;
442 provider.OnRecordingEnabled();
443 AppendProfiles(
444 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false),
445 std::vector<Profile>(1, profile));
446 ChromeUserMetricsExtension uma_proto;
447 provider.ProvideGeneralMetrics(&uma_proto);
449 ASSERT_EQ(1, uma_proto.sampled_profile().size());
450 const SampledProfile& sampled_profile = uma_proto.sampled_profile().Get(0);
451 ASSERT_TRUE(sampled_profile.has_call_stack_profile());
452 const CallStackProfile& call_stack_profile =
453 sampled_profile.call_stack_profile();
455 ASSERT_EQ(1, call_stack_profile.sample().size());
456 const CallStackProfile::Sample& proto_sample =
457 call_stack_profile.sample().Get(0);
458 ASSERT_EQ(1, proto_sample.entry().size());
459 ASSERT_TRUE(proto_sample.has_count());
460 EXPECT_EQ(1u, proto_sample.count());
461 const CallStackProfile::Entry& entry = proto_sample.entry().Get(0);
462 EXPECT_FALSE(entry.has_address());
463 EXPECT_FALSE(entry.has_module_id_index());
466 // Checks that pending profiles are only passed back to ProvideGeneralMetrics
467 // once.
468 TEST_F(CallStackProfileMetricsProviderTest, ProfilesProvidedOnlyOnce) {
469 CallStackProfileMetricsProvider provider;
470 for (int i = 0; i < 2; ++i) {
471 Profile profile;
472 profile.samples.push_back(
473 Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex)));
475 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
476 // Use the sampling period to distinguish the two profiles.
477 profile.sampling_period = base::TimeDelta::FromMilliseconds(i);
479 provider.OnRecordingEnabled();
480 AppendProfiles(
481 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false),
482 std::vector<Profile>(1, profile));
483 ChromeUserMetricsExtension uma_proto;
484 provider.ProvideGeneralMetrics(&uma_proto);
486 ASSERT_EQ(1, uma_proto.sampled_profile().size());
487 const SampledProfile& sampled_profile = uma_proto.sampled_profile().Get(0);
488 ASSERT_TRUE(sampled_profile.has_call_stack_profile());
489 const CallStackProfile& call_stack_profile =
490 sampled_profile.call_stack_profile();
491 ASSERT_TRUE(call_stack_profile.has_sampling_period_ms());
492 EXPECT_EQ(i, call_stack_profile.sampling_period_ms());
496 // Checks that pending profiles are provided to ProvideGeneralMetrics
497 // when collected before CallStackProfileMetricsProvider is instantiated.
498 TEST_F(CallStackProfileMetricsProviderTest,
499 ProfilesProvidedWhenCollectedBeforeInstantiation) {
500 Profile profile;
501 profile.samples.push_back(
502 Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex)));
504 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
505 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
507 AppendProfiles(
508 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false),
509 std::vector<Profile>(1, profile));
511 CallStackProfileMetricsProvider provider;
512 provider.OnRecordingEnabled();
513 ChromeUserMetricsExtension uma_proto;
514 provider.ProvideGeneralMetrics(&uma_proto);
516 EXPECT_EQ(1, uma_proto.sampled_profile_size());
519 // Checks that pending profiles are not provided to ProvideGeneralMetrics
520 // while recording is disabled.
521 TEST_F(CallStackProfileMetricsProviderTest, ProfilesNotProvidedWhileDisabled) {
522 Profile profile;
523 profile.samples.push_back(
524 Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex)));
526 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
527 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
529 CallStackProfileMetricsProvider provider;
530 provider.OnRecordingDisabled();
531 AppendProfiles(
532 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false),
533 std::vector<Profile>(1, profile));
534 ChromeUserMetricsExtension uma_proto;
535 provider.ProvideGeneralMetrics(&uma_proto);
537 EXPECT_EQ(0, uma_proto.sampled_profile_size());
540 // Checks that pending profiles are not provided to ProvideGeneralMetrics
541 // if recording is disabled while profiling.
542 TEST_F(CallStackProfileMetricsProviderTest,
543 ProfilesNotProvidedAfterChangeToDisabled) {
544 Profile profile;
545 profile.samples.push_back(
546 Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex)));
548 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
549 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
551 CallStackProfileMetricsProvider provider;
552 provider.OnRecordingEnabled();
553 base::StackSamplingProfiler::CompletedCallback callback =
554 CallStackProfileMetricsProvider::GetProfilerCallback(
555 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false));
557 provider.OnRecordingDisabled();
558 callback.Run(std::vector<Profile>(1, profile));
559 ChromeUserMetricsExtension uma_proto;
560 provider.ProvideGeneralMetrics(&uma_proto);
562 EXPECT_EQ(0, uma_proto.sampled_profile_size());
565 // Checks that pending profiles are not provided to ProvideGeneralMetrics if
566 // recording is enabled, but then disabled and reenabled while profiling.
567 TEST_F(CallStackProfileMetricsProviderTest,
568 ProfilesNotProvidedAfterChangeToDisabledThenEnabled) {
569 Profile profile;
570 profile.samples.push_back(
571 Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex)));
573 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
574 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
576 CallStackProfileMetricsProvider provider;
577 provider.OnRecordingEnabled();
578 base::StackSamplingProfiler::CompletedCallback callback =
579 CallStackProfileMetricsProvider::GetProfilerCallback(
580 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false));
582 provider.OnRecordingDisabled();
583 provider.OnRecordingEnabled();
584 callback.Run(std::vector<Profile>(1, profile));
585 ChromeUserMetricsExtension uma_proto;
586 provider.ProvideGeneralMetrics(&uma_proto);
588 EXPECT_EQ(0, uma_proto.sampled_profile_size());
591 // Checks that pending profiles are not provided to ProvideGeneralMetrics
592 // if recording is disabled, but then enabled while profiling.
593 TEST_F(CallStackProfileMetricsProviderTest,
594 ProfilesNotProvidedAfterChangeFromDisabled) {
595 Profile profile;
596 profile.samples.push_back(
597 Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex)));
599 profile.profile_duration = base::TimeDelta::FromMilliseconds(100);
600 profile.sampling_period = base::TimeDelta::FromMilliseconds(10);
602 CallStackProfileMetricsProvider provider;
603 provider.OnRecordingDisabled();
604 base::StackSamplingProfiler::CompletedCallback callback =
605 CallStackProfileMetricsProvider::GetProfilerCallback(
606 Params(CallStackProfileMetricsProvider::PROCESS_STARTUP, false));
608 provider.OnRecordingEnabled();
609 callback.Run(std::vector<Profile>(1, profile));
610 ChromeUserMetricsExtension uma_proto;
611 provider.ProvideGeneralMetrics(&uma_proto);
613 EXPECT_EQ(0, uma_proto.sampled_profile_size());
616 } // namespace metrics