| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include <stdlib.h> | |
| 6 #include <string.h> | |
| 7 | |
| 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" | |
| 15 | |
| 16 namespace mojo { | |
| 17 namespace test { | |
| 18 namespace { | |
| 19 | |
| 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); | |
| 25 } | |
| 26 | |
| 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); | |
| 33 } | |
| 34 | |
| 35 class MessageAccumulator : public MessageReceiver { | |
| 36 public: | |
| 37 explicit MessageAccumulator(internal::MessageQueue* queue) : queue_(queue) { | |
| 38 } | |
| 39 | |
| 40 virtual bool Accept(Message* message) MOJO_OVERRIDE { | |
| 41 queue_->Push(message); | |
| 42 return true; | |
| 43 } | |
| 44 | |
| 45 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) | |
| 46 MOJO_OVERRIDE { | |
| 47 return false; | |
| 48 } | |
| 49 | |
| 50 private: | |
| 51 internal::MessageQueue* queue_; | |
| 52 }; | |
| 53 | |
| 54 class ResponseGenerator : public MessageReceiver { | |
| 55 public: | |
| 56 ResponseGenerator() { | |
| 57 } | |
| 58 | |
| 59 virtual bool Accept(Message* message) MOJO_OVERRIDE { | |
| 60 return false; | |
| 61 } | |
| 62 | |
| 63 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) | |
| 64 MOJO_OVERRIDE { | |
| 65 EXPECT_TRUE(message->has_flag(internal::kMessageExpectsResponse)); | |
| 66 | |
| 67 return SendResponse(message->name(), message->request_id(), responder); | |
| 68 } | |
| 69 | |
| 70 bool SendResponse(uint32_t name, uint64_t request_id, | |
| 71 MessageReceiver* responder) { | |
| 72 Message response; | |
| 73 AllocResponseMessage(name, "world", request_id, &response); | |
| 74 | |
| 75 bool result = responder->Accept(&response); | |
| 76 delete responder; | |
| 77 return result; | |
| 78 } | |
| 79 }; | |
| 80 | |
| 81 class LazyResponseGenerator : public ResponseGenerator { | |
| 82 public: | |
| 83 LazyResponseGenerator() : responder_(NULL), name_(0), request_id_(0) { | |
| 84 } | |
| 85 | |
| 86 virtual ~LazyResponseGenerator() { | |
| 87 delete responder_; | |
| 88 } | |
| 89 | |
| 90 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) | |
| 91 MOJO_OVERRIDE { | |
| 92 name_ = message->name(); | |
| 93 request_id_ = message->request_id(); | |
| 94 responder_ = responder; | |
| 95 return true; | |
| 96 } | |
| 97 | |
| 98 bool has_responder() const { return !!responder_; } | |
| 99 | |
| 100 void Complete() { | |
| 101 SendResponse(name_, request_id_, responder_); | |
| 102 responder_ = NULL; | |
| 103 } | |
| 104 | |
| 105 private: | |
| 106 MessageReceiver* responder_; | |
| 107 uint32_t name_; | |
| 108 uint32_t request_id_; | |
| 109 }; | |
| 110 | |
| 111 class RouterTest : public testing::Test { | |
| 112 public: | |
| 113 RouterTest() { | |
| 114 } | |
| 115 | |
| 116 virtual void SetUp() MOJO_OVERRIDE { | |
| 117 CreateMessagePipe(&handle0_, &handle1_); | |
| 118 } | |
| 119 | |
| 120 virtual void TearDown() MOJO_OVERRIDE { | |
| 121 } | |
| 122 | |
| 123 void PumpMessages() { | |
| 124 loop_.RunUntilIdle(); | |
| 125 } | |
| 126 | |
| 127 protected: | |
| 128 ScopedMessagePipeHandle handle0_; | |
| 129 ScopedMessagePipeHandle handle1_; | |
| 130 | |
| 131 private: | |
| 132 Environment env_; | |
| 133 RunLoop loop_; | |
| 134 }; | |
| 135 | |
| 136 TEST_F(RouterTest, BasicRequestResponse) { | |
| 137 internal::Router router0(handle0_.Pass()); | |
| 138 internal::Router router1(handle1_.Pass()); | |
| 139 | |
| 140 ResponseGenerator generator; | |
| 141 router1.set_incoming_receiver(&generator); | |
| 142 | |
| 143 Message request; | |
| 144 AllocRequestMessage(1, "hello", &request); | |
| 145 | |
| 146 internal::MessageQueue message_queue; | |
| 147 router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); | |
| 148 | |
| 149 PumpMessages(); | |
| 150 | |
| 151 EXPECT_FALSE(message_queue.IsEmpty()); | |
| 152 | |
| 153 Message response; | |
| 154 message_queue.Pop(&response); | |
| 155 | |
| 156 EXPECT_EQ(std::string("world"), | |
| 157 std::string(reinterpret_cast<const char*>(response.payload()))); | |
| 158 } | |
| 159 | |
| 160 TEST_F(RouterTest, RequestWithNoReceiver) { | |
| 161 internal::Router router0(handle0_.Pass()); | |
| 162 internal::Router router1(handle1_.Pass()); | |
| 163 | |
| 164 // Without an incoming receiver set on router1, we expect router0 to observe | |
| 165 // an error as a result of sending a message. | |
| 166 | |
| 167 Message request; | |
| 168 AllocRequestMessage(1, "hello", &request); | |
| 169 | |
| 170 internal::MessageQueue message_queue; | |
| 171 router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); | |
| 172 | |
| 173 PumpMessages(); | |
| 174 | |
| 175 EXPECT_TRUE(router0.encountered_error()); | |
| 176 EXPECT_TRUE(router1.encountered_error()); | |
| 177 EXPECT_TRUE(message_queue.IsEmpty()); | |
| 178 } | |
| 179 | |
| 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. | |
| 184 | |
| 185 LazyResponseGenerator generator; | |
| 186 { | |
| 187 internal::Router router0(handle0_.Pass()); | |
| 188 internal::Router router1(handle1_.Pass()); | |
| 189 | |
| 190 router1.set_incoming_receiver(&generator); | |
| 191 | |
| 192 Message request; | |
| 193 AllocRequestMessage(1, "hello", &request); | |
| 194 | |
| 195 internal::MessageQueue message_queue; | |
| 196 router0.AcceptWithResponder(&request, | |
| 197 new MessageAccumulator(&message_queue)); | |
| 198 | |
| 199 PumpMessages(); | |
| 200 | |
| 201 EXPECT_TRUE(generator.has_responder()); | |
| 202 | |
| 203 } | |
| 204 | |
| 205 generator.Complete(); // This should end up doing nothing. | |
| 206 } | |
| 207 | |
| 208 } // namespace | |
| 209 } // namespace test | |
| 210 } // namespace mojo | |
| OLD | NEW |