| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Test of classes in the tracked_objects.h classes. | 5 // Test of classes in the tracked_objects.h classes. |
| 6 | 6 |
| 7 #include "base/tracked_objects.h" | 7 #include "base/tracked_objects.h" |
| 8 | 8 |
| 9 #include "base/json/json_writer.h" | |
| 10 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/process_util.h" |
| 11 #include "base/time.h" | 11 #include "base/time.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 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 |
| 14 namespace tracked_objects { | 20 namespace tracked_objects { |
| 15 | 21 |
| 16 class TrackedObjectsTest : public testing::Test { | 22 class TrackedObjectsTest : public testing::Test { |
| 17 protected: | 23 protected: |
| 18 TrackedObjectsTest() { | 24 TrackedObjectsTest() { |
| 19 // On entry, leak any database structures in case they are still in use by | 25 // On entry, leak any database structures in case they are still in use by |
| 20 // prior threads. | 26 // prior threads. |
| 21 ThreadData::ShutdownSingleThreadedCleanup(true); | 27 ThreadData::ShutdownSingleThreadedCleanup(true); |
| 22 } | 28 } |
| 23 | 29 |
| 24 virtual ~TrackedObjectsTest() { | 30 virtual ~TrackedObjectsTest() { |
| 25 // We should not need to leak any structures we create, since we are | 31 // We should not need to leak any structures we create, since we are |
| 26 // single threaded, and carefully accounting for items. | 32 // single threaded, and carefully accounting for items. |
| 27 ThreadData::ShutdownSingleThreadedCleanup(false); | 33 ThreadData::ShutdownSingleThreadedCleanup(false); |
| 28 } | 34 } |
| 29 | 35 |
| 30 // Provide access, since this class is a friend of ThreadData. | 36 // Reset the profiler state. |
| 31 void ShutdownSingleThreadedCleanup(bool leak) { | 37 void Reset() { |
| 32 ThreadData::ShutdownSingleThreadedCleanup(leak); | 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); |
| 33 } | 90 } |
| 34 }; | 91 }; |
| 35 | 92 |
| 36 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { | 93 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { |
| 37 // Minimal test doesn't even create any tasks. | 94 // Minimal test doesn't even create any tasks. |
| 38 if (!ThreadData::InitializeAndSetTrackingStatus( | 95 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 39 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 96 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 40 return; | 97 return; |
| 41 | 98 |
| 42 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. | 99 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. |
| 43 ThreadData* data = ThreadData::Get(); | 100 ThreadData* data = ThreadData::Get(); |
| 44 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. | 101 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. |
| 45 EXPECT_TRUE(data); | 102 ASSERT_TRUE(data); |
| 46 EXPECT_TRUE(!data->next()); | 103 EXPECT_FALSE(data->next()); |
| 47 EXPECT_EQ(data, ThreadData::Get()); | 104 EXPECT_EQ(data, ThreadData::Get()); |
| 48 ThreadData::BirthMap birth_map; | 105 ThreadData::BirthMap birth_map; |
| 49 ThreadData::DeathMap death_map; | 106 ThreadData::DeathMap death_map; |
| 50 ThreadData::ParentChildSet parent_child_set; | 107 ThreadData::ParentChildSet parent_child_set; |
| 51 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); | 108 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
| 52 EXPECT_EQ(0u, birth_map.size()); | 109 EXPECT_EQ(0u, birth_map.size()); |
| 53 EXPECT_EQ(0u, death_map.size()); | 110 EXPECT_EQ(0u, death_map.size()); |
| 54 EXPECT_EQ(0u, parent_child_set.size()); | 111 EXPECT_EQ(0u, parent_child_set.size()); |
| 55 // Cleanup with no leaking. | 112 |
| 56 ShutdownSingleThreadedCleanup(false); | 113 // Clean up with no leaking. |
| 114 Reset(); |
| 57 | 115 |
| 58 // Do it again, just to be sure we reset state completely. | 116 // Do it again, just to be sure we reset state completely. |
| 59 ThreadData::InitializeAndSetTrackingStatus( | 117 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus( |
| 60 ThreadData::PROFILING_CHILDREN_ACTIVE); | 118 ThreadData::PROFILING_CHILDREN_ACTIVE)); |
| 61 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. | 119 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. |
| 62 data = ThreadData::Get(); | 120 data = ThreadData::Get(); |
| 63 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. | 121 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. |
| 64 EXPECT_TRUE(data); | 122 ASSERT_TRUE(data); |
| 65 EXPECT_TRUE(!data->next()); | 123 EXPECT_FALSE(data->next()); |
| 66 EXPECT_EQ(data, ThreadData::Get()); | 124 EXPECT_EQ(data, ThreadData::Get()); |
| 67 birth_map.clear(); | 125 birth_map.clear(); |
| 68 death_map.clear(); | 126 death_map.clear(); |
| 127 parent_child_set.clear(); |
| 69 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); | 128 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
| 70 EXPECT_EQ(0u, birth_map.size()); | 129 EXPECT_EQ(0u, birth_map.size()); |
| 71 EXPECT_EQ(0u, death_map.size()); | 130 EXPECT_EQ(0u, death_map.size()); |
| 72 EXPECT_EQ(0u, parent_child_set.size()); | 131 EXPECT_EQ(0u, parent_child_set.size()); |
| 73 } | 132 } |
| 74 | 133 |
| 75 TEST_F(TrackedObjectsTest, TinyStartupShutdown) { | 134 TEST_F(TrackedObjectsTest, TinyStartupShutdown) { |
| 76 if (!ThreadData::InitializeAndSetTrackingStatus( | 135 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 77 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 136 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 78 return; | 137 return; |
| 79 | 138 |
| 80 // Instigate tracking on a single tracked object, on our thread. | 139 // Instigate tracking on a single tracked object, on our thread. |
| 81 const Location& location = FROM_HERE; | 140 const char kFunction[] = "TinyStartupShutdown"; |
| 141 Location location(kFunction, kFile, kLineNumber, NULL); |
| 82 Births* first_birth = ThreadData::TallyABirthIfActive(location); | 142 Births* first_birth = ThreadData::TallyABirthIfActive(location); |
| 83 | 143 |
| 84 ThreadData* data = ThreadData::first(); | 144 ThreadData* data = ThreadData::first(); |
| 85 ASSERT_TRUE(data); | 145 ASSERT_TRUE(data); |
| 86 EXPECT_TRUE(!data->next()); | 146 EXPECT_FALSE(data->next()); |
| 87 EXPECT_EQ(data, ThreadData::Get()); | 147 EXPECT_EQ(data, ThreadData::Get()); |
| 88 ThreadData::BirthMap birth_map; | 148 ThreadData::BirthMap birth_map; |
| 89 ThreadData::DeathMap death_map; | 149 ThreadData::DeathMap death_map; |
| 90 ThreadData::ParentChildSet parent_child_set; | 150 ThreadData::ParentChildSet parent_child_set; |
| 91 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); | 151 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
| 92 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. | 152 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 93 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. | 153 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. |
| 94 EXPECT_EQ(0u, death_map.size()); // No deaths. | 154 EXPECT_EQ(0u, death_map.size()); // No deaths. |
| 95 EXPECT_EQ(0u, parent_child_set.size()); // No children. | 155 EXPECT_EQ(0u, parent_child_set.size()); // No children. |
| 96 | 156 |
| 97 | 157 |
| 98 // Now instigate another birth, while we are timing the run of the first | 158 // Now instigate another birth, while we are timing the run of the first |
| 99 // execution. | 159 // execution. |
| 100 TrackedTime start_time = | 160 TrackedTime start_time = ThreadData::NowForStartOfRun(first_birth); |
| 101 ThreadData::NowForStartOfRun(first_birth); | |
| 102 // Create a child (using the same birth location). | 161 // Create a child (using the same birth location). |
| 103 // TrackingInfo will call TallyABirth() during construction. | 162 // TrackingInfo will call TallyABirth() during construction. |
| 104 base::TimeTicks kBogusBirthTime; | 163 base::TimeTicks kBogusBirthTime; |
| 105 base::TrackingInfo pending_task(location, kBogusBirthTime); | 164 base::TrackingInfo pending_task(location, kBogusBirthTime); |
| 106 // Finally conclude the outer run. | 165 // Finally conclude the outer run. |
| 107 TrackedTime end_time = ThreadData::NowForEndOfRun(); | 166 TrackedTime end_time = ThreadData::NowForEndOfRun(); |
| 108 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time, | 167 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time, |
| 109 end_time); | 168 end_time); |
| 110 | 169 |
| 111 birth_map.clear(); | 170 birth_map.clear(); |
| 112 death_map.clear(); | 171 death_map.clear(); |
| 113 parent_child_set.clear(); | 172 parent_child_set.clear(); |
| 114 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); | 173 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
| 115 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. | 174 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 116 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. | 175 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. |
| 117 EXPECT_EQ(1u, death_map.size()); // 1 location. | 176 EXPECT_EQ(1u, death_map.size()); // 1 location. |
| 118 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. | 177 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. |
| 119 if (ThreadData::TrackingParentChildStatus()) { | 178 if (ThreadData::TrackingParentChildStatus()) { |
| 120 EXPECT_EQ(1u, parent_child_set.size()); // 1 child. | 179 EXPECT_EQ(1u, parent_child_set.size()); // 1 child. |
| 121 EXPECT_EQ(parent_child_set.begin()->first, | 180 EXPECT_EQ(parent_child_set.begin()->first, |
| 122 parent_child_set.begin()->second); | 181 parent_child_set.begin()->second); |
| 123 } else { | 182 } else { |
| 124 EXPECT_EQ(0u, parent_child_set.size()); // no stats. | 183 EXPECT_EQ(0u, parent_child_set.size()); // no stats. |
| 125 } | 184 } |
| 126 | 185 |
| 127 // The births were at the same location as the one known death. | 186 // The births were at the same location as the one known death. |
| 128 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); | 187 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); |
| 129 } | |
| 130 | 188 |
| 131 TEST_F(TrackedObjectsTest, ParentChildTest) { | 189 ProcessDataSnapshot process_data; |
| 132 if (!ThreadData::InitializeAndSetTrackingStatus( | 190 ThreadData::Snapshot(false, &process_data); |
| 133 ThreadData::PROFILING_CHILDREN_ACTIVE)) | |
| 134 return; | |
| 135 if (!ThreadData::TrackingParentChildStatus()) | |
| 136 return; // Feature not compiled in. | |
| 137 | 191 |
| 138 // Instigate tracking on a single tracked object, on our thread. | 192 const int32 time_elapsed = (end_time - start_time).InMilliseconds(); |
| 139 const int kFakeLineNumber = 1776; | 193 ASSERT_EQ(1u, process_data.tasks.size()); |
| 140 const char* kFile = "FixedUnitTestFileName"; | 194 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name); |
| 141 const char* kFunction = "ParentChildTest"; | 195 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name); |
| 142 Location location(kFunction, kFile, kFakeLineNumber, NULL); | 196 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number); |
| 197 EXPECT_EQ(kWorkerThreadName, process_data.tasks[0].birth.thread_name); |
| 198 EXPECT_EQ(1, process_data.tasks[0].death_data.count); |
| 199 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_sum); |
| 200 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_max); |
| 201 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_sample); |
| 202 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_sum); |
| 203 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_max); |
| 204 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_sample); |
| 205 EXPECT_EQ(kWorkerThreadName, process_data.tasks[0].death_thread_name); |
| 143 | 206 |
| 144 // Now instigate another birth, while we are timing the run of the first | 207 if (ThreadData::TrackingParentChildStatus()) { |
| 145 // execution. | 208 ASSERT_EQ(1u, process_data.descendants.size()); |
| 146 | 209 EXPECT_EQ(kFile, process_data.descendants[0].parent.location.file_name); |
| 147 // Create a child (using the same birth location). | 210 EXPECT_EQ(kFunction, |
| 148 // TrackingInfo will call TallyABirth() during construction. | 211 process_data.descendants[0].parent.location.function_name); |
| 149 base::TimeTicks kBogusBirthTime; | 212 EXPECT_EQ(kLineNumber, |
| 150 base::TrackingInfo pending_task(location, kBogusBirthTime); | 213 process_data.descendants[0].parent.location.line_number); |
| 151 | 214 EXPECT_EQ(kWorkerThreadName, |
| 152 // Don't conclude the run, so that we don't use the actual timer that we | 215 process_data.descendants[0].parent.thread_name); |
| 153 // started for the outer profile. This way the JSON will not include some | 216 EXPECT_EQ(kFile, process_data.descendants[0].child.location.file_name); |
| 154 // random time. | 217 EXPECT_EQ(kFunction, |
| 155 ThreadData* data = ThreadData::first(); | 218 process_data.descendants[0].child.location.function_name); |
| 156 ASSERT_TRUE(data); | 219 EXPECT_EQ(kLineNumber, |
| 157 EXPECT_TRUE(!data->next()); | 220 process_data.descendants[0].child.location.line_number); |
| 158 EXPECT_EQ(data, ThreadData::Get()); | 221 EXPECT_EQ(kWorkerThreadName, process_data.descendants[0].child.thread_name); |
| 159 | 222 } else { |
| 160 ThreadData::BirthMap birth_map; | 223 EXPECT_EQ(0u, process_data.descendants.size()); |
| 161 ThreadData::DeathMap death_map; | 224 } |
| 162 ThreadData::ParentChildSet parent_child_set; | |
| 163 | |
| 164 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); | |
| 165 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. | |
| 166 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. | |
| 167 EXPECT_EQ(0u, death_map.size()); // No status yet. | |
| 168 // Just like TinyStartupShutdown test. | |
| 169 EXPECT_EQ(1u, parent_child_set.size()); // 1 child. | |
| 170 EXPECT_EQ(parent_child_set.begin()->first, | |
| 171 parent_child_set.begin()->second); | |
| 172 | |
| 173 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | |
| 174 std::string json; | |
| 175 base::JSONWriter::Write(value.get(), &json); | |
| 176 std::string birth_only_result = "{" | |
| 177 "\"descendants\":[" | |
| 178 "{" | |
| 179 "\"child_location\":{" | |
| 180 "\"file_name\":\"FixedUnitTestFileName\"," | |
| 181 "\"function_name\":\"ParentChildTest\"," | |
| 182 "\"line_number\":1776" | |
| 183 "}," | |
| 184 "\"child_thread\":\"WorkerThread-1\"," | |
| 185 "\"parent_location\":{" | |
| 186 "\"file_name\":\"FixedUnitTestFileName\"," | |
| 187 "\"function_name\":\"ParentChildTest\"," | |
| 188 "\"line_number\":1776" | |
| 189 "}," | |
| 190 "\"parent_thread\":\"WorkerThread-1\"" | |
| 191 "}" | |
| 192 "]," | |
| 193 "\"list\":[" | |
| 194 "{" | |
| 195 "\"birth_thread\":\"WorkerThread-1\"," | |
| 196 "\"death_data\":{" | |
| 197 "\"count\":2," | |
| 198 "\"queue_ms\":0," | |
| 199 "\"queue_ms_max\":0," | |
| 200 "\"queue_ms_sample\":0," | |
| 201 "\"run_ms\":0," | |
| 202 "\"run_ms_max\":0," | |
| 203 "\"run_ms_sample\":0" | |
| 204 "}," | |
| 205 "\"death_thread\":\"Still_Alive\"," | |
| 206 "\"location\":{" | |
| 207 "\"file_name\":\"FixedUnitTestFileName\"," | |
| 208 "\"function_name\":\"ParentChildTest\"," | |
| 209 "\"line_number\":1776" | |
| 210 "}" | |
| 211 "}" | |
| 212 "]" | |
| 213 "}"; | |
| 214 EXPECT_EQ(json, birth_only_result); | |
| 215 } | 225 } |
| 216 | 226 |
| 217 TEST_F(TrackedObjectsTest, DeathDataTest) { | 227 TEST_F(TrackedObjectsTest, DeathDataTest) { |
| 218 if (!ThreadData::InitializeAndSetTrackingStatus( | 228 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 219 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 229 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 220 return; | 230 return; |
| 221 | 231 |
| 222 scoped_ptr<DeathData> data(new DeathData()); | 232 scoped_ptr<DeathData> data(new DeathData()); |
| 223 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); | 233 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); |
| 224 EXPECT_EQ(data->run_duration_sum(), 0); | 234 EXPECT_EQ(data->run_duration_sum(), 0); |
| 225 EXPECT_EQ(data->run_duration_sample(), 0); | 235 EXPECT_EQ(data->run_duration_sample(), 0); |
| 226 EXPECT_EQ(data->queue_duration_sum(), 0); | 236 EXPECT_EQ(data->queue_duration_sum(), 0); |
| 227 EXPECT_EQ(data->queue_duration_sample(), 0); | 237 EXPECT_EQ(data->queue_duration_sample(), 0); |
| 228 EXPECT_EQ(data->count(), 0); | 238 EXPECT_EQ(data->count(), 0); |
| 229 | 239 |
| 230 int32 run_ms = 42; | 240 int32 run_ms = 42; |
| 231 int32 queue_ms = 8; | 241 int32 queue_ms = 8; |
| 232 | 242 |
| 233 const int kUnrandomInt = 0; // Fake random int that ensure we sample data. | 243 const int kUnrandomInt = 0; // Fake random int that ensure we sample data. |
| 234 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); | 244 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); |
| 235 EXPECT_EQ(data->run_duration_sum(), run_ms); | 245 EXPECT_EQ(data->run_duration_sum(), run_ms); |
| 236 EXPECT_EQ(data->run_duration_sample(), run_ms); | 246 EXPECT_EQ(data->run_duration_sample(), run_ms); |
| 237 EXPECT_EQ(data->queue_duration_sum(), queue_ms); | 247 EXPECT_EQ(data->queue_duration_sum(), queue_ms); |
| 238 EXPECT_EQ(data->queue_duration_sample(), queue_ms); | 248 EXPECT_EQ(data->queue_duration_sample(), queue_ms); |
| 239 EXPECT_EQ(data->count(), 1); | 249 EXPECT_EQ(data->count(), 1); |
| 240 | 250 |
| 241 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); | 251 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); |
| 242 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); | 252 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); |
| 243 EXPECT_EQ(data->run_duration_sample(), run_ms); | 253 EXPECT_EQ(data->run_duration_sample(), run_ms); |
| 244 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); | 254 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); |
| 245 EXPECT_EQ(data->queue_duration_sample(), queue_ms); | 255 EXPECT_EQ(data->queue_duration_sample(), queue_ms); |
| 246 EXPECT_EQ(data->count(), 2); | 256 EXPECT_EQ(data->count(), 2); |
| 247 | 257 |
| 248 scoped_ptr<base::DictionaryValue> dictionary(data->ToValue()); | 258 DeathDataSnapshot snapshot(*data); |
| 249 int integer; | 259 EXPECT_EQ(2, snapshot.count); |
| 250 EXPECT_TRUE(dictionary->GetInteger("run_ms", &integer)); | 260 EXPECT_EQ(2 * run_ms, snapshot.run_duration_sum); |
| 251 EXPECT_EQ(integer, 2 * run_ms); | 261 EXPECT_EQ(run_ms, snapshot.run_duration_max); |
| 252 EXPECT_TRUE(dictionary->GetInteger("run_ms_sample", &integer)); | 262 EXPECT_EQ(run_ms, snapshot.run_duration_sample); |
| 253 EXPECT_EQ(integer, run_ms); | 263 EXPECT_EQ(2 * queue_ms, snapshot.queue_duration_sum); |
| 254 EXPECT_TRUE(dictionary->GetInteger("queue_ms", &integer)); | 264 EXPECT_EQ(queue_ms, snapshot.queue_duration_max); |
| 255 EXPECT_EQ(integer, 2 * queue_ms); | 265 EXPECT_EQ(queue_ms, snapshot.queue_duration_sample); |
| 256 EXPECT_TRUE(dictionary->GetInteger("queue_ms_sample", &integer)); | |
| 257 EXPECT_EQ(integer, queue_ms); | |
| 258 EXPECT_TRUE(dictionary->GetInteger("count", &integer)); | |
| 259 EXPECT_EQ(integer, 2); | |
| 260 | |
| 261 scoped_ptr<base::Value> value(data->ToValue()); | |
| 262 std::string json; | |
| 263 base::JSONWriter::Write(value.get(), &json); | |
| 264 std::string birth_only_result = "{" | |
| 265 "\"count\":2," | |
| 266 "\"queue_ms\":16," | |
| 267 "\"queue_ms_max\":8," | |
| 268 "\"queue_ms_sample\":8," | |
| 269 "\"run_ms\":84," | |
| 270 "\"run_ms_max\":42," | |
| 271 "\"run_ms_sample\":42" | |
| 272 "}"; | |
| 273 EXPECT_EQ(birth_only_result, json); | |
| 274 } | 266 } |
| 275 | 267 |
| 276 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueWorkerThread) { | 268 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotWorkerThread) { |
| 277 // Transition to Deactivated state before doing anything. | |
| 278 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) | |
| 279 return; | |
| 280 // We don't initialize system with a thread name, so we're viewed as a worker | |
| 281 // thread. | |
| 282 const int kFakeLineNumber = 173; | |
| 283 const char* kFile = "FixedFileName"; | |
| 284 const char* kFunction = "BirthOnlyToValueWorkerThread"; | |
| 285 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 286 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 287 // We should now see a NULL birth record. | |
| 288 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); | |
| 289 | |
| 290 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | |
| 291 std::string json; | |
| 292 base::JSONWriter::Write(value.get(), &json); | |
| 293 std::string birth_only_result = "{" | |
| 294 "\"descendants\":[" | |
| 295 "]," | |
| 296 "\"list\":[" | |
| 297 "]" | |
| 298 "}"; | |
| 299 EXPECT_EQ(json, birth_only_result); | |
| 300 } | |
| 301 | |
| 302 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueMainThread) { | |
| 303 // Start in the deactivated state. | 269 // Start in the deactivated state. |
| 304 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) | 270 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) |
| 305 return; | 271 return; |
| 306 | 272 |
| 307 // Use a well named thread. | 273 const char kFunction[] = "DeactivatedBirthOnlyToSnapshotWorkerThread"; |
| 308 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 274 Location location(kFunction, kFile, kLineNumber, NULL); |
| 309 const int kFakeLineNumber = 173; | 275 TallyABirth(location, std::string()); |
| 310 const char* kFile = "FixedFileName"; | |
| 311 const char* kFunction = "BirthOnlyToValueMainThread"; | |
| 312 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 313 // Do not delete birth. We don't own it. | |
| 314 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 315 // We expect to not get a birth record. | |
| 316 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); | |
| 317 | 276 |
| 318 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 277 ProcessDataSnapshot process_data; |
| 319 std::string json; | 278 ThreadData::Snapshot(false, &process_data); |
| 320 base::JSONWriter::Write(value.get(), &json); | 279 EXPECT_EQ(0u, process_data.tasks.size()); |
| 321 std::string birth_only_result = "{" | 280 EXPECT_EQ(0u, process_data.descendants.size()); |
| 322 "\"descendants\":[" | 281 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); |
| 323 "]," | |
| 324 "\"list\":[" | |
| 325 "]" | |
| 326 "}"; | |
| 327 EXPECT_EQ(json, birth_only_result); | |
| 328 } | 282 } |
| 329 | 283 |
| 330 TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) { | 284 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotMainThread) { |
| 331 if (!ThreadData::InitializeAndSetTrackingStatus( | 285 // Start in the deactivated state. |
| 332 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 286 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) |
| 333 return; | 287 return; |
| 334 // We don't initialize system with a thread name, so we're viewed as a worker | |
| 335 // thread. | |
| 336 const int kFakeLineNumber = 173; | |
| 337 const char* kFile = "FixedFileName"; | |
| 338 const char* kFunction = "BirthOnlyToValueWorkerThread"; | |
| 339 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 340 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 341 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 342 | 288 |
| 343 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 289 const char kFunction[] = "DeactivatedBirthOnlyToSnapshotMainThread"; |
| 344 std::string json; | 290 Location location(kFunction, kFile, kLineNumber, NULL); |
| 345 base::JSONWriter::Write(value.get(), &json); | 291 TallyABirth(location, kMainThreadName); |
| 346 std::string birth_only_result = "{" | 292 |
| 347 "\"descendants\":[" | 293 ProcessDataSnapshot process_data; |
| 348 "]," | 294 ThreadData::Snapshot(false, &process_data); |
| 349 "\"list\":[" | 295 EXPECT_EQ(0u, process_data.tasks.size()); |
| 350 "{" | 296 EXPECT_EQ(0u, process_data.descendants.size()); |
| 351 "\"birth_thread\":\"WorkerThread-1\"," | 297 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); |
| 352 "\"death_data\":{" | |
| 353 "\"count\":1," | |
| 354 "\"queue_ms\":0," | |
| 355 "\"queue_ms_max\":0," | |
| 356 "\"queue_ms_sample\":0," | |
| 357 "\"run_ms\":0," | |
| 358 "\"run_ms_max\":0," | |
| 359 "\"run_ms_sample\":0" | |
| 360 "}," | |
| 361 "\"death_thread\":\"Still_Alive\"," | |
| 362 "\"location\":{" | |
| 363 "\"file_name\":\"FixedFileName\"," | |
| 364 "\"function_name\":\"BirthOnlyToValueWorkerThread\"," | |
| 365 "\"line_number\":173" | |
| 366 "}" | |
| 367 "}" | |
| 368 "]" | |
| 369 "}"; | |
| 370 EXPECT_EQ(json, birth_only_result); | |
| 371 } | 298 } |
| 372 | 299 |
| 373 TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) { | 300 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotWorkerThread) { |
| 374 if (!ThreadData::InitializeAndSetTrackingStatus( | 301 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 375 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 302 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 376 return; | 303 return; |
| 377 | 304 |
| 378 // Use a well named thread. | 305 const char kFunction[] = "BirthOnlyToSnapshotWorkerThread"; |
| 379 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 306 Location location(kFunction, kFile, kLineNumber, NULL); |
| 380 const int kFakeLineNumber = 173; | 307 TallyABirth(location, std::string()); |
| 381 const char* kFile = "FixedFileName"; | |
| 382 const char* kFunction = "BirthOnlyToValueMainThread"; | |
| 383 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 384 // Do not delete birth. We don't own it. | |
| 385 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 386 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 387 | 308 |
| 388 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 309 ProcessDataSnapshot process_data; |
| 389 std::string json; | 310 ThreadData::Snapshot(false, &process_data); |
| 390 base::JSONWriter::Write(value.get(), &json); | 311 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName, |
| 391 std::string birth_only_result = "{" | 312 kStillAlive, 1, 0, 0); |
| 392 "\"descendants\":[" | |
| 393 "]," | |
| 394 "\"list\":[" | |
| 395 "{" | |
| 396 "\"birth_thread\":\"SomeMainThreadName\"," | |
| 397 "\"death_data\":{" | |
| 398 "\"count\":1," | |
| 399 "\"queue_ms\":0," | |
| 400 "\"queue_ms_max\":0," | |
| 401 "\"queue_ms_sample\":0," | |
| 402 "\"run_ms\":0," | |
| 403 "\"run_ms_max\":0," | |
| 404 "\"run_ms_sample\":0" | |
| 405 "}," | |
| 406 "\"death_thread\":\"Still_Alive\"," | |
| 407 "\"location\":{" | |
| 408 "\"file_name\":\"FixedFileName\"," | |
| 409 "\"function_name\":\"BirthOnlyToValueMainThread\"," | |
| 410 "\"line_number\":173" | |
| 411 "}" | |
| 412 "}" | |
| 413 "]" | |
| 414 "}"; | |
| 415 EXPECT_EQ(json, birth_only_result); | |
| 416 } | 313 } |
| 417 | 314 |
| 418 TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) { | 315 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotMainThread) { |
| 419 if (!ThreadData::InitializeAndSetTrackingStatus( | 316 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 420 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 317 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 421 return; | 318 return; |
| 422 | 319 |
| 423 // Use a well named thread. | 320 const char kFunction[] = "BirthOnlyToSnapshotMainThread"; |
| 424 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 321 Location location(kFunction, kFile, kLineNumber, NULL); |
| 425 const int kFakeLineNumber = 236; | 322 TallyABirth(location, kMainThreadName); |
| 426 const char* kFile = "FixedFileName"; | |
| 427 const char* kFunction = "LifeCycleToValueMainThread"; | |
| 428 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 429 // Do not delete birth. We don't own it. | |
| 430 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 431 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 432 | 323 |
| 433 const base::TimeTicks kTimePosted = base::TimeTicks() | 324 ProcessDataSnapshot process_data; |
| 434 + base::TimeDelta::FromMilliseconds(1); | 325 ThreadData::Snapshot(false, &process_data); |
| 326 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, kStillAlive, |
| 327 1, 0, 0); |
| 328 } |
| 329 |
| 330 TEST_F(TrackedObjectsTest, LifeCycleToSnapshotMainThread) { |
| 331 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 332 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 333 return; |
| 334 |
| 335 const char kFunction[] = "LifeCycleToSnapshotMainThread"; |
| 336 Location location(kFunction, kFile, kLineNumber, NULL); |
| 337 TallyABirth(location, kMainThreadName); |
| 338 |
| 339 const base::TimeTicks kTimePosted = base::TimeTicks() + |
| 340 base::TimeDelta::FromMilliseconds(1); |
| 435 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 341 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 436 // TrackingInfo will call TallyABirth() during construction. | 342 // TrackingInfo will call TallyABirth() during construction. |
| 437 base::TrackingInfo pending_task(location, kDelayedStartTime); | 343 base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 438 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 344 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 439 | 345 |
| 440 const TrackedTime kStartOfRun = TrackedTime() + | 346 const TrackedTime kStartOfRun = TrackedTime() + |
| 441 Duration::FromMilliseconds(5); | 347 Duration::FromMilliseconds(5); |
| 442 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 348 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 443 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | 349 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 444 kStartOfRun, kEndOfRun); | 350 kStartOfRun, kEndOfRun); |
| 445 | 351 |
| 446 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 352 ProcessDataSnapshot process_data; |
| 447 std::string json; | 353 ThreadData::Snapshot(false, &process_data); |
| 448 base::JSONWriter::Write(value.get(), &json); | 354 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, |
| 449 std::string one_line_result = "{" | 355 kMainThreadName, 1, 2, 4); |
| 450 "\"descendants\":[" | |
| 451 "]," | |
| 452 "\"list\":[" | |
| 453 "{" | |
| 454 "\"birth_thread\":\"SomeMainThreadName\"," | |
| 455 "\"death_data\":{" | |
| 456 "\"count\":1," | |
| 457 "\"queue_ms\":4," | |
| 458 "\"queue_ms_max\":4," | |
| 459 "\"queue_ms_sample\":4," | |
| 460 "\"run_ms\":2," | |
| 461 "\"run_ms_max\":2," | |
| 462 "\"run_ms_sample\":2" | |
| 463 "}," | |
| 464 "\"death_thread\":\"SomeMainThreadName\"," | |
| 465 "\"location\":{" | |
| 466 "\"file_name\":\"FixedFileName\"," | |
| 467 "\"function_name\":\"LifeCycleToValueMainThread\"," | |
| 468 "\"line_number\":236" | |
| 469 "}" | |
| 470 "}" | |
| 471 "]" | |
| 472 "}"; | |
| 473 EXPECT_EQ(one_line_result, json); | |
| 474 } | 356 } |
| 475 | 357 |
| 476 // We will deactivate tracking after the birth, and before the death, and | 358 // We will deactivate tracking after the birth, and before the death, and |
| 477 // demonstrate that the lifecycle is completely tallied. This ensures that | 359 // demonstrate that the lifecycle is completely tallied. This ensures that |
| 478 // our tallied births are matched by tallied deaths (except for when the | 360 // our tallied births are matched by tallied deaths (except for when the |
| 479 // task is still running, or is queued). | 361 // task is still running, or is queued). |
| 480 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToValueMainThread) { | 362 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToSnapshotMainThread) { |
| 481 if (!ThreadData::InitializeAndSetTrackingStatus( | 363 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 482 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 364 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 483 return; | 365 return; |
| 484 | 366 |
| 485 // Use a well named thread. | 367 const char kFunction[] = "LifeCycleMidDeactivatedToSnapshotMainThread"; |
| 486 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 368 Location location(kFunction, kFile, kLineNumber, NULL); |
| 487 const int kFakeLineNumber = 236; | 369 TallyABirth(location, kMainThreadName); |
| 488 const char* kFile = "FixedFileName"; | |
| 489 const char* kFunction = "LifeCycleToValueMainThread"; | |
| 490 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 491 // Do not delete birth. We don't own it. | |
| 492 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 493 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 494 | 370 |
| 495 const base::TimeTicks kTimePosted = base::TimeTicks() | 371 const base::TimeTicks kTimePosted = base::TimeTicks() + |
| 496 + base::TimeDelta::FromMilliseconds(1); | 372 base::TimeDelta::FromMilliseconds(1); |
| 497 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 373 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 498 // TrackingInfo will call TallyABirth() during construction. | 374 // TrackingInfo will call TallyABirth() during construction. |
| 499 base::TrackingInfo pending_task(location, kDelayedStartTime); | 375 base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 500 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 376 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 501 | 377 |
| 502 // Turn off tracking now that we have births. | 378 // Turn off tracking now that we have births. |
| 503 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus( | 379 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus( |
| 504 ThreadData::DEACTIVATED)); | 380 ThreadData::DEACTIVATED)); |
| 505 | 381 |
| 506 const TrackedTime kStartOfRun = TrackedTime() + | 382 const TrackedTime kStartOfRun = TrackedTime() + |
| 507 Duration::FromMilliseconds(5); | 383 Duration::FromMilliseconds(5); |
| 508 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 384 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 509 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | 385 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 510 kStartOfRun, kEndOfRun); | 386 kStartOfRun, kEndOfRun); |
| 511 | 387 |
| 512 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 388 ProcessDataSnapshot process_data; |
| 513 std::string json; | 389 ThreadData::Snapshot(false, &process_data); |
| 514 base::JSONWriter::Write(value.get(), &json); | 390 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, |
| 515 std::string one_line_result = "{" | 391 kMainThreadName, 1, 2, 4); |
| 516 "\"descendants\":[" | |
| 517 "]," | |
| 518 "\"list\":[" | |
| 519 "{" | |
| 520 "\"birth_thread\":\"SomeMainThreadName\"," | |
| 521 "\"death_data\":{" | |
| 522 "\"count\":1," | |
| 523 "\"queue_ms\":4," | |
| 524 "\"queue_ms_max\":4," | |
| 525 "\"queue_ms_sample\":4," | |
| 526 "\"run_ms\":2," | |
| 527 "\"run_ms_max\":2," | |
| 528 "\"run_ms_sample\":2" | |
| 529 "}," | |
| 530 "\"death_thread\":\"SomeMainThreadName\"," | |
| 531 "\"location\":{" | |
| 532 "\"file_name\":\"FixedFileName\"," | |
| 533 "\"function_name\":\"LifeCycleToValueMainThread\"," | |
| 534 "\"line_number\":236" | |
| 535 "}" | |
| 536 "}" | |
| 537 "]" | |
| 538 "}"; | |
| 539 EXPECT_EQ(one_line_result, json); | |
| 540 } | 392 } |
| 541 | 393 |
| 542 // We will deactivate tracking before starting a life cycle, and neither | 394 // We will deactivate tracking before starting a life cycle, and neither |
| 543 // the birth nor the death will be recorded. | 395 // the birth nor the death will be recorded. |
| 544 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToValueMainThread) { | 396 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToSnapshotMainThread) { |
| 397 // Start in the deactivated state. |
| 545 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) | 398 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) |
| 546 return; | 399 return; |
| 547 | 400 |
| 548 // Use a well named thread. | 401 const char kFunction[] = "LifeCyclePreDeactivatedToSnapshotMainThread"; |
| 549 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 402 Location location(kFunction, kFile, kLineNumber, NULL); |
| 550 const int kFakeLineNumber = 236; | 403 TallyABirth(location, kMainThreadName); |
| 551 const char* kFile = "FixedFileName"; | |
| 552 const char* kFunction = "LifeCycleToValueMainThread"; | |
| 553 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 554 // Do not delete birth. We don't own it. | |
| 555 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 556 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); | |
| 557 | 404 |
| 558 const base::TimeTicks kTimePosted = base::TimeTicks() | 405 const base::TimeTicks kTimePosted = base::TimeTicks() + |
| 559 + base::TimeDelta::FromMilliseconds(1); | 406 base::TimeDelta::FromMilliseconds(1); |
| 560 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 407 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 561 // TrackingInfo will call TallyABirth() during construction. | 408 // TrackingInfo will call TallyABirth() during construction. |
| 562 base::TrackingInfo pending_task(location, kDelayedStartTime); | 409 base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 563 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 410 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 564 | 411 |
| 565 const TrackedTime kStartOfRun = TrackedTime() + | 412 const TrackedTime kStartOfRun = TrackedTime() + |
| 566 Duration::FromMilliseconds(5); | 413 Duration::FromMilliseconds(5); |
| 567 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 414 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 568 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | 415 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 569 kStartOfRun, kEndOfRun); | 416 kStartOfRun, kEndOfRun); |
| 570 | 417 |
| 571 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 418 ProcessDataSnapshot process_data; |
| 572 std::string json; | 419 ThreadData::Snapshot(false, &process_data); |
| 573 base::JSONWriter::Write(value.get(), &json); | 420 EXPECT_EQ(0u, process_data.tasks.size()); |
| 574 std::string one_line_result = "{" | 421 EXPECT_EQ(0u, process_data.descendants.size()); |
| 575 "\"descendants\":[" | 422 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); |
| 576 "]," | |
| 577 "\"list\":[" | |
| 578 "]" | |
| 579 "}"; | |
| 580 EXPECT_EQ(one_line_result, json); | |
| 581 } | 423 } |
| 582 | 424 |
| 583 TEST_F(TrackedObjectsTest, LifeCycleToValueWorkerThread) { | 425 TEST_F(TrackedObjectsTest, LifeCycleToSnapshotWorkerThread) { |
| 584 if (!ThreadData::InitializeAndSetTrackingStatus( | 426 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 585 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 427 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 586 return; | 428 return; |
| 587 | 429 |
| 588 // Don't initialize thread, so that we appear as a worker thread. | 430 const char kFunction[] = "LifeCycleToSnapshotWorkerThread"; |
| 589 // ThreadData::InitializeThreadContext("SomeMainThreadName"); | 431 Location location(kFunction, kFile, kLineNumber, NULL); |
| 590 | 432 // Do not delete |birth|. We don't own it. |
| 591 const int kFakeLineNumber = 236; | |
| 592 const char* kFile = "FixedFileName"; | |
| 593 const char* kFunction = "LifeCycleToValueWorkerThread"; | |
| 594 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 595 // Do not delete birth. We don't own it. | |
| 596 Births* birth = ThreadData::TallyABirthIfActive(location); | 433 Births* birth = ThreadData::TallyABirthIfActive(location); |
| 597 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | 434 EXPECT_NE(reinterpret_cast<Births*>(NULL), birth); |
| 598 | 435 |
| 599 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1); | 436 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1); |
| 600 const TrackedTime kStartOfRun = TrackedTime() + | 437 const TrackedTime kStartOfRun = TrackedTime() + |
| 601 Duration::FromMilliseconds(5); | 438 Duration::FromMilliseconds(5); |
| 602 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 439 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 603 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted, | 440 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted, |
| 604 kStartOfRun, kEndOfRun); | 441 kStartOfRun, kEndOfRun); |
| 605 | 442 |
| 606 // Call for the ToValue, but tell it to not the maxes after scanning. | 443 // Call for the ToSnapshot, but tell it to not reset the maxes after scanning. |
| 607 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 444 ProcessDataSnapshot process_data; |
| 608 std::string json; | 445 ThreadData::Snapshot(false, &process_data); |
| 609 base::JSONWriter::Write(value.get(), &json); | 446 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName, |
| 610 std::string one_line_result = "{" | 447 kWorkerThreadName, 1, 2, 4); |
| 611 "\"descendants\":[" | |
| 612 "]," | |
| 613 "\"list\":[" | |
| 614 "{" | |
| 615 "\"birth_thread\":\"WorkerThread-1\"," | |
| 616 "\"death_data\":{" | |
| 617 "\"count\":1," | |
| 618 "\"queue_ms\":4," | |
| 619 "\"queue_ms_max\":4," | |
| 620 "\"queue_ms_sample\":4," | |
| 621 "\"run_ms\":2," | |
| 622 "\"run_ms_max\":2," | |
| 623 "\"run_ms_sample\":2" | |
| 624 "}," | |
| 625 "\"death_thread\":\"WorkerThread-1\"," | |
| 626 "\"location\":{" | |
| 627 "\"file_name\":\"FixedFileName\"," | |
| 628 "\"function_name\":\"LifeCycleToValueWorkerThread\"," | |
| 629 "\"line_number\":236" | |
| 630 "}" | |
| 631 "}" | |
| 632 "]" | |
| 633 "}"; | |
| 634 EXPECT_EQ(one_line_result, json); | |
| 635 | 448 |
| 636 // Call for the ToValue, but tell it to reset the maxes after scanning. | 449 // Call for the ToSnapshot, but tell it to reset the maxes after scanning. |
| 637 // We'll still get the same values, but the data will be reset (which we'll | 450 // We'll still get the same values, but the data will be reset (which we'll |
| 638 // see in a moment). | 451 // see in a moment). |
| 639 value.reset(ThreadData::ToValue(true)); | 452 ProcessDataSnapshot process_data_pre_reset; |
| 640 base::JSONWriter::Write(value.get(), &json); | 453 ThreadData::Snapshot(true, &process_data_pre_reset); |
| 641 // Result should be unchanged. | 454 ExpectSimpleProcessData(process_data, kFunction, kWorkerThreadName, |
| 642 EXPECT_EQ(one_line_result, json); | 455 kWorkerThreadName, 1, 2, 4); |
| 643 | 456 |
| 644 // Call for the ToValue, and now we'll see the result of the last translation, | 457 // Call for the ToSnapshot, and now we'll see the result of the last |
| 645 // as the max will have been pushed back to zero. | 458 // translation, as the max will have been pushed back to zero. |
| 646 value.reset(ThreadData::ToValue(false)); | 459 ProcessDataSnapshot process_data_post_reset; |
| 647 base::JSONWriter::Write(value.get(), &json); | 460 ThreadData::Snapshot(true, &process_data_post_reset); |
| 648 std::string one_line_result_with_zeros = "{" | 461 ASSERT_EQ(1u, process_data_post_reset.tasks.size()); |
| 649 "\"descendants\":[" | 462 EXPECT_EQ(kFile, process_data_post_reset.tasks[0].birth.location.file_name); |
| 650 "]," | 463 EXPECT_EQ(kFunction, |
| 651 "\"list\":[" | 464 process_data_post_reset.tasks[0].birth.location.function_name); |
| 652 "{" | 465 EXPECT_EQ(kLineNumber, |
| 653 "\"birth_thread\":\"WorkerThread-1\"," | 466 process_data_post_reset.tasks[0].birth.location.line_number); |
| 654 "\"death_data\":{" | 467 EXPECT_EQ(kWorkerThreadName, |
| 655 "\"count\":1," | 468 process_data_post_reset.tasks[0].birth.thread_name); |
| 656 "\"queue_ms\":4," | 469 EXPECT_EQ(1, process_data_post_reset.tasks[0].death_data.count); |
| 657 "\"queue_ms_max\":0," // Note zero here. | 470 EXPECT_EQ(2, process_data_post_reset.tasks[0].death_data.run_duration_sum); |
| 658 "\"queue_ms_sample\":4," | 471 EXPECT_EQ(0, process_data_post_reset.tasks[0].death_data.run_duration_max); |
| 659 "\"run_ms\":2," | 472 EXPECT_EQ(2, process_data_post_reset.tasks[0].death_data.run_duration_sample); |
| 660 "\"run_ms_max\":0," // Note zero here. | 473 EXPECT_EQ(4, process_data_post_reset.tasks[0].death_data.queue_duration_sum); |
| 661 "\"run_ms_sample\":2" | 474 EXPECT_EQ(0, process_data_post_reset.tasks[0].death_data.queue_duration_max); |
| 662 "}," | 475 EXPECT_EQ(4, |
| 663 "\"death_thread\":\"WorkerThread-1\"," | 476 process_data_post_reset.tasks[0].death_data.queue_duration_sample); |
| 664 "\"location\":{" | 477 EXPECT_EQ(kWorkerThreadName, |
| 665 "\"file_name\":\"FixedFileName\"," | 478 process_data_post_reset.tasks[0].death_thread_name); |
| 666 "\"function_name\":\"LifeCycleToValueWorkerThread\"," | 479 EXPECT_EQ(0u, process_data_post_reset.descendants.size()); |
| 667 "\"line_number\":236" | 480 EXPECT_EQ(base::GetCurrentProcId(), process_data_post_reset.process_id); |
| 668 "}" | |
| 669 "}" | |
| 670 "]" | |
| 671 "}"; | |
| 672 EXPECT_EQ(one_line_result_with_zeros, json); | |
| 673 } | 481 } |
| 674 | 482 |
| 675 TEST_F(TrackedObjectsTest, TwoLives) { | 483 TEST_F(TrackedObjectsTest, TwoLives) { |
| 676 if (!ThreadData::InitializeAndSetTrackingStatus( | 484 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 677 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 485 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 678 return; | 486 return; |
| 679 | 487 |
| 680 // Use a well named thread. | 488 const char kFunction[] = "TwoLives"; |
| 681 ThreadData::InitializeThreadContext("SomeFileThreadName"); | 489 Location location(kFunction, kFile, kLineNumber, NULL); |
| 682 const int kFakeLineNumber = 222; | 490 TallyABirth(location, kMainThreadName); |
| 683 const char* kFile = "AnotherFileName"; | |
| 684 const char* kFunction = "TwoLives"; | |
| 685 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 686 // Do not delete birth. We don't own it. | |
| 687 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 688 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 689 | 491 |
| 690 | 492 const base::TimeTicks kTimePosted = base::TimeTicks() + |
| 691 const base::TimeTicks kTimePosted = base::TimeTicks() | 493 base::TimeDelta::FromMilliseconds(1); |
| 692 + base::TimeDelta::FromMilliseconds(1); | |
| 693 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 494 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 694 // TrackingInfo will call TallyABirth() during construction. | 495 // TrackingInfo will call TallyABirth() during construction. |
| 695 base::TrackingInfo pending_task(location, kDelayedStartTime); | 496 base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 696 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 497 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 697 | 498 |
| 698 const TrackedTime kStartOfRun = TrackedTime() + | 499 const TrackedTime kStartOfRun = TrackedTime() + |
| 699 Duration::FromMilliseconds(5); | 500 Duration::FromMilliseconds(5); |
| 700 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 501 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 701 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | 502 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 702 kStartOfRun, kEndOfRun); | 503 kStartOfRun, kEndOfRun); |
| 703 | 504 |
| 704 // TrackingInfo will call TallyABirth() during construction. | 505 // TrackingInfo will call TallyABirth() during construction. |
| 705 base::TrackingInfo pending_task2(location, kDelayedStartTime); | 506 base::TrackingInfo pending_task2(location, kDelayedStartTime); |
| 706 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). | 507 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). |
| 707 | 508 |
| 708 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, | 509 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, |
| 709 kStartOfRun, kEndOfRun); | 510 kStartOfRun, kEndOfRun); |
| 710 | 511 |
| 711 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 512 ProcessDataSnapshot process_data; |
| 712 std::string json; | 513 ThreadData::Snapshot(false, &process_data); |
| 713 base::JSONWriter::Write(value.get(), &json); | 514 ExpectSimpleProcessData(process_data, kFunction, kMainThreadName, |
| 714 std::string one_line_result = "{" | 515 kMainThreadName, 2, 2, 4); |
| 715 "\"descendants\":[" | |
| 716 "]," | |
| 717 "\"list\":[" | |
| 718 "{" | |
| 719 "\"birth_thread\":\"SomeFileThreadName\"," | |
| 720 "\"death_data\":{" | |
| 721 "\"count\":2," | |
| 722 "\"queue_ms\":8," | |
| 723 "\"queue_ms_max\":4," | |
| 724 "\"queue_ms_sample\":4," | |
| 725 "\"run_ms\":4," | |
| 726 "\"run_ms_max\":2," | |
| 727 "\"run_ms_sample\":2" | |
| 728 "}," | |
| 729 "\"death_thread\":\"SomeFileThreadName\"," | |
| 730 "\"location\":{" | |
| 731 "\"file_name\":\"AnotherFileName\"," | |
| 732 "\"function_name\":\"TwoLives\"," | |
| 733 "\"line_number\":222" | |
| 734 "}" | |
| 735 "}" | |
| 736 "]" | |
| 737 "}"; | |
| 738 EXPECT_EQ(one_line_result, json); | |
| 739 } | 516 } |
| 740 | 517 |
| 741 TEST_F(TrackedObjectsTest, DifferentLives) { | 518 TEST_F(TrackedObjectsTest, DifferentLives) { |
| 742 if (!ThreadData::InitializeAndSetTrackingStatus( | 519 if (!ThreadData::InitializeAndSetTrackingStatus( |
| 743 ThreadData::PROFILING_CHILDREN_ACTIVE)) | 520 ThreadData::PROFILING_CHILDREN_ACTIVE)) |
| 744 return; | 521 return; |
| 745 | 522 |
| 746 // Use a well named thread. | 523 // Use a well named thread. |
| 747 ThreadData::InitializeThreadContext("SomeFileThreadName"); | 524 ThreadData::InitializeThreadContext(kMainThreadName); |
| 748 const int kFakeLineNumber = 567; | 525 const char kFunction[] = "DifferentLives"; |
| 749 const char* kFile = "AnotherFileName"; | 526 Location location(kFunction, kFile, kLineNumber, NULL); |
| 750 const char* kFunction = "DifferentLives"; | |
| 751 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 752 | 527 |
| 753 const base::TimeTicks kTimePosted = base::TimeTicks() | 528 const base::TimeTicks kTimePosted = base::TimeTicks() + |
| 754 + base::TimeDelta::FromMilliseconds(1); | 529 base::TimeDelta::FromMilliseconds(1); |
| 755 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 530 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 756 // TrackingInfo will call TallyABirth() during construction. | 531 // TrackingInfo will call TallyABirth() during construction. |
| 757 base::TrackingInfo pending_task(location, kDelayedStartTime); | 532 base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 758 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 533 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 759 | 534 |
| 760 const TrackedTime kStartOfRun = TrackedTime() + | 535 const TrackedTime kStartOfRun = TrackedTime() + |
| 761 Duration::FromMilliseconds(5); | 536 Duration::FromMilliseconds(5); |
| 762 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 537 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 763 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | 538 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 764 kStartOfRun, kEndOfRun); | 539 kStartOfRun, kEndOfRun); |
| 765 | 540 |
| 766 const int kSecondFakeLineNumber = 999; | 541 const int kSecondFakeLineNumber = 999; |
| 767 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); | 542 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); |
| 768 | 543 |
| 769 // TrackingInfo will call TallyABirth() during construction. | 544 // TrackingInfo will call TallyABirth() during construction. |
| 770 base::TrackingInfo pending_task2(second_location, kDelayedStartTime); | 545 base::TrackingInfo pending_task2(second_location, kDelayedStartTime); |
| 771 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). | 546 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). |
| 772 | 547 |
| 773 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); | 548 ProcessDataSnapshot process_data; |
| 774 std::string json; | 549 ThreadData::Snapshot(false, &process_data); |
| 775 base::JSONWriter::Write(value.get(), &json); | 550 ASSERT_EQ(2u, process_data.tasks.size()); |
| 776 std::string one_line_result = "{" | 551 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name); |
| 777 "\"descendants\":[" | 552 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name); |
| 778 "]," | 553 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number); |
| 779 "\"list\":[" | 554 EXPECT_EQ(kMainThreadName, process_data.tasks[0].birth.thread_name); |
| 780 "{" | 555 EXPECT_EQ(1, process_data.tasks[0].death_data.count); |
| 781 "\"birth_thread\":\"SomeFileThreadName\"," | 556 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_sum); |
| 782 "\"death_data\":{" | 557 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_max); |
| 783 "\"count\":1," | 558 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_sample); |
| 784 "\"queue_ms\":4," | 559 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_sum); |
| 785 "\"queue_ms_max\":4," | 560 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_max); |
| 786 "\"queue_ms_sample\":4," | 561 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_sample); |
| 787 "\"run_ms\":2," | 562 EXPECT_EQ(kMainThreadName, process_data.tasks[0].death_thread_name); |
| 788 "\"run_ms_max\":2," | 563 EXPECT_EQ(kFile, process_data.tasks[1].birth.location.file_name); |
| 789 "\"run_ms_sample\":2" | 564 EXPECT_EQ(kFunction, process_data.tasks[1].birth.location.function_name); |
| 790 "}," | 565 EXPECT_EQ(kSecondFakeLineNumber, |
| 791 "\"death_thread\":\"SomeFileThreadName\"," | 566 process_data.tasks[1].birth.location.line_number); |
| 792 "\"location\":{" | 567 EXPECT_EQ(kMainThreadName, process_data.tasks[1].birth.thread_name); |
| 793 "\"file_name\":\"AnotherFileName\"," | 568 EXPECT_EQ(1, process_data.tasks[1].death_data.count); |
| 794 "\"function_name\":\"DifferentLives\"," | 569 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_sum); |
| 795 "\"line_number\":567" | 570 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_max); |
| 796 "}" | 571 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_sample); |
| 797 "}," | 572 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_sum); |
| 798 "{" | 573 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_max); |
| 799 "\"birth_thread\":\"SomeFileThreadName\"," | 574 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_sample); |
| 800 "\"death_data\":{" | 575 EXPECT_EQ(kStillAlive, process_data.tasks[1].death_thread_name); |
| 801 "\"count\":1," | 576 EXPECT_EQ(0u, process_data.descendants.size()); |
| 802 "\"queue_ms\":0," | 577 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id); |
| 803 "\"queue_ms_max\":0," | |
| 804 "\"queue_ms_sample\":0," | |
| 805 "\"run_ms\":0," | |
| 806 "\"run_ms_max\":0," | |
| 807 "\"run_ms_sample\":0" | |
| 808 "}," | |
| 809 "\"death_thread\":\"Still_Alive\"," | |
| 810 "\"location\":{" | |
| 811 "\"file_name\":\"AnotherFileName\"," | |
| 812 "\"function_name\":\"DifferentLives\"," | |
| 813 "\"line_number\":999" | |
| 814 "}" | |
| 815 "}" | |
| 816 "]" | |
| 817 "}"; | |
| 818 EXPECT_EQ(one_line_result, json); | |
| 819 } | 578 } |
| 820 | 579 |
| 821 | |
| 822 } // namespace tracked_objects | 580 } // namespace tracked_objects |
| OLD | NEW |