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