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

Unified Diff: mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc

Issue 1455063004: Mojo C++ bindings: introduce MultiplexRouter and related classes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 1 month 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: mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
diff --git a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c175a0d7c027665ef1e947132c25a24dad61cd0b
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
@@ -0,0 +1,297 @@
+// 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 "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
+#include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
+#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
+#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/message_filter.h"
+#include "mojo/public/cpp/bindings/tests/message_queue.h"
+#include "mojo/public/cpp/bindings/tests/router_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+using mojo::internal::InterfaceEndpointClient;
+using mojo::internal::MultiplexRouter;
+using mojo::internal::ScopedInterfaceEndpointHandle;
+
+class MultiplexRouterTest : public testing::Test {
+ public:
+ MultiplexRouterTest() : loop_(common::MessagePumpMojo::Create()) {}
+
+ void SetUp() override {
+ MessagePipe pipe;
+ router0_ = new MultiplexRouter(true, pipe.handle0.Pass());
+ router1_ = new MultiplexRouter(true, pipe.handle1.Pass());
+ router0_->CreateEndpointHandlePair(&endpoint0_, &endpoint1_);
+ endpoint1_ =
+ EmulatePassingEndpointHandle(endpoint1_.Pass(), router1_.get());
+ }
+
+ void TearDown() override {}
+
+ void PumpMessages() { loop_.RunUntilIdle(); }
+
+ ScopedInterfaceEndpointHandle EmulatePassingEndpointHandle(
+ ScopedInterfaceEndpointHandle handle,
+ MultiplexRouter* target) {
+ CHECK(!handle.is_local());
+
+ return target->CreateLocalEndpointHandle(handle.release());
+ }
+
+ protected:
+ scoped_refptr<MultiplexRouter> router0_;
+ scoped_refptr<MultiplexRouter> router1_;
+ ScopedInterfaceEndpointHandle endpoint0_;
+ ScopedInterfaceEndpointHandle endpoint1_;
+
+ private:
+ base::MessageLoop loop_;
+};
+
+TEST_F(MultiplexRouterTest, BasicRequestResponse) {
+ InterfaceEndpointClient client0(endpoint0_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+ ResponseGenerator generator;
+ InterfaceEndpointClient client1(endpoint1_.Pass(), &generator,
+ make_scoped_ptr(new PassThroughFilter()));
+
+ Message request;
+ AllocRequestMessage(1, "hello", &request);
+
+ MessageQueue message_queue;
+ client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
+
+ PumpMessages();
+
+ EXPECT_FALSE(message_queue.IsEmpty());
+
+ Message response;
+ message_queue.Pop(&response);
+
+ EXPECT_EQ(std::string("hello world!"),
+ std::string(reinterpret_cast<const char*>(response.payload())));
+
+ // Send a second message on the pipe.
+ Message request2;
+ AllocRequestMessage(1, "hello again", &request2);
+
+ client0.AcceptWithResponder(&request2,
+ new MessageAccumulator(&message_queue));
+
+ PumpMessages();
+
+ EXPECT_FALSE(message_queue.IsEmpty());
+
+ message_queue.Pop(&response);
+
+ EXPECT_EQ(std::string("hello again world!"),
+ std::string(reinterpret_cast<const char*>(response.payload())));
+}
+
+TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
+ InterfaceEndpointClient client0(endpoint0_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+ ResponseGenerator generator;
+ InterfaceEndpointClient client1(endpoint1_.Pass(), &generator,
+ make_scoped_ptr(new PassThroughFilter()));
+
+ Message request;
+ AllocRequestMessage(1, "hello", &request);
+
+ MessageQueue message_queue;
+ client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
+
+ router1_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
+ router0_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
+
+ EXPECT_FALSE(message_queue.IsEmpty());
+
+ Message response;
+ message_queue.Pop(&response);
+
+ EXPECT_EQ(std::string("hello world!"),
+ std::string(reinterpret_cast<const char*>(response.payload())));
+
+ // Send a second message on the pipe.
+ Message request2;
+ AllocRequestMessage(1, "hello again", &request2);
+
+ client0.AcceptWithResponder(&request2,
+ new MessageAccumulator(&message_queue));
+
+ router1_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
+ router0_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
+
+ EXPECT_FALSE(message_queue.IsEmpty());
+
+ message_queue.Pop(&response);
+
+ EXPECT_EQ(std::string("hello again world!"),
+ std::string(reinterpret_cast<const char*>(response.payload())));
+}
+
+TEST_F(MultiplexRouterTest, RequestWithNoReceiver) {
+ InterfaceEndpointClient client0(endpoint0_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+ InterfaceEndpointClient client1(endpoint1_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+
+ // Without an incoming receiver set on client1, we expect client0 to observe
+ // an error as a result of sending a message.
+
+ Message request;
+ AllocRequestMessage(1, "hello", &request);
+
+ MessageQueue message_queue;
+ client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
+
+ PumpMessages();
+
+ EXPECT_TRUE(client0.encountered_error());
+ EXPECT_TRUE(client1.encountered_error());
+ EXPECT_TRUE(message_queue.IsEmpty());
+}
+
+// Tests MultiplexRouter using the LazyResponseGenerator. The responses will not
+// be sent until after the requests have been accepted.
+TEST_F(MultiplexRouterTest, LazyResponses) {
+ InterfaceEndpointClient client0(endpoint0_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+ LazyResponseGenerator generator;
+ InterfaceEndpointClient client1(endpoint1_.Pass(), &generator,
+ make_scoped_ptr(new PassThroughFilter()));
+
+ Message request;
+ AllocRequestMessage(1, "hello", &request);
+
+ MessageQueue message_queue;
+ client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
+ PumpMessages();
+
+ // The request has been received but the response has not been sent yet.
+ EXPECT_TRUE(message_queue.IsEmpty());
+
+ // Send the response.
+ EXPECT_TRUE(generator.responder_is_valid());
+ generator.CompleteWithResponse();
+ PumpMessages();
+
+ // Check the response.
+ EXPECT_FALSE(message_queue.IsEmpty());
+ Message response;
+ message_queue.Pop(&response);
+ EXPECT_EQ(std::string("hello world!"),
+ std::string(reinterpret_cast<const char*>(response.payload())));
+
+ // Send a second message on the pipe.
+ Message request2;
+ AllocRequestMessage(1, "hello again", &request2);
+
+ client0.AcceptWithResponder(&request2,
+ new MessageAccumulator(&message_queue));
+ PumpMessages();
+
+ // The request has been received but the response has not been sent yet.
+ EXPECT_TRUE(message_queue.IsEmpty());
+
+ // Send the second response.
+ EXPECT_TRUE(generator.responder_is_valid());
+ generator.CompleteWithResponse();
+ PumpMessages();
+
+ // Check the second response.
+ EXPECT_FALSE(message_queue.IsEmpty());
+ message_queue.Pop(&response);
+ EXPECT_EQ(std::string("hello again world!"),
+ std::string(reinterpret_cast<const char*>(response.payload())));
+}
+
+// Tests that if the receiving application destroys the responder_ without
+// sending a response, then we trigger connection error at both sides. Moreover,
+// both sides still appear to have a valid message pipe handle bound.
+TEST_F(MultiplexRouterTest, MissingResponses) {
+ InterfaceEndpointClient client0(endpoint0_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+ bool error_handler_called0 = false;
+ client0.set_connection_error_handler(
+ [&error_handler_called0]() { error_handler_called0 = true; });
+
+ LazyResponseGenerator generator;
+ InterfaceEndpointClient client1(endpoint1_.Pass(), &generator,
+ make_scoped_ptr(new PassThroughFilter()));
+ bool error_handler_called1 = false;
+ client1.set_connection_error_handler(
+ [&error_handler_called1]() { error_handler_called1 = true; });
+
+ Message request;
+ AllocRequestMessage(1, "hello", &request);
+
+ MessageQueue message_queue;
+ client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
+ PumpMessages();
+
+ // The request has been received but no response has been sent.
+ EXPECT_TRUE(message_queue.IsEmpty());
+
+ // Destroy the responder MessagerReceiver but don't send any response.
+ generator.CompleteWithoutResponse();
+ PumpMessages();
+
+ // Check that no response was received.
+ EXPECT_TRUE(message_queue.IsEmpty());
+
+ // Connection error handler is called at both sides.
+ EXPECT_TRUE(error_handler_called0);
+ EXPECT_TRUE(error_handler_called1);
+
+ // The error flag is set at both sides.
+ EXPECT_TRUE(client0.encountered_error());
+ EXPECT_TRUE(client1.encountered_error());
+
+ // The message pipe handle is valid at both sides.
+ EXPECT_TRUE(router0_->is_valid());
+ EXPECT_TRUE(router1_->is_valid());
+}
+
+TEST_F(MultiplexRouterTest, LateResponse) {
+ // Test that things won't blow up if we try to send a message to a
+ // MessageReceiver, which was given to us via AcceptWithResponder,
+ // after the router has gone away.
+
+ LazyResponseGenerator generator;
+ {
+ InterfaceEndpointClient client0(endpoint0_.Pass(), nullptr,
+ make_scoped_ptr(new PassThroughFilter()));
+ InterfaceEndpointClient client1(endpoint1_.Pass(), &generator,
+ make_scoped_ptr(new PassThroughFilter()));
+
+ Message request;
+ AllocRequestMessage(1, "hello", &request);
+
+ MessageQueue message_queue;
+ client0.AcceptWithResponder(&request,
+ new MessageAccumulator(&message_queue));
+
+ PumpMessages();
+
+ EXPECT_TRUE(generator.has_responder());
+ }
+
+ EXPECT_FALSE(generator.responder_is_valid());
+ generator.CompleteWithResponse(); // This should end up doing nothing.
+}
+
+// TODO(yzshen): add more tests.
+
+} // namespace
+} // namespace test
+} // namespace mojo
« no previous file with comments | « mojo/public/cpp/bindings/tests/connector_unittest.cc ('k') | mojo/public/cpp/bindings/tests/router_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698