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

Side by Side Diff: base/tracked_objects_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698