Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 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/trace_net_log_observer.h" | |
| 6 | |
| 7 #include <string> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/debug/trace_event.h" | |
| 11 #include "base/debug/trace_event_impl.h" | |
| 12 #include "base/json/json_reader.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "base/memory/ref_counted_memory.h" | |
| 16 #include "base/memory/scoped_ptr.h" | |
| 17 #include "base/strings/stringprintf.h" | |
| 18 #include "base/values.h" | |
| 19 #include "net/base/capturing_net_log.h" | |
| 20 #include "net/base/net_log.h" | |
| 21 #include "testing/gtest/include/gtest/gtest.h" | |
| 22 | |
| 23 namespace net { | |
| 24 | |
| 25 namespace { | |
| 26 | |
| 27 using base::debug::TraceLog; | |
| 28 | |
| 29 class TraceNetLogObserverTest : public testing::Test { | |
| 30 public: | |
| 31 virtual void SetUp() OVERRIDE { | |
| 32 TraceLog::DeleteForTesting(); | |
| 33 TraceLog* tracelog = TraceLog::GetInstance(); | |
| 34 ASSERT_TRUE(tracelog); | |
| 35 ASSERT_FALSE(tracelog->IsEnabled()); | |
| 36 trace_buffer_.SetOutputCallback(json_output_.GetCallback()); | |
| 37 net_log_.reset(new CapturingNetLog); | |
| 38 trace_net_log_observer_.reset(new TraceNetLogObserver()); | |
| 39 // TODO(xunjieli): Remove this once Trace bug is fixed. | |
| 40 TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop(); | |
| 41 } | |
| 42 | |
| 43 virtual void TearDown() OVERRIDE { | |
| 44 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled()); | |
| 45 TraceLog::DeleteForTesting(); | |
| 46 } | |
| 47 | |
| 48 void OnTraceDataCollected( | |
| 49 const scoped_refptr<base::RefCountedString>& events_str, | |
| 50 bool has_more_events) { | |
| 51 DCHECK(trace_events_.empty()); | |
| 52 trace_buffer_.Start(); | |
| 53 trace_buffer_.AddFragment(events_str->data()); | |
| 54 trace_buffer_.Finish(); | |
| 55 | |
| 56 scoped_ptr<base::Value> trace_value; | |
| 57 trace_value.reset(base::JSONReader::Read( | |
| 58 json_output_.json_output, | |
| 59 base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN)); | |
| 60 | |
| 61 ASSERT_TRUE(trace_value) << json_output_.json_output; | |
| 62 base::ListValue* trace_events = NULL; | |
| 63 ASSERT_TRUE(trace_value.get()); | |
| 64 ASSERT_TRUE(trace_value->GetAsList(&trace_events)); | |
| 65 trace_events_.Swap(trace_events); | |
| 66 } | |
| 67 | |
| 68 void EnableTraceLog() { | |
| 69 TraceLog::GetInstance()->SetEnabled( | |
| 70 base::debug::CategoryFilter("*"), | |
| 71 TraceLog::RECORDING_MODE, | |
| 72 base::debug::TraceOptions()); | |
| 73 } | |
| 74 | |
| 75 void DisableTraceLog() { | |
|
mmenke
2014/08/22 18:28:14
Optional: May want to make this and EnableTraceLo
xunjieli
2014/08/22 19:04:40
Done.
| |
| 76 TraceLog::GetInstance()->SetDisabled(); | |
| 77 } | |
| 78 | |
| 79 void EndTraceAndFlush() { | |
| 80 TraceLog::GetInstance()->SetDisabled(); | |
| 81 TraceLog::GetInstance()->Flush( | |
| 82 Bind(&TraceNetLogObserverTest::OnTraceDataCollected, | |
| 83 base::Unretained(this))); | |
| 84 } | |
| 85 | |
| 86 void ResetTraceNetLogObserver(TraceNetLogObserver* trace_net_log_observer) { | |
| 87 trace_net_log_observer_.reset(trace_net_log_observer); | |
| 88 } | |
| 89 | |
| 90 const base::DictionaryValue* FindTraceEntry(NetLog::EventType event_type, | |
| 91 size_t& pos) { | |
| 92 // Scan all items | |
| 93 std::string type(NetLog::EventTypeToString(event_type)); | |
| 94 size_t trace_events_count = trace_events_.GetSize(); | |
| 95 for (size_t i = 0; i < trace_events_count; i++) { | |
| 96 const base::Value* value = NULL; | |
| 97 trace_events_.Get(i, &value); | |
| 98 const base::DictionaryValue* dict = NULL; | |
| 99 if (!value->GetAsDictionary(&dict)) | |
| 100 continue; | |
| 101 std::string actual_type; | |
| 102 if (dict->GetString("name", &actual_type)) { | |
| 103 if (actual_type == type) { | |
| 104 pos = i; | |
| 105 return dict; | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 return NULL; | |
| 110 } | |
| 111 | |
| 112 std::vector<const base::DictionaryValue*> FindTraceEntries( | |
| 113 NetLog::EventType event_type) { | |
| 114 std::vector<const base::DictionaryValue*> hits; | |
| 115 std::string type(NetLog::EventTypeToString(event_type)); | |
| 116 size_t trace_events_count = trace_events_.GetSize(); | |
| 117 for (size_t i = 0; i < trace_events_count; i++) { | |
| 118 const base::Value* value = NULL; | |
| 119 trace_events_.Get(i, &value); | |
| 120 const base::DictionaryValue* dict = NULL; | |
| 121 if (!value->GetAsDictionary(&dict)) | |
| 122 continue; | |
| 123 std::string actual_type; | |
| 124 if (dict->GetString("name", &actual_type)) { | |
| 125 if (actual_type == type) | |
| 126 hits.push_back(dict); | |
| 127 } | |
| 128 } | |
| 129 return hits; | |
| 130 } | |
| 131 | |
| 132 CapturingNetLog* net_log() const { | |
| 133 return net_log_.get(); | |
| 134 } | |
| 135 | |
| 136 TraceNetLogObserver* trace_net_log_observer() const { | |
| 137 return trace_net_log_observer_.get(); | |
| 138 } | |
| 139 | |
| 140 private: | |
| 141 base::ListValue trace_events_; | |
| 142 base::debug::TraceResultBuffer trace_buffer_; | |
| 143 base::debug::TraceResultBuffer::SimpleOutput json_output_; | |
| 144 scoped_ptr<CapturingNetLog> net_log_; | |
| 145 scoped_ptr<TraceNetLogObserver> trace_net_log_observer_; | |
| 146 }; | |
| 147 | |
| 148 const size_t npos = size_t(-1); | |
|
mmenke
2014/08/22 18:28:14
I don't think we need this - if FindTraceEntry ret
xunjieli
2014/08/22 19:04:40
Done.
| |
| 149 | |
| 150 TEST_F(TraceNetLogObserverTest, TracingNotEnabled) { | |
| 151 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 152 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 153 | |
| 154 EndTraceAndFlush(); | |
| 155 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 156 | |
| 157 size_t pos = npos; | |
| 158 const base::DictionaryValue* item = FindTraceEntry( | |
| 159 NetLog::TYPE_REQUEST_ALIVE, pos); | |
| 160 EXPECT_FALSE(item); | |
| 161 EXPECT_EQ(npos, pos); | |
| 162 } | |
| 163 | |
| 164 TEST_F(TraceNetLogObserverTest, TraceEventCaptured) { | |
| 165 CapturingNetLog::CapturedEntryList entries; | |
| 166 net_log()->GetEntries(&entries); | |
| 167 EXPECT_EQ(0u, entries.size()); | |
| 168 | |
| 169 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 170 EnableTraceLog(); | |
| 171 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED); | |
| 172 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 173 | |
| 174 net_log()->GetEntries(&entries); | |
| 175 ASSERT_EQ(2u, entries.size()); | |
| 176 | |
| 177 EndTraceAndFlush(); | |
| 178 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 179 | |
| 180 size_t pos1, pos2 = npos; | |
|
mmenke
2014/08/22 18:28:14
Per Google style guide, use one line per variable.
xunjieli
2014/08/22 19:04:40
Done.
| |
| 181 const base::DictionaryValue* item1 = FindTraceEntry( | |
| 182 NetLog::TYPE_CANCELLED, pos1); | |
| 183 const base::DictionaryValue* item2 = FindTraceEntry( | |
| 184 NetLog::TYPE_REQUEST_ALIVE, pos2); | |
| 185 EXPECT_TRUE(pos1 < pos2); | |
| 186 | |
| 187 std::string item1_phase, item2_phase; | |
| 188 EXPECT_TRUE(item1 && item1->GetString("ph", &item1_phase)); | |
| 189 EXPECT_TRUE(item2 && item2->GetString("ph", &item2_phase)); | |
| 190 EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NET_LOG_INSTANT), item1_phase); | |
| 191 EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NET_LOG_INSTANT), item2_phase); | |
| 192 | |
| 193 std::string item1_id, item2_id; | |
| 194 EXPECT_TRUE(item1->GetString("id", &item1_id) && | |
| 195 item2->GetString("id", &item2_id)); | |
| 196 std::string item1_expected_id = | |
| 197 base::StringPrintf("0x%d", entries[0].source.id); | |
| 198 std::string item2_expected_id = | |
| 199 base::StringPrintf("0x%d", entries[1].source.id); | |
| 200 EXPECT_EQ(item1_expected_id, item1_id); | |
| 201 EXPECT_EQ(item2_expected_id, item2_id); | |
| 202 EXPECT_NE(item1_id, item2_id); | |
| 203 | |
| 204 std::string item1_source_type, item2_source_type; | |
| 205 EXPECT_TRUE(item1->GetString("args.source_type", &item1_source_type)); | |
| 206 EXPECT_TRUE(item2->GetString("args.source_type", &item2_source_type)); | |
| 207 | |
| 208 EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type), | |
| 209 item1_source_type); | |
| 210 EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type), | |
| 211 item2_source_type); | |
| 212 | |
| 213 std::string item1_category, item2_category; | |
| 214 EXPECT_TRUE(item1->GetString("cat", &item1_category)); | |
| 215 EXPECT_TRUE(item2->GetString("cat", &item2_category)); | |
| 216 | |
| 217 EXPECT_EQ("netlog", item1_category); | |
| 218 EXPECT_EQ("netlog", item2_category); | |
| 219 | |
| 220 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_CANCELLED).size()); | |
| 221 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_REQUEST_ALIVE).size()); | |
| 222 } | |
| 223 | |
| 224 TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) { | |
| 225 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 226 EnableTraceLog(); | |
| 227 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED); | |
| 228 DisableTraceLog(); | |
| 229 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 230 EnableTraceLog(); | |
| 231 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB); | |
| 232 | |
| 233 EndTraceAndFlush(); | |
| 234 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 235 | |
| 236 size_t pos1, pos2, pos3 = npos; | |
| 237 const base::DictionaryValue* item1 = FindTraceEntry( | |
| 238 NetLog::TYPE_CANCELLED, pos1); | |
| 239 const base::DictionaryValue* item2 = FindTraceEntry( | |
| 240 NetLog::TYPE_REQUEST_ALIVE, pos2); | |
| 241 const base::DictionaryValue* item3 = FindTraceEntry( | |
| 242 NetLog::TYPE_URL_REQUEST_START_JOB, pos3); | |
| 243 EXPECT_TRUE(item1); | |
| 244 EXPECT_FALSE(item2); | |
| 245 EXPECT_TRUE(item3); | |
| 246 EXPECT_TRUE(pos2 == npos && pos1 < pos3); | |
|
mmenke
2014/08/22 18:28:14
Should use EXPECT_EQ and EXPECT_LT. They provide
xunjieli
2014/08/22 19:04:39
Done. Thanks!
| |
| 247 | |
| 248 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_CANCELLED).size()); | |
| 249 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_URL_REQUEST_START_JOB).size()); | |
| 250 } | |
| 251 | |
| 252 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) { | |
| 253 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 254 EnableTraceLog(); | |
| 255 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED); | |
| 256 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 257 ResetTraceNetLogObserver(NULL); | |
| 258 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 259 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB); | |
| 260 | |
| 261 EndTraceAndFlush(); | |
| 262 | |
| 263 size_t pos1, pos2, pos3 = npos; | |
| 264 const base::DictionaryValue* item1 = FindTraceEntry( | |
| 265 NetLog::TYPE_CANCELLED, pos1); | |
| 266 const base::DictionaryValue* item2 = FindTraceEntry( | |
| 267 NetLog::TYPE_REQUEST_ALIVE, pos2); | |
| 268 const base::DictionaryValue* item3 = FindTraceEntry( | |
| 269 NetLog::TYPE_URL_REQUEST_START_JOB, pos3); | |
| 270 EXPECT_TRUE(item1); | |
| 271 EXPECT_FALSE(item2); | |
| 272 EXPECT_FALSE(item3); | |
| 273 EXPECT_TRUE(pos1 != npos && pos2 == npos && pos3 == npos); | |
| 274 | |
| 275 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_CANCELLED).size()); | |
| 276 } | |
| 277 | |
| 278 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) { | |
| 279 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 280 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED); | |
| 281 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 282 ResetTraceNetLogObserver(NULL); | |
| 283 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 284 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB); | |
| 285 | |
| 286 EndTraceAndFlush(); | |
| 287 | |
| 288 size_t pos1, pos2, pos3 = npos; | |
| 289 const base::DictionaryValue* item1 = FindTraceEntry( | |
| 290 NetLog::TYPE_CANCELLED, pos1); | |
| 291 const base::DictionaryValue* item2 = FindTraceEntry( | |
| 292 NetLog::TYPE_REQUEST_ALIVE, pos2); | |
| 293 const base::DictionaryValue* item3 = FindTraceEntry( | |
| 294 NetLog::TYPE_URL_REQUEST_START_JOB, pos3); | |
| 295 EXPECT_FALSE(item1); | |
| 296 EXPECT_FALSE(item2); | |
| 297 EXPECT_FALSE(item3); | |
| 298 EXPECT_TRUE(pos1 == npos && pos2 == npos && pos3 == npos); | |
| 299 } | |
| 300 | |
| 301 TEST_F(TraceNetLogObserverTest, CreateObserverAfterTracingStarts) { | |
| 302 ResetTraceNetLogObserver(NULL); | |
| 303 EnableTraceLog(); | |
| 304 ResetTraceNetLogObserver(new TraceNetLogObserver()); | |
| 305 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 306 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED); | |
| 307 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 308 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 309 net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB); | |
| 310 | |
| 311 EndTraceAndFlush(); | |
| 312 | |
| 313 size_t pos1, pos2, pos3 = npos; | |
| 314 const base::DictionaryValue* item1 = FindTraceEntry( | |
| 315 NetLog::TYPE_CANCELLED, pos1); | |
| 316 const base::DictionaryValue* item2 = FindTraceEntry( | |
| 317 NetLog::TYPE_REQUEST_ALIVE, pos2); | |
| 318 const base::DictionaryValue* item3 = FindTraceEntry( | |
| 319 NetLog::TYPE_URL_REQUEST_START_JOB, pos3); | |
| 320 EXPECT_FALSE(item1); | |
| 321 EXPECT_FALSE(item2); | |
| 322 EXPECT_FALSE(item3); | |
| 323 EXPECT_TRUE(pos1 == npos && pos2 == npos && pos3 == npos); | |
| 324 } | |
| 325 | |
| 326 TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) { | |
| 327 trace_net_log_observer()->WatchForTraceStart(net_log()); | |
| 328 EnableTraceLog(); | |
| 329 NetLog::ParametersCallback net_log_callback; | |
| 330 std::string param = "bar"; | |
| 331 net_log_callback = NetLog::StringCallback("foo", | |
| 332 ¶m); | |
| 333 | |
| 334 net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED, net_log_callback); | |
| 335 net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE); | |
| 336 | |
| 337 EndTraceAndFlush(); | |
| 338 trace_net_log_observer()->StopWatchForTraceStart(); | |
| 339 | |
| 340 size_t pos1, pos2 = npos; | |
| 341 const base::DictionaryValue* item1 = FindTraceEntry( | |
| 342 NetLog::TYPE_CANCELLED, pos1); | |
| 343 const base::DictionaryValue* item2 = FindTraceEntry( | |
| 344 NetLog::TYPE_REQUEST_ALIVE, pos2); | |
| 345 EXPECT_TRUE(pos1 < pos2); | |
|
mmenke
2014/08/22 18:28:14
EXPECT_LE
xunjieli
2014/08/22 19:04:40
Done.
| |
| 346 | |
| 347 std::string item1_params, item2_params; | |
| 348 EXPECT_TRUE(item1 && item1->GetString("args.params.foo", &item1_params)); | |
| 349 EXPECT_EQ("bar", item1_params); | |
| 350 | |
| 351 EXPECT_TRUE(item2 && item2->GetString("args.params", &item2_params)); | |
| 352 EXPECT_TRUE(item2_params.empty()); | |
| 353 | |
| 354 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_CANCELLED).size()); | |
| 355 EXPECT_EQ(1u, FindTraceEntries(NetLog::TYPE_REQUEST_ALIVE).size()); | |
| 356 } | |
| 357 | |
| 358 } // namespace | |
| 359 | |
| 360 } // namespace net | |
| OLD | NEW |