OLD | NEW |
---|---|
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 |
OLD | NEW |