Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: base/tracked_objects_unittest.cc

Issue 8313013: Support JSON encoding of data for about:tracking information (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« base/tracked_objects.cc ('K') | « base/tracked_objects.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
10 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h" 11 #include "base/message_loop.h"
10 #include "base/time.h" 12 #include "base/time.h"
11 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
12 14
13 namespace tracked_objects { 15 namespace tracked_objects {
14 16
15 class TrackedObjectsTest : public testing::Test { 17 class TrackedObjectsTest : public testing::Test {
16 public: 18 public:
17 MessageLoop message_loop_; 19
ramant (doing other things) 2011/10/24 18:03:49 nit: lint was saying no extra space after public:
jar (doing other things) 2011/10/24 18:43:27 Removed references to message_loop (including head
20 // MessageLoop message_loop_;
18 }; 21 };
19 22
20 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { 23 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) {
21 // Minimal test doesn't even create any tasks. 24 // Minimal test doesn't even create any tasks.
22 if (!ThreadData::StartTracking(true)) 25 if (!ThreadData::StartTracking(true))
23 return; 26 return;
24 27
25 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. 28 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
26 ThreadData* data = ThreadData::Get(); 29 ThreadData* data = ThreadData::Get();
27 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. 30 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
(...skipping 15 matching lines...) Expand all
43 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. 46 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
44 EXPECT_TRUE(data); 47 EXPECT_TRUE(data);
45 EXPECT_TRUE(!data->next()); 48 EXPECT_TRUE(!data->next());
46 EXPECT_EQ(data, ThreadData::Get()); 49 EXPECT_EQ(data, ThreadData::Get());
47 birth_map.clear(); 50 birth_map.clear();
48 data->SnapshotBirthMap(&birth_map); 51 data->SnapshotBirthMap(&birth_map);
49 EXPECT_EQ(0u, birth_map.size()); 52 EXPECT_EQ(0u, birth_map.size());
50 death_map.clear(); 53 death_map.clear();
51 data->SnapshotDeathMap(&death_map); 54 data->SnapshotDeathMap(&death_map);
52 EXPECT_EQ(0u, death_map.size()); 55 EXPECT_EQ(0u, death_map.size());
56
53 ThreadData::ShutdownSingleThreadedCleanup(); 57 ThreadData::ShutdownSingleThreadedCleanup();
54 } 58 }
55 59
56 TEST_F(TrackedObjectsTest, TinyStartupShutdown) { 60 TEST_F(TrackedObjectsTest, TinyStartupShutdown) {
57 if (!ThreadData::StartTracking(true)) 61 if (!ThreadData::StartTracking(true))
58 return; 62 return;
59 63
60 // Instigate tracking on a single tracked object, or our thread. 64 // Instigate tracking on a single tracked object, on our thread.
61 const Location& location = FROM_HERE; 65 const Location& location = FROM_HERE;
62 ThreadData::TallyABirthIfActive(location); 66 ThreadData::TallyABirthIfActive(location);
63 67
64 const ThreadData* data = ThreadData::first(); 68 const ThreadData* data = ThreadData::first();
65 ASSERT_TRUE(data); 69 ASSERT_TRUE(data);
66 EXPECT_TRUE(!data->next()); 70 EXPECT_TRUE(!data->next());
67 EXPECT_EQ(data, ThreadData::Get()); 71 EXPECT_EQ(data, ThreadData::Get());
68 ThreadData::BirthMap birth_map; 72 ThreadData::BirthMap birth_map;
69 data->SnapshotBirthMap(&birth_map); 73 data->SnapshotBirthMap(&birth_map);
70 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. 74 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
71 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. 75 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth.
72 ThreadData::DeathMap death_map; 76 ThreadData::DeathMap death_map;
73 data->SnapshotDeathMap(&death_map); 77 data->SnapshotDeathMap(&death_map);
74 EXPECT_EQ(0u, death_map.size()); // No deaths. 78 EXPECT_EQ(0u, death_map.size()); // No deaths.
75 79
76 80
77 // Now instigate a birth, and a death. 81 // Now instigate a birth, and a death.
78 const Births* second_birth = ThreadData::TallyABirthIfActive(location); 82 const Births* second_birth = ThreadData::TallyABirthIfActive(location);
79 ThreadData::TallyADeathIfActive( 83 ThreadData::TallyADeathIfActive(
80 second_birth, 84 second_birth,
81 base::TimeTicks(), /* Bogus post_time. */ 85 base::TimeTicks(), /* Bogus post_time. */
82 base::TimeTicks(), /* Bogus delayed_start_time. */ 86 base::TimeTicks(), /* Bogus delayed_start_time. */
83 base::TimeTicks() /* Bogus start_run_time. */); 87 base::TimeTicks(), /* Bogus start_run_time. */
88 base::TimeTicks() /* Bogus end_run_time */ );
84 89
85 birth_map.clear(); 90 birth_map.clear();
86 data->SnapshotBirthMap(&birth_map); 91 data->SnapshotBirthMap(&birth_map);
87 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. 92 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
88 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. 93 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births.
89 death_map.clear(); 94 death_map.clear();
90 data->SnapshotDeathMap(&death_map); 95 data->SnapshotDeathMap(&death_map);
91 EXPECT_EQ(1u, death_map.size()); // 1 location. 96 EXPECT_EQ(1u, death_map.size()); // 1 location.
92 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. 97 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death.
93 98
94 // The births were at the same location as the one known death. 99 // The births were at the same location as the one known death.
95 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); 100 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first);
96 101
97 ThreadData::ShutdownSingleThreadedCleanup(); 102 ThreadData::ShutdownSingleThreadedCleanup();
ramant (doing other things) 2011/10/24 18:03:49 nit: consider putting it in TearDown?
jar (doing other things) 2011/10/24 18:43:27 Done.
98 } 103 }
99 104
105 TEST_F(TrackedObjectsTest, DeathDataTest) {
106 if (!ThreadData::StartTracking(true))
107 return;
108
109 scoped_ptr<DeathData> data(new DeathData());
110 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
111 EXPECT_EQ(data->run_duration(), base::TimeDelta());
112 EXPECT_EQ(data->queue_duration(), base::TimeDelta());
113 EXPECT_EQ(data->AverageMsRunDuration(), 0);
114 EXPECT_EQ(data->AverageMsQueueDuration(), 0);
115 EXPECT_EQ(data->count(), 0);
116
117 int run_ms = 42;
118 int queue_ms = 8;
119
120 base::TimeDelta run_duration = base::TimeDelta().FromMilliseconds(run_ms);
121 base::TimeDelta queue_duration = base::TimeDelta().FromMilliseconds(queue_ms);
122 data->RecordDeath(queue_duration, run_duration);
123 EXPECT_EQ(data->run_duration(), run_duration);
124 EXPECT_EQ(data->queue_duration(), queue_duration);
125 EXPECT_EQ(data->AverageMsRunDuration(), run_ms);
126 EXPECT_EQ(data->AverageMsQueueDuration(), queue_ms);
127 EXPECT_EQ(data->count(), 1);
128
129 data->RecordDeath(queue_duration, run_duration);
130 EXPECT_EQ(data->run_duration(), run_duration + run_duration);
131 EXPECT_EQ(data->queue_duration(), queue_duration + queue_duration);
132 EXPECT_EQ(data->AverageMsRunDuration(), run_ms);
133 EXPECT_EQ(data->AverageMsQueueDuration(), queue_ms);
134 EXPECT_EQ(data->count(), 2);
135
136 scoped_ptr<base::DictionaryValue> dictionary(data->ToValue());
137 int integer;
138 EXPECT_TRUE(dictionary->GetInteger("run_ms", &integer));
139 EXPECT_EQ(integer, 2 * run_ms);
140 EXPECT_TRUE(dictionary->GetInteger("queue_ms", &integer));
141 EXPECT_EQ(integer, 2* queue_ms);
142 EXPECT_TRUE(dictionary->GetInteger("count", &integer));
143 EXPECT_EQ(integer, 2);
144
145 std::string output;
146 data->WriteHTML(&output);
147 std::string results = "Lives:2, Run:84ms(42ms/life) Queue:16ms(8ms/life) ";
148 EXPECT_EQ(output, results);
149
150 scoped_ptr<base::Value> value(data->ToValue());
151 std::string json;
152 base::JSONWriter::Write(value.get(), false, &json);
153 std::string birth_only_result = "{\"count\":2,\"queue_ms\":16,\"run_ms\":84}";
154 EXPECT_EQ(json, birth_only_result);
155
156 ThreadData::ShutdownSingleThreadedCleanup();
157 }
158
159 TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) {
160 if (!ThreadData::StartTracking(true))
161 return;
162 // We don't initialize system with a thread name, so we're viewed as a worker
163 // thread.
164 int fake_line_number = 173;
165 const char* kFile = "FixedFileName";
166 const char* kFunction = "BirthOnlyToValueWorkerThread";
167 Location location(kFunction, kFile, fake_line_number, NULL);
168 Births* birth = ThreadData::TallyABirthIfActive(location);
169 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
170
171 int process_type = 3;
172 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
173 std::string json;
174 base::JSONWriter::Write(value.get(), false, &json);
175 std::string birth_only_result = "{"
176 "\"list\":["
177 "{"
178 "\"birth_thread\":\"WorkerThread-1\","
179 "\"death_data\":{"
180 "\"count\":1,"
181 "\"queue_ms\":0,"
182 "\"run_ms\":0"
183 "},"
184 "\"death_thread\":\"Still_Alive\","
185 "\"location\":{"
186 "\"file_name\":\"FixedFileName\","
187 "\"function_name\":\"BirthOnlyToValueWorkerThread\","
188 "\"line_number\":173"
189 "}"
190 "}"
191 "],"
192 "\"process\":3"
193 "}";
194 EXPECT_EQ(json, birth_only_result);
195
196 ThreadData::ShutdownSingleThreadedCleanup();
197 }
198
199 TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) {
200 if (!ThreadData::StartTracking(true))
201 return;
202
203 // Use a well named thread.
204 ThreadData::InitializeThreadContext("SomeMainThreadName");
205 int fake_line_number = 173;
206 const char* kFile = "FixedFileName";
207 const char* kFunction = "BirthOnlyToValueMainThread";
208 Location location(kFunction, kFile, fake_line_number, NULL);
209 // Do not delete birth. We don't own it.
210 Births* birth = ThreadData::TallyABirthIfActive(location);
211 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
212
213 int process_type = 34;
214 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
215 std::string json;
216 base::JSONWriter::Write(value.get(), false, &json);
217 std::string birth_only_result = "{"
218 "\"list\":["
219 "{"
220 "\"birth_thread\":\"SomeMainThreadName\","
221 "\"death_data\":{"
222 "\"count\":1,"
223 "\"queue_ms\":0,"
224 "\"run_ms\":0"
225 "},"
226 "\"death_thread\":\"Still_Alive\","
227 "\"location\":{"
228 "\"file_name\":\"FixedFileName\","
229 "\"function_name\":\"BirthOnlyToValueMainThread\","
230 "\"line_number\":173"
231 "}"
232 "}"
233 "],"
234 "\"process\":34"
235 "}";
236 EXPECT_EQ(json, birth_only_result);
237
238 ThreadData::ShutdownSingleThreadedCleanup();
239 }
240
241 TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) {
242 if (!ThreadData::StartTracking(true))
243 return;
244
245 // Use a well named thread.
246 ThreadData::InitializeThreadContext("SomeMainThreadName");
247 int fake_line_number = 236;
248 const char* kFile = "FixedFileName";
249 const char* kFunction = "LifeCycleToValueMainThread";
250 Location location(kFunction, kFile, fake_line_number, NULL);
251 // Do not delete birth. We don't own it.
252 Births* birth = ThreadData::TallyABirthIfActive(location);
253 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
254
255 // TimeTicks initializers ar ein microseconds. Durations are calculated in
256 // milliseconds, so we need to use 1000x.
257 const base::TimeTicks time_posted = base::TimeTicks() +
258 base::TimeDelta::FromMilliseconds(1);
259 const base::TimeTicks delayed_start_time = base::TimeTicks();
260 const base::TimeTicks start_of_run = base::TimeTicks() +
261 base::TimeDelta::FromMilliseconds(5);
262 const base::TimeTicks end_of_run = base::TimeTicks() +
263 base::TimeDelta::FromMilliseconds(7);
264 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
265 start_of_run, end_of_run);
266
267 int process_type = 7;
268 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
269 std::string json;
270 base::JSONWriter::Write(value.get(), false, &json);
271 std::string one_line_result = "{"
272 "\"list\":["
273 "{"
274 "\"birth_thread\":\"SomeMainThreadName\","
275 "\"death_data\":{"
276 "\"count\":1,"
277 "\"queue_ms\":4,"
278 "\"run_ms\":2"
279 "},"
280 "\"death_thread\":\"SomeMainThreadName\","
281 "\"location\":{"
282 "\"file_name\":\"FixedFileName\","
283 "\"function_name\":\"LifeCycleToValueMainThread\","
284 "\"line_number\":236"
285 "}"
286 "}"
287 "],"
288 "\"process\":7"
289 "}";
290 EXPECT_EQ(json, one_line_result);
291
292 ThreadData::ShutdownSingleThreadedCleanup();
293 }
294
295 TEST_F(TrackedObjectsTest, TwoLives) {
296 if (!ThreadData::StartTracking(true))
297 return;
298
299 // Use a well named thread.
300 ThreadData::InitializeThreadContext("SomeFileThreadName");
301 int fake_line_number = 222;
302 const char* kFile = "AnotherFileName";
303 const char* kFunction = "TwoLives";
304 Location location(kFunction, kFile, fake_line_number, NULL);
305 // Do not delete birth. We don't own it.
306 Births* birth = ThreadData::TallyABirthIfActive(location);
307 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
308
309 // TimeTicks initializers ar ein microseconds. Durations are calculated in
310 // milliseconds, so we need to use 1000x.
311 const base::TimeTicks time_posted = base::TimeTicks() +
312 base::TimeDelta::FromMilliseconds(1);
313 const base::TimeTicks delayed_start_time = base::TimeTicks();
314 const base::TimeTicks start_of_run = base::TimeTicks() +
315 base::TimeDelta::FromMilliseconds(5);
316 const base::TimeTicks end_of_run = base::TimeTicks() +
317 base::TimeDelta::FromMilliseconds(7);
318 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
319 start_of_run, end_of_run);
320
321 birth = ThreadData::TallyABirthIfActive(location);
322 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
323 start_of_run, end_of_run);
324
325 int process_type = 7;
326 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
327 std::string json;
328 base::JSONWriter::Write(value.get(), false, &json);
329 std::string one_line_result = "{"
330 "\"list\":["
331 "{"
332 "\"birth_thread\":\"SomeFileThreadName\","
333 "\"death_data\":{"
334 "\"count\":2,"
335 "\"queue_ms\":8,"
336 "\"run_ms\":4"
337 "},"
338 "\"death_thread\":\"SomeFileThreadName\","
339 "\"location\":{"
340 "\"file_name\":\"AnotherFileName\","
341 "\"function_name\":\"TwoLives\","
342 "\"line_number\":222"
343 "}"
344 "}"
345 "],"
346 "\"process\":7"
347 "}";
348 EXPECT_EQ(json, one_line_result);
349
350 ThreadData::ShutdownSingleThreadedCleanup();
351 }
352
353 TEST_F(TrackedObjectsTest, DifferentLives) {
354 if (!ThreadData::StartTracking(true))
355 return;
356
357 // Use a well named thread.
358 ThreadData::InitializeThreadContext("SomeFileThreadName");
359 int fake_line_number = 567;
360 const char* kFile = "AnotherFileName";
361 const char* kFunction = "DifferentLives";
362 Location location(kFunction, kFile, fake_line_number, NULL);
363 // Do not delete birth. We don't own it.
364 Births* birth = ThreadData::TallyABirthIfActive(location);
365 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
366
367 // TimeTicks initializers ar ein microseconds. Durations are calculated in
368 // milliseconds, so we need to use 1000x.
369 const base::TimeTicks time_posted = base::TimeTicks() +
370 base::TimeDelta::FromMilliseconds(1);
371 const base::TimeTicks delayed_start_time = base::TimeTicks();
372 const base::TimeTicks start_of_run = base::TimeTicks() +
373 base::TimeDelta::FromMilliseconds(5);
374 const base::TimeTicks end_of_run = base::TimeTicks() +
375 base::TimeDelta::FromMilliseconds(7);
376 ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
377 start_of_run, end_of_run);
378
379 int second_fake_line_number = 999;
380 Location second_location(kFunction, kFile, second_fake_line_number, NULL);
381 birth = ThreadData::TallyABirthIfActive(second_location);
382
383 int process_type = 2;
384 scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
385 std::string json;
386 base::JSONWriter::Write(value.get(), false, &json);
387 std::string one_line_result = "{"
388 "\"list\":["
389 "{"
390 "\"birth_thread\":\"SomeFileThreadName\","
391 "\"death_data\":{"
392 "\"count\":1,"
393 "\"queue_ms\":4,"
394 "\"run_ms\":2"
395 "},"
396 "\"death_thread\":\"SomeFileThreadName\","
397 "\"location\":{"
398 "\"file_name\":\"AnotherFileName\","
399 "\"function_name\":\"DifferentLives\","
400 "\"line_number\":567"
401 "}"
402 "},"
403 "{"
404 "\"birth_thread\":\"SomeFileThreadName\","
405 "\"death_data\":{"
406 "\"count\":1,"
407 "\"queue_ms\":0,"
408 "\"run_ms\":0"
409 "},"
410 "\"death_thread\":\"Still_Alive\","
411 "\"location\":{"
412 "\"file_name\":\"AnotherFileName\","
413 "\"function_name\":\"DifferentLives\","
414 "\"line_number\":999"
415 "}"
416 "}"
417 "],"
418 "\"process\":2"
419 "}";
420 EXPECT_EQ(json, one_line_result);
421
422 ThreadData::ShutdownSingleThreadedCleanup();
423 }
424
100 } // namespace tracked_objects 425 } // namespace tracked_objects
OLDNEW
« base/tracked_objects.cc ('K') | « base/tracked_objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698