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

Side by Side Diff: net/base/trace_net_log_observer_unittest.cc

Issue 468083004: Use NESTABLE_ASYNC APIs to get NetLog data into Tracing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Filtered trace events in unittests Created 6 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/trace_net_log_observer.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/debug/trace_event.h"
11 #include "base/debug/trace_event_impl.h"
12 #include "base/json/json_reader.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/ref_counted_memory.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/values.h"
19 #include "net/base/capturing_net_log.h"
20 #include "net/base/net_log.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using base::debug::TraceLog;
24
25 namespace net {
26
27 namespace {
28
29 struct TraceEntryInfo {
30 std::string category;
31 std::string id;
32 std::string phase;
33 std::string name;
34 std::string source_type;
35 };
36
37 TraceEntryInfo GetTraceEntryInfoFromValue(const base::DictionaryValue& value) {
38 TraceEntryInfo info;
39 value.GetString("cat", &info.category);
40 value.GetString("id", &info.id);
41 value.GetString("ph", &info.phase);
42 value.GetString("name", &info.name);
43 value.GetString("args.source_type", &info.source_type);
44
45 return info;
46 }
47
48 class TraceNetLogObserverTest : public testing::Test {
49 public:
50 TraceNetLogObserverTest() {
51 TraceLog::DeleteForTesting();
52 TraceLog* tracelog = TraceLog::GetInstance();
53 DCHECK(tracelog);
54 DCHECK(!tracelog->IsEnabled());
55 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
56 trace_net_log_observer_.reset(new TraceNetLogObserver());
57 // TODO(xunjieli): Remove this once the Trace bug (397022) is fixed.
58 TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop();
59 }
60
61 virtual ~TraceNetLogObserverTest() {
62 DCHECK(!TraceLog::GetInstance()->IsEnabled());
63 TraceLog::DeleteForTesting();
64 }
65
66 void OnTraceDataCollected(
67 const scoped_refptr<base::RefCountedString>& events_str,
68 bool has_more_events) {
69 DCHECK(trace_events_.empty());
70 trace_buffer_.Start();
71 trace_buffer_.AddFragment(events_str->data());
72 trace_buffer_.Finish();
73
74 scoped_ptr<base::Value> trace_value;
75 trace_value.reset(base::JSONReader::Read(
76 json_output_.json_output,
77 base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN));
78
79 ASSERT_TRUE(trace_value) << json_output_.json_output;
80 base::ListValue* trace_events = NULL;
81 ASSERT_TRUE(trace_value);
82 ASSERT_TRUE(trace_value->GetAsList(&trace_events));
83 base::ListValue* filtered_events = FilterNetLogTraceEvents(trace_events);
mmenke 2014/09/03 19:12:11 BUG: You're leaking |filtered_events| here.
xunjieli 2014/09/08 14:08:41 Done. Thanks!
84 trace_events_.Swap(filtered_events);
mmenke 2014/09/03 19:12:11 Think it makes sense to just switch trace_events_
xunjieli 2014/09/08 14:08:41 Done.
85 }
86
87 static void EnableTraceLog() {
88 TraceLog::GetInstance()->SetEnabled(
89 base::debug::CategoryFilter("netlog"),
90 TraceLog::RECORDING_MODE,
91 base::debug::TraceOptions());
92 }
93
94 static void DisableTraceLog() {
95 TraceLog::GetInstance()->SetDisabled();
96 }
97
98 void EndTraceAndFlush() {
99 TraceLog::GetInstance()->SetDisabled();
100 TraceLog::GetInstance()->Flush(
101 Bind(&TraceNetLogObserverTest::OnTraceDataCollected,
102 base::Unretained(this)));
103 }
104
105 void set_trace_net_log_observer(TraceNetLogObserver* trace_net_log_observer) {
106 trace_net_log_observer_.reset(trace_net_log_observer);
107 }
108
109 base::ListValue* FilterNetLogTraceEvents(base::ListValue* trace_events) {
mmenke 2014/09/03 19:12:11 Should make this: static scoped_ptr<base::ListVal
xunjieli 2014/09/08 14:08:41 Done. Thanks for the detailed explanation! I will
110 base::ListValue* filtered_trace_events = new base::ListValue();
mmenke 2014/09/03 19:12:11 Should make this a scoped_ptr as well, and return
xunjieli 2014/09/08 14:08:41 Done.
111 for (size_t i = 0; i < trace_events->GetSize(); i++) {
112 const base::DictionaryValue* dict = NULL;
113 if (!trace_events->GetDictionary(i, &dict))
mmenke 2014/09/03 19:12:11 completely optional: Since this isn't expected, m
xunjieli 2014/09/08 14:08:41 Done.
114 continue;
115 std::string category;
116 if (dict->GetString("cat", &category)) {
mmenke 2014/09/03 19:12:11 nit: Early abort is preferred, in general, as it
xunjieli 2014/09/08 14:08:41 Done.
117 if (category == "netlog")
118 filtered_trace_events->Append(dict->DeepCopy());
119 }
120 }
121 return filtered_trace_events;
122 }
123
124 const base::ListValue& trace_events() const {
125 return trace_events_;
126 }
127
128 CapturingNetLog* net_log() {
129 return &net_log_;
130 }
131
132 TraceNetLogObserver* trace_net_log_observer() const {
133 return trace_net_log_observer_.get();
134 }
135
136 private:
137 base::ListValue trace_events_;
138 base::debug::TraceResultBuffer trace_buffer_;
139 base::debug::TraceResultBuffer::SimpleOutput json_output_;
140 CapturingNetLog net_log_;
141 scoped_ptr<TraceNetLogObserver> trace_net_log_observer_;
142 };
143
144 TEST_F(TraceNetLogObserverTest, TracingNotEnabled) {
145 trace_net_log_observer()->WatchForTraceStart(net_log());
146 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
147
148 EndTraceAndFlush();
149 trace_net_log_observer()->StopWatchForTraceStart();
150
151 EXPECT_EQ(0u, trace_events().GetSize());
152 }
153
154 TEST_F(TraceNetLogObserverTest, TraceEventCaptured) {
155 CapturingNetLog::CapturedEntryList entries;
156 net_log()->GetEntries(&entries);
157 EXPECT_TRUE(entries.empty());
158
159 trace_net_log_observer()->WatchForTraceStart(net_log());
160 EnableTraceLog();
161 BoundNetLog bound_net_log = BoundNetLog::Make(net_log(),
162 net::NetLog::SOURCE_NONE);
163 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
164 bound_net_log.BeginEvent(NetLog::TYPE_URL_REQUEST_START_JOB);
165 bound_net_log.EndEvent(NetLog::TYPE_REQUEST_ALIVE);
166
167 net_log()->GetEntries(&entries);
168 ASSERT_EQ(3u, entries.size());
169
170 EndTraceAndFlush();
171 trace_net_log_observer()->StopWatchForTraceStart();
172
173 ASSERT_EQ(3u, trace_events().GetSize());
174 const base::DictionaryValue* item1 = NULL;
175 EXPECT_TRUE(trace_events().GetDictionary(0, &item1));
176 const base::DictionaryValue* item2 = NULL;
177 EXPECT_TRUE(trace_events().GetDictionary(1, &item2));
178 const base::DictionaryValue* item3 = NULL;
179 EXPECT_TRUE(trace_events().GetDictionary(2, &item3));
mmenke 2014/09/03 19:12:11 These should all be asserts.
xunjieli 2014/09/08 14:08:41 Done.
180
181 TraceEntryInfo expected_item1 = TraceEntryInfo{
182 "netlog",
183 base::StringPrintf("0x%d", entries[0].source.id),
184 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_INSTANT),
185 NetLog::EventTypeToString(entries[0].type),
186 NetLog::SourceTypeToString(entries[0].source.type)};
187 TraceEntryInfo expected_item2 = TraceEntryInfo{
188 "netlog",
189 base::StringPrintf("0x%d", entries[1].source.id),
190 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_BEGIN),
191 NetLog::EventTypeToString(entries[1].type),
192 NetLog::SourceTypeToString(entries[1].source.type)};
193 TraceEntryInfo expected_item3 = TraceEntryInfo{
194 "netlog",
195 base::StringPrintf("0x%d", entries[2].source.id),
196 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_END),
197 NetLog::EventTypeToString(entries[2].type),
198 NetLog::SourceTypeToString(entries[2].source.type)};
mmenke 2014/09/03 19:12:11 Don't think these get you a whole lot - suggest ju
xunjieli 2014/09/08 14:08:41 Partially done. I inlined event types, since those
199
200 TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
201 TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
202 TraceEntryInfo actual_item3 = GetTraceEntryInfoFromValue(*item3);
203 EXPECT_EQ(expected_item1.category, actual_item1.category);
204 EXPECT_EQ(expected_item1.id, actual_item1.id);
205 EXPECT_EQ(expected_item1.phase, actual_item1.phase);
206 EXPECT_EQ(expected_item1.source_type, actual_item1.source_type);
mmenke 2014/09/03 19:12:11 Should check the names here, too. This goes for o
xunjieli 2014/09/08 14:08:41 Done. Sorry!
207
208 EXPECT_EQ(expected_item2.category, actual_item2.category);
209 EXPECT_EQ(expected_item2.id, actual_item2.id);
210 EXPECT_EQ(expected_item2.phase, actual_item2.phase);
211 EXPECT_EQ(expected_item2.source_type, actual_item2.source_type);
212
213 EXPECT_EQ(expected_item3.category, actual_item3.category);
214 EXPECT_EQ(expected_item3.id, actual_item3.id);
215 EXPECT_EQ(expected_item3.phase, actual_item3.phase);
216 EXPECT_EQ(expected_item3.source_type, actual_item3.source_type);
217 }
218
219 TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) {
220 trace_net_log_observer()->WatchForTraceStart(net_log());
221 EnableTraceLog();
222 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
223 DisableTraceLog();
224 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
225 EnableTraceLog();
226 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
227
228 EndTraceAndFlush();
229 trace_net_log_observer()->StopWatchForTraceStart();
230
231 CapturingNetLog::CapturedEntryList entries;
232 net_log()->GetEntries(&entries);
233 ASSERT_EQ(3u, entries.size());
234 ASSERT_EQ(2u, trace_events().GetSize());
235 const base::DictionaryValue* item1 = NULL;
236 EXPECT_TRUE(trace_events().GetDictionary(0, &item1));
237 const base::DictionaryValue* item2 = NULL;
238 EXPECT_TRUE(trace_events().GetDictionary(1, &item2));
239
240 TraceEntryInfo expected_item1 = TraceEntryInfo{
241 "netlog",
242 base::StringPrintf("0x%d", entries[0].source.id),
243 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_INSTANT),
244 NetLog::EventTypeToString(entries[0].type),
245 NetLog::SourceTypeToString(entries[0].source.type)};
246 TraceEntryInfo expected_item2 = TraceEntryInfo{
247 "netlog",
248 base::StringPrintf("0x%d", entries[2].source.id),
249 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_INSTANT),
250 NetLog::EventTypeToString(entries[2].type),
251 NetLog::SourceTypeToString(entries[2].source.type)};
252
253 TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
254 TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
255 EXPECT_EQ(expected_item1.category, actual_item1.category);
256 EXPECT_EQ(expected_item1.id, actual_item1.id);
257 EXPECT_EQ(expected_item1.phase, actual_item1.phase);
258 EXPECT_EQ(expected_item1.source_type, actual_item1.source_type);
259
260 EXPECT_EQ(expected_item2.category, actual_item2.category);
261 EXPECT_EQ(expected_item2.id, actual_item2.id);
262 EXPECT_EQ(expected_item2.phase, actual_item2.phase);
263 EXPECT_EQ(expected_item2.source_type, actual_item2.source_type);
264 }
265
266 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) {
267 trace_net_log_observer()->WatchForTraceStart(net_log());
268 EnableTraceLog();
269 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
270 trace_net_log_observer()->StopWatchForTraceStart();
271 set_trace_net_log_observer(NULL);
272 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
273
274 EndTraceAndFlush();
275
276 CapturingNetLog::CapturedEntryList entries;
277 net_log()->GetEntries(&entries);
278 ASSERT_EQ(2u, entries.size());
279 ASSERT_EQ(1u, trace_events().GetSize());
280
281 const base::DictionaryValue* item1 = NULL;
282 EXPECT_TRUE(trace_events().GetDictionary(0, &item1));
283
284 TraceEntryInfo expected_item1 = TraceEntryInfo{
285 "netlog",
286 base::StringPrintf("0x%d", entries[0].source.id),
287 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_INSTANT),
288 NetLog::EventTypeToString(entries[0].type),
289 NetLog::SourceTypeToString(entries[0].source.type)};
290
291 TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
292 EXPECT_EQ(expected_item1.category, actual_item1.category);
293 EXPECT_EQ(expected_item1.id, actual_item1.id);
294 EXPECT_EQ(expected_item1.phase, actual_item1.phase);
295 EXPECT_EQ(expected_item1.source_type, actual_item1.source_type);
296 }
297
298 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) {
299 trace_net_log_observer()->WatchForTraceStart(net_log());
300 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
301 trace_net_log_observer()->StopWatchForTraceStart();
302 set_trace_net_log_observer(NULL);
303 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
304 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
305
306 EndTraceAndFlush();
307
308 CapturingNetLog::CapturedEntryList entries;
309 net_log()->GetEntries(&entries);
310 ASSERT_EQ(3u, entries.size());
311 ASSERT_EQ(0u, trace_events().GetSize());
312 }
313
314 TEST_F(TraceNetLogObserverTest, CreateObserverAfterTracingStarts) {
315 set_trace_net_log_observer(NULL);
316 EnableTraceLog();
317 set_trace_net_log_observer(new TraceNetLogObserver());
318 trace_net_log_observer()->WatchForTraceStart(net_log());
319 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
320 trace_net_log_observer()->StopWatchForTraceStart();
321 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
322 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
323
324 EndTraceAndFlush();
325
326 CapturingNetLog::CapturedEntryList entries;
327 net_log()->GetEntries(&entries);
328 ASSERT_EQ(3u, entries.size());
329 ASSERT_EQ(0u, trace_events().GetSize());
330 }
331
332 TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) {
333 trace_net_log_observer()->WatchForTraceStart(net_log());
334 EnableTraceLog();
335 NetLog::ParametersCallback net_log_callback;
336 std::string param = "bar";
337 net_log_callback = NetLog::StringCallback("foo",
338 &param);
339
340 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED, net_log_callback);
341 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
342
343 EndTraceAndFlush();
344 trace_net_log_observer()->StopWatchForTraceStart();
345
346 CapturingNetLog::CapturedEntryList entries;
347 net_log()->GetEntries(&entries);
348 ASSERT_EQ(2u, entries.size());
349 ASSERT_EQ(2u, trace_events().GetSize());
350 const base::DictionaryValue* item1 = NULL;
351 EXPECT_TRUE(trace_events().GetDictionary(0, &item1));
352 const base::DictionaryValue* item2 = NULL;
353 EXPECT_TRUE(trace_events().GetDictionary(1, &item2));
354
355 TraceEntryInfo expected_item1 = TraceEntryInfo{
356 "netlog",
357 base::StringPrintf("0x%d", entries[0].source.id),
358 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_INSTANT),
359 NetLog::EventTypeToString(entries[0].type),
360 NetLog::SourceTypeToString(entries[0].source.type)};
361 TraceEntryInfo expected_item2 = TraceEntryInfo{
362 "netlog",
363 base::StringPrintf("0x%d", entries[1].source.id),
364 std::string(1, TRACE_EVENT_PHASE_ASYNC_NESTABLE_INSTANT),
365 NetLog::EventTypeToString(entries[1].type),
366 NetLog::SourceTypeToString(entries[1].source.type)};
367
368 TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
369 TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
370 EXPECT_EQ(expected_item1.category, actual_item1.category);
371 EXPECT_EQ(expected_item1.id, actual_item1.id);
372 EXPECT_EQ(expected_item1.phase, actual_item1.phase);
373 EXPECT_EQ(expected_item1.source_type, actual_item1.source_type);
374
375 EXPECT_EQ(expected_item2.category, actual_item2.category);
376 EXPECT_EQ(expected_item2.id, actual_item2.id);
377 EXPECT_EQ(expected_item2.phase, actual_item2.phase);
378 EXPECT_EQ(expected_item2.source_type, actual_item2.source_type);
379
380 std::string item1_params;
381 std::string item2_params;
382 EXPECT_TRUE(item1->GetString("args.params.foo", &item1_params));
383 EXPECT_EQ("bar", item1_params);
384
385 EXPECT_TRUE(item2->GetString("args.params", &item2_params));
386 EXPECT_TRUE(item2_params.empty());
387 }
388
389 } // namespace
390
391 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698