Home | History | Annotate | Download | only in base
      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 
     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 
     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.
     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:
     80   CountingObserver() : count_(0) {}
     81 
     82   virtual ~CountingObserver() {
     83     if (net_log())
     84       net_log()->RemoveThreadSafeObserver(this);
     85   }
     86 
     87   virtual void OnAddEntry(const NetLog::Entry& entry) OVERRIDE {
     88     ++count_;
     89   }
     90 
     91   int count() const { return count_; }
     92 
     93  private:
     94   int count_;
     95 };
     96 
     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:
    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.
    113   void Init(NetLog* net_log, base::WaitableEvent* start_event) {
    114     start_event_ = start_event;
    115     net_log_ = net_log;
    116   }
    117 
    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:
    141   AddEventsTestThread() {}
    142   virtual ~AddEventsTestThread() {}
    143 
    144  private:
    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:
    156   AddRemoveObserverTestThread() {}
    157 
    158   virtual ~AddRemoveObserverTestThread() {
    159     EXPECT_TRUE(!observer_.net_log());
    160   }
    161 
    162  private:
    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>
    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.
    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.
    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.
    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.
    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