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

Side by Side Diff: test/unittests/counters-unittest.cc

Issue 2511093002: [counters] RuntimeStats: fix wrong bookkeeping when dynamically changing counters. (Closed)
Patch Set: moar tests Created 4 years, 1 month 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
« src/counters-inl.h ('K') | « src/counters-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 6
7 #include "src/counters-inl.h"
7 #include "src/counters.h" 8 #include "src/counters.h"
8 #include "src/handles-inl.h" 9 #include "src/handles-inl.h"
9 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
11 #include "src/tracing/tracing-category-observer.h"
10 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
11 13
12 namespace v8 { 14 namespace v8 {
13 namespace internal { 15 namespace internal {
14 16
15 namespace { 17 namespace {
16 18
17 class MockHistogram : public Histogram { 19 class MockHistogram : public Histogram {
18 public: 20 public:
19 void AddSample(int value) { samples_.push_back(value); } 21 void AddSample(int value) { samples_.push_back(value); }
(...skipping 15 matching lines...) Expand all
35 aggregated_.AddSample(current_ms, current_value); 37 aggregated_.AddSample(current_ms, current_value);
36 } 38 }
37 39
38 std::vector<int>* samples() { return mock_.samples(); } 40 std::vector<int>* samples() { return mock_.samples(); }
39 41
40 private: 42 private:
41 AggregatedMemoryHistogram<MockHistogram> aggregated_; 43 AggregatedMemoryHistogram<MockHistogram> aggregated_;
42 MockHistogram mock_; 44 MockHistogram mock_;
43 }; 45 };
44 46
47 class RuntimeCallStatsTest : public ::testing::Test {
48 public:
49 RuntimeCallStatsTest() {
50 FLAG_runtime_stats =
51 v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE;
52 }
53 virtual ~RuntimeCallStatsTest() {}
54
55 RuntimeCallStats* stats() { return &stats_; }
56 RuntimeCallStats::CounterId counter_id() {
57 return &RuntimeCallStats::TestCounter1;
58 }
59 RuntimeCallStats::CounterId counter_id2() {
60 return &RuntimeCallStats::TestCounter2;
61 }
62 RuntimeCallCounter* counter() { return &(stats()->*counter_id()); }
63 RuntimeCallCounter* counter2() { return &(stats()->*counter_id2()); }
64 void Sleep(int32_t microseconds) {
Igor Sheludko 2016/11/18 18:56:27 Probably you don't need microseconds precision. WD
65 base::OS::Sleep(base::TimeDelta::FromMicroseconds(microseconds));
66 }
67
68 const uint32_t kTimeMargin = 150;
Igor Sheludko 2016/11/18 18:56:28 Maybe kEpsilonMs = 50;
69
70 private:
71 RuntimeCallStats stats_;
72 };
73
45 } // namespace 74 } // namespace
46 75
47 76
48 TEST_F(AggregatedMemoryHistogramTest, OneSample1) { 77 TEST_F(AggregatedMemoryHistogramTest, OneSample1) {
49 FLAG_histogram_interval = 10; 78 FLAG_histogram_interval = 10;
50 AddSample(10, 1000); 79 AddSample(10, 1000);
51 AddSample(20, 1000); 80 AddSample(20, 1000);
52 EXPECT_EQ(1U, samples()->size()); 81 EXPECT_EQ(1U, samples()->size());
53 EXPECT_EQ(1000, (*samples())[0]); 82 EXPECT_EQ(1000, (*samples())[0]);
54 } 83 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 FLAG_histogram_interval = 10; 217 FLAG_histogram_interval = 10;
189 const int kMaxSamples = 1000; 218 const int kMaxSamples = 1000;
190 AddSample(0, 0); 219 AddSample(0, 0);
191 AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples)); 220 AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples));
192 EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size()); 221 EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size());
193 for (int i = 0; i < kMaxSamples; i++) { 222 for (int i = 0; i < kMaxSamples; i++) {
194 EXPECT_EQ(i * 10 + 5, (*samples())[i]); 223 EXPECT_EQ(i * 10 + 5, (*samples())[i]);
195 } 224 }
196 } 225 }
197 226
227 #define EXPECT_IN_RANGE(start, value, end) \
228 EXPECT_LE(start, value); \
229 EXPECT_GE(end, value)
230
231 TEST_F(RuntimeCallStatsTest, RuntimeCallTimer) {
232 RuntimeCallTimer timer;
233
234 RuntimeCallStats::Enter(stats(), &timer, counter_id());
235 EXPECT_EQ(counter(), timer.counter());
236 EXPECT_EQ(nullptr, timer.parent());
237 EXPECT_TRUE(timer.timer().IsStarted());
238 EXPECT_EQ(&timer, stats()->current_timer());
239
240 Sleep(500);
Igor Sheludko 2016/11/18 18:56:27 Probably 100-300 ms should be enough...
241
242 RuntimeCallStats::Leave(stats(), &timer);
243 EXPECT_FALSE(timer.timer().IsStarted());
244 EXPECT_EQ(1, counter()->count);
245 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
Igor Sheludko 2016/11/18 18:56:28 ... because what we are testing here and below is
246 }
247
248 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerSubTimer) {
249 RuntimeCallTimer timer;
250 RuntimeCallTimer timer2;
251
252 RuntimeCallStats::Enter(stats(), &timer, counter_id());
253 EXPECT_TRUE(timer.timer().IsStarted());
254 EXPECT_FALSE(timer2.timer().IsStarted());
255 EXPECT_EQ(counter(), timer.counter());
256 EXPECT_EQ(nullptr, timer.parent());
257 EXPECT_EQ(&timer, stats()->current_timer());
258
Igor Sheludko 2016/11/18 18:56:28 Maybe Sleep here as well.
259 RuntimeCallStats::Enter(stats(), &timer2, counter_id2());
260 EXPECT_TRUE(timer.timer().IsStarted());
261 EXPECT_TRUE(timer2.timer().IsStarted());
262 EXPECT_EQ(counter(), timer.counter());
263 EXPECT_EQ(counter2(), timer2.counter());
264 EXPECT_EQ(nullptr, timer.parent());
265 EXPECT_EQ(&timer, timer2.parent());
266 EXPECT_EQ(&timer2, stats()->current_timer());
267
268 Sleep(500);
269 RuntimeCallStats::Leave(stats(), &timer2);
270
271 // The subtimer subtracts its time from the parent timer.
272 EXPECT_TRUE(timer.timer().IsStarted());
273 EXPECT_FALSE(timer2.timer().IsStarted());
274 EXPECT_EQ(0, counter()->count);
275 EXPECT_EQ(1, counter2()->count);
276 EXPECT_EQ(-counter()->time, counter()->time);
Igor Sheludko 2016/11/18 18:56:28 We never subtract from time. This should start fai
277 EXPECT_IN_RANGE(500, counter2()->time.InMicroseconds(), 500 + kTimeMargin);
278 EXPECT_EQ(&timer, stats()->current_timer());
279
280 Sleep(500);
Igor Sheludko 2016/11/18 18:56:28 Maybe you can make the numbers different so that w
281
282 RuntimeCallStats::Leave(stats(), &timer);
283 EXPECT_FALSE(timer.timer().IsStarted());
284 EXPECT_EQ(1, counter()->count);
285 EXPECT_EQ(1, counter2()->count);
286 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
287 EXPECT_IN_RANGE(500, counter2()->time.InMicroseconds(), 500 + kTimeMargin);
288 EXPECT_EQ(nullptr, stats()->current_timer());
289 }
290
291 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerRecursive) {
292 RuntimeCallTimer timer;
293 RuntimeCallTimer timer2;
294
295 RuntimeCallStats::Enter(stats(), &timer, counter_id());
296 EXPECT_EQ(counter(), timer.counter());
297 EXPECT_EQ(nullptr, timer.parent());
298 EXPECT_TRUE(timer.timer().IsStarted());
299 EXPECT_EQ(&timer, stats()->current_timer());
300
301 RuntimeCallStats::Enter(stats(), &timer2, counter_id());
302 EXPECT_EQ(counter(), timer2.counter());
303 EXPECT_EQ(&timer, timer2.parent());
304 EXPECT_TRUE(timer2.timer().IsStarted());
305 EXPECT_EQ(&timer2, stats()->current_timer());
306
307 Sleep(500);
308
309 RuntimeCallStats::Leave(stats(), &timer2);
310 EXPECT_FALSE(timer2.timer().IsStarted());
311 EXPECT_TRUE(timer.timer().IsStarted());
312 EXPECT_EQ(1, counter()->count);
313 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
314
315 Sleep(500);
316
317 RuntimeCallStats::Leave(stats(), &timer);
318 EXPECT_FALSE(timer.timer().IsStarted());
319 EXPECT_EQ(2, counter()->count);
320 EXPECT_IN_RANGE(1000, counter()->time.InMicroseconds(),
321 1000 + 2 * kTimeMargin);
322 }
323
324 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScope) {
325 {
326 RuntimeCallTimerScope scope(stats(), counter_id());
327 Sleep(500);
328 }
Igor Sheludko 2016/11/18 18:56:27 Maybe Sleep between scopes too to ensure that this
329 EXPECT_EQ(1, counter()->count);
330 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
331 {
332 RuntimeCallTimerScope scope(stats(), counter_id());
333 Sleep(500);
334 }
335 EXPECT_EQ(2, counter()->count);
336 EXPECT_IN_RANGE(1000, counter()->time.InMicroseconds(),
337 1000 + 2 * kTimeMargin);
338 }
339
340 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScopeRecursive) {
341 {
342 RuntimeCallTimerScope scope(stats(), counter_id());
343 Sleep(500);
344 EXPECT_EQ(0, counter()->count);
345 EXPECT_EQ(0, counter()->time.InMicroseconds());
346 {
347 RuntimeCallTimerScope scope(stats(), counter_id());
348 Sleep(500);
349 }
350 EXPECT_EQ(1, counter()->count);
351 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
352 }
353 EXPECT_EQ(2, counter()->count);
354 EXPECT_IN_RANGE(1000, counter()->time.InMicroseconds(),
355 1000 + 2 * kTimeMargin);
356 }
357
358 TEST_F(RuntimeCallStatsTest, RenameTimer) {
359 {
360 RuntimeCallTimerScope scope(stats(), counter_id());
361 Sleep(500);
362 EXPECT_EQ(0, counter()->count);
363 EXPECT_EQ(0, counter2()->count);
364 EXPECT_EQ(0, counter()->time.InMicroseconds());
365 EXPECT_EQ(0, counter2()->time.InMicroseconds());
366 {
367 RuntimeCallTimerScope scope(stats(), counter_id());
368 Sleep(500);
369 }
370 CHANGE_CURRENT_RUNTIME_COUNTER(stats(), TestCounter2);
371 EXPECT_EQ(1, counter()->count);
372 EXPECT_EQ(0, counter2()->count);
373 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
374 EXPECT_IN_RANGE(0, counter2()->time.InMicroseconds(), 0);
375 }
376 EXPECT_EQ(1, counter()->count);
377 EXPECT_EQ(1, counter2()->count);
378 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
379 EXPECT_IN_RANGE(500, counter2()->time.InMicroseconds(), 500 + kTimeMargin);
380 }
381
382 TEST_F(RuntimeCallStatsTest, PrintAndSnapshot) {
383 uint32_t offset = 200;
384 {
385 RuntimeCallTimerScope scope(stats(), counter_id());
386 Sleep(500);
387 EXPECT_EQ(0, counter()->count);
388 EXPECT_EQ(0, counter()->time.InMicroseconds());
389 {
390 RuntimeCallTimerScope scope(stats(), counter_id2());
391 EXPECT_EQ(0, counter2()->count);
392 EXPECT_EQ(0, counter2()->time.InMicroseconds());
393 Sleep(500);
394
395 // This calls Snapshot on the current active timer and sychronizes and
396 // commits the whole timer stack.
397 stats()->Print(std::cerr);
Igor Sheludko 2016/11/18 18:56:28 Test driver does not like a lot of output. You may
398 EXPECT_EQ(0, counter()->count);
399 EXPECT_EQ(0, counter2()->count);
400 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
401 EXPECT_IN_RANGE(500, counter2()->time.InMicroseconds(),
402 500 + kTimeMargin);
403 Sleep(500);
404 }
405 EXPECT_EQ(0, counter()->count);
406 EXPECT_EQ(1, counter2()->count);
407 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
408 EXPECT_IN_RANGE(1000 + offset, counter2()->time.InMicroseconds(),
409 1000 + offset + 2 * kTimeMargin);
410 }
411 EXPECT_EQ(1, counter()->count);
412 EXPECT_EQ(1, counter2()->count);
413 EXPECT_IN_RANGE(500, counter()->time.InMicroseconds(), 500 + kTimeMargin);
414 EXPECT_IN_RANGE(1000, counter2()->time.InMicroseconds(),
415 1000 + offset + 2 * kTimeMargin);
416 }
198 417
199 } // namespace internal 418 } // namespace internal
200 } // namespace v8 419 } // namespace v8
OLDNEW
« src/counters-inl.h ('K') | « src/counters-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698