summaryrefslogtreecommitdiffstats
path: root/blimp
diff options
context:
space:
mode:
authorhaibinlu <haibinlu@chromium.org>2015-12-17 17:55:34 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-18 01:56:24 +0000
commit87329b210c0369bca136d02b603d4e5df0010419 (patch)
treef43f511381a9d2533aef2d3946db5b1e3d3ee4ae /blimp
parent50cbe2069fcf41ec3adef3a2ee68c91585ab90f8 (diff)
downloadchromium_src-87329b210c0369bca136d02b603d4e5df0010419.zip
chromium_src-87329b210c0369bca136d02b603d4e5df0010419.tar.gz
chromium_src-87329b210c0369bca136d02b603d4e5df0010419.tar.bz2
[Blimp Net] Adds unit test for BrowserConnectionHandler
Review URL: https://codereview.chromium.org/1512763008 Cr-Commit-Position: refs/heads/master@{#365979}
Diffstat (limited to 'blimp')
-rw-r--r--blimp/net/BUILD.gn1
-rw-r--r--blimp/net/blimp_connection.cc2
-rw-r--r--blimp/net/blimp_connection.h2
-rw-r--r--blimp/net/blimp_message_checkpoint_observer.h2
-rw-r--r--blimp/net/blimp_message_output_buffer.h4
-rw-r--r--blimp/net/browser_connection_handler.cc6
-rw-r--r--blimp/net/browser_connection_handler_unittest.cc223
-rw-r--r--blimp/net/test_common.h2
8 files changed, 235 insertions, 7 deletions
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn
index 94b8a01..5a37dc7 100644
--- a/blimp/net/BUILD.gn
+++ b/blimp/net/BUILD.gn
@@ -88,6 +88,7 @@ source_set("unit_tests") {
"blimp_message_multiplexer_unittest.cc",
"blimp_message_output_buffer_unittest.cc",
"blimp_message_pump_unittest.cc",
+ "browser_connection_handler_unittest.cc",
"client_connection_manager_unittest.cc",
"engine_authentication_handler_unittest.cc",
"engine_connection_manager_unittest.cc",
diff --git a/blimp/net/blimp_connection.cc b/blimp/net/blimp_connection.cc
index db2f63d..dd40021 100644
--- a/blimp/net/blimp_connection.cc
+++ b/blimp/net/blimp_connection.cc
@@ -113,7 +113,7 @@ void BlimpConnection::SetIncomingMessageProcessor(
message_pump_->SetMessageProcessor(processor);
}
-BlimpMessageProcessor* BlimpConnection::GetOutgoingMessageProcessor() const {
+BlimpMessageProcessor* BlimpConnection::GetOutgoingMessageProcessor() {
return outgoing_msg_processor_.get();
}
diff --git a/blimp/net/blimp_connection.h b/blimp/net/blimp_connection.h
index f95a91c..36128af 100644
--- a/blimp/net/blimp_connection.h
+++ b/blimp/net/blimp_connection.h
@@ -35,7 +35,7 @@ class BLIMP_NET_EXPORT BlimpConnection {
virtual void SetIncomingMessageProcessor(BlimpMessageProcessor* processor);
// Gets a processor for BrowserSession->BlimpConnection message routing.
- virtual BlimpMessageProcessor* GetOutgoingMessageProcessor() const;
+ virtual BlimpMessageProcessor* GetOutgoingMessageProcessor();
protected:
BlimpConnection();
diff --git a/blimp/net/blimp_message_checkpoint_observer.h b/blimp/net/blimp_message_checkpoint_observer.h
index 127ce33..890819c 100644
--- a/blimp/net/blimp_message_checkpoint_observer.h
+++ b/blimp/net/blimp_message_checkpoint_observer.h
@@ -9,7 +9,7 @@
namespace blimp {
-// Allows objects to subscribe to message acknowledgement checkpoints.
+// Allows objects to subscribe to message acknowledgment checkpoints.
class BlimpMessageCheckpointObserver {
public:
virtual ~BlimpMessageCheckpointObserver() {}
diff --git a/blimp/net/blimp_message_output_buffer.h b/blimp/net/blimp_message_output_buffer.h
index 0a7bddf..d8168ba 100644
--- a/blimp/net/blimp_message_output_buffer.h
+++ b/blimp/net/blimp_message_output_buffer.h
@@ -23,7 +23,7 @@ class BlimpConnection;
// Messages are retained for redelivery until they are acknowledged by the
// receiving end (via BlimpMessageCheckpointObserver).
// Messages can be paired with callbacks that are invoked on successful
-// message acknowledgement.
+// message acknowledgment.
// (Redelivery will be used in a future CL to implement Fast Recovery
// of dropped connections.)
class BLIMP_NET_EXPORT BlimpMessageOutputBuffer
@@ -86,7 +86,7 @@ class BLIMP_NET_EXPORT BlimpMessageOutputBuffer
// List of unsent messages.
MessageBuffer write_buffer_;
- // List of messages that are sent and awaiting acknoweldgement.
+ // List of messages that are sent and awaiting acknowledgment.
// The messages in |ack_buffer_| are contiguous with the messages in
// |write_buffer_|.
MessageBuffer ack_buffer_;
diff --git a/blimp/net/browser_connection_handler.cc b/blimp/net/browser_connection_handler.cc
index 9d3931c..baa63c3 100644
--- a/blimp/net/browser_connection_handler.cc
+++ b/blimp/net/browser_connection_handler.cc
@@ -11,6 +11,7 @@
#include "blimp/net/blimp_message_multiplexer.h"
#include "blimp/net/blimp_message_output_buffer.h"
#include "blimp/net/blimp_message_processor.h"
+#include "net/base/net_errors.h"
namespace blimp {
namespace {
@@ -41,6 +42,7 @@ void BrowserConnectionHandler::HandleConnection(
// replace an existing one.
DropCurrentConnection();
connection_ = std::move(connection);
+ connection_->SetConnectionErrorObserver(this);
// Connect the incoming & outgoing message streams.
connection_->SetIncomingMessageProcessor(demultiplexer_.get());
@@ -51,13 +53,15 @@ void BrowserConnectionHandler::HandleConnection(
void BrowserConnectionHandler::DropCurrentConnection() {
if (!connection_)
return;
+
+ connection_->SetConnectionErrorObserver(nullptr);
connection_->SetIncomingMessageProcessor(nullptr);
output_buffer_->SetOutputProcessor(nullptr);
connection_.reset();
}
void BrowserConnectionHandler::OnConnectionError(int error) {
- LOG(WARNING) << "Connection error " << error;
+ LOG(WARNING) << "Connection error " << net::ErrorToString(error);
DropCurrentConnection();
}
diff --git a/blimp/net/browser_connection_handler_unittest.cc b/blimp/net/browser_connection_handler_unittest.cc
new file mode 100644
index 0000000..c838ba6e
--- /dev/null
+++ b/blimp/net/browser_connection_handler_unittest.cc
@@ -0,0 +1,223 @@
+// Copyright 2015 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 <stddef.h>
+#include <string>
+
+#include "base/callback_helpers.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "blimp/common/proto/blimp_message.pb.h"
+#include "blimp/net/blimp_message_processor.h"
+#include "blimp/net/browser_connection_handler.h"
+#include "blimp/net/common.h"
+#include "blimp/net/connection_error_observer.h"
+#include "blimp/net/test_common.h"
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Return;
+using testing::SaveArg;
+
+namespace blimp {
+namespace {
+
+// Compares two blimp messages and ignores message_id field.
+MATCHER_P(EqualsMessageIgnoringId, message, "") {
+ BlimpMessage expected_message = message;
+ expected_message.clear_message_id();
+ BlimpMessage actual_message = arg;
+ actual_message.clear_message_id();
+
+ std::string expected_serialized;
+ std::string actual_serialized;
+ expected_message.SerializeToString(&expected_serialized);
+ actual_message.SerializeToString(&actual_serialized);
+ return expected_serialized == actual_serialized;
+}
+
+class FakeFeature {
+ public:
+ FakeFeature(BlimpMessage::Type type,
+ BrowserConnectionHandler* connection_handler) {
+ outgoing_message_processor_ =
+ connection_handler->RegisterFeature(type, &incoming_message_processor_);
+ }
+
+ ~FakeFeature() {}
+
+ BlimpMessageProcessor* outgoing_message_processor() {
+ return outgoing_message_processor_.get();
+ }
+
+ MockBlimpMessageProcessor* incoming_message_processor() {
+ return &incoming_message_processor_;
+ }
+
+ private:
+ testing::StrictMock<MockBlimpMessageProcessor> incoming_message_processor_;
+ scoped_ptr<BlimpMessageProcessor> outgoing_message_processor_;
+};
+
+class FakeBlimpConnection : public BlimpConnection,
+ public BlimpMessageProcessor {
+ public:
+ FakeBlimpConnection() {}
+ ~FakeBlimpConnection() override {}
+
+ void set_other_end(FakeBlimpConnection* other_end) { other_end_ = other_end; }
+
+ ConnectionErrorObserver* error_observer() { return error_observer_; }
+
+ // BlimpConnection implementation.
+ void SetConnectionErrorObserver(ConnectionErrorObserver* observer) override {
+ error_observer_ = observer;
+ }
+
+ void SetIncomingMessageProcessor(BlimpMessageProcessor* processor) override {
+ incoming_message_processor_ = processor;
+ }
+
+ BlimpMessageProcessor* GetOutgoingMessageProcessor() override { return this; }
+
+ private:
+ void ForwardMessage(scoped_ptr<BlimpMessage> message) {
+ other_end_->incoming_message_processor_->ProcessMessage(
+ std::move(message), net::CompletionCallback());
+ }
+
+ // BlimpMessageProcessor implementation.
+ void ProcessMessage(scoped_ptr<BlimpMessage> message,
+ const net::CompletionCallback& callback) override {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&FakeBlimpConnection::ForwardMessage,
+ base::Unretained(this), base::Passed(&message)));
+
+ callback.Run(net::OK);
+ }
+
+ FakeBlimpConnection* other_end_ = nullptr;
+ ConnectionErrorObserver* error_observer_ = nullptr;
+ BlimpMessageProcessor* incoming_message_processor_ = nullptr;
+};
+
+scoped_ptr<BlimpMessage> CreateInputMessage(int tab_id) {
+ scoped_ptr<BlimpMessage> output(new BlimpMessage);
+ output->set_type(BlimpMessage::INPUT);
+ output->set_target_tab_id(tab_id);
+ return output;
+}
+
+scoped_ptr<BlimpMessage> CreateControlMessage(int tab_id) {
+ scoped_ptr<BlimpMessage> output(new BlimpMessage);
+ output->set_type(BlimpMessage::TAB_CONTROL);
+ output->set_target_tab_id(tab_id);
+ return output;
+}
+
+class BrowserConnectionHandlerTest : public testing::Test {
+ public:
+ BrowserConnectionHandlerTest()
+ : client_connection_handler_(new BrowserConnectionHandler),
+ engine_connection_handler_(new BrowserConnectionHandler) {
+ SetupConnections();
+
+ client_input_feature_.reset(
+ new FakeFeature(BlimpMessage::INPUT, client_connection_handler_.get()));
+ engine_input_feature_.reset(
+ new FakeFeature(BlimpMessage::INPUT, engine_connection_handler_.get()));
+ client_control_feature_.reset(new FakeFeature(
+ BlimpMessage::TAB_CONTROL, client_connection_handler_.get()));
+ engine_control_feature_.reset(new FakeFeature(
+ BlimpMessage::TAB_CONTROL, engine_connection_handler_.get()));
+ }
+
+ ~BrowserConnectionHandlerTest() override {}
+ void TearDown() override { base::RunLoop().RunUntilIdle(); }
+
+ protected:
+ void SetupConnections() {
+ client_connection_ = new FakeBlimpConnection();
+ engine_connection_ = new FakeBlimpConnection();
+ client_connection_->set_other_end(engine_connection_);
+ engine_connection_->set_other_end(client_connection_);
+ client_connection_handler_->HandleConnection(
+ make_scoped_ptr(client_connection_));
+ engine_connection_handler_->HandleConnection(
+ make_scoped_ptr(engine_connection_));
+ }
+
+ base::MessageLoop message_loop_;
+
+ FakeBlimpConnection* client_connection_;
+ FakeBlimpConnection* engine_connection_;
+
+ scoped_ptr<BrowserConnectionHandler> client_connection_handler_;
+ scoped_ptr<BrowserConnectionHandler> engine_connection_handler_;
+
+ scoped_ptr<FakeFeature> client_input_feature_;
+ scoped_ptr<FakeFeature> engine_input_feature_;
+ scoped_ptr<FakeFeature> client_control_feature_;
+ scoped_ptr<FakeFeature> engine_control_feature_;
+};
+
+TEST_F(BrowserConnectionHandlerTest, ExchangeMessages) {
+ scoped_ptr<BlimpMessage> client_input_message = CreateInputMessage(1);
+ scoped_ptr<BlimpMessage> client_control_message = CreateControlMessage(1);
+ scoped_ptr<BlimpMessage> engine_control_message = CreateControlMessage(2);
+
+ EXPECT_CALL(
+ *(engine_input_feature_->incoming_message_processor()),
+ MockableProcessMessage(EqualsMessageIgnoringId(*client_input_message), _))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*(engine_control_feature_->incoming_message_processor()),
+ MockableProcessMessage(
+ EqualsMessageIgnoringId(*client_control_message), _))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*(client_control_feature_->incoming_message_processor()),
+ MockableProcessMessage(
+ EqualsMessageIgnoringId(*engine_control_message), _))
+ .RetiresOnSaturation();
+
+ client_input_feature_->outgoing_message_processor()->ProcessMessage(
+ std::move(client_input_message), net::CompletionCallback());
+ client_control_feature_->outgoing_message_processor()->ProcessMessage(
+ std::move(client_control_message), net::CompletionCallback());
+ engine_control_feature_->outgoing_message_processor()->ProcessMessage(
+ std::move(engine_control_message), net::CompletionCallback());
+}
+
+TEST_F(BrowserConnectionHandlerTest, ConnectionError) {
+ // Engine will not get message after connection error.
+ client_connection_->error_observer()->OnConnectionError(net::ERR_FAILED);
+ scoped_ptr<BlimpMessage> client_input_message = CreateInputMessage(1);
+ client_input_feature_->outgoing_message_processor()->ProcessMessage(
+ std::move(client_input_message), net::CompletionCallback());
+}
+
+TEST_F(BrowserConnectionHandlerTest, ReconnectionAfterError) {
+ scoped_ptr<BlimpMessage> client_input_message = CreateInputMessage(1);
+ EXPECT_CALL(
+ *(engine_input_feature_->incoming_message_processor()),
+ MockableProcessMessage(EqualsMessageIgnoringId(*client_input_message), _))
+ .RetiresOnSaturation();
+
+ client_connection_->error_observer()->OnConnectionError(net::ERR_FAILED);
+ // Message will be queued to be transmitted when the connection is
+ // re-established.
+ client_input_feature_->outgoing_message_processor()->ProcessMessage(
+ std::move(client_input_message), net::CompletionCallback());
+
+ // Simulates reconnection.
+ SetupConnections();
+}
+
+} // namespace
+} // namespace blimp
diff --git a/blimp/net/test_common.h b/blimp/net/test_common.h
index b42c3d8..b743c4a 100644
--- a/blimp/net/test_common.h
+++ b/blimp/net/test_common.h
@@ -177,7 +177,7 @@ class MockBlimpConnection : public BlimpConnection {
MOCK_METHOD1(SetIncomingMessageProcessor,
void(BlimpMessageProcessor* processor));
- MOCK_CONST_METHOD0(GetOutgoingMessageProcessor, BlimpMessageProcessor*());
+ MOCK_METHOD0(GetOutgoingMessageProcessor, BlimpMessageProcessor*());
};
class MockConnectionErrorObserver : public ConnectionErrorObserver {