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

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

Issue 16137008: Refactor net::NetLog to provide implementation of observer pattern, not just the interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 6 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #include "net/base/net_log_unittest.h" 5 #include "net/base/net_log_unittest.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/simple_thread.h"
8 #include "base/values.h" 10 #include "base/values.h"
9 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
10 12
11 namespace net { 13 namespace net {
12 14
13 namespace { 15 namespace {
14 16
17 const int kThreads = 10;
18 const int kEvents = 100;
19
15 base::Value* NetLogLevelCallback(NetLog::LogLevel log_level) { 20 base::Value* NetLogLevelCallback(NetLog::LogLevel log_level) {
16 base::DictionaryValue* dict = new base::DictionaryValue(); 21 base::DictionaryValue* dict = new base::DictionaryValue();
17 dict->SetInteger("log_level", log_level); 22 dict->SetInteger("log_level", log_level);
18 return dict; 23 return dict;
19 } 24 }
20 25
21 TEST(NetLogTest, Basic) { 26 TEST(NetLogTest, Basic) {
22 CapturingNetLog net_log; 27 NetLog net_log;
23 net::CapturingNetLog::CapturedEntryList entries; 28
24 net_log.GetEntries(&entries); 29 CapturingNetLogObserver capturing_net_log_observer;
30 net_log.AddThreadSafeObserver(&capturing_net_log_observer, NetLog::LOG_BASIC);
31
32 net::CapturingNetLogObserver::CapturedEntryList entries;
33 capturing_net_log_observer.GetEntries(&entries);
25 EXPECT_EQ(0u, entries.size()); 34 EXPECT_EQ(0u, entries.size());
26 35
27 net_log.AddGlobalEntry(NetLog::TYPE_CANCELLED); 36 net_log.AddGlobalEntry(NetLog::TYPE_CANCELLED);
28 37
29 net_log.GetEntries(&entries); 38 capturing_net_log_observer.GetEntries(&entries);
30 ASSERT_EQ(1u, entries.size()); 39 ASSERT_EQ(1u, entries.size());
31 EXPECT_EQ(NetLog::TYPE_CANCELLED, entries[0].type); 40 EXPECT_EQ(NetLog::TYPE_CANCELLED, entries[0].type);
32 EXPECT_EQ(NetLog::SOURCE_NONE, entries[0].source.type); 41 EXPECT_EQ(NetLog::SOURCE_NONE, entries[0].source.type);
33 EXPECT_NE(NetLog::Source::kInvalidId, entries[0].source.id); 42 EXPECT_NE(NetLog::Source::kInvalidId, entries[0].source.id);
34 EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase); 43 EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase);
35 EXPECT_GE(base::TimeTicks::Now(), entries[0].time); 44 EXPECT_GE(base::TimeTicks::Now(), entries[0].time);
36 EXPECT_FALSE(entries[0].params); 45 EXPECT_FALSE(entries[0].params);
46
47 net_log.RemoveThreadSafeObserver(&capturing_net_log_observer);
37 } 48 }
38 49
39 // Check that the correct LogLevel is sent to NetLog Value callbacks, and that 50 // Check that the correct LogLevel is sent to NetLog Value callbacks, and that
40 // LOG_NONE logs no events. 51 // LOG_NONE logs no events.
41 TEST(NetLogTest, LogLevels) { 52 TEST(NetLogTest, LogLevels) {
42 CapturingNetLog net_log; 53 NetLog net_log;
54
55 CapturingNetLogObserver capturing_net_log_observer;
56 net_log.AddThreadSafeObserver(&capturing_net_log_observer, NetLog::LOG_BASIC);
57
43 for (int log_level = NetLog::LOG_ALL; log_level <= NetLog::LOG_NONE; 58 for (int log_level = NetLog::LOG_ALL; log_level <= NetLog::LOG_NONE;
44 ++log_level) { 59 ++log_level) {
45 net_log.SetLogLevel(static_cast<NetLog::LogLevel>(log_level)); 60 net_log.SetObserverLogLevel(&capturing_net_log_observer,
46 EXPECT_EQ(log_level, net_log.GetLogLevel()); 61 static_cast<NetLog::LogLevel>(log_level));
62 EXPECT_EQ(log_level, capturing_net_log_observer.log_level());
47 63
48 net_log.AddGlobalEntry(NetLog::TYPE_SOCKET_ALIVE, 64 net_log.AddGlobalEntry(NetLog::TYPE_SOCKET_ALIVE,
49 base::Bind(NetLogLevelCallback)); 65 base::Bind(NetLogLevelCallback));
50 66
51 net::CapturingNetLog::CapturedEntryList entries; 67 net::CapturingNetLogObserver::CapturedEntryList entries;
52 net_log.GetEntries(&entries); 68 capturing_net_log_observer.GetEntries(&entries);
53 69
54 if (log_level == NetLog::LOG_NONE) { 70 if (log_level == NetLog::LOG_NONE) {
55 EXPECT_EQ(0u, entries.size()); 71 EXPECT_EQ(0u, entries.size());
56 } else { 72 } else {
57 ASSERT_EQ(1u, entries.size()); 73 ASSERT_EQ(1u, entries.size());
58 EXPECT_EQ(NetLog::TYPE_SOCKET_ALIVE, entries[0].type); 74 EXPECT_EQ(NetLog::TYPE_SOCKET_ALIVE, entries[0].type);
59 EXPECT_EQ(NetLog::SOURCE_NONE, entries[0].source.type); 75 EXPECT_EQ(NetLog::SOURCE_NONE, entries[0].source.type);
60 EXPECT_NE(NetLog::Source::kInvalidId, entries[0].source.id); 76 EXPECT_NE(NetLog::Source::kInvalidId, entries[0].source.id);
61 EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase); 77 EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase);
62 EXPECT_GE(base::TimeTicks::Now(), entries[0].time); 78 EXPECT_GE(base::TimeTicks::Now(), entries[0].time);
63 79
64 int logged_log_level; 80 int logged_log_level;
65 ASSERT_TRUE(entries[0].GetIntegerValue("log_level", &logged_log_level)); 81 ASSERT_TRUE(entries[0].GetIntegerValue("log_level", &logged_log_level));
66 EXPECT_EQ(log_level, logged_log_level); 82 EXPECT_EQ(log_level, logged_log_level);
67 } 83 }
68 84
69 net_log.Clear(); 85 capturing_net_log_observer.Clear();
70 } 86 }
87
88 net_log.RemoveThreadSafeObserver(&capturing_net_log_observer);
89 }
90
91 void AddEvent(NetLog* net_log) {
92 net_log->AddGlobalEntry(net::NetLog::TYPE_CANCELLED);
93 }
94
95 // A thread that waits until an event has been signalled before calling
96 // RunTestThread.
97 class NetLogTestThread : public base::SimpleThread {
98 public:
99 NetLogTestThread() : base::SimpleThread("NetLogTest"),
100 net_log_(NULL),
101 start_event_(NULL) {
mmenke 2013/06/03 14:27:09 nit: fix indent.
kouhei (in TOK) 2013/06/04 15:41:44 Done.
102 }
103
104 // We'll wait for |start_event| to be triggered before calling a subclass's
105 // subclass's RunTestThread() function.
106 void Init(NetLog* net_log, base::WaitableEvent* start_event) {
107 start_event_ = start_event;
108 net_log_ = net_log;
109 }
110
111 virtual void Run() OVERRIDE {
112 start_event_->Wait();
113 RunTestThread();
114 }
115
116 // Subclasses must override this with the code they want to run on their
117 // thread.
118 virtual void RunTestThread() = 0;
119
120 protected:
121 NetLog* net_log_;
122
123 private:
124 // Only triggered once all threads have been created, to make it less likely
125 // each thread completes before the next one starts.
126 base::WaitableEvent* start_event_;
127
128 DISALLOW_COPY_AND_ASSIGN(NetLogTestThread);
129 };
130
131 // A thread that adds a bunch of events to the NetLog.
132 class AddEventsTestThread : public NetLogTestThread {
133 public:
134 AddEventsTestThread() {}
135 virtual ~AddEventsTestThread() {}
136
137 private:
138 virtual void RunTestThread() OVERRIDE {
139 for (int i = 0; i < kEvents; ++i)
140 AddEvent(net_log_);
141 }
142
143 DISALLOW_COPY_AND_ASSIGN(AddEventsTestThread);
144 };
145
146 // A thread that adds and removes an observer from the NetLog repeatedly.
147 class AddRemoveObserverTestThread : public NetLogTestThread {
148 public:
149 AddRemoveObserverTestThread() {}
150
151 virtual ~AddRemoveObserverTestThread() {
152 EXPECT_TRUE(!observer_.net_log());
153 }
154
155 private:
156 virtual void RunTestThread() OVERRIDE {
157 for (int i = 0; i < kEvents; ++i) {
158 ASSERT_FALSE(observer_.net_log());
159
160 net_log_->AddThreadSafeObserver(&observer_, net::NetLog::LOG_BASIC);
161 ASSERT_EQ(net_log_, observer_.net_log());
162 ASSERT_EQ(net::NetLog::LOG_BASIC, observer_.log_level());
163
164 net_log_->SetObserverLogLevel(&observer_, net::NetLog::LOG_ALL_BUT_BYTES);
165 ASSERT_EQ(net_log_, observer_.net_log());
166 ASSERT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, observer_.log_level());
167 ASSERT_LE(net_log_->GetLogLevel(), net::NetLog::LOG_ALL_BUT_BYTES);
168
169 net_log_->SetObserverLogLevel(&observer_, net::NetLog::LOG_ALL);
170 ASSERT_EQ(net_log_, observer_.net_log());
171 ASSERT_EQ(net::NetLog::LOG_ALL, observer_.log_level());
172 ASSERT_LE(net_log_->GetLogLevel(), net::NetLog::LOG_ALL);
173
174 net_log_->RemoveThreadSafeObserver(&observer_);
175 ASSERT_TRUE(!observer_.net_log());
176 }
177 }
178
179 CapturingNetLogObserver observer_;
180
181 DISALLOW_COPY_AND_ASSIGN(AddRemoveObserverTestThread);
182 };
183
184 // Creates |kThreads| threads of type |ThreadType| and then runs them all
185 // to completion.
186 template<class ThreadType>
187 void RunTestThreads(NetLog* net_log) {
188 ThreadType threads[kThreads];
189 base::WaitableEvent start_event(true, false);
190
191 for (size_t i = 0; i < arraysize(threads); ++i) {
192 threads[i].Init(net_log, &start_event);
193 threads[i].Start();
194 }
195
196 start_event.Signal();
197
198 for (size_t i = 0; i < arraysize(threads); ++i)
199 threads[i].Join();
200 }
201
202 // Makes sure that events on multiple threads are dispatched to all observers.
203 TEST(NetLogTest, NetLogEventThreads) {
204 NetLog net_log;
205
206 // Attach some observers. Since they're created after |net_log|, they'll
207 // safely detach themselves on destruction.
208 CapturingNetLogObserver observers[3];
mmenke 2013/06/03 14:27:09 I'm sorry - turns out that since CapturingNetLogOb
kouhei (in TOK) 2013/06/04 15:41:44 ok
209 for (size_t i = 0; i < arraysize(observers); ++i)
210 net_log.AddThreadSafeObserver(&observers[i], net::NetLog::LOG_BASIC);
211
212 // Run a bunch of threads to completion, each of which will emit events to
213 // |net_log|.
214 RunTestThreads<AddEventsTestThread>(&net_log);
215
216 // Check that each observer saw the emitted events.
217 const size_t kTotalEvents = kThreads * kEvents;
218 for (size_t i = 0; i < arraysize(observers); ++i)
219 EXPECT_EQ(kTotalEvents, observers[i].GetSize());
220
221 // Remove all observers.
222 for (size_t i = 0; i < arraysize(observers); ++i)
223 net_log.RemoveThreadSafeObserver(&observers[i]);
224 }
225
226 // Test adding and removing a single observer.
227 TEST(NetLogTest, NetLogAddRemoveObserver) {
228 NetLog net_log;
229 CapturingNetLogObserver observer;
230
231 AddEvent(&net_log);
232 EXPECT_EQ(0U, observer.GetSize());
233 EXPECT_EQ(NULL, observer.net_log());
234 EXPECT_EQ(net::NetLog::LOG_NONE, net_log.GetLogLevel());
235
236 // Add the observer and add an event.
237 net_log.AddThreadSafeObserver(&observer, net::NetLog::LOG_BASIC);
238 EXPECT_EQ(&net_log, observer.net_log());
239 EXPECT_EQ(net::NetLog::LOG_BASIC, observer.log_level());
240 EXPECT_EQ(net::NetLog::LOG_BASIC, net_log.GetLogLevel());
241
242 AddEvent(&net_log);
243 EXPECT_EQ(1U, observer.GetSize());
244
245 // Change the observer's logging level and add an event.
246 net_log.SetObserverLogLevel(&observer, net::NetLog::LOG_ALL);
247 EXPECT_EQ(&net_log, observer.net_log());
248 EXPECT_EQ(net::NetLog::LOG_ALL, observer.log_level());
249 EXPECT_EQ(net::NetLog::LOG_ALL, net_log.GetLogLevel());
250
251 AddEvent(&net_log);
252 EXPECT_EQ(2U, observer.GetSize());
253
254 // Remove observer and add an event.
255 net_log.RemoveThreadSafeObserver(&observer);
256 EXPECT_EQ(NULL, observer.net_log());
257 EXPECT_EQ(net::NetLog::LOG_NONE, net_log.GetLogLevel());
258
259 AddEvent(&net_log);
260 EXPECT_EQ(2U, observer.GetSize());
261
262 // Add the observer a final time, and add an event.
263 net_log.AddThreadSafeObserver(&observer, net::NetLog::LOG_ALL);
264 EXPECT_EQ(&net_log, observer.net_log());
265 EXPECT_EQ(net::NetLog::LOG_ALL, observer.log_level());
266 EXPECT_EQ(net::NetLog::LOG_ALL, net_log.GetLogLevel());
267
268 AddEvent(&net_log);
269 EXPECT_EQ(3U, observer.GetSize());
270
271 // Remove observer.
272 net_log.RemoveThreadSafeObserver(&observer);
273 }
274
275 // Test adding and removing two observers.
276 TEST(NetLogTest, NetLogTwoObservers) {
277 NetLog net_log;
278 CapturingNetLogObserver observer[2];
279
280 // Add first observer.
281 net_log.AddThreadSafeObserver(&observer[0], net::NetLog::LOG_ALL_BUT_BYTES);
282 EXPECT_EQ(&net_log, observer[0].net_log());
283 EXPECT_EQ(NULL, observer[1].net_log());
284 EXPECT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
285 EXPECT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
286
287 // Add second observer observer.
288 net_log.AddThreadSafeObserver(&observer[1], net::NetLog::LOG_ALL);
289 EXPECT_EQ(&net_log, observer[0].net_log());
290 EXPECT_EQ(&net_log, observer[1].net_log());
291 EXPECT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
292 EXPECT_EQ(net::NetLog::LOG_ALL, observer[1].log_level());
293 EXPECT_EQ(net::NetLog::LOG_ALL, net_log.GetLogLevel());
294
295 // Add event and make sure both observers receive it.
296 AddEvent(&net_log);
297 EXPECT_EQ(1U, observer[0].GetSize());
298 EXPECT_EQ(1U, observer[1].GetSize());
299
300 // Remove second observer.
301 net_log.RemoveThreadSafeObserver(&observer[1]);
302 EXPECT_EQ(&net_log, observer[0].net_log());
303 EXPECT_EQ(NULL, observer[1].net_log());
304 EXPECT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
305 EXPECT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
306
307 // Add event and make sure only second observer gets it.
308 AddEvent(&net_log);
309 EXPECT_EQ(2U, observer[0].GetSize());
310 EXPECT_EQ(1U, observer[1].GetSize());
311
312 // Remove first observer.
313 net_log.RemoveThreadSafeObserver(&observer[0]);
314 EXPECT_EQ(NULL, observer[0].net_log());
315 EXPECT_EQ(NULL, observer[1].net_log());
316 EXPECT_EQ(net::NetLog::LOG_NONE, net_log.GetLogLevel());
317
318 // Add event and make sure neither observer gets it.
319 AddEvent(&net_log);
320 EXPECT_EQ(2U, observer[0].GetSize());
321 EXPECT_EQ(1U, observer[1].GetSize());
322 }
323
324 // Makes sure that adding and removing observers simultaneously on different
325 // threads works.
326 TEST(NetLogTest, NetLogAddRemoveObserverThreads) {
327 NetLog net_log;
328
329 // Run a bunch of threads to completion, each of which will repeatedly add
330 // and remove an observer, and set its logging level.
331 RunTestThreads<AddRemoveObserverTestThread>(&net_log);
71 } 332 }
72 333
73 } // namespace 334 } // namespace
74 335
75 } // namespace net 336 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698