Home | History | Annotate | Download | only in base
      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 
     14 const int kLineNumber = 1776;
     15 const char kFile[] = "FixedUnitTestFileName";
     16 const char kWorkerThreadName[] = "WorkerThread-1";
     17 const char kMainThreadName[] = "SomeMainThreadName";
     18 const char kStillAlive[] = "Still_Alive";
     19 
     20 namespace tracked_objects {
     21 
     22 class 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 
     93 TEST_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 
    134 TEST_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 
    228 TEST_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 
    269 TEST_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 
    285 TEST_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 
    301 TEST_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 
    316 TEST_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 
    331 TEST_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).
    363 TEST_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.
    397 TEST_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 
    426 TEST_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 
    484 TEST_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 
    519 TEST_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