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