OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <utility> |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/macros.h" |
| 9 #include "base/message_loop/message_loop.h" |
| 10 #include "components/metrics/call_stack_profile_collector_test.mojom.h" |
| 11 #include "mojo/public/cpp/bindings/binding.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 |
| 14 namespace metrics { |
| 15 |
| 16 namespace { |
| 17 |
| 18 base::StackSamplingProfiler::CallStackProfile CreateProfile( |
| 19 const std::vector<base::StackSamplingProfiler::Module>& modules, |
| 20 const std::vector<base::StackSamplingProfiler::Sample>& samples, |
| 21 base::TimeDelta profile_duration, |
| 22 base::TimeDelta sampling_period) { |
| 23 base::StackSamplingProfiler::CallStackProfile profile; |
| 24 profile.modules = modules; |
| 25 profile.samples = samples; |
| 26 profile.profile_duration = profile_duration; |
| 27 profile.sampling_period = sampling_period; |
| 28 return profile; |
| 29 } |
| 30 |
| 31 } |
| 32 |
| 33 class CallStackProfileCollectorTestImpl |
| 34 : public mojom::CallStackProfileCollectorTest { |
| 35 public: |
| 36 explicit CallStackProfileCollectorTestImpl( |
| 37 mojo::InterfaceRequest<mojom::CallStackProfileCollectorTest> request) |
| 38 : binding_(this, std::move(request)) { |
| 39 } |
| 40 |
| 41 // CallStackProfileCollectorTest: |
| 42 void BounceFrame(const base::StackSamplingProfiler::Frame& in, |
| 43 const BounceFrameCallback& callback) override { |
| 44 callback.Run(in); |
| 45 } |
| 46 |
| 47 void BounceModule(const base::StackSamplingProfiler::Module& in, |
| 48 const BounceModuleCallback& callback) override { |
| 49 callback.Run(in); |
| 50 } |
| 51 |
| 52 void BounceProfile(const base::StackSamplingProfiler::CallStackProfile& in, |
| 53 const BounceProfileCallback& callback) override { |
| 54 callback.Run(in); |
| 55 } |
| 56 |
| 57 private: |
| 58 mojo::Binding<CallStackProfileCollectorTest> binding_; |
| 59 }; |
| 60 |
| 61 // Checks serialization/deserialization of Module fields. |
| 62 TEST(CallStackProfileStructTraitsTest, Module) { |
| 63 using Module = base::StackSamplingProfiler::Module; |
| 64 |
| 65 base::MessageLoop message_loop; |
| 66 |
| 67 mojom::CallStackProfileCollectorTestPtr proxy; |
| 68 CallStackProfileCollectorTestImpl impl(GetProxy(&proxy)); |
| 69 |
| 70 const Module serialize_cases[] = { |
| 71 Module(0x0, "abcd", base::FilePath(base::FilePath::kCurrentDirectory)), |
| 72 Module(0x10, "abcd", base::FilePath(base::FilePath::kCurrentDirectory)), |
| 73 Module(1ULL << (sizeof(uintptr_t) * 8) * 3 / 4, "abcd", |
| 74 base::FilePath(base::FilePath::kCurrentDirectory)), |
| 75 Module(0x10, "", base::FilePath(base::FilePath::kCurrentDirectory)), |
| 76 }; |
| 77 |
| 78 for (const Module& input : serialize_cases) { |
| 79 Module output; |
| 80 EXPECT_TRUE(proxy->BounceModule(input, &output)); |
| 81 |
| 82 EXPECT_EQ(input.base_address, output.base_address); |
| 83 EXPECT_EQ(input.id, output.id); |
| 84 EXPECT_EQ(input.filename, output.filename); |
| 85 } |
| 86 } |
| 87 |
| 88 // Checks serialization/deserialization of Frame fields. |
| 89 TEST(CallStackProfileStructTraitsTest, Frame) { |
| 90 using Frame = base::StackSamplingProfiler::Frame; |
| 91 |
| 92 base::MessageLoop message_loop; |
| 93 |
| 94 mojom::CallStackProfileCollectorTestPtr proxy; |
| 95 CallStackProfileCollectorTestImpl impl(GetProxy(&proxy)); |
| 96 |
| 97 const Frame serialize_cases[] = { |
| 98 Frame(0x0, 10), |
| 99 Frame(0x10, 10), |
| 100 Frame(1ULL << (sizeof(uintptr_t) * 8) * 3 / 4, 10), |
| 101 Frame(0xabcd, 0), |
| 102 Frame(0xabcd, 1), |
| 103 Frame(0xabcd, 10), |
| 104 Frame(0xabcd, Frame::kUnknownModuleIndex), |
| 105 }; |
| 106 |
| 107 for (const Frame& input : serialize_cases) { |
| 108 Frame output; |
| 109 EXPECT_TRUE(proxy->BounceFrame(input, &output)); |
| 110 |
| 111 EXPECT_EQ(input.instruction_pointer, output.instruction_pointer); |
| 112 EXPECT_EQ(input.module_index, output.module_index); |
| 113 } |
| 114 } |
| 115 |
| 116 // Checks serialization/deserialization of Profile fields, including validation |
| 117 // of the Frame module_index field. |
| 118 TEST(CallStackProfileStructTraitsTest, Profile) { |
| 119 using Module = base::StackSamplingProfiler::Module; |
| 120 using Frame = base::StackSamplingProfiler::Frame; |
| 121 using Sample = base::StackSamplingProfiler::Sample; |
| 122 using Profile = base::StackSamplingProfiler::CallStackProfile; |
| 123 |
| 124 base::MessageLoop message_loop; |
| 125 |
| 126 mojom::CallStackProfileCollectorTestPtr proxy; |
| 127 CallStackProfileCollectorTestImpl impl(GetProxy(&proxy)); |
| 128 |
| 129 struct SerializeCase { |
| 130 Profile profile; |
| 131 bool expect_success; |
| 132 }; |
| 133 const SerializeCase serialize_cases[] = { |
| 134 { |
| 135 CreateProfile(std::vector<Module>(), std::vector<Sample>(), |
| 136 base::TimeDelta::FromSeconds(1), |
| 137 base::TimeDelta::FromSeconds(2)), |
| 138 true |
| 139 }, |
| 140 { |
| 141 CreateProfile({ Module(0x4000, "a", base::FilePath()) }, |
| 142 std::vector<Sample>(), |
| 143 base::TimeDelta::FromSeconds(1), |
| 144 base::TimeDelta::FromSeconds(2)), |
| 145 true |
| 146 }, |
| 147 { |
| 148 CreateProfile({ |
| 149 Module(0x4000, "a", base::FilePath()), |
| 150 Module(0x4100, "b", base::FilePath()), |
| 151 }, |
| 152 { |
| 153 { |
| 154 Frame(0x4010, 0), |
| 155 Frame(0x4110, 1), |
| 156 Frame(0x4110, Frame::kUnknownModuleIndex), |
| 157 } |
| 158 }, |
| 159 base::TimeDelta::FromSeconds(1), |
| 160 base::TimeDelta::FromSeconds(2)), |
| 161 true |
| 162 }, |
| 163 // The out of range module index in the second sample should cause the |
| 164 // entire deserialization to fail. |
| 165 { |
| 166 CreateProfile({ |
| 167 Module(0x4000, "a", base::FilePath()), |
| 168 Module(0x4100, "b", base::FilePath()), |
| 169 }, |
| 170 { |
| 171 { |
| 172 Frame(0x4010, 0), |
| 173 Frame(0x4110, 1), |
| 174 Frame(0x4110, Frame::kUnknownModuleIndex), |
| 175 }, |
| 176 { |
| 177 Frame(0x4010, 0), |
| 178 Frame(0x4110, 2), |
| 179 }, |
| 180 }, |
| 181 base::TimeDelta::FromSeconds(1), |
| 182 base::TimeDelta::FromSeconds(2)), |
| 183 false |
| 184 }, |
| 185 }; |
| 186 |
| 187 for (const SerializeCase& input : serialize_cases) { |
| 188 SCOPED_TRACE(&input - &serialize_cases[0]); |
| 189 |
| 190 Profile output; |
| 191 EXPECT_EQ(input.expect_success, |
| 192 proxy->BounceProfile(input.profile, &output)); |
| 193 |
| 194 if (!input.expect_success) |
| 195 continue; |
| 196 |
| 197 EXPECT_EQ(input.profile.modules, output.modules); |
| 198 EXPECT_EQ(input.profile.samples, output.samples); |
| 199 EXPECT_EQ(input.profile.profile_duration, output.profile_duration); |
| 200 EXPECT_EQ(input.profile.sampling_period, output.sampling_period); |
| 201 } |
| 202 } |
| 203 |
| 204 } // namespace metrics |
OLD | NEW |