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. 4 5// Test of classes in the tracked_objects.h classes. 6 7#include "base/tracked_objects.h" 8 9#include "base/memory/scoped_ptr.h" 10#include "base/process/process_handle.h" 11#include "base/time/time.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14const int kLineNumber = 1776; 15const char kFile[] = "FixedUnitTestFileName"; 16const char kWorkerThreadName[] = "WorkerThread-1"; 17const char kMainThreadName[] = "SomeMainThreadName"; 18const char kStillAlive[] = "Still_Alive"; 19 20namespace tracked_objects { 21 22class TrackedObjectsTest : public testing::Test { 23 protected: 24 TrackedObjectsTest() { 25 // On entry, leak any database structures in case they are still in use by 26 // prior threads. 27 ThreadData::ShutdownSingleThreadedCleanup(true); 28 } 29 30 virtual ~TrackedObjectsTest() { 31 // We should not need to leak any structures we create, since we are 32 // single threaded, and carefully accounting for items. 33 ThreadData::ShutdownSingleThreadedCleanup(false); 34 } 35 36 // Reset the profiler state. 37 void Reset() { 38 ThreadData::ShutdownSingleThreadedCleanup(false); 39 } 40 41 // Simulate a birth on the thread named |thread_name|, at the given 42 // |location|. 43 void TallyABirth(const Location& location, const std::string& thread_name) { 44 // If the |thread_name| is empty, we don't initialize system with a thread 45 // name, so we're viewed as a worker thread. 46 if (!thread_name.empty()) 47 ThreadData::InitializeThreadContext(kMainThreadName); 48 49 // Do not delete |birth|. We don't own it. 50 Births* birth = ThreadData::TallyABirthIfActive(location); 51 52 if (ThreadData::status() == ThreadData::DEACTIVATED) 53 EXPECT_EQ(reinterpret_cast<Births*>(NULL), birth); 54 else 55 EXPECT_NE(reinterpret_cast<Births*>(NULL), birth); 56 } 57 58 // Helper function to verify the most common test expectations. 59 void ExpectSimpleProcessData(const ProcessDataSnapshot& process_data, 60 const std::string& function_name, 61 const std::string& birth_thread, 62 const std::string& death_thread, 63 int count, 64 int run_ms, 65 int queue_ms) { 66 ASSERT_EQ(1u, process_data.tasks.size()); 67 68 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name); 69 EXPECT_EQ(function_name, 70 process_data.tasks[0].birth.location.function_name); 71 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number); 72 73 EXPECT_EQ(birth_thread, process_data.tasks[0].birth.thread_name); 74 75 EXPECT_EQ(count, process_data.tasks[0].death_data.count); 76 EXPECT_EQ(count * run_ms, 77 process_data.tasks[0].death_data.run_duration_sum); 78 EXPECT_EQ(run_ms, process_data.tasks[0].death_data.run_duration_max); 79 EXPECT_EQ(run_ms, process_data.tasks[0].death_data.run_duration_sample); 80 EXPECT_EQ(count * queue_ms, 81 process_data.tasks[0].death_data.queue_duration_sum); 82 EXPECT_EQ(queue_ms, process_data.tasks[0].death_data.queue_duration_max); 83 EXPECT_EQ(queue_ms, process_data.tasks[0].death_data.queue_duration_sample); 84 85 EXPECT_EQ(death_thread, process_data.tasks[0].death_thread_name); 86 87 EXPECT_EQ(0u, process_data.descendants.size()); 88 89 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); 90 } 91}; 92 93TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { 94 // Minimal test doesn't even create any tasks. 95 if (!ThreadData::InitializeAndSetTrackingStatus( 96 ThreadData::PROFILING_CHILDREN_ACTIVE)) 97 return; 98 99 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. 100 ThreadData* data = ThreadData::Get(); 101 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. 102 ASSERT_TRUE(data); 103 EXPECT_FALSE(data->next()); 104 EXPECT_EQ(data, ThreadData::Get()); 105 ThreadData::BirthMap birth_map; 106 ThreadData::DeathMap death_map; 107 ThreadData::ParentChildSet parent_child_set; 108 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 109 EXPECT_EQ(0u, birth_map.size()); 110 EXPECT_EQ(0u, death_map.size()); 111 EXPECT_EQ(0u, parent_child_set.size()); 112 113 // Clean up with no leaking. 114 Reset(); 115 116 // Do it again, just to be sure we reset state completely. 117 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus( 118 ThreadData::PROFILING_CHILDREN_ACTIVE)); 119 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. 120 data = ThreadData::Get(); 121 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. 122 ASSERT_TRUE(data); 123 EXPECT_FALSE(data->next()); 124 EXPECT_EQ(data, ThreadData::Get()); 125 birth_map.clear(); 126 death_map.clear(); 127 parent_child_set.clear(); 128 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 129 EXPECT_EQ(0u, birth_map.size()); 130 EXPECT_EQ(0u, death_map.size()); 131 EXPECT_EQ(0u, parent_child_set.size()); 132} 133 134TEST_F(TrackedObjectsTest, TinyStartupShutdown) { 135 if (!ThreadData::InitializeAndSetTrackingStatus( 136 ThreadData::PROFILING_CHILDREN_ACTIVE)) 137 return; 138 139 // Instigate tracking on a single tracked object, on our thread. 140 const char kFunction[] = "TinyStartupShutdown"; 141 Location location(kFunction, kFile, kLineNumber, NULL); 142 Births* first_birth = ThreadData::TallyABirthIfActive(location); 143 144 ThreadData* data = ThreadData::first(); 145 ASSERT_TRUE(data); 146 EXPECT_FALSE(data->next()); 147 EXPECT_EQ(data, ThreadData::Get()); 148 ThreadData::BirthMap birth_map; 149 ThreadData::DeathMap death_map; 150 ThreadData::ParentChildSet parent_child_set; 151 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 152 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. 153 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. 154 EXPECT_EQ(0u, death_map.size()); // No deaths. 155 EXPECT_EQ(0u, parent_child_set.size()); // No children. 156 157 158 // Now instigate another birth, while we are timing the run of the first 159 // execution. 160 ThreadData::NowForStartOfRun(first_birth); 161 // Create a child (using the same birth location). 162 // TrackingInfo will call TallyABirth() during construction. 163 base::TimeTicks kBogusBirthTime; 164 base::TrackingInfo pending_task(location, kBogusBirthTime); 165 TrackedTime start_time(pending_task.time_posted); 166 // Finally conclude the outer run. 167 TrackedTime end_time = ThreadData::NowForEndOfRun(); 168 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time, 169 end_time); 170 171 birth_map.clear(); 172 death_map.clear(); 173 parent_child_set.clear(); 174 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 175 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. 176 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. 177 EXPECT_EQ(1u, death_map.size()); // 1 location. 178 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. 179 if (ThreadData::TrackingParentChildStatus()) { 180 EXPECT_EQ(1u, parent_child_set.size()); // 1 child. 181 EXPECT_EQ(parent_child_set.begin()->first, 182 parent_child_set.begin()->second); 183 } else { 184 EXPECT_EQ(0u, parent_child_set.size()); // no stats. 185 } 186 187 // The births were at the same location as the one known death. 188 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); 189 190 ProcessDataSnapshot process_data; 191 ThreadData::Snapshot(false, &process_data); 192 193 const int32 time_elapsed = (end_time - start_time).InMilliseconds(); 194 ASSERT_EQ(1u, process_data.tasks.size()); 195 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name); 196 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name); 197 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number); 198 EXPECT_EQ(kWorkerThreadName, process_data.tasks[0].birth.thread_name); 199 EXPECT_EQ(1, process_data.tasks[0].death_data.count); 200 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_sum); 201 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_max); 202 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_sample); 203 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_sum); 204 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_max); 205 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_sample); 206 EXPECT_EQ(kWorkerThreadName, process_data.tasks[0].death_thread_name); 207 208 if (ThreadData::TrackingParentChildStatus()) { 209 ASSERT_EQ(1u, process_data.descendants.size()); 210 EXPECT_EQ(kFile, process_data.descendants[0].parent.location.file_name); 211 EXPECT_EQ(kFunction, 212 process_data.descendants[0].parent.location.function_name); 213 EXPECT_EQ(kLineNumber, 214 process_data.descendants[0].parent.location.line_number); 215 EXPECT_EQ(kWorkerThreadName, 216 process_data.descendants[0].parent.thread_name); 217 EXPECT_EQ(kFile, process_data.descendants[0].child.location.file_name); 218 EXPECT_EQ(kFunction, 219 process_data.descendants[0].child.location.function_name); 220 EXPECT_EQ(kLineNumber, 221 process_data.descendants[0].child.location.line_number); 222 EXPECT_EQ(kWorkerThreadName, process_data.descendants[0].child.thread_name); 223 } else { 224 EXPECT_EQ(0u, process_data.descendants.size()); 225 } 226} 227 228TEST_F(TrackedObjectsTest, DeathDataTest) { 229 if (!ThreadData::InitializeAndSetTrackingStatus( 230 ThreadData::PROFILING_CHILDREN_ACTIVE)) 231 return; 232 233 scoped_ptr<DeathData> data(new DeathData()); 234 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); 235 EXPECT_EQ(data->run_duration_sum(), 0); 236 EXPECT_EQ(data->run_duration_sample(), 0); 237 EXPECT_EQ(data->queue_duration_sum(), 0); 238 EXPECT_EQ(data->queue_duration_sample(), 0); 239 EXPECT_EQ(data->count(), 0); 240 241 int32 run_ms = 42; 242 int32 queue_ms = 8; 243 244 const int kUnrandomInt = 0; // Fake random int that ensure we sample data. 245 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); 246 EXPECT_EQ(data->run_duration_sum(), run_ms); 247 EXPECT_EQ(data->run_duration_sample(), run_ms); 248 EXPECT_EQ(data->queue_duration_sum(), queue_ms); 249 EXPECT_EQ(data->queue_duration_sample(), queue_ms); 250 EXPECT_EQ(data->count(), 1); 251 252 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); 253 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); 254 EXPECT_EQ(data->run_duration_sample(), run_ms); 255 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); 256 EXPECT_EQ(data->queue_duration_sample(), queue_ms); 257 EXPECT_EQ(data->count(), 2); 258 259 DeathDataSnapshot snapshot(*data); 260 EXPECT_EQ(2, snapshot.count); 261 EXPECT_EQ(2 * run_ms, snapshot.run_duration_sum); 262 EXPECT_EQ(run_ms, snapshot.run_duration_max); 263 EXPECT_EQ(run_ms, snapshot.run_duration_sample); 264 EXPECT_EQ(2 * queue_ms, snapshot.queue_duration_sum); 265 EXPECT_EQ(queue_ms, snapshot.queue_duration_max); 266 EXPECT_EQ(queue_ms, snapshot.queue_duration_sample); 267} 268 269TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotWorkerThread) { 270 // Start in the deactivated state. 271 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) 272 return; 273 274 const char kFunction[] = "DeactivatedBirthOnlyToSnapshotWorkerThread"; 275 Location location(kFunction, kFile, kLineNumber, NULL); 276 TallyABirth(location, std::string()); 277 278 ProcessDataSnapshot process_data; 279 ThreadData::Snapshot(false, &process_data); 280 EXPECT_EQ(0u, process_data.tasks.size()); 281 EXPECT_EQ(0u, process_data.descendants.size()); 282 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); 283} 284 285TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotMainThread) { 286 // Start in the deactivated state. 287 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) 288 return; 289 290 const char kFunction[] = "DeactivatedBirthOnlyToSnapshotMainThread"; 291 Location location(kFunction, kFile, kLineNumber, NULL); 292 TallyABirth(location, kMainThreadName); 293 294 ProcessDataSnapshot process_data; 295 ThreadData::Snapshot(false, &process_data); 296 EXPECT_EQ(0u, process_data.tasks.size()); 297 EXPECT_EQ(0u, process_data.descendants.size()); 298 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); 299} 300 301TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotWorkerThread) { 302 if (!ThreadData::InitializeAndSetTrackingStatus( 303 ThreadData::PROFILING_CHILDREN_ACTIVE)) 304 return; 305 306 const char kFunction[] = "BirthOnlyToSnapshotWorkerThread"; 307 Location location(kFunction, kFile, kLineNumber, NULL); 308 TallyABirth(location, std::string()); 309 310 ProcessDataSnapshot process_data; 311 ThreadData::Snapshot(false, &process_data); 312 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName, 313 kStillAlive, 1, 0, 0); 314} 315 316TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotMainThread) { 317 if (!ThreadData::InitializeAndSetTrackingStatus( 318 ThreadData::PROFILING_CHILDREN_ACTIVE)) 319 return; 320 321 const char kFunction[] = "BirthOnlyToSnapshotMainThread"; 322 Location location(kFunction, kFile, kLineNumber, NULL); 323 TallyABirth(location, kMainThreadName); 324 325 ProcessDataSnapshot process_data; 326 ThreadData::Snapshot(false, &process_data); 327 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, kStillAlive, 328 1, 0, 0); 329} 330 331TEST_F(TrackedObjectsTest, LifeCycleToSnapshotMainThread) { 332 if (!ThreadData::InitializeAndSetTrackingStatus( 333 ThreadData::PROFILING_CHILDREN_ACTIVE)) 334 return; 335 336 const char kFunction[] = "LifeCycleToSnapshotMainThread"; 337 Location location(kFunction, kFile, kLineNumber, NULL); 338 TallyABirth(location, kMainThreadName); 339 340 const base::TimeTicks kTimePosted = base::TimeTicks() + 341 base::TimeDelta::FromMilliseconds(1); 342 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 343 // TrackingInfo will call TallyABirth() during construction. 344 base::TrackingInfo pending_task(location, kDelayedStartTime); 345 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 346 347 const TrackedTime kStartOfRun = TrackedTime() + 348 Duration::FromMilliseconds(5); 349 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 350 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 351 kStartOfRun, kEndOfRun); 352 353 ProcessDataSnapshot process_data; 354 ThreadData::Snapshot(false, &process_data); 355 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, 356 kMainThreadName, 1, 2, 4); 357} 358 359// We will deactivate tracking after the birth, and before the death, and 360// demonstrate that the lifecycle is completely tallied. This ensures that 361// our tallied births are matched by tallied deaths (except for when the 362// task is still running, or is queued). 363TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToSnapshotMainThread) { 364 if (!ThreadData::InitializeAndSetTrackingStatus( 365 ThreadData::PROFILING_CHILDREN_ACTIVE)) 366 return; 367 368 const char kFunction[] = "LifeCycleMidDeactivatedToSnapshotMainThread"; 369 Location location(kFunction, kFile, kLineNumber, NULL); 370 TallyABirth(location, kMainThreadName); 371 372 const base::TimeTicks kTimePosted = base::TimeTicks() + 373 base::TimeDelta::FromMilliseconds(1); 374 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 375 // TrackingInfo will call TallyABirth() during construction. 376 base::TrackingInfo pending_task(location, kDelayedStartTime); 377 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 378 379 // Turn off tracking now that we have births. 380 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus( 381 ThreadData::DEACTIVATED)); 382 383 const TrackedTime kStartOfRun = TrackedTime() + 384 Duration::FromMilliseconds(5); 385 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 386 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 387 kStartOfRun, kEndOfRun); 388 389 ProcessDataSnapshot process_data; 390 ThreadData::Snapshot(false, &process_data); 391 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, 392 kMainThreadName, 1, 2, 4); 393} 394 395// We will deactivate tracking before starting a life cycle, and neither 396// the birth nor the death will be recorded. 397TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToSnapshotMainThread) { 398 // Start in the deactivated state. 399 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) 400 return; 401 402 const char kFunction[] = "LifeCyclePreDeactivatedToSnapshotMainThread"; 403 Location location(kFunction, kFile, kLineNumber, NULL); 404 TallyABirth(location, kMainThreadName); 405 406 const base::TimeTicks kTimePosted = base::TimeTicks() + 407 base::TimeDelta::FromMilliseconds(1); 408 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 409 // TrackingInfo will call TallyABirth() during construction. 410 base::TrackingInfo pending_task(location, kDelayedStartTime); 411 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 412 413 const TrackedTime kStartOfRun = TrackedTime() + 414 Duration::FromMilliseconds(5); 415 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 416 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 417 kStartOfRun, kEndOfRun); 418 419 ProcessDataSnapshot process_data; 420 ThreadData::Snapshot(false, &process_data); 421 EXPECT_EQ(0u, process_data.tasks.size()); 422 EXPECT_EQ(0u, process_data.descendants.size()); 423 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); 424} 425 426TEST_F(TrackedObjectsTest, LifeCycleToSnapshotWorkerThread) { 427 if (!ThreadData::InitializeAndSetTrackingStatus( 428 ThreadData::PROFILING_CHILDREN_ACTIVE)) 429 return; 430 431 const char kFunction[] = "LifeCycleToSnapshotWorkerThread"; 432 Location location(kFunction, kFile, kLineNumber, NULL); 433 // Do not delete |birth|. We don't own it. 434 Births* birth = ThreadData::TallyABirthIfActive(location); 435 EXPECT_NE(reinterpret_cast<Births*>(NULL), birth); 436 437 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1); 438 const TrackedTime kStartOfRun = TrackedTime() + 439 Duration::FromMilliseconds(5); 440 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 441 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted, 442 kStartOfRun, kEndOfRun); 443 444 // Call for the ToSnapshot, but tell it to not reset the maxes after scanning. 445 ProcessDataSnapshot process_data; 446 ThreadData::Snapshot(false, &process_data); 447 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName, 448 kWorkerThreadName, 1, 2, 4); 449 450 // Call for the ToSnapshot, but tell it to reset the maxes after scanning. 451 // We'll still get the same values, but the data will be reset (which we'll 452 // see in a moment). 453 ProcessDataSnapshot process_data_pre_reset; 454 ThreadData::Snapshot(true, &process_data_pre_reset); 455 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName, 456 kWorkerThreadName, 1, 2, 4); 457 458 // Call for the ToSnapshot, and now we'll see the result of the last 459 // translation, as the max will have been pushed back to zero. 460 ProcessDataSnapshot process_data_post_reset; 461 ThreadData::Snapshot(true, &process_data_post_reset); 462 ASSERT_EQ(1u, process_data_post_reset.tasks.size()); 463 EXPECT_EQ(kFile, process_data_post_reset.tasks[0].birth.location.file_name); 464 EXPECT_EQ(kFunction, 465 process_data_post_reset.tasks[0].birth.location.function_name); 466 EXPECT_EQ(kLineNumber, 467 process_data_post_reset.tasks[0].birth.location.line_number); 468 EXPECT_EQ(kWorkerThreadName, 469 process_data_post_reset.tasks[0].birth.thread_name); 470 EXPECT_EQ(1, process_data_post_reset.tasks[0].death_data.count); 471 EXPECT_EQ(2, process_data_post_reset.tasks[0].death_data.run_duration_sum); 472 EXPECT_EQ(0, process_data_post_reset.tasks[0].death_data.run_duration_max); 473 EXPECT_EQ(2, process_data_post_reset.tasks[0].death_data.run_duration_sample); 474 EXPECT_EQ(4, process_data_post_reset.tasks[0].death_data.queue_duration_sum); 475 EXPECT_EQ(0, process_data_post_reset.tasks[0].death_data.queue_duration_max); 476 EXPECT_EQ(4, 477 process_data_post_reset.tasks[0].death_data.queue_duration_sample); 478 EXPECT_EQ(kWorkerThreadName, 479 process_data_post_reset.tasks[0].death_thread_name); 480 EXPECT_EQ(0u, process_data_post_reset.descendants.size()); 481 EXPECT_EQ(base::GetCurrentProcId(), process_data_post_reset.process_id); 482} 483 484TEST_F(TrackedObjectsTest, TwoLives) { 485 if (!ThreadData::InitializeAndSetTrackingStatus( 486 ThreadData::PROFILING_CHILDREN_ACTIVE)) 487 return; 488 489 const char kFunction[] = "TwoLives"; 490 Location location(kFunction, kFile, kLineNumber, NULL); 491 TallyABirth(location, kMainThreadName); 492 493 const base::TimeTicks kTimePosted = base::TimeTicks() + 494 base::TimeDelta::FromMilliseconds(1); 495 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 496 // TrackingInfo will call TallyABirth() during construction. 497 base::TrackingInfo pending_task(location, kDelayedStartTime); 498 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 499 500 const TrackedTime kStartOfRun = TrackedTime() + 501 Duration::FromMilliseconds(5); 502 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 503 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 504 kStartOfRun, kEndOfRun); 505 506 // TrackingInfo will call TallyABirth() during construction. 507 base::TrackingInfo pending_task2(location, kDelayedStartTime); 508 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). 509 510 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, 511 kStartOfRun, kEndOfRun); 512 513 ProcessDataSnapshot process_data; 514 ThreadData::Snapshot(false, &process_data); 515 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, 516 kMainThreadName, 2, 2, 4); 517} 518 519TEST_F(TrackedObjectsTest, DifferentLives) { 520 if (!ThreadData::InitializeAndSetTrackingStatus( 521 ThreadData::PROFILING_CHILDREN_ACTIVE)) 522 return; 523 524 // Use a well named thread. 525 ThreadData::InitializeThreadContext(kMainThreadName); 526 const char kFunction[] = "DifferentLives"; 527 Location location(kFunction, kFile, kLineNumber, NULL); 528 529 const base::TimeTicks kTimePosted = base::TimeTicks() + 530 base::TimeDelta::FromMilliseconds(1); 531 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 532 // TrackingInfo will call TallyABirth() during construction. 533 base::TrackingInfo pending_task(location, kDelayedStartTime); 534 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 535 536 const TrackedTime kStartOfRun = TrackedTime() + 537 Duration::FromMilliseconds(5); 538 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 539 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 540 kStartOfRun, kEndOfRun); 541 542 const int kSecondFakeLineNumber = 999; 543 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); 544 545 // TrackingInfo will call TallyABirth() during construction. 546 base::TrackingInfo pending_task2(second_location, kDelayedStartTime); 547 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). 548 549 ProcessDataSnapshot process_data; 550 ThreadData::Snapshot(false, &process_data); 551 ASSERT_EQ(2u, process_data.tasks.size()); 552 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name); 553 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name); 554 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number); 555 EXPECT_EQ(kMainThreadName, process_data.tasks[0].birth.thread_name); 556 EXPECT_EQ(1, process_data.tasks[0].death_data.count); 557 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_sum); 558 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_max); 559 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_sample); 560 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_sum); 561 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_max); 562 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_sample); 563 EXPECT_EQ(kMainThreadName, process_data.tasks[0].death_thread_name); 564 EXPECT_EQ(kFile, process_data.tasks[1].birth.location.file_name); 565 EXPECT_EQ(kFunction, process_data.tasks[1].birth.location.function_name); 566 EXPECT_EQ(kSecondFakeLineNumber, 567 process_data.tasks[1].birth.location.line_number); 568 EXPECT_EQ(kMainThreadName, process_data.tasks[1].birth.thread_name); 569 EXPECT_EQ(1, process_data.tasks[1].death_data.count); 570 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_sum); 571 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_max); 572 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_sample); 573 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_sum); 574 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_max); 575 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_sample); 576 EXPECT_EQ(kStillAlive, process_data.tasks[1].death_thread_name); 577 EXPECT_EQ(0u, process_data.descendants.size()); 578 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); 579} 580 581} // namespace tracked_objects 582