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

Side by Side Diff: util/mach/mach_message_server_test.cc

Issue 557793002: Enhance the MachMessageServer test to cover large messages (MACH_RCV_LARGE) (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback Created 6 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 unified diff | Download patch
« no previous file with comments | « util/mach/mach_message_server.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // Make the server see the reply port as a dead name by setting the reply 49 // Make the server see the reply port as a dead name by setting the reply
50 // port to a receive right and then destroying that right before the 50 // port to a receive right and then destroying that right before the
51 // server processes the request. The server should return 51 // server processes the request. The server should return
52 // MACH_SEND_INVALID_DEST, and the client will not expect a reply. 52 // MACH_SEND_INVALID_DEST, and the client will not expect a reply.
53 kReplyPortDead, 53 kReplyPortDead,
54 }; 54 };
55 55
56 Options() 56 Options()
57 : expect_server_interface_method_called(true), 57 : expect_server_interface_method_called(true),
58 parent_wait_for_child_pipe(false), 58 parent_wait_for_child_pipe(false),
59 server_options(MACH_MSG_OPTION_NONE),
59 server_persistent(MachMessageServer::kOneShot), 60 server_persistent(MachMessageServer::kOneShot),
60 server_nonblocking(MachMessageServer::kBlocking), 61 server_nonblocking(MachMessageServer::kBlocking),
61 server_timeout_ms(MACH_MSG_TIMEOUT_NONE), 62 server_timeout_ms(MACH_MSG_TIMEOUT_NONE),
62 server_mig_retcode(KERN_SUCCESS), 63 server_mig_retcode(KERN_SUCCESS),
63 server_destroy_complex(true), 64 server_destroy_complex(true),
64 expect_server_destroyed_complex(true), 65 expect_server_destroyed_complex(true),
65 expect_server_result(KERN_SUCCESS), 66 expect_server_result(KERN_SUCCESS),
67 expect_server_transaction_count(1),
66 client_send_request_count(1), 68 client_send_request_count(1),
67 client_send_complex(false), 69 client_send_complex(false),
70 client_send_large(false),
68 client_reply_port_type(kReplyPortNormal), 71 client_reply_port_type(kReplyPortNormal),
69 client_expect_reply(true), 72 client_expect_reply(true),
70 child_send_all_requests_before_receiving_any_replies(false), 73 child_send_all_requests_before_receiving_any_replies(false),
71 child_wait_for_parent_pipe(false) { 74 child_wait_for_parent_pipe(false) {
72 } 75 }
73 76
74 // true if MachMessageServerFunction() is expected to be called. 77 // true if MachMessageServerFunction() is expected to be called.
75 bool expect_server_interface_method_called; 78 bool expect_server_interface_method_called;
76 79
77 // true if the parent should wait for the child to write a byte to the pipe 80 // true if the parent should wait for the child to write a byte to the pipe
78 // as a signal that the child is ready for the parent to begin its side of 81 // as a signal that the child is ready for the parent to begin its side of
79 // the test. This is used for nonblocking tests, which require that there 82 // the test. This is used for nonblocking tests, which require that there
80 // be something in the server’s queue before attempting a nonblocking 83 // be something in the server’s queue before attempting a nonblocking
81 // receive if the receive is to be successful. 84 // receive if the receive is to be successful.
82 bool parent_wait_for_child_pipe; 85 bool parent_wait_for_child_pipe;
83 86
87 // Options to pass to MachMessageServer::Run() as the |options| parameter.
88 mach_msg_options_t server_options;
89
84 // Whether the server should run in one-shot or persistent mode. 90 // Whether the server should run in one-shot or persistent mode.
85 MachMessageServer::Persistent server_persistent; 91 MachMessageServer::Persistent server_persistent;
86 92
87 // Whether the server should run in blocking or nonblocking mode. 93 // Whether the server should run in blocking or nonblocking mode.
88 MachMessageServer::Nonblocking server_nonblocking; 94 MachMessageServer::Nonblocking server_nonblocking;
89 95
90 // The server’s timeout. 96 // The server’s timeout.
91 mach_msg_timeout_t server_timeout_ms; 97 mach_msg_timeout_t server_timeout_ms;
92 98
93 // The return code that the server returns to the client via the 99 // The return code that the server returns to the client via the
94 // mig_reply_error_t::RetCode field. A client would normally see this as 100 // mig_reply_error_t::RetCode field. A client would normally see this as
95 // a Mach RPC return value. 101 // a Mach RPC return value.
96 kern_return_t server_mig_retcode; 102 kern_return_t server_mig_retcode;
97 103
98 // The value that the server function should set its destroy_complex_request 104 // The value that the server function should set its destroy_complex_request
99 // parameter to. This is true if resources sent in complex request messages 105 // parameter to. This is true if resources sent in complex request messages
100 // should be destroyed, and false if they should not be destroyed, assuming 106 // should be destroyed, and false if they should not be destroyed, assuming
101 // that the server function indicates success. 107 // that the server function indicates success.
102 bool server_destroy_complex; 108 bool server_destroy_complex;
103 109
104 // Whether to expect the server to destroy a complex message. Even if 110 // Whether to expect the server to destroy a complex message. Even if
105 // server_destroy_complex is false, a complex message will be destroyed if 111 // server_destroy_complex is false, a complex message will be destroyed if
106 // the MIG return code was unsuccessful. 112 // the MIG return code was unsuccessful.
107 bool expect_server_destroyed_complex; 113 bool expect_server_destroyed_complex;
108 114
109 // The expected return value from MachMessageServer::Run(). 115 // The expected return value from MachMessageServer::Run().
110 kern_return_t expect_server_result; 116 kern_return_t expect_server_result;
111 117
118 // The number of transactions that the server is expected to handle.
119 size_t expect_server_transaction_count;
120
112 // The number of requests that the client should send to the server. 121 // The number of requests that the client should send to the server.
113 size_t client_send_request_count; 122 size_t client_send_request_count;
114 123
115 // true if the client should send a complex message, one that carries a port 124 // true if the client should send a complex message, one that carries a port
116 // descriptor in its body. Normally false. 125 // descriptor in its body. Normally false.
117 bool client_send_complex; 126 bool client_send_complex;
118 127
128 // true if the client should send a larger message than the server has
129 // allocated space to receive. If server_options contains MACH_RCV_LARGE,
130 // the server will resize its buffer to receive the message. Otherwise, the
131 // message will be destroyed and the server will return MACH_RCV_TOO_LARGE.
132 bool client_send_large;
133
119 // The type of reply port that the client should provide in its request’s 134 // The type of reply port that the client should provide in its request’s
120 // mach_msg_header_t::msgh_local_port, which will appear to the server as 135 // mach_msg_header_t::msgh_local_port, which will appear to the server as
121 // mach_msg_header_t::msgh_remote_port. 136 // mach_msg_header_t::msgh_remote_port.
122 ReplyPortType client_reply_port_type; 137 ReplyPortType client_reply_port_type;
123 138
124 // true if the client should wait for a reply from the server. For 139 // true if the client should wait for a reply from the server. For
125 // non-normal reply ports or requests which the server responds to with no 140 // non-normal reply ports or requests which the server responds to with no
126 // reply (MIG_NO_REPLY), the server will either not send a reply or not 141 // reply (MIG_NO_REPLY), the server will either not send a reply or not
127 // succeed in sending a reply, and the child process should not wait for 142 // succeed in sending a reply, and the child process should not wait for
128 // one. 143 // one.
(...skipping 23 matching lines...) Expand all
152 } 167 }
153 168
154 // Runs the test. 169 // Runs the test.
155 void Test() { 170 void Test() {
156 EXPECT_EQ(requests_, replies_); 171 EXPECT_EQ(requests_, replies_);
157 uint32_t start = requests_; 172 uint32_t start = requests_;
158 173
159 Run(); 174 Run();
160 175
161 EXPECT_EQ(requests_, replies_); 176 EXPECT_EQ(requests_, replies_);
162 EXPECT_EQ(options_.client_send_request_count, requests_ - start); 177 EXPECT_EQ(options_.expect_server_transaction_count, requests_ - start);
163 } 178 }
164 179
165 // MachMessageServerInterface: 180 // MachMessageServerInterface:
166 181
167 virtual bool MachMessageServerFunction( 182 virtual bool MachMessageServerFunction(
168 mach_msg_header_t* in, 183 mach_msg_header_t* in,
169 mach_msg_header_t* out, 184 mach_msg_header_t* out,
170 bool* destroy_complex_request) override { 185 bool* destroy_complex_request) override {
171 *destroy_complex_request = options_.server_destroy_complex; 186 *destroy_complex_request = options_.server_destroy_complex;
172 187
173 EXPECT_TRUE(options_.expect_server_interface_method_called); 188 EXPECT_TRUE(options_.expect_server_interface_method_called);
174 if (!options_.expect_server_interface_method_called) { 189 if (!options_.expect_server_interface_method_called) {
175 return false; 190 return false;
176 } 191 }
177 192
178 struct ReceiveRequestMessage : public RequestMessage { 193 struct ReceiveRequestMessage : public RequestMessage {
179 mach_msg_trailer_t trailer; 194 mach_msg_trailer_t trailer;
180 }; 195 };
181 196
197 struct ReceiveLargeRequestMessage : public LargeRequestMessage {
198 mach_msg_trailer_t trailer;
199 };
200
182 const ReceiveRequestMessage* request = 201 const ReceiveRequestMessage* request =
183 reinterpret_cast<ReceiveRequestMessage*>(in); 202 reinterpret_cast<ReceiveRequestMessage*>(in);
184 const mach_msg_bits_t expect_msgh_bits = 203 const mach_msg_bits_t expect_msgh_bits =
185 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MOVE_SEND) | 204 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MOVE_SEND) |
186 (options_.client_send_complex ? MACH_MSGH_BITS_COMPLEX : 0); 205 (options_.client_send_complex ? MACH_MSGH_BITS_COMPLEX : 0);
187 EXPECT_EQ(expect_msgh_bits, request->header.msgh_bits); 206 EXPECT_EQ(expect_msgh_bits, request->header.msgh_bits);
188 EXPECT_EQ(sizeof(RequestMessage), request->header.msgh_size); 207 EXPECT_EQ(options_.client_send_large ? sizeof(LargeRequestMessage) :
208 sizeof(RequestMessage),
209 request->header.msgh_size);
189 if (options_.client_reply_port_type == Options::kReplyPortNormal) { 210 if (options_.client_reply_port_type == Options::kReplyPortNormal) {
190 EXPECT_EQ(RemotePort(), request->header.msgh_remote_port); 211 EXPECT_EQ(RemotePort(), request->header.msgh_remote_port);
191 } 212 }
192 EXPECT_EQ(LocalPort(), request->header.msgh_local_port); 213 EXPECT_EQ(LocalPort(), request->header.msgh_local_port);
193 EXPECT_EQ(kRequestMessageId, request->header.msgh_id); 214 EXPECT_EQ(kRequestMessageId, request->header.msgh_id);
194 if (options_.client_send_complex) { 215 if (options_.client_send_complex) {
195 EXPECT_EQ(1u, request->body.msgh_descriptor_count); 216 EXPECT_EQ(1u, request->body.msgh_descriptor_count);
196 EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL), 217 EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL),
197 request->port_descriptor.name); 218 request->port_descriptor.name);
198 parent_complex_message_port_ = request->port_descriptor.name; 219 parent_complex_message_port_ = request->port_descriptor.name;
199 EXPECT_EQ(static_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_MOVE_SEND), 220 EXPECT_EQ(static_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_MOVE_SEND),
200 request->port_descriptor.disposition); 221 request->port_descriptor.disposition);
201 EXPECT_EQ( 222 EXPECT_EQ(
202 static_cast<mach_msg_descriptor_type_t>(MACH_MSG_PORT_DESCRIPTOR), 223 static_cast<mach_msg_descriptor_type_t>(MACH_MSG_PORT_DESCRIPTOR),
203 request->port_descriptor.type); 224 request->port_descriptor.type);
204 } else { 225 } else {
205 EXPECT_EQ(0u, request->body.msgh_descriptor_count); 226 EXPECT_EQ(0u, request->body.msgh_descriptor_count);
206 EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL), 227 EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
207 request->port_descriptor.name); 228 request->port_descriptor.name);
208 EXPECT_EQ(0u, request->port_descriptor.disposition); 229 EXPECT_EQ(0u, request->port_descriptor.disposition);
209 EXPECT_EQ(0u, request->port_descriptor.type); 230 EXPECT_EQ(0u, request->port_descriptor.type);
210 } 231 }
211 EXPECT_EQ(0, memcmp(&request->ndr, &NDR_record, sizeof(NDR_record))); 232 EXPECT_EQ(0, memcmp(&request->ndr, &NDR_record, sizeof(NDR_record)));
212 EXPECT_EQ(requests_, request->number); 233 EXPECT_EQ(requests_, request->number);
234
235 // Look for the trailer in the right spot, depending on whether the request
236 // message was a RequestMessage or a LargeRequestMessage.
237 const mach_msg_trailer_t* trailer;
238 if (options_.client_send_large) {
239 const ReceiveLargeRequestMessage* large_request =
240 reinterpret_cast<const ReceiveLargeRequestMessage*>(request);
241 for (size_t index = 0; index < sizeof(large_request->data); ++index) {
242 EXPECT_EQ('!', large_request->data[index]);
243 }
244 trailer = &large_request->trailer;
245 } else {
246 trailer = &request->trailer;
247 }
248
213 EXPECT_EQ(static_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0), 249 EXPECT_EQ(static_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0),
214 request->trailer.msgh_trailer_type); 250 trailer->msgh_trailer_type);
215 EXPECT_EQ(MACH_MSG_TRAILER_MINIMUM_SIZE, 251 EXPECT_EQ(MACH_MSG_TRAILER_MINIMUM_SIZE, trailer->msgh_trailer_size);
216 request->trailer.msgh_trailer_size);
217 252
218 ++requests_; 253 ++requests_;
219 254
220 ReplyMessage* reply = reinterpret_cast<ReplyMessage*>(out); 255 ReplyMessage* reply = reinterpret_cast<ReplyMessage*>(out);
221 reply->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); 256 reply->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
222 reply->Head.msgh_size = sizeof(*reply); 257 reply->Head.msgh_size = sizeof(*reply);
223 reply->Head.msgh_remote_port = request->header.msgh_remote_port; 258 reply->Head.msgh_remote_port = request->header.msgh_remote_port;
224 reply->Head.msgh_local_port = MACH_PORT_NULL; 259 reply->Head.msgh_local_port = MACH_PORT_NULL;
225 reply->Head.msgh_id = kReplyMessageId; 260 reply->Head.msgh_id = kReplyMessageId;
226 reply->NDR = NDR_record; 261 reply->NDR = NDR_record;
227 reply->RetCode = options_.server_mig_retcode; 262 reply->RetCode = options_.server_mig_retcode;
228 reply->number = replies_++; 263 reply->number = replies_++;
229 264
230 return true; 265 return true;
231 } 266 }
232 267
233 virtual mach_msg_size_t MachMessageServerRequestSize() override { 268 virtual mach_msg_size_t MachMessageServerRequestSize() override {
234 return sizeof(RequestMessage); 269 return sizeof(RequestMessage);
235 } 270 }
236 271
237 virtual mach_msg_size_t MachMessageServerReplySize() override { 272 virtual mach_msg_size_t MachMessageServerReplySize() override {
238 return sizeof(ReplyMessage); 273 return sizeof(ReplyMessage);
239 } 274 }
240 275
241 private: 276 private:
242 struct RequestMessage : public mach_msg_base_t { 277 struct RequestMessage : public mach_msg_base_t {
278 // If body.msgh_descriptor_count is 0, port_descriptor will still be
279 // present, but it will be zeroed out. It wouldn’t normally be present in a
280 // message froma MIG-generated interface, but it’s harmless and simpler to
281 // leave it here and just treat it as more data.
243 mach_msg_port_descriptor_t port_descriptor; 282 mach_msg_port_descriptor_t port_descriptor;
283
244 NDR_record_t ndr; 284 NDR_record_t ndr;
245 uint32_t number; 285 uint32_t number;
246 }; 286 };
247 287
288 // LargeRequestMessage is larger enough than a regular RequestMessage to
289 // ensure that whatever buffer was allocated to receive a RequestMessage is
290 // not large enough to receive a LargeRequestMessage.
291 struct LargeRequestMessage : public RequestMessage {
292 uint8_t data[4 * PAGE_SIZE];
293 };
294
248 struct ReplyMessage : public mig_reply_error_t { 295 struct ReplyMessage : public mig_reply_error_t {
249 uint32_t number; 296 uint32_t number;
250 }; 297 };
251 298
252 // MachMultiprocess: 299 // MachMultiprocess:
253 300
254 virtual void MachMultiprocessParent() override { 301 virtual void MachMultiprocessParent() override {
255 if (options_.parent_wait_for_child_pipe) { 302 if (options_.parent_wait_for_child_pipe) {
256 // Wait until the child is done sending what it’s going to send. 303 // Wait until the child is done sending what it’s going to send.
257 char c; 304 char c;
258 ssize_t rv = ReadFD(ReadPipeFD(), &c, 1); 305 ssize_t rv = ReadFD(ReadPipeFD(), &c, 1);
259 EXPECT_EQ(1, rv) << ErrnoMessage("read"); 306 EXPECT_EQ(1, rv) << ErrnoMessage("read");
260 EXPECT_EQ('\0', c); 307 EXPECT_EQ('\0', c);
261 } 308 }
262 309
263 kern_return_t kr; 310 kern_return_t kr;
264 ASSERT_EQ(options_.expect_server_result, 311 ASSERT_EQ(options_.expect_server_result,
265 (kr = MachMessageServer::Run(this, 312 (kr = MachMessageServer::Run(this,
266 LocalPort(), 313 LocalPort(),
267 MACH_MSG_OPTION_NONE, 314 options_.server_options,
268 options_.server_persistent, 315 options_.server_persistent,
269 options_.server_nonblocking, 316 options_.server_nonblocking,
270 options_.server_timeout_ms))) 317 options_.server_timeout_ms)))
271 << MachErrorMessage(kr, "MachMessageServer"); 318 << MachErrorMessage(kr, "MachMessageServer");
272 319
273 if (options_.client_send_complex) { 320 if (options_.client_send_complex) {
274 EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL), 321 EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL),
275 parent_complex_message_port_); 322 parent_complex_message_port_);
276 mach_port_type_t type; 323 mach_port_type_t type;
277 324
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 401 }
355 } 402 }
356 403
357 // In the child process, sends a request message to the server. 404 // In the child process, sends a request message to the server.
358 void ChildSendRequest() { 405 void ChildSendRequest() {
359 // local_receive_port_owner will the receive right that is created in this 406 // local_receive_port_owner will the receive right that is created in this
360 // scope and intended to be destroyed when leaving this scope, after it has 407 // scope and intended to be destroyed when leaving this scope, after it has
361 // been carried in a Mach message. 408 // been carried in a Mach message.
362 base::mac::ScopedMachReceiveRight local_receive_port_owner; 409 base::mac::ScopedMachReceiveRight local_receive_port_owner;
363 410
364 RequestMessage request = {}; 411 // A LargeRequestMessage is always allocated, but the message that will be
412 // sent will be a normal RequestMessage due to the msgh_size field
413 // indicating the size of the smaller base structure unless
414 // options_.client_send_large is true.
415 LargeRequestMessage request = {};
416
365 request.header.msgh_bits = 417 request.header.msgh_bits =
366 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND) | 418 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND) |
367 (options_.client_send_complex ? MACH_MSGH_BITS_COMPLEX : 0); 419 (options_.client_send_complex ? MACH_MSGH_BITS_COMPLEX : 0);
368 request.header.msgh_size = sizeof(request); 420 request.header.msgh_size = options_.client_send_large ?
421 sizeof(LargeRequestMessage) : sizeof(RequestMessage);
369 request.header.msgh_remote_port = RemotePort(); 422 request.header.msgh_remote_port = RemotePort();
370 kern_return_t kr; 423 kern_return_t kr;
371 switch (options_.client_reply_port_type) { 424 switch (options_.client_reply_port_type) {
372 case Options::kReplyPortNormal: 425 case Options::kReplyPortNormal:
373 request.header.msgh_local_port = LocalPort(); 426 request.header.msgh_local_port = LocalPort();
374 break; 427 break;
375 case Options::kReplyPortNull: 428 case Options::kReplyPortNull:
376 request.header.msgh_local_port = MACH_PORT_NULL; 429 request.header.msgh_local_port = MACH_PORT_NULL;
377 break; 430 break;
378 case Options::kReplyPortDead: { 431 case Options::kReplyPortDead: {
(...skipping 26 matching lines...) Expand all
405 request.port_descriptor.type = MACH_MSG_PORT_DESCRIPTOR; 458 request.port_descriptor.type = MACH_MSG_PORT_DESCRIPTOR;
406 } else { 459 } else {
407 request.body.msgh_descriptor_count = 0; 460 request.body.msgh_descriptor_count = 0;
408 request.port_descriptor.name = MACH_PORT_NULL; 461 request.port_descriptor.name = MACH_PORT_NULL;
409 request.port_descriptor.disposition = 0; 462 request.port_descriptor.disposition = 0;
410 request.port_descriptor.type = 0; 463 request.port_descriptor.type = 0;
411 } 464 }
412 request.ndr = NDR_record; 465 request.ndr = NDR_record;
413 request.number = requests_++; 466 request.number = requests_++;
414 467
468 if (options_.client_send_large) {
469 memset(request.data, '!', sizeof(request.data));
470 }
471
415 kr = mach_msg(&request.header, 472 kr = mach_msg(&request.header,
416 MACH_SEND_MSG | MACH_SEND_TIMEOUT, 473 MACH_SEND_MSG | MACH_SEND_TIMEOUT,
417 request.header.msgh_size, 474 request.header.msgh_size,
418 0, 475 0,
419 MACH_PORT_NULL, 476 MACH_PORT_NULL,
420 MACH_MSG_TIMEOUT_NONE, 477 MACH_MSG_TIMEOUT_NONE,
421 MACH_PORT_NULL); 478 MACH_PORT_NULL);
422 ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg"); 479 ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg");
423 } 480 }
424 481
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 test_mach_message_server.Test(); 584 test_mach_message_server.Test();
528 } 585 }
529 586
530 TEST(MachMessageServer, NonblockingNoMessage) { 587 TEST(MachMessageServer, NonblockingNoMessage) {
531 // The server waits in nonblocking mode and the client sends nothing, so the 588 // The server waits in nonblocking mode and the client sends nothing, so the
532 // server should return immediately without processing any message. 589 // server should return immediately without processing any message.
533 TestMachMessageServer::Options options; 590 TestMachMessageServer::Options options;
534 options.expect_server_interface_method_called = false; 591 options.expect_server_interface_method_called = false;
535 options.server_nonblocking = MachMessageServer::kNonblocking; 592 options.server_nonblocking = MachMessageServer::kNonblocking;
536 options.expect_server_result = MACH_RCV_TIMED_OUT; 593 options.expect_server_result = MACH_RCV_TIMED_OUT;
594 options.expect_server_transaction_count = 0;
537 options.client_send_request_count = 0; 595 options.client_send_request_count = 0;
538 TestMachMessageServer test_mach_message_server(options); 596 TestMachMessageServer test_mach_message_server(options);
539 test_mach_message_server.Test(); 597 test_mach_message_server.Test();
540 } 598 }
541 599
542 TEST(MachMessageServer, TimeoutNoMessage) { 600 TEST(MachMessageServer, TimeoutNoMessage) {
543 // The server waits in blocking mode for one message, but with a timeout. The 601 // The server waits in blocking mode for one message, but with a timeout. The
544 // client sends no message, so the server returns after the timeout. 602 // client sends no message, so the server returns after the timeout.
545 TestMachMessageServer::Options options; 603 TestMachMessageServer::Options options;
546 options.expect_server_interface_method_called = false; 604 options.expect_server_interface_method_called = false;
547 options.server_timeout_ms = 10; 605 options.server_timeout_ms = 10;
548 options.expect_server_result = MACH_RCV_TIMED_OUT; 606 options.expect_server_result = MACH_RCV_TIMED_OUT;
607 options.expect_server_transaction_count = 0;
549 options.client_send_request_count = 0; 608 options.client_send_request_count = 0;
550 TestMachMessageServer test_mach_message_server(options); 609 TestMachMessageServer test_mach_message_server(options);
551 test_mach_message_server.Test(); 610 test_mach_message_server.Test();
552 } 611 }
553 612
554 TEST(MachMessageServer, Nonblocking) { 613 TEST(MachMessageServer, Nonblocking) {
555 // The client sends one message to the server and then signals the server that 614 // The client sends one message to the server and then signals the server that
556 // it’s safe to start waiting for it in nonblocking mode. The message is in 615 // it’s safe to start waiting for it in nonblocking mode. The message is in
557 // the server’s queue, so it’s able to receive it when it begins listening in 616 // the server’s queue, so it’s able to receive it when it begins listening in
558 // nonblocking mode. 617 // nonblocking mode.
(...skipping 14 matching lines...) Expand all
573 } 632 }
574 633
575 TEST(MachMessageServer, PersistentTenMessages) { 634 TEST(MachMessageServer, PersistentTenMessages) {
576 // The server waits for as many messages as it can receive in blocking mode 635 // The server waits for as many messages as it can receive in blocking mode
577 // with a timeout. The client sends several messages, and the server processes 636 // with a timeout. The client sends several messages, and the server processes
578 // them all. 637 // them all.
579 TestMachMessageServer::Options options; 638 TestMachMessageServer::Options options;
580 options.server_persistent = MachMessageServer::kPersistent; 639 options.server_persistent = MachMessageServer::kPersistent;
581 options.server_timeout_ms = 10; 640 options.server_timeout_ms = 10;
582 options.expect_server_result = MACH_RCV_TIMED_OUT; 641 options.expect_server_result = MACH_RCV_TIMED_OUT;
642 options.expect_server_transaction_count = 10;
583 options.client_send_request_count = 10; 643 options.client_send_request_count = 10;
584 TestMachMessageServer test_mach_message_server(options); 644 TestMachMessageServer test_mach_message_server(options);
585 test_mach_message_server.Test(); 645 test_mach_message_server.Test();
586 } 646 }
587 647
588 TEST(MachMessageServer, PersistentNonblockingFourMessages) { 648 TEST(MachMessageServer, PersistentNonblockingFourMessages) {
589 // The client sends several messages to the server and then signals the server 649 // The client sends several messages to the server and then signals the server
590 // that it’s safe to start waiting for them in nonblocking mode. The server 650 // that it’s safe to start waiting for them in nonblocking mode. The server
591 // then listens for them in nonblocking persistent mode, and receives all of 651 // then listens for them in nonblocking persistent mode, and receives all of
592 // them because they’ve been queued up. The client doesn’t wait for the 652 // them because they’ve been queued up. The client doesn’t wait for the
593 // replies until after it’s put all of its requests into the server’s queue. 653 // replies until after it’s put all of its requests into the server’s queue.
594 // 654 //
595 // This test is sensitive to the length of the IPC queue limit. Mach ports 655 // This test is sensitive to the length of the IPC queue limit. Mach ports
596 // normally have a queue length limit of MACH_PORT_QLIMIT_DEFAULT (which is 656 // normally have a queue length limit of MACH_PORT_QLIMIT_DEFAULT (which is
597 // MACH_PORT_QLIMIT_BASIC, or 5). The number of messages sent for this test 657 // MACH_PORT_QLIMIT_BASIC, or 5). The number of messages sent for this test
598 // must be below this, because the server does not begin dequeueing request 658 // must be below this, because the server does not begin dequeueing request
599 // messages until the client has finished sending them. 659 // messages until the client has finished sending them.
660 const size_t kTransactionCount = 4;
661 COMPILE_ASSERT(kTransactionCount <= MACH_PORT_QLIMIT_DEFAULT,
662 must_not_exceed_queue_limit);
663
600 TestMachMessageServer::Options options; 664 TestMachMessageServer::Options options;
601 options.parent_wait_for_child_pipe = true; 665 options.parent_wait_for_child_pipe = true;
602 options.server_persistent = MachMessageServer::kPersistent; 666 options.server_persistent = MachMessageServer::kPersistent;
603 options.server_nonblocking = MachMessageServer::kNonblocking; 667 options.server_nonblocking = MachMessageServer::kNonblocking;
604 options.expect_server_result = MACH_RCV_TIMED_OUT; 668 options.expect_server_result = MACH_RCV_TIMED_OUT;
605 options.client_send_request_count = 4; 669 options.expect_server_transaction_count = kTransactionCount;
670 options.client_send_request_count = kTransactionCount;
606 options.child_send_all_requests_before_receiving_any_replies = true; 671 options.child_send_all_requests_before_receiving_any_replies = true;
607 TestMachMessageServer test_mach_message_server(options); 672 TestMachMessageServer test_mach_message_server(options);
608 test_mach_message_server.Test(); 673 test_mach_message_server.Test();
609 } 674 }
610 675
611 TEST(MachMessageServer, ReturnCodeInvalidArgument) { 676 TEST(MachMessageServer, ReturnCodeInvalidArgument) {
612 // This tests that the mig_reply_error_t::RetCode field is properly returned 677 // This tests that the mig_reply_error_t::RetCode field is properly returned
613 // to the client. 678 // to the client.
614 TestMachMessageServer::Options options; 679 TestMachMessageServer::Options options;
615 options.server_mig_retcode = KERN_INVALID_ARGUMENT; 680 options.server_mig_retcode = KERN_INVALID_ARGUMENT;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 options.server_mig_retcode = MIG_NO_REPLY; 774 options.server_mig_retcode = MIG_NO_REPLY;
710 options.server_destroy_complex = false; 775 options.server_destroy_complex = false;
711 options.expect_server_destroyed_complex = false; 776 options.expect_server_destroyed_complex = false;
712 options.client_send_complex = true; 777 options.client_send_complex = true;
713 options.client_expect_reply = false; 778 options.client_expect_reply = false;
714 options.child_wait_for_parent_pipe = true; 779 options.child_wait_for_parent_pipe = true;
715 TestMachMessageServer test_mach_message_server(options); 780 TestMachMessageServer test_mach_message_server(options);
716 test_mach_message_server.Test(); 781 test_mach_message_server.Test();
717 } 782 }
718 783
784 TEST(MachMessageServer, LargeUnexpected) {
785 // The client sends a request to the server that is larger than the server is
786 // expecting. The server did not specify MACH_RCV_LARGE in its options, so the
787 // request is destroyed and the server returns a MACH_RCV_TOO_LARGE error. The
788 // client does not receive a reply.
789 TestMachMessageServer::Options options;
790 options.expect_server_result = MACH_RCV_TOO_LARGE;
791 options.expect_server_transaction_count = 0;
792 options.client_send_large = true;
793 options.client_expect_reply = false;
794 TestMachMessageServer test_mach_message_server(options);
795 test_mach_message_server.Test();
796 }
797
798 TEST(MachMessageServer, LargeExpected) {
799 // The client sends a request to the server that is larger than the server is
800 // initially expecting. The server did specify MACH_RCV_LARGE in its options,
801 // so a new buffer is allocated to receive the message. The server receives
802 // the large request message, processes it, and returns a reply to the client.
803 TestMachMessageServer::Options options;
804 options.server_options = MACH_RCV_LARGE;
805 options.client_send_large = true;
806 TestMachMessageServer test_mach_message_server(options);
807 test_mach_message_server.Test();
808 }
809
719 } // namespace 810 } // namespace
OLDNEW
« no previous file with comments | « util/mach/mach_message_server.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698