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

Side by Side Diff: base/tracked_objects_unittest.cc

Issue 9702014: [UMA] Use proper C++ objects to serialize tracked_objects across process boundaries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unit test compilation Created 8 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/memory/scoped_ptr.h"
10 #include "base/process_util.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 const int kLineNumber = 1776;
15 const char kFile[] = "FixedUnitTestFileName";
16 const char kFunction[] = "CatchEmAll";
17 const char kWorkerThreadName[] = "WorkerThread-1";
18 const char kMainThreadName[] = "SomeMainThreadName";
19 const char kStillAlive[] = "Still_Alive";
jar (doing other things) 2012/04/10 15:09:36 The standardizing on the names, and line numbers t
Ilya Sherman 2012/04/10 20:34:41 Does the DifferentLives test not give us the desir
20
14 namespace tracked_objects { 21 namespace tracked_objects {
15 22
16 class TrackedObjectsTest : public testing::Test { 23 class TrackedObjectsTest : public testing::Test {
17 protected: 24 protected:
18 TrackedObjectsTest() { 25 TrackedObjectsTest() {
19 // On entry, leak any database structures in case they are still in use by 26 // On entry, leak any database structures in case they are still in use by
20 // prior threads. 27 // prior threads.
21 ThreadData::ShutdownSingleThreadedCleanup(true); 28 ThreadData::ShutdownSingleThreadedCleanup(true);
22 } 29 }
23 30
24 virtual ~TrackedObjectsTest() { 31 virtual ~TrackedObjectsTest() {
25 // We should not need to leak any structures we create, since we are 32 // We should not need to leak any structures we create, since we are
26 // single threaded, and carefully accounting for items. 33 // single threaded, and carefully accounting for items.
27 ThreadData::ShutdownSingleThreadedCleanup(false); 34 ThreadData::ShutdownSingleThreadedCleanup(false);
28 } 35 }
29 36
30 // Provide access, since this class is a friend of ThreadData. 37 // Reset the profiler state.
31 void ShutdownSingleThreadedCleanup(bool leak) { 38 void Reset() {
32 ThreadData::ShutdownSingleThreadedCleanup(leak); 39 ThreadData::ShutdownSingleThreadedCleanup(false);
40 }
41
42 // Simulate a birth on the thread named |thread_name|, at the given
43 // |location|.
44 void TallyABirth(const Location& location, const std::string& thread_name) {
jar (doing other things) 2012/04/10 15:09:36 This was a nice refactor to create these two helpe
45 // If the |thread_name| is empty, we don't initialize system with a thread
46 // name, so we're viewed as a worker thread.
47 if (!thread_name.empty())
48 ThreadData::InitializeThreadContext(kMainThreadName);
49
50 // Do not delete |birth|. We don't own it.
51 Births* birth = ThreadData::TallyABirthIfActive(location);
52
53 if (ThreadData::status() == ThreadData::DEACTIVATED)
54 EXPECT_EQ(reinterpret_cast<Births*>(NULL), birth);
55 else
56 EXPECT_NE(reinterpret_cast<Births*>(NULL), birth);
57 }
58
59 // Helper function to verify the most common test expectations.
60 void ExpectSimpleProcessData(const ProcessDataSnapshot& process_data,
61 const std::string& birth_thread,
62 const std::string& death_thread,
63 int count,
64 int run_ms,
65 int queue_ms) {
66 ASSERT_EQ(1u, process_data.tasks.size());
67
68 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name);
69 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name);
70 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number);
71
72 EXPECT_EQ(birth_thread, process_data.tasks[0].birth.thread_name);
73
74 EXPECT_EQ(count, process_data.tasks[0].death_data.count);
75 EXPECT_EQ(count * run_ms,
76 process_data.tasks[0].death_data.run_duration_sum);
77 EXPECT_EQ(run_ms, process_data.tasks[0].death_data.run_duration_max);
78 EXPECT_EQ(run_ms, process_data.tasks[0].death_data.run_duration_sample);
79 EXPECT_EQ(count * queue_ms,
80 process_data.tasks[0].death_data.queue_duration_sum);
81 EXPECT_EQ(queue_ms, process_data.tasks[0].death_data.queue_duration_max);
82 EXPECT_EQ(queue_ms, process_data.tasks[0].death_data.queue_duration_sample);
83
84 EXPECT_EQ(death_thread, process_data.tasks[0].death_thread_name);
85
86 EXPECT_EQ(0u, process_data.descendants.size());
87
88 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
33 } 89 }
34 }; 90 };
35 91
36 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { 92 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) {
37 // Minimal test doesn't even create any tasks. 93 // Minimal test doesn't even create any tasks.
38 if (!ThreadData::InitializeAndSetTrackingStatus( 94 if (!ThreadData::InitializeAndSetTrackingStatus(
39 ThreadData::PROFILING_CHILDREN_ACTIVE)) 95 ThreadData::PROFILING_CHILDREN_ACTIVE))
40 return; 96 return;
41 97
42 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. 98 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
43 ThreadData* data = ThreadData::Get(); 99 ThreadData* data = ThreadData::Get();
44 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. 100 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
45 EXPECT_TRUE(data); 101 ASSERT_TRUE(data);
46 EXPECT_TRUE(!data->next()); 102 EXPECT_FALSE(data->next());
47 EXPECT_EQ(data, ThreadData::Get()); 103 EXPECT_EQ(data, ThreadData::Get());
48 ThreadData::BirthMap birth_map; 104 ThreadData::BirthMap birth_map;
49 ThreadData::DeathMap death_map; 105 ThreadData::DeathMap death_map;
50 ThreadData::ParentChildSet parent_child_set; 106 ThreadData::ParentChildSet parent_child_set;
51 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 107 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
52 EXPECT_EQ(0u, birth_map.size()); 108 EXPECT_EQ(0u, birth_map.size());
53 EXPECT_EQ(0u, death_map.size()); 109 EXPECT_EQ(0u, death_map.size());
54 EXPECT_EQ(0u, parent_child_set.size()); 110 EXPECT_EQ(0u, parent_child_set.size());
55 // Cleanup with no leaking. 111
56 ShutdownSingleThreadedCleanup(false); 112 // Clean up with no leaking.
113 Reset();
57 114
58 // Do it again, just to be sure we reset state completely. 115 // Do it again, just to be sure we reset state completely.
59 ThreadData::InitializeAndSetTrackingStatus( 116 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(
60 ThreadData::PROFILING_CHILDREN_ACTIVE); 117 ThreadData::PROFILING_CHILDREN_ACTIVE));
61 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. 118 EXPECT_FALSE(ThreadData::first()); // No activity even on this thread.
62 data = ThreadData::Get(); 119 data = ThreadData::Get();
63 EXPECT_TRUE(ThreadData::first()); // Now class was constructed. 120 EXPECT_TRUE(ThreadData::first()); // Now class was constructed.
64 EXPECT_TRUE(data); 121 ASSERT_TRUE(data);
65 EXPECT_TRUE(!data->next()); 122 EXPECT_FALSE(data->next());
66 EXPECT_EQ(data, ThreadData::Get()); 123 EXPECT_EQ(data, ThreadData::Get());
67 birth_map.clear(); 124 birth_map.clear();
68 death_map.clear(); 125 death_map.clear();
126 parent_child_set.clear();
69 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 127 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
70 EXPECT_EQ(0u, birth_map.size()); 128 EXPECT_EQ(0u, birth_map.size());
71 EXPECT_EQ(0u, death_map.size()); 129 EXPECT_EQ(0u, death_map.size());
72 EXPECT_EQ(0u, parent_child_set.size()); 130 EXPECT_EQ(0u, parent_child_set.size());
73 } 131 }
74 132
75 TEST_F(TrackedObjectsTest, TinyStartupShutdown) { 133 TEST_F(TrackedObjectsTest, TinyStartupShutdown) {
76 if (!ThreadData::InitializeAndSetTrackingStatus( 134 if (!ThreadData::InitializeAndSetTrackingStatus(
77 ThreadData::PROFILING_CHILDREN_ACTIVE)) 135 ThreadData::PROFILING_CHILDREN_ACTIVE))
78 return; 136 return;
79 137
80 // Instigate tracking on a single tracked object, on our thread. 138 // Instigate tracking on a single tracked object, on our thread.
81 const Location& location = FROM_HERE; 139 Location location(kFunction, kFile, kLineNumber, NULL);
82 Births* first_birth = ThreadData::TallyABirthIfActive(location); 140 Births* first_birth = ThreadData::TallyABirthIfActive(location);
83 141
84 ThreadData* data = ThreadData::first(); 142 ThreadData* data = ThreadData::first();
85 ASSERT_TRUE(data); 143 ASSERT_TRUE(data);
86 EXPECT_TRUE(!data->next()); 144 EXPECT_FALSE(data->next());
87 EXPECT_EQ(data, ThreadData::Get()); 145 EXPECT_EQ(data, ThreadData::Get());
88 ThreadData::BirthMap birth_map; 146 ThreadData::BirthMap birth_map;
89 ThreadData::DeathMap death_map; 147 ThreadData::DeathMap death_map;
90 ThreadData::ParentChildSet parent_child_set; 148 ThreadData::ParentChildSet parent_child_set;
91 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 149 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
92 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. 150 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
93 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. 151 EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth.
94 EXPECT_EQ(0u, death_map.size()); // No deaths. 152 EXPECT_EQ(0u, death_map.size()); // No deaths.
95 EXPECT_EQ(0u, parent_child_set.size()); // No children. 153 EXPECT_EQ(0u, parent_child_set.size()); // No children.
96 154
97 155
98 // Now instigate another birth, while we are timing the run of the first 156 // Now instigate another birth, while we are timing the run of the first
99 // execution. 157 // execution.
100 TrackedTime start_time = 158 TrackedTime start_time = ThreadData::NowForStartOfRun(first_birth);
101 ThreadData::NowForStartOfRun(first_birth);
102 // Create a child (using the same birth location). 159 // Create a child (using the same birth location).
103 // TrackingInfo will call TallyABirth() during construction. 160 // TrackingInfo will call TallyABirth() during construction.
104 base::TimeTicks kBogusBirthTime; 161 base::TimeTicks kBogusBirthTime;
105 base::TrackingInfo pending_task(location, kBogusBirthTime); 162 base::TrackingInfo pending_task(location, kBogusBirthTime);
106 // Finally conclude the outer run. 163 // Finally conclude the outer run.
107 TrackedTime end_time = ThreadData::NowForEndOfRun(); 164 TrackedTime end_time = ThreadData::NowForEndOfRun();
108 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time, 165 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time,
109 end_time); 166 end_time);
110 167
111 birth_map.clear(); 168 birth_map.clear();
112 death_map.clear(); 169 death_map.clear();
113 parent_child_set.clear(); 170 parent_child_set.clear();
114 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); 171 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
115 EXPECT_EQ(1u, birth_map.size()); // 1 birth location. 172 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
116 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. 173 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births.
117 EXPECT_EQ(1u, death_map.size()); // 1 location. 174 EXPECT_EQ(1u, death_map.size()); // 1 location.
118 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. 175 EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death.
119 if (ThreadData::TrackingParentChildStatus()) { 176 if (ThreadData::TrackingParentChildStatus()) {
120 EXPECT_EQ(1u, parent_child_set.size()); // 1 child. 177 EXPECT_EQ(1u, parent_child_set.size()); // 1 child.
121 EXPECT_EQ(parent_child_set.begin()->first, 178 EXPECT_EQ(parent_child_set.begin()->first,
122 parent_child_set.begin()->second); 179 parent_child_set.begin()->second);
123 } else { 180 } else {
124 EXPECT_EQ(0u, parent_child_set.size()); // no stats. 181 EXPECT_EQ(0u, parent_child_set.size()); // no stats.
125 } 182 }
126 183
127 // The births were at the same location as the one known death. 184 // The births were at the same location as the one known death.
128 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); 185 EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first);
129 }
130 186
131 TEST_F(TrackedObjectsTest, ParentChildTest) { 187 ProcessDataSnapshot process_data;
132 if (!ThreadData::InitializeAndSetTrackingStatus( 188 ThreadData::Snapshot(false, &process_data);
133 ThreadData::PROFILING_CHILDREN_ACTIVE))
134 return;
135 if (!ThreadData::TrackingParentChildStatus())
136 return; // Feature not compiled in.
137 189
138 // Instigate tracking on a single tracked object, on our thread. 190 const int32 time_elapsed = (end_time - start_time).InMilliseconds();
139 const int kFakeLineNumber = 1776; 191 ASSERT_EQ(1u, process_data.tasks.size());
140 const char* kFile = "FixedUnitTestFileName"; 192 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name);
141 const char* kFunction = "ParentChildTest"; 193 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name);
142 Location location(kFunction, kFile, kFakeLineNumber, NULL); 194 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number);
195 EXPECT_EQ(kWorkerThreadName, process_data.tasks[0].birth.thread_name);
196 EXPECT_EQ(1, process_data.tasks[0].death_data.count);
197 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_sum);
198 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_max);
199 EXPECT_EQ(time_elapsed, process_data.tasks[0].death_data.run_duration_sample);
200 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_sum);
201 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_max);
202 EXPECT_EQ(0, process_data.tasks[0].death_data.queue_duration_sample);
203 EXPECT_EQ(kWorkerThreadName, process_data.tasks[0].death_thread_name);
143 204
144 // Now instigate another birth, while we are timing the run of the first 205 if (ThreadData::TrackingParentChildStatus()) {
145 // execution. 206 ASSERT_EQ(1u, process_data.descendants.size());
146 207 EXPECT_EQ(kFile, process_data.descendants[0].parent.location.file_name);
147 // Create a child (using the same birth location). 208 EXPECT_EQ(kFunction,
148 // TrackingInfo will call TallyABirth() during construction. 209 process_data.descendants[0].parent.location.function_name);
149 base::TimeTicks kBogusBirthTime; 210 EXPECT_EQ(kLineNumber,
150 base::TrackingInfo pending_task(location, kBogusBirthTime); 211 process_data.descendants[0].parent.location.line_number);
151 212 EXPECT_EQ(kWorkerThreadName,
152 // Don't conclude the run, so that we don't use the actual timer that we 213 process_data.descendants[0].parent.thread_name);
153 // started for the outer profile. This way the JSON will not include some 214 EXPECT_EQ(kFile, process_data.descendants[0].child.location.file_name);
154 // random time. 215 EXPECT_EQ(kFunction,
155 ThreadData* data = ThreadData::first(); 216 process_data.descendants[0].child.location.function_name);
156 ASSERT_TRUE(data); 217 EXPECT_EQ(kLineNumber,
157 EXPECT_TRUE(!data->next()); 218 process_data.descendants[0].child.location.line_number);
158 EXPECT_EQ(data, ThreadData::Get()); 219 EXPECT_EQ(kWorkerThreadName, process_data.descendants[0].child.thread_name);
159 220 } else {
160 ThreadData::BirthMap birth_map; 221 EXPECT_EQ(0u, process_data.descendants.size());
161 ThreadData::DeathMap death_map; 222 }
162 ThreadData::ParentChildSet parent_child_set;
163
164 data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set);
165 EXPECT_EQ(1u, birth_map.size()); // 1 birth location.
166 EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births.
167 EXPECT_EQ(0u, death_map.size()); // No status yet.
168 // Just like TinyStartupShutdown test.
169 EXPECT_EQ(1u, parent_child_set.size()); // 1 child.
170 EXPECT_EQ(parent_child_set.begin()->first,
171 parent_child_set.begin()->second);
172
173 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
174 std::string json;
175 base::JSONWriter::Write(value.get(), &json);
176 std::string birth_only_result = "{"
177 "\"descendants\":["
178 "{"
179 "\"child_location\":{"
180 "\"file_name\":\"FixedUnitTestFileName\","
181 "\"function_name\":\"ParentChildTest\","
182 "\"line_number\":1776"
183 "},"
184 "\"child_thread\":\"WorkerThread-1\","
185 "\"parent_location\":{"
186 "\"file_name\":\"FixedUnitTestFileName\","
187 "\"function_name\":\"ParentChildTest\","
188 "\"line_number\":1776"
189 "},"
190 "\"parent_thread\":\"WorkerThread-1\""
191 "}"
192 "],"
193 "\"list\":["
194 "{"
195 "\"birth_thread\":\"WorkerThread-1\","
196 "\"death_data\":{"
197 "\"count\":2,"
198 "\"queue_ms\":0,"
199 "\"queue_ms_max\":0,"
200 "\"queue_ms_sample\":0,"
201 "\"run_ms\":0,"
202 "\"run_ms_max\":0,"
203 "\"run_ms_sample\":0"
204 "},"
205 "\"death_thread\":\"Still_Alive\","
206 "\"location\":{"
207 "\"file_name\":\"FixedUnitTestFileName\","
208 "\"function_name\":\"ParentChildTest\","
209 "\"line_number\":1776"
210 "}"
211 "}"
212 "]"
213 "}";
214 EXPECT_EQ(json, birth_only_result);
215 } 223 }
216 224
217 TEST_F(TrackedObjectsTest, DeathDataTest) { 225 TEST_F(TrackedObjectsTest, DeathDataTest) {
218 if (!ThreadData::InitializeAndSetTrackingStatus( 226 if (!ThreadData::InitializeAndSetTrackingStatus(
219 ThreadData::PROFILING_CHILDREN_ACTIVE)) 227 ThreadData::PROFILING_CHILDREN_ACTIVE))
220 return; 228 return;
221 229
222 scoped_ptr<DeathData> data(new DeathData()); 230 scoped_ptr<DeathData> data(new DeathData());
223 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); 231 ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
224 EXPECT_EQ(data->run_duration_sum(), 0); 232 EXPECT_EQ(data->run_duration_sum(), 0);
225 EXPECT_EQ(data->run_duration_sample(), 0); 233 EXPECT_EQ(data->run_duration_sample(), 0);
226 EXPECT_EQ(data->queue_duration_sum(), 0); 234 EXPECT_EQ(data->queue_duration_sum(), 0);
227 EXPECT_EQ(data->queue_duration_sample(), 0); 235 EXPECT_EQ(data->queue_duration_sample(), 0);
228 EXPECT_EQ(data->count(), 0); 236 EXPECT_EQ(data->count(), 0);
229 237
230 int32 run_ms = 42; 238 int32 run_ms = 42;
231 int32 queue_ms = 8; 239 int32 queue_ms = 8;
232 240
233 const int kUnrandomInt = 0; // Fake random int that ensure we sample data. 241 const int kUnrandomInt = 0; // Fake random int that ensure we sample data.
234 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); 242 data->RecordDeath(queue_ms, run_ms, kUnrandomInt);
235 EXPECT_EQ(data->run_duration_sum(), run_ms); 243 EXPECT_EQ(data->run_duration_sum(), run_ms);
236 EXPECT_EQ(data->run_duration_sample(), run_ms); 244 EXPECT_EQ(data->run_duration_sample(), run_ms);
237 EXPECT_EQ(data->queue_duration_sum(), queue_ms); 245 EXPECT_EQ(data->queue_duration_sum(), queue_ms);
238 EXPECT_EQ(data->queue_duration_sample(), queue_ms); 246 EXPECT_EQ(data->queue_duration_sample(), queue_ms);
239 EXPECT_EQ(data->count(), 1); 247 EXPECT_EQ(data->count(), 1);
240 248
241 data->RecordDeath(queue_ms, run_ms, kUnrandomInt); 249 data->RecordDeath(queue_ms, run_ms, kUnrandomInt);
242 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); 250 EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms);
243 EXPECT_EQ(data->run_duration_sample(), run_ms); 251 EXPECT_EQ(data->run_duration_sample(), run_ms);
244 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); 252 EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms);
245 EXPECT_EQ(data->queue_duration_sample(), queue_ms); 253 EXPECT_EQ(data->queue_duration_sample(), queue_ms);
246 EXPECT_EQ(data->count(), 2); 254 EXPECT_EQ(data->count(), 2);
247 255
248 scoped_ptr<base::DictionaryValue> dictionary(data->ToValue()); 256 DeathDataSnapshot snapshot(*data);
249 int integer; 257 EXPECT_EQ(2, snapshot.count);
250 EXPECT_TRUE(dictionary->GetInteger("run_ms", &integer)); 258 EXPECT_EQ(2 * run_ms, snapshot.run_duration_sum);
251 EXPECT_EQ(integer, 2 * run_ms); 259 EXPECT_EQ(run_ms, snapshot.run_duration_max);
252 EXPECT_TRUE(dictionary->GetInteger("run_ms_sample", &integer)); 260 EXPECT_EQ(run_ms, snapshot.run_duration_sample);
253 EXPECT_EQ(integer, run_ms); 261 EXPECT_EQ(2 * queue_ms, snapshot.queue_duration_sum);
254 EXPECT_TRUE(dictionary->GetInteger("queue_ms", &integer)); 262 EXPECT_EQ(queue_ms, snapshot.queue_duration_max);
255 EXPECT_EQ(integer, 2 * queue_ms); 263 EXPECT_EQ(queue_ms, snapshot.queue_duration_sample);
256 EXPECT_TRUE(dictionary->GetInteger("queue_ms_sample", &integer));
257 EXPECT_EQ(integer, queue_ms);
258 EXPECT_TRUE(dictionary->GetInteger("count", &integer));
259 EXPECT_EQ(integer, 2);
260
261 scoped_ptr<base::Value> value(data->ToValue());
262 std::string json;
263 base::JSONWriter::Write(value.get(), &json);
264 std::string birth_only_result = "{"
265 "\"count\":2,"
266 "\"queue_ms\":16,"
267 "\"queue_ms_max\":8,"
268 "\"queue_ms_sample\":8,"
269 "\"run_ms\":84,"
270 "\"run_ms_max\":42,"
271 "\"run_ms_sample\":42"
272 "}";
273 EXPECT_EQ(birth_only_result, json);
274 } 264 }
275 265
276 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueWorkerThread) { 266 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotWorkerThread) {
277 // Transition to Deactivated state before doing anything.
278 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED))
279 return;
280 // We don't initialize system with a thread name, so we're viewed as a worker
281 // thread.
282 const int kFakeLineNumber = 173;
283 const char* kFile = "FixedFileName";
284 const char* kFunction = "BirthOnlyToValueWorkerThread";
285 Location location(kFunction, kFile, kFakeLineNumber, NULL);
286 Births* birth = ThreadData::TallyABirthIfActive(location);
287 // We should now see a NULL birth record.
288 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL));
289
290 scoped_ptr<base::Value> value(ThreadData::ToValue(false));
291 std::string json;
292 base::JSONWriter::Write(value.get(), &json);
293 std::string birth_only_result = "{"
294 "\"descendants\":["
295 "],"
296 "\"list\":["
297 "]"
298 "}";
299 EXPECT_EQ(json, birth_only_result);
300 }
301
302 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueMainThread) {
303 // Start in the deactivated state. 267 // Start in the deactivated state.
304 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) 268 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED))
305 return; 269 return;
306 270
307 // Use a well named thread. 271 Location location(kFunction, kFile, kLineNumber, NULL);
308 ThreadData::InitializeThreadContext("SomeMainThreadName"); 272 TallyABirth(location, std::string());
309 const int kFakeLineNumber = 173;
310 const char* kFile = "FixedFileName";
311 const char* kFunction = "BirthOnlyToValueMainThread";
312 Location location(kFunction, kFile, kFakeLineNumber, NULL);
313 // Do not delete birth. We don't own it.
314 Births* birth = ThreadData::TallyABirthIfActive(location);
315 // We expect to not get a birth record.
316 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL));
317 273
318 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 274 ProcessDataSnapshot process_data;
319 std::string json; 275 ThreadData::Snapshot(false, &process_data);
320 base::JSONWriter::Write(value.get(), &json); 276 EXPECT_EQ(0u, process_data.tasks.size());
321 std::string birth_only_result = "{" 277 EXPECT_EQ(0u, process_data.descendants.size());
322 "\"descendants\":[" 278 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
323 "],"
324 "\"list\":["
325 "]"
326 "}";
327 EXPECT_EQ(json, birth_only_result);
328 } 279 }
329 280
330 TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) { 281 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotMainThread) {
331 if (!ThreadData::InitializeAndSetTrackingStatus( 282 // Start in the deactivated state.
332 ThreadData::PROFILING_CHILDREN_ACTIVE)) 283 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED))
333 return; 284 return;
334 // We don't initialize system with a thread name, so we're viewed as a worker
335 // thread.
336 const int kFakeLineNumber = 173;
337 const char* kFile = "FixedFileName";
338 const char* kFunction = "BirthOnlyToValueWorkerThread";
339 Location location(kFunction, kFile, kFakeLineNumber, NULL);
340 Births* birth = ThreadData::TallyABirthIfActive(location);
341 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
342 285
343 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 286 Location location(kFunction, kFile, kLineNumber, NULL);
344 std::string json; 287 TallyABirth(location, kMainThreadName);
345 base::JSONWriter::Write(value.get(), &json); 288
346 std::string birth_only_result = "{" 289 ProcessDataSnapshot process_data;
347 "\"descendants\":[" 290 ThreadData::Snapshot(false, &process_data);
348 "]," 291 EXPECT_EQ(0u, process_data.tasks.size());
349 "\"list\":[" 292 EXPECT_EQ(0u, process_data.descendants.size());
350 "{" 293 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
351 "\"birth_thread\":\"WorkerThread-1\","
352 "\"death_data\":{"
353 "\"count\":1,"
354 "\"queue_ms\":0,"
355 "\"queue_ms_max\":0,"
356 "\"queue_ms_sample\":0,"
357 "\"run_ms\":0,"
358 "\"run_ms_max\":0,"
359 "\"run_ms_sample\":0"
360 "},"
361 "\"death_thread\":\"Still_Alive\","
362 "\"location\":{"
363 "\"file_name\":\"FixedFileName\","
364 "\"function_name\":\"BirthOnlyToValueWorkerThread\","
365 "\"line_number\":173"
366 "}"
367 "}"
368 "]"
369 "}";
370 EXPECT_EQ(json, birth_only_result);
371 } 294 }
372 295
373 TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) { 296 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotWorkerThread) {
374 if (!ThreadData::InitializeAndSetTrackingStatus( 297 if (!ThreadData::InitializeAndSetTrackingStatus(
375 ThreadData::PROFILING_CHILDREN_ACTIVE)) 298 ThreadData::PROFILING_CHILDREN_ACTIVE))
376 return; 299 return;
377 300
378 // Use a well named thread. 301 Location location(kFunction, kFile, kLineNumber, NULL);
379 ThreadData::InitializeThreadContext("SomeMainThreadName"); 302 TallyABirth(location, std::string());
380 const int kFakeLineNumber = 173;
381 const char* kFile = "FixedFileName";
382 const char* kFunction = "BirthOnlyToValueMainThread";
383 Location location(kFunction, kFile, kFakeLineNumber, NULL);
384 // Do not delete birth. We don't own it.
385 Births* birth = ThreadData::TallyABirthIfActive(location);
386 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
387 303
388 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 304 ProcessDataSnapshot process_data;
389 std::string json; 305 ThreadData::Snapshot(false, &process_data);
390 base::JSONWriter::Write(value.get(), &json); 306 ExpectSimpleProcessData(process_data, kWorkerThreadName, kStillAlive,
391 std::string birth_only_result = "{" 307 1, 0, 0);
392 "\"descendants\":["
393 "],"
394 "\"list\":["
395 "{"
396 "\"birth_thread\":\"SomeMainThreadName\","
397 "\"death_data\":{"
398 "\"count\":1,"
399 "\"queue_ms\":0,"
400 "\"queue_ms_max\":0,"
401 "\"queue_ms_sample\":0,"
402 "\"run_ms\":0,"
403 "\"run_ms_max\":0,"
404 "\"run_ms_sample\":0"
405 "},"
406 "\"death_thread\":\"Still_Alive\","
407 "\"location\":{"
408 "\"file_name\":\"FixedFileName\","
409 "\"function_name\":\"BirthOnlyToValueMainThread\","
410 "\"line_number\":173"
411 "}"
412 "}"
413 "]"
414 "}";
415 EXPECT_EQ(json, birth_only_result);
416 } 308 }
417 309
418 TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) { 310 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotMainThread) {
419 if (!ThreadData::InitializeAndSetTrackingStatus( 311 if (!ThreadData::InitializeAndSetTrackingStatus(
420 ThreadData::PROFILING_CHILDREN_ACTIVE)) 312 ThreadData::PROFILING_CHILDREN_ACTIVE))
421 return; 313 return;
422 314
423 // Use a well named thread. 315 Location location(kFunction, kFile, kLineNumber, NULL);
424 ThreadData::InitializeThreadContext("SomeMainThreadName"); 316 TallyABirth(location, kMainThreadName);
425 const int kFakeLineNumber = 236;
426 const char* kFile = "FixedFileName";
427 const char* kFunction = "LifeCycleToValueMainThread";
428 Location location(kFunction, kFile, kFakeLineNumber, NULL);
429 // Do not delete birth. We don't own it.
430 Births* birth = ThreadData::TallyABirthIfActive(location);
431 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
432 317
433 const base::TimeTicks kTimePosted = base::TimeTicks() 318 ProcessDataSnapshot process_data;
434 + base::TimeDelta::FromMilliseconds(1); 319 ThreadData::Snapshot(false, &process_data);
320 ExpectSimpleProcessData(process_data, kMainThreadName, kStillAlive,
321 1, 0, 0);
322 }
323
324 TEST_F(TrackedObjectsTest, LifeCycleToSnapshotMainThread) {
325 if (!ThreadData::InitializeAndSetTrackingStatus(
326 ThreadData::PROFILING_CHILDREN_ACTIVE))
327 return;
328
329 Location location(kFunction, kFile, kLineNumber, NULL);
330 TallyABirth(location, kMainThreadName);
331
332 const base::TimeTicks kTimePosted = base::TimeTicks() +
333 base::TimeDelta::FromMilliseconds(1);
435 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 334 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
436 // TrackingInfo will call TallyABirth() during construction. 335 // TrackingInfo will call TallyABirth() during construction.
437 base::TrackingInfo pending_task(location, kDelayedStartTime); 336 base::TrackingInfo pending_task(location, kDelayedStartTime);
438 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 337 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
439 338
440 const TrackedTime kStartOfRun = TrackedTime() + 339 const TrackedTime kStartOfRun = TrackedTime() +
441 Duration::FromMilliseconds(5); 340 Duration::FromMilliseconds(5);
442 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 341 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
443 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 342 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
444 kStartOfRun, kEndOfRun); 343 kStartOfRun, kEndOfRun);
445 344
446 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 345 ProcessDataSnapshot process_data;
447 std::string json; 346 ThreadData::Snapshot(false, &process_data);
448 base::JSONWriter::Write(value.get(), &json); 347 ExpectSimpleProcessData(process_data, kMainThreadName, kMainThreadName,
449 std::string one_line_result = "{" 348 1, 2, 4);
450 "\"descendants\":["
451 "],"
452 "\"list\":["
453 "{"
454 "\"birth_thread\":\"SomeMainThreadName\","
455 "\"death_data\":{"
456 "\"count\":1,"
457 "\"queue_ms\":4,"
458 "\"queue_ms_max\":4,"
459 "\"queue_ms_sample\":4,"
460 "\"run_ms\":2,"
461 "\"run_ms_max\":2,"
462 "\"run_ms_sample\":2"
463 "},"
464 "\"death_thread\":\"SomeMainThreadName\","
465 "\"location\":{"
466 "\"file_name\":\"FixedFileName\","
467 "\"function_name\":\"LifeCycleToValueMainThread\","
468 "\"line_number\":236"
469 "}"
470 "}"
471 "]"
472 "}";
473 EXPECT_EQ(one_line_result, json);
474 } 349 }
475 350
476 // We will deactivate tracking after the birth, and before the death, and 351 // We will deactivate tracking after the birth, and before the death, and
477 // demonstrate that the lifecycle is completely tallied. This ensures that 352 // demonstrate that the lifecycle is completely tallied. This ensures that
478 // our tallied births are matched by tallied deaths (except for when the 353 // our tallied births are matched by tallied deaths (except for when the
479 // task is still running, or is queued). 354 // task is still running, or is queued).
480 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToValueMainThread) { 355 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToSnapshotMainThread) {
481 if (!ThreadData::InitializeAndSetTrackingStatus( 356 if (!ThreadData::InitializeAndSetTrackingStatus(
482 ThreadData::PROFILING_CHILDREN_ACTIVE)) 357 ThreadData::PROFILING_CHILDREN_ACTIVE))
483 return; 358 return;
484 359
485 // Use a well named thread. 360 Location location(kFunction, kFile, kLineNumber, NULL);
486 ThreadData::InitializeThreadContext("SomeMainThreadName"); 361 TallyABirth(location, kMainThreadName);
487 const int kFakeLineNumber = 236;
488 const char* kFile = "FixedFileName";
489 const char* kFunction = "LifeCycleToValueMainThread";
490 Location location(kFunction, kFile, kFakeLineNumber, NULL);
491 // Do not delete birth. We don't own it.
492 Births* birth = ThreadData::TallyABirthIfActive(location);
493 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
494 362
495 const base::TimeTicks kTimePosted = base::TimeTicks() 363 const base::TimeTicks kTimePosted = base::TimeTicks() +
496 + base::TimeDelta::FromMilliseconds(1); 364 base::TimeDelta::FromMilliseconds(1);
497 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 365 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
498 // TrackingInfo will call TallyABirth() during construction. 366 // TrackingInfo will call TallyABirth() during construction.
499 base::TrackingInfo pending_task(location, kDelayedStartTime); 367 base::TrackingInfo pending_task(location, kDelayedStartTime);
500 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 368 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
501 369
502 // Turn off tracking now that we have births. 370 // Turn off tracking now that we have births.
503 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus( 371 EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(
504 ThreadData::DEACTIVATED)); 372 ThreadData::DEACTIVATED));
505 373
506 const TrackedTime kStartOfRun = TrackedTime() + 374 const TrackedTime kStartOfRun = TrackedTime() +
507 Duration::FromMilliseconds(5); 375 Duration::FromMilliseconds(5);
508 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 376 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
509 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 377 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
510 kStartOfRun, kEndOfRun); 378 kStartOfRun, kEndOfRun);
511 379
512 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 380 ProcessDataSnapshot process_data;
513 std::string json; 381 ThreadData::Snapshot(false, &process_data);
514 base::JSONWriter::Write(value.get(), &json); 382 ExpectSimpleProcessData(process_data, kMainThreadName, kMainThreadName,
515 std::string one_line_result = "{" 383 1, 2, 4);
516 "\"descendants\":["
517 "],"
518 "\"list\":["
519 "{"
520 "\"birth_thread\":\"SomeMainThreadName\","
521 "\"death_data\":{"
522 "\"count\":1,"
523 "\"queue_ms\":4,"
524 "\"queue_ms_max\":4,"
525 "\"queue_ms_sample\":4,"
526 "\"run_ms\":2,"
527 "\"run_ms_max\":2,"
528 "\"run_ms_sample\":2"
529 "},"
530 "\"death_thread\":\"SomeMainThreadName\","
531 "\"location\":{"
532 "\"file_name\":\"FixedFileName\","
533 "\"function_name\":\"LifeCycleToValueMainThread\","
534 "\"line_number\":236"
535 "}"
536 "}"
537 "]"
538 "}";
539 EXPECT_EQ(one_line_result, json);
540 } 384 }
541 385
542 // We will deactivate tracking before starting a life cycle, and neither 386 // We will deactivate tracking before starting a life cycle, and neither
543 // the birth nor the death will be recorded. 387 // the birth nor the death will be recorded.
544 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToValueMainThread) { 388 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToSnapshotMainThread) {
389 // Start in the deactivated state.
545 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) 390 if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED))
546 return; 391 return;
547 392
548 // Use a well named thread. 393 Location location(kFunction, kFile, kLineNumber, NULL);
549 ThreadData::InitializeThreadContext("SomeMainThreadName"); 394 TallyABirth(location, kMainThreadName);
550 const int kFakeLineNumber = 236;
551 const char* kFile = "FixedFileName";
552 const char* kFunction = "LifeCycleToValueMainThread";
553 Location location(kFunction, kFile, kFakeLineNumber, NULL);
554 // Do not delete birth. We don't own it.
555 Births* birth = ThreadData::TallyABirthIfActive(location);
556 EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL));
557 395
558 const base::TimeTicks kTimePosted = base::TimeTicks() 396 const base::TimeTicks kTimePosted = base::TimeTicks() +
559 + base::TimeDelta::FromMilliseconds(1); 397 base::TimeDelta::FromMilliseconds(1);
560 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 398 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
561 // TrackingInfo will call TallyABirth() during construction. 399 // TrackingInfo will call TallyABirth() during construction.
562 base::TrackingInfo pending_task(location, kDelayedStartTime); 400 base::TrackingInfo pending_task(location, kDelayedStartTime);
563 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 401 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
564 402
565 const TrackedTime kStartOfRun = TrackedTime() + 403 const TrackedTime kStartOfRun = TrackedTime() +
566 Duration::FromMilliseconds(5); 404 Duration::FromMilliseconds(5);
567 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 405 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
568 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 406 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
569 kStartOfRun, kEndOfRun); 407 kStartOfRun, kEndOfRun);
570 408
571 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 409 ProcessDataSnapshot process_data;
572 std::string json; 410 ThreadData::Snapshot(false, &process_data);
573 base::JSONWriter::Write(value.get(), &json); 411 EXPECT_EQ(0u, process_data.tasks.size());
574 std::string one_line_result = "{" 412 EXPECT_EQ(0u, process_data.descendants.size());
575 "\"descendants\":[" 413 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
576 "],"
577 "\"list\":["
578 "]"
579 "}";
580 EXPECT_EQ(one_line_result, json);
581 } 414 }
582 415
583 TEST_F(TrackedObjectsTest, LifeCycleToValueWorkerThread) { 416 TEST_F(TrackedObjectsTest, LifeCycleToSnapshotWorkerThread) {
584 if (!ThreadData::InitializeAndSetTrackingStatus( 417 if (!ThreadData::InitializeAndSetTrackingStatus(
585 ThreadData::PROFILING_CHILDREN_ACTIVE)) 418 ThreadData::PROFILING_CHILDREN_ACTIVE))
586 return; 419 return;
587 420
588 // Don't initialize thread, so that we appear as a worker thread. 421 Location location(kFunction, kFile, kLineNumber, NULL);
589 // ThreadData::InitializeThreadContext("SomeMainThreadName"); 422 // Do not delete |birth|. We don't own it.
590
591 const int kFakeLineNumber = 236;
592 const char* kFile = "FixedFileName";
593 const char* kFunction = "LifeCycleToValueWorkerThread";
594 Location location(kFunction, kFile, kFakeLineNumber, NULL);
595 // Do not delete birth. We don't own it.
596 Births* birth = ThreadData::TallyABirthIfActive(location); 423 Births* birth = ThreadData::TallyABirthIfActive(location);
597 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); 424 EXPECT_NE(reinterpret_cast<Births*>(NULL), birth);
598 425
599 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1); 426 const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1);
600 const TrackedTime kStartOfRun = TrackedTime() + 427 const TrackedTime kStartOfRun = TrackedTime() +
601 Duration::FromMilliseconds(5); 428 Duration::FromMilliseconds(5);
602 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 429 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
603 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted, 430 ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted,
604 kStartOfRun, kEndOfRun); 431 kStartOfRun, kEndOfRun);
605 432
606 // Call for the ToValue, but tell it to not the maxes after scanning. 433 // Call for the ToSnapshot, but tell it to not reset the maxes after scanning.
607 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 434 ProcessDataSnapshot process_data;
608 std::string json; 435 ThreadData::Snapshot(false, &process_data);
609 base::JSONWriter::Write(value.get(), &json); 436 ExpectSimpleProcessData(process_data, kWorkerThreadName, kWorkerThreadName,
610 std::string one_line_result = "{" 437 1, 2, 4);
611 "\"descendants\":["
612 "],"
613 "\"list\":["
614 "{"
615 "\"birth_thread\":\"WorkerThread-1\","
616 "\"death_data\":{"
617 "\"count\":1,"
618 "\"queue_ms\":4,"
619 "\"queue_ms_max\":4,"
620 "\"queue_ms_sample\":4,"
621 "\"run_ms\":2,"
622 "\"run_ms_max\":2,"
623 "\"run_ms_sample\":2"
624 "},"
625 "\"death_thread\":\"WorkerThread-1\","
626 "\"location\":{"
627 "\"file_name\":\"FixedFileName\","
628 "\"function_name\":\"LifeCycleToValueWorkerThread\","
629 "\"line_number\":236"
630 "}"
631 "}"
632 "]"
633 "}";
634 EXPECT_EQ(one_line_result, json);
635 438
636 // Call for the ToValue, but tell it to reset the maxes after scanning. 439 // Call for the ToSnapshot, but tell it to reset the maxes after scanning.
637 // We'll still get the same values, but the data will be reset (which we'll 440 // We'll still get the same values, but the data will be reset (which we'll
638 // see in a moment). 441 // see in a moment).
639 value.reset(ThreadData::ToValue(true)); 442 ProcessDataSnapshot process_data_pre_reset;
640 base::JSONWriter::Write(value.get(), &json); 443 ThreadData::Snapshot(true, &process_data_pre_reset);
641 // Result should be unchanged. 444 ExpectSimpleProcessData(process_data, kWorkerThreadName, kWorkerThreadName,
642 EXPECT_EQ(one_line_result, json); 445 1, 2, 4);
643 446
644 // Call for the ToValue, and now we'll see the result of the last translation, 447 // Call for the ToSnapshot, and now we'll see the result of the last
645 // as the max will have been pushed back to zero. 448 // translation, as the max will have been pushed back to zero.
646 value.reset(ThreadData::ToValue(false)); 449 ProcessDataSnapshot process_data_post_reset;
647 base::JSONWriter::Write(value.get(), &json); 450 ThreadData::Snapshot(true, &process_data_post_reset);
648 std::string one_line_result_with_zeros = "{" 451 ASSERT_EQ(1u, process_data_post_reset.tasks.size());
649 "\"descendants\":[" 452 EXPECT_EQ(kFile, process_data_post_reset.tasks[0].birth.location.file_name);
650 "]," 453 EXPECT_EQ(kFunction,
651 "\"list\":[" 454 process_data_post_reset.tasks[0].birth.location.function_name);
652 "{" 455 EXPECT_EQ(kLineNumber,
653 "\"birth_thread\":\"WorkerThread-1\"," 456 process_data_post_reset.tasks[0].birth.location.line_number);
654 "\"death_data\":{" 457 EXPECT_EQ(kWorkerThreadName,
655 "\"count\":1," 458 process_data_post_reset.tasks[0].birth.thread_name);
656 "\"queue_ms\":4," 459 EXPECT_EQ(1, process_data_post_reset.tasks[0].death_data.count);
657 "\"queue_ms_max\":0," // Note zero here. 460 EXPECT_EQ(2, process_data_post_reset.tasks[0].death_data.run_duration_sum);
658 "\"queue_ms_sample\":4," 461 EXPECT_EQ(0, process_data_post_reset.tasks[0].death_data.run_duration_max);
659 "\"run_ms\":2," 462 EXPECT_EQ(2, process_data_post_reset.tasks[0].death_data.run_duration_sample);
660 "\"run_ms_max\":0," // Note zero here. 463 EXPECT_EQ(4, process_data_post_reset.tasks[0].death_data.queue_duration_sum);
661 "\"run_ms_sample\":2" 464 EXPECT_EQ(0, process_data_post_reset.tasks[0].death_data.queue_duration_max);
662 "}," 465 EXPECT_EQ(4,
663 "\"death_thread\":\"WorkerThread-1\"," 466 process_data_post_reset.tasks[0].death_data.queue_duration_sample);
664 "\"location\":{" 467 EXPECT_EQ(kWorkerThreadName,
665 "\"file_name\":\"FixedFileName\"," 468 process_data_post_reset.tasks[0].death_thread_name);
666 "\"function_name\":\"LifeCycleToValueWorkerThread\"," 469 EXPECT_EQ(0u, process_data_post_reset.descendants.size());
667 "\"line_number\":236" 470 EXPECT_EQ(base::GetCurrentProcId(), process_data_post_reset.process_id);
668 "}"
669 "}"
670 "]"
671 "}";
672 EXPECT_EQ(one_line_result_with_zeros, json);
673 } 471 }
674 472
675 TEST_F(TrackedObjectsTest, TwoLives) { 473 TEST_F(TrackedObjectsTest, TwoLives) {
676 if (!ThreadData::InitializeAndSetTrackingStatus( 474 if (!ThreadData::InitializeAndSetTrackingStatus(
677 ThreadData::PROFILING_CHILDREN_ACTIVE)) 475 ThreadData::PROFILING_CHILDREN_ACTIVE))
678 return; 476 return;
679 477
680 // Use a well named thread. 478 Location location(kFunction, kFile, kLineNumber, NULL);
681 ThreadData::InitializeThreadContext("SomeFileThreadName"); 479 TallyABirth(location, kMainThreadName);
682 const int kFakeLineNumber = 222;
683 const char* kFile = "AnotherFileName";
684 const char* kFunction = "TwoLives";
685 Location location(kFunction, kFile, kFakeLineNumber, NULL);
686 // Do not delete birth. We don't own it.
687 Births* birth = ThreadData::TallyABirthIfActive(location);
688 EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
689 480
690 481 const base::TimeTicks kTimePosted = base::TimeTicks() +
691 const base::TimeTicks kTimePosted = base::TimeTicks() 482 base::TimeDelta::FromMilliseconds(1);
692 + base::TimeDelta::FromMilliseconds(1);
693 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 483 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
694 // TrackingInfo will call TallyABirth() during construction. 484 // TrackingInfo will call TallyABirth() during construction.
695 base::TrackingInfo pending_task(location, kDelayedStartTime); 485 base::TrackingInfo pending_task(location, kDelayedStartTime);
696 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 486 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
697 487
698 const TrackedTime kStartOfRun = TrackedTime() + 488 const TrackedTime kStartOfRun = TrackedTime() +
699 Duration::FromMilliseconds(5); 489 Duration::FromMilliseconds(5);
700 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 490 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
701 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 491 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
702 kStartOfRun, kEndOfRun); 492 kStartOfRun, kEndOfRun);
703 493
704 // TrackingInfo will call TallyABirth() during construction. 494 // TrackingInfo will call TallyABirth() during construction.
705 base::TrackingInfo pending_task2(location, kDelayedStartTime); 495 base::TrackingInfo pending_task2(location, kDelayedStartTime);
706 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). 496 pending_task2.time_posted = kTimePosted; // Overwrite implied Now().
707 497
708 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, 498 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2,
709 kStartOfRun, kEndOfRun); 499 kStartOfRun, kEndOfRun);
710 500
711 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 501 ProcessDataSnapshot process_data;
712 std::string json; 502 ThreadData::Snapshot(false, &process_data);
713 base::JSONWriter::Write(value.get(), &json); 503 ExpectSimpleProcessData(process_data, kMainThreadName, kMainThreadName,
714 std::string one_line_result = "{" 504 2, 2, 4);
715 "\"descendants\":["
716 "],"
717 "\"list\":["
718 "{"
719 "\"birth_thread\":\"SomeFileThreadName\","
720 "\"death_data\":{"
721 "\"count\":2,"
722 "\"queue_ms\":8,"
723 "\"queue_ms_max\":4,"
724 "\"queue_ms_sample\":4,"
725 "\"run_ms\":4,"
726 "\"run_ms_max\":2,"
727 "\"run_ms_sample\":2"
728 "},"
729 "\"death_thread\":\"SomeFileThreadName\","
730 "\"location\":{"
731 "\"file_name\":\"AnotherFileName\","
732 "\"function_name\":\"TwoLives\","
733 "\"line_number\":222"
734 "}"
735 "}"
736 "]"
737 "}";
738 EXPECT_EQ(one_line_result, json);
739 } 505 }
740 506
741 TEST_F(TrackedObjectsTest, DifferentLives) { 507 TEST_F(TrackedObjectsTest, DifferentLives) {
742 if (!ThreadData::InitializeAndSetTrackingStatus( 508 if (!ThreadData::InitializeAndSetTrackingStatus(
743 ThreadData::PROFILING_CHILDREN_ACTIVE)) 509 ThreadData::PROFILING_CHILDREN_ACTIVE))
744 return; 510 return;
745 511
746 // Use a well named thread. 512 // Use a well named thread.
747 ThreadData::InitializeThreadContext("SomeFileThreadName"); 513 ThreadData::InitializeThreadContext(kMainThreadName);
748 const int kFakeLineNumber = 567; 514 Location location(kFunction, kFile, kLineNumber, NULL);
749 const char* kFile = "AnotherFileName";
750 const char* kFunction = "DifferentLives";
751 Location location(kFunction, kFile, kFakeLineNumber, NULL);
752 515
753 const base::TimeTicks kTimePosted = base::TimeTicks() 516 const base::TimeTicks kTimePosted = base::TimeTicks() +
754 + base::TimeDelta::FromMilliseconds(1); 517 base::TimeDelta::FromMilliseconds(1);
755 const base::TimeTicks kDelayedStartTime = base::TimeTicks(); 518 const base::TimeTicks kDelayedStartTime = base::TimeTicks();
756 // TrackingInfo will call TallyABirth() during construction. 519 // TrackingInfo will call TallyABirth() during construction.
757 base::TrackingInfo pending_task(location, kDelayedStartTime); 520 base::TrackingInfo pending_task(location, kDelayedStartTime);
758 pending_task.time_posted = kTimePosted; // Overwrite implied Now(). 521 pending_task.time_posted = kTimePosted; // Overwrite implied Now().
759 522
760 const TrackedTime kStartOfRun = TrackedTime() + 523 const TrackedTime kStartOfRun = TrackedTime() +
761 Duration::FromMilliseconds(5); 524 Duration::FromMilliseconds(5);
762 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); 525 const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7);
763 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 526 ThreadData::TallyRunOnNamedThreadIfTracking(pending_task,
764 kStartOfRun, kEndOfRun); 527 kStartOfRun, kEndOfRun);
765 528
766 const int kSecondFakeLineNumber = 999; 529 const int kSecondFakeLineNumber = 999;
767 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); 530 Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL);
768 531
769 // TrackingInfo will call TallyABirth() during construction. 532 // TrackingInfo will call TallyABirth() during construction.
770 base::TrackingInfo pending_task2(second_location, kDelayedStartTime); 533 base::TrackingInfo pending_task2(second_location, kDelayedStartTime);
771 pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). 534 pending_task2.time_posted = kTimePosted; // Overwrite implied Now().
772 535
773 scoped_ptr<base::Value> value(ThreadData::ToValue(false)); 536 ProcessDataSnapshot process_data;
774 std::string json; 537 ThreadData::Snapshot(false, &process_data);
775 base::JSONWriter::Write(value.get(), &json); 538 ASSERT_EQ(2u, process_data.tasks.size());
776 std::string one_line_result = "{" 539 EXPECT_EQ(kFile, process_data.tasks[0].birth.location.file_name);
777 "\"descendants\":[" 540 EXPECT_EQ(kFunction, process_data.tasks[0].birth.location.function_name);
778 "]," 541 EXPECT_EQ(kLineNumber, process_data.tasks[0].birth.location.line_number);
779 "\"list\":[" 542 EXPECT_EQ(kMainThreadName, process_data.tasks[0].birth.thread_name);
780 "{" 543 EXPECT_EQ(1, process_data.tasks[0].death_data.count);
781 "\"birth_thread\":\"SomeFileThreadName\"," 544 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_sum);
782 "\"death_data\":{" 545 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_max);
783 "\"count\":1," 546 EXPECT_EQ(2, process_data.tasks[0].death_data.run_duration_sample);
784 "\"queue_ms\":4," 547 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_sum);
785 "\"queue_ms_max\":4," 548 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_max);
786 "\"queue_ms_sample\":4," 549 EXPECT_EQ(4, process_data.tasks[0].death_data.queue_duration_sample);
787 "\"run_ms\":2," 550 EXPECT_EQ(kMainThreadName, process_data.tasks[0].death_thread_name);
788 "\"run_ms_max\":2," 551 EXPECT_EQ(kFile, process_data.tasks[1].birth.location.file_name);
789 "\"run_ms_sample\":2" 552 EXPECT_EQ(kFunction, process_data.tasks[1].birth.location.function_name);
790 "}," 553 EXPECT_EQ(kSecondFakeLineNumber,
791 "\"death_thread\":\"SomeFileThreadName\"," 554 process_data.tasks[1].birth.location.line_number);
792 "\"location\":{" 555 EXPECT_EQ(kMainThreadName, process_data.tasks[1].birth.thread_name);
793 "\"file_name\":\"AnotherFileName\"," 556 EXPECT_EQ(1, process_data.tasks[1].death_data.count);
794 "\"function_name\":\"DifferentLives\"," 557 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_sum);
795 "\"line_number\":567" 558 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_max);
796 "}" 559 EXPECT_EQ(0, process_data.tasks[1].death_data.run_duration_sample);
797 "}," 560 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_sum);
798 "{" 561 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_max);
799 "\"birth_thread\":\"SomeFileThreadName\"," 562 EXPECT_EQ(0, process_data.tasks[1].death_data.queue_duration_sample);
800 "\"death_data\":{" 563 EXPECT_EQ(kStillAlive, process_data.tasks[1].death_thread_name);
801 "\"count\":1," 564 EXPECT_EQ(0u, process_data.descendants.size());
802 "\"queue_ms\":0," 565 EXPECT_EQ(base::GetCurrentProcId(), process_data.process_id);
803 "\"queue_ms_max\":0,"
804 "\"queue_ms_sample\":0,"
805 "\"run_ms\":0,"
806 "\"run_ms_max\":0,"
807 "\"run_ms_sample\":0"
808 "},"
809 "\"death_thread\":\"Still_Alive\","
810 "\"location\":{"
811 "\"file_name\":\"AnotherFileName\","
812 "\"function_name\":\"DifferentLives\","
813 "\"line_number\":999"
814 "}"
815 "}"
816 "]"
817 "}";
818 EXPECT_EQ(one_line_result, json);
819 } 566 }
820 567
821
822 } // namespace tracked_objects 568 } // namespace tracked_objects
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698