blob: 68911bbd9013ce71d5ae1e9efcca964f9ebf3716 [file] [log] [blame]
[email protected]9fc44162012-01-23 22:56:411// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
5// Test of classes in the tracked_objects.h classes.
6
7#include "base/tracked_objects.h"
[email protected]f5393332009-06-03 15:01:298
[email protected]84baeca2011-10-24 18:55:169#include "base/json/json_writer.h"
10#include "base/memory/scoped_ptr.h"
[email protected]c62dd9d2011-09-21 18:05:4111#include "base/time.h"
initial.commitd7cae122008-07-26 21:49:3812#include "testing/gtest/include/gtest/gtest.h"
13
14namespace tracked_objects {
15
16class TrackedObjectsTest : public testing::Test {
[email protected]eab79c382011-11-06 19:14:4817 protected:
[email protected]b2a9bbd2011-10-31 22:36:2118 TrackedObjectsTest() {
19 // On entry, leak any database structures in case they are still in use by
20 // prior threads.
21 ThreadData::ShutdownSingleThreadedCleanup(true);
22 }
[email protected]84baeca2011-10-24 18:55:1623
[email protected]b2a9bbd2011-10-31 22:36:2124 ~TrackedObjectsTest() {
25 // We should not need to leak any structures we create, since we are
26 // single threaded, and carefully accounting for items.
27 ThreadData::ShutdownSingleThreadedCleanup(false);
28 }
[email protected]eab79c382011-11-06 19:14:4829
30 // Provide access, since this class is a friend of ThreadData.
31 void ShutdownSingleThreadedCleanup(bool leak) {
32 ThreadData::ShutdownSingleThreadedCleanup(leak);
33 }
initial.commitd7cae122008-07-26 21:49:3834};
35
[email protected]c7788d62008-08-26 06:44:3836TEST_F(TrackedObjectsTest, MinimalStartupShutdown) {
initial.commitd7cae122008-07-26 21:49:3837 // Minimal test doesn't even create any tasks.
[email protected]b2a9bbd2011-10-31 22:36:2138 if (!ThreadData::InitializeAndSetTrackingStatus(true))
initial.commitd7cae122008-07-26 21:49:3839 return;
40
41 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
[email protected]84b57952011-10-15 23:52:4542 ThreadData* data = ThreadData::Get();
initial.commitd7cae122008-07-26 21:49:3843 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
44 EXPECT_TRUE(data);
45 EXPECT_TRUE(!data->next());
[email protected]84b57952011-10-15 23:52:4546 EXPECT_EQ(data, ThreadData::Get());
initial.commitd7cae122008-07-26 21:49:3847 ThreadData::BirthMap birth_map;
initial.commitd7cae122008-07-26 21:49:3848 ThreadData::DeathMap death_map;
[email protected]8aa1e6e2011-12-14 01:36:4849 ThreadData::ParentChildSet parent_child_set;
50 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
[email protected]b6b2b892011-12-04 07:19:1051 EXPECT_EQ(0u, birth_map.size());
initial.commitd7cae122008-07-26 21:49:3852 EXPECT_EQ(0u, death_map.size());
[email protected]8aa1e6e2011-12-14 01:36:4853 EXPECT_EQ(0u, parent_child_set.size());
[email protected]b2a9bbd2011-10-31 22:36:2154 // Cleanup with no leaking.
[email protected]eab79c382011-11-06 19:14:4855 ShutdownSingleThreadedCleanup(false);
initial.commitd7cae122008-07-26 21:49:3856
57 // Do it again, just to be sure we reset state completely.
[email protected]b2a9bbd2011-10-31 22:36:2158 ThreadData::InitializeAndSetTrackingStatus(true);
initial.commitd7cae122008-07-26 21:49:3859 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
[email protected]84b57952011-10-15 23:52:4560 data = ThreadData::Get();
initial.commitd7cae122008-07-26 21:49:3861 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
62 EXPECT_TRUE(data);
63 EXPECT_TRUE(!data->next());
[email protected]84b57952011-10-15 23:52:4564 EXPECT_EQ(data, ThreadData::Get());
initial.commitd7cae122008-07-26 21:49:3865 birth_map.clear();
initial.commitd7cae122008-07-26 21:49:3866 death_map.clear();
[email protected]8aa1e6e2011-12-14 01:36:4867 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
[email protected]b6b2b892011-12-04 07:19:1068 EXPECT_EQ(0u, birth_map.size());
initial.commitd7cae122008-07-26 21:49:3869 EXPECT_EQ(0u, death_map.size());
[email protected]8aa1e6e2011-12-14 01:36:4870 EXPECT_EQ(0u, parent_child_set.size());
initial.commitd7cae122008-07-26 21:49:3871}
72
[email protected]c7788d62008-08-26 06:44:3873TEST_F(TrackedObjectsTest, TinyStartupShutdown) {
[email protected]b2a9bbd2011-10-31 22:36:2174 if (!ThreadData::InitializeAndSetTrackingStatus(true))
initial.commitd7cae122008-07-26 21:49:3875 return;
76
[email protected]84baeca2011-10-24 18:55:1677 // Instigate tracking on a single tracked object, on our thread.
[email protected]7d550fa02011-06-23 23:20:3978 const Location& location = FROM_HERE;
[email protected]8aa1e6e2011-12-14 01:36:4879 Births* first_birth = ThreadData::TallyABirthIfActive(location);
initial.commitd7cae122008-07-26 21:49:3880
[email protected]b6b2b892011-12-04 07:19:1081 ThreadData* data = ThreadData::first();
[email protected]7d550fa02011-06-23 23:20:3982 ASSERT_TRUE(data);
initial.commitd7cae122008-07-26 21:49:3883 EXPECT_TRUE(!data->next());
[email protected]84b57952011-10-15 23:52:4584 EXPECT_EQ(data, ThreadData::Get());
initial.commitd7cae122008-07-26 21:49:3885 ThreadData::BirthMap birth_map;
[email protected]b6b2b892011-12-04 07:19:1086 ThreadData::DeathMap death_map;
[email protected]8aa1e6e2011-12-14 01:36:4887 ThreadData::ParentChildSet parent_child_set;
88 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
initial.commitd7cae122008-07-26 21:49:3889 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
90 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth.
initial.commitd7cae122008-07-26 21:49:3891 EXPECT_EQ(0u, death_map.size()); // No deaths.
[email protected]8aa1e6e2011-12-14 01:36:4892 EXPECT_EQ(0u, parent_child_set.size()); // No children.
initial.commitd7cae122008-07-26 21:49:3893
94
[email protected]8aa1e6e2011-12-14 01:36:4895 // Now instigate another birth, while we are timing the run of the first
96 // execution.
97 TrackedTime start_time =
98 ThreadData::NowForStartOfRun(first_birth);
99 // Create a child (using the same birth location).
[email protected]b2a9bbd2011-10-31 22:36:21100 // TrackingInfo will call TallyABirth() during construction.
[email protected]8aa1e6e2011-12-14 01:36:48101 base::TimeTicks kBogusBirthTime;
102 base::TrackingInfo pending_task(location, kBogusBirthTime);
103 // Finally conclude the outer run.
104 TrackedTime end_time = ThreadData::NowForEndOfRun();
105 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time,
106 end_time);
initial.commitd7cae122008-07-26 21:49:38107
108 birth_map.clear();
[email protected]b6b2b892011-12-04 07:19:10109 death_map.clear();
[email protected]8aa1e6e2011-12-14 01:36:48110 parent_child_set.clear();
111 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
initial.commitd7cae122008-07-26 21:49:38112 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
113 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births.
initial.commitd7cae122008-07-26 21:49:38114 EXPECT_EQ(1u, death_map.size()); // 1 location.
115 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death.
[email protected]8aa1e6e2011-12-14 01:36:48116 if (ThreadData::tracking_parent_child_status()) {
117 EXPECT_EQ(1u, parent_child_set.size()); // 1 child.
118 EXPECT_EQ(parent_child_set.begin()->first,
119 parent_child_set.begin()->second);
120 } else {
121 EXPECT_EQ(0u, parent_child_set.size()); // no stats.
122 }
initial.commitd7cae122008-07-26 21:49:38123
124 // The births were at the same location as the one known death.
125 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first);
[email protected]84baeca2011-10-24 18:55:16126}
initial.commitd7cae122008-07-26 21:49:38127
[email protected]8aa1e6e2011-12-14 01:36:48128TEST_F(TrackedObjectsTest, ParentChildTest) {
129 if (!ThreadData::InitializeAndSetTrackingStatus(true))
130 return;
131 if (!ThreadData::tracking_parent_child_status())
132 return; // Feature not compiled in.
133
134 // Instigate tracking on a single tracked object, on our thread.
135 const int kFakeLineNumber = 1776;
136 const char* kFile = "FixedUnitTestFileName";
137 const char* kFunction = "ParentChildTest";
138 Location location(kFunction, kFile, kFakeLineNumber, NULL);
[email protected]8aa1e6e2011-12-14 01:36:48139
140 // Now instigate another birth, while we are timing the run of the first
141 // execution.
[email protected]8e3d327e2011-12-21 12:54:47142
[email protected]8aa1e6e2011-12-14 01:36:48143 // Create a child (using the same birth location).
144 // TrackingInfo will call TallyABirth() during construction.
145 base::TimeTicks kBogusBirthTime;
146 base::TrackingInfo pending_task(location, kBogusBirthTime);
147
148 // Don't conclude the run, so that we don't use the actual timer that we
149 // started for the outer profile. This way the JSON will not include some
150 // random time.
151 ThreadData* data = ThreadData::first();
152 ASSERT_TRUE(data);
153 EXPECT_TRUE(!data->next());
154 EXPECT_EQ(data, ThreadData::Get());
155
156 ThreadData::BirthMap birth_map;
157 ThreadData::DeathMap death_map;
158 ThreadData::ParentChildSet parent_child_set;
159
160 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
161 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
162 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births.
163 EXPECT_EQ(0u, death_map.size()); // No status yet.
164 // Just like TinyStartupShutdown test.
165 EXPECT_EQ(1u, parent_child_set.size()); // 1 child.
166 EXPECT_EQ(parent_child_set.begin()->first,
167 parent_child_set.begin()->second);
168
169 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
170 std::string json;
171 base::JSONWriter::Write(value.get(), false, &json);
172 std::string birth_only_result = "{"
173 "\"descendants\":["
174 "{"
175 "\"child_location\":{"
176 "\"file_name\":\"FixedUnitTestFileName\","
177 "\"function_name\":\"ParentChildTest\","
178 "\"line_number\":1776"
179 "},"
180 "\"child_thread\":\"WorkerThread-1\","
181 "\"parent_location\":{"
182 "\"file_name\":\"FixedUnitTestFileName\","
183 "\"function_name\":\"ParentChildTest\","
184 "\"line_number\":1776"
185 "},"
186 "\"parent_thread\":\"WorkerThread-1\""
187 "}"
188 "],"
189 "\"list\":["
190 "{"
191 "\"birth_thread\":\"WorkerThread-1\","
192 "\"death_data\":{"
193 "\"count\":2,"
194 "\"queue_ms\":0,"
195 "\"queue_ms_max\":0,"
196 "\"queue_ms_sample\":0,"
197 "\"run_ms\":0,"
198 "\"run_ms_max\":0,"
199 "\"run_ms_sample\":0"
200 "},"
201 "\"death_thread\":\"Still_Alive\","
202 "\"location\":{"
203 "\"file_name\":\"FixedUnitTestFileName\","
204 "\"function_name\":\"ParentChildTest\","
205 "\"line_number\":1776"
206 "}"
207 "}"
208 "]"
209 "}";
210 EXPECT_EQ(json, birth_only_result);
211}
212
[email protected]84baeca2011-10-24 18:55:16213TEST_F(TrackedObjectsTest, DeathDataTest) {
[email protected]b2a9bbd2011-10-31 22:36:21214 if (!ThreadData::InitializeAndSetTrackingStatus(true))
[email protected]84baeca2011-10-24 18:55:16215 return;
216
217 scoped_ptr<DeathData> data(new DeathData());
218 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
[email protected]b6b2b892011-12-04 07:19:10219 EXPECT_EQ(data->run_duration_sum(), 0);
220 EXPECT_EQ(data->run_duration_sample(), 0);
221 EXPECT_EQ(data->queue_duration_sum(), 0);
222 EXPECT_EQ(data->queue_duration_sample(), 0);
[email protected]84baeca2011-10-24 18:55:16223 EXPECT_EQ(data->count(), 0);
224
[email protected]c25db182011-11-11 22:40:27225 DurationInt run_ms = 42;
226 DurationInt queue_ms = 8;
[email protected]84baeca2011-10-24 18:55:16227
[email protected]b6b2b892011-12-04 07:19:10228 const int kUnrandomInt = 0; // Fake random int that ensure we sample data.
229 data->RecordDeath(queue_ms, run_ms, kUnrandomInt);
230 EXPECT_EQ(data->run_duration_sum(), run_ms);
231 EXPECT_EQ(data->run_duration_sample(), run_ms);
232 EXPECT_EQ(data->queue_duration_sum(), queue_ms);
233 EXPECT_EQ(data->queue_duration_sample(), queue_ms);
[email protected]84baeca2011-10-24 18:55:16234 EXPECT_EQ(data->count(), 1);
235
[email protected]b6b2b892011-12-04 07:19:10236 data->RecordDeath(queue_ms, run_ms, kUnrandomInt);
237 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms);
238 EXPECT_EQ(data->run_duration_sample(), run_ms);
239 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms);
240 EXPECT_EQ(data->queue_duration_sample(), queue_ms);
[email protected]84baeca2011-10-24 18:55:16241 EXPECT_EQ(data->count(), 2);
242
243 scoped_ptr<base::DictionaryValue> dictionary(data->ToValue());
244 int integer;
245 EXPECT_TRUE(dictionary->GetInteger("run_ms", &integer));
246 EXPECT_EQ(integer, 2 * run_ms);
[email protected]b6b2b892011-12-04 07:19:10247 EXPECT_TRUE(dictionary->GetInteger("run_ms_sample", &integer));
248 EXPECT_EQ(integer, run_ms);
[email protected]84baeca2011-10-24 18:55:16249 EXPECT_TRUE(dictionary->GetInteger("queue_ms", &integer));
[email protected]b2a9bbd2011-10-31 22:36:21250 EXPECT_EQ(integer, 2 * queue_ms);
[email protected]b6b2b892011-12-04 07:19:10251 EXPECT_TRUE(dictionary->GetInteger("queue_ms_sample", &integer));
252 EXPECT_EQ(integer, queue_ms);
[email protected]84baeca2011-10-24 18:55:16253 EXPECT_TRUE(dictionary->GetInteger("count", &integer));
254 EXPECT_EQ(integer, 2);
255
[email protected]84baeca2011-10-24 18:55:16256 scoped_ptr<base::Value> value(data->ToValue());
257 std::string json;
258 base::JSONWriter::Write(value.get(), false, &json);
[email protected]63f5b0e2011-11-04 00:23:27259 std::string birth_only_result = "{"
260 "\"count\":2,"
261 "\"queue_ms\":16,"
262 "\"queue_ms_max\":8,"
[email protected]b6b2b892011-12-04 07:19:10263 "\"queue_ms_sample\":8,"
[email protected]63f5b0e2011-11-04 00:23:27264 "\"run_ms\":84,"
[email protected]b6b2b892011-12-04 07:19:10265 "\"run_ms_max\":42,"
266 "\"run_ms_sample\":42"
[email protected]63f5b0e2011-11-04 00:23:27267 "}";
268 EXPECT_EQ(birth_only_result, json);
[email protected]84baeca2011-10-24 18:55:16269}
270
[email protected]b2a9bbd2011-10-31 22:36:21271TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueWorkerThread) {
272 // Transition to Deactivated state before doing anything.
273 if (!ThreadData::InitializeAndSetTrackingStatus(false))
[email protected]f0ab5ba2011-10-30 03:44:25274 return;
275 // We don't initialize system with a thread name, so we're viewed as a worker
276 // thread.
[email protected]b2a9bbd2011-10-31 22:36:21277 const int kFakeLineNumber = 173;
[email protected]f0ab5ba2011-10-30 03:44:25278 const char* kFile = "FixedFileName";
279 const char* kFunction = "BirthOnlyToValueWorkerThread";
[email protected]b2a9bbd2011-10-31 22:36:21280 Location location(kFunction, kFile, kFakeLineNumber, NULL);
281 Births* birth = ThreadData::TallyABirthIfActive(location);
282 // We should now see a NULL birth record.
283 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL));
284
[email protected]b6b2b892011-12-04 07:19:10285 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]b2a9bbd2011-10-31 22:36:21286 std::string json;
287 base::JSONWriter::Write(value.get(), false, &json);
288 std::string birth_only_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48289 "\"descendants\":["
290 "],"
[email protected]b2a9bbd2011-10-31 22:36:21291 "\"list\":["
292 "]"
293 "}";
294 EXPECT_EQ(json, birth_only_result);
295}
296
297TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueMainThread) {
298 // Start in the deactivated state.
299 if (!ThreadData::InitializeAndSetTrackingStatus(false))
300 return;
301
302 // Use a well named thread.
303 ThreadData::InitializeThreadContext("SomeMainThreadName");
304 const int kFakeLineNumber = 173;
305 const char* kFile = "FixedFileName";
306 const char* kFunction = "BirthOnlyToValueMainThread";
307 Location location(kFunction, kFile, kFakeLineNumber, NULL);
308 // Do not delete birth. We don't own it.
309 Births* birth = ThreadData::TallyABirthIfActive(location);
310 // We expect to not get a birth record.
311 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL));
312
[email protected]b6b2b892011-12-04 07:19:10313 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]b2a9bbd2011-10-31 22:36:21314 std::string json;
315 base::JSONWriter::Write(value.get(), false, &json);
316 std::string birth_only_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48317 "\"descendants\":["
318 "],"
[email protected]b2a9bbd2011-10-31 22:36:21319 "\"list\":["
320 "]"
321 "}";
322 EXPECT_EQ(json, birth_only_result);
323}
324
325TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) {
326 if (!ThreadData::InitializeAndSetTrackingStatus(true))
327 return;
328 // We don't initialize system with a thread name, so we're viewed as a worker
329 // thread.
330 const int kFakeLineNumber = 173;
331 const char* kFile = "FixedFileName";
332 const char* kFunction = "BirthOnlyToValueWorkerThread";
333 Location location(kFunction, kFile, kFakeLineNumber, NULL);
[email protected]84baeca2011-10-24 18:55:16334 Births* birth = ThreadData::TallyABirthIfActive(location);
335 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
336
[email protected]b6b2b892011-12-04 07:19:10337 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]84baeca2011-10-24 18:55:16338 std::string json;
339 base::JSONWriter::Write(value.get(), false, &json);
340 std::string birth_only_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48341 "\"descendants\":["
342 "],"
[email protected]84baeca2011-10-24 18:55:16343 "\"list\":["
344 "{"
345 "\"birth_thread\":\"WorkerThread-1\","
346 "\"death_data\":{"
347 "\"count\":1,"
348 "\"queue_ms\":0,"
[email protected]63f5b0e2011-11-04 00:23:27349 "\"queue_ms_max\":0,"
[email protected]b6b2b892011-12-04 07:19:10350 "\"queue_ms_sample\":0,"
[email protected]63f5b0e2011-11-04 00:23:27351 "\"run_ms\":0,"
[email protected]b6b2b892011-12-04 07:19:10352 "\"run_ms_max\":0,"
353 "\"run_ms_sample\":0"
[email protected]84baeca2011-10-24 18:55:16354 "},"
355 "\"death_thread\":\"Still_Alive\","
356 "\"location\":{"
357 "\"file_name\":\"FixedFileName\","
358 "\"function_name\":\"BirthOnlyToValueWorkerThread\","
359 "\"line_number\":173"
360 "}"
361 "}"
[email protected]b2a9bbd2011-10-31 22:36:21362 "]"
[email protected]84baeca2011-10-24 18:55:16363 "}";
364 EXPECT_EQ(json, birth_only_result);
365}
366
367TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) {
[email protected]b2a9bbd2011-10-31 22:36:21368 if (!ThreadData::InitializeAndSetTrackingStatus(true))
[email protected]84baeca2011-10-24 18:55:16369 return;
370
371 // Use a well named thread.
372 ThreadData::InitializeThreadContext("SomeMainThreadName");
[email protected]b2a9bbd2011-10-31 22:36:21373 const int kFakeLineNumber = 173;
[email protected]84baeca2011-10-24 18:55:16374 const char* kFile = "FixedFileName";
375 const char* kFunction = "BirthOnlyToValueMainThread";
[email protected]b2a9bbd2011-10-31 22:36:21376 Location location(kFunction, kFile, kFakeLineNumber, NULL);
[email protected]84baeca2011-10-24 18:55:16377 // Do not delete birth. We don't own it.
378 Births* birth = ThreadData::TallyABirthIfActive(location);
379 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
380
[email protected]b6b2b892011-12-04 07:19:10381 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]84baeca2011-10-24 18:55:16382 std::string json;
383 base::JSONWriter::Write(value.get(), false, &json);
384 std::string birth_only_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48385 "\"descendants\":["
386 "],"
[email protected]84baeca2011-10-24 18:55:16387 "\"list\":["
388 "{"
389 "\"birth_thread\":\"SomeMainThreadName\","
390 "\"death_data\":{"
391 "\"count\":1,"
392 "\"queue_ms\":0,"
[email protected]63f5b0e2011-11-04 00:23:27393 "\"queue_ms_max\":0,"
[email protected]b6b2b892011-12-04 07:19:10394 "\"queue_ms_sample\":0,"
[email protected]63f5b0e2011-11-04 00:23:27395 "\"run_ms\":0,"
[email protected]b6b2b892011-12-04 07:19:10396 "\"run_ms_max\":0,"
397 "\"run_ms_sample\":0"
[email protected]84baeca2011-10-24 18:55:16398 "},"
399 "\"death_thread\":\"Still_Alive\","
400 "\"location\":{"
401 "\"file_name\":\"FixedFileName\","
402 "\"function_name\":\"BirthOnlyToValueMainThread\","
403 "\"line_number\":173"
404 "}"
405 "}"
[email protected]b2a9bbd2011-10-31 22:36:21406 "]"
[email protected]84baeca2011-10-24 18:55:16407 "}";
408 EXPECT_EQ(json, birth_only_result);
409}
410
411TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) {
[email protected]b2a9bbd2011-10-31 22:36:21412 if (!ThreadData::InitializeAndSetTrackingStatus(true))
[email protected]84baeca2011-10-24 18:55:16413 return;
414
415 // Use a well named thread.
416 ThreadData::InitializeThreadContext("SomeMainThreadName");
[email protected]b2a9bbd2011-10-31 22:36:21417 const int kFakeLineNumber = 236;
[email protected]84baeca2011-10-24 18:55:16418 const char* kFile = "FixedFileName";
419 const char* kFunction = "LifeCycleToValueMainThread";
[email protected]b2a9bbd2011-10-31 22:36:21420 Location location(kFunction, kFile, kFakeLineNumber, NULL);
[email protected]84baeca2011-10-24 18:55:16421 // Do not delete birth. We don't own it.
422 Births* birth = ThreadData::TallyABirthIfActive(location);
423 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
424
[email protected]b2a9bbd2011-10-31 22:36:21425 const base::TimeTicks kTimePosted = base::TimeTicks()
426 + base::TimeDelta::FromMilliseconds(1);
427 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
428 // TrackingInfo will call TallyABirth() during construction.
429 base::TrackingInfo pending_task(location, kDelayedStartTime);
430 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
[email protected]84baeca2011-10-24 18:55:16431
[email protected]b2a9bbd2011-10-31 22:36:21432 const TrackedTime kStartOfRun = TrackedTime() +
433 Duration::FromMilliseconds(5);
434 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
435 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
436 kStartOfRun, kEndOfRun);
437
[email protected]b6b2b892011-12-04 07:19:10438 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]84baeca2011-10-24 18:55:16439 std::string json;
440 base::JSONWriter::Write(value.get(), false, &json);
441 std::string one_line_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48442 "\"descendants\":["
443 "],"
[email protected]84baeca2011-10-24 18:55:16444 "\"list\":["
445 "{"
446 "\"birth_thread\":\"SomeMainThreadName\","
447 "\"death_data\":{"
448 "\"count\":1,"
449 "\"queue_ms\":4,"
[email protected]63f5b0e2011-11-04 00:23:27450 "\"queue_ms_max\":4,"
[email protected]b6b2b892011-12-04 07:19:10451 "\"queue_ms_sample\":4,"
[email protected]63f5b0e2011-11-04 00:23:27452 "\"run_ms\":2,"
[email protected]b6b2b892011-12-04 07:19:10453 "\"run_ms_max\":2,"
454 "\"run_ms_sample\":2"
[email protected]84baeca2011-10-24 18:55:16455 "},"
456 "\"death_thread\":\"SomeMainThreadName\","
457 "\"location\":{"
458 "\"file_name\":\"FixedFileName\","
459 "\"function_name\":\"LifeCycleToValueMainThread\","
460 "\"line_number\":236"
461 "}"
462 "}"
[email protected]b2a9bbd2011-10-31 22:36:21463 "]"
[email protected]84baeca2011-10-24 18:55:16464 "}";
[email protected]b2a9bbd2011-10-31 22:36:21465 EXPECT_EQ(one_line_result, json);
[email protected]f0ab5ba2011-10-30 03:44:25466}
467
[email protected]b2a9bbd2011-10-31 22:36:21468// We will deactivate tracking after the birth, and before the death, and
469// demonstrate that the lifecycle is completely tallied. This ensures that
470// our tallied births are matched by tallied deaths (except for when the
471// task is still running, or is queued).
472TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToValueMainThread) {
473 if (!ThreadData::InitializeAndSetTrackingStatus(true))
[email protected]f0ab5ba2011-10-30 03:44:25474 return;
475
476 // Use a well named thread.
[email protected]b2a9bbd2011-10-31 22:36:21477 ThreadData::InitializeThreadContext("SomeMainThreadName");
478 const int kFakeLineNumber = 236;
479 const char* kFile = "FixedFileName";
480 const char* kFunction = "LifeCycleToValueMainThread";
481 Location location(kFunction, kFile, kFakeLineNumber, NULL);
[email protected]f0ab5ba2011-10-30 03:44:25482 // Do not delete birth. We don't own it.
483 Births* birth = ThreadData::TallyABirthIfActive(location);
484 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
485
[email protected]b2a9bbd2011-10-31 22:36:21486 const base::TimeTicks kTimePosted = base::TimeTicks()
487 + base::TimeDelta::FromMilliseconds(1);
488 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
489 // TrackingInfo will call TallyABirth() during construction.
490 base::TrackingInfo pending_task(location, kDelayedStartTime);
491 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
[email protected]f0ab5ba2011-10-30 03:44:25492
[email protected]b2a9bbd2011-10-31 22:36:21493 // Turn off tracking now that we have births.
494 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(false));
[email protected]f0ab5ba2011-10-30 03:44:25495
[email protected]b2a9bbd2011-10-31 22:36:21496 const TrackedTime kStartOfRun = TrackedTime() +
497 Duration::FromMilliseconds(5);
498 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
499 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
500 kStartOfRun, kEndOfRun);
501
[email protected]b6b2b892011-12-04 07:19:10502 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]b2a9bbd2011-10-31 22:36:21503 std::string json;
504 base::JSONWriter::Write(value.get(), false, &json);
505 std::string one_line_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48506 "\"descendants\":["
507 "],"
[email protected]b2a9bbd2011-10-31 22:36:21508 "\"list\":["
509 "{"
510 "\"birth_thread\":\"SomeMainThreadName\","
511 "\"death_data\":{"
512 "\"count\":1,"
513 "\"queue_ms\":4,"
[email protected]63f5b0e2011-11-04 00:23:27514 "\"queue_ms_max\":4,"
[email protected]b6b2b892011-12-04 07:19:10515 "\"queue_ms_sample\":4,"
[email protected]63f5b0e2011-11-04 00:23:27516 "\"run_ms\":2,"
[email protected]b6b2b892011-12-04 07:19:10517 "\"run_ms_max\":2,"
518 "\"run_ms_sample\":2"
[email protected]b2a9bbd2011-10-31 22:36:21519 "},"
520 "\"death_thread\":\"SomeMainThreadName\","
521 "\"location\":{"
522 "\"file_name\":\"FixedFileName\","
523 "\"function_name\":\"LifeCycleToValueMainThread\","
524 "\"line_number\":236"
525 "}"
526 "}"
527 "]"
528 "}";
529 EXPECT_EQ(one_line_result, json);
530}
531
532// We will deactivate tracking before starting a life cycle, and neither
533// the birth nor the death will be recorded.
534TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToValueMainThread) {
535 if (!ThreadData::InitializeAndSetTrackingStatus(false))
536 return;
537
538 // Use a well named thread.
539 ThreadData::InitializeThreadContext("SomeMainThreadName");
540 const int kFakeLineNumber = 236;
541 const char* kFile = "FixedFileName";
542 const char* kFunction = "LifeCycleToValueMainThread";
543 Location location(kFunction, kFile, kFakeLineNumber, NULL);
544 // Do not delete birth. We don't own it.
545 Births* birth = ThreadData::TallyABirthIfActive(location);
546 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL));
547
548 const base::TimeTicks kTimePosted = base::TimeTicks()
549 + base::TimeDelta::FromMilliseconds(1);
550 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
551 // TrackingInfo will call TallyABirth() during construction.
552 base::TrackingInfo pending_task(location, kDelayedStartTime);
553 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
554
555 const TrackedTime kStartOfRun = TrackedTime() +
556 Duration::FromMilliseconds(5);
557 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
558 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
559 kStartOfRun, kEndOfRun);
560
[email protected]b6b2b892011-12-04 07:19:10561 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]b2a9bbd2011-10-31 22:36:21562 std::string json;
563 base::JSONWriter::Write(value.get(), false, &json);
564 std::string one_line_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48565 "\"descendants\":["
566 "],"
[email protected]b2a9bbd2011-10-31 22:36:21567 "\"list\":["
568 "]"
569 "}";
570 EXPECT_EQ(one_line_result, json);
571}
572
573TEST_F(TrackedObjectsTest, LifeCycleToValueWorkerThread) {
574 if (!ThreadData::InitializeAndSetTrackingStatus(true))
575 return;
576
577 // Don't initialize thread, so that we appear as a worker thread.
578 // ThreadData::InitializeThreadContext("SomeMainThreadName");
579
580 const int kFakeLineNumber = 236;
581 const char* kFile = "FixedFileName";
582 const char* kFunction = "LifeCycleToValueWorkerThread";
583 Location location(kFunction, kFile, kFakeLineNumber, NULL);
584 // Do not delete birth. We don't own it.
585 Births* birth = ThreadData::TallyABirthIfActive(location);
586 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
587
588 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1);
589 const TrackedTime kStartOfRun = TrackedTime() +
590 Duration::FromMilliseconds(5);
591 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
592 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted,
593 kStartOfRun, kEndOfRun);
594
[email protected]b6b2b892011-12-04 07:19:10595 // Call for the ToValue, but tell it to not the maxes after scanning.
596 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]b2a9bbd2011-10-31 22:36:21597 std::string json;
598 base::JSONWriter::Write(value.get(), false, &json);
599 std::string one_line_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48600 "\"descendants\":["
601 "],"
[email protected]b2a9bbd2011-10-31 22:36:21602 "\"list\":["
603 "{"
604 "\"birth_thread\":\"WorkerThread-1\","
605 "\"death_data\":{"
606 "\"count\":1,"
607 "\"queue_ms\":4,"
[email protected]63f5b0e2011-11-04 00:23:27608 "\"queue_ms_max\":4,"
[email protected]b6b2b892011-12-04 07:19:10609 "\"queue_ms_sample\":4,"
[email protected]63f5b0e2011-11-04 00:23:27610 "\"run_ms\":2,"
[email protected]b6b2b892011-12-04 07:19:10611 "\"run_ms_max\":2,"
612 "\"run_ms_sample\":2"
[email protected]b2a9bbd2011-10-31 22:36:21613 "},"
614 "\"death_thread\":\"WorkerThread-1\","
615 "\"location\":{"
616 "\"file_name\":\"FixedFileName\","
617 "\"function_name\":\"LifeCycleToValueWorkerThread\","
618 "\"line_number\":236"
619 "}"
620 "}"
621 "]"
622 "}";
623 EXPECT_EQ(one_line_result, json);
[email protected]b6b2b892011-12-04 07:19:10624
625 // Call for the ToValue, but tell it to reset the maxes after scanning.
626 // We'll still get the same values, but the data will be reset (which we'll
627 // see in a moment).
628 value.reset(ThreadData::ToValue(true));
629 base::JSONWriter::Write(value.get(), false, &json);
630 // Result should be unchanged.
631 EXPECT_EQ(one_line_result, json);
632
633 // Call for the ToValue, and now we'll see the result of the last translation,
634 // as the max will have been pushed back to zero.
635 value.reset(ThreadData::ToValue(false));
636 base::JSONWriter::Write(value.get(), false, &json);
637 std::string one_line_result_with_zeros = "{"
[email protected]8aa1e6e2011-12-14 01:36:48638 "\"descendants\":["
639 "],"
[email protected]b6b2b892011-12-04 07:19:10640 "\"list\":["
641 "{"
642 "\"birth_thread\":\"WorkerThread-1\","
643 "\"death_data\":{"
644 "\"count\":1,"
645 "\"queue_ms\":4,"
646 "\"queue_ms_max\":0," // Note zero here.
647 "\"queue_ms_sample\":4,"
648 "\"run_ms\":2,"
649 "\"run_ms_max\":0," // Note zero here.
650 "\"run_ms_sample\":2"
651 "},"
652 "\"death_thread\":\"WorkerThread-1\","
653 "\"location\":{"
654 "\"file_name\":\"FixedFileName\","
655 "\"function_name\":\"LifeCycleToValueWorkerThread\","
656 "\"line_number\":236"
657 "}"
658 "}"
659 "]"
660 "}";
661 EXPECT_EQ(one_line_result_with_zeros, json);
[email protected]b2a9bbd2011-10-31 22:36:21662}
663
664TEST_F(TrackedObjectsTest, TwoLives) {
665 if (!ThreadData::InitializeAndSetTrackingStatus(true))
666 return;
667
668 // Use a well named thread.
669 ThreadData::InitializeThreadContext("SomeFileThreadName");
670 const int kFakeLineNumber = 222;
671 const char* kFile = "AnotherFileName";
672 const char* kFunction = "TwoLives";
673 Location location(kFunction, kFile, kFakeLineNumber, NULL);
674 // Do not delete birth. We don't own it.
675 Births* birth = ThreadData::TallyABirthIfActive(location);
676 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
677
678
679 const base::TimeTicks kTimePosted = base::TimeTicks()
680 + base::TimeDelta::FromMilliseconds(1);
681 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
682 // TrackingInfo will call TallyABirth() during construction.
683 base::TrackingInfo pending_task(location, kDelayedStartTime);
684 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
685
686 const TrackedTime kStartOfRun = TrackedTime() +
687 Duration::FromMilliseconds(5);
688 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
689 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
690 kStartOfRun, kEndOfRun);
691
692 // TrackingInfo will call TallyABirth() during construction.
693 base::TrackingInfo pending_task2(location, kDelayedStartTime);
694 pending_task2.time_posted = kTimePosted; // Overwrite implied Now().
695
696 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2,
697 kStartOfRun, kEndOfRun);
698
[email protected]b6b2b892011-12-04 07:19:10699 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]84baeca2011-10-24 18:55:16700 std::string json;
701 base::JSONWriter::Write(value.get(), false, &json);
702 std::string one_line_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48703 "\"descendants\":["
704 "],"
[email protected]84baeca2011-10-24 18:55:16705 "\"list\":["
706 "{"
707 "\"birth_thread\":\"SomeFileThreadName\","
708 "\"death_data\":{"
709 "\"count\":2,"
710 "\"queue_ms\":8,"
[email protected]63f5b0e2011-11-04 00:23:27711 "\"queue_ms_max\":4,"
[email protected]b6b2b892011-12-04 07:19:10712 "\"queue_ms_sample\":4,"
[email protected]63f5b0e2011-11-04 00:23:27713 "\"run_ms\":4,"
[email protected]b6b2b892011-12-04 07:19:10714 "\"run_ms_max\":2,"
715 "\"run_ms_sample\":2"
[email protected]84baeca2011-10-24 18:55:16716 "},"
717 "\"death_thread\":\"SomeFileThreadName\","
718 "\"location\":{"
719 "\"file_name\":\"AnotherFileName\","
720 "\"function_name\":\"TwoLives\","
721 "\"line_number\":222"
722 "}"
723 "}"
[email protected]b2a9bbd2011-10-31 22:36:21724 "]"
[email protected]84baeca2011-10-24 18:55:16725 "}";
[email protected]b2a9bbd2011-10-31 22:36:21726 EXPECT_EQ(one_line_result, json);
[email protected]84baeca2011-10-24 18:55:16727}
728
729TEST_F(TrackedObjectsTest, DifferentLives) {
[email protected]b2a9bbd2011-10-31 22:36:21730 if (!ThreadData::InitializeAndSetTrackingStatus(true))
[email protected]84baeca2011-10-24 18:55:16731 return;
732
733 // Use a well named thread.
734 ThreadData::InitializeThreadContext("SomeFileThreadName");
[email protected]b2a9bbd2011-10-31 22:36:21735 const int kFakeLineNumber = 567;
[email protected]84baeca2011-10-24 18:55:16736 const char* kFile = "AnotherFileName";
737 const char* kFunction = "DifferentLives";
[email protected]b2a9bbd2011-10-31 22:36:21738 Location location(kFunction, kFile, kFakeLineNumber, NULL);
[email protected]84baeca2011-10-24 18:55:16739
[email protected]b2a9bbd2011-10-31 22:36:21740 const base::TimeTicks kTimePosted = base::TimeTicks()
741 + base::TimeDelta::FromMilliseconds(1);
742 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
743 // TrackingInfo will call TallyABirth() during construction.
744 base::TrackingInfo pending_task(location, kDelayedStartTime);
745 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
[email protected]84baeca2011-10-24 18:55:16746
[email protected]b2a9bbd2011-10-31 22:36:21747 const TrackedTime kStartOfRun = TrackedTime() +
748 Duration::FromMilliseconds(5);
749 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
750 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
751 kStartOfRun, kEndOfRun);
[email protected]84baeca2011-10-24 18:55:16752
[email protected]b2a9bbd2011-10-31 22:36:21753 const int kSecondFakeLineNumber = 999;
754 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL);
755
756 // TrackingInfo will call TallyABirth() during construction.
757 base::TrackingInfo pending_task2(second_location, kDelayedStartTime);
758 pending_task2.time_posted = kTimePosted; // Overwrite implied Now().
759
[email protected]b6b2b892011-12-04 07:19:10760 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
[email protected]84baeca2011-10-24 18:55:16761 std::string json;
762 base::JSONWriter::Write(value.get(), false, &json);
763 std::string one_line_result = "{"
[email protected]8aa1e6e2011-12-14 01:36:48764 "\"descendants\":["
765 "],"
[email protected]84baeca2011-10-24 18:55:16766 "\"list\":["
767 "{"
768 "\"birth_thread\":\"SomeFileThreadName\","
769 "\"death_data\":{"
770 "\"count\":1,"
771 "\"queue_ms\":4,"
[email protected]63f5b0e2011-11-04 00:23:27772 "\"queue_ms_max\":4,"
[email protected]b6b2b892011-12-04 07:19:10773 "\"queue_ms_sample\":4,"
[email protected]63f5b0e2011-11-04 00:23:27774 "\"run_ms\":2,"
[email protected]b6b2b892011-12-04 07:19:10775 "\"run_ms_max\":2,"
776 "\"run_ms_sample\":2"
[email protected]84baeca2011-10-24 18:55:16777 "},"
778 "\"death_thread\":\"SomeFileThreadName\","
779 "\"location\":{"
780 "\"file_name\":\"AnotherFileName\","
781 "\"function_name\":\"DifferentLives\","
782 "\"line_number\":567"
783 "}"
784 "},"
785 "{"
786 "\"birth_thread\":\"SomeFileThreadName\","
787 "\"death_data\":{"
788 "\"count\":1,"
789 "\"queue_ms\":0,"
[email protected]63f5b0e2011-11-04 00:23:27790 "\"queue_ms_max\":0,"
[email protected]b6b2b892011-12-04 07:19:10791 "\"queue_ms_sample\":0,"
[email protected]63f5b0e2011-11-04 00:23:27792 "\"run_ms\":0,"
[email protected]b6b2b892011-12-04 07:19:10793 "\"run_ms_max\":0,"
794 "\"run_ms_sample\":0"
[email protected]84baeca2011-10-24 18:55:16795 "},"
796 "\"death_thread\":\"Still_Alive\","
797 "\"location\":{"
798 "\"file_name\":\"AnotherFileName\","
799 "\"function_name\":\"DifferentLives\","
800 "\"line_number\":999"
801 "}"
802 "}"
[email protected]b2a9bbd2011-10-31 22:36:21803 "]"
[email protected]84baeca2011-10-24 18:55:16804 "}";
[email protected]b2a9bbd2011-10-31 22:36:21805 EXPECT_EQ(one_line_result, json);
initial.commitd7cae122008-07-26 21:49:38806}
807
[email protected]92735c42011-11-02 01:35:05808
[email protected]0ce642c2008-08-26 11:29:01809} // namespace tracked_objects