Commit 16354054 authored by klm@google.com's avatar klm@google.com

C++ readability review from original change https://chromiumcodereview.appspot.com/14263024/

Review bug: http://b/8772053

Review URL: https://chromiumcodereview.appspot.com/14591005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204053 0039d316-1c4b-4281-b951-d872f2087c98
parent 0f0e9772
...@@ -4,10 +4,9 @@ ...@@ -4,10 +4,9 @@
#include "chrome/test/chromedriver/chrome/console_logger.h" #include "chrome/test/chromedriver/chrome/console_logger.h"
#include <sstream>
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/string_util.h" #include "base/logging.h"
#include "base/stringprintf.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/devtools_client.h"
#include "chrome/test/chromedriver/chrome/log.h" #include "chrome/test/chromedriver/chrome/log.h"
...@@ -15,14 +14,15 @@ ...@@ -15,14 +14,15 @@
namespace { namespace {
// Translates Console.messageAdded.message.level into Log::Level.
bool ConsoleLevelToLogLevel(const std::string& name, Log::Level *out_level) { bool ConsoleLevelToLogLevel(const std::string& name, Log::Level *out_level) {
const char* kConsoleLevelNames[] = { const char* const kConsoleLevelNames[] = {
"debug", "log", "warning", "error" "debug", "log", "warning", "error"
}; };
for (size_t i = 0; i < arraysize(kConsoleLevelNames); ++i) { for (size_t i = 0; i < arraysize(kConsoleLevelNames); ++i) {
if (name == kConsoleLevelNames[i]) { if (name == kConsoleLevelNames[i]) {
CHECK(Log::kDebug + i <= Log::kError); CHECK_LE(Log::kDebug + i, static_cast<size_t>(Log::kError));
*out_level = static_cast<Log::Level>(Log::kDebug + i); *out_level = static_cast<Log::Level>(Log::kDebug + i);
return true; return true;
} }
...@@ -40,53 +40,54 @@ Status ConsoleLogger::OnConnected(DevToolsClient* client) { ...@@ -40,53 +40,54 @@ Status ConsoleLogger::OnConnected(DevToolsClient* client) {
return client->SendCommand("Console.enable", params); return client->SendCommand("Console.enable", params);
} }
Status ConsoleLogger::OnEvent(DevToolsClient* client, Status ConsoleLogger::OnEvent(
DevToolsClient* client,
const std::string& method, const std::string& method,
const base::DictionaryValue& params) { const base::DictionaryValue& params) {
if (!StartsWithASCII(method, "Console.messageAdded", true)) if (method != "Console.messageAdded")
return Status(kOk); return Status(kOk);
// If the event has proper structure and fields, log formatted. // If the event has proper structure and fields, log formatted.
// Else it's a weird message that we don't know how to format, log full JSON. // Else it's a weird message that we don't know how to format, log full JSON.
const base::DictionaryValue *message_dict = NULL; const base::DictionaryValue *message_dict = NULL;
if (params.GetDictionary("message", &message_dict)) { if (params.GetDictionary("message", &message_dict)) {
std::ostringstream message; std::string text;
std::string level_name;
Log::Level level = Log::kLog;
if (message_dict->GetString("text", &text) && !text.empty() &&
message_dict->GetString("level", &level_name) &&
ConsoleLevelToLogLevel(level_name, &level)) {
const char* origin_cstr = "unknown";
std::string origin; std::string origin;
if (message_dict->GetString("url", &origin) && !origin.empty()) { if ((message_dict->GetString("url", &origin) && !origin.empty()) ||
message << origin; (message_dict->GetString("source", &origin) && !origin.empty())) {
} else if (message_dict->GetString("source", &origin) && !origin.empty()) { origin_cstr = origin.c_str();
message << origin;
} else {
message << "unknown";
} }
std::string line_column;
int line = -1; int line = -1;
if (message_dict->GetInteger("line", &line)) { if (message_dict->GetInteger("line", &line)) {
message << " " << line;
int column = -1; int column = -1;
if (message_dict->GetInteger("column", &column)) { if (message_dict->GetInteger("column", &column)) {
message << ":" << column; base::SStringPrintf(&line_column, "%d:%d", line, column);
} else {
base::SStringPrintf(&line_column, "%d", line);
} }
} else { } else {
// No line number, but print anyway, just to maintain the number of // No line number, but print anyway, just to maintain the number of
// fields in the formatted message in case someone wants to parse it. // fields in the formatted message in case someone wants to parse it.
message << " -"; line_column = "-";
} }
std::string text; log_->AddEntry(level,
if (message_dict->GetString("text", &text)) { base::StringPrintf("%s %s %s",
message << " " << text; origin_cstr,
line_column.c_str(),
std::string level_name; text.c_str()));
Log::Level level = Log::kLog;
if (message_dict->GetString("level", &level_name)) {
if (ConsoleLevelToLogLevel(level_name, &level)) {
log_->AddEntry(level, message.str()); // Found all expected fields.
return Status(kOk); return Status(kOk);
} }
} }
}
}
// Don't know how to format, log full JSON. // Don't know how to format, log full JSON.
std::string message_json; std::string message_json;
......
...@@ -19,15 +19,19 @@ class Log; ...@@ -19,15 +19,19 @@ class Log;
// Translates the level into Log::Level, drops all other fields. // Translates the level into Log::Level, drops all other fields.
class ConsoleLogger : public DevToolsEventListener { class ConsoleLogger : public DevToolsEventListener {
public: public:
// Creates a ConsoleLogger that creates entries in the given Log object.
// The log is owned elsewhere and must not be null.
explicit ConsoleLogger(Log* log); explicit ConsoleLogger(Log* log);
// Enables Console events for the client, which must not be null.
virtual Status OnConnected(DevToolsClient* client) OVERRIDE; virtual Status OnConnected(DevToolsClient* client) OVERRIDE;
// Translates an event into a log entry.
virtual Status OnEvent(DevToolsClient* client, virtual Status OnEvent(DevToolsClient* client,
const std::string& method, const std::string& method,
const base::DictionaryValue& params) OVERRIDE; const base::DictionaryValue& params) OVERRIDE;
private: private:
Log* log_; Log* log_; // The log where to create entries.
DISALLOW_COPY_AND_ASSIGN(ConsoleLogger); DISALLOW_COPY_AND_ASSIGN(ConsoleLogger);
}; };
......
...@@ -18,7 +18,8 @@ namespace { ...@@ -18,7 +18,8 @@ namespace {
class FakeDevToolsClient : public StubDevToolsClient { class FakeDevToolsClient : public StubDevToolsClient {
public: public:
explicit FakeDevToolsClient(const std::string& id) : id_(id) {} explicit FakeDevToolsClient(const std::string& id)
: id_(id), listener_(NULL) {}
virtual ~FakeDevToolsClient() {} virtual ~FakeDevToolsClient() {}
std::string PopSentCommand() { std::string PopSentCommand() {
...@@ -49,6 +50,7 @@ class FakeDevToolsClient : public StubDevToolsClient { ...@@ -49,6 +50,7 @@ class FakeDevToolsClient : public StubDevToolsClient {
} }
virtual void AddListener(DevToolsEventListener* listener) OVERRIDE { virtual void AddListener(DevToolsEventListener* listener) OVERRIDE {
CHECK(!listener_);
listener_ = listener; listener_ = listener;
} }
...@@ -57,9 +59,9 @@ class FakeDevToolsClient : public StubDevToolsClient { ...@@ -57,9 +59,9 @@ class FakeDevToolsClient : public StubDevToolsClient {
} }
private: private:
const std::string id_; const std::string id_; // WebView id.
std::list<std::string> sent_command_queue_; std::list<std::string> sent_command_queue_; // Commands that were sent.
DevToolsEventListener* listener_; DevToolsEventListener* listener_; // The fake allows only one event listener.
}; };
struct LogEntry { struct LogEntry {
...@@ -75,24 +77,29 @@ struct LogEntry { ...@@ -75,24 +77,29 @@ struct LogEntry {
class FakeLog : public Log { class FakeLog : public Log {
public: public:
virtual void AddEntry(const base::Time& time, virtual void AddEntryTimestamped(const base::Time& timestamp,
Level level, Level level,
const std::string& message) OVERRIDE; const std::string& message) OVERRIDE;
ScopedVector<LogEntry> entries; const ScopedVector<LogEntry>& GetEntries() {
return entries_;
}
private:
ScopedVector<LogEntry> entries_;
}; };
void FakeLog::AddEntry( void FakeLog::AddEntryTimestamped(
const base::Time& time, Level level, const std::string& message) { const base::Time& timestamp, Level level, const std::string& message) {
entries.push_back(new LogEntry(time, level, message)); entries_.push_back(new LogEntry(timestamp, level, message));
} }
void ValidateLogEntry(LogEntry *entry, void ValidateLogEntry(const LogEntry *entry,
Log::Level expect_level, Log::Level expected_level,
const char* expect_message) { const std::string& expected_message) {
EXPECT_EQ(expect_level, entry->level); EXPECT_EQ(expected_level, entry->level);
EXPECT_LT(0, entry->timestamp.ToTimeT()); EXPECT_LT(0, entry->timestamp.ToTimeT());
EXPECT_STREQ(expect_message, entry->message.c_str()); EXPECT_EQ(expected_message, entry->message);
} }
void ConsoleLogParams(base::DictionaryValue* out_params, void ConsoleLogParams(base::DictionaryValue* out_params,
...@@ -102,17 +109,17 @@ void ConsoleLogParams(base::DictionaryValue* out_params, ...@@ -102,17 +109,17 @@ void ConsoleLogParams(base::DictionaryValue* out_params,
int line, int line,
int column, int column,
const char* text) { const char* text) {
if (NULL != source) if (source != NULL)
out_params->SetString("message.source", source); out_params->SetString("message.source", source);
if (NULL != url) if (url != NULL)
out_params->SetString("message.url", url); out_params->SetString("message.url", url);
if (NULL != level) if (level != NULL)
out_params->SetString("message.level", level); out_params->SetString("message.level", level);
if (-1 != line) if (line != -1)
out_params->SetInteger("message.line", line); out_params->SetInteger("message.line", line);
if (-1 != column) if (column != -1)
out_params->SetInteger("message.column", column); out_params->SetInteger("message.column", column);
if (NULL != text) if (text != NULL)
out_params->SetString("message.text", text); out_params->SetString("message.text", text);
} }
...@@ -125,8 +132,8 @@ TEST(ConsoleLogger, ConsoleMessages) { ...@@ -125,8 +132,8 @@ TEST(ConsoleLogger, ConsoleMessages) {
client.AddListener(&logger); client.AddListener(&logger);
logger.OnConnected(&client); logger.OnConnected(&client);
EXPECT_STREQ("Console.enable", client.PopSentCommand().c_str()); EXPECT_EQ("Console.enable", client.PopSentCommand());
EXPECT_STREQ("", client.PopSentCommand().c_str()); EXPECT_TRUE(client.PopSentCommand().empty());
base::DictionaryValue params1; // All fields are set. base::DictionaryValue params1; // All fields are set.
ConsoleLogParams(&params1, "source1", "url1", "debug", 10, 1, "text1"); ConsoleLogParams(&params1, "source1", "url1", "debug", 10, 1, "text1");
...@@ -162,24 +169,24 @@ TEST(ConsoleLogger, ConsoleMessages) { ...@@ -162,24 +169,24 @@ TEST(ConsoleLogger, ConsoleMessages) {
params8.SetInteger("gaga", 8); params8.SetInteger("gaga", 8);
ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params8).code()); ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params8).code());
EXPECT_STREQ("", client.PopSentCommand().c_str()); // No other commands sent. EXPECT_TRUE(client.PopSentCommand().empty()); // No other commands sent.
ASSERT_EQ(8u, log.entries.size()); ASSERT_EQ(8u, log.GetEntries().size());
ValidateLogEntry(log.entries[0], Log::kDebug, "url1 10:1 text1"); ValidateLogEntry(log.GetEntries()[0], Log::kDebug, "url1 10:1 text1");
ValidateLogEntry(log.entries[1], Log::kLog, "source2 - text2"); ValidateLogEntry(log.GetEntries()[1], Log::kLog, "source2 - text2");
ValidateLogEntry(log.entries[2], Log::kWarning, "url3 30 text3"); ValidateLogEntry(log.GetEntries()[2], Log::kWarning, "url3 30 text3");
ValidateLogEntry(log.entries[3], Log::kError, "url4 - text4"); ValidateLogEntry(log.GetEntries()[3], Log::kError, "url4 - text4");
ValidateLogEntry( ValidateLogEntry(
log.entries[4], Log::kWarning, log.GetEntries()[4], Log::kWarning,
"{\"message\":{\"column\":5,\"level\":\"gaga\",\"line\":50," "{\"message\":{\"column\":5,\"level\":\"gaga\",\"line\":50,"
"\"source\":\"source5\",\"text\":\"ulala\",\"url\":\"url5\"}}"); "\"source\":\"source5\",\"text\":\"ulala\",\"url\":\"url5\"}}");
ValidateLogEntry( ValidateLogEntry(
log.entries[5], Log::kWarning, log.GetEntries()[5], Log::kWarning,
"{\"message\":{\"column\":6,\"line\":60," "{\"message\":{\"column\":6,\"line\":60,"
"\"source\":\"source6\",\"url\":\"url6\"}}"); "\"source\":\"source6\",\"url\":\"url6\"}}");
ValidateLogEntry( ValidateLogEntry(
log.entries[6], Log::kWarning, log.GetEntries()[6], Log::kWarning,
"{\"message\":{\"level\":\"log\"," "{\"message\":{\"level\":\"log\","
"\"source\":\"source7\",\"url\":\"url7\"}}"); "\"source\":\"source7\",\"url\":\"url7\"}}");
ValidateLogEntry(log.entries[7], Log::kWarning, "{\"gaga\":8}"); ValidateLogEntry(log.GetEntries()[7], Log::kWarning, "{\"gaga\":8}");
} }
...@@ -78,8 +78,8 @@ std::string ConvertForDisplay(const std::string& input) { ...@@ -78,8 +78,8 @@ std::string ConvertForDisplay(const std::string& input) {
} // namespace } // namespace
void Log::AddEntry(Log::Level level, const std::string& message) { void Log::AddEntry(Level level, const std::string& message) {
return AddEntry(base::Time::Now(), level, message); AddEntryTimestamped(base::Time::Now(), level, message);
} }
Logger::Logger() : min_log_level_(kLog), start_(base::Time::Now()) {} Logger::Logger() : min_log_level_(kLog), start_(base::Time::Now()) {}
...@@ -89,7 +89,7 @@ Logger::Logger(Level min_log_level) ...@@ -89,7 +89,7 @@ Logger::Logger(Level min_log_level)
Logger::~Logger() {} Logger::~Logger() {}
void Logger::AddEntry(const base::Time& time, void Logger::AddEntryTimestamped(const base::Time& timestamp,
Level level, Level level,
const std::string& message) { const std::string& message) {
if (level < min_log_level_) if (level < min_log_level_)
...@@ -114,7 +114,7 @@ void Logger::AddEntry(const base::Time& time, ...@@ -114,7 +114,7 @@ void Logger::AddEntry(const base::Time& time,
} }
std::string entry = std::string entry =
base::StringPrintf("[%.3lf][%s]: %s", base::StringPrintf("[%.3lf][%s]: %s",
base::TimeDelta(time - start_).InSecondsF(), base::TimeDelta(timestamp - start_).InSecondsF(),
level_name, level_name,
ConvertForDisplay(message).c_str()); ConvertForDisplay(message).c_str());
const char* format = "%s\n"; const char* format = "%s\n";
......
...@@ -10,9 +10,10 @@ ...@@ -10,9 +10,10 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/time.h" #include "base/time.h"
// Accepts log entries that have a level, timestamp, and a string message. // Abstract class for logging entries with a level, timestamp, string message.
class Log { class Log {
public: public:
// Log entry severity level.
enum Level { enum Level {
kDebug, kDebug,
kLog, kLog,
...@@ -22,12 +23,12 @@ class Log { ...@@ -22,12 +23,12 @@ class Log {
virtual ~Log() {} virtual ~Log() {}
// Log a message with an explicit timestamp. // Adds an entry to the log.
virtual void AddEntry(const base::Time& time, virtual void AddEntryTimestamped(const base::Time& timestamp,
Level level, Level level,
const std::string& message) = 0; const std::string& message) = 0;
// Implicit timestamp, default to current time. // Adds an entry to the log, timestamped with the current time.
void AddEntry(Level level, const std::string& message); void AddEntry(Level level, const std::string& message);
}; };
...@@ -39,7 +40,7 @@ class Logger : public Log { ...@@ -39,7 +40,7 @@ class Logger : public Log {
explicit Logger(Level min_log_level); explicit Logger(Level min_log_level);
virtual ~Logger(); virtual ~Logger();
virtual void AddEntry(const base::Time& time, virtual void AddEntryTimestamped(const base::Time& timestamp,
Level level, Level level,
const std::string& message) OVERRIDE; const std::string& message) OVERRIDE;
......
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
namespace { namespace {
// DevTools event domain prefixes to intercept. // DevTools event domain prefixes to intercept.
const char* kDomains[] = {"Network.", "Page.", "Timeline."}; const char* const kDomains[] = {"Network.", "Page.", "Timeline."};
const char* kDomainEnableCommands[] = { const char* const kDomainEnableCommands[] = {
"Network.enable", "Page.enable", "Timeline.start" "Network.enable", "Page.enable", "Timeline.start"
}; };
// Returns whether the event belongs to one of kDomains. // Returns whether the event belongs to one of kDomains.
bool ShouldLogEvent(const std::string& method) { bool ShouldLogEvent(const std::string& method) {
for (size_t i_domain = 0; i_domain < arraysize(kDomains); ++i_domain) { for (size_t i_domain = 0; i_domain < arraysize(kDomains); ++i_domain) {
if (StartsWithASCII(method, kDomains[i_domain], true)) if (StartsWithASCII(method, kDomains[i_domain], true /* case_sensitive */))
return true; return true;
} }
return false; return false;
......
...@@ -20,15 +20,19 @@ class Log; ...@@ -20,15 +20,19 @@ class Log;
// } // }
class PerformanceLogger : public DevToolsEventListener { class PerformanceLogger : public DevToolsEventListener {
public: public:
// Creates a PerformanceLogger that creates entries in the given Log object.
// The log is owned elsewhere and must not be null.
explicit PerformanceLogger(Log* log); explicit PerformanceLogger(Log* log);
// Enables Page,Network,Timeline events for client, which must not be null.
virtual Status OnConnected(DevToolsClient* client) OVERRIDE; virtual Status OnConnected(DevToolsClient* client) OVERRIDE;
// Translates an event into a log entry.
virtual Status OnEvent(DevToolsClient* client, virtual Status OnEvent(DevToolsClient* client,
const std::string& method, const std::string& method,
const base::DictionaryValue& params) OVERRIDE; const base::DictionaryValue& params) OVERRIDE;
private: private:
Log* log_; Log* log_; // The log where to create entries.
DISALLOW_COPY_AND_ASSIGN(PerformanceLogger); DISALLOW_COPY_AND_ASSIGN(PerformanceLogger);
}; };
......
...@@ -19,7 +19,8 @@ namespace { ...@@ -19,7 +19,8 @@ namespace {
class FakeDevToolsClient : public StubDevToolsClient { class FakeDevToolsClient : public StubDevToolsClient {
public: public:
explicit FakeDevToolsClient(const std::string& id) : id_(id) {} explicit FakeDevToolsClient(const std::string& id)
: id_(id), listener_(NULL) {}
virtual ~FakeDevToolsClient() {} virtual ~FakeDevToolsClient() {}
std::string PopSentCommand() { std::string PopSentCommand() {
...@@ -50,6 +51,7 @@ class FakeDevToolsClient : public StubDevToolsClient { ...@@ -50,6 +51,7 @@ class FakeDevToolsClient : public StubDevToolsClient {
} }
virtual void AddListener(DevToolsEventListener* listener) OVERRIDE { virtual void AddListener(DevToolsEventListener* listener) OVERRIDE {
CHECK(!listener_);
listener_ = listener; listener_ = listener;
} }
...@@ -58,9 +60,9 @@ class FakeDevToolsClient : public StubDevToolsClient { ...@@ -58,9 +60,9 @@ class FakeDevToolsClient : public StubDevToolsClient {
} }
private: private:
const std::string id_; const std::string id_; // WebView id.
std::list<std::string> sent_command_queue_; std::list<std::string> sent_command_queue_; // Commands that were sent.
DevToolsEventListener* listener_; DevToolsEventListener* listener_; // The fake allows only one event listener.
}; };
struct LogEntry { struct LogEntry {
...@@ -76,29 +78,34 @@ struct LogEntry { ...@@ -76,29 +78,34 @@ struct LogEntry {
class FakeLog : public Log { class FakeLog : public Log {
public: public:
virtual void AddEntry(const base::Time& time, virtual void AddEntryTimestamped(const base::Time& timestamp,
Level level, Level level,
const std::string& message) OVERRIDE; const std::string& message) OVERRIDE;
ScopedVector<LogEntry> entries; const ScopedVector<LogEntry>& GetEntries() {
return entries_;
}
private:
ScopedVector<LogEntry> entries_;
}; };
void FakeLog::AddEntry( void FakeLog::AddEntryTimestamped(
const base::Time& time, Level level, const std::string& message) { const base::Time& timestamp, Level level, const std::string& message) {
entries.push_back(new LogEntry(time, level, message)); entries_.push_back(new LogEntry(timestamp, level, message));
} }
scoped_ptr<DictionaryValue> ParseDictionary(const std::string& json) { scoped_ptr<DictionaryValue> ParseDictionary(const std::string& json) {
std::string error; std::string error;
scoped_ptr<Value> value(base::JSONReader::ReadAndReturnError( scoped_ptr<Value> value(base::JSONReader::ReadAndReturnError(
json, base::JSON_PARSE_RFC, NULL, &error)); json, base::JSON_PARSE_RFC, NULL, &error));
if (NULL == value) { if (value == NULL) {
SCOPED_TRACE(json.c_str()); SCOPED_TRACE(json.c_str());
SCOPED_TRACE(error.c_str()); SCOPED_TRACE(error.c_str());
ADD_FAILURE(); ADD_FAILURE();
return scoped_ptr<DictionaryValue>(NULL); return scoped_ptr<DictionaryValue>(NULL);
} }
DictionaryValue* dict = 0; DictionaryValue* dict = NULL;
if (!value->GetAsDictionary(&dict)) { if (!value->GetAsDictionary(&dict)) {
SCOPED_TRACE("JSON object is not a dictionary"); SCOPED_TRACE("JSON object is not a dictionary");
ADD_FAILURE(); ADD_FAILURE();
...@@ -107,29 +114,29 @@ scoped_ptr<DictionaryValue> ParseDictionary(const std::string& json) { ...@@ -107,29 +114,29 @@ scoped_ptr<DictionaryValue> ParseDictionary(const std::string& json) {
return scoped_ptr<DictionaryValue>(dict->DeepCopy()); return scoped_ptr<DictionaryValue>(dict->DeepCopy());
} }
void ValidateLogEntry(LogEntry *entry, void ValidateLogEntry(const LogEntry *entry,
const char* expect_webview, const std::string& expected_webview,
const char* expect_method) { const std::string& expected_method) {
EXPECT_EQ(Log::kLog, entry->level); EXPECT_EQ(Log::kLog, entry->level);
EXPECT_LT(0, entry->timestamp.ToTimeT()); EXPECT_LT(0, entry->timestamp.ToTimeT());
scoped_ptr<base::DictionaryValue> message(ParseDictionary(entry->message)); scoped_ptr<base::DictionaryValue> message(ParseDictionary(entry->message));
std::string webview; std::string webview;
EXPECT_TRUE(message->GetString("webview", &webview)); EXPECT_TRUE(message->GetString("webview", &webview));
EXPECT_STREQ(expect_webview, webview.c_str()); EXPECT_EQ(expected_webview, webview);
std::string method; std::string method;
EXPECT_TRUE(message->GetString("message.method", &method)); EXPECT_TRUE(message->GetString("message.method", &method));
EXPECT_STREQ(expect_method, method.c_str()); EXPECT_EQ(expected_method, method);
DictionaryValue* params; DictionaryValue* params;
EXPECT_TRUE(message->GetDictionary("message.params", &params)); EXPECT_TRUE(message->GetDictionary("message.params", &params));
EXPECT_EQ(0u, params->size()); EXPECT_EQ(0u, params->size());
} }
void ExpectEnableDomains(FakeDevToolsClient& client) { void ExpectEnableDomains(FakeDevToolsClient& client) {
EXPECT_STREQ("Network.enable", client.PopSentCommand().c_str()); EXPECT_EQ("Network.enable", client.PopSentCommand());
EXPECT_STREQ("Page.enable", client.PopSentCommand().c_str()); EXPECT_EQ("Page.enable", client.PopSentCommand());
EXPECT_STREQ("Timeline.start", client.PopSentCommand().c_str()); EXPECT_EQ("Timeline.start", client.PopSentCommand());
EXPECT_STREQ("", client.PopSentCommand().c_str()); EXPECT_TRUE(client.PopSentCommand().empty());
} }
} // namespace } // namespace
...@@ -147,9 +154,9 @@ TEST(PerformanceLogger, OneWebView) { ...@@ -147,9 +154,9 @@ TEST(PerformanceLogger, OneWebView) {
// Ignore -- different domain. // Ignore -- different domain.
ASSERT_EQ(kOk, client.TriggerEvent("Console.bad").code()); ASSERT_EQ(kOk, client.TriggerEvent("Console.bad").code());
ASSERT_EQ(2u, log.entries.size()); ASSERT_EQ(2u, log.GetEntries().size());
ValidateLogEntry(log.entries[0], "webview-1", "Network.gaga"); ValidateLogEntry(log.GetEntries()[0], "webview-1", "Network.gaga");
ValidateLogEntry(log.entries[1], "webview-1", "Page.ulala"); ValidateLogEntry(log.GetEntries()[1], "webview-1", "Page.ulala");
} }
TEST(PerformanceLogger, TwoWebViews) { TEST(PerformanceLogger, TwoWebViews) {
...@@ -167,12 +174,12 @@ TEST(PerformanceLogger, TwoWebViews) { ...@@ -167,12 +174,12 @@ TEST(PerformanceLogger, TwoWebViews) {
// OnConnected sends the enable command only to that client, not others. // OnConnected sends the enable command only to that client, not others.
client1.ConnectIfNecessary(); client1.ConnectIfNecessary();
ExpectEnableDomains(client1); ExpectEnableDomains(client1);
EXPECT_STREQ("", client2.PopSentCommand().c_str()); EXPECT_TRUE(client2.PopSentCommand().empty());;
ASSERT_EQ(kOk, client1.TriggerEvent("Page.gaga1").code()); ASSERT_EQ(kOk, client1.TriggerEvent("Page.gaga1").code());
ASSERT_EQ(kOk, client2.TriggerEvent("Timeline.gaga2").code()); ASSERT_EQ(kOk, client2.TriggerEvent("Timeline.gaga2").code());
ASSERT_EQ(2u, log.entries.size()); ASSERT_EQ(2u, log.GetEntries().size());
ValidateLogEntry(log.entries[0], "webview-1", "Page.gaga1"); ValidateLogEntry(log.GetEntries()[0], "webview-1", "Page.gaga1");
ValidateLogEntry(log.entries[1], "webview-2", "Timeline.gaga2"); ValidateLogEntry(log.GetEntries()[1], "webview-2", "Timeline.gaga2");
} }
...@@ -17,7 +17,7 @@ namespace { ...@@ -17,7 +17,7 @@ namespace {
// Map between WebDriverLog::WebDriverLevel and its name in WD wire protocol. // Map between WebDriverLog::WebDriverLevel and its name in WD wire protocol.
// Array indices are the WebDriverLog::WebDriverLevel enum values. // Array indices are the WebDriverLog::WebDriverLevel enum values.
const char* kWebDriverLevelNames[] = { const char* const kWebDriverLevelNames[] = {
"ALL", "DEBUG", "INFO", "WARNING", "SEVERE", "OFF" "ALL", "DEBUG", "INFO", "WARNING", "SEVERE", "OFF"
}; };
...@@ -30,18 +30,20 @@ WebDriverLog::WebDriverLevel kLogLevelToWebDriverLevels[] = { ...@@ -30,18 +30,20 @@ WebDriverLog::WebDriverLevel kLogLevelToWebDriverLevels[] = {
WebDriverLog::kWdSevere // kError WebDriverLog::kWdSevere // kError
}; };
// Translates Log::Level to WebDriverLog::WebDriverLevel.
WebDriverLog::WebDriverLevel LogLevelToWebDriverLevel(Log::Level level) { WebDriverLog::WebDriverLevel LogLevelToWebDriverLevel(Log::Level level) {
const int index = level - Log::kDebug; const int index = level - Log::kDebug;
CHECK(index >= 0); CHECK_GE(index, 0);
CHECK(static_cast<size_t>(index) < arraysize(kLogLevelToWebDriverLevels)); CHECK_LT(static_cast<size_t>(index), arraysize(kLogLevelToWebDriverLevels));
return kLogLevelToWebDriverLevels[index]; return kLogLevelToWebDriverLevels[index];
} }
// Returns WD wire protocol level name for a WebDriverLog::WebDriverLevel.
std::string GetWebDriverLevelName( std::string GetWebDriverLevelName(
const WebDriverLog::WebDriverLevel level) { const WebDriverLog::WebDriverLevel level) {
const int index = level - WebDriverLog::kWdAll; const int index = level - WebDriverLog::kWdAll;
CHECK(index >= 0); CHECK_GE(index, 0);
CHECK(static_cast<size_t>(index) < arraysize(kWebDriverLevelNames)); CHECK_LT(static_cast<size_t>(index), arraysize(kWebDriverLevelNames));
return kWebDriverLevelNames[index]; return kWebDriverLevelNames[index];
} }
...@@ -51,7 +53,8 @@ bool WebDriverLog::NameToLevel( ...@@ -51,7 +53,8 @@ bool WebDriverLog::NameToLevel(
const std::string& name, WebDriverLog::WebDriverLevel* out_level) { const std::string& name, WebDriverLog::WebDriverLevel* out_level) {
for (size_t i = 0; i < arraysize(kWebDriverLevelNames); ++i) { for (size_t i = 0; i < arraysize(kWebDriverLevelNames); ++i) {
if (name == kWebDriverLevelNames[i]) { if (name == kWebDriverLevelNames[i]) {
CHECK(WebDriverLog::kWdAll + i <= WebDriverLog::kWdOff); CHECK_LE(WebDriverLog::kWdAll + i,
static_cast<size_t>(WebDriverLog::kWdOff));
*out_level = *out_level =
static_cast<WebDriverLog::WebDriverLevel>(WebDriverLog::kWdAll + i); static_cast<WebDriverLog::WebDriverLevel>(WebDriverLog::kWdAll + i);
return true; return true;
...@@ -77,14 +80,15 @@ const std::string& WebDriverLog::GetType() { ...@@ -77,14 +80,15 @@ const std::string& WebDriverLog::GetType() {
return type_; return type_;
} }
void WebDriverLog::AddEntry(const base::Time& time, void WebDriverLog::AddEntryTimestamped(const base::Time& timestamp,
Log::Level level, Log::Level level,
const std::string& message) { const std::string& message) {
const WebDriverLog::WebDriverLevel wd_level = LogLevelToWebDriverLevel(level); const WebDriverLog::WebDriverLevel wd_level = LogLevelToWebDriverLevel(level);
if (wd_level < min_wd_level_) if (wd_level < min_wd_level_)
return; return;
scoped_ptr<base::DictionaryValue> log_entry_dict(new base::DictionaryValue()); scoped_ptr<base::DictionaryValue> log_entry_dict(new base::DictionaryValue());
log_entry_dict->SetDouble("timestamp", static_cast<int64>(time.ToJsTime())); log_entry_dict->SetDouble("timestamp",
static_cast<int64>(timestamp.ToJsTime()));
log_entry_dict->SetString("level", GetWebDriverLevelName(wd_level)); log_entry_dict->SetString("level", GetWebDriverLevelName(wd_level));
log_entry_dict->SetString("message", message); log_entry_dict->SetString("message", message);
entries_->Append(log_entry_dict.release()); entries_->Append(log_entry_dict.release());
......
...@@ -18,10 +18,11 @@ class DevToolsEventListener; ...@@ -18,10 +18,11 @@ class DevToolsEventListener;
class ListValue; class ListValue;
class Status; class Status;
// Accumulates WebDriver Logging API events of a given type and minimum level. // Accumulates WebDriver Logging API entries of a given type and minimum level.
// See https://code.google.com/p/selenium/wiki/Logging. // See https://code.google.com/p/selenium/wiki/Logging.
class WebDriverLog : public Log { class WebDriverLog : public Log {
public: public:
// Constants corresponding to log entry severity levels in the wire protocol.
enum WebDriverLevel { enum WebDriverLevel {
kWdAll, kWdAll,
kWdDebug, kWdDebug,
...@@ -34,22 +35,28 @@ class WebDriverLog : public Log { ...@@ -34,22 +35,28 @@ class WebDriverLog : public Log {
// Converts WD wire protocol level name -> WebDriverLevel, false on bad name. // Converts WD wire protocol level name -> WebDriverLevel, false on bad name.
static bool NameToLevel(const std::string& name, WebDriverLevel* out_level); static bool NameToLevel(const std::string& name, WebDriverLevel* out_level);
// Creates a WebDriverLog with the given type and minimum level.
WebDriverLog(const std::string& type, WebDriverLevel min_wd_level); WebDriverLog(const std::string& type, WebDriverLevel min_wd_level);
virtual ~WebDriverLog(); virtual ~WebDriverLog();
// Returns this log's type, for the WD wire protocol "/log" and "/log/types".
const std::string& GetType(); const std::string& GetType();
// Returns entries accumulated so far, as a ListValue ready for serialization
// into the wire protocol response to the "/log" command.
// The caller assumes ownership of the ListValue, and the WebDriverLog
// creates and owns a new empty ListValue for further accumulation.
scoped_ptr<base::ListValue> GetAndClearEntries(); scoped_ptr<base::ListValue> GetAndClearEntries();
virtual void AddEntry(const base::Time& time, // Translates a Log entry level into a WebDriver level and stores the entry.
virtual void AddEntryTimestamped(const base::Time& timestamp,
Level level, Level level,
const std::string& message) OVERRIDE; const std::string& message) OVERRIDE;
using Log::AddEntry; // Inherited overload that takes level and message.
private: private:
const std::string type_; const std::string type_; // WebDriver log type.
const WebDriverLevel min_wd_level_; const WebDriverLevel min_wd_level_; // Minimum level of entries to store.
scoped_ptr<base::ListValue> entries_; scoped_ptr<base::ListValue> entries_; // Accumulated entries.
DISALLOW_COPY_AND_ASSIGN(WebDriverLog); DISALLOW_COPY_AND_ASSIGN(WebDriverLog);
}; };
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
namespace { namespace {
static const char* kAllWdLevels[] = { const char* const kAllWdLevels[] = {
"ALL", "DEBUG", "INFO", "WARNING", "SEVERE", "OFF" "ALL", "DEBUG", "INFO", "WARNING", "SEVERE", "OFF"
}; };
...@@ -46,16 +46,16 @@ namespace { ...@@ -46,16 +46,16 @@ namespace {
void ValidateLogEntry(base::ListValue *entries, void ValidateLogEntry(base::ListValue *entries,
int index, int index,
const char* expect_level, const std::string& expected_level,
const char* expect_message) { const std::string& expected_message) {
const base::DictionaryValue *entry; const base::DictionaryValue *entry;
ASSERT_TRUE(entries->GetDictionary(index, &entry)); ASSERT_TRUE(entries->GetDictionary(index, &entry));
std::string level; std::string level;
EXPECT_TRUE(entry->GetString("level", &level)); EXPECT_TRUE(entry->GetString("level", &level));
EXPECT_STREQ(expect_level, level.c_str()); EXPECT_EQ(expected_level, level);
std::string message; std::string message;
ASSERT_TRUE(entry->GetString("message", &message)); ASSERT_TRUE(entry->GetString("message", &message));
EXPECT_STREQ(expect_message, message.c_str()); EXPECT_EQ(expected_message, message);
double timestamp = 0; double timestamp = 0;
EXPECT_TRUE(entry->GetDouble("timestamp", &timestamp)); EXPECT_TRUE(entry->GetDouble("timestamp", &timestamp));
EXPECT_LT(0, timestamp); EXPECT_LT(0, timestamp);
...@@ -109,8 +109,8 @@ TEST(Logging, CreatePerformanceLog) { ...@@ -109,8 +109,8 @@ TEST(Logging, CreatePerformanceLog) {
ASSERT_TRUE(status.IsOk()); ASSERT_TRUE(status.IsOk());
ASSERT_EQ(2u, logs.size()); ASSERT_EQ(2u, logs.size());
ASSERT_EQ(2u, listeners.size()); ASSERT_EQ(2u, listeners.size());
ASSERT_STREQ("performance", logs[0]->GetType().c_str()); ASSERT_EQ("performance", logs[0]->GetType());
ASSERT_STREQ("browser", logs[1]->GetType().c_str()); // Always created. ASSERT_EQ("browser", logs[1]->GetType()); // Always created.
} }
TEST(Logging, CreateBrowserLogOff) { TEST(Logging, CreateBrowserLogOff) {
...@@ -124,7 +124,7 @@ TEST(Logging, CreateBrowserLogOff) { ...@@ -124,7 +124,7 @@ TEST(Logging, CreateBrowserLogOff) {
ASSERT_TRUE(status.IsOk()); ASSERT_TRUE(status.IsOk());
ASSERT_EQ(1u, logs.size()); ASSERT_EQ(1u, logs.size());
ASSERT_EQ(0u, listeners.size()); ASSERT_EQ(0u, listeners.size());
ASSERT_STREQ("browser", logs[0]->GetType().c_str()); ASSERT_EQ("browser", logs[0]->GetType());
// Verify the created log is "OFF" -- drops all messages. // Verify the created log is "OFF" -- drops all messages.
logs[0]->AddEntry(Log::kError, "drop even errors"); logs[0]->AddEntry(Log::kError, "drop even errors");
...@@ -143,7 +143,7 @@ TEST(Logging, IgnoreUnknownLogType) { ...@@ -143,7 +143,7 @@ TEST(Logging, IgnoreUnknownLogType) {
EXPECT_TRUE(status.IsOk()); EXPECT_TRUE(status.IsOk());
ASSERT_EQ(1u, logs.size()); ASSERT_EQ(1u, logs.size());
ASSERT_EQ(1u, listeners.size()); ASSERT_EQ(1u, listeners.size());
ASSERT_STREQ("browser", logs[0]->GetType().c_str()); ASSERT_EQ("browser", logs[0]->GetType());
} }
TEST(Logging, BrowserLogCreatedWithoutLoggingPrefs) { TEST(Logging, BrowserLogCreatedWithoutLoggingPrefs) {
...@@ -155,7 +155,7 @@ TEST(Logging, BrowserLogCreatedWithoutLoggingPrefs) { ...@@ -155,7 +155,7 @@ TEST(Logging, BrowserLogCreatedWithoutLoggingPrefs) {
EXPECT_TRUE(status.IsOk()); EXPECT_TRUE(status.IsOk());
ASSERT_EQ(1u, logs.size()); ASSERT_EQ(1u, logs.size());
ASSERT_EQ(1u, listeners.size()); ASSERT_EQ(1u, listeners.size());
ASSERT_STREQ("browser", logs[0]->GetType().c_str()); ASSERT_EQ("browser", logs[0]->GetType());
// Verify the created "browser" log is "INFO" level. // Verify the created "browser" log is "INFO" level.
logs[0]->AddEntry(Log::kLog, "info message"); logs[0]->AddEntry(Log::kLog, "info message");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment