summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-21 20:45:10 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-21 20:45:10 +0000
commitbf6c087a98c4f6ce40f233dbf20f23b4722315da (patch)
tree790f8c75b69027f6b4c59e7ab421e371697b1a6b /net/base
parent37ee9fd744eaa36d4458e6f8029812e6d891ad1b (diff)
downloadchromium_src-bf6c087a98c4f6ce40f233dbf20f23b4722315da.zip
chromium_src-bf6c087a98c4f6ce40f233dbf20f23b4722315da.tar.gz
chromium_src-bf6c087a98c4f6ce40f233dbf20f23b4722315da.tar.bz2
Extend LoadLog to support logging of arbitrary strings, and of network error codes.
- The logging of error codes is intended to be used in passive mode. - The logging of string messages is intended to be used when in full-logging mode. - The logging of string literal messages is intended to be used in passive mode. BUG=27552 Review URL: http://codereview.chromium.org/503066 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35103 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r--net/base/host_resolver_impl_unittest.cc10
-rw-r--r--net/base/load_log.cc16
-rw-r--r--net/base/load_log.h116
-rw-r--r--net/base/load_log_unittest.cc87
-rw-r--r--net/base/load_log_unittest.h45
-rw-r--r--net/base/load_log_util.cc99
-rw-r--r--net/base/load_log_util_unittest.cc99
7 files changed, 331 insertions, 141 deletions
diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc
index 5453d77..09436e3 100644
--- a/net/base/host_resolver_impl_unittest.cc
+++ b/net/base/host_resolver_impl_unittest.cc
@@ -192,7 +192,7 @@ TEST_F(HostResolverImplTest, SynchronousLookup) {
int err = host_resolver->Resolve(info, &adrlist, NULL, NULL, log);
EXPECT_EQ(OK, err);
- EXPECT_EQ(2u, log->events().size());
+ EXPECT_EQ(2u, log->entries().size());
ExpectLogContains(log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL,
LoadLog::PHASE_BEGIN);
ExpectLogContains(log, 1, LoadLog::TYPE_HOST_RESOLVER_IMPL,
@@ -224,7 +224,7 @@ TEST_F(HostResolverImplTest, AsynchronousLookup) {
int err = host_resolver->Resolve(info, &adrlist, &callback_, NULL, log);
EXPECT_EQ(ERR_IO_PENDING, err);
- EXPECT_EQ(1u, log->events().size());
+ EXPECT_EQ(1u, log->entries().size());
ExpectLogContains(log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL,
LoadLog::PHASE_BEGIN);
@@ -233,7 +233,7 @@ TEST_F(HostResolverImplTest, AsynchronousLookup) {
ASSERT_TRUE(callback_called_);
ASSERT_EQ(OK, callback_result_);
- EXPECT_EQ(2u, log->events().size());
+ EXPECT_EQ(2u, log->entries().size());
ExpectLogContains(log, 1, LoadLog::TYPE_HOST_RESOLVER_IMPL,
LoadLog::PHASE_END);
@@ -271,7 +271,7 @@ TEST_F(HostResolverImplTest, CanceledAsynchronousLookup) {
resolver_proc->Signal();
- EXPECT_EQ(3u, log->events().size());
+ EXPECT_EQ(3u, log->entries().size());
ExpectLogContains(log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL,
LoadLog::PHASE_BEGIN);
ExpectLogContains(log, 1, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
@@ -825,7 +825,7 @@ TEST_F(HostResolverImplTest, Observers) {
int rv = host_resolver->Resolve(info1, &addrlist, NULL, NULL, log);
EXPECT_EQ(OK, rv);
- EXPECT_EQ(6u, log->events().size());
+ EXPECT_EQ(6u, log->entries().size());
ExpectLogContains(log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL,
LoadLog::PHASE_BEGIN);
ExpectLogContains(log, 1, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
diff --git a/net/base/load_log.cc b/net/base/load_log.cc
index 451d4e3..ec7f59b 100644
--- a/net/base/load_log.cc
+++ b/net/base/load_log.cc
@@ -22,26 +22,26 @@ const char* LoadLog::EventTypeToString(EventType event) {
return NULL;
}
-void LoadLog::Add(const Event& event) {
+void LoadLog::Add(const Entry& entry) {
// Minor optimization. TODO(eroman): use StackVector instead.
- if (events_.empty())
- events_.reserve(10); // It is likely we will have at least 10 entries.
+ if (entries_.empty())
+ entries_.reserve(10); // It is likely we will have at least 10 entries.
// Enforce a bound of |max_num_entries_| -- once we reach it, keep overwriting
// the final entry in the log.
- if (events_.size() + 1 <= max_num_entries_ ||
+ if (entries_.size() + 1 <= max_num_entries_ ||
max_num_entries_ == kUnbounded) {
- events_.push_back(event);
+ entries_.push_back(entry);
} else {
num_entries_truncated_ += 1;
- events_[max_num_entries_ - 1] = event;
+ entries_[max_num_entries_ - 1] = entry;
}
}
void LoadLog::Append(const LoadLog* log) {
- for (size_t i = 0; i < log->events().size(); ++i)
- Add(log->events()[i]);
+ for (size_t i = 0; i < log->entries().size(); ++i)
+ Add(log->entries()[i]);
num_entries_truncated_ += log->num_entries_truncated();
}
diff --git a/net/base/load_log.h b/net/base/load_log.h
index 3f433ac..8553f8b 100644
--- a/net/base/load_log.h
+++ b/net/base/load_log.h
@@ -5,6 +5,7 @@
#ifndef NET_BASE_LOAD_LOG_H_
#define NET_BASE_LOAD_LOG_H_
+#include <string>
#include <vector>
#include "base/ref_counted.h"
@@ -12,53 +13,94 @@
namespace net {
-// LoadLog stores profiling information on where time was spent while servicing
-// a request (waiting in queues, resolving hosts, resolving proxy, etc...).
+// LoadLog stores information associated with an individual request. This
+// includes event traces (used to build up profiling information), error
+// return codes from network modules, and arbitrary text messages.
//
// Note that LoadLog is NOT THREADSAFE, however it is RefCountedThreadSafe so
// that it can be AddRef() / Release() across threads.
class LoadLog : public base::RefCountedThreadSafe<LoadLog> {
public:
+ // TODO(eroman): Really, EventType and EventPhase should be
+ // Event::Type and Event::Phase, to be consisent with Entry.
+ // But there lots of consumers to change!
enum EventType {
#define EVENT_TYPE(label) TYPE_ ## label,
#include "net/base/load_log_event_type_list.h"
#undef EVENT_TYPE
};
- // Whether this is the start/end of an event. Or in the case of EventTypes
- // that are "instantaneous", kNone.
+ // The 'phase' of an event trace (whether it marks the beginning or end
+ // of an event.).
enum EventPhase {
PHASE_NONE,
PHASE_BEGIN,
+ // TODO(eroman): DEPRECATED: Use TYPE_STRING_LITERAL instead.
PHASE_END,
};
- // A logged event. Note that "phase" means if this is the start/end of a
- // particular event type (in order to record a timestamp for both endpoints).
struct Event {
- Event(base::TimeTicks time,
- EventType type,
- EventPhase phase)
- : time(time), type(type), phase(phase) {
- }
+ Event(EventType type, EventPhase phase) : type(type), phase(phase) {}
+ Event() {}
- base::TimeTicks time;
EventType type;
EventPhase phase;
};
- // Ordered set of events that were logged.
+ struct Entry {
+ enum Type {
+ // This entry describes an event trace.
+ TYPE_EVENT,
+
+ // This entry describes a network error code that was returned.
+ TYPE_ERROR_CODE,
+
+ // This entry is a free-form std::string.
+ TYPE_STRING,
+
+ // This entry is a C-string literal.
+ TYPE_STRING_LITERAL,
+ };
+
+ Entry(base::TimeTicks time, int error_code)
+ : type(TYPE_ERROR_CODE), time(time), error_code(error_code) {
+ }
+
+ Entry(base::TimeTicks time, const Event& event)
+ : type(TYPE_EVENT), time(time), event(event) {
+ }
+
+ Entry(base::TimeTicks time, const std::string& string)
+ : type(TYPE_STRING), time(time), string(string) {
+ }
+
+ Entry(base::TimeTicks time, const char* literal)
+ : type(TYPE_STRING_LITERAL), time(time), literal(literal) {
+ }
+
+ Type type;
+ base::TimeTicks time;
+
+ // The following is basically a union, only one of them should be
+ // used depending on what |type| is.
+ Event event; // valid when (type == TYPE_EVENT).
+ int error_code; // valid when (type == TYPE_ERROR_CODE).
+ std::string string; // valid when (type == TYPE_STRING).
+ const char* literal; // valid when (type == TYPE_STRING_LITERAL).
+ };
+
+ // Ordered set of entries that were logged.
// TODO(eroman): use a StackVector or array to avoid allocations.
- typedef std::vector<Event> EventList;
+ typedef std::vector<Entry> EntryList;
// Value for max_num_entries to indicate the LoadLog has no size limit.
static const size_t kUnbounded = static_cast<size_t>(-1);
- // Creates a log, which can hold up to |max_num_entries| Events.
+ // Creates a log, which can hold up to |max_num_entries| entries.
// If |max_num_entries| is |kUnbounded|, then the log can grow arbitrarily
// large.
//
- // If events are dropped because the log has grown too large, the final entry
+ // If entries are dropped because the log has grown too large, the final entry
// will be overwritten.
explicit LoadLog(size_t max_num_entries);
@@ -68,30 +110,38 @@ class LoadLog : public base::RefCountedThreadSafe<LoadLog> {
// This makes it easier to deal with optionally NULL LoadLog.
// Adds an instantaneous event to the log.
- static void AddEvent(LoadLog* log, EventType event) {
+ // TODO(eroman): DEPRECATED: use AddStringLiteral() instead.
+ static void AddEvent(LoadLog* log, EventType event_type) {
if (log)
- log->Add(base::TimeTicks::Now(), event, PHASE_NONE);
+ log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_NONE)));
}
// Adds the start of an event to the log. Presumably this event type measures
- // a time duration, and will be matched by a call to EndEvent(event).
- static void BeginEvent(LoadLog* log, EventType event) {
+ // a time duration, and will be matched by a call to EndEvent(event_type).
+ static void BeginEvent(LoadLog* log, EventType event_type) {
if (log)
- log->Add(base::TimeTicks::Now(), event, PHASE_BEGIN);
+ log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_BEGIN)));
}
// Adds the end of an event to the log. Presumably this event type measures
- // a time duration, and we are matching an earlier call to BeginEvent(event).
- static void EndEvent(LoadLog* log, EventType event) {
+ // a time duration, and we are matching an earlier call to
+ // BeginEvent(event_type).
+ static void EndEvent(LoadLog* log, EventType event_type) {
if (log)
- log->Add(base::TimeTicks::Now(), event, PHASE_END);
+ log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_END)));
+ }
+
+ // |literal| should be a string literal (i.e. lives in static storage).
+ static void AddStringLiteral(LoadLog* log, const char* literal) {
+ if (log)
+ log->Add(Entry(base::TimeTicks::Now(), literal));
}
// --------------------------------------------------------------------------
- // Returns the list of all events in the log.
- const EventList& events() const {
- return events_;
+ // Returns the list of all entries in the log.
+ const EntryList& entries() const {
+ return entries_;
}
// Returns the number of entries that were dropped from the log because the
@@ -106,15 +156,11 @@ class LoadLog : public base::RefCountedThreadSafe<LoadLog> {
}
// Returns a C-String symbolic name for |event|.
- static const char* EventTypeToString(EventType event);
+ static const char* EventTypeToString(EventType event_type);
- void Add(const Event& event);
-
- void Add(base::TimeTicks t, EventType event, EventPhase phase) {
- Add(Event(t, event, phase));
- }
+ void Add(const Entry& entry);
- // Copies all events from |log|, appending it to the end of |this|.
+ // Copies all entries from |log|, appending it to the end of |this|.
void Append(const LoadLog* log);
private:
@@ -122,7 +168,7 @@ class LoadLog : public base::RefCountedThreadSafe<LoadLog> {
~LoadLog() {}
- EventList events_;
+ EntryList entries_;
size_t num_entries_truncated_;
size_t max_num_entries_;;
};
diff --git a/net/base/load_log_unittest.cc b/net/base/load_log_unittest.cc
index a3db7bb..d3f5ed5 100644
--- a/net/base/load_log_unittest.cc
+++ b/net/base/load_log_unittest.cc
@@ -21,17 +21,24 @@ TEST(LoadLogTest, Basic) {
scoped_refptr<LoadLog> log(new LoadLog(10));
// Logs start off empty.
- EXPECT_EQ(0u, log->events().size());
+ EXPECT_EQ(0u, log->entries().size());
EXPECT_EQ(0u, log->num_entries_truncated());
// Add 3 entries.
- log->Add(MakeTime(0), LoadLog::TYPE_HOST_RESOLVER_IMPL, LoadLog::PHASE_BEGIN);
- log->Add(MakeTime(2), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log->Add(MakeTime(11), LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
- LoadLog::PHASE_END);
-
- EXPECT_EQ(3u, log->events().size());
+ log->Add(LoadLog::Entry(MakeTime(0),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_BEGIN)));
+ log->Add(LoadLog::Entry(MakeTime(2),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+ log->Add(
+ LoadLog::Entry(
+ MakeTime(11),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
+ LoadLog::PHASE_END)));
+
+ EXPECT_EQ(3u, log->entries().size());
EXPECT_EQ(0u, log->num_entries_truncated());
ExpectLogContains(log, 0, MakeTime(0), LoadLog::TYPE_HOST_RESOLVER_IMPL,
@@ -52,10 +59,12 @@ TEST(LoadLogTest, Truncation) {
// Max it out.
for (size_t i = 0; i < kMaxNumEntries; ++i) {
- log->Add(MakeTime(i), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
+ log->Add(LoadLog::Entry(MakeTime(i),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
}
- EXPECT_EQ(kMaxNumEntries, log->events().size());
+ EXPECT_EQ(kMaxNumEntries, log->entries().size());
EXPECT_EQ(0u, log->num_entries_truncated());
// Check the last entry.
@@ -64,11 +73,17 @@ TEST(LoadLogTest, Truncation) {
LoadLog::PHASE_NONE);
// Add three entries while maxed out (will cause truncation)
- log->Add(MakeTime(0), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log->Add(MakeTime(1), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log->Add(MakeTime(2), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
-
- EXPECT_EQ(kMaxNumEntries, log->events().size());
+ log->Add(LoadLog::Entry(MakeTime(0),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+ log->Add(LoadLog::Entry(MakeTime(1),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+ log->Add(LoadLog::Entry(MakeTime(2),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+
+ EXPECT_EQ(kMaxNumEntries, log->entries().size());
EXPECT_EQ(3u, log->num_entries_truncated());
// Check the last entry -- it should be the final entry we added.
@@ -81,18 +96,25 @@ TEST(LoadLogTest, Append) {
scoped_refptr<LoadLog> log1(new LoadLog(10));
scoped_refptr<LoadLog> log2(new LoadLog(10));
- log1->Add(MakeTime(0), LoadLog::TYPE_HOST_RESOLVER_IMPL,
- LoadLog::PHASE_BEGIN);
+ log1->Add(LoadLog::Entry(MakeTime(0),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_BEGIN)));
- log2->Add(MakeTime(3), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log2->Add(MakeTime(9), LoadLog::TYPE_HOST_RESOLVER_IMPL, LoadLog::PHASE_END);
+ log2->Add(LoadLog::Entry(MakeTime(3),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+ log2->Add(LoadLog::Entry(MakeTime(9),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_END)));
log1->Append(log2);
// Add something else to log2 (should NOT be reflected in log1).
- log2->Add(MakeTime(19), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
+ log2->Add(LoadLog::Entry(MakeTime(19),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
- EXPECT_EQ(3u, log1->events().size());
+ EXPECT_EQ(3u, log1->entries().size());
EXPECT_EQ(0u, log1->num_entries_truncated());
ExpectLogContains(log1, 0, MakeTime(0), LoadLog::TYPE_HOST_RESOLVER_IMPL,
@@ -114,15 +136,19 @@ TEST(LoadLogTest, AppendWithTruncation) {
scoped_refptr<LoadLog> log1(new LoadLog(kMaxNumEntries));
scoped_refptr<LoadLog> log2(new LoadLog(kMaxNumEntries));
for (size_t i = 0; i < 6; ++i) {
- log1->Add(MakeTime(i), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log2->Add(MakeTime(2 * i), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
+ log1->Add(LoadLog::Entry(MakeTime(i),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+ log2->Add(LoadLog::Entry(MakeTime(2 * i),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
}
// Append log2 to log1.
log1->Append(log2);
// The combined log totalled 12 entries, so 2 must have been dropped.
- EXPECT_EQ(10u, log1->events().size());
+ EXPECT_EQ(10u, log1->entries().size());
EXPECT_EQ(2u, log1->num_entries_truncated());
// Combined log should end with the final entry of log2.
@@ -138,5 +164,20 @@ TEST(LoadLogTest, EventTypeToString) {
LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART));
}
+TEST(LoadLogTest, String) {
+ scoped_refptr<LoadLog> log(new LoadLog(10));
+
+ // Make sure that AddStringLiteral() adds a literal and not a std::string.
+ // (in case there is any funny-business with implicit conversions).
+ LoadLog::AddStringLiteral(log, "This is a literal");
+ log->Add(LoadLog::Entry(MakeTime(0), "Another literal"));
+ log->Add(LoadLog::Entry(MakeTime(0), std::string("Now a std::string")));
+
+ ASSERT_EQ(3u, log->entries().size());
+ EXPECT_EQ(LoadLog::Entry::TYPE_STRING_LITERAL, log->entries()[0].type);
+ EXPECT_EQ(LoadLog::Entry::TYPE_STRING_LITERAL, log->entries()[1].type);
+ EXPECT_EQ(LoadLog::Entry::TYPE_STRING, log->entries()[2].type);
+}
+
} // namespace
} // namespace net
diff --git a/net/base/load_log_unittest.h b/net/base/load_log_unittest.h
index 6f0cb45..ea9a37d 100644
--- a/net/base/load_log_unittest.h
+++ b/net/base/load_log_unittest.h
@@ -25,10 +25,12 @@ inline void ExpectLogContains(const LoadLog* log,
base::TimeTicks expected_time,
LoadLog::EventType expected_event,
LoadLog::EventPhase expected_phase) {
- ASSERT_LT(i, log->events().size());
- EXPECT_TRUE(expected_time == log->events()[i].time);
- EXPECT_EQ(expected_event, log->events()[i].type);
- EXPECT_EQ(expected_phase, log->events()[i].phase);
+ ASSERT_LT(i, log->entries().size());
+ const LoadLog::Entry& entry = log->entries()[i];
+ EXPECT_EQ(LoadLog::Entry::TYPE_EVENT, entry.type);
+ EXPECT_TRUE(expected_time == entry.time);
+ EXPECT_EQ(expected_event, entry.event.type);
+ EXPECT_EQ(expected_phase, entry.event.phase);
}
// Same as above, but without an expectation for the timestamp.
@@ -36,9 +38,11 @@ inline void ExpectLogContains(const LoadLog* log,
size_t i,
LoadLog::EventType expected_event,
LoadLog::EventPhase expected_phase) {
- ASSERT_LT(i, log->events().size());
- EXPECT_EQ(expected_event, log->events()[i].type);
- EXPECT_EQ(expected_phase, log->events()[i].phase);
+ ASSERT_LT(i, log->entries().size());
+ const LoadLog::Entry& entry = log->entries()[i];
+ EXPECT_EQ(LoadLog::Entry::TYPE_EVENT, entry.type);
+ EXPECT_EQ(expected_event, entry.event.type);
+ EXPECT_EQ(expected_phase, entry.event.phase);
}
inline ::testing::AssertionResult LogContains(
@@ -47,18 +51,22 @@ inline ::testing::AssertionResult LogContains(
LoadLog::EventType expected_event,
LoadLog::EventPhase expected_phase) {
// Negative indices are reverse indices.
- size_t j = (i < 0) ? log.events().size() + i : i;
- if (j >= log.events().size())
+ size_t j = (i < 0) ? log.entries().size() + i : i;
+ if (j >= log.entries().size())
return ::testing::AssertionFailure() << j << " is out of bounds.";
- if (expected_event != log.events()[j].type) {
+ const LoadLog::Entry& entry = log.entries()[j];
+ if (entry.type != LoadLog::Entry::TYPE_EVENT) {
+ return ::testing::AssertionFailure() << "Not a TYPE_EVENT entry";
+ }
+ if (expected_event != entry.event.type) {
return ::testing::AssertionFailure()
- << "Actual event: " << LoadLog::EventTypeToString(log.events()[j].type)
+ << "Actual event: " << LoadLog::EventTypeToString(entry.event.type)
<< ". Expected event: " << LoadLog::EventTypeToString(expected_event)
<< ".";
}
- if (expected_phase != log.events()[j].phase) {
+ if (expected_phase != entry.event.phase) {
return ::testing::AssertionFailure()
- << "Actual phase: " << log.events()[j].phase
+ << "Actual phase: " << entry.event.phase
<< ". Expected phase: " << expected_phase << ".";
}
return ::testing::AssertionSuccess();
@@ -72,11 +80,14 @@ inline size_t ExpectLogContainsSomewhere(const LoadLog* log,
LoadLog::EventType expected_event,
LoadLog::EventPhase expected_phase) {
size_t i = 0;
- for (; i < log->events().size(); ++i)
- if (log->events()[i].type == expected_event &&
- log->events()[i].phase == expected_phase)
+ for (; i < log->entries().size(); ++i) {
+ const LoadLog::Entry& entry = log->entries()[i];
+ if (entry.type == LoadLog::Entry::TYPE_EVENT &&
+ entry.event.type == expected_event &&
+ entry.event.phase == expected_phase)
break;
- EXPECT_LT(i, log->events().size());
+ }
+ EXPECT_LT(i, log->entries().size());
EXPECT_GE(i, min_index);
return i;
}
diff --git a/net/base/load_log_util.cc b/net/base/load_log_util.cc
index 3905f4a..9410eb0 100644
--- a/net/base/load_log_util.cc
+++ b/net/base/load_log_util.cc
@@ -6,6 +6,7 @@
#include "base/format_macros.h"
#include "base/string_util.h"
+#include "net/base/net_errors.h"
namespace net {
namespace {
@@ -45,17 +46,17 @@ class FormatHelper {
}
int indentation_spaces = entries_[i].indentation * kSpacesPerIndentation;
- std::string event_str = GetEventString(i);
+ std::string entry_str = GetEntryString(i);
result += StringPrintf("t=%s: %s%s",
PadStringLeft(GetTimeString(i), max_time_width).c_str(),
PadStringLeft("", indentation_spaces).c_str(),
- event_str.c_str());
+ entry_str.c_str());
- if (entries_[i].event->phase == LoadLog::PHASE_BEGIN) {
+ if (entries_[i].IsBeginEvent()) {
// Summarize how long this block lasted.
int padding = ((max_indentation - entries_[i].indentation) *
- kSpacesPerIndentation) + (max_type_width - event_str.size());
+ kSpacesPerIndentation) + (max_type_width - entry_str.size());
result += StringPrintf("%s [dt=%s]",
PadStringLeft("", padding).c_str(),
PadStringLeft(GetBlockDtString(i), max_dt_width).c_str());
@@ -70,10 +71,20 @@ class FormatHelper {
private:
struct Entry {
- explicit Entry(const LoadLog::Event* event)
- : event(event), indentation(0), block_index(-1) {}
+ explicit Entry(const LoadLog::Entry* log_entry)
+ : log_entry(log_entry), indentation(0), block_index(-1) {}
- const LoadLog::Event* event;
+ bool IsBeginEvent() const {
+ return log_entry->type == LoadLog::Entry::TYPE_EVENT &&
+ log_entry->event.phase == LoadLog::PHASE_BEGIN;
+ }
+
+ bool IsEndEvent() const {
+ return log_entry->type == LoadLog::Entry::TYPE_EVENT &&
+ log_entry->event.phase == LoadLog::PHASE_END;
+ }
+
+ const LoadLog::Entry* log_entry;
size_t indentation;
int block_index; // The index of the matching start / end of block.
};
@@ -81,17 +92,17 @@ class FormatHelper {
void PopulateEntries(const LoadLog* log) {
int current_indentation = 0;
- for (size_t i = 0; i < log->events().size(); ++i) {
- Entry entry(&log->events()[i]);
+ for (size_t i = 0; i < log->entries().size(); ++i) {
+ Entry entry(&log->entries()[i]);
entry.indentation = current_indentation;
- if (entry.event->phase == LoadLog::PHASE_BEGIN) {
+ if (entry.IsBeginEvent()) {
// Indent everything contained in this block.
current_indentation++;
}
- if (entry.event->phase == LoadLog::PHASE_END) {
+ if (entry.IsEndEvent()) {
int start_index = FindStartOfBlockIndex(entry);
if (start_index != -1) {
// Point the start / end of block at each other.
@@ -110,12 +121,12 @@ class FormatHelper {
}
int FindStartOfBlockIndex(const Entry& entry) {
- DCHECK_EQ(LoadLog::PHASE_END, entry.event->phase);
+ DCHECK(entry.IsEndEvent());
// Find the matching start of block by scanning backwards.
for (int i = entries_.size() - 1; i >= 0; --i) {
- if (entries_[i].event->phase == LoadLog::PHASE_BEGIN &&
- entries_[i].event->type == entry.event->type) {
+ if (entries_[i].IsBeginEvent() &&
+ entries_[i].log_entry->event.type == entry.log_entry->event.type) {
return i;
}
}
@@ -129,10 +140,11 @@ class FormatHelper {
*max_time_width = *max_indentation = *max_type_width = *max_dt_width = 0;
for (size_t i = 0; i < entries_.size(); ++i) {
*max_time_width = std::max(*max_time_width, GetTimeString(i).size());
- *max_type_width = std::max(*max_type_width, GetEventString(i).size());
+ if (entries_[i].log_entry->type == LoadLog::Entry::TYPE_EVENT)
+ *max_type_width = std::max(*max_type_width, GetEntryString(i).size());
*max_indentation = std::max(*max_indentation, entries_[i].indentation);
- if (entries_[i].event->phase == LoadLog::PHASE_BEGIN)
+ if (entries_[i].IsBeginEvent())
*max_dt_width = std::max(*max_dt_width, GetBlockDtString(i).size());
}
}
@@ -143,39 +155,58 @@ class FormatHelper {
// Block is not closed, implicitly close it at EOF.
end_index = entries_.size() - 1;
}
- int64 dt_ms = (entries_[end_index].event->time -
- entries_[start_index].event->time).InMilliseconds();
+ int64 dt_ms = (entries_[end_index].log_entry->time -
+ entries_[start_index].log_entry->time).InMilliseconds();
return Int64ToString(dt_ms);
}
std::string GetTimeString(size_t index) {
- int64 t_ms = (entries_[index].event->time -
+ int64 t_ms = (entries_[index].log_entry->time -
base::TimeTicks()).InMilliseconds();
return Int64ToString(t_ms);
}
- std::string GetEventString(size_t index) {
- const LoadLog::Event* event = entries_[index].event;
- const char* type_str = LoadLog::EventTypeToString(event->type);
-
- LoadLog::EventPhase phase = event->phase;
-
- if (phase == LoadLog::PHASE_BEGIN &&
- index + 1 < entries_.size() &&
- static_cast<size_t>(entries_[index + 1].block_index) == index) {
- // If this starts an empty block, we will pretend it is a PHASE_NONE
- // so we don't print the "+" prefix.
- phase = LoadLog::PHASE_NONE;
+ std::string GetEntryString(size_t index) {
+ const LoadLog::Entry* entry = entries_[index].log_entry;
+
+ std::string entry_str;
+ LoadLog::EventPhase phase = LoadLog::PHASE_NONE;
+ switch (entry->type) {
+ case LoadLog::Entry::TYPE_EVENT:
+ entry_str = LoadLog::EventTypeToString(entry->event.type);
+ phase = entry->event.phase;
+
+ if (phase == LoadLog::PHASE_BEGIN &&
+ index + 1 < entries_.size() &&
+ static_cast<size_t>(entries_[index + 1].block_index) == index) {
+ // If this starts an empty block, we will pretend it is a PHASE_NONE
+ // so we don't print the "+" prefix.
+ phase = LoadLog::PHASE_NONE;
+ }
+ break;
+ case LoadLog::Entry::TYPE_ERROR_CODE:
+ entry_str = StringPrintf("error code: %d (%s)",
+ entry->error_code,
+ ErrorToString(entry->error_code));
+ break;
+ case LoadLog::Entry::TYPE_STRING:
+ entry_str = StringPrintf("\"%s\"", entry->string.c_str());
+ break;
+ case LoadLog::Entry::TYPE_STRING_LITERAL:
+ entry_str = StringPrintf("\"%s\"", entry->literal);
+ break;
+ default:
+ NOTREACHED();
}
switch (phase) {
case LoadLog::PHASE_BEGIN:
- return std::string("+") + type_str;
+ return std::string("+") + entry_str;
case LoadLog::PHASE_END:
- return std::string("-") + type_str;
+ return std::string("-") + entry_str;
case LoadLog::PHASE_NONE:
- return std::string(" ") + type_str;
+ return std::string(" ") + entry_str;
default:
NOTREACHED();
return std::string();
diff --git a/net/base/load_log_util_unittest.cc b/net/base/load_log_util_unittest.cc
index 4ca3854..7dba908 100644
--- a/net/base/load_log_util_unittest.cc
+++ b/net/base/load_log_util_unittest.cc
@@ -4,6 +4,7 @@
#include "net/base/load_log_unittest.h"
#include "net/base/load_log_util.h"
+#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -12,13 +13,27 @@ namespace {
TEST(LoadLogUtilTest, Basic) {
scoped_refptr<LoadLog> log(new LoadLog(10));
- log->Add(MakeTime(1), LoadLog::TYPE_HOST_RESOLVER_IMPL, LoadLog::PHASE_BEGIN);
- log->Add(MakeTime(5), LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
- LoadLog::PHASE_BEGIN);
- log->Add(MakeTime(8), LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
- LoadLog::PHASE_END);
- log->Add(MakeTime(12), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log->Add(MakeTime(131), LoadLog::TYPE_HOST_RESOLVER_IMPL, LoadLog::PHASE_END);
+ log->Add(LoadLog::Entry(MakeTime(1),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_BEGIN)));
+ log->Add(
+ LoadLog::Entry(
+ MakeTime(5),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
+ LoadLog::PHASE_BEGIN)));
+ log->Add(
+ LoadLog::Entry(
+ MakeTime(8),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
+ LoadLog::PHASE_END)));
+
+ log->Add(LoadLog::Entry(MakeTime(12),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+
+ log->Add(LoadLog::Entry(MakeTime(131),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_END)));
EXPECT_EQ(
"t= 1: +HOST_RESOLVER_IMPL [dt=130]\n"
@@ -28,19 +43,59 @@ TEST(LoadLogUtilTest, Basic) {
LoadLogUtil::PrettyPrintAsEventTree(log));
}
+TEST(LoadLogUtilTest, Basic2) {
+ scoped_refptr<LoadLog> log(new LoadLog(10));
+
+ log->Add(LoadLog::Entry(MakeTime(1),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_BEGIN)));
+
+ log->Add(LoadLog::Entry(MakeTime(12), "Sup foo"));
+ log->Add(LoadLog::Entry(MakeTime(12), ERR_UNEXPECTED));
+ log->Add(LoadLog::Entry(MakeTime(14), "Multiline\nString"));
+
+ log->Add(LoadLog::Entry(MakeTime(131),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_END)));
+
+ EXPECT_EQ(
+ "t= 1: +HOST_RESOLVER_IMPL [dt=130]\n"
+ "t= 12: \"Sup foo\"\n"
+ "t= 12: error code: -9 (net::ERR_UNEXPECTED)\n"
+ "t= 14: \"Multiline\n"
+ "String\"\n"
+ "t=131: -HOST_RESOLVER_IMPL",
+ LoadLogUtil::PrettyPrintAsEventTree(log));
+}
+
TEST(LoadLogUtilTest, UnmatchedOpen) {
scoped_refptr<LoadLog> log(new LoadLog(10));
- log->Add(MakeTime(3), LoadLog::TYPE_HOST_RESOLVER_IMPL, LoadLog::PHASE_BEGIN);
+ log->Add(LoadLog::Entry(MakeTime(3),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_BEGIN)));
// Note that there is no matching call to PHASE_END for all of the following.
- log->Add(MakeTime(6), LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
- LoadLog::PHASE_BEGIN);
- log->Add(MakeTime(7), LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
- LoadLog::PHASE_BEGIN);
- log->Add(MakeTime(8), LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
- LoadLog::PHASE_BEGIN);
- log->Add(MakeTime(10), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
- log->Add(MakeTime(16), LoadLog::TYPE_HOST_RESOLVER_IMPL, LoadLog::PHASE_END);
+ log->Add(
+ LoadLog::Entry(
+ MakeTime(6),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
+ LoadLog::PHASE_BEGIN)));
+ log->Add(
+ LoadLog::Entry(
+ MakeTime(7),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
+ LoadLog::PHASE_BEGIN)));
+ log->Add(
+ LoadLog::Entry(
+ MakeTime(8),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART,
+ LoadLog::PHASE_BEGIN)));
+ log->Add(LoadLog::Entry(MakeTime(10),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
+ log->Add(LoadLog::Entry(MakeTime(16),
+ LoadLog::Event(LoadLog::TYPE_HOST_RESOLVER_IMPL,
+ LoadLog::PHASE_END)));
EXPECT_EQ(
"t= 3: +HOST_RESOLVER_IMPL [dt=13]\n"
@@ -57,11 +112,17 @@ TEST(LoadLogUtilTest, DisplayOfTruncated) {
scoped_refptr<LoadLog> log(new LoadLog(kMaxNumEntries));
// Add a total of 10 events. This means that 5 will be truncated.
- log->Add(MakeTime(0), LoadLog::TYPE_TCP_CONNECT, LoadLog::PHASE_BEGIN);
+ log->Add(LoadLog::Entry(MakeTime(0),
+ LoadLog::Event(LoadLog::TYPE_TCP_CONNECT,
+ LoadLog::PHASE_BEGIN)));
for (size_t i = 1; i < 8; ++i) {
- log->Add(MakeTime(i), LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
+ log->Add(LoadLog::Entry(MakeTime(i),
+ LoadLog::Event(LoadLog::TYPE_CANCELLED,
+ LoadLog::PHASE_NONE)));
}
- log->Add(MakeTime(9), LoadLog::TYPE_TCP_CONNECT, LoadLog::PHASE_END);
+ log->Add(LoadLog::Entry(MakeTime(9),
+ LoadLog::Event(LoadLog::TYPE_TCP_CONNECT,
+ LoadLog::PHASE_END)));
EXPECT_EQ(
"t=0: +TCP_CONNECT [dt=9]\n"