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

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: Added Unit Tests Created 6 years, 4 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 "base/debug/trace_event.h"
8
mmenke 2014/08/21 15:35:40 nit: Remove blank line.
xunjieli 2014/08/22 17:20:10 Done.
9 #include "base/json/json_reader.h"
10 #include "base/values.h"
11 #include "testing/gtest/include/gtest/gtest.h"
mmenke 2014/08/21 15:35:41 Should include NetLog and TraceLog headers (They'r
xunjieli 2014/08/22 17:20:11 Done.
12
13 namespace net {
14
15 namespace {
16
17 using namespace base;
xunjieli 2014/08/20 22:00:43 I think this "using namespace" directive is not re
mmenke 2014/08/21 15:35:40 It's not too common in net/, but you can use indiv
xunjieli 2014/08/22 17:20:11 Done. Thanks!
18
19 // A net log that logs all events by default.
20 class MyTestNetLog : public net::NetLog {
21 public:
22 MyTestNetLog() {
23 SetBaseLogLevel(LOG_ALL);
mmenke 2014/08/21 15:35:40 This class shouldn't be needed - the NetLog should
xunjieli 2014/08/22 17:20:11 Done. Thanks!
24 }
25 virtual ~MyTestNetLog() {}
26 };
27
28 class TraceNetLogObserverTest : public testing::Test {
29 public:
30 void OnTraceDataCollected(
31 const scoped_refptr<RefCountedString>& events_str,
mmenke 2014/08/21 15:35:40 Should include base/memory/ref_counted.h, and ref_
xunjieli 2014/08/22 17:20:11 Done.
32 bool has_more_events);
mmenke 2014/08/21 15:35:41 nit: Should inline all functions, to be consisten
xunjieli 2014/08/22 17:20:10 Done.
33 void Clear() {
mmenke 2014/08/21 15:35:41 nit: Blank line before clear.
xunjieli 2014/08/22 17:20:10 Done.
34 trace_parsed_.Clear();
35 json_output_.json_output.clear();
36 }
37
38 void EnableTraceLog() {
39 debug::TraceLog::GetInstance()->SetEnabled(
40 debug::CategoryFilter("*"),
41 debug::TraceLog::RECORDING_MODE,
42 debug::TraceOptions());
43 }
44
45 void DisableTraceLog() {
46 debug::TraceLog::GetInstance()->SetDisabled();
47 }
48
49 void EndTraceAndFlush() {
50 debug::TraceLog::GetInstance()->SetDisabled();
51 debug::TraceLog::GetInstance()->Flush(
52 Bind(&TraceNetLogObserverTest::OnTraceDataCollected,
53 Unretained(this)));
54 }
55
56 virtual void SetUp() OVERRIDE {
mmenke 2014/08/21 15:35:40 nit: Suggest putting SetUp and TearDown first.
xunjieli 2014/08/22 17:20:10 Done. Thanks!
57 debug::TraceLog::DeleteForTesting();
58 debug::TraceLog* tracelog = debug::TraceLog::GetInstance();
59 ASSERT_TRUE(tracelog);
60 ASSERT_FALSE(tracelog->IsEnabled());
61 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
62 net_log_.reset(new MyTestNetLog);
63 trace_net_log_observer_.reset(new TraceNetLogObserver());
64 // TODO(xunjieli): not sure whether this is okay.
65 debug::TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop();
66 }
67
68 virtual void TearDown() OVERRIDE {
69 if (debug::TraceLog::GetInstance())
mmenke 2014/08/21 15:35:41 Is this conditional needed? Looks like it always
xunjieli 2014/08/22 17:20:11 Done. Right, I think it is not needed. Thanks!
70 EXPECT_FALSE(debug::TraceLog::GetInstance()->IsEnabled());
71 debug::TraceLog::DeleteForTesting();
72 }
73
74 ListValue trace_parsed_;
mmenke 2014/08/21 15:35:41 These should be private, with accessors as needed.
xunjieli 2014/08/22 17:20:11 Done. Got it. Thanks!
75 debug::TraceResultBuffer trace_buffer_;
76 debug::TraceResultBuffer::SimpleOutput json_output_;
77 scoped_ptr<NetLog> net_log_;
78 scoped_ptr<TraceNetLogObserver> trace_net_log_observer_;
mmenke 2014/08/21 15:35:40 Should include the scoped_ptr header.
xunjieli 2014/08/22 17:20:10 Done.
79 };
80
81
82 void TraceNetLogObserverTest::OnTraceDataCollected(
83 const scoped_refptr<RefCountedString>& events_str,
84 bool has_more_events) {
85 json_output_.json_output.clear();
mmenke 2014/08/21 15:35:40 DCHECK(trace_parsed_.empty());? (DCHECK instead o
xunjieli 2014/08/22 17:20:11 Done. Thanks!
86 trace_buffer_.Start();
87 trace_buffer_.AddFragment(events_str->data());
88 trace_buffer_.Finish();
89
90 scoped_ptr<Value> root;
mmenke 2014/08/21 15:35:41 trace_value, maybe?
xunjieli 2014/08/22 17:20:11 Done.
91 root.reset(JSONReader::Read(json_output_.json_output,
92 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN));
93
94 if (!root.get()) {
95 LOG(ERROR) << json_output_.json_output;
96 }
mmenke 2014/08/21 15:35:41 This can be replaced with: ASSERT_TRUE(root) << j
xunjieli 2014/08/22 17:20:11 Done. Thanks! That's convenient!
97
98 ListValue* root_list = NULL;
99 ASSERT_TRUE(root.get());
100 ASSERT_TRUE(root->GetAsList(&root_list));
101
102 while (root_list->GetSize()) {
mmenke 2014/08/21 15:35:41 Rather than copying, this can be replaced with: t
mmenke 2014/08/21 15:35:42 suggest renaming root_list to trace_events and tra
xunjieli 2014/08/22 17:20:11 Done. Thanks!
103 scoped_ptr<Value> item;
104 root_list->Remove(0, &item);
105 trace_parsed_.Append(item.release());
106 }
107 }
108
109 bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
110 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
111 if (it.key().find(string_to_match) != std::string::npos)
112 return true;
113
114 std::string value_str;
mmenke 2014/08/21 15:35:40 Should include <string>
xunjieli 2014/08/22 17:20:10 Done.
115 it.value().GetAsString(&value_str);
116 if (value_str.find(string_to_match) != std::string::npos)
117 return true;
118 }
119
120 // Recurse to test arguments
121 const DictionaryValue* args_dict = NULL;
122 dict->GetDictionary("args", &args_dict);
123 if (args_dict)
124 return IsStringInDict(string_to_match, args_dict);
mmenke 2014/08/21 15:35:41 This seems much too broad. Surely we know just wh
xunjieli 2014/08/22 17:20:10 Done. You are right! Thanks!
125
126 return false;
127 }
128
129 const DictionaryValue* FindTraceEntry(
130 const ListValue& trace_parsed,
mmenke 2014/08/21 15:35:41 Since this is a member of the class, don't need to
xunjieli 2014/08/22 17:20:11 Done.
131 const char* string_to_match) {
mmenke 2014/08/21 15:35:41 Maybe call this event_type, and just take raw NetL
xunjieli 2014/08/22 17:20:10 Done. That's smart. Thank you!
132 // Scan all items
133 size_t trace_parsed_count = trace_parsed.GetSize();
134 for (size_t i = 0; i < trace_parsed_count; i++) {
135 const Value* value = NULL;
136 trace_parsed.Get(i, &value);
137 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
138 continue;
139 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
mmenke 2014/08/21 15:35:41 Should get rid of the type check, and use value->G
xunjieli 2014/08/22 17:20:10 Done.
140
141 if (IsStringInDict(string_to_match, dict))
mmenke 2014/08/21 15:35:41 Again, it seems like we should know exactly where
xunjieli 2014/08/22 17:20:11 Done.
142 return dict;
143 }
144 return NULL;
145 }
146
147 } // namespace
mmenke 2014/08/21 15:35:42 Can just extend the anonymous namespace to the end
xunjieli 2014/08/22 17:20:10 Done.
148
149 TEST_F(TraceNetLogObserverTest, TracingNotEnabled) {
150 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
151 net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
152
153 EndTraceAndFlush();
154
155 trace_net_log_observer_->StopWatchForTraceStart();
156 const DictionaryValue* item = FindTraceEntry(
157 trace_parsed_,
158 NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
159 EXPECT_FALSE(item);
160 }
161
162
163 TEST_F(TraceNetLogObserverTest, TraceEventCaptured) {
164 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
165 EnableTraceLog();
166 net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
167
168 EndTraceAndFlush();
169
170 const DictionaryValue* item = FindTraceEntry(
171 trace_parsed_,
172 NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
173 EXPECT_TRUE(item);
mmenke 2014/08/21 15:35:40 Also, maybe log a second event, and make sure orde
mmenke 2014/08/21 15:35:40 Also, should check other values as well - make sur
mmenke 2014/08/21 15:35:41 Should we make sure there's only one such event?
xunjieli 2014/08/22 17:20:10 Done.
xunjieli 2014/08/22 17:20:11 Done.
xunjieli 2014/08/22 17:20:11 Done.
174 }
175
176 TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) {
177 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
178 EnableTraceLog();
179 net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
180 DisableTraceLog();
181 net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
182 EnableTraceLog();
183 net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
184
185 EndTraceAndFlush();
186
187 const DictionaryValue* item1 = FindTraceEntry(
188 trace_parsed_,
189 NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
190 const DictionaryValue* item2 = FindTraceEntry(
191 trace_parsed_,
192 NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
193 const DictionaryValue* item3 = FindTraceEntry(
194 trace_parsed_,
195 NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
196 EXPECT_TRUE(item1);
197 EXPECT_FALSE(item2);
198 EXPECT_TRUE(item3);
199 }
200
201 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) {
202 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
203 EnableTraceLog();
204 net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
205 trace_net_log_observer_->StopWatchForTraceStart();
206 trace_net_log_observer_.reset(NULL);
xunjieli 2014/08/20 22:00:43 Matt, if I just reset the observer scope_ptr, the
mmenke 2014/08/21 15:35:41 Yes, this is just what you should be doing.
xunjieli 2014/08/22 17:20:11 Done. Thanks!
207 net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
208 net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
209
210 EndTraceAndFlush();
211
212 const DictionaryValue* item1 = FindTraceEntry(
213 trace_parsed_,
214 NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
215 const DictionaryValue* item2 = FindTraceEntry(
216 trace_parsed_,
217 NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
218 const DictionaryValue* item3 = FindTraceEntry(
219 trace_parsed_,
220 NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
221 EXPECT_TRUE(item1);
222 EXPECT_FALSE(item2);
223 EXPECT_FALSE(item3);
224 }
225
226 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) {
227 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
228 net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
229 trace_net_log_observer_->StopWatchForTraceStart();
230 trace_net_log_observer_.reset(NULL);
231 net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
232 net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
233
234 EndTraceAndFlush();
235
236 const DictionaryValue* item1 = FindTraceEntry(
237 trace_parsed_,
238 NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
239 const DictionaryValue* item2 = FindTraceEntry(
240 trace_parsed_,
241 NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
242 const DictionaryValue* item3 = FindTraceEntry(
243 trace_parsed_,
244 NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
245 EXPECT_FALSE(item1);
246 EXPECT_FALSE(item2);
247 EXPECT_FALSE(item3);
248 }
249 /**
250 TEST_F(TraceNetLogObserverTest, CreateObserverAfterTracingStarts) {
251 trace_net_log_observer_.reset(NULL);
252 EnableTraceLog();
253 trace_net_log_observer_.reset(new TraceNetLogObserver());
xunjieli 2014/08/20 22:00:43 If we start the observer after Tracing is enabled,
mmenke 2014/08/21 15:35:41 This is probably expected behavior. I suggest jus
xunjieli 2014/08/22 17:20:10 I see. Thanks! On 2014/08/21 15:35:41, mmenke wrot
254 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
255 net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
256 trace_net_log_observer_->StopWatchForTraceStart();
257 net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
258 net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
259
260 EndTraceAndFlush();
261
262 const DictionaryValue* item1 = FindTraceEntry(
263 trace_parsed_,
264 NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
265 const DictionaryValue* item2 = FindTraceEntry(
266 trace_parsed_,
267 NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
268 const DictionaryValue* item3 = FindTraceEntry(
269 trace_parsed_,
270 NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
271 EXPECT_TRUE(item1);
272 EXPECT_FALSE(item2);
273 EXPECT_FALSE(item3);
274 } **/
275
276 TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) {
277 trace_net_log_observer_->WatchForTraceStart(net_log_.get());
278 EnableTraceLog();
279 NetLog::ParametersCallback net_log_callback;
280 std::string param = "bar";
281 net_log_callback = NetLog::StringCallback("foo",
282 &param);
283
284 net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED, net_log_callback);
285 net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
286
287 EndTraceAndFlush();
288
289 const DictionaryValue* item1 = FindTraceEntry(
290 trace_parsed_,
291 NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
292 EXPECT_TRUE(item1);
293 const DictionaryValue* item1_args = NULL;
294 item1->GetDictionary("args", &item1_args);
295 EXPECT_TRUE(item1_args);
296 const DictionaryValue* item1_value = NULL;
297 item1_args->GetDictionary("value", &item1_value);
298 EXPECT_TRUE(item1_value);
299 const DictionaryValue* item1_params = NULL;
300 item1_value->GetDictionary("params", &item1_params);
301 EXPECT_TRUE(item1_params);
302 std::string actual_value;
303 item1_params->GetString("foo", &actual_value);
304 EXPECT_EQ("bar", actual_value);
mmenke 2014/08/21 15:35:41 Dictionaries support recursion, I believe, so this
xunjieli 2014/08/22 17:20:11 Done. Thanks for letting me know!
305
306 const DictionaryValue* item2 = FindTraceEntry(
307 trace_parsed_,
308 NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
309 EXPECT_TRUE(item2);
310 const DictionaryValue* item2_args = NULL;
311 item2->GetDictionary("args", &item2_args);
312 EXPECT_TRUE(item2_args);
313 const DictionaryValue* item2_value = NULL;
314 item2_args->GetDictionary("value", &item2_value);
315 EXPECT_TRUE(item2_value);
316 const DictionaryValue* item2_params = NULL;
317 item2_value->GetDictionary("params", &item2_params);
318 EXPECT_FALSE(item2_params);
319 }
mmenke 2014/08/21 15:35:40 nit: Blank line before ending a namespace.
xunjieli 2014/08/22 17:20:12 Done.
320 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698