Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Unified Diff: net/base/trace_net_log_observer_unittest.cc

Issue 468083004: Use NESTABLE_ASYNC APIs to get NetLog data into Tracing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added Unit Tests Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/base/trace_net_log_observer_unittest.cc
diff --git a/net/base/trace_net_log_observer_unittest.cc b/net/base/trace_net_log_observer_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f7309ad0f2e3b4d1fa04678d3a7497f69f4ff093
--- /dev/null
+++ b/net/base/trace_net_log_observer_unittest.cc
@@ -0,0 +1,320 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/trace_net_log_observer.h"
+
+#include "base/debug/trace_event.h"
+
mmenke 2014/08/21 15:35:40 nit: Remove blank line.
xunjieli 2014/08/22 17:20:10 Done.
+#include "base/json/json_reader.h"
+#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
mmenke 2014/08/21 15:35:41 Should include NetLog and TraceLog headers (They'r
xunjieli 2014/08/22 17:20:11 Done.
+
+namespace net {
+
+namespace {
+
+using namespace base;
xunjieli 2014/08/20 22:00:43 I think this "using namespace" directive is not re
mmenke 2014/08/21 15:35:40 It's not too common in net/, but you can use indiv
xunjieli 2014/08/22 17:20:11 Done. Thanks!
+
+// A net log that logs all events by default.
+class MyTestNetLog : public net::NetLog {
+ public:
+ MyTestNetLog() {
+ SetBaseLogLevel(LOG_ALL);
mmenke 2014/08/21 15:35:40 This class shouldn't be needed - the NetLog should
xunjieli 2014/08/22 17:20:11 Done. Thanks!
+ }
+ virtual ~MyTestNetLog() {}
+};
+
+class TraceNetLogObserverTest : public testing::Test {
+ public:
+ void OnTraceDataCollected(
+ const scoped_refptr<RefCountedString>& events_str,
mmenke 2014/08/21 15:35:40 Should include base/memory/ref_counted.h, and ref_
xunjieli 2014/08/22 17:20:11 Done.
+ bool has_more_events);
mmenke 2014/08/21 15:35:41 nit: Should inline all functions, to be consisten
xunjieli 2014/08/22 17:20:10 Done.
+ void Clear() {
mmenke 2014/08/21 15:35:41 nit: Blank line before clear.
xunjieli 2014/08/22 17:20:10 Done.
+ trace_parsed_.Clear();
+ json_output_.json_output.clear();
+ }
+
+ void EnableTraceLog() {
+ debug::TraceLog::GetInstance()->SetEnabled(
+ debug::CategoryFilter("*"),
+ debug::TraceLog::RECORDING_MODE,
+ debug::TraceOptions());
+ }
+
+ void DisableTraceLog() {
+ debug::TraceLog::GetInstance()->SetDisabled();
+ }
+
+ void EndTraceAndFlush() {
+ debug::TraceLog::GetInstance()->SetDisabled();
+ debug::TraceLog::GetInstance()->Flush(
+ Bind(&TraceNetLogObserverTest::OnTraceDataCollected,
+ Unretained(this)));
+ }
+
+ virtual void SetUp() OVERRIDE {
mmenke 2014/08/21 15:35:40 nit: Suggest putting SetUp and TearDown first.
xunjieli 2014/08/22 17:20:10 Done. Thanks!
+ debug::TraceLog::DeleteForTesting();
+ debug::TraceLog* tracelog = debug::TraceLog::GetInstance();
+ ASSERT_TRUE(tracelog);
+ ASSERT_FALSE(tracelog->IsEnabled());
+ trace_buffer_.SetOutputCallback(json_output_.GetCallback());
+ net_log_.reset(new MyTestNetLog);
+ trace_net_log_observer_.reset(new TraceNetLogObserver());
+ // TODO(xunjieli): not sure whether this is okay.
+ debug::TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ if (debug::TraceLog::GetInstance())
mmenke 2014/08/21 15:35:41 Is this conditional needed? Looks like it always
xunjieli 2014/08/22 17:20:11 Done. Right, I think it is not needed. Thanks!
+ EXPECT_FALSE(debug::TraceLog::GetInstance()->IsEnabled());
+ debug::TraceLog::DeleteForTesting();
+ }
+
+ ListValue trace_parsed_;
mmenke 2014/08/21 15:35:41 These should be private, with accessors as needed.
xunjieli 2014/08/22 17:20:11 Done. Got it. Thanks!
+ debug::TraceResultBuffer trace_buffer_;
+ debug::TraceResultBuffer::SimpleOutput json_output_;
+ scoped_ptr<NetLog> net_log_;
+ scoped_ptr<TraceNetLogObserver> trace_net_log_observer_;
mmenke 2014/08/21 15:35:40 Should include the scoped_ptr header.
xunjieli 2014/08/22 17:20:10 Done.
+};
+
+
+void TraceNetLogObserverTest::OnTraceDataCollected(
+ const scoped_refptr<RefCountedString>& events_str,
+ bool has_more_events) {
+ json_output_.json_output.clear();
mmenke 2014/08/21 15:35:40 DCHECK(trace_parsed_.empty());? (DCHECK instead o
xunjieli 2014/08/22 17:20:11 Done. Thanks!
+ trace_buffer_.Start();
+ trace_buffer_.AddFragment(events_str->data());
+ trace_buffer_.Finish();
+
+ scoped_ptr<Value> root;
mmenke 2014/08/21 15:35:41 trace_value, maybe?
xunjieli 2014/08/22 17:20:11 Done.
+ root.reset(JSONReader::Read(json_output_.json_output,
+ JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN));
+
+ if (!root.get()) {
+ LOG(ERROR) << json_output_.json_output;
+ }
mmenke 2014/08/21 15:35:41 This can be replaced with: ASSERT_TRUE(root) << j
xunjieli 2014/08/22 17:20:11 Done. Thanks! That's convenient!
+
+ ListValue* root_list = NULL;
+ ASSERT_TRUE(root.get());
+ ASSERT_TRUE(root->GetAsList(&root_list));
+
+ while (root_list->GetSize()) {
mmenke 2014/08/21 15:35:41 Rather than copying, this can be replaced with: t
mmenke 2014/08/21 15:35:42 suggest renaming root_list to trace_events and tra
xunjieli 2014/08/22 17:20:11 Done. Thanks!
+ scoped_ptr<Value> item;
+ root_list->Remove(0, &item);
+ trace_parsed_.Append(item.release());
+ }
+}
+
+bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
+ for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
+ if (it.key().find(string_to_match) != std::string::npos)
+ return true;
+
+ std::string value_str;
mmenke 2014/08/21 15:35:40 Should include <string>
xunjieli 2014/08/22 17:20:10 Done.
+ it.value().GetAsString(&value_str);
+ if (value_str.find(string_to_match) != std::string::npos)
+ return true;
+ }
+
+ // Recurse to test arguments
+ const DictionaryValue* args_dict = NULL;
+ dict->GetDictionary("args", &args_dict);
+ if (args_dict)
+ return IsStringInDict(string_to_match, args_dict);
mmenke 2014/08/21 15:35:41 This seems much too broad. Surely we know just wh
xunjieli 2014/08/22 17:20:10 Done. You are right! Thanks!
+
+ return false;
+}
+
+const DictionaryValue* FindTraceEntry(
+ const ListValue& trace_parsed,
mmenke 2014/08/21 15:35:41 Since this is a member of the class, don't need to
xunjieli 2014/08/22 17:20:11 Done.
+ const char* string_to_match) {
mmenke 2014/08/21 15:35:41 Maybe call this event_type, and just take raw NetL
xunjieli 2014/08/22 17:20:10 Done. That's smart. Thank you!
+ // Scan all items
+ size_t trace_parsed_count = trace_parsed.GetSize();
+ for (size_t i = 0; i < trace_parsed_count; i++) {
+ const Value* value = NULL;
+ trace_parsed.Get(i, &value);
+ if (!value || value->GetType() != Value::TYPE_DICTIONARY)
+ continue;
+ const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
mmenke 2014/08/21 15:35:41 Should get rid of the type check, and use value->G
xunjieli 2014/08/22 17:20:10 Done.
+
+ if (IsStringInDict(string_to_match, dict))
mmenke 2014/08/21 15:35:41 Again, it seems like we should know exactly where
xunjieli 2014/08/22 17:20:11 Done.
+ return dict;
+ }
+ return NULL;
+}
+
+} // namespace
mmenke 2014/08/21 15:35:42 Can just extend the anonymous namespace to the end
xunjieli 2014/08/22 17:20:10 Done.
+
+TEST_F(TraceNetLogObserverTest, TracingNotEnabled) {
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+
+ EndTraceAndFlush();
+
+ trace_net_log_observer_->StopWatchForTraceStart();
+ const DictionaryValue* item = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
+ EXPECT_FALSE(item);
+}
+
+
+TEST_F(TraceNetLogObserverTest, TraceEventCaptured) {
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ EnableTraceLog();
+ net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+
+ EndTraceAndFlush();
+
+ const DictionaryValue* item = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
+ EXPECT_TRUE(item);
mmenke 2014/08/21 15:35:40 Also, maybe log a second event, and make sure orde
mmenke 2014/08/21 15:35:40 Also, should check other values as well - make sur
mmenke 2014/08/21 15:35:41 Should we make sure there's only one such event?
xunjieli 2014/08/22 17:20:10 Done.
xunjieli 2014/08/22 17:20:11 Done.
xunjieli 2014/08/22 17:20:11 Done.
+}
+
+TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) {
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ EnableTraceLog();
+ net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ DisableTraceLog();
+ net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ EnableTraceLog();
+ net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+
+ const DictionaryValue* item1 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
+ const DictionaryValue* item2 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
+ const DictionaryValue* item3 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
+ EXPECT_TRUE(item1);
+ EXPECT_FALSE(item2);
+ EXPECT_TRUE(item3);
+}
+
+TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) {
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ EnableTraceLog();
+ net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ trace_net_log_observer_->StopWatchForTraceStart();
+ trace_net_log_observer_.reset(NULL);
xunjieli 2014/08/20 22:00:43 Matt, if I just reset the observer scope_ptr, the
mmenke 2014/08/21 15:35:41 Yes, this is just what you should be doing.
xunjieli 2014/08/22 17:20:11 Done. Thanks!
+ net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+
+ const DictionaryValue* item1 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
+ const DictionaryValue* item2 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
+ const DictionaryValue* item3 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
+ EXPECT_TRUE(item1);
+ EXPECT_FALSE(item2);
+ EXPECT_FALSE(item3);
+}
+
+TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) {
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ trace_net_log_observer_->StopWatchForTraceStart();
+ trace_net_log_observer_.reset(NULL);
+ net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+
+ const DictionaryValue* item1 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
+ const DictionaryValue* item2 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
+ const DictionaryValue* item3 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
+ EXPECT_FALSE(item1);
+ EXPECT_FALSE(item2);
+ EXPECT_FALSE(item3);
+}
+/**
+TEST_F(TraceNetLogObserverTest, CreateObserverAfterTracingStarts) {
+ trace_net_log_observer_.reset(NULL);
+ EnableTraceLog();
+ trace_net_log_observer_.reset(new TraceNetLogObserver());
xunjieli 2014/08/20 22:00:43 If we start the observer after Tracing is enabled,
mmenke 2014/08/21 15:35:41 This is probably expected behavior. I suggest jus
xunjieli 2014/08/22 17:20:10 I see. Thanks! On 2014/08/21 15:35:41, mmenke wrot
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ trace_net_log_observer_->StopWatchForTraceStart();
+ net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ net_log_->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+
+ const DictionaryValue* item1 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
+ const DictionaryValue* item2 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
+ const DictionaryValue* item3 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB));
+ EXPECT_TRUE(item1);
+ EXPECT_FALSE(item2);
+ EXPECT_FALSE(item3);
+} **/
+
+TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) {
+ trace_net_log_observer_->WatchForTraceStart(net_log_.get());
+ EnableTraceLog();
+ NetLog::ParametersCallback net_log_callback;
+ std::string param = "bar";
+ net_log_callback = NetLog::StringCallback("foo",
+ &param);
+
+ net_log_->AddGlobalEntry(NetLog::TYPE_CANCELLED, net_log_callback);
+ net_log_->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+
+ EndTraceAndFlush();
+
+ const DictionaryValue* item1 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_CANCELLED));
+ EXPECT_TRUE(item1);
+ const DictionaryValue* item1_args = NULL;
+ item1->GetDictionary("args", &item1_args);
+ EXPECT_TRUE(item1_args);
+ const DictionaryValue* item1_value = NULL;
+ item1_args->GetDictionary("value", &item1_value);
+ EXPECT_TRUE(item1_value);
+ const DictionaryValue* item1_params = NULL;
+ item1_value->GetDictionary("params", &item1_params);
+ EXPECT_TRUE(item1_params);
+ std::string actual_value;
+ item1_params->GetString("foo", &actual_value);
+ EXPECT_EQ("bar", actual_value);
mmenke 2014/08/21 15:35:41 Dictionaries support recursion, I believe, so this
xunjieli 2014/08/22 17:20:11 Done. Thanks for letting me know!
+
+ const DictionaryValue* item2 = FindTraceEntry(
+ trace_parsed_,
+ NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE));
+ EXPECT_TRUE(item2);
+ const DictionaryValue* item2_args = NULL;
+ item2->GetDictionary("args", &item2_args);
+ EXPECT_TRUE(item2_args);
+ const DictionaryValue* item2_value = NULL;
+ item2_args->GetDictionary("value", &item2_value);
+ EXPECT_TRUE(item2_value);
+ const DictionaryValue* item2_params = NULL;
+ item2_value->GetDictionary("params", &item2_params);
+ EXPECT_FALSE(item2_params);
+}
mmenke 2014/08/21 15:35:40 nit: Blank line before ending a namespace.
xunjieli 2014/08/22 17:20:12 Done.
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698