Chromium Code Reviews| Index: components/metrics/call_stack_profile_metrics_provider_unittest.cc |
| diff --git a/components/metrics/call_stack_profile_metrics_provider_unittest.cc b/components/metrics/call_stack_profile_metrics_provider_unittest.cc |
| index 3e515b5c2db336cc09e2b1cbf66d5e4437cfa6af..7417197e7ca9cc5088d5801e8e042e2660c7b4a2 100644 |
| --- a/components/metrics/call_stack_profile_metrics_provider_unittest.cc |
| +++ b/components/metrics/call_stack_profile_metrics_provider_unittest.cc |
| @@ -193,9 +193,9 @@ TEST_F(CallStackProfileMetricsProviderTest, MultipleProfiles) { |
| for (size_t j = 0; j < arraysize(profile_sample_frames[i]); ++j) { |
| profile.samples.push_back(Sample()); |
| Sample& sample = profile.samples.back(); |
| - sample.insert(sample.end(), &profile_sample_frames[i][j][0], |
| - &profile_sample_frames[i][j][0] + |
| - arraysize(profile_sample_frames[i][j])); |
| + sample.frames.insert(sample.frames.end(), &profile_sample_frames[i][j][0], |
| + &profile_sample_frames[i][j][0] + |
| + arraysize(profile_sample_frames[i][j])); |
| } |
| profile.profile_duration = profile_durations[i]; |
| @@ -223,7 +223,6 @@ TEST_F(CallStackProfileMetricsProviderTest, MultipleProfiles) { |
| ASSERT_TRUE(sampled_profile.has_call_stack_profile()); |
| const CallStackProfile& call_stack_profile = |
| sampled_profile.call_stack_profile(); |
| - |
| ASSERT_EQ(static_cast<int>(arraysize(profile_sample_frames[i])), |
| call_stack_profile.sample().size()); |
| for (size_t j = 0; j < arraysize(profile_sample_frames[i]); ++j) { |
| @@ -297,12 +296,32 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) { |
| ) |
| }; |
| - // Duplicate samples in slots 0, 2, and 3. |
| + // Samples are unique only if the phase, activity, and frame all match. |
| + const uint32_t profile_phases_and_activities[][2] = { |
| + { 1, 0 }, |
| + { 1, 0 }, |
| + { 3, 0 }, |
| + { 3, 0 }, |
| + { 3, 1 }, |
| + // Unique above, duplicates below. |
| + { 1, 0 }, |
| + { 1, 0 }, |
| + { 3, 0 }, |
| + }; |
| const Frame sample_frames[][1] = { |
|
Mike Wittman
2016/11/03 21:15:39
This test is getting kind of hard to follow... I t
|
| { Frame(module_base_address + 0x10, 0), }, |
| { Frame(module_base_address + 0x20, 0), }, |
| { Frame(module_base_address + 0x10, 0), }, |
| - { Frame(module_base_address + 0x10, 0) } |
| + { Frame(module_base_address + 0x20, 0), }, |
| + { Frame(module_base_address + 0x10, 0), }, |
| + // Unique above, duplicates below. |
| + { Frame(module_base_address + 0x10, 0), }, |
| + { Frame(module_base_address + 0x10, 0), }, |
| + { Frame(module_base_address + 0x10, 0), }, |
| + }; |
| + |
| + const int duplicate_counts[] = { |
| + 3, 1, 2, 1, 1, |
| }; |
| Profile profile; |
| @@ -312,8 +331,10 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) { |
| for (size_t i = 0; i < arraysize(sample_frames); ++i) { |
| profile.samples.push_back(Sample()); |
| Sample& sample = profile.samples.back(); |
| - sample.insert(sample.end(), &sample_frames[i][0], |
| - &sample_frames[i][0] + arraysize(sample_frames[i])); |
| + sample.process_phases = profile_phases_and_activities[i][0]; |
| + sample.current_activities = profile_phases_and_activities[i][1]; |
| + sample.frames.insert(sample.frames.end(), &sample_frames[i][0], |
| + &sample_frames[i][0] + arraysize(sample_frames[i])); |
| } |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| @@ -338,15 +359,21 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) { |
| const CallStackProfile& call_stack_profile = |
| sampled_profile.call_stack_profile(); |
| - ASSERT_EQ(2, call_stack_profile.sample().size()); |
| - for (int i = 0; i < 2; ++i) { |
| - SCOPED_TRACE("sample " + base::IntToString(i)); |
| + ASSERT_EQ(static_cast<int>(arraysize(duplicate_counts)), |
| + call_stack_profile.sample().size()); |
| + for (size_t i = 0; i < arraysize(duplicate_counts); ++i) { |
| + SCOPED_TRACE("sample " + base::SizeTToString(i)); |
| const CallStackProfile::Sample& proto_sample = |
| call_stack_profile.sample().Get(i); |
| + |
| + // For MAY_SHUFFLE, these are reset with every sample. |
| + uint32_t process_phase = 0; |
| + uint32_t current_activities = 0; |
| + |
| ASSERT_EQ(static_cast<int>(arraysize(sample_frames[i])), |
| proto_sample.entry().size()); |
| ASSERT_TRUE(proto_sample.has_count()); |
| - EXPECT_EQ(i == 0 ? 3u : 1u, proto_sample.count()); |
| + EXPECT_EQ(duplicate_counts[i], proto_sample.count()); |
| for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) { |
| SCOPED_TRACE("frame " + base::SizeTToString(j)); |
| const CallStackProfile::Entry& entry = proto_sample.entry().Get(j); |
| @@ -362,6 +389,19 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) { |
| EXPECT_EQ(sample_frames[i][j].module_index, |
| static_cast<size_t>(entry.module_id_index())); |
| } |
| + |
| + for (int x = 0; x < proto_sample.process_phase_size(); ++x) { |
| + process_phase |= 1 << proto_sample.process_phase(x); |
| + } |
| + EXPECT_EQ(profile_phases_and_activities[i][0], process_phase); |
| + |
| + for (int x = 0; x < proto_sample.activities_begun_size(); ++x) { |
| + current_activities |= 1 << proto_sample.activities_begun(x); |
| + } |
| + for (int x = 0; x < proto_sample.activities_ended_size(); ++x) { |
|
Mike Wittman
2016/11/03 21:15:39
EXPECT_EQ(0u, proto_sample.activities_ended_size()
|
| + current_activities &= ~(1 << proto_sample.activities_ended(x)); |
| + } |
| + EXPECT_EQ(profile_phases_and_activities[i][1], current_activities); |
| } |
| } |
| @@ -382,12 +422,32 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) { |
| ) |
| }; |
| - // Duplicate samples in slots 0, 2, and 3. |
| + // Samples are unique only if the phase, activity, and frame all match. |
| + const uint32_t profile_phases_and_activities[][2] = { |
| + { 1, 0 }, |
| + { 1, 0 }, |
| + { 1, 0 }, |
| + { 1, 0 }, |
| + |
| + { 3, 0 }, |
| + { 3, 1 }, |
| + { 3, 0 }, |
| + { 3, 0 }, |
| + }; |
| const Frame sample_frames[][1] = { |
|
Mike Wittman
2016/11/03 21:15:39
Same comment here about representing with Sample.
|
| { Frame(module_base_address + 0x10, 0), }, |
| { Frame(module_base_address + 0x20, 0), }, |
| { Frame(module_base_address + 0x10, 0), }, |
| - { Frame(module_base_address + 0x10, 0) } |
| + { Frame(module_base_address + 0x10, 0), }, |
| + |
| + { Frame(module_base_address + 0x10, 0), }, |
| + { Frame(module_base_address + 0x20, 0), }, |
| + { Frame(module_base_address + 0x10, 0), }, |
| + { Frame(module_base_address + 0x10, 0), }, |
| + }; |
| + |
| + const int duplicate_counts[] = { |
| + 1, 1, 2, 1, 1, 2 |
| }; |
| Profile profile; |
| @@ -397,8 +457,10 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) { |
| for (size_t i = 0; i < arraysize(sample_frames); ++i) { |
| profile.samples.push_back(Sample()); |
| Sample& sample = profile.samples.back(); |
| - sample.insert(sample.end(), &sample_frames[i][0], |
| - &sample_frames[i][0] + arraysize(sample_frames[i])); |
| + sample.process_phases = profile_phases_and_activities[i][0]; |
| + sample.current_activities = profile_phases_and_activities[i][1]; |
| + sample.frames.insert(sample.frames.end(), &sample_frames[i][0], |
| + &sample_frames[i][0] + arraysize(sample_frames[i])); |
| } |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| @@ -422,41 +484,57 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) { |
| const CallStackProfile& call_stack_profile = |
| sampled_profile.call_stack_profile(); |
| - ASSERT_EQ(3, call_stack_profile.sample().size()); |
| - for (int i = 0; i < 3; ++i) { |
| - SCOPED_TRACE("sample " + base::IntToString(i)); |
| + // For PRESERVE_ORDER, these are reset with every profile. |
| + uint32_t process_phase = 0; |
| + uint32_t current_activities = 0; |
| + |
| + ASSERT_EQ(static_cast<int>(arraysize(duplicate_counts)), |
| + call_stack_profile.sample().size()); |
| + for (size_t i = 0, d = 0; i < arraysize(duplicate_counts); |
| + d += duplicate_counts[i], ++i) { |
| + // |d| is the index after compensating for duplicate compression. |
| + SCOPED_TRACE("sample " + base::SizeTToString(i)); |
| const CallStackProfile::Sample& proto_sample = |
| call_stack_profile.sample().Get(i); |
| ASSERT_EQ(static_cast<int>(arraysize(sample_frames[i])), |
| proto_sample.entry().size()); |
| ASSERT_TRUE(proto_sample.has_count()); |
| - EXPECT_EQ(i == 2 ? 2u : 1u, proto_sample.count()); |
| - for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) { |
| + EXPECT_EQ(duplicate_counts[i], proto_sample.count()); |
| + for (size_t j = 0; j < arraysize(sample_frames[d]); ++j) { |
| SCOPED_TRACE("frame " + base::SizeTToString(j)); |
| const CallStackProfile::Entry& entry = proto_sample.entry().Get(j); |
| ASSERT_TRUE(entry.has_address()); |
| const char* instruction_pointer = reinterpret_cast<const char*>( |
| - sample_frames[i][j].instruction_pointer); |
| + sample_frames[d][j].instruction_pointer); |
| const char* module_base_address = reinterpret_cast<const char*>( |
| - modules[sample_frames[i][j].module_index].base_address); |
| + modules[sample_frames[d][j].module_index].base_address); |
| EXPECT_EQ( |
| static_cast<uint64_t>(instruction_pointer - module_base_address), |
| entry.address()); |
| ASSERT_TRUE(entry.has_module_id_index()); |
| - EXPECT_EQ(sample_frames[i][j].module_index, |
| + EXPECT_EQ(sample_frames[d][j].module_index, |
| static_cast<size_t>(entry.module_id_index())); |
| } |
| + |
| + for (int x = 0; x < proto_sample.process_phase_size(); ++x) { |
| + process_phase |= 1 << proto_sample.process_phase(x); |
| + } |
| + EXPECT_EQ(profile_phases_and_activities[d][0], process_phase); |
| + |
| + for (int x = 0; x < proto_sample.activities_begun_size(); ++x) { |
| + current_activities |= 1 << proto_sample.activities_begun(x); |
| + } |
| + for (int x = 0; x < proto_sample.activities_ended_size(); ++x) { |
| + current_activities &= ~(1 << proto_sample.activities_ended(x)); |
| + } |
| + EXPECT_EQ(profile_phases_and_activities[d][1], current_activities); |
| } |
| } |
| // Checks that unknown modules produce an empty Entry. |
| TEST_F(CallStackProfileMetricsProviderTest, UnknownModule) { |
| - const Frame frame(0x1000, Frame::kUnknownModuleIndex); |
| - |
| Profile profile; |
| - |
| - profile.samples.push_back(Sample(1, frame)); |
| - |
| + profile.samples.push_back(Sample(Frame(0x1000, Frame::kUnknownModuleIndex))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| profile.sampling_period = base::TimeDelta::FromMilliseconds(10); |
| Profiles profiles; |
| @@ -497,7 +575,7 @@ TEST_F(CallStackProfileMetricsProviderTest, ProfilesProvidedOnlyOnce) { |
| for (int i = 0; i < 2; ++i) { |
| Profile profile; |
| profile.samples.push_back( |
| - Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex))); |
| + Sample((Frame(0x1000, Frame::kUnknownModuleIndex)))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| // Use the sampling period to distinguish the two profiles. |
| @@ -530,9 +608,7 @@ TEST_F(CallStackProfileMetricsProviderTest, ProfilesProvidedOnlyOnce) { |
| TEST_F(CallStackProfileMetricsProviderTest, |
| ProfilesProvidedWhenCollectedBeforeInstantiation) { |
| Profile profile; |
| - profile.samples.push_back( |
| - Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex))); |
| - |
| + profile.samples.push_back(Sample(Frame(0x1000, Frame::kUnknownModuleIndex))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| profile.sampling_period = base::TimeDelta::FromMilliseconds(10); |
| Profiles profiles; |
| @@ -557,9 +633,7 @@ TEST_F(CallStackProfileMetricsProviderTest, |
| // while recording is disabled. |
| TEST_F(CallStackProfileMetricsProviderTest, ProfilesNotProvidedWhileDisabled) { |
| Profile profile; |
| - profile.samples.push_back( |
| - Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex))); |
| - |
| + profile.samples.push_back(Sample(Frame(0x1000, Frame::kUnknownModuleIndex))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| profile.sampling_period = base::TimeDelta::FromMilliseconds(10); |
| Profiles profiles; |
| @@ -584,9 +658,7 @@ TEST_F(CallStackProfileMetricsProviderTest, ProfilesNotProvidedWhileDisabled) { |
| TEST_F(CallStackProfileMetricsProviderTest, |
| ProfilesNotProvidedAfterChangeToDisabled) { |
| Profile profile; |
| - profile.samples.push_back( |
| - Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex))); |
| - |
| + profile.samples.push_back(Sample(Frame(0x1000, Frame::kUnknownModuleIndex))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| profile.sampling_period = base::TimeDelta::FromMilliseconds(10); |
| @@ -614,9 +686,7 @@ TEST_F(CallStackProfileMetricsProviderTest, |
| TEST_F(CallStackProfileMetricsProviderTest, |
| ProfilesNotProvidedAfterChangeToDisabledThenEnabled) { |
| Profile profile; |
| - profile.samples.push_back( |
| - Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex))); |
| - |
| + profile.samples.push_back(Sample(Frame(0x1000, Frame::kUnknownModuleIndex))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| profile.sampling_period = base::TimeDelta::FromMilliseconds(10); |
| @@ -645,9 +715,7 @@ TEST_F(CallStackProfileMetricsProviderTest, |
| TEST_F(CallStackProfileMetricsProviderTest, |
| ProfilesNotProvidedAfterChangeFromDisabled) { |
| Profile profile; |
| - profile.samples.push_back( |
| - Sample(1, Frame(0x1000, Frame::kUnknownModuleIndex))); |
| - |
| + profile.samples.push_back(Sample(Frame(0x1000, Frame::kUnknownModuleIndex))); |
| profile.profile_duration = base::TimeDelta::FromMilliseconds(100); |
| profile.sampling_period = base::TimeDelta::FromMilliseconds(10); |