1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/net_log_unittest.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_vector.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/threading/simple_thread.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/net_errors.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net {
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kThreads = 10;
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kEvents = 100;
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::Value* NetLogLevelCallback(NetLog::LogLevel log_level) {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dict->SetInteger("log_level", log_level);
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return dict;
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(NetLogTest, Basic) {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CapturingNetLog net_log;
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CapturingNetLog::CapturedEntryList entries;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net_log.GetEntries(&entries);
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0u, entries.size());
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net_log.AddGlobalEntry(NetLog::TYPE_CANCELLED);
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net_log.GetEntries(&entries);
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1u, entries.size());
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(NetLog::TYPE_CANCELLED, entries[0].type);
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(NetLog::SOURCE_NONE, entries[0].source.type);
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_NE(NetLog::Source::kInvalidId, entries[0].source.id);
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase);
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_GE(base::TimeTicks::Now(), entries[0].time);
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(entries[0].params);
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Check that the correct LogLevel is sent to NetLog Value callbacks.
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(NetLogTest, LogLevels) {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CapturingNetLog net_log;
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int log_level = NetLog::LOG_ALL; log_level < NetLog::LOG_NONE;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ++log_level) {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    net_log.SetLogLevel(static_cast<NetLog::LogLevel>(log_level));
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(log_level, net_log.GetLogLevel());
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    net_log.AddGlobalEntry(NetLog::TYPE_SOCKET_ALIVE,
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           base::Bind(NetLogLevelCallback));
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CapturingNetLog::CapturedEntryList entries;
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    net_log.GetEntries(&entries);
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ(1u, entries.size());
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(NetLog::TYPE_SOCKET_ALIVE, entries[0].type);
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(NetLog::SOURCE_NONE, entries[0].source.type);
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(NetLog::Source::kInvalidId, entries[0].source.id);
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(NetLog::PHASE_NONE, entries[0].phase);
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_GE(base::TimeTicks::Now(), entries[0].time);
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int logged_log_level;
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(entries[0].GetIntegerValue("log_level", &logged_log_level));
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(log_level, logged_log_level);
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    net_log.Clear();
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CountingObserver : public NetLog::ThreadSafeObserver {
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CountingObserver() : count_(0) {}
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~CountingObserver() {
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (net_log())
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net_log()->RemoveThreadSafeObserver(this);
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void OnAddEntry(const NetLog::Entry& entry) OVERRIDE {
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ++count_;
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int count() const { return count_; }
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int count_;
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class LoggingObserver : public NetLog::ThreadSafeObserver {
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LoggingObserver() {}
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~LoggingObserver() {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (net_log())
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net_log()->RemoveThreadSafeObserver(this);
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnAddEntry(const NetLog::Entry& entry) OVERRIDE {
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Value* value = entry.ToValue();
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::DictionaryValue* dict = NULL;
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(value->GetAsDictionary(&dict));
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    values_.push_back(dict);
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t GetNumValues() const { return values_.size(); }
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::DictionaryValue* GetValue(size_t index) const { return values_[index]; }
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedVector<base::DictionaryValue> values_;
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)base::Value* LogLevelToValue(NetLog::LogLevel log_level) {
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return new base::FundamentalValue(log_level);
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AddEvent(NetLog* net_log) {
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  net_log->AddGlobalEntry(NetLog::TYPE_CANCELLED, base::Bind(LogLevelToValue));
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A thread that waits until an event has been signalled before calling
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// RunTestThread.
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class NetLogTestThread : public base::SimpleThread {
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetLogTestThread()
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : base::SimpleThread("NetLogTest"),
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        net_log_(NULL),
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        start_event_(NULL) {
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We'll wait for |start_event| to be triggered before calling a subclass's
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // subclass's RunTestThread() function.
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void Init(NetLog* net_log, base::WaitableEvent* start_event) {
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    start_event_ = start_event;
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    net_log_ = net_log;
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void Run() OVERRIDE {
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    start_event_->Wait();
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RunTestThread();
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Subclasses must override this with the code they want to run on their
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // thread.
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void RunTestThread() = 0;
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetLog* net_log_;
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Only triggered once all threads have been created, to make it less likely
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // each thread completes before the next one starts.
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::WaitableEvent* start_event_;
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetLogTestThread);
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A thread that adds a bunch of events to the NetLog.
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class AddEventsTestThread : public NetLogTestThread {
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEventsTestThread() {}
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~AddEventsTestThread() {}
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void RunTestThread() OVERRIDE {
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (int i = 0; i < kEvents; ++i)
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AddEvent(net_log_);
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddEventsTestThread);
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A thread that adds and removes an observer from the NetLog repeatedly.
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class AddRemoveObserverTestThread : public NetLogTestThread {
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddRemoveObserverTestThread() {}
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~AddRemoveObserverTestThread() {
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(!observer_.net_log());
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void RunTestThread() OVERRIDE {
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (int i = 0; i < kEvents; ++i) {
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_FALSE(observer_.net_log());
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net_log_->AddThreadSafeObserver(&observer_, NetLog::LOG_ALL_BUT_BYTES);
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_EQ(net_log_, observer_.net_log());
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer_.log_level());
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_LE(net_log_->GetLogLevel(), NetLog::LOG_ALL_BUT_BYTES);
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net_log_->SetObserverLogLevel(&observer_, NetLog::LOG_ALL);
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_EQ(net_log_, observer_.net_log());
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_EQ(NetLog::LOG_ALL, observer_.log_level());
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_LE(net_log_->GetLogLevel(), NetLog::LOG_ALL);
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net_log_->RemoveThreadSafeObserver(&observer_);
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_TRUE(!observer_.net_log());
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CountingObserver observer_;
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddRemoveObserverTestThread);
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Creates |kThreads| threads of type |ThreadType| and then runs them all
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// to completion.
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template<class ThreadType>
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void RunTestThreads(NetLog* net_log) {
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ThreadType threads[kThreads];
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::WaitableEvent start_event(true, false);
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < arraysize(threads); ++i) {
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    threads[i].Init(net_log, &start_event);
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    threads[i].Start();
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  start_event.Signal();
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < arraysize(threads); ++i)
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    threads[i].Join();
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Makes sure that events on multiple threads are dispatched to all observers.
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(NetLogTest, NetLogEventThreads) {
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetLog net_log;
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Attach some observers.  Since they're created after |net_log|, they'll
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // safely detach themselves on destruction.
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CountingObserver observers[3];
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < arraysize(observers); ++i)
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net_log.AddThreadSafeObserver(&observers[i], NetLog::LOG_ALL);
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Run a bunch of threads to completion, each of which will emit events to
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // |net_log|.
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunTestThreads<AddEventsTestThread>(&net_log);
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Check that each observer saw the emitted events.
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const int kTotalEvents = kThreads * kEvents;
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < arraysize(observers); ++i)
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(kTotalEvents, observers[i].count());
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test adding and removing a single observer.
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(NetLogTest, NetLogAddRemoveObserver) {
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetLog net_log;
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CountingObserver observer;
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, observer.count());
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NULL, observer.net_log());
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_NONE, net_log.GetLogLevel());
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add the observer and add an event.
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  net_log.AddThreadSafeObserver(&observer, NetLog::LOG_ALL_BUT_BYTES);
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer.net_log());
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer.log_level());
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, observer.count());
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Change the observer's logging level and add an event.
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.SetObserverLogLevel(&observer, NetLog::LOG_ALL);
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer.net_log());
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL, observer.log_level());
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL, net_log.GetLogLevel());
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, observer.count());
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Remove observer and add an event.
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.RemoveThreadSafeObserver(&observer);
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NULL, observer.net_log());
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_NONE, net_log.GetLogLevel());
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, observer.count());
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add the observer a final time, and add an event.
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.AddThreadSafeObserver(&observer, NetLog::LOG_ALL);
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer.net_log());
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL, observer.log_level());
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL, net_log.GetLogLevel());
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(3, observer.count());
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test adding and removing two observers at different log levels.
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(NetLogTest, NetLogTwoObservers) {
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetLog net_log;
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LoggingObserver observer[2];
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add first observer.
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.AddThreadSafeObserver(&observer[0], NetLog::LOG_ALL_BUT_BYTES);
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer[0].net_log());
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NULL, observer[1].net_log());
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add second observer observer.
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.AddThreadSafeObserver(&observer[1], NetLog::LOG_ALL);
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer[0].net_log());
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer[1].net_log());
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL, observer[1].log_level());
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL, net_log.GetLogLevel());
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Add event and make sure both observers receive it at their respective log
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // levels.
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int param;
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, observer[0].GetNumValues());
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(observer[0].GetValue(0)->GetInteger("params", &param));
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(observer[0].log_level(), param);
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, observer[1].GetNumValues());
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(observer[1].GetValue(0)->GetInteger("params", &param));
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(observer[1].log_level(), param);
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Remove second observer.
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.RemoveThreadSafeObserver(&observer[1]);
327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(&net_log, observer[0].net_log());
328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NULL, observer[1].net_log());
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, observer[0].log_level());
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add event and make sure only second observer gets it.
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2U, observer[0].GetNumValues());
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1U, observer[1].GetNumValues());
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Remove first observer.
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net_log.RemoveThreadSafeObserver(&observer[0]);
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NULL, observer[0].net_log());
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NULL, observer[1].net_log());
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NetLog::LOG_NONE, net_log.GetLogLevel());
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add event and make sure neither observer gets it.
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AddEvent(&net_log);
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2U, observer[0].GetNumValues());
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1U, observer[1].GetNumValues());
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Makes sure that adding and removing observers simultaneously on different
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// threads works.
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(NetLogTest, NetLogAddRemoveObserverThreads) {
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetLog net_log;
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Run a bunch of threads to completion, each of which will repeatedly add
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and remove an observer, and set its logging level.
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunTestThreads<AddRemoveObserverTestThread>(&net_log);
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace net
362