Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: chrome/browser/metrics/perf_provider_chromeos_unittest.cc

Issue 1218583002: metrics: Add dbus interface for GetRandomPerfOutput (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed remaining comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/metrics/perf_provider_chromeos.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "chrome/browser/metrics/windowed_incognito_observer.h"
13 #include "chromeos/dbus/dbus_thread_manager.h"
14 #include "chromeos/login/login_state.h"
15 #include "components/metrics/proto/sampled_profile.pb.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace metrics {
19
20 namespace {
21
22 // Return values for perf.
23 const int kPerfSuccess = 0;
24 const int kPerfFailure = 1;
25
26 // Converts a protobuf to serialized format as a byte vector.
27 std::vector<uint8_t> SerializeMessageToVector(
28 const google::protobuf::MessageLite& message) {
29 std::vector<uint8_t> result(message.ByteSize());
30 message.SerializeToArray(result.data(), result.size());
31 return result;
32 }
33
34 // Returns an example PerfDataProto. The contents don't have to make sense. They
35 // just need to constitute a semantically valid protobuf.
36 // |proto| is an output parameter that will contain the created protobuf.
37 // Also returns the serialized form of |*proto| as a byte vector.
38 std::vector<uint8_t> GetExamplePerfDataProto(PerfDataProto* proto) {
39 proto->set_timestamp_sec(1435604013); // Time since epoch in seconds->
40
41 PerfDataProto_PerfFileAttr* file_attr = proto->add_file_attrs();
42 file_attr->add_ids(61);
43 file_attr->add_ids(62);
44 file_attr->add_ids(63);
45
46 PerfDataProto_PerfEventAttr* attr = file_attr->mutable_attr();
47 attr->set_type(1);
48 attr->set_size(2);
49 attr->set_config(3);
50 attr->set_sample_period(4);
51 attr->set_sample_freq(5);
52
53 PerfDataProto_PerfEventStats* stats = proto->mutable_stats();
54 stats->set_num_events_read(100);
55 stats->set_num_sample_events(200);
56 stats->set_num_mmap_events(300);
57 stats->set_num_fork_events(400);
58 stats->set_num_exit_events(500);
59
60 return SerializeMessageToVector(*proto);
61 }
62
63 // Returns an example PerfStatProto. The contents don't have to make sense. They
64 // just need to constitute a semantically valid protobuf.
65 // |result| is an output parameter that will contain the created protobuf.
66 // |result_raw| is |result| in serialized format.
67 std::vector<uint8_t> GetExamplePerfStatProto(PerfStatProto* proto) {
68 proto->set_command_line(
69 "perf stat -a -e cycles -e instructions -e branches -- sleep 2");
70
71 PerfStatProto_PerfStatLine* line1 = proto->add_line();
72 line1->set_time_ms(1000);
73 line1->set_count(2000);
74 line1->set_event("cycles");
75
76 PerfStatProto_PerfStatLine* line2 = proto->add_line();
77 line2->set_time_ms(2000);
78 line2->set_count(5678);
79 line2->set_event("instructions");
80
81 PerfStatProto_PerfStatLine* line3 = proto->add_line();
82 line3->set_time_ms(3000);
83 line3->set_count(9999);
84 line3->set_event("branches");
85
86 return SerializeMessageToVector(*proto);
87 }
88
89 // Allows testing of PerfProvider behavior when an incognito window is opened.
90 class TestIncognitoObserver : public WindowedIncognitoObserver {
91 public:
92 void set_incognito_launched(bool value) {
93 incognito_launched_ = value;
94 }
95 };
Ilya Sherman 2015/07/02 00:40:16 nit: DISALLOW_COPY_AND_ASSIGN
Simon Que 2015/07/02 18:53:02 Done.
96
97 // Allows access to PerfProvider::ParseOutputProtoIfValid() for testing.
98 class PerfProviderForTesting : public PerfProvider {
Ilya Sherman 2015/07/02 00:40:16 Optional nit: I'd name this "TestPerfProvider", fo
Simon Que 2015/07/02 18:53:02 Done.
99 public:
100 void ParseOutputProtoIfValidForTesting(
101 const scoped_ptr<TestIncognitoObserver>& incognito_observer,
Ilya Sherman 2015/07/02 00:40:16 I'd expect that you could replace this entire meth
Simon Que 2015/07/06 00:50:34 Done.
102 const SampledProfile& sampled_profile,
103 int result,
104 const std::vector<uint8>& perf_data,
105 const std::vector<uint8>& perf_stat) {
106 // Create copies of |incognito_observer| and |sampled_profile| to pass to
107 // PerfProvider::ParseOutputProtoIfValid.
108 scoped_ptr<WindowedIncognitoObserver> incognito_observer_copy(
109 new TestIncognitoObserver(*incognito_observer));
Ilya Sherman 2015/07/02 00:40:16 Why do you make a copy, rather than passing in the
Simon Que 2015/07/02 18:53:02 The object will get destroyed by ParseOutputProtoI
110 scoped_ptr<SampledProfile> sampled_profile_copy(
111 new SampledProfile(sampled_profile));
Ilya Sherman 2015/07/02 00:40:16 Ditto.
112
113 ParseOutputProtoIfValid(incognito_observer_copy.Pass(),
114 sampled_profile_copy.Pass(),
115 result,
116 perf_data,
117 perf_stat);
118
119 // PerfProvider does not provide a direct accessor for the SampledProfiles
120 // stored by ParseOutputProtoIfValid. Instead, use the public method
121 // GetSampledProfiles() to append them to |stored_profiles_|.
122 std::vector<SampledProfile> sampled_profiles;
123 if (GetSampledProfiles(&sampled_profiles)) {
124 for (SampledProfile& profile : sampled_profiles) {
125 stored_profiles_.push_back(SampledProfile());
126 stored_profiles_.back().Swap(&profile);
127 }
128 }
Ilya Sherman 2015/07/02 00:40:16 Please call GetSampledProfiles() directly from the
Simon Que 2015/07/02 18:53:01 Done.
129 }
130
131 // Used to accumulate SampledProfiles containing perf data passed into
132 // ParseOutputProtoIfValidForTesting().
133 const std::vector<SampledProfile> stored_profiles() const {
Ilya Sherman 2015/07/02 00:40:16 nit: I'd recommend omitting this method entirely;
Simon Que 2015/07/02 18:53:01 Done.
134 return stored_profiles_;
135 }
136
137 private:
138 std::vector<SampledProfile> stored_profiles_;
139 };
Ilya Sherman 2015/07/02 00:40:16 nit: DISALLOW_COPY_AND_ASSIGN
Simon Que 2015/07/02 18:53:02 Done.
140
141 } // namespace
142
143 class PerfProviderTest : public testing::Test {
144 public:
145 PerfProviderTest() {
146 perf_data_raw_ = GetExamplePerfDataProto(&perf_data_proto_);
147 perf_stat_raw_ = GetExamplePerfStatProto(&perf_stat_proto_);
148 }
149
150 void SetUp() override {
151 // PerfProvider requires chromeos::LoginState and
152 // chromeos::DBusThreadManagerto be initialized.
153 chromeos::LoginState::Initialize();
154 chromeos::DBusThreadManager::Initialize();
155
156 perf_provider_.reset(new PerfProviderForTesting);
157 incognito_observer_.reset(new TestIncognitoObserver);
158 }
159
160 void TearDown() override {
161 perf_provider_.reset();
162 chromeos::DBusThreadManager::Shutdown();
163 chromeos::LoginState::Shutdown();
164 }
165
166 protected:
167 scoped_ptr<PerfProviderForTesting> perf_provider_;
168
169 // For simulating whether an incognito window is open.
170 scoped_ptr<TestIncognitoObserver> incognito_observer_;
171
172 // These store example perf data/stat protobufs for testing.
173 PerfDataProto perf_data_proto_;
174 PerfStatProto perf_stat_proto_;
175 // These are the equivalents of the above protobufs as serialized raw data.
176 std::vector<uint8_t> perf_data_raw_;
177 std::vector<uint8_t> perf_stat_raw_;
Ilya Sherman 2015/07/02 00:40:16 What I meant was: Why do you need to store the pro
Simon Que 2015/07/02 18:53:02 Done.
178
179 DISALLOW_COPY_AND_ASSIGN(PerfProviderTest);
180 };
181
182 TEST_F(PerfProviderTest, CheckSetup) {
183 EXPECT_GT(perf_data_proto_.ByteSize(), 0);
184 EXPECT_GT(perf_stat_proto_.ByteSize(), 0);
185 EXPECT_FALSE(perf_data_raw_.empty());
186 EXPECT_FALSE(perf_stat_raw_.empty());
187
188 EXPECT_TRUE(perf_provider_->stored_profiles().empty());
189 EXPECT_FALSE(incognito_observer_->incognito_launched());
190 }
191
192 TEST_F(PerfProviderTest, PerfDataProtoOnly) {
193 SampledProfile sampled_profile;
194 sampled_profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
195
196 perf_provider_->ParseOutputProtoIfValidForTesting(
197 incognito_observer_,
198 sampled_profile,
199 kPerfSuccess,
200 perf_data_raw_,
201 std::vector<uint8_t>());
202 ASSERT_EQ(1U, perf_provider_->stored_profiles().size());
203
204 const SampledProfile& profile = perf_provider_->stored_profiles()[0];
205 EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile.trigger_event());
206 EXPECT_GT(profile.ms_after_login(), 0);
207
208 ASSERT_TRUE(profile.has_perf_data());
209 EXPECT_FALSE(profile.has_perf_stat());
210 EXPECT_EQ(perf_data_raw_, SerializeMessageToVector(profile.perf_data()));
Simon Que 2015/07/01 22:16:07 Calling ByteSize() in SerializeMessageToVector() f
Ilya Sherman 2015/07/02 00:40:16 I'm also not sure. You could try gdb/lldb.
Simon Que 2015/07/02 18:53:01 Don't see this anymore.
211 }
212
213 TEST_F(PerfProviderTest, PerfStatProtoOnly) {
214 SampledProfile sampled_profile;
215 sampled_profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
216
217 perf_provider_->ParseOutputProtoIfValidForTesting(
218 incognito_observer_,
219 sampled_profile,
220 kPerfSuccess,
221 std::vector<uint8_t>(),
222 perf_stat_raw_);
223 ASSERT_EQ(1U, perf_provider_->stored_profiles().size());
224
225 const SampledProfile& profile = perf_provider_->stored_profiles()[0];
226 EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile.trigger_event());
227 EXPECT_GT(profile.ms_after_login(), 0);
228
229 EXPECT_FALSE(profile.has_perf_data());
230 ASSERT_TRUE(profile.has_perf_stat());
231 EXPECT_EQ(perf_stat_raw_, SerializeMessageToVector(profile.perf_stat()));
232 }
233
234 TEST_F(PerfProviderTest, BothPerfDataProtoAndPerfStatProto) {
235 SampledProfile sampled_profile;
236 sampled_profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
237
238 perf_provider_->ParseOutputProtoIfValidForTesting(
239 incognito_observer_,
240 sampled_profile,
241 kPerfSuccess,
242 perf_data_raw_,
243 perf_stat_raw_);
244 ASSERT_TRUE(perf_provider_->stored_profiles().empty());
245 }
246
247 TEST_F(PerfProviderTest, InvalidPerfOutputResult) {
248 SampledProfile sampled_profile;
249 sampled_profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
250
251 perf_provider_->ParseOutputProtoIfValidForTesting(
252 incognito_observer_,
253 sampled_profile,
254 kPerfFailure,
255 perf_data_raw_,
256 std::vector<uint8_t>());
257
258 // Should not have been stored.
259 EXPECT_TRUE(perf_provider_->stored_profiles().empty());
260 }
261
262 // Change |sampled_profile| between calls to ParseOutputProtoIfValid().
263 TEST_F(PerfProviderTest, MultipleCalls) {
264 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
265 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
266
267 perf_provider_->ParseOutputProtoIfValidForTesting(
268 incognito_observer_,
269 *sampled_profile,
270 kPerfSuccess,
271 perf_data_raw_,
272 std::vector<uint8_t>());
273 EXPECT_EQ(1U, perf_provider_->stored_profiles().size());
274
275 sampled_profile.reset(new SampledProfile);
276 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION);
277 sampled_profile->set_ms_after_login(23456);
278 sampled_profile->set_ms_after_restore(3000);
279 perf_provider_->ParseOutputProtoIfValidForTesting(
280 incognito_observer_,
281 *sampled_profile,
282 kPerfSuccess,
283 std::vector<uint8_t>(),
284 perf_stat_raw_);
285 EXPECT_EQ(2U, perf_provider_->stored_profiles().size());
286
287 sampled_profile.reset(new SampledProfile);
288 sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND);
289 sampled_profile->set_ms_after_login(34567);
290 sampled_profile->set_suspend_duration_ms(60000);
291 sampled_profile->set_ms_after_resume(1500);
292 perf_provider_->ParseOutputProtoIfValidForTesting(
293 incognito_observer_,
294 *sampled_profile,
295 kPerfSuccess,
296 perf_data_raw_,
297 std::vector<uint8_t>());
298 EXPECT_EQ(3U, perf_provider_->stored_profiles().size());
299
300 sampled_profile.reset(new SampledProfile);
301 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
302 perf_provider_->ParseOutputProtoIfValidForTesting(
303 incognito_observer_,
304 *sampled_profile,
305 kPerfSuccess,
306 std::vector<uint8_t>(),
307 perf_stat_raw_);
308 ASSERT_EQ(4U, perf_provider_->stored_profiles().size());
309
310 const SampledProfile& profile1 = perf_provider_->stored_profiles()[0];
311 EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile1.trigger_event());
312 EXPECT_GT(profile1.ms_after_login(), 0);
313 ASSERT_TRUE(profile1.has_perf_data());
314 EXPECT_FALSE(profile1.has_perf_stat());
315 EXPECT_EQ(perf_data_raw_, SerializeMessageToVector(profile1.perf_data()));
316
317 const SampledProfile& profile2 = perf_provider_->stored_profiles()[1];
318 EXPECT_EQ(SampledProfile::RESTORE_SESSION, profile2.trigger_event());
319 EXPECT_GT(profile2.ms_after_login(), 0);
320 EXPECT_EQ(3000, profile2.ms_after_restore());
321 EXPECT_FALSE(profile2.has_perf_data());
322 ASSERT_TRUE(profile2.has_perf_stat());
323 EXPECT_EQ(perf_stat_raw_, SerializeMessageToVector(profile2.perf_stat()));
324
325 const SampledProfile& profile3 = perf_provider_->stored_profiles()[2];
326 EXPECT_EQ(SampledProfile::RESUME_FROM_SUSPEND, profile3.trigger_event());
327 EXPECT_GT(profile3.ms_after_login(), 0);
328 EXPECT_EQ(60000, profile3.suspend_duration_ms());
329 EXPECT_EQ(1500, profile3.ms_after_resume());
330 ASSERT_TRUE(profile3.has_perf_data());
331 EXPECT_FALSE(profile3.has_perf_stat());
332 EXPECT_EQ(perf_data_raw_, SerializeMessageToVector(profile3.perf_data()));
333
334 const SampledProfile& profile4 = perf_provider_->stored_profiles()[3];
335 EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile4.trigger_event());
336 EXPECT_GT(profile4.ms_after_login(), 0);
337 EXPECT_FALSE(profile4.has_perf_data());
338 ASSERT_TRUE(profile4.has_perf_stat());
339 EXPECT_EQ(perf_stat_raw_, SerializeMessageToVector(profile4.perf_stat()));
340 }
341
342 // Simulate opening and closing of incognito window in between calls to
343 // ParseOutputProtoIfValid().
344 TEST_F(PerfProviderTest, IncognitoWindowOpened) {
345 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
346 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
347
348 perf_provider_->ParseOutputProtoIfValidForTesting(
349 incognito_observer_,
350 *sampled_profile,
351 kPerfSuccess,
352 perf_data_raw_,
353 std::vector<uint8_t>());
354 EXPECT_EQ(1U, perf_provider_->stored_profiles().size());
355
356 sampled_profile.reset(new SampledProfile);
357 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION);
358 sampled_profile->set_ms_after_login(23456);
359 sampled_profile->set_ms_after_restore(3000);
360 perf_provider_->ParseOutputProtoIfValidForTesting(
361 incognito_observer_,
362 *sampled_profile,
363 kPerfSuccess,
364 std::vector<uint8_t>(),
365 perf_stat_raw_);
366 EXPECT_EQ(2U, perf_provider_->stored_profiles().size());
367
368 // An incognito window opens.
369 incognito_observer_->set_incognito_launched(true);
370
371 sampled_profile.reset(new SampledProfile);
372 sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND);
373 perf_provider_->ParseOutputProtoIfValidForTesting(
374 incognito_observer_,
375 *sampled_profile,
376 kPerfSuccess,
377 perf_data_raw_,
378 std::vector<uint8_t>());
379 EXPECT_EQ(2U, perf_provider_->stored_profiles().size());
380
381 sampled_profile.reset(new SampledProfile);
382 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
383 perf_provider_->ParseOutputProtoIfValidForTesting(
384 incognito_observer_,
385 *sampled_profile,
386 kPerfSuccess,
387 std::vector<uint8_t>(),
388 perf_stat_raw_);
389 ASSERT_EQ(2U, perf_provider_->stored_profiles().size());
390
391 // Incognito window closes, should be good to go again.
392 incognito_observer_->set_incognito_launched(false);
393
394 sampled_profile.reset(new SampledProfile);
395 sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND);
396 sampled_profile->set_ms_after_login(34567);
397 sampled_profile->set_suspend_duration_ms(60000);
398 sampled_profile->set_ms_after_resume(1500);
399 perf_provider_->ParseOutputProtoIfValidForTesting(
400 incognito_observer_,
401 *sampled_profile,
402 kPerfSuccess,
403 perf_data_raw_,
404 std::vector<uint8_t>());
405 EXPECT_EQ(3U, perf_provider_->stored_profiles().size());
406
407 const SampledProfile& profile1 = perf_provider_->stored_profiles()[0];
408 EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile1.trigger_event());
409 EXPECT_GT(profile1.ms_after_login(), 0);
410 ASSERT_TRUE(profile1.has_perf_data());
411 EXPECT_FALSE(profile1.has_perf_stat());
412 EXPECT_EQ(perf_data_raw_, SerializeMessageToVector(profile1.perf_data()));
413
414 const SampledProfile& profile2 = perf_provider_->stored_profiles()[1];
415 EXPECT_EQ(SampledProfile::RESTORE_SESSION, profile2.trigger_event());
416 EXPECT_GT(profile2.ms_after_login(), 0);
417 EXPECT_EQ(3000, profile2.ms_after_restore());
418 EXPECT_FALSE(profile2.has_perf_data());
419 ASSERT_TRUE(profile2.has_perf_stat());
420 EXPECT_EQ(perf_stat_raw_, SerializeMessageToVector(profile2.perf_stat()));
421
422 const SampledProfile& profile3 = perf_provider_->stored_profiles()[2];
423 EXPECT_EQ(SampledProfile::RESUME_FROM_SUSPEND, profile3.trigger_event());
424 EXPECT_GT(profile3.ms_after_login(), 0);
425 EXPECT_EQ(60000, profile3.suspend_duration_ms());
426 EXPECT_EQ(1500, profile3.ms_after_resume());
427 ASSERT_TRUE(profile3.has_perf_data());
428 EXPECT_FALSE(profile3.has_perf_stat());
429 EXPECT_EQ(perf_data_raw_, SerializeMessageToVector(profile3.perf_data()));
430 }
431
432 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698