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.
5 #include "net/log/net_log_unittest.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/threading/simple_thread.h"
11 #include "base/values.h"
12 #include "net/base/net_errors.h"
18 const int kThreads
= 10;
19 const int kEvents
= 100;
21 base::Value
* CaptureModeToValue(NetLogCaptureMode capture_mode
) {
22 return new base::FundamentalValue(capture_mode
.ToInternalValueForTesting());
25 base::Value
* NetCaptureModeCallback(NetLogCaptureMode capture_mode
) {
26 base::DictionaryValue
* dict
= new base::DictionaryValue();
27 dict
->Set("capture_mode", CaptureModeToValue(capture_mode
));
31 TEST(NetLogTest
, Basic
) {
33 TestNetLog::CapturedEntryList entries
;
34 net_log
.GetEntries(&entries
);
35 EXPECT_EQ(0u, entries
.size());
37 net_log
.AddGlobalEntry(NetLog::TYPE_CANCELLED
);
39 net_log
.GetEntries(&entries
);
40 ASSERT_EQ(1u, entries
.size());
41 EXPECT_EQ(NetLog::TYPE_CANCELLED
, entries
[0].type
);
42 EXPECT_EQ(NetLog::SOURCE_NONE
, entries
[0].source
.type
);
43 EXPECT_NE(NetLog::Source::kInvalidId
, entries
[0].source
.id
);
44 EXPECT_EQ(NetLog::PHASE_NONE
, entries
[0].phase
);
45 EXPECT_GE(base::TimeTicks::Now(), entries
[0].time
);
46 EXPECT_FALSE(entries
[0].params
);
49 // Check that the correct CaptureMode is sent to NetLog Value callbacks.
50 TEST(NetLogTest
, CaptureModes
) {
51 NetLogCaptureMode kModes
[] = {
52 NetLogCaptureMode::Default(),
53 NetLogCaptureMode::IncludeCookiesAndCredentials(),
54 NetLogCaptureMode::IncludeSocketBytes(),
59 for (NetLogCaptureMode mode
: kModes
) {
60 net_log
.SetCaptureMode(mode
);
61 EXPECT_EQ(mode
, net_log
.GetCaptureMode());
63 net_log
.AddGlobalEntry(NetLog::TYPE_SOCKET_ALIVE
,
64 base::Bind(NetCaptureModeCallback
));
66 TestNetLog::CapturedEntryList entries
;
67 net_log
.GetEntries(&entries
);
69 ASSERT_EQ(1u, entries
.size());
70 EXPECT_EQ(NetLog::TYPE_SOCKET_ALIVE
, entries
[0].type
);
71 EXPECT_EQ(NetLog::SOURCE_NONE
, entries
[0].source
.type
);
72 EXPECT_NE(NetLog::Source::kInvalidId
, entries
[0].source
.id
);
73 EXPECT_EQ(NetLog::PHASE_NONE
, entries
[0].phase
);
74 EXPECT_GE(base::TimeTicks::Now(), entries
[0].time
);
76 int logged_capture_mode
;
78 entries
[0].GetIntegerValue("capture_mode", &logged_capture_mode
));
79 EXPECT_EQ(mode
.ToInternalValueForTesting(), logged_capture_mode
);
85 class CountingObserver
: public NetLog::ThreadSafeObserver
{
87 CountingObserver() : count_(0) {}
89 ~CountingObserver() override
{
91 net_log()->DeprecatedRemoveObserver(this);
94 void OnAddEntry(const NetLog::Entry
& entry
) override
{ ++count_
; }
96 int count() const { return count_
; }
102 class LoggingObserver
: public NetLog::ThreadSafeObserver
{
106 ~LoggingObserver() override
{
108 net_log()->DeprecatedRemoveObserver(this);
111 void OnAddEntry(const NetLog::Entry
& entry
) override
{
112 base::Value
* value
= entry
.ToValue();
113 base::DictionaryValue
* dict
= NULL
;
114 ASSERT_TRUE(value
->GetAsDictionary(&dict
));
115 values_
.push_back(dict
);
118 size_t GetNumValues() const { return values_
.size(); }
119 base::DictionaryValue
* GetValue(size_t index
) const { return values_
[index
]; }
122 ScopedVector
<base::DictionaryValue
> values_
;
125 void AddEvent(NetLog
* net_log
) {
126 net_log
->AddGlobalEntry(NetLog::TYPE_CANCELLED
,
127 base::Bind(CaptureModeToValue
));
130 // A thread that waits until an event has been signalled before calling
132 class NetLogTestThread
: public base::SimpleThread
{
135 : base::SimpleThread("NetLogTest"), net_log_(NULL
), start_event_(NULL
) {}
137 // We'll wait for |start_event| to be triggered before calling a subclass's
138 // subclass's RunTestThread() function.
139 void Init(NetLog
* net_log
, base::WaitableEvent
* start_event
) {
140 start_event_
= start_event
;
144 void Run() override
{
145 start_event_
->Wait();
149 // Subclasses must override this with the code they want to run on their
151 virtual void RunTestThread() = 0;
157 // Only triggered once all threads have been created, to make it less likely
158 // each thread completes before the next one starts.
159 base::WaitableEvent
* start_event_
;
161 DISALLOW_COPY_AND_ASSIGN(NetLogTestThread
);
164 // A thread that adds a bunch of events to the NetLog.
165 class AddEventsTestThread
: public NetLogTestThread
{
167 AddEventsTestThread() {}
168 ~AddEventsTestThread() override
{}
171 void RunTestThread() override
{
172 for (int i
= 0; i
< kEvents
; ++i
)
176 DISALLOW_COPY_AND_ASSIGN(AddEventsTestThread
);
179 // A thread that adds and removes an observer from the NetLog repeatedly.
180 class AddRemoveObserverTestThread
: public NetLogTestThread
{
182 AddRemoveObserverTestThread() {}
184 ~AddRemoveObserverTestThread() override
{ EXPECT_TRUE(!observer_
.net_log()); }
187 void RunTestThread() override
{
188 for (int i
= 0; i
< kEvents
; ++i
) {
189 ASSERT_FALSE(observer_
.net_log());
191 net_log_
->DeprecatedAddObserver(
192 &observer_
, NetLogCaptureMode::IncludeCookiesAndCredentials());
193 ASSERT_EQ(net_log_
, observer_
.net_log());
194 ASSERT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
195 observer_
.capture_mode());
197 net_log_
->SetObserverCaptureMode(&observer_
,
198 NetLogCaptureMode::IncludeSocketBytes());
199 ASSERT_EQ(net_log_
, observer_
.net_log());
200 ASSERT_EQ(NetLogCaptureMode::IncludeSocketBytes(),
201 observer_
.capture_mode());
203 net_log_
->DeprecatedRemoveObserver(&observer_
);
204 ASSERT_TRUE(!observer_
.net_log());
208 CountingObserver observer_
;
210 DISALLOW_COPY_AND_ASSIGN(AddRemoveObserverTestThread
);
213 // Creates |kThreads| threads of type |ThreadType| and then runs them all
215 template <class ThreadType
>
216 void RunTestThreads(NetLog
* net_log
) {
217 ThreadType threads
[kThreads
];
218 base::WaitableEvent
start_event(true, false);
220 for (size_t i
= 0; i
< arraysize(threads
); ++i
) {
221 threads
[i
].Init(net_log
, &start_event
);
225 start_event
.Signal();
227 for (size_t i
= 0; i
< arraysize(threads
); ++i
)
231 // Makes sure that events on multiple threads are dispatched to all observers.
232 TEST(NetLogTest
, NetLogEventThreads
) {
235 // Attach some observers. Since they're created after |net_log|, they'll
236 // safely detach themselves on destruction.
237 CountingObserver observers
[3];
238 for (size_t i
= 0; i
< arraysize(observers
); ++i
) {
239 net_log
.DeprecatedAddObserver(&observers
[i
],
240 NetLogCaptureMode::IncludeSocketBytes());
243 // Run a bunch of threads to completion, each of which will emit events to
245 RunTestThreads
<AddEventsTestThread
>(&net_log
);
247 // Check that each observer saw the emitted events.
248 const int kTotalEvents
= kThreads
* kEvents
;
249 for (size_t i
= 0; i
< arraysize(observers
); ++i
)
250 EXPECT_EQ(kTotalEvents
, observers
[i
].count());
253 // Test adding and removing a single observer.
254 TEST(NetLogTest
, NetLogAddRemoveObserver
) {
256 CountingObserver observer
;
259 EXPECT_EQ(0, observer
.count());
260 EXPECT_EQ(NULL
, observer
.net_log());
261 EXPECT_FALSE(net_log
.GetCaptureMode().enabled());
263 // Add the observer and add an event.
264 net_log
.DeprecatedAddObserver(
265 &observer
, NetLogCaptureMode::IncludeCookiesAndCredentials());
266 EXPECT_EQ(&net_log
, observer
.net_log());
267 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
268 observer
.capture_mode());
269 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
270 net_log
.GetCaptureMode());
273 EXPECT_EQ(1, observer
.count());
275 // Change the observer's logging level and add an event.
276 net_log
.SetObserverCaptureMode(&observer
,
277 NetLogCaptureMode::IncludeSocketBytes());
278 EXPECT_EQ(&net_log
, observer
.net_log());
279 EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), observer
.capture_mode());
280 EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), net_log
.GetCaptureMode());
283 EXPECT_EQ(2, observer
.count());
285 // Remove observer and add an event.
286 net_log
.DeprecatedRemoveObserver(&observer
);
287 EXPECT_EQ(NULL
, observer
.net_log());
288 EXPECT_FALSE(net_log
.GetCaptureMode().enabled());
291 EXPECT_EQ(2, observer
.count());
293 // Add the observer a final time, and add an event.
294 net_log
.DeprecatedAddObserver(&observer
,
295 NetLogCaptureMode::IncludeSocketBytes());
296 EXPECT_EQ(&net_log
, observer
.net_log());
297 EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), observer
.capture_mode());
298 EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), net_log
.GetCaptureMode());
301 EXPECT_EQ(3, observer
.count());
304 // Test adding and removing two observers at different log levels.
305 TEST(NetLogTest
, NetLogTwoObservers
) {
307 LoggingObserver observer
[2];
309 // Add first observer.
310 net_log
.DeprecatedAddObserver(
311 &observer
[0], NetLogCaptureMode::IncludeCookiesAndCredentials());
312 EXPECT_EQ(&net_log
, observer
[0].net_log());
313 EXPECT_EQ(NULL
, observer
[1].net_log());
314 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
315 observer
[0].capture_mode());
316 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
317 net_log
.GetCaptureMode());
319 // Add second observer observer.
320 net_log
.DeprecatedAddObserver(&observer
[1],
321 NetLogCaptureMode::IncludeSocketBytes());
322 EXPECT_EQ(&net_log
, observer
[0].net_log());
323 EXPECT_EQ(&net_log
, observer
[1].net_log());
324 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
325 observer
[0].capture_mode());
326 EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(),
327 observer
[1].capture_mode());
328 EXPECT_EQ(NetLogCaptureMode::IncludeSocketBytes(), net_log
.GetCaptureMode());
330 // Add event and make sure both observers receive it at their respective log
334 ASSERT_EQ(1U, observer
[0].GetNumValues());
335 ASSERT_TRUE(observer
[0].GetValue(0)->GetInteger("params", ¶m
));
336 EXPECT_EQ(observer
[0].capture_mode().ToInternalValueForTesting(), param
);
337 ASSERT_EQ(1U, observer
[1].GetNumValues());
338 ASSERT_TRUE(observer
[1].GetValue(0)->GetInteger("params", ¶m
));
339 EXPECT_EQ(observer
[1].capture_mode().ToInternalValueForTesting(), param
);
341 // Remove second observer.
342 net_log
.DeprecatedRemoveObserver(&observer
[1]);
343 EXPECT_EQ(&net_log
, observer
[0].net_log());
344 EXPECT_EQ(NULL
, observer
[1].net_log());
345 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
346 observer
[0].capture_mode());
347 EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
348 net_log
.GetCaptureMode());
350 // Add event and make sure only second observer gets it.
352 EXPECT_EQ(2U, observer
[0].GetNumValues());
353 EXPECT_EQ(1U, observer
[1].GetNumValues());
355 // Remove first observer.
356 net_log
.DeprecatedRemoveObserver(&observer
[0]);
357 EXPECT_EQ(NULL
, observer
[0].net_log());
358 EXPECT_EQ(NULL
, observer
[1].net_log());
359 EXPECT_FALSE(net_log
.GetCaptureMode().enabled());
361 // Add event and make sure neither observer gets it.
363 EXPECT_EQ(2U, observer
[0].GetNumValues());
364 EXPECT_EQ(1U, observer
[1].GetNumValues());
367 // Makes sure that adding and removing observers simultaneously on different
369 TEST(NetLogTest
, NetLogAddRemoveObserverThreads
) {
372 // Run a bunch of threads to completion, each of which will repeatedly add
373 // and remove an observer, and set its logging level.
374 RunTestThreads
<AddRemoveObserverTestThread
>(&net_log
);