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"
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
{
27 TrackedObjectsTest() {
28 // On entry, leak any database structures in case they are still in use by
30 ThreadData::ShutdownSingleThreadedCleanup(true);
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.
45 ThreadData::ShutdownSingleThreadedCleanup(false);
49 // Simulate a birth on the thread named |thread_name|, at the given
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
);
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
,
74 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
75 auto it
= process_data
.phased_snapshots
.find(0);
76 ASSERT_TRUE(it
!= process_data
.phased_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
);
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
);
98 process_data_phase
.tasks
[0].death_data
.queue_duration_max
);
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
; }
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_
;
121 unsigned int TrackedObjectsTest::test_time_
;
123 TEST_F(TrackedObjectsTest
, TaskStopwatchNoStartStop
) {
124 if (!ThreadData::InitializeAndSetTrackingStatus(
125 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
126 // Don't run the test if task tracking is not compiled in.
130 // Check that creating and destroying a stopwatch without starting it doesn't
132 TaskStopwatch stopwatch
;
135 TEST_F(TrackedObjectsTest
, MinimalStartupShutdown
) {
136 // Minimal test doesn't even create any tasks.
137 if (!ThreadData::InitializeAndSetTrackingStatus(
138 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
139 // Don't run the test if task tracking is not compiled in.
143 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
144 ThreadData
* data
= ThreadData::Get();
145 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
147 EXPECT_FALSE(data
->next());
148 EXPECT_EQ(data
, ThreadData::Get());
149 ThreadData::BirthMap birth_map
;
150 ThreadData::DeathsSnapshot deaths
;
151 ThreadData::ParentChildSet parent_child_set
;
152 data
->SnapshotMaps(0, &birth_map
, &deaths
, &parent_child_set
);
153 EXPECT_EQ(0u, birth_map
.size());
154 EXPECT_EQ(0u, deaths
.size());
155 EXPECT_EQ(0u, parent_child_set
.size());
157 // Clean up with no leaking.
160 // Do it again, just to be sure we reset state completely.
161 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(
162 ThreadData::PROFILING_CHILDREN_ACTIVE
));
163 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
164 data
= ThreadData::Get();
165 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
167 EXPECT_FALSE(data
->next());
168 EXPECT_EQ(data
, ThreadData::Get());
171 parent_child_set
.clear();
172 data
->SnapshotMaps(0, &birth_map
, &deaths
, &parent_child_set
);
173 EXPECT_EQ(0u, birth_map
.size());
174 EXPECT_EQ(0u, deaths
.size());
175 EXPECT_EQ(0u, parent_child_set
.size());
178 TEST_F(TrackedObjectsTest
, TinyStartupShutdown
) {
179 if (!ThreadData::InitializeAndSetTrackingStatus(
180 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
181 // Don't run the test if task tracking is not compiled in.
185 // Instigate tracking on a single tracked object, on our thread.
186 const char kFunction
[] = "TinyStartupShutdown";
187 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
188 Births
* first_birth
= ThreadData::TallyABirthIfActive(location
);
190 ThreadData
* data
= ThreadData::first();
192 EXPECT_FALSE(data
->next());
193 EXPECT_EQ(data
, ThreadData::Get());
194 ThreadData::BirthMap birth_map
;
195 ThreadData::DeathsSnapshot deaths
;
196 ThreadData::ParentChildSet parent_child_set
;
197 data
->SnapshotMaps(0, &birth_map
, &deaths
, &parent_child_set
);
198 EXPECT_EQ(1u, birth_map
.size()); // 1 birth location.
199 EXPECT_EQ(1, birth_map
.begin()->second
->birth_count()); // 1 birth.
200 EXPECT_EQ(0u, deaths
.size()); // No deaths.
201 EXPECT_EQ(0u, parent_child_set
.size()); // No children.
204 // Now instigate another birth, while we are timing the run of the first
206 ThreadData::PrepareForStartOfRun(first_birth
);
207 // Create a child (using the same birth location).
208 // TrackingInfo will call TallyABirth() during construction.
209 const int32 start_time
= 1;
210 base::TimeTicks kBogusBirthTime
= base::TimeTicks() +
211 base::TimeDelta::FromMilliseconds(start_time
);
212 base::TrackingInfo
pending_task(location
, kBogusBirthTime
);
214 TaskStopwatch stopwatch
;
216 // Finally conclude the outer run.
217 const int32 time_elapsed
= 1000;
218 SetTestTime(start_time
+ time_elapsed
);
221 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
225 parent_child_set
.clear();
226 data
->SnapshotMaps(0, &birth_map
, &deaths
, &parent_child_set
);
227 EXPECT_EQ(1u, birth_map
.size()); // 1 birth location.
228 EXPECT_EQ(2, birth_map
.begin()->second
->birth_count()); // 2 births.
229 EXPECT_EQ(1u, deaths
.size()); // 1 location.
230 EXPECT_EQ(1, deaths
.begin()->second
.death_data
.count
); // 1 death.
231 if (ThreadData::TrackingParentChildStatus()) {
232 EXPECT_EQ(1u, parent_child_set
.size()); // 1 child.
233 EXPECT_EQ(parent_child_set
.begin()->first
,
234 parent_child_set
.begin()->second
);
236 EXPECT_EQ(0u, parent_child_set
.size()); // no stats.
239 // The births were at the same location as the one known death.
240 EXPECT_EQ(birth_map
.begin()->second
, deaths
.begin()->first
);
242 ProcessDataSnapshot process_data
;
243 ThreadData::Snapshot(0, &process_data
);
245 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
246 auto it
= process_data
.phased_snapshots
.find(0);
247 ASSERT_TRUE(it
!= process_data
.phased_snapshots
.end());
248 const ProcessDataPhaseSnapshot
& process_data_phase
= it
->second
;
249 ASSERT_EQ(1u, process_data_phase
.tasks
.size());
250 EXPECT_EQ(kFile
, process_data_phase
.tasks
[0].birth
.location
.file_name
);
252 process_data_phase
.tasks
[0].birth
.location
.function_name
);
253 EXPECT_EQ(kLineNumber
,
254 process_data_phase
.tasks
[0].birth
.location
.line_number
);
255 EXPECT_EQ(kWorkerThreadName
, process_data_phase
.tasks
[0].birth
.thread_name
);
256 EXPECT_EQ(1, process_data_phase
.tasks
[0].death_data
.count
);
257 EXPECT_EQ(time_elapsed
,
258 process_data_phase
.tasks
[0].death_data
.run_duration_sum
);
259 EXPECT_EQ(time_elapsed
,
260 process_data_phase
.tasks
[0].death_data
.run_duration_max
);
261 EXPECT_EQ(time_elapsed
,
262 process_data_phase
.tasks
[0].death_data
.run_duration_sample
);
263 EXPECT_EQ(0, process_data_phase
.tasks
[0].death_data
.queue_duration_sum
);
264 EXPECT_EQ(0, process_data_phase
.tasks
[0].death_data
.queue_duration_max
);
265 EXPECT_EQ(0, process_data_phase
.tasks
[0].death_data
.queue_duration_sample
);
266 EXPECT_EQ(kWorkerThreadName
, process_data_phase
.tasks
[0].death_thread_name
);
268 if (ThreadData::TrackingParentChildStatus()) {
269 ASSERT_EQ(1u, process_data_phase
.descendants
.size());
271 process_data_phase
.descendants
[0].parent
.location
.file_name
);
273 process_data_phase
.descendants
[0].parent
.location
.function_name
);
274 EXPECT_EQ(kLineNumber
,
275 process_data_phase
.descendants
[0].parent
.location
.line_number
);
276 EXPECT_EQ(kWorkerThreadName
,
277 process_data_phase
.descendants
[0].parent
.thread_name
);
279 process_data_phase
.descendants
[0].child
.location
.file_name
);
281 process_data_phase
.descendants
[0].child
.location
.function_name
);
282 EXPECT_EQ(kLineNumber
,
283 process_data_phase
.descendants
[0].child
.location
.line_number
);
284 EXPECT_EQ(kWorkerThreadName
,
285 process_data_phase
.descendants
[0].child
.thread_name
);
287 EXPECT_EQ(0u, process_data_phase
.descendants
.size());
291 TEST_F(TrackedObjectsTest
, DeathDataTestRecordDeath
) {
292 if (!ThreadData::InitializeAndSetTrackingStatus(
293 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
294 // Don't run the test if task tracking is not compiled in.
298 scoped_ptr
<DeathData
> data(new DeathData());
299 ASSERT_NE(data
, reinterpret_cast<DeathData
*>(NULL
));
300 EXPECT_EQ(data
->run_duration_sum(), 0);
301 EXPECT_EQ(data
->run_duration_max(), 0);
302 EXPECT_EQ(data
->run_duration_sample(), 0);
303 EXPECT_EQ(data
->queue_duration_sum(), 0);
304 EXPECT_EQ(data
->queue_duration_max(), 0);
305 EXPECT_EQ(data
->queue_duration_sample(), 0);
306 EXPECT_EQ(data
->count(), 0);
307 EXPECT_EQ(nullptr, data
->last_phase_snapshot());
312 const int kUnrandomInt
= 0; // Fake random int that ensure we sample data.
313 data
->RecordDeath(queue_ms
, run_ms
, kUnrandomInt
);
314 EXPECT_EQ(data
->run_duration_sum(), run_ms
);
315 EXPECT_EQ(data
->run_duration_max(), run_ms
);
316 EXPECT_EQ(data
->run_duration_sample(), run_ms
);
317 EXPECT_EQ(data
->queue_duration_sum(), queue_ms
);
318 EXPECT_EQ(data
->queue_duration_max(), queue_ms
);
319 EXPECT_EQ(data
->queue_duration_sample(), queue_ms
);
320 EXPECT_EQ(data
->count(), 1);
321 EXPECT_EQ(nullptr, data
->last_phase_snapshot());
323 data
->RecordDeath(queue_ms
, run_ms
, kUnrandomInt
);
324 EXPECT_EQ(data
->run_duration_sum(), run_ms
+ run_ms
);
325 EXPECT_EQ(data
->run_duration_max(), run_ms
);
326 EXPECT_EQ(data
->run_duration_sample(), run_ms
);
327 EXPECT_EQ(data
->queue_duration_sum(), queue_ms
+ queue_ms
);
328 EXPECT_EQ(data
->queue_duration_max(), queue_ms
);
329 EXPECT_EQ(data
->queue_duration_sample(), queue_ms
);
330 EXPECT_EQ(data
->count(), 2);
331 EXPECT_EQ(nullptr, data
->last_phase_snapshot());
334 TEST_F(TrackedObjectsTest
, DeathDataTest2Phases
) {
335 if (!ThreadData::InitializeAndSetTrackingStatus(
336 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
337 // Don't run the test if task tracking is not compiled in.
341 scoped_ptr
<DeathData
> data(new DeathData());
342 ASSERT_NE(data
, reinterpret_cast<DeathData
*>(NULL
));
347 const int kUnrandomInt
= 0; // Fake random int that ensure we sample data.
348 data
->RecordDeath(queue_ms
, run_ms
, kUnrandomInt
);
349 data
->RecordDeath(queue_ms
, run_ms
, kUnrandomInt
);
351 data
->OnProfilingPhaseCompleted(123);
352 EXPECT_EQ(data
->run_duration_sum(), run_ms
+ run_ms
);
353 EXPECT_EQ(data
->run_duration_max(), 0);
354 EXPECT_EQ(data
->run_duration_sample(), run_ms
);
355 EXPECT_EQ(data
->queue_duration_sum(), queue_ms
+ queue_ms
);
356 EXPECT_EQ(data
->queue_duration_max(), 0);
357 EXPECT_EQ(data
->queue_duration_sample(), queue_ms
);
358 EXPECT_EQ(data
->count(), 2);
359 ASSERT_NE(nullptr, data
->last_phase_snapshot());
360 EXPECT_EQ(123, data
->last_phase_snapshot()->profiling_phase
);
361 EXPECT_EQ(2, data
->last_phase_snapshot()->death_data
.count
);
362 EXPECT_EQ(2 * run_ms
,
363 data
->last_phase_snapshot()->death_data
.run_duration_sum
);
364 EXPECT_EQ(run_ms
, data
->last_phase_snapshot()->death_data
.run_duration_max
);
366 data
->last_phase_snapshot()->death_data
.run_duration_sample
);
367 EXPECT_EQ(2 * queue_ms
,
368 data
->last_phase_snapshot()->death_data
.queue_duration_sum
);
370 data
->last_phase_snapshot()->death_data
.queue_duration_max
);
372 data
->last_phase_snapshot()->death_data
.queue_duration_sample
);
373 EXPECT_EQ(nullptr, data
->last_phase_snapshot()->prev
);
378 data
->RecordDeath(queue_ms1
, run_ms1
, kUnrandomInt
);
379 EXPECT_EQ(data
->run_duration_sum(), run_ms
+ run_ms
+ run_ms1
);
380 EXPECT_EQ(data
->run_duration_max(), run_ms1
);
381 EXPECT_EQ(data
->run_duration_sample(), run_ms1
);
382 EXPECT_EQ(data
->queue_duration_sum(), queue_ms
+ queue_ms
+ queue_ms1
);
383 EXPECT_EQ(data
->queue_duration_max(), queue_ms1
);
384 EXPECT_EQ(data
->queue_duration_sample(), queue_ms1
);
385 EXPECT_EQ(data
->count(), 3);
386 ASSERT_NE(nullptr, data
->last_phase_snapshot());
387 EXPECT_EQ(123, data
->last_phase_snapshot()->profiling_phase
);
388 EXPECT_EQ(2, data
->last_phase_snapshot()->death_data
.count
);
389 EXPECT_EQ(2 * run_ms
,
390 data
->last_phase_snapshot()->death_data
.run_duration_sum
);
391 EXPECT_EQ(run_ms
, data
->last_phase_snapshot()->death_data
.run_duration_max
);
393 data
->last_phase_snapshot()->death_data
.run_duration_sample
);
394 EXPECT_EQ(2 * queue_ms
,
395 data
->last_phase_snapshot()->death_data
.queue_duration_sum
);
397 data
->last_phase_snapshot()->death_data
.queue_duration_max
);
399 data
->last_phase_snapshot()->death_data
.queue_duration_sample
);
400 EXPECT_EQ(nullptr, data
->last_phase_snapshot()->prev
);
403 TEST_F(TrackedObjectsTest
, Delta
) {
404 if (!ThreadData::InitializeAndSetTrackingStatus(
405 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
406 // Don't run the test if task tracking is not compiled in.
410 DeathDataSnapshot snapshot
;
412 snapshot
.run_duration_sum
= 100;
413 snapshot
.run_duration_max
= 50;
414 snapshot
.run_duration_sample
= 25;
415 snapshot
.queue_duration_sum
= 200;
416 snapshot
.queue_duration_max
= 101;
417 snapshot
.queue_duration_sample
= 26;
419 DeathDataSnapshot older_snapshot
;
420 older_snapshot
.count
= 2;
421 older_snapshot
.run_duration_sum
= 95;
422 older_snapshot
.run_duration_max
= 48;
423 older_snapshot
.run_duration_sample
= 22;
424 older_snapshot
.queue_duration_sum
= 190;
425 older_snapshot
.queue_duration_max
= 99;
426 older_snapshot
.queue_duration_sample
= 21;
428 const DeathDataSnapshot
& delta
= snapshot
.Delta(older_snapshot
);
429 EXPECT_EQ(8, delta
.count
);
430 EXPECT_EQ(5, delta
.run_duration_sum
);
431 EXPECT_EQ(50, delta
.run_duration_max
);
432 EXPECT_EQ(25, delta
.run_duration_sample
);
433 EXPECT_EQ(10, delta
.queue_duration_sum
);
434 EXPECT_EQ(101, delta
.queue_duration_max
);
435 EXPECT_EQ(26, delta
.queue_duration_sample
);
438 TEST_F(TrackedObjectsTest
, DeactivatedBirthOnlyToSnapshotWorkerThread
) {
439 // Start in the deactivated state.
440 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED
)) {
441 // Don't run the test if task tracking is not compiled in.
445 const char kFunction
[] = "DeactivatedBirthOnlyToSnapshotWorkerThread";
446 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
447 TallyABirth(location
, std::string());
449 ProcessDataSnapshot process_data
;
450 ThreadData::Snapshot(0, &process_data
);
452 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
454 auto it
= process_data
.phased_snapshots
.find(0);
455 ASSERT_TRUE(it
!= process_data
.phased_snapshots
.end());
456 const ProcessDataPhaseSnapshot
& process_data_phase
= it
->second
;
458 ASSERT_EQ(0u, process_data_phase
.tasks
.size());
460 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
463 TEST_F(TrackedObjectsTest
, DeactivatedBirthOnlyToSnapshotMainThread
) {
464 // Start in the deactivated state.
465 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED
)) {
466 // Don't run the test if task tracking is not compiled in.
470 const char kFunction
[] = "DeactivatedBirthOnlyToSnapshotMainThread";
471 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
472 TallyABirth(location
, kMainThreadName
);
474 ProcessDataSnapshot process_data
;
475 ThreadData::Snapshot(0, &process_data
);
477 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
479 auto it
= process_data
.phased_snapshots
.find(0);
480 ASSERT_TRUE(it
!= process_data
.phased_snapshots
.end());
481 const ProcessDataPhaseSnapshot
& process_data_phase
= it
->second
;
483 ASSERT_EQ(0u, process_data_phase
.tasks
.size());
485 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
488 TEST_F(TrackedObjectsTest
, BirthOnlyToSnapshotWorkerThread
) {
489 if (!ThreadData::InitializeAndSetTrackingStatus(
490 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
491 // Don't run the test if task tracking is not compiled in.
495 const char kFunction
[] = "BirthOnlyToSnapshotWorkerThread";
496 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
497 TallyABirth(location
, std::string());
499 ProcessDataSnapshot process_data
;
500 ThreadData::Snapshot(0, &process_data
);
501 ExpectSimpleProcessData(process_data
, kFunction
, kWorkerThreadName
,
502 kStillAlive
, 1, 0, 0);
505 TEST_F(TrackedObjectsTest
, BirthOnlyToSnapshotMainThread
) {
506 if (!ThreadData::InitializeAndSetTrackingStatus(
507 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
508 // Don't run the test if task tracking is not compiled in.
512 const char kFunction
[] = "BirthOnlyToSnapshotMainThread";
513 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
514 TallyABirth(location
, kMainThreadName
);
516 ProcessDataSnapshot process_data
;
517 ThreadData::Snapshot(0, &process_data
);
518 ExpectSimpleProcessData(process_data
, kFunction
, kMainThreadName
, kStillAlive
,
522 TEST_F(TrackedObjectsTest
, LifeCycleToSnapshotMainThread
) {
523 if (!ThreadData::InitializeAndSetTrackingStatus(
524 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
525 // Don't run the test if task tracking is not compiled in.
529 const char kFunction
[] = "LifeCycleToSnapshotMainThread";
530 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
531 TallyABirth(location
, kMainThreadName
);
533 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
534 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
535 // TrackingInfo will call TallyABirth() during construction.
536 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
537 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
539 const unsigned int kStartOfRun
= 5;
540 const unsigned int kEndOfRun
= 7;
541 SetTestTime(kStartOfRun
);
542 TaskStopwatch stopwatch
;
544 SetTestTime(kEndOfRun
);
547 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
549 ProcessDataSnapshot process_data
;
550 ThreadData::Snapshot(0, &process_data
);
551 ExpectSimpleProcessData(process_data
, kFunction
, kMainThreadName
,
552 kMainThreadName
, 1, 2, 4);
555 TEST_F(TrackedObjectsTest
, TwoPhases
) {
556 if (!ThreadData::InitializeAndSetTrackingStatus(
557 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
558 // Don't run the test if task tracking is not compiled in.
562 const char kFunction
[] = "TwoPhases";
563 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
564 TallyABirth(location
, kMainThreadName
);
566 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
567 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
568 // TrackingInfo will call TallyABirth() during construction.
569 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
570 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
572 const unsigned int kStartOfRun
= 5;
573 const unsigned int kEndOfRun
= 7;
574 SetTestTime(kStartOfRun
);
575 TaskStopwatch stopwatch
;
577 SetTestTime(kEndOfRun
);
580 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
582 ThreadData::OnProfilingPhaseCompleted(0);
584 TallyABirth(location
, kMainThreadName
);
586 const TrackedTime kTimePosted1
= TrackedTime::FromMilliseconds(9);
587 const base::TimeTicks kDelayedStartTime1
= base::TimeTicks();
588 // TrackingInfo will call TallyABirth() during construction.
589 base::TrackingInfo
pending_task1(location
, kDelayedStartTime1
);
590 pending_task1
.time_posted
= kTimePosted1
; // Overwrite implied Now().
592 const unsigned int kStartOfRun1
= 11;
593 const unsigned int kEndOfRun1
= 21;
594 SetTestTime(kStartOfRun1
);
595 TaskStopwatch stopwatch1
;
597 SetTestTime(kEndOfRun1
);
600 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task1
, stopwatch1
);
602 ProcessDataSnapshot process_data
;
603 ThreadData::Snapshot(1, &process_data
);
605 ASSERT_EQ(2u, process_data
.phased_snapshots
.size());
607 auto it0
= process_data
.phased_snapshots
.find(0);
608 ASSERT_TRUE(it0
!= process_data
.phased_snapshots
.end());
609 const ProcessDataPhaseSnapshot
& process_data_phase0
= it0
->second
;
611 ASSERT_EQ(1u, process_data_phase0
.tasks
.size());
613 EXPECT_EQ(kFile
, process_data_phase0
.tasks
[0].birth
.location
.file_name
);
615 process_data_phase0
.tasks
[0].birth
.location
.function_name
);
616 EXPECT_EQ(kLineNumber
,
617 process_data_phase0
.tasks
[0].birth
.location
.line_number
);
619 EXPECT_EQ(kMainThreadName
, process_data_phase0
.tasks
[0].birth
.thread_name
);
621 EXPECT_EQ(1, process_data_phase0
.tasks
[0].death_data
.count
);
622 EXPECT_EQ(2, process_data_phase0
.tasks
[0].death_data
.run_duration_sum
);
623 EXPECT_EQ(2, process_data_phase0
.tasks
[0].death_data
.run_duration_max
);
624 EXPECT_EQ(2, process_data_phase0
.tasks
[0].death_data
.run_duration_sample
);
625 EXPECT_EQ(4, process_data_phase0
.tasks
[0].death_data
.queue_duration_sum
);
626 EXPECT_EQ(4, process_data_phase0
.tasks
[0].death_data
.queue_duration_max
);
627 EXPECT_EQ(4, process_data_phase0
.tasks
[0].death_data
.queue_duration_sample
);
629 EXPECT_EQ(kMainThreadName
, process_data_phase0
.tasks
[0].death_thread_name
);
631 EXPECT_EQ(0u, process_data_phase0
.descendants
.size());
633 auto it1
= process_data
.phased_snapshots
.find(1);
634 ASSERT_TRUE(it1
!= process_data
.phased_snapshots
.end());
635 const ProcessDataPhaseSnapshot
& process_data_phase1
= it1
->second
;
637 ASSERT_EQ(1u, process_data_phase1
.tasks
.size());
639 EXPECT_EQ(kFile
, process_data_phase1
.tasks
[0].birth
.location
.file_name
);
641 process_data_phase1
.tasks
[0].birth
.location
.function_name
);
642 EXPECT_EQ(kLineNumber
,
643 process_data_phase1
.tasks
[0].birth
.location
.line_number
);
645 EXPECT_EQ(kMainThreadName
, process_data_phase1
.tasks
[0].birth
.thread_name
);
647 EXPECT_EQ(1, process_data_phase1
.tasks
[0].death_data
.count
);
648 EXPECT_EQ(10, process_data_phase1
.tasks
[0].death_data
.run_duration_sum
);
649 EXPECT_EQ(10, process_data_phase1
.tasks
[0].death_data
.run_duration_max
);
650 EXPECT_EQ(10, process_data_phase1
.tasks
[0].death_data
.run_duration_sample
);
651 EXPECT_EQ(2, process_data_phase1
.tasks
[0].death_data
.queue_duration_sum
);
652 EXPECT_EQ(2, process_data_phase1
.tasks
[0].death_data
.queue_duration_max
);
653 EXPECT_EQ(2, process_data_phase1
.tasks
[0].death_data
.queue_duration_sample
);
655 EXPECT_EQ(kMainThreadName
, process_data_phase1
.tasks
[0].death_thread_name
);
657 EXPECT_EQ(0u, process_data_phase1
.descendants
.size());
659 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
662 TEST_F(TrackedObjectsTest
, ThreePhases
) {
663 if (!ThreadData::InitializeAndSetTrackingStatus(
664 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
665 // Don't run the test if task tracking is not compiled in.
669 const char kFunction
[] = "ThreePhases";
670 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
674 TallyABirth(location
, kMainThreadName
);
676 // TrackingInfo will call TallyABirth() during construction.
678 base::TrackingInfo
pending_task(location
, base::TimeTicks());
681 TaskStopwatch stopwatch
;
686 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
689 ThreadData::OnProfilingPhaseCompleted(0);
693 TallyABirth(location
, kMainThreadName
);
696 base::TrackingInfo
pending_task(location
, base::TimeTicks());
699 TaskStopwatch stopwatch
;
704 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
707 ThreadData::OnProfilingPhaseCompleted(1);
711 TallyABirth(location
, kMainThreadName
);
713 // TrackingInfo will call TallyABirth() during construction.
715 base::TrackingInfo
pending_task(location
, base::TimeTicks());
718 TaskStopwatch stopwatch
;
723 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
726 // Snapshot and check results.
727 ProcessDataSnapshot process_data
;
728 ThreadData::Snapshot(2, &process_data
);
730 ASSERT_EQ(3u, process_data
.phased_snapshots
.size());
732 auto it0
= process_data
.phased_snapshots
.find(0);
733 ASSERT_TRUE(it0
!= process_data
.phased_snapshots
.end());
734 const ProcessDataPhaseSnapshot
& process_data_phase0
= it0
->second
;
736 ASSERT_EQ(1u, process_data_phase0
.tasks
.size());
738 EXPECT_EQ(kFile
, process_data_phase0
.tasks
[0].birth
.location
.file_name
);
740 process_data_phase0
.tasks
[0].birth
.location
.function_name
);
741 EXPECT_EQ(kLineNumber
,
742 process_data_phase0
.tasks
[0].birth
.location
.line_number
);
744 EXPECT_EQ(kMainThreadName
, process_data_phase0
.tasks
[0].birth
.thread_name
);
746 EXPECT_EQ(1, process_data_phase0
.tasks
[0].death_data
.count
);
747 EXPECT_EQ(6, process_data_phase0
.tasks
[0].death_data
.run_duration_sum
);
748 EXPECT_EQ(6, process_data_phase0
.tasks
[0].death_data
.run_duration_max
);
749 EXPECT_EQ(6, process_data_phase0
.tasks
[0].death_data
.run_duration_sample
);
750 EXPECT_EQ(7, process_data_phase0
.tasks
[0].death_data
.queue_duration_sum
);
751 EXPECT_EQ(7, process_data_phase0
.tasks
[0].death_data
.queue_duration_max
);
752 EXPECT_EQ(7, process_data_phase0
.tasks
[0].death_data
.queue_duration_sample
);
754 EXPECT_EQ(kMainThreadName
, process_data_phase0
.tasks
[0].death_thread_name
);
756 EXPECT_EQ(0u, process_data_phase0
.descendants
.size());
758 auto it1
= process_data
.phased_snapshots
.find(1);
759 ASSERT_TRUE(it1
!= process_data
.phased_snapshots
.end());
760 const ProcessDataPhaseSnapshot
& process_data_phase1
= it1
->second
;
762 ASSERT_EQ(1u, process_data_phase1
.tasks
.size());
764 EXPECT_EQ(kFile
, process_data_phase1
.tasks
[0].birth
.location
.file_name
);
766 process_data_phase1
.tasks
[0].birth
.location
.function_name
);
767 EXPECT_EQ(kLineNumber
,
768 process_data_phase1
.tasks
[0].birth
.location
.line_number
);
770 EXPECT_EQ(kMainThreadName
, process_data_phase1
.tasks
[0].birth
.thread_name
);
772 EXPECT_EQ(1, process_data_phase1
.tasks
[0].death_data
.count
);
773 EXPECT_EQ(4, process_data_phase1
.tasks
[0].death_data
.run_duration_sum
);
774 EXPECT_EQ(4, process_data_phase1
.tasks
[0].death_data
.run_duration_max
);
775 EXPECT_EQ(4, process_data_phase1
.tasks
[0].death_data
.run_duration_sample
);
776 EXPECT_EQ(5, process_data_phase1
.tasks
[0].death_data
.queue_duration_sum
);
777 EXPECT_EQ(5, process_data_phase1
.tasks
[0].death_data
.queue_duration_max
);
778 EXPECT_EQ(5, process_data_phase1
.tasks
[0].death_data
.queue_duration_sample
);
780 EXPECT_EQ(kMainThreadName
, process_data_phase1
.tasks
[0].death_thread_name
);
782 EXPECT_EQ(0u, process_data_phase1
.descendants
.size());
784 auto it2
= process_data
.phased_snapshots
.find(2);
785 ASSERT_TRUE(it2
!= process_data
.phased_snapshots
.end());
786 const ProcessDataPhaseSnapshot
& process_data_phase2
= it2
->second
;
788 ASSERT_EQ(1u, process_data_phase2
.tasks
.size());
790 EXPECT_EQ(kFile
, process_data_phase2
.tasks
[0].birth
.location
.file_name
);
792 process_data_phase2
.tasks
[0].birth
.location
.function_name
);
793 EXPECT_EQ(kLineNumber
,
794 process_data_phase2
.tasks
[0].birth
.location
.line_number
);
796 EXPECT_EQ(kMainThreadName
, process_data_phase2
.tasks
[0].birth
.thread_name
);
798 EXPECT_EQ(1, process_data_phase2
.tasks
[0].death_data
.count
);
799 EXPECT_EQ(2, process_data_phase2
.tasks
[0].death_data
.run_duration_sum
);
800 EXPECT_EQ(2, process_data_phase2
.tasks
[0].death_data
.run_duration_max
);
801 EXPECT_EQ(2, process_data_phase2
.tasks
[0].death_data
.run_duration_sample
);
802 EXPECT_EQ(3, process_data_phase2
.tasks
[0].death_data
.queue_duration_sum
);
803 EXPECT_EQ(3, process_data_phase2
.tasks
[0].death_data
.queue_duration_max
);
804 EXPECT_EQ(3, process_data_phase2
.tasks
[0].death_data
.queue_duration_sample
);
806 EXPECT_EQ(kMainThreadName
, process_data_phase2
.tasks
[0].death_thread_name
);
808 EXPECT_EQ(0u, process_data_phase2
.descendants
.size());
810 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
813 TEST_F(TrackedObjectsTest
, TwoPhasesSecondEmpty
) {
814 if (!ThreadData::InitializeAndSetTrackingStatus(
815 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
816 // Don't run the test if task tracking is not compiled in.
820 const char kFunction
[] = "TwoPhasesSecondEmpty";
821 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
822 ThreadData::InitializeThreadContext(kMainThreadName
);
824 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
825 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
826 // TrackingInfo will call TallyABirth() during construction.
827 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
828 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
830 const unsigned int kStartOfRun
= 5;
831 const unsigned int kEndOfRun
= 7;
832 SetTestTime(kStartOfRun
);
833 TaskStopwatch stopwatch
;
835 SetTestTime(kEndOfRun
);
838 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
840 ThreadData::OnProfilingPhaseCompleted(0);
842 ProcessDataSnapshot process_data
;
843 ThreadData::Snapshot(1, &process_data
);
845 ASSERT_EQ(2u, process_data
.phased_snapshots
.size());
847 auto it0
= process_data
.phased_snapshots
.find(0);
848 ASSERT_TRUE(it0
!= process_data
.phased_snapshots
.end());
849 const ProcessDataPhaseSnapshot
& process_data_phase0
= it0
->second
;
851 ASSERT_EQ(1u, process_data_phase0
.tasks
.size());
853 EXPECT_EQ(kFile
, process_data_phase0
.tasks
[0].birth
.location
.file_name
);
855 process_data_phase0
.tasks
[0].birth
.location
.function_name
);
856 EXPECT_EQ(kLineNumber
,
857 process_data_phase0
.tasks
[0].birth
.location
.line_number
);
859 EXPECT_EQ(kMainThreadName
, process_data_phase0
.tasks
[0].birth
.thread_name
);
861 EXPECT_EQ(1, process_data_phase0
.tasks
[0].death_data
.count
);
862 EXPECT_EQ(2, process_data_phase0
.tasks
[0].death_data
.run_duration_sum
);
863 EXPECT_EQ(2, process_data_phase0
.tasks
[0].death_data
.run_duration_max
);
864 EXPECT_EQ(2, process_data_phase0
.tasks
[0].death_data
.run_duration_sample
);
865 EXPECT_EQ(4, process_data_phase0
.tasks
[0].death_data
.queue_duration_sum
);
866 EXPECT_EQ(4, process_data_phase0
.tasks
[0].death_data
.queue_duration_max
);
867 EXPECT_EQ(4, process_data_phase0
.tasks
[0].death_data
.queue_duration_sample
);
869 EXPECT_EQ(kMainThreadName
, process_data_phase0
.tasks
[0].death_thread_name
);
871 auto it1
= process_data
.phased_snapshots
.find(1);
872 ASSERT_TRUE(it1
!= process_data
.phased_snapshots
.end());
873 const ProcessDataPhaseSnapshot
& process_data_phase1
= it1
->second
;
875 ASSERT_EQ(0u, process_data_phase1
.tasks
.size());
877 EXPECT_EQ(0u, process_data_phase0
.descendants
.size());
879 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
882 TEST_F(TrackedObjectsTest
, TwoPhasesFirstEmpty
) {
883 if (!ThreadData::InitializeAndSetTrackingStatus(
884 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
885 // Don't run the test if task tracking is not compiled in.
889 ThreadData::OnProfilingPhaseCompleted(0);
891 const char kFunction
[] = "TwoPhasesSecondEmpty";
892 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
893 ThreadData::InitializeThreadContext(kMainThreadName
);
895 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
896 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
897 // TrackingInfo will call TallyABirth() during construction.
898 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
899 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
901 const unsigned int kStartOfRun
= 5;
902 const unsigned int kEndOfRun
= 7;
903 SetTestTime(kStartOfRun
);
904 TaskStopwatch stopwatch
;
906 SetTestTime(kEndOfRun
);
909 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
911 ProcessDataSnapshot process_data
;
912 ThreadData::Snapshot(1, &process_data
);
914 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
916 auto it1
= process_data
.phased_snapshots
.find(1);
917 ASSERT_TRUE(it1
!= process_data
.phased_snapshots
.end());
918 const ProcessDataPhaseSnapshot
& process_data_phase1
= it1
->second
;
920 ASSERT_EQ(1u, process_data_phase1
.tasks
.size());
922 EXPECT_EQ(kFile
, process_data_phase1
.tasks
[0].birth
.location
.file_name
);
924 process_data_phase1
.tasks
[0].birth
.location
.function_name
);
925 EXPECT_EQ(kLineNumber
,
926 process_data_phase1
.tasks
[0].birth
.location
.line_number
);
928 EXPECT_EQ(kMainThreadName
, process_data_phase1
.tasks
[0].birth
.thread_name
);
930 EXPECT_EQ(1, process_data_phase1
.tasks
[0].death_data
.count
);
931 EXPECT_EQ(2, process_data_phase1
.tasks
[0].death_data
.run_duration_sum
);
932 EXPECT_EQ(2, process_data_phase1
.tasks
[0].death_data
.run_duration_max
);
933 EXPECT_EQ(2, process_data_phase1
.tasks
[0].death_data
.run_duration_sample
);
934 EXPECT_EQ(4, process_data_phase1
.tasks
[0].death_data
.queue_duration_sum
);
935 EXPECT_EQ(4, process_data_phase1
.tasks
[0].death_data
.queue_duration_max
);
936 EXPECT_EQ(4, process_data_phase1
.tasks
[0].death_data
.queue_duration_sample
);
938 EXPECT_EQ(kMainThreadName
, process_data_phase1
.tasks
[0].death_thread_name
);
940 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
943 // We will deactivate tracking after the birth, and before the death, and
944 // demonstrate that the lifecycle is completely tallied. This ensures that
945 // our tallied births are matched by tallied deaths (except for when the
946 // task is still running, or is queued).
947 TEST_F(TrackedObjectsTest
, LifeCycleMidDeactivatedToSnapshotMainThread
) {
948 if (!ThreadData::InitializeAndSetTrackingStatus(
949 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
950 // Don't run the test if task tracking is not compiled in.
954 const char kFunction
[] = "LifeCycleMidDeactivatedToSnapshotMainThread";
955 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
956 TallyABirth(location
, kMainThreadName
);
958 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
959 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
960 // TrackingInfo will call TallyABirth() during construction.
961 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
962 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
964 // Turn off tracking now that we have births.
966 ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED
));
968 const unsigned int kStartOfRun
= 5;
969 const unsigned int kEndOfRun
= 7;
970 SetTestTime(kStartOfRun
);
971 TaskStopwatch stopwatch
;
973 SetTestTime(kEndOfRun
);
976 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
978 ProcessDataSnapshot process_data
;
979 ThreadData::Snapshot(0, &process_data
);
980 ExpectSimpleProcessData(process_data
, kFunction
, kMainThreadName
,
981 kMainThreadName
, 1, 2, 4);
984 // We will deactivate tracking before starting a life cycle, and neither
985 // the birth nor the death will be recorded.
986 TEST_F(TrackedObjectsTest
, LifeCyclePreDeactivatedToSnapshotMainThread
) {
987 // Start in the deactivated state.
988 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED
)) {
989 // Don't run the test if task tracking is not compiled in.
993 const char kFunction
[] = "LifeCyclePreDeactivatedToSnapshotMainThread";
994 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
995 TallyABirth(location
, kMainThreadName
);
997 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
998 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
999 // TrackingInfo will call TallyABirth() during construction.
1000 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
1001 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
1003 const unsigned int kStartOfRun
= 5;
1004 const unsigned int kEndOfRun
= 7;
1005 SetTestTime(kStartOfRun
);
1006 TaskStopwatch stopwatch
;
1008 SetTestTime(kEndOfRun
);
1011 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
1013 ProcessDataSnapshot process_data
;
1014 ThreadData::Snapshot(0, &process_data
);
1016 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
1018 auto it
= process_data
.phased_snapshots
.find(0);
1019 ASSERT_TRUE(it
!= process_data
.phased_snapshots
.end());
1020 const ProcessDataPhaseSnapshot
& process_data_phase
= it
->second
;
1022 ASSERT_EQ(0u, process_data_phase
.tasks
.size());
1024 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
1027 TEST_F(TrackedObjectsTest
, TwoLives
) {
1028 if (!ThreadData::InitializeAndSetTrackingStatus(
1029 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
1030 // Don't run the test if task tracking is not compiled in.
1034 const char kFunction
[] = "TwoLives";
1035 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
1036 TallyABirth(location
, kMainThreadName
);
1038 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
1039 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
1040 // TrackingInfo will call TallyABirth() during construction.
1041 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
1042 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
1044 const unsigned int kStartOfRun
= 5;
1045 const unsigned int kEndOfRun
= 7;
1046 SetTestTime(kStartOfRun
);
1047 TaskStopwatch stopwatch
;
1049 SetTestTime(kEndOfRun
);
1052 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
1054 // TrackingInfo will call TallyABirth() during construction.
1055 base::TrackingInfo
pending_task2(location
, kDelayedStartTime
);
1056 pending_task2
.time_posted
= kTimePosted
; // Overwrite implied Now().
1057 SetTestTime(kStartOfRun
);
1058 TaskStopwatch stopwatch2
;
1060 SetTestTime(kEndOfRun
);
1063 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2
, stopwatch2
);
1065 ProcessDataSnapshot process_data
;
1066 ThreadData::Snapshot(0, &process_data
);
1067 ExpectSimpleProcessData(process_data
, kFunction
, kMainThreadName
,
1068 kMainThreadName
, 2, 2, 4);
1071 TEST_F(TrackedObjectsTest
, DifferentLives
) {
1072 if (!ThreadData::InitializeAndSetTrackingStatus(
1073 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
1074 // Don't run the test if task tracking is not compiled in.
1078 // Use a well named thread.
1079 ThreadData::InitializeThreadContext(kMainThreadName
);
1080 const char kFunction
[] = "DifferentLives";
1081 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
1083 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
1084 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
1085 // TrackingInfo will call TallyABirth() during construction.
1086 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
1087 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
1089 const unsigned int kStartOfRun
= 5;
1090 const unsigned int kEndOfRun
= 7;
1091 SetTestTime(kStartOfRun
);
1092 TaskStopwatch stopwatch
;
1094 SetTestTime(kEndOfRun
);
1097 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, stopwatch
);
1099 const int kSecondFakeLineNumber
= 999;
1100 Location
second_location(kFunction
, kFile
, kSecondFakeLineNumber
, NULL
);
1102 // TrackingInfo will call TallyABirth() during construction.
1103 base::TrackingInfo
pending_task2(second_location
, kDelayedStartTime
);
1104 pending_task2
.time_posted
= kTimePosted
; // Overwrite implied Now().
1106 ProcessDataSnapshot process_data
;
1107 ThreadData::Snapshot(0, &process_data
);
1109 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
1110 auto it
= process_data
.phased_snapshots
.find(0);
1111 ASSERT_TRUE(it
!= process_data
.phased_snapshots
.end());
1112 const ProcessDataPhaseSnapshot
& process_data_phase
= it
->second
;
1114 ASSERT_EQ(2u, process_data_phase
.tasks
.size());
1116 EXPECT_EQ(kFile
, process_data_phase
.tasks
[0].birth
.location
.file_name
);
1117 EXPECT_EQ(kFunction
,
1118 process_data_phase
.tasks
[0].birth
.location
.function_name
);
1119 EXPECT_EQ(kLineNumber
,
1120 process_data_phase
.tasks
[0].birth
.location
.line_number
);
1121 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[0].birth
.thread_name
);
1122 EXPECT_EQ(1, process_data_phase
.tasks
[0].death_data
.count
);
1123 EXPECT_EQ(2, process_data_phase
.tasks
[0].death_data
.run_duration_sum
);
1124 EXPECT_EQ(2, process_data_phase
.tasks
[0].death_data
.run_duration_max
);
1125 EXPECT_EQ(2, process_data_phase
.tasks
[0].death_data
.run_duration_sample
);
1126 EXPECT_EQ(4, process_data_phase
.tasks
[0].death_data
.queue_duration_sum
);
1127 EXPECT_EQ(4, process_data_phase
.tasks
[0].death_data
.queue_duration_max
);
1128 EXPECT_EQ(4, process_data_phase
.tasks
[0].death_data
.queue_duration_sample
);
1129 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[0].death_thread_name
);
1130 EXPECT_EQ(kFile
, process_data_phase
.tasks
[1].birth
.location
.file_name
);
1131 EXPECT_EQ(kFunction
,
1132 process_data_phase
.tasks
[1].birth
.location
.function_name
);
1133 EXPECT_EQ(kSecondFakeLineNumber
,
1134 process_data_phase
.tasks
[1].birth
.location
.line_number
);
1135 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[1].birth
.thread_name
);
1136 EXPECT_EQ(1, process_data_phase
.tasks
[1].death_data
.count
);
1137 EXPECT_EQ(0, process_data_phase
.tasks
[1].death_data
.run_duration_sum
);
1138 EXPECT_EQ(0, process_data_phase
.tasks
[1].death_data
.run_duration_max
);
1139 EXPECT_EQ(0, process_data_phase
.tasks
[1].death_data
.run_duration_sample
);
1140 EXPECT_EQ(0, process_data_phase
.tasks
[1].death_data
.queue_duration_sum
);
1141 EXPECT_EQ(0, process_data_phase
.tasks
[1].death_data
.queue_duration_max
);
1142 EXPECT_EQ(0, process_data_phase
.tasks
[1].death_data
.queue_duration_sample
);
1143 EXPECT_EQ(kStillAlive
, process_data_phase
.tasks
[1].death_thread_name
);
1144 EXPECT_EQ(0u, process_data_phase
.descendants
.size());
1145 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
1148 TEST_F(TrackedObjectsTest
, TaskWithNestedExclusion
) {
1149 if (!ThreadData::InitializeAndSetTrackingStatus(
1150 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
1151 // Don't run the test if task tracking is not compiled in.
1155 const char kFunction
[] = "TaskWithNestedExclusion";
1156 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
1157 TallyABirth(location
, kMainThreadName
);
1159 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
1160 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
1161 // TrackingInfo will call TallyABirth() during construction.
1162 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
1163 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
1166 TaskStopwatch task_stopwatch
;
1167 task_stopwatch
.Start();
1170 TaskStopwatch exclusion_stopwatch
;
1171 exclusion_stopwatch
.Start();
1173 exclusion_stopwatch
.Stop();
1176 task_stopwatch
.Stop();
1178 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, task_stopwatch
);
1180 ProcessDataSnapshot process_data
;
1181 ThreadData::Snapshot(0, &process_data
);
1182 ExpectSimpleProcessData(process_data
, kFunction
, kMainThreadName
,
1183 kMainThreadName
, 1, 6, 4);
1186 TEST_F(TrackedObjectsTest
, TaskWith2NestedExclusions
) {
1187 if (!ThreadData::InitializeAndSetTrackingStatus(
1188 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
1189 // Don't run the test if task tracking is not compiled in.
1193 const char kFunction
[] = "TaskWith2NestedExclusions";
1194 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
1195 TallyABirth(location
, kMainThreadName
);
1197 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
1198 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
1199 // TrackingInfo will call TallyABirth() during construction.
1200 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
1201 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
1204 TaskStopwatch task_stopwatch
;
1205 task_stopwatch
.Start();
1208 TaskStopwatch exclusion_stopwatch
;
1209 exclusion_stopwatch
.Start();
1211 exclusion_stopwatch
.Stop();
1214 TaskStopwatch exclusion_stopwatch2
;
1215 exclusion_stopwatch2
.Start();
1217 exclusion_stopwatch2
.Stop();
1220 task_stopwatch
.Stop();
1222 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, task_stopwatch
);
1224 ProcessDataSnapshot process_data
;
1225 ThreadData::Snapshot(0, &process_data
);
1226 ExpectSimpleProcessData(process_data
, kFunction
, kMainThreadName
,
1227 kMainThreadName
, 1, 13, 4);
1230 TEST_F(TrackedObjectsTest
, TaskWithNestedExclusionWithNestedTask
) {
1231 if (!ThreadData::InitializeAndSetTrackingStatus(
1232 ThreadData::PROFILING_CHILDREN_ACTIVE
)) {
1233 // Don't run the test if task tracking is not compiled in.
1237 const char kFunction
[] = "TaskWithNestedExclusionWithNestedTask";
1238 Location
location(kFunction
, kFile
, kLineNumber
, NULL
);
1240 const int kSecondFakeLineNumber
= 999;
1242 TallyABirth(location
, kMainThreadName
);
1244 const TrackedTime kTimePosted
= TrackedTime::FromMilliseconds(1);
1245 const base::TimeTicks kDelayedStartTime
= base::TimeTicks();
1246 // TrackingInfo will call TallyABirth() during construction.
1247 base::TrackingInfo
pending_task(location
, kDelayedStartTime
);
1248 pending_task
.time_posted
= kTimePosted
; // Overwrite implied Now().
1251 TaskStopwatch task_stopwatch
;
1252 task_stopwatch
.Start();
1255 TaskStopwatch exclusion_stopwatch
;
1256 exclusion_stopwatch
.Start();
1258 Location
second_location(kFunction
, kFile
, kSecondFakeLineNumber
, NULL
);
1259 base::TrackingInfo
nested_task(second_location
, kDelayedStartTime
);
1260 // Overwrite implied Now().
1261 nested_task
.time_posted
= TrackedTime::FromMilliseconds(8);
1263 TaskStopwatch nested_task_stopwatch
;
1264 nested_task_stopwatch
.Start();
1266 nested_task_stopwatch
.Stop();
1267 ThreadData::TallyRunOnNamedThreadIfTracking(
1268 nested_task
, nested_task_stopwatch
);
1271 exclusion_stopwatch
.Stop();
1274 task_stopwatch
.Stop();
1276 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task
, task_stopwatch
);
1278 ProcessDataSnapshot process_data
;
1279 ThreadData::Snapshot(0, &process_data
);
1281 ASSERT_EQ(1u, process_data
.phased_snapshots
.size());
1282 auto it
= process_data
.phased_snapshots
.find(0);
1283 ASSERT_TRUE(it
!= process_data
.phased_snapshots
.end());
1284 const ProcessDataPhaseSnapshot
& process_data_phase
= it
->second
;
1286 // The order in which the two task follow is platform-dependent.
1288 (process_data_phase
.tasks
[0].birth
.location
.line_number
== kLineNumber
)
1293 ASSERT_EQ(2u, process_data_phase
.tasks
.size());
1294 EXPECT_EQ(kFile
, process_data_phase
.tasks
[t0
].birth
.location
.file_name
);
1295 EXPECT_EQ(kFunction
,
1296 process_data_phase
.tasks
[t0
].birth
.location
.function_name
);
1297 EXPECT_EQ(kLineNumber
,
1298 process_data_phase
.tasks
[t0
].birth
.location
.line_number
);
1299 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[t0
].birth
.thread_name
);
1300 EXPECT_EQ(1, process_data_phase
.tasks
[t0
].death_data
.count
);
1301 EXPECT_EQ(6, process_data_phase
.tasks
[t0
].death_data
.run_duration_sum
);
1302 EXPECT_EQ(6, process_data_phase
.tasks
[t0
].death_data
.run_duration_max
);
1303 EXPECT_EQ(6, process_data_phase
.tasks
[t0
].death_data
.run_duration_sample
);
1304 EXPECT_EQ(4, process_data_phase
.tasks
[t0
].death_data
.queue_duration_sum
);
1305 EXPECT_EQ(4, process_data_phase
.tasks
[t0
].death_data
.queue_duration_max
);
1306 EXPECT_EQ(4, process_data_phase
.tasks
[t0
].death_data
.queue_duration_sample
);
1307 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[t0
].death_thread_name
);
1308 EXPECT_EQ(kFile
, process_data_phase
.tasks
[t1
].birth
.location
.file_name
);
1309 EXPECT_EQ(kFunction
,
1310 process_data_phase
.tasks
[t1
].birth
.location
.function_name
);
1311 EXPECT_EQ(kSecondFakeLineNumber
,
1312 process_data_phase
.tasks
[t1
].birth
.location
.line_number
);
1313 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[t1
].birth
.thread_name
);
1314 EXPECT_EQ(1, process_data_phase
.tasks
[t1
].death_data
.count
);
1315 EXPECT_EQ(2, process_data_phase
.tasks
[t1
].death_data
.run_duration_sum
);
1316 EXPECT_EQ(2, process_data_phase
.tasks
[t1
].death_data
.run_duration_max
);
1317 EXPECT_EQ(2, process_data_phase
.tasks
[t1
].death_data
.run_duration_sample
);
1318 EXPECT_EQ(1, process_data_phase
.tasks
[t1
].death_data
.queue_duration_sum
);
1319 EXPECT_EQ(1, process_data_phase
.tasks
[t1
].death_data
.queue_duration_max
);
1320 EXPECT_EQ(1, process_data_phase
.tasks
[t1
].death_data
.queue_duration_sample
);
1321 EXPECT_EQ(kMainThreadName
, process_data_phase
.tasks
[t1
].death_thread_name
);
1322 EXPECT_EQ(0u, process_data_phase
.descendants
.size());
1323 EXPECT_EQ(base::GetCurrentProcId(), process_data
.process_id
);
1326 } // namespace tracked_objects