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

Unified Diff: remoting/host/setup/native_messaging_host_unittest.cc

Issue 23461030: Made sure NativeMessagingHostTest.All can handle out of order responses. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix clang warning Created 7 years, 3 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: remoting/host/setup/native_messaging_host_unittest.cc
diff --git a/remoting/host/setup/native_messaging_host_unittest.cc b/remoting/host/setup/native_messaging_host_unittest.cc
index 209604a4f934c68709c7e5dfed11f443324c4062..a95271cd4f3f8ccd5d361e30b49c652ba17b65d1 100644
--- a/remoting/host/setup/native_messaging_host_unittest.cc
+++ b/remoting/host/setup/native_messaging_host_unittest.cc
@@ -27,7 +27,7 @@ using remoting::protocol::SynchronousPairingRegistry;
namespace {
-void VerifyHelloResponse(const base::DictionaryValue* response) {
+void VerifyHelloResponse(scoped_ptr<base::DictionaryValue> response) {
Lambros 2013/09/06 03:03:13 Changing to scoped_ptr means that these functions
alexeypa (please no reviews) 2013/09/06 16:14:57 Yes. It expresses the intent of these functions be
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -36,7 +36,7 @@ void VerifyHelloResponse(const base::DictionaryValue* response) {
EXPECT_EQ(STRINGIZE(VERSION), value);
}
-void VerifyGetHostNameResponse(const base::DictionaryValue* response) {
+void VerifyGetHostNameResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -45,7 +45,7 @@ void VerifyGetHostNameResponse(const base::DictionaryValue* response) {
EXPECT_EQ(net::GetHostName(), value);
}
-void VerifyGetPinHashResponse(const base::DictionaryValue* response) {
+void VerifyGetPinHashResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -54,7 +54,7 @@ void VerifyGetPinHashResponse(const base::DictionaryValue* response) {
EXPECT_EQ(remoting::MakeHostPinHash("my_host", "1234"), value);
}
-void VerifyGenerateKeyPairResponse(const base::DictionaryValue* response) {
+void VerifyGenerateKeyPairResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -63,7 +63,7 @@ void VerifyGenerateKeyPairResponse(const base::DictionaryValue* response) {
EXPECT_TRUE(response->GetString("publicKey", &value));
}
-void VerifyGetDaemonConfigResponse(const base::DictionaryValue* response) {
+void VerifyGetDaemonConfigResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -73,7 +73,8 @@ void VerifyGetDaemonConfigResponse(const base::DictionaryValue* response) {
EXPECT_TRUE(base::DictionaryValue().Equals(config));
}
-void VerifyGetUsageStatsConsentResponse(const base::DictionaryValue* response) {
+void VerifyGetUsageStatsConsentResponse(
+ scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -87,7 +88,7 @@ void VerifyGetUsageStatsConsentResponse(const base::DictionaryValue* response) {
EXPECT_TRUE(set_by_policy);
}
-void VerifyStopDaemonResponse(const base::DictionaryValue* response) {
+void VerifyStopDaemonResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -96,7 +97,7 @@ void VerifyStopDaemonResponse(const base::DictionaryValue* response) {
EXPECT_EQ("OK", value);
}
-void VerifyGetDaemonStateResponse(const base::DictionaryValue* response) {
+void VerifyGetDaemonStateResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -105,7 +106,8 @@ void VerifyGetDaemonStateResponse(const base::DictionaryValue* response) {
EXPECT_EQ("STARTED", value);
}
-void VerifyUpdateDaemonConfigResponse(const base::DictionaryValue* response) {
+void VerifyUpdateDaemonConfigResponse(
+ scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -114,7 +116,7 @@ void VerifyUpdateDaemonConfigResponse(const base::DictionaryValue* response) {
EXPECT_EQ("OK", value);
}
-void VerifyStartDaemonResponse(const base::DictionaryValue* response) {
+void VerifyStartDaemonResponse(scoped_ptr<base::DictionaryValue> response) {
ASSERT_TRUE(response);
std::string value;
EXPECT_TRUE(response->GetString("type", &value));
@@ -145,13 +147,7 @@ class MockDaemonController : public DaemonController {
virtual void GetUsageStatsConsent(
const GetUsageStatsConsentCallback& callback) OVERRIDE;
- // Returns a record of functions called, so that unittests can verify these
- // were called in the proper sequence.
- std::string call_log() { return call_log_; }
-
private:
- std::string call_log_;
-
DISALLOW_COPY_AND_ASSIGN(MockDaemonController);
};
@@ -160,12 +156,10 @@ MockDaemonController::MockDaemonController() {}
MockDaemonController::~MockDaemonController() {}
DaemonController::State MockDaemonController::GetState() {
- call_log_ += "GetState:";
return DaemonController::STATE_STARTED;
}
void MockDaemonController::GetConfig(const GetConfigCallback& callback) {
- call_log_ += "GetConfig:";
scoped_ptr<base::DictionaryValue> config(new base::DictionaryValue());
callback.Run(config.Pass());
}
@@ -173,7 +167,6 @@ void MockDaemonController::GetConfig(const GetConfigCallback& callback) {
void MockDaemonController::SetConfigAndStart(
scoped_ptr<base::DictionaryValue> config, bool consent,
const CompletionCallback& callback) {
- call_log_ += "SetConfigAndStart:";
// Verify parameters passed in.
if (consent && config && config->HasKey("start")) {
@@ -186,7 +179,6 @@ void MockDaemonController::SetConfigAndStart(
void MockDaemonController::UpdateConfig(
scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& callback) {
- call_log_ += "UpdateConfig:";
if (config && config->HasKey("update")) {
callback.Run(DaemonController::RESULT_OK);
} else {
@@ -195,7 +187,6 @@ void MockDaemonController::UpdateConfig(
}
void MockDaemonController::Stop(const CompletionCallback& callback) {
- call_log_ += "Stop:";
callback.Run(DaemonController::RESULT_OK);
}
@@ -208,7 +199,6 @@ void MockDaemonController::GetVersion(const GetVersionCallback& callback) {
void MockDaemonController::GetUsageStatsConsent(
const GetUsageStatsConsentCallback& callback) {
- call_log_ += "GetUsageStatsConsent:";
callback.Run(true, true, true);
}
@@ -235,7 +225,6 @@ class NativeMessagingHostTest : public testing::Test {
protected:
// Reference to the MockDaemonController, which is owned by |host_|.
MockDaemonController* daemon_controller_;
- std::string call_log_;
private:
// Each test creates two unidirectional pipes: "input" and "output".
@@ -296,9 +285,7 @@ void NativeMessagingHostTest::Run() {
// Destroy |host_| so that it closes its end of the output pipe, so that
// TestBadRequest() will see EOF and won't block waiting for more data.
- // Since |host_| owns |daemon_controller_|, capture its call log first.
- call_log_ = daemon_controller_->call_log();
- host_.reset(NULL);
+ host_.reset();
}
scoped_ptr<base::DictionaryValue>
@@ -343,6 +330,8 @@ void NativeMessagingHostTest::TestBadRequest(const base::Value& message) {
base::DictionaryValue good_message;
good_message.SetString("type", "hello");
+ // This test currently relies on synchronous processing of hello messages and
+ // message parameters verification.
WriteMessageToInputPipe(good_message);
WriteMessageToInputPipe(message);
WriteMessageToInputPipe(good_message);
@@ -352,7 +341,7 @@ void NativeMessagingHostTest::TestBadRequest(const base::Value& message) {
// Read from output pipe, and verify responses.
scoped_ptr<base::DictionaryValue> response =
ReadMessageFromOutputPipe();
- VerifyHelloResponse(response.get());
+ VerifyHelloResponse(response.Pass());
response = ReadMessageFromOutputPipe();
EXPECT_FALSE(response);
@@ -360,31 +349,40 @@ void NativeMessagingHostTest::TestBadRequest(const base::Value& message) {
// Test all valid request-types.
TEST_F(NativeMessagingHostTest, All) {
+ int next_id = 0;
base::DictionaryValue message;
+ message.SetInteger("id", next_id++);
Lambros 2013/09/06 03:03:13 Optional: Maybe have WriteMessageWithIdToInputPipe
alexeypa (please no reviews) 2013/09/06 16:14:57 I thought about it. The missing id test seems to b
message.SetString("type", "hello");
WriteMessageToInputPipe(message);
+ message.SetInteger("id", next_id++);
message.SetString("type", "getHostName");
WriteMessageToInputPipe(message);
+ message.SetInteger("id", next_id++);
message.SetString("type", "getPinHash");
message.SetString("hostId", "my_host");
message.SetString("pin", "1234");
WriteMessageToInputPipe(message);
message.Clear();
+ message.SetInteger("id", next_id++);
message.SetString("type", "generateKeyPair");
WriteMessageToInputPipe(message);
+ message.SetInteger("id", next_id++);
message.SetString("type", "getDaemonConfig");
WriteMessageToInputPipe(message);
+ message.SetInteger("id", next_id++);
message.SetString("type", "getUsageStatsConsent");
WriteMessageToInputPipe(message);
+ message.SetInteger("id", next_id++);
message.SetString("type", "stopDaemon");
WriteMessageToInputPipe(message);
+ message.SetInteger("id", next_id++);
message.SetString("type", "getDaemonState");
WriteMessageToInputPipe(message);
@@ -392,6 +390,7 @@ TEST_F(NativeMessagingHostTest, All) {
base::DictionaryValue config;
config.SetBoolean("update", true);
message.Set("config", config.DeepCopy());
+ message.SetInteger("id", next_id++);
message.SetString("type", "updateDaemonConfig");
WriteMessageToInputPipe(message);
@@ -399,47 +398,41 @@ TEST_F(NativeMessagingHostTest, All) {
config.SetBoolean("start", true);
message.Set("config", config.DeepCopy());
message.SetBoolean("consent", true);
+ message.SetInteger("id", next_id++);
message.SetString("type", "startDaemon");
WriteMessageToInputPipe(message);
Run();
- // Read from output pipe, and verify responses.
- scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe();
- VerifyHelloResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyGetHostNameResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyGetPinHashResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyGenerateKeyPairResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyGetDaemonConfigResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyGetUsageStatsConsentResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyStopDaemonResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyGetDaemonStateResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyUpdateDaemonConfigResponse(response.get());
-
- response = ReadMessageFromOutputPipe();
- VerifyStartDaemonResponse(response.get());
-
- // Verify that DaemonController methods were called in the correct sequence.
- // This detects cases where NativeMessagingHost might call a wrong method
- // that takes the same parameters and writes out the same response.
- EXPECT_EQ("GetConfig:GetUsageStatsConsent:Stop:GetState:UpdateConfig:"
- "SetConfigAndStart:", call_log_);
+ void (*verify_routines[])(scoped_ptr<base::DictionaryValue>) = {
+ &VerifyHelloResponse,
+ &VerifyGetHostNameResponse,
+ &VerifyGetPinHashResponse,
+ &VerifyGenerateKeyPairResponse,
+ &VerifyGetDaemonConfigResponse,
+ &VerifyGetUsageStatsConsentResponse,
+ &VerifyStopDaemonResponse,
+ &VerifyGetDaemonStateResponse,
+ &VerifyUpdateDaemonConfigResponse,
+ &VerifyStartDaemonResponse,
+ };
+ ASSERT_EQ(arraysize(verify_routines), static_cast<size_t>(next_id));
+
+ // Read all responses from output pipe, and verify them.
+ for (int i = 0; i < next_id; ++i) {
+ scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe();
+
+ // Make sure that id is available and is in the range.
+ int id;
+ ASSERT_TRUE(response->GetInteger("id", &id));
+ ASSERT_TRUE(0 <= id && id < next_id);
+
+ // Call the verification routine corresponding to the message id.
Lambros 2013/09/06 03:03:13 ASSERT_TRUE(verify_routines[id] != NULL); before t
alexeypa (please no reviews) 2013/09/06 16:14:57 Calling a routine using a NULL pointer will crash
Lambros 2013/09/06 18:55:42 We shouldn't be crashing the test binary, as this
alexeypa (please no reviews) 2013/09/06 22:19:26 Done.
+ verify_routines[id](response.Pass());
+
+ // Clear the pointer so that the routine cannot be called the second time.
+ verify_routines[id] = NULL;
+ }
}
// Verify that response ID matches request ID.
« remoting/host/setup/native_messaging_host.cc ('K') | « remoting/host/setup/native_messaging_host.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698