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