1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "mojo/public/cpp/bindings/lib/message_builder.h"
9 #include "mojo/public/cpp/bindings/lib/message_queue.h"
10 #include "mojo/public/cpp/bindings/lib/router.h"
11 #include "mojo/public/cpp/environment/environment.h"
12 #include "mojo/public/cpp/system/macros.h"
13 #include "mojo/public/cpp/utility/run_loop.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 void AllocRequestMessage(uint32_t name, const char* text, Message* message) {
21 size_t payload_size = strlen(text) + 1; // Plus null terminator.
22 internal::RequestMessageBuilder builder(name, payload_size);
23 memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
24 builder.Finish(message);
27 void AllocResponseMessage(uint32_t name, const char* text,
28 uint64_t request_id, Message* message) {
29 size_t payload_size = strlen(text) + 1; // Plus null terminator.
30 internal::ResponseMessageBuilder builder(name, payload_size, request_id);
31 memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
32 builder.Finish(message);
35 class MessageAccumulator : public MessageReceiver {
37 explicit MessageAccumulator(internal::MessageQueue* queue) : queue_(queue) {
40 virtual bool Accept(Message* message) MOJO_OVERRIDE {
41 queue_->Push(message);
45 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
51 internal::MessageQueue* queue_;
54 class ResponseGenerator : public MessageReceiver {
59 virtual bool Accept(Message* message) MOJO_OVERRIDE {
63 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
65 EXPECT_TRUE(message->has_flag(internal::kMessageExpectsResponse));
67 return SendResponse(message->name(), message->request_id(), responder);
70 bool SendResponse(uint32_t name, uint64_t request_id,
71 MessageReceiver* responder) {
73 AllocResponseMessage(name, "world", request_id, &response);
75 bool result = responder->Accept(&response);
81 class LazyResponseGenerator : public ResponseGenerator {
83 LazyResponseGenerator() : responder_(NULL), name_(0), request_id_(0) {
86 virtual ~LazyResponseGenerator() {
90 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
92 name_ = message->name();
93 request_id_ = message->request_id();
94 responder_ = responder;
98 bool has_responder() const { return !!responder_; }
101 SendResponse(name_, request_id_, responder_);
106 MessageReceiver* responder_;
108 uint32_t request_id_;
111 class RouterTest : public testing::Test {
116 virtual void SetUp() MOJO_OVERRIDE {
117 CreateMessagePipe(&handle0_, &handle1_);
120 virtual void TearDown() MOJO_OVERRIDE {
123 void PumpMessages() {
124 loop_.RunUntilIdle();
128 ScopedMessagePipeHandle handle0_;
129 ScopedMessagePipeHandle handle1_;
136 TEST_F(RouterTest, BasicRequestResponse) {
137 internal::Router router0(handle0_.Pass());
138 internal::Router router1(handle1_.Pass());
140 ResponseGenerator generator;
141 router1.set_incoming_receiver(&generator);
144 AllocRequestMessage(1, "hello", &request);
146 internal::MessageQueue message_queue;
147 router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
151 EXPECT_FALSE(message_queue.IsEmpty());
154 message_queue.Pop(&response);
156 EXPECT_EQ(std::string("world"),
157 std::string(reinterpret_cast<const char*>(response.payload())));
160 TEST_F(RouterTest, RequestWithNoReceiver) {
161 internal::Router router0(handle0_.Pass());
162 internal::Router router1(handle1_.Pass());
164 // Without an incoming receiver set on router1, we expect router0 to observe
165 // an error as a result of sending a message.
168 AllocRequestMessage(1, "hello", &request);
170 internal::MessageQueue message_queue;
171 router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
175 EXPECT_TRUE(router0.encountered_error());
176 EXPECT_TRUE(router1.encountered_error());
177 EXPECT_TRUE(message_queue.IsEmpty());
180 TEST_F(RouterTest, LateResponse) {
181 // Test that things won't blow up if we try to send a message to a
182 // MessageReceiver, which was given to us via AcceptWithResponder,
183 // after the router has gone away.
185 LazyResponseGenerator generator;
187 internal::Router router0(handle0_.Pass());
188 internal::Router router1(handle1_.Pass());
190 router1.set_incoming_receiver(&generator);
193 AllocRequestMessage(1, "hello", &request);
195 internal::MessageQueue message_queue;
196 router0.AcceptWithResponder(&request,
197 new MessageAccumulator(&message_queue));
201 EXPECT_TRUE(generator.has_responder());
205 generator.Complete(); // This should end up doing nothing.