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

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

Powered by Google App Engine
This is Rietveld 408576698