Remove unused parameter.
[chromium-blink-merge.git] / base / tracked_objects_unittest.cc
blob5455fef72c1ccdf76020ea047cea92bd626fc8e7
1 // Copyright (c) 2012 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 // Test of classes in the tracked_objects.h classes.
7 #include "base/tracked_objects.h"
9 #include <stddef.h>
11 #include "base/memory/scoped_ptr.h"
12 #include "base/process/process_handle.h"
13 #include "base/time/time.h"
14 #include "base/tracking_info.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 const int kLineNumber = 1776;
18 const char kFile[] = "FixedUnitTestFileName";
19 const char kWorkerThreadName[] = "WorkerThread-1";
20 const char kMainThreadName[] = "SomeMainThreadName";
21 const char kStillAlive[] = "Still_Alive";
23 namespace tracked_objects {
25 class TrackedObjectsTest : public testing::Test {
26 protected:
27 TrackedObjectsTest() {
28 // On entry, leak any database structures in case they are still in use by
29 // prior threads.
30 ThreadData::ShutdownSingleThreadedCleanup(true);
32 test_time_ = 0;
33 ThreadData::SetAlternateTimeSource(&TrackedObjectsTest::GetTestTime);
34 ThreadData::now_function_is_time_ = true;
37 ~TrackedObjectsTest() override {
38 // We should not need to leak any structures we create, since we are
39 // single threaded, and carefully accounting for items.
40 ThreadData::ShutdownSingleThreadedCleanup(false);
43 // Reset the profiler state.
44 void Reset() {
45 ThreadData::ShutdownSingleThreadedCleanup(false);
46 test_time_ = 0;
49 // Simulate a birth on the thread named |thread_name|, at the given
50 // |location|.
51 void TallyABirth(const Location& location, const std::string& thread_name) {
52 // If the |thread_name| is empty, we don't initialize system with a thread
53 // name, so we're viewed as a worker thread.
54 if (!thread_name.empty())
55 ThreadData::InitializeThreadContext(kMainThreadName);
57 // Do not delete |birth|. We don't own it.
58 Births* birth = ThreadData::TallyABirthIfActive(location);
60 if (ThreadData::status() == ThreadData::DEACTIVATED)
61 EXPECT_EQ(reinterpret_cast<Births*>(NULL), birth);
62 else
63 EXPECT_NE(reinterpret_cast<Births*>(NULL), birth);
66 // Helper function to verify the most common test expectations.
67 void ExpectSimpleProcessData(const ProcessDataSnapshot& process_data,
68 const std::string& function_name,
69 const std::string& birth_thread,
70 const std::string& death_thread,
71 int count,
72 int run_ms,
73 int queue_ms) {
74 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
75 auto it = process_data.phased_process_data_snapshots.find(0);
76 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
77 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
79 ASSERT_EQ(1u, process_data_phase.tasks.size());
81 EXPECT_EQ(kFile, process_data_phase.tasks[0].birth.location.file_name);
82 EXPECT_EQ(function_name,
83 process_data_phase.tasks[0].birth.location.function_name);
84 EXPECT_EQ(kLineNumber,
85 process_data_phase.tasks[0].birth.location.line_number);
87 EXPECT_EQ(birth_thread, process_data_phase.tasks[0].birth.thread_name);
89 EXPECT_EQ(count, process_data_phase.tasks[0].death_data.count);
90 EXPECT_EQ(count * run_ms,
91 process_data_phase.tasks[0].death_data.run_duration_sum);
92 EXPECT_EQ(run_ms, process_data_phase.tasks[0].death_data.run_duration_max);
93 EXPECT_EQ(run_ms,
94 process_data_phase.tasks[0].death_data.run_duration_sample);
95 EXPECT_EQ(count * queue_ms,
96 process_data_phase.tasks[0].death_data.queue_duration_sum);
97 EXPECT_EQ(queue_ms,
98 process_data_phase.tasks[0].death_data.queue_duration_max);
99 EXPECT_EQ(queue_ms,
100 process_data_phase.tasks[0].death_data.queue_duration_sample);
102 EXPECT_EQ(death_thread, process_data_phase.tasks[0].death_thread_name);
104 EXPECT_EQ(0u, process_data_phase.descendants.size());
106 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
109 // Sets time that will be returned by ThreadData::Now().
110 static void SetTestTime(unsigned int test_time) { test_time_ = test_time; }
112 private:
113 // Returns test time in milliseconds.
114 static unsigned int GetTestTime() { return test_time_; }
116 // Test time in milliseconds.
117 static unsigned int test_time_;
120 // static
121 unsigned int TrackedObjectsTest::test_time_;
123 TEST_F(TrackedObjectsTest, TaskStopwatchNoStartStop) {
124 if (!ThreadData::InitializeAndSetTrackingStatus(
125 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
126 return;
129 // Check that creating and destroying a stopwatch without starting it doesn't
130 // crash.
131 TaskStopwatch stopwatch;
134 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) {
135 // Minimal test doesn't even create any tasks.
136 if (!ThreadData::InitializeAndSetTrackingStatus(
137 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
138 return;
141 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
142 ThreadData* data = ThreadData::Get();
143 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
144 ASSERT_TRUE(data);
145 EXPECT_FALSE(data->next());
146 EXPECT_EQ(data, ThreadData::Get());
147 ThreadData::BirthMap birth_map;
148 ThreadData::DeathMap death_map;
149 ThreadData::ParentChildSet parent_child_set;
150 data->SnapshotMaps(&birth_map, &death_map, &parent_child_set);
151 EXPECT_EQ(0u, birth_map.size());
152 EXPECT_EQ(0u, death_map.size());
153 EXPECT_EQ(0u, parent_child_set.size());
155 // Clean up with no leaking.
156 Reset();
158 // Do it again, just to be sure we reset state completely.
159 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(
160 ThreadData::PROFILING_CHILDREN_ACTIVE));
161 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
162 data = ThreadData::Get();
163 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
164 ASSERT_TRUE(data);
165 EXPECT_FALSE(data->next());
166 EXPECT_EQ(data, ThreadData::Get());
167 birth_map.clear();
168 death_map.clear();
169 parent_child_set.clear();
170 data->SnapshotMaps(&birth_map, &death_map, &parent_child_set);
171 EXPECT_EQ(0u, birth_map.size());
172 EXPECT_EQ(0u, death_map.size());
173 EXPECT_EQ(0u, parent_child_set.size());
176 TEST_F(TrackedObjectsTest, TinyStartupShutdown) {
177 if (!ThreadData::InitializeAndSetTrackingStatus(
178 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
179 return;
182 // Instigate tracking on a single tracked object, on our thread.
183 const char kFunction[] = "TinyStartupShutdown";
184 Location location(kFunction, kFile, kLineNumber, NULL);
185 Births* first_birth = ThreadData::TallyABirthIfActive(location);
187 ThreadData* data = ThreadData::first();
188 ASSERT_TRUE(data);
189 EXPECT_FALSE(data->next());
190 EXPECT_EQ(data, ThreadData::Get());
191 ThreadData::BirthMap birth_map;
192 ThreadData::DeathMap death_map;
193 ThreadData::ParentChildSet parent_child_set;
194 data->SnapshotMaps(&birth_map, &death_map, &parent_child_set);
195 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
196 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth.
197 EXPECT_EQ(0u, death_map.size()); // No deaths.
198 EXPECT_EQ(0u, parent_child_set.size()); // No children.
201 // Now instigate another birth, while we are timing the run of the first
202 // execution.
203 ThreadData::PrepareForStartOfRun(first_birth);
204 // Create a child (using the same birth location).
205 // TrackingInfo will call TallyABirth() during construction.
206 const int32 start_time = 1;
207 base::TimeTicks kBogusBirthTime = base::TimeTicks() +
208 base::TimeDelta::FromMilliseconds(start_time);
209 base::TrackingInfo pending_task(location, kBogusBirthTime);
210 SetTestTime(1);
211 TaskStopwatch stopwatch;
212 stopwatch.Start();
213 // Finally conclude the outer run.
214 const int32 time_elapsed = 1000;
215 SetTestTime(start_time + time_elapsed);
216 stopwatch.Stop();
218 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, stopwatch);
220 birth_map.clear();
221 death_map.clear();
222 parent_child_set.clear();
223 data->SnapshotMaps(&birth_map, &death_map, &parent_child_set);
224 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
225 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births.
226 EXPECT_EQ(1u, death_map.size()); // 1 location.
227 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death.
228 if (ThreadData::TrackingParentChildStatus()) {
229 EXPECT_EQ(1u, parent_child_set.size()); // 1 child.
230 EXPECT_EQ(parent_child_set.begin()->first,
231 parent_child_set.begin()->second);
232 } else {
233 EXPECT_EQ(0u, parent_child_set.size()); // no stats.
236 // The births were at the same location as the one known death.
237 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first);
239 ProcessDataSnapshot process_data;
240 ThreadData::Snapshot(&process_data);
242 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
243 auto it = process_data.phased_process_data_snapshots.find(0);
244 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
245 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
246 ASSERT_EQ(1u, process_data_phase.tasks.size());
247 EXPECT_EQ(kFile, process_data_phase.tasks[0].birth.location.file_name);
248 EXPECT_EQ(kFunction,
249 process_data_phase.tasks[0].birth.location.function_name);
250 EXPECT_EQ(kLineNumber,
251 process_data_phase.tasks[0].birth.location.line_number);
252 EXPECT_EQ(kWorkerThreadName, process_data_phase.tasks[0].birth.thread_name);
253 EXPECT_EQ(1, process_data_phase.tasks[0].death_data.count);
254 EXPECT_EQ(time_elapsed,
255 process_data_phase.tasks[0].death_data.run_duration_sum);
256 EXPECT_EQ(time_elapsed,
257 process_data_phase.tasks[0].death_data.run_duration_max);
258 EXPECT_EQ(time_elapsed,
259 process_data_phase.tasks[0].death_data.run_duration_sample);
260 EXPECT_EQ(0, process_data_phase.tasks[0].death_data.queue_duration_sum);
261 EXPECT_EQ(0, process_data_phase.tasks[0].death_data.queue_duration_max);
262 EXPECT_EQ(0, process_data_phase.tasks[0].death_data.queue_duration_sample);
263 EXPECT_EQ(kWorkerThreadName, process_data_phase.tasks[0].death_thread_name);
265 if (ThreadData::TrackingParentChildStatus()) {
266 ASSERT_EQ(1u, process_data_phase.descendants.size());
267 EXPECT_EQ(kFile,
268 process_data_phase.descendants[0].parent.location.file_name);
269 EXPECT_EQ(kFunction,
270 process_data_phase.descendants[0].parent.location.function_name);
271 EXPECT_EQ(kLineNumber,
272 process_data_phase.descendants[0].parent.location.line_number);
273 EXPECT_EQ(kWorkerThreadName,
274 process_data_phase.descendants[0].parent.thread_name);
275 EXPECT_EQ(kFile,
276 process_data_phase.descendants[0].child.location.file_name);
277 EXPECT_EQ(kFunction,
278 process_data_phase.descendants[0].child.location.function_name);
279 EXPECT_EQ(kLineNumber,
280 process_data_phase.descendants[0].child.location.line_number);
281 EXPECT_EQ(kWorkerThreadName,
282 process_data_phase.descendants[0].child.thread_name);
283 } else {
284 EXPECT_EQ(0u, process_data_phase.descendants.size());
288 TEST_F(TrackedObjectsTest, DeathDataTest) {
289 if (!ThreadData::InitializeAndSetTrackingStatus(
290 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
291 return;
294 scoped_ptr<DeathData> data(new DeathData());
295 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
296 EXPECT_EQ(data->run_duration_sum(), 0);
297 EXPECT_EQ(data->run_duration_sample(), 0);
298 EXPECT_EQ(data->queue_duration_sum(), 0);
299 EXPECT_EQ(data->queue_duration_sample(), 0);
300 EXPECT_EQ(data->count(), 0);
302 int32 run_ms = 42;
303 int32 queue_ms = 8;
305 const int kUnrandomInt = 0; // Fake random int that ensure we sample data.
306 data->RecordDeath(queue_ms, run_ms, kUnrandomInt);
307 EXPECT_EQ(data->run_duration_sum(), run_ms);
308 EXPECT_EQ(data->run_duration_sample(), run_ms);
309 EXPECT_EQ(data->queue_duration_sum(), queue_ms);
310 EXPECT_EQ(data->queue_duration_sample(), queue_ms);
311 EXPECT_EQ(data->count(), 1);
313 data->RecordDeath(queue_ms, run_ms, kUnrandomInt);
314 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms);
315 EXPECT_EQ(data->run_duration_sample(), run_ms);
316 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms);
317 EXPECT_EQ(data->queue_duration_sample(), queue_ms);
318 EXPECT_EQ(data->count(), 2);
320 DeathDataSnapshot snapshot(*data);
321 EXPECT_EQ(2, snapshot.count);
322 EXPECT_EQ(2 * run_ms, snapshot.run_duration_sum);
323 EXPECT_EQ(run_ms, snapshot.run_duration_max);
324 EXPECT_EQ(run_ms, snapshot.run_duration_sample);
325 EXPECT_EQ(2 * queue_ms, snapshot.queue_duration_sum);
326 EXPECT_EQ(queue_ms, snapshot.queue_duration_max);
327 EXPECT_EQ(queue_ms, snapshot.queue_duration_sample);
330 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotWorkerThread) {
331 // Start in the deactivated state.
332 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) {
333 return;
336 const char kFunction[] = "DeactivatedBirthOnlyToSnapshotWorkerThread";
337 Location location(kFunction, kFile, kLineNumber, NULL);
338 TallyABirth(location, std::string());
340 ProcessDataSnapshot process_data;
341 ThreadData::Snapshot(&process_data);
343 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
344 auto it = process_data.phased_process_data_snapshots.find(0);
345 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
346 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
348 EXPECT_EQ(0u, process_data_phase.tasks.size());
349 EXPECT_EQ(0u, process_data_phase.descendants.size());
350 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
353 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotMainThread) {
354 // Start in the deactivated state.
355 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) {
356 return;
359 const char kFunction[] = "DeactivatedBirthOnlyToSnapshotMainThread";
360 Location location(kFunction, kFile, kLineNumber, NULL);
361 TallyABirth(location, kMainThreadName);
363 ProcessDataSnapshot process_data;
364 ThreadData::Snapshot(&process_data);
366 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
367 auto it = process_data.phased_process_data_snapshots.find(0);
368 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
369 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
371 EXPECT_EQ(0u, process_data_phase.tasks.size());
372 EXPECT_EQ(0u, process_data_phase.descendants.size());
373 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
376 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotWorkerThread) {
377 if (!ThreadData::InitializeAndSetTrackingStatus(
378 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
379 return;
382 const char kFunction[] = "BirthOnlyToSnapshotWorkerThread";
383 Location location(kFunction, kFile, kLineNumber, NULL);
384 TallyABirth(location, std::string());
386 ProcessDataSnapshot process_data;
387 ThreadData::Snapshot(&process_data);
388 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName,
389 kStillAlive, 1, 0, 0);
392 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotMainThread) {
393 if (!ThreadData::InitializeAndSetTrackingStatus(
394 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
395 return;
398 const char kFunction[] = "BirthOnlyToSnapshotMainThread";
399 Location location(kFunction, kFile, kLineNumber, NULL);
400 TallyABirth(location, kMainThreadName);
402 ProcessDataSnapshot process_data;
403 ThreadData::Snapshot(&process_data);
404 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, kStillAlive,
405 1, 0, 0);
408 TEST_F(TrackedObjectsTest, LifeCycleToSnapshotMainThread) {
409 if (!ThreadData::InitializeAndSetTrackingStatus(
410 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
411 return;
414 const char kFunction[] = "LifeCycleToSnapshotMainThread";
415 Location location(kFunction, kFile, kLineNumber, NULL);
416 TallyABirth(location, kMainThreadName);
418 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
419 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
420 // TrackingInfo will call TallyABirth() during construction.
421 base::TrackingInfo pending_task(location, kDelayedStartTime);
422 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
424 const unsigned int kStartOfRun = 5;
425 const unsigned int kEndOfRun = 7;
426 SetTestTime(kStartOfRun);
427 TaskStopwatch stopwatch;
428 stopwatch.Start();
429 SetTestTime(kEndOfRun);
430 stopwatch.Stop();
432 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, stopwatch);
434 ProcessDataSnapshot process_data;
435 ThreadData::Snapshot(&process_data);
436 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName,
437 kMainThreadName, 1, 2, 4);
440 // We will deactivate tracking after the birth, and before the death, and
441 // demonstrate that the lifecycle is completely tallied. This ensures that
442 // our tallied births are matched by tallied deaths (except for when the
443 // task is still running, or is queued).
444 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToSnapshotMainThread) {
445 if (!ThreadData::InitializeAndSetTrackingStatus(
446 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
447 return;
450 const char kFunction[] = "LifeCycleMidDeactivatedToSnapshotMainThread";
451 Location location(kFunction, kFile, kLineNumber, NULL);
452 TallyABirth(location, kMainThreadName);
454 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
455 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
456 // TrackingInfo will call TallyABirth() during construction.
457 base::TrackingInfo pending_task(location, kDelayedStartTime);
458 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
460 // Turn off tracking now that we have births.
461 EXPECT_TRUE(
462 ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED));
464 const unsigned int kStartOfRun = 5;
465 const unsigned int kEndOfRun = 7;
466 SetTestTime(kStartOfRun);
467 TaskStopwatch stopwatch;
468 stopwatch.Start();
469 SetTestTime(kEndOfRun);
470 stopwatch.Stop();
472 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, stopwatch);
474 ProcessDataSnapshot process_data;
475 ThreadData::Snapshot(&process_data);
476 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName,
477 kMainThreadName, 1, 2, 4);
480 // We will deactivate tracking before starting a life cycle, and neither
481 // the birth nor the death will be recorded.
482 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToSnapshotMainThread) {
483 // Start in the deactivated state.
484 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) {
485 return;
488 const char kFunction[] = "LifeCyclePreDeactivatedToSnapshotMainThread";
489 Location location(kFunction, kFile, kLineNumber, NULL);
490 TallyABirth(location, kMainThreadName);
492 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
493 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
494 // TrackingInfo will call TallyABirth() during construction.
495 base::TrackingInfo pending_task(location, kDelayedStartTime);
496 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
498 const unsigned int kStartOfRun = 5;
499 const unsigned int kEndOfRun = 7;
500 SetTestTime(kStartOfRun);
501 TaskStopwatch stopwatch;
502 stopwatch.Start();
503 SetTestTime(kEndOfRun);
504 stopwatch.Stop();
506 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, stopwatch);
508 ProcessDataSnapshot process_data;
509 ThreadData::Snapshot(&process_data);
511 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
512 auto it = process_data.phased_process_data_snapshots.find(0);
513 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
514 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
516 EXPECT_EQ(0u, process_data_phase.tasks.size());
517 EXPECT_EQ(0u, process_data_phase.descendants.size());
518 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
521 TEST_F(TrackedObjectsTest, TwoLives) {
522 if (!ThreadData::InitializeAndSetTrackingStatus(
523 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
524 return;
527 const char kFunction[] = "TwoLives";
528 Location location(kFunction, kFile, kLineNumber, NULL);
529 TallyABirth(location, kMainThreadName);
531 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
532 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
533 // TrackingInfo will call TallyABirth() during construction.
534 base::TrackingInfo pending_task(location, kDelayedStartTime);
535 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
537 const unsigned int kStartOfRun = 5;
538 const unsigned int kEndOfRun = 7;
539 SetTestTime(kStartOfRun);
540 TaskStopwatch stopwatch;
541 stopwatch.Start();
542 SetTestTime(kEndOfRun);
543 stopwatch.Stop();
545 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, stopwatch);
547 // TrackingInfo will call TallyABirth() during construction.
548 base::TrackingInfo pending_task2(location, kDelayedStartTime);
549 pending_task2.time_posted = kTimePosted; // Overwrite implied Now().
550 SetTestTime(kStartOfRun);
551 TaskStopwatch stopwatch2;
552 stopwatch2.Start();
553 SetTestTime(kEndOfRun);
554 stopwatch2.Stop();
556 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, stopwatch2);
558 ProcessDataSnapshot process_data;
559 ThreadData::Snapshot(&process_data);
560 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName,
561 kMainThreadName, 2, 2, 4);
564 TEST_F(TrackedObjectsTest, DifferentLives) {
565 if (!ThreadData::InitializeAndSetTrackingStatus(
566 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
567 return;
570 // Use a well named thread.
571 ThreadData::InitializeThreadContext(kMainThreadName);
572 const char kFunction[] = "DifferentLives";
573 Location location(kFunction, kFile, kLineNumber, NULL);
575 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
576 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
577 // TrackingInfo will call TallyABirth() during construction.
578 base::TrackingInfo pending_task(location, kDelayedStartTime);
579 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
581 const unsigned int kStartOfRun = 5;
582 const unsigned int kEndOfRun = 7;
583 SetTestTime(kStartOfRun);
584 TaskStopwatch stopwatch;
585 stopwatch.Start();
586 SetTestTime(kEndOfRun);
587 stopwatch.Stop();
589 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, stopwatch);
591 const int kSecondFakeLineNumber = 999;
592 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL);
594 // TrackingInfo will call TallyABirth() during construction.
595 base::TrackingInfo pending_task2(second_location, kDelayedStartTime);
596 pending_task2.time_posted = kTimePosted; // Overwrite implied Now().
598 ProcessDataSnapshot process_data;
599 ThreadData::Snapshot(&process_data);
601 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
602 auto it = process_data.phased_process_data_snapshots.find(0);
603 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
604 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
606 ASSERT_EQ(2u, process_data_phase.tasks.size());
608 EXPECT_EQ(kFile, process_data_phase.tasks[0].birth.location.file_name);
609 EXPECT_EQ(kFunction,
610 process_data_phase.tasks[0].birth.location.function_name);
611 EXPECT_EQ(kLineNumber,
612 process_data_phase.tasks[0].birth.location.line_number);
613 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[0].birth.thread_name);
614 EXPECT_EQ(1, process_data_phase.tasks[0].death_data.count);
615 EXPECT_EQ(2, process_data_phase.tasks[0].death_data.run_duration_sum);
616 EXPECT_EQ(2, process_data_phase.tasks[0].death_data.run_duration_max);
617 EXPECT_EQ(2, process_data_phase.tasks[0].death_data.run_duration_sample);
618 EXPECT_EQ(4, process_data_phase.tasks[0].death_data.queue_duration_sum);
619 EXPECT_EQ(4, process_data_phase.tasks[0].death_data.queue_duration_max);
620 EXPECT_EQ(4, process_data_phase.tasks[0].death_data.queue_duration_sample);
621 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[0].death_thread_name);
622 EXPECT_EQ(kFile, process_data_phase.tasks[1].birth.location.file_name);
623 EXPECT_EQ(kFunction,
624 process_data_phase.tasks[1].birth.location.function_name);
625 EXPECT_EQ(kSecondFakeLineNumber,
626 process_data_phase.tasks[1].birth.location.line_number);
627 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[1].birth.thread_name);
628 EXPECT_EQ(1, process_data_phase.tasks[1].death_data.count);
629 EXPECT_EQ(0, process_data_phase.tasks[1].death_data.run_duration_sum);
630 EXPECT_EQ(0, process_data_phase.tasks[1].death_data.run_duration_max);
631 EXPECT_EQ(0, process_data_phase.tasks[1].death_data.run_duration_sample);
632 EXPECT_EQ(0, process_data_phase.tasks[1].death_data.queue_duration_sum);
633 EXPECT_EQ(0, process_data_phase.tasks[1].death_data.queue_duration_max);
634 EXPECT_EQ(0, process_data_phase.tasks[1].death_data.queue_duration_sample);
635 EXPECT_EQ(kStillAlive, process_data_phase.tasks[1].death_thread_name);
636 EXPECT_EQ(0u, process_data_phase.descendants.size());
637 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
640 TEST_F(TrackedObjectsTest, TaskWithNestedExclusion) {
641 if (!ThreadData::InitializeAndSetTrackingStatus(
642 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
643 return;
646 const char kFunction[] = "TaskWithNestedExclusion";
647 Location location(kFunction, kFile, kLineNumber, NULL);
648 TallyABirth(location, kMainThreadName);
650 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
651 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
652 // TrackingInfo will call TallyABirth() during construction.
653 base::TrackingInfo pending_task(location, kDelayedStartTime);
654 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
656 SetTestTime(5);
657 TaskStopwatch task_stopwatch;
658 task_stopwatch.Start();
660 SetTestTime(8);
661 TaskStopwatch exclusion_stopwatch;
662 exclusion_stopwatch.Start();
663 SetTestTime(12);
664 exclusion_stopwatch.Stop();
666 SetTestTime(15);
667 task_stopwatch.Stop();
669 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, task_stopwatch);
671 ProcessDataSnapshot process_data;
672 ThreadData::Snapshot(&process_data);
673 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName,
674 kMainThreadName, 1, 6, 4);
677 TEST_F(TrackedObjectsTest, TaskWith2NestedExclusions) {
678 if (!ThreadData::InitializeAndSetTrackingStatus(
679 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
680 return;
683 const char kFunction[] = "TaskWith2NestedExclusions";
684 Location location(kFunction, kFile, kLineNumber, NULL);
685 TallyABirth(location, kMainThreadName);
687 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
688 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
689 // TrackingInfo will call TallyABirth() during construction.
690 base::TrackingInfo pending_task(location, kDelayedStartTime);
691 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
693 SetTestTime(5);
694 TaskStopwatch task_stopwatch;
695 task_stopwatch.Start();
697 SetTestTime(8);
698 TaskStopwatch exclusion_stopwatch;
699 exclusion_stopwatch.Start();
700 SetTestTime(12);
701 exclusion_stopwatch.Stop();
703 SetTestTime(15);
704 TaskStopwatch exclusion_stopwatch2;
705 exclusion_stopwatch2.Start();
706 SetTestTime(18);
707 exclusion_stopwatch2.Stop();
709 SetTestTime(25);
710 task_stopwatch.Stop();
712 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, task_stopwatch);
714 ProcessDataSnapshot process_data;
715 ThreadData::Snapshot(&process_data);
716 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName,
717 kMainThreadName, 1, 13, 4);
720 TEST_F(TrackedObjectsTest, TaskWithNestedExclusionWithNestedTask) {
721 if (!ThreadData::InitializeAndSetTrackingStatus(
722 ThreadData::PROFILING_CHILDREN_ACTIVE)) {
723 return;
726 const char kFunction[] = "TaskWithNestedExclusionWithNestedTask";
727 Location location(kFunction, kFile, kLineNumber, NULL);
729 const int kSecondFakeLineNumber = 999;
731 TallyABirth(location, kMainThreadName);
733 const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1);
734 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
735 // TrackingInfo will call TallyABirth() during construction.
736 base::TrackingInfo pending_task(location, kDelayedStartTime);
737 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
739 SetTestTime(5);
740 TaskStopwatch task_stopwatch;
741 task_stopwatch.Start();
743 SetTestTime(8);
744 TaskStopwatch exclusion_stopwatch;
745 exclusion_stopwatch.Start();
747 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL);
748 base::TrackingInfo nested_task(second_location, kDelayedStartTime);
749 // Overwrite implied Now().
750 nested_task.time_posted = TrackedTime::FromMilliseconds(8);
751 SetTestTime(9);
752 TaskStopwatch nested_task_stopwatch;
753 nested_task_stopwatch.Start();
754 SetTestTime(11);
755 nested_task_stopwatch.Stop();
756 ThreadData::TallyRunOnNamedThreadIfTracking(
757 nested_task, nested_task_stopwatch);
759 SetTestTime(12);
760 exclusion_stopwatch.Stop();
762 SetTestTime(15);
763 task_stopwatch.Stop();
765 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, task_stopwatch);
767 ProcessDataSnapshot process_data;
768 ThreadData::Snapshot(&process_data);
770 ASSERT_EQ(1u, process_data.phased_process_data_snapshots.size());
771 auto it = process_data.phased_process_data_snapshots.find(0);
772 ASSERT_TRUE(it != process_data.phased_process_data_snapshots.end());
773 const ProcessDataPhaseSnapshot& process_data_phase = it->second;
775 // The order in which the two task follow is platform-dependent.
776 int t0 =
777 (process_data_phase.tasks[0].birth.location.line_number == kLineNumber)
779 : 1;
780 int t1 = 1 - t0;
782 ASSERT_EQ(2u, process_data_phase.tasks.size());
783 EXPECT_EQ(kFile, process_data_phase.tasks[t0].birth.location.file_name);
784 EXPECT_EQ(kFunction,
785 process_data_phase.tasks[t0].birth.location.function_name);
786 EXPECT_EQ(kLineNumber,
787 process_data_phase.tasks[t0].birth.location.line_number);
788 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[t0].birth.thread_name);
789 EXPECT_EQ(1, process_data_phase.tasks[t0].death_data.count);
790 EXPECT_EQ(6, process_data_phase.tasks[t0].death_data.run_duration_sum);
791 EXPECT_EQ(6, process_data_phase.tasks[t0].death_data.run_duration_max);
792 EXPECT_EQ(6, process_data_phase.tasks[t0].death_data.run_duration_sample);
793 EXPECT_EQ(4, process_data_phase.tasks[t0].death_data.queue_duration_sum);
794 EXPECT_EQ(4, process_data_phase.tasks[t0].death_data.queue_duration_max);
795 EXPECT_EQ(4, process_data_phase.tasks[t0].death_data.queue_duration_sample);
796 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[t0].death_thread_name);
797 EXPECT_EQ(kFile, process_data_phase.tasks[t1].birth.location.file_name);
798 EXPECT_EQ(kFunction,
799 process_data_phase.tasks[t1].birth.location.function_name);
800 EXPECT_EQ(kSecondFakeLineNumber,
801 process_data_phase.tasks[t1].birth.location.line_number);
802 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[t1].birth.thread_name);
803 EXPECT_EQ(1, process_data_phase.tasks[t1].death_data.count);
804 EXPECT_EQ(2, process_data_phase.tasks[t1].death_data.run_duration_sum);
805 EXPECT_EQ(2, process_data_phase.tasks[t1].death_data.run_duration_max);
806 EXPECT_EQ(2, process_data_phase.tasks[t1].death_data.run_duration_sample);
807 EXPECT_EQ(1, process_data_phase.tasks[t1].death_data.queue_duration_sum);
808 EXPECT_EQ(1, process_data_phase.tasks[t1].death_data.queue_duration_max);
809 EXPECT_EQ(1, process_data_phase.tasks[t1].death_data.queue_duration_sample);
810 EXPECT_EQ(kMainThreadName, process_data_phase.tasks[t1].death_thread_name);
811 EXPECT_EQ(0u, process_data_phase.descendants.size());
812 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
815 } // namespace tracked_objects