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 |