| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.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 namespace tracked_objects { | 14 namespace tracked_objects { |
| 15 | 15 |
| 16 class TrackedObjectsTest : public testing::Test { | 16 class TrackedObjectsTest : public testing::Test { |
| 17 public: | 17 public: |
| 18 TrackedObjectsTest() { | 18 ~TrackedObjectsTest() { |
| 19 ThreadData::ShutdownSingleThreadedCleanup(); | 19 ThreadData::ShutdownSingleThreadedCleanup(); |
| 20 } | 20 } |
| 21 | 21 |
| 22 ~TrackedObjectsTest() { | |
| 23 ThreadData::ShutdownSingleThreadedCleanup(); | |
| 24 } | |
| 25 }; | 22 }; |
| 26 | 23 |
| 27 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { | 24 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { |
| 28 // Minimal test doesn't even create any tasks. | 25 // Minimal test doesn't even create any tasks. |
| 29 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 26 if (!ThreadData::StartTracking(true)) |
| 30 return; | 27 return; |
| 31 | 28 |
| 32 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. | 29 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. |
| 33 ThreadData* data = ThreadData::Get(); | 30 ThreadData* data = ThreadData::Get(); |
| 34 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. | 31 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. |
| 35 EXPECT_TRUE(data); | 32 EXPECT_TRUE(data); |
| 36 EXPECT_TRUE(!data->next()); | 33 EXPECT_TRUE(!data->next()); |
| 37 EXPECT_EQ(data, ThreadData::Get()); | 34 EXPECT_EQ(data, ThreadData::Get()); |
| 38 ThreadData::BirthMap birth_map; | 35 ThreadData::BirthMap birth_map; |
| 39 data->SnapshotBirthMap(&birth_map); | 36 data->SnapshotBirthMap(&birth_map); |
| 40 EXPECT_EQ(0u, birth_map.size()); | 37 EXPECT_EQ(0u, birth_map.size()); |
| 41 ThreadData::DeathMap death_map; | 38 ThreadData::DeathMap death_map; |
| 42 data->SnapshotDeathMap(&death_map); | 39 data->SnapshotDeathMap(&death_map); |
| 43 EXPECT_EQ(0u, death_map.size()); | 40 EXPECT_EQ(0u, death_map.size()); |
| 44 ThreadData::ShutdownSingleThreadedCleanup(); | 41 ThreadData::ShutdownSingleThreadedCleanup(); |
| 45 | 42 |
| 46 // Do it again, just to be sure we reset state completely. | 43 // Do it again, just to be sure we reset state completely. |
| 47 ThreadData::InitializeAndSetTrackingStatus(true); | 44 ThreadData::StartTracking(true); |
| 48 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. | 45 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. |
| 49 data = ThreadData::Get(); | 46 data = ThreadData::Get(); |
| 50 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. | 47 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. |
| 51 EXPECT_TRUE(data); | 48 EXPECT_TRUE(data); |
| 52 EXPECT_TRUE(!data->next()); | 49 EXPECT_TRUE(!data->next()); |
| 53 EXPECT_EQ(data, ThreadData::Get()); | 50 EXPECT_EQ(data, ThreadData::Get()); |
| 54 birth_map.clear(); | 51 birth_map.clear(); |
| 55 data->SnapshotBirthMap(&birth_map); | 52 data->SnapshotBirthMap(&birth_map); |
| 56 EXPECT_EQ(0u, birth_map.size()); | 53 EXPECT_EQ(0u, birth_map.size()); |
| 57 death_map.clear(); | 54 death_map.clear(); |
| 58 data->SnapshotDeathMap(&death_map); | 55 data->SnapshotDeathMap(&death_map); |
| 59 EXPECT_EQ(0u, death_map.size()); | 56 EXPECT_EQ(0u, death_map.size()); |
| 60 } | 57 } |
| 61 | 58 |
| 62 TEST_F(TrackedObjectsTest, TinyStartupShutdown) { | 59 TEST_F(TrackedObjectsTest, TinyStartupShutdown) { |
| 63 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 60 if (!ThreadData::StartTracking(true)) |
| 64 return; | 61 return; |
| 65 | 62 |
| 66 // Instigate tracking on a single tracked object, on our thread. | 63 // Instigate tracking on a single tracked object, on our thread. |
| 67 const Location& location = FROM_HERE; | 64 const Location& location = FROM_HERE; |
| 68 ThreadData::TallyABirthIfActive(location); | 65 ThreadData::TallyABirthIfActive(location); |
| 69 | 66 |
| 70 const ThreadData* data = ThreadData::first(); | 67 const ThreadData* data = ThreadData::first(); |
| 71 ASSERT_TRUE(data); | 68 ASSERT_TRUE(data); |
| 72 EXPECT_TRUE(!data->next()); | 69 EXPECT_TRUE(!data->next()); |
| 73 EXPECT_EQ(data, ThreadData::Get()); | 70 EXPECT_EQ(data, ThreadData::Get()); |
| 74 ThreadData::BirthMap birth_map; | 71 ThreadData::BirthMap birth_map; |
| 75 data->SnapshotBirthMap(&birth_map); | 72 data->SnapshotBirthMap(&birth_map); |
| 76 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. | 73 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 77 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. | 74 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. |
| 78 ThreadData::DeathMap death_map; | 75 ThreadData::DeathMap death_map; |
| 79 data->SnapshotDeathMap(&death_map); | 76 data->SnapshotDeathMap(&death_map); |
| 80 EXPECT_EQ(0u, death_map.size()); // No deaths. | 77 EXPECT_EQ(0u, death_map.size()); // No deaths. |
| 81 | 78 |
| 82 | 79 |
| 83 // Now instigate another birth, and a first death at the same location. | 80 // Now instigate a birth, and a death. |
| 84 // TrackingInfo will call TallyABirth() during construction. | 81 const Births* second_birth = ThreadData::TallyABirthIfActive(location); |
| 85 base::TimeTicks kBogusStartTime; | 82 ThreadData::TallyADeathIfActive( |
| 86 base::TrackingInfo pending_task(location, kBogusStartTime); | 83 second_birth, |
| 87 TrackedTime kBogusStartRunTime; | 84 base::TimeTicks(), /* Bogus post_time. */ |
| 88 TrackedTime kBogusEndRunTime; | 85 base::TimeTicks(), /* Bogus delayed_start_time. */ |
| 89 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, kBogusStartRunTime, | 86 base::TimeTicks(), /* Bogus start_run_time. */ |
| 90 kBogusEndRunTime); | 87 base::TimeTicks() /* Bogus end_run_time */ ); |
| 91 | 88 |
| 92 birth_map.clear(); | 89 birth_map.clear(); |
| 93 data->SnapshotBirthMap(&birth_map); | 90 data->SnapshotBirthMap(&birth_map); |
| 94 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. | 91 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 95 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. | 92 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. |
| 96 death_map.clear(); | 93 death_map.clear(); |
| 97 data->SnapshotDeathMap(&death_map); | 94 data->SnapshotDeathMap(&death_map); |
| 98 EXPECT_EQ(1u, death_map.size()); // 1 location. | 95 EXPECT_EQ(1u, death_map.size()); // 1 location. |
| 99 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. | 96 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. |
| 100 | 97 |
| 101 // The births were at the same location as the one known death. | 98 // The births were at the same location as the one known death. |
| 102 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); | 99 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); |
| 103 } | 100 } |
| 104 | 101 |
| 105 TEST_F(TrackedObjectsTest, DeathDataTest) { | 102 TEST_F(TrackedObjectsTest, DeathDataTest) { |
| 106 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 103 if (!ThreadData::StartTracking(true)) |
| 107 return; | 104 return; |
| 108 | 105 |
| 109 scoped_ptr<DeathData> data(new DeathData()); | 106 scoped_ptr<DeathData> data(new DeathData()); |
| 110 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); | 107 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); |
| 111 EXPECT_EQ(data->run_duration(), Duration()); | 108 EXPECT_EQ(data->run_duration(), base::TimeDelta()); |
| 112 EXPECT_EQ(data->queue_duration(), Duration()); | 109 EXPECT_EQ(data->queue_duration(), base::TimeDelta()); |
| 113 EXPECT_EQ(data->AverageMsRunDuration(), 0); | 110 EXPECT_EQ(data->AverageMsRunDuration(), 0); |
| 114 EXPECT_EQ(data->AverageMsQueueDuration(), 0); | 111 EXPECT_EQ(data->AverageMsQueueDuration(), 0); |
| 115 EXPECT_EQ(data->count(), 0); | 112 EXPECT_EQ(data->count(), 0); |
| 116 | 113 |
| 117 int run_ms = 42; | 114 int run_ms = 42; |
| 118 int queue_ms = 8; | 115 int queue_ms = 8; |
| 119 | 116 |
| 120 Duration run_duration = Duration().FromMilliseconds(run_ms); | 117 base::TimeDelta run_duration = base::TimeDelta().FromMilliseconds(run_ms); |
| 121 Duration queue_duration = Duration().FromMilliseconds(queue_ms); | 118 base::TimeDelta queue_duration = base::TimeDelta().FromMilliseconds(queue_ms); |
| 122 data->RecordDeath(queue_duration, run_duration); | 119 data->RecordDeath(queue_duration, run_duration); |
| 123 EXPECT_EQ(data->run_duration(), run_duration); | 120 EXPECT_EQ(data->run_duration(), run_duration); |
| 124 EXPECT_EQ(data->queue_duration(), queue_duration); | 121 EXPECT_EQ(data->queue_duration(), queue_duration); |
| 125 EXPECT_EQ(data->AverageMsRunDuration(), run_ms); | 122 EXPECT_EQ(data->AverageMsRunDuration(), run_ms); |
| 126 EXPECT_EQ(data->AverageMsQueueDuration(), queue_ms); | 123 EXPECT_EQ(data->AverageMsQueueDuration(), queue_ms); |
| 127 EXPECT_EQ(data->count(), 1); | 124 EXPECT_EQ(data->count(), 1); |
| 128 | 125 |
| 129 data->RecordDeath(queue_duration, run_duration); | 126 data->RecordDeath(queue_duration, run_duration); |
| 130 EXPECT_EQ(data->run_duration(), run_duration + run_duration); | 127 EXPECT_EQ(data->run_duration(), run_duration + run_duration); |
| 131 EXPECT_EQ(data->queue_duration(), queue_duration + queue_duration); | 128 EXPECT_EQ(data->queue_duration(), queue_duration + queue_duration); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 147 std::string results = "Lives:2, Run:84ms(42ms/life) Queue:16ms(8ms/life) "; | 144 std::string results = "Lives:2, Run:84ms(42ms/life) Queue:16ms(8ms/life) "; |
| 148 EXPECT_EQ(output, results); | 145 EXPECT_EQ(output, results); |
| 149 | 146 |
| 150 scoped_ptr<base::Value> value(data->ToValue()); | 147 scoped_ptr<base::Value> value(data->ToValue()); |
| 151 std::string json; | 148 std::string json; |
| 152 base::JSONWriter::Write(value.get(), false, &json); | 149 base::JSONWriter::Write(value.get(), false, &json); |
| 153 std::string birth_only_result = "{\"count\":2,\"queue_ms\":16,\"run_ms\":84}"; | 150 std::string birth_only_result = "{\"count\":2,\"queue_ms\":16,\"run_ms\":84}"; |
| 154 EXPECT_EQ(json, birth_only_result); | 151 EXPECT_EQ(json, birth_only_result); |
| 155 } | 152 } |
| 156 | 153 |
| 157 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueWorkerThread) { | |
| 158 // Transition to Deactivated state before doing anything. | |
| 159 if (!ThreadData::InitializeAndSetTrackingStatus(false)) | |
| 160 return; | |
| 161 // We don't initialize system with a thread name, so we're viewed as a worker | |
| 162 // thread. | |
| 163 const int kFakeLineNumber = 173; | |
| 164 const char* kFile = "FixedFileName"; | |
| 165 const char* kFunction = "BirthOnlyToValueWorkerThread"; | |
| 166 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 167 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 168 // We should now see a NULL birth record. | |
| 169 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); | |
| 170 | |
| 171 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 172 std::string json; | |
| 173 base::JSONWriter::Write(value.get(), false, &json); | |
| 174 std::string birth_only_result = "{" | |
| 175 "\"list\":[" | |
| 176 "]" | |
| 177 "}"; | |
| 178 EXPECT_EQ(json, birth_only_result); | |
| 179 } | |
| 180 | |
| 181 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueMainThread) { | |
| 182 // Start in the deactivated state. | |
| 183 if (!ThreadData::InitializeAndSetTrackingStatus(false)) | |
| 184 return; | |
| 185 | |
| 186 // Use a well named thread. | |
| 187 ThreadData::InitializeThreadContext("SomeMainThreadName"); | |
| 188 const int kFakeLineNumber = 173; | |
| 189 const char* kFile = "FixedFileName"; | |
| 190 const char* kFunction = "BirthOnlyToValueMainThread"; | |
| 191 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 192 // Do not delete birth. We don't own it. | |
| 193 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 194 // We expect to not get a birth record. | |
| 195 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); | |
| 196 | |
| 197 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 198 std::string json; | |
| 199 base::JSONWriter::Write(value.get(), false, &json); | |
| 200 std::string birth_only_result = "{" | |
| 201 "\"list\":[" | |
| 202 "]" | |
| 203 "}"; | |
| 204 EXPECT_EQ(json, birth_only_result); | |
| 205 } | |
| 206 | |
| 207 TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) { | 154 TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) { |
| 208 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 155 if (!ThreadData::StartTracking(true)) |
| 209 return; | 156 return; |
| 210 // We don't initialize system with a thread name, so we're viewed as a worker | 157 // We don't initialize system with a thread name, so we're viewed as a worker |
| 211 // thread. | 158 // thread. |
| 212 const int kFakeLineNumber = 173; | 159 int fake_line_number = 173; |
| 213 const char* kFile = "FixedFileName"; | 160 const char* kFile = "FixedFileName"; |
| 214 const char* kFunction = "BirthOnlyToValueWorkerThread"; | 161 const char* kFunction = "BirthOnlyToValueWorkerThread"; |
| 215 Location location(kFunction, kFile, kFakeLineNumber, NULL); | 162 Location location(kFunction, kFile, fake_line_number, NULL); |
| 216 Births* birth = ThreadData::TallyABirthIfActive(location); | 163 Births* birth = ThreadData::TallyABirthIfActive(location); |
| 217 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | 164 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 218 | 165 |
| 219 scoped_ptr<base::Value> value(ThreadData::ToValue()); | 166 int process_type = 3; |
| 167 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type)); |
| 220 std::string json; | 168 std::string json; |
| 221 base::JSONWriter::Write(value.get(), false, &json); | 169 base::JSONWriter::Write(value.get(), false, &json); |
| 222 std::string birth_only_result = "{" | 170 std::string birth_only_result = "{" |
| 223 "\"list\":[" | 171 "\"list\":[" |
| 224 "{" | 172 "{" |
| 225 "\"birth_thread\":\"WorkerThread-1\"," | 173 "\"birth_thread\":\"WorkerThread-1\"," |
| 226 "\"death_data\":{" | 174 "\"death_data\":{" |
| 227 "\"count\":1," | 175 "\"count\":1," |
| 228 "\"queue_ms\":0," | 176 "\"queue_ms\":0," |
| 229 "\"run_ms\":0" | 177 "\"run_ms\":0" |
| 230 "}," | 178 "}," |
| 231 "\"death_thread\":\"Still_Alive\"," | 179 "\"death_thread\":\"Still_Alive\"," |
| 232 "\"location\":{" | 180 "\"location\":{" |
| 233 "\"file_name\":\"FixedFileName\"," | 181 "\"file_name\":\"FixedFileName\"," |
| 234 "\"function_name\":\"BirthOnlyToValueWorkerThread\"," | 182 "\"function_name\":\"BirthOnlyToValueWorkerThread\"," |
| 235 "\"line_number\":173" | 183 "\"line_number\":173" |
| 236 "}" | 184 "}" |
| 237 "}" | 185 "}" |
| 238 "]" | 186 "]," |
| 187 "\"process\":3" |
| 239 "}"; | 188 "}"; |
| 240 EXPECT_EQ(json, birth_only_result); | 189 EXPECT_EQ(json, birth_only_result); |
| 241 } | 190 } |
| 242 | 191 |
| 243 TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) { | 192 TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) { |
| 244 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 193 if (!ThreadData::StartTracking(true)) |
| 245 return; | 194 return; |
| 246 | 195 |
| 247 // Use a well named thread. | 196 // Use a well named thread. |
| 248 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 197 ThreadData::InitializeThreadContext("SomeMainThreadName"); |
| 249 const int kFakeLineNumber = 173; | 198 int fake_line_number = 173; |
| 250 const char* kFile = "FixedFileName"; | 199 const char* kFile = "FixedFileName"; |
| 251 const char* kFunction = "BirthOnlyToValueMainThread"; | 200 const char* kFunction = "BirthOnlyToValueMainThread"; |
| 252 Location location(kFunction, kFile, kFakeLineNumber, NULL); | 201 Location location(kFunction, kFile, fake_line_number, NULL); |
| 253 // Do not delete birth. We don't own it. | 202 // Do not delete birth. We don't own it. |
| 254 Births* birth = ThreadData::TallyABirthIfActive(location); | 203 Births* birth = ThreadData::TallyABirthIfActive(location); |
| 255 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | 204 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 256 | 205 |
| 257 scoped_ptr<base::Value> value(ThreadData::ToValue()); | 206 int process_type = 34; |
| 207 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type)); |
| 258 std::string json; | 208 std::string json; |
| 259 base::JSONWriter::Write(value.get(), false, &json); | 209 base::JSONWriter::Write(value.get(), false, &json); |
| 260 std::string birth_only_result = "{" | 210 std::string birth_only_result = "{" |
| 261 "\"list\":[" | 211 "\"list\":[" |
| 262 "{" | 212 "{" |
| 263 "\"birth_thread\":\"SomeMainThreadName\"," | 213 "\"birth_thread\":\"SomeMainThreadName\"," |
| 264 "\"death_data\":{" | 214 "\"death_data\":{" |
| 265 "\"count\":1," | 215 "\"count\":1," |
| 266 "\"queue_ms\":0," | 216 "\"queue_ms\":0," |
| 267 "\"run_ms\":0" | 217 "\"run_ms\":0" |
| 268 "}," | 218 "}," |
| 269 "\"death_thread\":\"Still_Alive\"," | 219 "\"death_thread\":\"Still_Alive\"," |
| 270 "\"location\":{" | 220 "\"location\":{" |
| 271 "\"file_name\":\"FixedFileName\"," | 221 "\"file_name\":\"FixedFileName\"," |
| 272 "\"function_name\":\"BirthOnlyToValueMainThread\"," | 222 "\"function_name\":\"BirthOnlyToValueMainThread\"," |
| 273 "\"line_number\":173" | 223 "\"line_number\":173" |
| 274 "}" | 224 "}" |
| 275 "}" | 225 "}" |
| 276 "]" | 226 "]," |
| 227 "\"process\":34" |
| 277 "}"; | 228 "}"; |
| 278 EXPECT_EQ(json, birth_only_result); | 229 EXPECT_EQ(json, birth_only_result); |
| 279 } | 230 } |
| 280 | 231 |
| 281 TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) { | 232 TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) { |
| 282 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 233 if (!ThreadData::StartTracking(true)) |
| 283 return; | 234 return; |
| 284 | 235 |
| 285 // Use a well named thread. | 236 // Use a well named thread. |
| 286 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 237 ThreadData::InitializeThreadContext("SomeMainThreadName"); |
| 287 const int kFakeLineNumber = 236; | 238 int fake_line_number = 236; |
| 288 const char* kFile = "FixedFileName"; | 239 const char* kFile = "FixedFileName"; |
| 289 const char* kFunction = "LifeCycleToValueMainThread"; | 240 const char* kFunction = "LifeCycleToValueMainThread"; |
| 290 Location location(kFunction, kFile, kFakeLineNumber, NULL); | 241 Location location(kFunction, kFile, fake_line_number, NULL); |
| 291 // Do not delete birth. We don't own it. | 242 // Do not delete birth. We don't own it. |
| 292 Births* birth = ThreadData::TallyABirthIfActive(location); | 243 Births* birth = ThreadData::TallyABirthIfActive(location); |
| 293 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | 244 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 294 | 245 |
| 295 const base::TimeTicks kTimePosted = base::TimeTicks() | 246 // TimeTicks initializers ar ein microseconds. Durations are calculated in |
| 296 + base::TimeDelta::FromMilliseconds(1); | 247 // milliseconds, so we need to use 1000x. |
| 297 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 248 const base::TimeTicks time_posted = base::TimeTicks() + |
| 298 // TrackingInfo will call TallyABirth() during construction. | 249 base::TimeDelta::FromMilliseconds(1); |
| 299 base::TrackingInfo pending_task(location, kDelayedStartTime); | 250 const base::TimeTicks delayed_start_time = base::TimeTicks(); |
| 300 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 251 const base::TimeTicks start_of_run = base::TimeTicks() + |
| 252 base::TimeDelta::FromMilliseconds(5); |
| 253 const base::TimeTicks end_of_run = base::TimeTicks() + |
| 254 base::TimeDelta::FromMilliseconds(7); |
| 255 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time, |
| 256 start_of_run, end_of_run); |
| 301 | 257 |
| 302 const TrackedTime kStartOfRun = TrackedTime() + | 258 int process_type = 7; |
| 303 Duration::FromMilliseconds(5); | 259 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type)); |
| 304 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | |
| 305 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | |
| 306 kStartOfRun, kEndOfRun); | |
| 307 | |
| 308 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 309 std::string json; | 260 std::string json; |
| 310 base::JSONWriter::Write(value.get(), false, &json); | 261 base::JSONWriter::Write(value.get(), false, &json); |
| 311 std::string one_line_result = "{" | 262 std::string one_line_result = "{" |
| 312 "\"list\":[" | 263 "\"list\":[" |
| 313 "{" | 264 "{" |
| 314 "\"birth_thread\":\"SomeMainThreadName\"," | 265 "\"birth_thread\":\"SomeMainThreadName\"," |
| 315 "\"death_data\":{" | 266 "\"death_data\":{" |
| 316 "\"count\":1," | 267 "\"count\":1," |
| 317 "\"queue_ms\":4," | 268 "\"queue_ms\":4," |
| 318 "\"run_ms\":2" | 269 "\"run_ms\":2" |
| 319 "}," | 270 "}," |
| 320 "\"death_thread\":\"SomeMainThreadName\"," | 271 "\"death_thread\":\"SomeMainThreadName\"," |
| 321 "\"location\":{" | 272 "\"location\":{" |
| 322 "\"file_name\":\"FixedFileName\"," | 273 "\"file_name\":\"FixedFileName\"," |
| 323 "\"function_name\":\"LifeCycleToValueMainThread\"," | 274 "\"function_name\":\"LifeCycleToValueMainThread\"," |
| 324 "\"line_number\":236" | 275 "\"line_number\":236" |
| 325 "}" | 276 "}" |
| 326 "}" | 277 "}" |
| 327 "]" | 278 "]," |
| 279 "\"process\":7" |
| 328 "}"; | 280 "}"; |
| 329 EXPECT_EQ(one_line_result, json); | 281 EXPECT_EQ(json, one_line_result); |
| 330 } | 282 } |
| 331 | 283 |
| 332 // We will deactivate tracking after the birth, and before the death, and | 284 TEST_F(TrackedObjectsTest, TwoLives) { |
| 333 // demonstrate that the lifecycle is completely tallied. This ensures that | 285 if (!ThreadData::StartTracking(true)) |
| 334 // our tallied births are matched by tallied deaths (except for when the | |
| 335 // task is still running, or is queued). | |
| 336 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToValueMainThread) { | |
| 337 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | |
| 338 return; | 286 return; |
| 339 | 287 |
| 340 // Use a well named thread. | 288 // Use a well named thread. |
| 341 ThreadData::InitializeThreadContext("SomeMainThreadName"); | 289 ThreadData::InitializeThreadContext("SomeFileThreadName"); |
| 342 const int kFakeLineNumber = 236; | 290 int fake_line_number = 222; |
| 343 const char* kFile = "FixedFileName"; | 291 const char* kFile = "AnotherFileName"; |
| 344 const char* kFunction = "LifeCycleToValueMainThread"; | 292 const char* kFunction = "TwoLives"; |
| 345 Location location(kFunction, kFile, kFakeLineNumber, NULL); | 293 Location location(kFunction, kFile, fake_line_number, NULL); |
| 346 // Do not delete birth. We don't own it. | 294 // Do not delete birth. We don't own it. |
| 347 Births* birth = ThreadData::TallyABirthIfActive(location); | 295 Births* birth = ThreadData::TallyABirthIfActive(location); |
| 348 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | 296 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 349 | 297 |
| 350 const base::TimeTicks kTimePosted = base::TimeTicks() | 298 // TimeTicks initializers ar ein microseconds. Durations are calculated in |
| 351 + base::TimeDelta::FromMilliseconds(1); | 299 // milliseconds, so we need to use 1000x. |
| 352 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 300 const base::TimeTicks time_posted = base::TimeTicks() + |
| 353 // TrackingInfo will call TallyABirth() during construction. | 301 base::TimeDelta::FromMilliseconds(1); |
| 354 base::TrackingInfo pending_task(location, kDelayedStartTime); | 302 const base::TimeTicks delayed_start_time = base::TimeTicks(); |
| 355 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 303 const base::TimeTicks start_of_run = base::TimeTicks() + |
| 304 base::TimeDelta::FromMilliseconds(5); |
| 305 const base::TimeTicks end_of_run = base::TimeTicks() + |
| 306 base::TimeDelta::FromMilliseconds(7); |
| 307 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time, |
| 308 start_of_run, end_of_run); |
| 356 | 309 |
| 357 // Turn off tracking now that we have births. | 310 birth = ThreadData::TallyABirthIfActive(location); |
| 358 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(false)); | 311 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time, |
| 312 start_of_run, end_of_run); |
| 359 | 313 |
| 360 const TrackedTime kStartOfRun = TrackedTime() + | 314 int process_type = 7; |
| 361 Duration::FromMilliseconds(5); | 315 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type)); |
| 362 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | |
| 363 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | |
| 364 kStartOfRun, kEndOfRun); | |
| 365 | |
| 366 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 367 std::string json; | 316 std::string json; |
| 368 base::JSONWriter::Write(value.get(), false, &json); | 317 base::JSONWriter::Write(value.get(), false, &json); |
| 369 std::string one_line_result = "{" | 318 std::string one_line_result = "{" |
| 370 "\"list\":[" | |
| 371 "{" | |
| 372 "\"birth_thread\":\"SomeMainThreadName\"," | |
| 373 "\"death_data\":{" | |
| 374 "\"count\":1," | |
| 375 "\"queue_ms\":4," | |
| 376 "\"run_ms\":2" | |
| 377 "}," | |
| 378 "\"death_thread\":\"SomeMainThreadName\"," | |
| 379 "\"location\":{" | |
| 380 "\"file_name\":\"FixedFileName\"," | |
| 381 "\"function_name\":\"LifeCycleToValueMainThread\"," | |
| 382 "\"line_number\":236" | |
| 383 "}" | |
| 384 "}" | |
| 385 "]" | |
| 386 "}"; | |
| 387 EXPECT_EQ(one_line_result, json); | |
| 388 } | |
| 389 | |
| 390 // We will deactivate tracking before starting a life cycle, and neither | |
| 391 // the birth nor the death will be recorded. | |
| 392 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToValueMainThread) { | |
| 393 if (!ThreadData::InitializeAndSetTrackingStatus(false)) | |
| 394 return; | |
| 395 | |
| 396 // Use a well named thread. | |
| 397 ThreadData::InitializeThreadContext("SomeMainThreadName"); | |
| 398 const int kFakeLineNumber = 236; | |
| 399 const char* kFile = "FixedFileName"; | |
| 400 const char* kFunction = "LifeCycleToValueMainThread"; | |
| 401 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 402 // Do not delete birth. We don't own it. | |
| 403 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 404 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); | |
| 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 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 420 std::string json; | |
| 421 base::JSONWriter::Write(value.get(), false, &json); | |
| 422 std::string one_line_result = "{" | |
| 423 "\"list\":[" | |
| 424 "]" | |
| 425 "}"; | |
| 426 EXPECT_EQ(one_line_result, json); | |
| 427 } | |
| 428 | |
| 429 TEST_F(TrackedObjectsTest, LifeCycleToValueWorkerThread) { | |
| 430 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | |
| 431 return; | |
| 432 | |
| 433 // Don't initialize thread, so that we appear as a worker thread. | |
| 434 // ThreadData::InitializeThreadContext("SomeMainThreadName"); | |
| 435 | |
| 436 const int kFakeLineNumber = 236; | |
| 437 const char* kFile = "FixedFileName"; | |
| 438 const char* kFunction = "LifeCycleToValueWorkerThread"; | |
| 439 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 440 // Do not delete birth. We don't own it. | |
| 441 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 442 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 443 | |
| 444 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1); | |
| 445 const TrackedTime kStartOfRun = TrackedTime() + | |
| 446 Duration::FromMilliseconds(5); | |
| 447 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | |
| 448 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted, | |
| 449 kStartOfRun, kEndOfRun); | |
| 450 | |
| 451 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 452 std::string json; | |
| 453 base::JSONWriter::Write(value.get(), false, &json); | |
| 454 std::string one_line_result = "{" | |
| 455 "\"list\":[" | |
| 456 "{" | |
| 457 "\"birth_thread\":\"WorkerThread-1\"," | |
| 458 "\"death_data\":{" | |
| 459 "\"count\":1," | |
| 460 "\"queue_ms\":4," | |
| 461 "\"run_ms\":2" | |
| 462 "}," | |
| 463 "\"death_thread\":\"WorkerThread-1\"," | |
| 464 "\"location\":{" | |
| 465 "\"file_name\":\"FixedFileName\"," | |
| 466 "\"function_name\":\"LifeCycleToValueWorkerThread\"," | |
| 467 "\"line_number\":236" | |
| 468 "}" | |
| 469 "}" | |
| 470 "]" | |
| 471 "}"; | |
| 472 EXPECT_EQ(one_line_result, json); | |
| 473 } | |
| 474 | |
| 475 TEST_F(TrackedObjectsTest, TwoLives) { | |
| 476 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | |
| 477 return; | |
| 478 | |
| 479 // Use a well named thread. | |
| 480 ThreadData::InitializeThreadContext("SomeFileThreadName"); | |
| 481 const int kFakeLineNumber = 222; | |
| 482 const char* kFile = "AnotherFileName"; | |
| 483 const char* kFunction = "TwoLives"; | |
| 484 Location location(kFunction, kFile, kFakeLineNumber, NULL); | |
| 485 // Do not delete birth. We don't own it. | |
| 486 Births* birth = ThreadData::TallyABirthIfActive(location); | |
| 487 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); | |
| 488 | |
| 489 | |
| 490 const base::TimeTicks kTimePosted = base::TimeTicks() | |
| 491 + base::TimeDelta::FromMilliseconds(1); | |
| 492 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | |
| 493 // TrackingInfo will call TallyABirth() during construction. | |
| 494 base::TrackingInfo pending_task(location, kDelayedStartTime); | |
| 495 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | |
| 496 | |
| 497 const TrackedTime kStartOfRun = TrackedTime() + | |
| 498 Duration::FromMilliseconds(5); | |
| 499 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | |
| 500 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | |
| 501 kStartOfRun, kEndOfRun); | |
| 502 | |
| 503 // TrackingInfo will call TallyABirth() during construction. | |
| 504 base::TrackingInfo pending_task2(location, kDelayedStartTime); | |
| 505 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). | |
| 506 | |
| 507 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, | |
| 508 kStartOfRun, kEndOfRun); | |
| 509 | |
| 510 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 511 std::string json; | |
| 512 base::JSONWriter::Write(value.get(), false, &json); | |
| 513 std::string one_line_result = "{" | |
| 514 "\"list\":[" | 319 "\"list\":[" |
| 515 "{" | 320 "{" |
| 516 "\"birth_thread\":\"SomeFileThreadName\"," | 321 "\"birth_thread\":\"SomeFileThreadName\"," |
| 517 "\"death_data\":{" | 322 "\"death_data\":{" |
| 518 "\"count\":2," | 323 "\"count\":2," |
| 519 "\"queue_ms\":8," | 324 "\"queue_ms\":8," |
| 520 "\"run_ms\":4" | 325 "\"run_ms\":4" |
| 521 "}," | 326 "}," |
| 522 "\"death_thread\":\"SomeFileThreadName\"," | 327 "\"death_thread\":\"SomeFileThreadName\"," |
| 523 "\"location\":{" | 328 "\"location\":{" |
| 524 "\"file_name\":\"AnotherFileName\"," | 329 "\"file_name\":\"AnotherFileName\"," |
| 525 "\"function_name\":\"TwoLives\"," | 330 "\"function_name\":\"TwoLives\"," |
| 526 "\"line_number\":222" | 331 "\"line_number\":222" |
| 527 "}" | 332 "}" |
| 528 "}" | 333 "}" |
| 529 "]" | 334 "]," |
| 335 "\"process\":7" |
| 530 "}"; | 336 "}"; |
| 531 EXPECT_EQ(one_line_result, json); | 337 EXPECT_EQ(json, one_line_result); |
| 532 } | 338 } |
| 533 | 339 |
| 534 TEST_F(TrackedObjectsTest, DifferentLives) { | 340 TEST_F(TrackedObjectsTest, DifferentLives) { |
| 535 if (!ThreadData::InitializeAndSetTrackingStatus(true)) | 341 if (!ThreadData::StartTracking(true)) |
| 536 return; | 342 return; |
| 537 | 343 |
| 538 // Use a well named thread. | 344 // Use a well named thread. |
| 539 ThreadData::InitializeThreadContext("SomeFileThreadName"); | 345 ThreadData::InitializeThreadContext("SomeFileThreadName"); |
| 540 const int kFakeLineNumber = 567; | 346 int fake_line_number = 567; |
| 541 const char* kFile = "AnotherFileName"; | 347 const char* kFile = "AnotherFileName"; |
| 542 const char* kFunction = "DifferentLives"; | 348 const char* kFunction = "DifferentLives"; |
| 543 Location location(kFunction, kFile, kFakeLineNumber, NULL); | 349 Location location(kFunction, kFile, fake_line_number, NULL); |
| 350 // Do not delete birth. We don't own it. |
| 351 Births* birth = ThreadData::TallyABirthIfActive(location); |
| 352 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 544 | 353 |
| 545 const base::TimeTicks kTimePosted = base::TimeTicks() | 354 // TimeTicks initializers ar ein microseconds. Durations are calculated in |
| 546 + base::TimeDelta::FromMilliseconds(1); | 355 // milliseconds, so we need to use 1000x. |
| 547 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); | 356 const base::TimeTicks time_posted = base::TimeTicks() + |
| 548 // TrackingInfo will call TallyABirth() during construction. | 357 base::TimeDelta::FromMilliseconds(1); |
| 549 base::TrackingInfo pending_task(location, kDelayedStartTime); | 358 const base::TimeTicks delayed_start_time = base::TimeTicks(); |
| 550 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). | 359 const base::TimeTicks start_of_run = base::TimeTicks() + |
| 360 base::TimeDelta::FromMilliseconds(5); |
| 361 const base::TimeTicks end_of_run = base::TimeTicks() + |
| 362 base::TimeDelta::FromMilliseconds(7); |
| 363 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time, |
| 364 start_of_run, end_of_run); |
| 551 | 365 |
| 552 const TrackedTime kStartOfRun = TrackedTime() + | 366 int second_fake_line_number = 999; |
| 553 Duration::FromMilliseconds(5); | 367 Location second_location(kFunction, kFile, second_fake_line_number, NULL); |
| 554 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); | 368 birth = ThreadData::TallyABirthIfActive(second_location); |
| 555 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | |
| 556 kStartOfRun, kEndOfRun); | |
| 557 | 369 |
| 558 const int kSecondFakeLineNumber = 999; | 370 int process_type = 2; |
| 559 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); | 371 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type)); |
| 560 | |
| 561 // TrackingInfo will call TallyABirth() during construction. | |
| 562 base::TrackingInfo pending_task2(second_location, kDelayedStartTime); | |
| 563 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). | |
| 564 | |
| 565 scoped_ptr<base::Value> value(ThreadData::ToValue()); | |
| 566 std::string json; | 372 std::string json; |
| 567 base::JSONWriter::Write(value.get(), false, &json); | 373 base::JSONWriter::Write(value.get(), false, &json); |
| 568 std::string one_line_result = "{" | 374 std::string one_line_result = "{" |
| 569 "\"list\":[" | 375 "\"list\":[" |
| 570 "{" | 376 "{" |
| 571 "\"birth_thread\":\"SomeFileThreadName\"," | 377 "\"birth_thread\":\"SomeFileThreadName\"," |
| 572 "\"death_data\":{" | 378 "\"death_data\":{" |
| 573 "\"count\":1," | 379 "\"count\":1," |
| 574 "\"queue_ms\":4," | 380 "\"queue_ms\":4," |
| 575 "\"run_ms\":2" | 381 "\"run_ms\":2" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 588 "\"queue_ms\":0," | 394 "\"queue_ms\":0," |
| 589 "\"run_ms\":0" | 395 "\"run_ms\":0" |
| 590 "}," | 396 "}," |
| 591 "\"death_thread\":\"Still_Alive\"," | 397 "\"death_thread\":\"Still_Alive\"," |
| 592 "\"location\":{" | 398 "\"location\":{" |
| 593 "\"file_name\":\"AnotherFileName\"," | 399 "\"file_name\":\"AnotherFileName\"," |
| 594 "\"function_name\":\"DifferentLives\"," | 400 "\"function_name\":\"DifferentLives\"," |
| 595 "\"line_number\":999" | 401 "\"line_number\":999" |
| 596 "}" | 402 "}" |
| 597 "}" | 403 "}" |
| 598 "]" | 404 "]," |
| 405 "\"process\":2" |
| 599 "}"; | 406 "}"; |
| 600 EXPECT_EQ(one_line_result, json); | 407 EXPECT_EQ(json, one_line_result); |
| 601 } | 408 } |
| 602 | 409 |
| 603 } // namespace tracked_objects | 410 } // namespace tracked_objects |
| OLD | NEW |