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

Side by Side Diff: mojo/edk/system/local_data_pipe_unittest.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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 | « mojo/edk/system/local_data_pipe.cc ('k') | mojo/edk/system/local_message_pipe_endpoint.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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 "mojo/edk/system/local_data_pipe.h"
6
7 #include <string.h>
8
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "mojo/edk/system/data_pipe.h"
12 #include "mojo/edk/system/waiter.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace mojo {
16 namespace system {
17 namespace {
18
19 const uint32_t kSizeOfOptions =
20 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions));
21
22 // Validate options.
23 TEST(LocalDataPipeTest, Creation) {
24 // Create using default options.
25 {
26 // Get default options.
27 MojoCreateDataPipeOptions default_options = {0};
28 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
29 NullUserPointer(), &default_options));
30 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(default_options));
31 dp->ProducerClose();
32 dp->ConsumerClose();
33 }
34
35 // Create using non-default options.
36 {
37 const MojoCreateDataPipeOptions options = {
38 kSizeOfOptions, // |struct_size|.
39 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
40 1, // |element_num_bytes|.
41 1000 // |capacity_num_bytes|.
42 };
43 MojoCreateDataPipeOptions validated_options = {0};
44 EXPECT_EQ(MOJO_RESULT_OK,
45 DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
46 &validated_options));
47 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
48 dp->ProducerClose();
49 dp->ConsumerClose();
50 }
51 {
52 const MojoCreateDataPipeOptions options = {
53 kSizeOfOptions, // |struct_size|.
54 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
55 4, // |element_num_bytes|.
56 4000 // |capacity_num_bytes|.
57 };
58 MojoCreateDataPipeOptions validated_options = {0};
59 EXPECT_EQ(MOJO_RESULT_OK,
60 DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
61 &validated_options));
62 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
63 dp->ProducerClose();
64 dp->ConsumerClose();
65 }
66 {
67 const MojoCreateDataPipeOptions options = {
68 kSizeOfOptions, // |struct_size|.
69 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
70 7, // |element_num_bytes|.
71 7000000 // |capacity_num_bytes|.
72 };
73 MojoCreateDataPipeOptions validated_options = {0};
74 EXPECT_EQ(MOJO_RESULT_OK,
75 DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
76 &validated_options));
77 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
78 dp->ProducerClose();
79 dp->ConsumerClose();
80 }
81 // Default capacity.
82 {
83 const MojoCreateDataPipeOptions options = {
84 kSizeOfOptions, // |struct_size|.
85 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
86 100, // |element_num_bytes|.
87 0 // |capacity_num_bytes|.
88 };
89 MojoCreateDataPipeOptions validated_options = {0};
90 EXPECT_EQ(MOJO_RESULT_OK,
91 DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
92 &validated_options));
93 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
94 dp->ProducerClose();
95 dp->ConsumerClose();
96 }
97 }
98
99 TEST(LocalDataPipeTest, SimpleReadWrite) {
100 const MojoCreateDataPipeOptions options = {
101 kSizeOfOptions, // |struct_size|.
102 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
103 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
104 1000 * sizeof(int32_t) // |capacity_num_bytes|.
105 };
106 MojoCreateDataPipeOptions validated_options = {0};
107 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
108 MakeUserPointer(&options), &validated_options));
109
110 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
111
112 int32_t elements[10] = {0};
113 uint32_t num_bytes = 0;
114
115 // Try reading; nothing there yet.
116 num_bytes = static_cast<uint32_t>(arraysize(elements) * sizeof(elements[0]));
117 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
118 dp->ConsumerReadData(UserPointer<void>(elements),
119 MakeUserPointer(&num_bytes), false, false));
120
121 // Query; nothing there yet.
122 num_bytes = 0;
123 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
124 EXPECT_EQ(0u, num_bytes);
125
126 // Discard; nothing there yet.
127 num_bytes = static_cast<uint32_t>(5u * sizeof(elements[0]));
128 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
129 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), false));
130
131 // Read with invalid |num_bytes|.
132 num_bytes = sizeof(elements[0]) + 1;
133 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
134 dp->ConsumerReadData(UserPointer<void>(elements),
135 MakeUserPointer(&num_bytes), false, false));
136
137 // Write two elements.
138 elements[0] = 123;
139 elements[1] = 456;
140 num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
141 EXPECT_EQ(MOJO_RESULT_OK,
142 dp->ProducerWriteData(UserPointer<const void>(elements),
143 MakeUserPointer(&num_bytes), false));
144 // It should have written everything (even without "all or none").
145 EXPECT_EQ(2u * sizeof(elements[0]), num_bytes);
146
147 // Query.
148 num_bytes = 0;
149 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
150 EXPECT_EQ(2 * sizeof(elements[0]), num_bytes);
151
152 // Read one element.
153 elements[0] = -1;
154 elements[1] = -1;
155 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
156 EXPECT_EQ(MOJO_RESULT_OK,
157 dp->ConsumerReadData(UserPointer<void>(elements),
158 MakeUserPointer(&num_bytes), false, false));
159 EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
160 EXPECT_EQ(123, elements[0]);
161 EXPECT_EQ(-1, elements[1]);
162
163 // Query.
164 num_bytes = 0;
165 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
166 EXPECT_EQ(1 * sizeof(elements[0]), num_bytes);
167
168 // Peek one element.
169 elements[0] = -1;
170 elements[1] = -1;
171 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
172 EXPECT_EQ(MOJO_RESULT_OK,
173 dp->ConsumerReadData(UserPointer<void>(elements),
174 MakeUserPointer(&num_bytes), false, true));
175 EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
176 EXPECT_EQ(456, elements[0]);
177 EXPECT_EQ(-1, elements[1]);
178
179 // Query. Still has 1 element remaining.
180 num_bytes = 0;
181 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
182 EXPECT_EQ(1 * sizeof(elements[0]), num_bytes);
183
184 // Try to read two elements, with "all or none".
185 elements[0] = -1;
186 elements[1] = -1;
187 num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
188 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
189 dp->ConsumerReadData(UserPointer<void>(elements),
190 MakeUserPointer(&num_bytes), true, false));
191 EXPECT_EQ(-1, elements[0]);
192 EXPECT_EQ(-1, elements[1]);
193
194 // Try to read two elements, without "all or none".
195 elements[0] = -1;
196 elements[1] = -1;
197 num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
198 EXPECT_EQ(MOJO_RESULT_OK,
199 dp->ConsumerReadData(UserPointer<void>(elements),
200 MakeUserPointer(&num_bytes), false, false));
201 EXPECT_EQ(456, elements[0]);
202 EXPECT_EQ(-1, elements[1]);
203
204 // Query.
205 num_bytes = 0;
206 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
207 EXPECT_EQ(0u, num_bytes);
208
209 dp->ProducerClose();
210 dp->ConsumerClose();
211 }
212
213 // Note: The "basic" waiting tests test that the "wait states" are correct in
214 // various situations; they don't test that waiters are properly awoken on state
215 // changes. (For that, we need to use multiple threads.)
216 TEST(LocalDataPipeTest, BasicProducerWaiting) {
217 // Note: We take advantage of the fact that for |LocalDataPipe|, capacities
218 // are strict maximums. This is not guaranteed by the API.
219
220 const MojoCreateDataPipeOptions options = {
221 kSizeOfOptions, // |struct_size|.
222 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
223 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
224 2 * sizeof(int32_t) // |capacity_num_bytes|.
225 };
226 MojoCreateDataPipeOptions validated_options = {0};
227 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
228 MakeUserPointer(&options), &validated_options));
229
230 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
231 Waiter waiter;
232 uint32_t context = 0;
233 HandleSignalsState hss;
234
235 // Never readable.
236 waiter.Init();
237 hss = HandleSignalsState();
238 EXPECT_EQ(
239 MOJO_RESULT_FAILED_PRECONDITION,
240 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 12, &hss));
241 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
242 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
243 hss.satisfiable_signals);
244
245 // Already writable.
246 waiter.Init();
247 hss = HandleSignalsState();
248 EXPECT_EQ(
249 MOJO_RESULT_ALREADY_EXISTS,
250 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 34, &hss));
251
252 // Write two elements.
253 int32_t elements[2] = {123, 456};
254 uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
255 EXPECT_EQ(MOJO_RESULT_OK,
256 dp->ProducerWriteData(UserPointer<const void>(elements),
257 MakeUserPointer(&num_bytes), true));
258 EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
259
260 // Adding a waiter should now succeed.
261 waiter.Init();
262 ASSERT_EQ(MOJO_RESULT_OK,
263 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 56,
264 nullptr));
265 // And it shouldn't be writable yet.
266 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
267 hss = HandleSignalsState();
268 dp->ProducerRemoveAwakable(&waiter, &hss);
269 EXPECT_EQ(0u, hss.satisfied_signals);
270 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
271 hss.satisfiable_signals);
272
273 // Peek one element.
274 elements[0] = -1;
275 elements[1] = -1;
276 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
277 EXPECT_EQ(MOJO_RESULT_OK,
278 dp->ConsumerReadData(UserPointer<void>(elements),
279 MakeUserPointer(&num_bytes), true, true));
280 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
281 EXPECT_EQ(123, elements[0]);
282 EXPECT_EQ(-1, elements[1]);
283
284 // Add a waiter.
285 waiter.Init();
286 ASSERT_EQ(MOJO_RESULT_OK,
287 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 56,
288 nullptr));
289 // And it still shouldn't be writable yet.
290 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
291 hss = HandleSignalsState();
292 dp->ProducerRemoveAwakable(&waiter, &hss);
293 EXPECT_EQ(0u, hss.satisfied_signals);
294 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
295 hss.satisfiable_signals);
296
297 // Do it again.
298 waiter.Init();
299 ASSERT_EQ(MOJO_RESULT_OK,
300 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 78,
301 nullptr));
302
303 // Read one element.
304 elements[0] = -1;
305 elements[1] = -1;
306 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
307 EXPECT_EQ(MOJO_RESULT_OK,
308 dp->ConsumerReadData(UserPointer<void>(elements),
309 MakeUserPointer(&num_bytes), true, false));
310 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
311 EXPECT_EQ(123, elements[0]);
312 EXPECT_EQ(-1, elements[1]);
313
314 // Waiting should now succeed.
315 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
316 EXPECT_EQ(78u, context);
317 hss = HandleSignalsState();
318 dp->ProducerRemoveAwakable(&waiter, &hss);
319 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
320 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
321 hss.satisfiable_signals);
322
323 // Try writing, using a two-phase write.
324 void* buffer = nullptr;
325 num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
326 EXPECT_EQ(MOJO_RESULT_OK,
327 dp->ProducerBeginWriteData(MakeUserPointer(&buffer),
328 MakeUserPointer(&num_bytes), false));
329 EXPECT_TRUE(buffer);
330 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
331
332 static_cast<int32_t*>(buffer)[0] = 789;
333 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(static_cast<uint32_t>(
334 1u * sizeof(elements[0]))));
335
336 // Add a waiter.
337 waiter.Init();
338 ASSERT_EQ(MOJO_RESULT_OK,
339 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 90,
340 nullptr));
341
342 // Read one element, using a two-phase read.
343 const void* read_buffer = nullptr;
344 num_bytes = 0u;
345 EXPECT_EQ(MOJO_RESULT_OK,
346 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
347 MakeUserPointer(&num_bytes), false));
348 EXPECT_TRUE(read_buffer);
349 // Since we only read one element (after having written three in all), the
350 // two-phase read should only allow us to read one. This checks an
351 // implementation detail!
352 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
353 EXPECT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]);
354 EXPECT_EQ(
355 MOJO_RESULT_OK,
356 dp->ConsumerEndReadData(static_cast<uint32_t>(1u * sizeof(elements[0]))));
357
358 // Waiting should succeed.
359 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
360 EXPECT_EQ(90u, context);
361 hss = HandleSignalsState();
362 dp->ProducerRemoveAwakable(&waiter, &hss);
363 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
364 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
365 hss.satisfiable_signals);
366
367 // Write one element.
368 elements[0] = 123;
369 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
370 EXPECT_EQ(MOJO_RESULT_OK,
371 dp->ProducerWriteData(UserPointer<const void>(elements),
372 MakeUserPointer(&num_bytes), false));
373 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
374
375 // Add a waiter.
376 waiter.Init();
377 ASSERT_EQ(MOJO_RESULT_OK,
378 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 12,
379 nullptr));
380
381 // Close the consumer.
382 dp->ConsumerClose();
383
384 // It should now be never-writable.
385 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000, &context));
386 EXPECT_EQ(12u, context);
387 hss = HandleSignalsState();
388 dp->ProducerRemoveAwakable(&waiter, &hss);
389 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
390 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
391
392 dp->ProducerClose();
393 }
394
395 TEST(LocalDataPipeTest, PeerClosedWaiting) {
396 const MojoCreateDataPipeOptions options = {
397 kSizeOfOptions, // |struct_size|.
398 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
399 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
400 2 * sizeof(int32_t) // |capacity_num_bytes|.
401 };
402 MojoCreateDataPipeOptions validated_options = {0};
403 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
404 MakeUserPointer(&options), &validated_options));
405
406 Waiter waiter;
407 HandleSignalsState hss;
408
409 // Check MOJO_HANDLE_SIGNAL_PEER_CLOSED on producer.
410 {
411 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
412 // Add a waiter.
413 waiter.Init();
414 ASSERT_EQ(MOJO_RESULT_OK,
415 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
416 12, nullptr));
417
418 // Close the consumer.
419 dp->ConsumerClose();
420
421 // It should be signaled.
422 uint32_t context = 0;
423 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
424 EXPECT_EQ(12u, context);
425 hss = HandleSignalsState();
426 dp->ProducerRemoveAwakable(&waiter, &hss);
427 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
428 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
429
430 dp->ProducerClose();
431 }
432
433 // Check MOJO_HANDLE_SIGNAL_PEER_CLOSED on consumer.
434 {
435 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
436 // Add a waiter.
437 waiter.Init();
438 ASSERT_EQ(MOJO_RESULT_OK,
439 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
440 12, nullptr));
441
442 // Close the producer.
443 dp->ProducerClose();
444
445 // It should be signaled.
446 uint32_t context = 0;
447 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
448 EXPECT_EQ(12u, context);
449 hss = HandleSignalsState();
450 dp->ConsumerRemoveAwakable(&waiter, &hss);
451 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
452 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
453
454 dp->ConsumerClose();
455 }
456 }
457
458 TEST(LocalDataPipeTest, BasicConsumerWaiting) {
459 const MojoCreateDataPipeOptions options = {
460 kSizeOfOptions, // |struct_size|.
461 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
462 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
463 1000 * sizeof(int32_t) // |capacity_num_bytes|.
464 };
465 MojoCreateDataPipeOptions validated_options = {0};
466 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
467 MakeUserPointer(&options), &validated_options));
468
469 {
470 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
471 Waiter waiter;
472 uint32_t context = 0;
473 HandleSignalsState hss;
474
475 // Never writable.
476 waiter.Init();
477 hss = HandleSignalsState();
478 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
479 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 12,
480 &hss));
481 EXPECT_EQ(0u, hss.satisfied_signals);
482 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
483 hss.satisfiable_signals);
484
485 // Not yet readable.
486 waiter.Init();
487 ASSERT_EQ(MOJO_RESULT_OK,
488 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
489 nullptr));
490 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
491 hss = HandleSignalsState();
492 dp->ConsumerRemoveAwakable(&waiter, &hss);
493 EXPECT_EQ(0u, hss.satisfied_signals);
494 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
495 hss.satisfiable_signals);
496
497 // Write two elements.
498 int32_t elements[2] = {123, 456};
499 uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
500 EXPECT_EQ(MOJO_RESULT_OK,
501 dp->ProducerWriteData(UserPointer<const void>(elements),
502 MakeUserPointer(&num_bytes), true));
503
504 // Should already be readable.
505 waiter.Init();
506 hss = HandleSignalsState();
507 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
508 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 56,
509 &hss));
510 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
511 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
512 hss.satisfiable_signals);
513
514 // Discard one element.
515 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
516 EXPECT_EQ(MOJO_RESULT_OK,
517 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
518 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
519
520 // Should still be readable.
521 waiter.Init();
522 hss = HandleSignalsState();
523 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
524 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 78,
525 &hss));
526 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
527 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
528 hss.satisfiable_signals);
529
530 // Peek one element.
531 elements[0] = -1;
532 elements[1] = -1;
533 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
534 EXPECT_EQ(MOJO_RESULT_OK,
535 dp->ConsumerReadData(UserPointer<void>(elements),
536 MakeUserPointer(&num_bytes), true, true));
537 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
538 EXPECT_EQ(456, elements[0]);
539 EXPECT_EQ(-1, elements[1]);
540
541 // Should still be readable.
542 waiter.Init();
543 hss = HandleSignalsState();
544 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
545 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 78,
546 &hss));
547 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
548 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
549 hss.satisfiable_signals);
550
551 // Read one element.
552 elements[0] = -1;
553 elements[1] = -1;
554 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
555 EXPECT_EQ(MOJO_RESULT_OK,
556 dp->ConsumerReadData(UserPointer<void>(elements),
557 MakeUserPointer(&num_bytes), true, false));
558 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
559 EXPECT_EQ(456, elements[0]);
560 EXPECT_EQ(-1, elements[1]);
561
562 // Adding a waiter should now succeed.
563 waiter.Init();
564 ASSERT_EQ(MOJO_RESULT_OK,
565 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 90,
566 nullptr));
567
568 // Write one element.
569 elements[0] = 789;
570 elements[1] = -1;
571 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
572 EXPECT_EQ(MOJO_RESULT_OK,
573 dp->ProducerWriteData(UserPointer<const void>(elements),
574 MakeUserPointer(&num_bytes), true));
575
576 // Waiting should now succeed.
577 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
578 EXPECT_EQ(90u, context);
579 hss = HandleSignalsState();
580 dp->ConsumerRemoveAwakable(&waiter, &hss);
581 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
582 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
583 hss.satisfiable_signals);
584
585 // Close the producer.
586 dp->ProducerClose();
587
588 // Should still be readable.
589 waiter.Init();
590 hss = HandleSignalsState();
591 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
592 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 12,
593 &hss));
594 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
595 hss.satisfied_signals);
596 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
597 hss.satisfiable_signals);
598
599 // Read one element.
600 elements[0] = -1;
601 elements[1] = -1;
602 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
603 EXPECT_EQ(MOJO_RESULT_OK,
604 dp->ConsumerReadData(UserPointer<void>(elements),
605 MakeUserPointer(&num_bytes), true, false));
606 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
607 EXPECT_EQ(789, elements[0]);
608 EXPECT_EQ(-1, elements[1]);
609
610 // Should be never-readable.
611 waiter.Init();
612 hss = HandleSignalsState();
613 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
614 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
615 &hss));
616 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
617 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
618
619 dp->ConsumerClose();
620 }
621
622 // Test with two-phase APIs and closing the producer with an active consumer
623 // waiter.
624 {
625 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
626 Waiter waiter;
627 uint32_t context = 0;
628 HandleSignalsState hss;
629
630 // Write two elements.
631 int32_t* elements = nullptr;
632 void* buffer = nullptr;
633 // Request room for three (but we'll only write two).
634 uint32_t num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
635 EXPECT_EQ(MOJO_RESULT_OK,
636 dp->ProducerBeginWriteData(MakeUserPointer(&buffer),
637 MakeUserPointer(&num_bytes), true));
638 EXPECT_TRUE(buffer);
639 EXPECT_GE(num_bytes, static_cast<uint32_t>(3u * sizeof(elements[0])));
640 elements = static_cast<int32_t*>(buffer);
641 elements[0] = 123;
642 elements[1] = 456;
643 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(static_cast<uint32_t>(
644 2u * sizeof(elements[0]))));
645
646 // Should already be readable.
647 waiter.Init();
648 hss = HandleSignalsState();
649 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
650 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 12,
651 &hss));
652 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
653 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
654 hss.satisfiable_signals);
655
656 // Read one element.
657 // Request two in all-or-none mode, but only read one.
658 const void* read_buffer = nullptr;
659 num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
660 EXPECT_EQ(MOJO_RESULT_OK,
661 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
662 MakeUserPointer(&num_bytes), true));
663 EXPECT_TRUE(read_buffer);
664 EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
665 const int32_t* read_elements = static_cast<const int32_t*>(read_buffer);
666 EXPECT_EQ(123, read_elements[0]);
667 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(static_cast<uint32_t>(
668 1u * sizeof(elements[0]))));
669
670 // Should still be readable.
671 waiter.Init();
672 hss = HandleSignalsState();
673 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
674 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
675 &hss));
676 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
677 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
678 hss.satisfiable_signals);
679
680 // Read one element.
681 // Request three, but not in all-or-none mode.
682 read_buffer = nullptr;
683 num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
684 EXPECT_EQ(MOJO_RESULT_OK,
685 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
686 MakeUserPointer(&num_bytes), false));
687 EXPECT_TRUE(read_buffer);
688 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
689 read_elements = static_cast<const int32_t*>(read_buffer);
690 EXPECT_EQ(456, read_elements[0]);
691 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(static_cast<uint32_t>(
692 1u * sizeof(elements[0]))));
693
694 // Adding a waiter should now succeed.
695 waiter.Init();
696 ASSERT_EQ(MOJO_RESULT_OK,
697 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 56,
698 nullptr));
699
700 // Close the producer.
701 dp->ProducerClose();
702
703 // Should be never-readable.
704 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000, &context));
705 EXPECT_EQ(56u, context);
706 hss = HandleSignalsState();
707 dp->ConsumerRemoveAwakable(&waiter, &hss);
708 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
709 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
710
711 dp->ConsumerClose();
712 }
713 }
714
715 // Tests that data pipes aren't writable/readable during two-phase writes/reads.
716 TEST(LocalDataPipeTest, BasicTwoPhaseWaiting) {
717 const MojoCreateDataPipeOptions options = {
718 kSizeOfOptions, // |struct_size|.
719 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
720 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
721 1000 * sizeof(int32_t) // |capacity_num_bytes|.
722 };
723 MojoCreateDataPipeOptions validated_options = {0};
724 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
725 MakeUserPointer(&options), &validated_options));
726
727 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
728 Waiter waiter;
729 HandleSignalsState hss;
730
731 // It should be writable.
732 waiter.Init();
733 hss = HandleSignalsState();
734 EXPECT_EQ(
735 MOJO_RESULT_ALREADY_EXISTS,
736 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
737 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
738 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
739 hss.satisfiable_signals);
740
741 uint32_t num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
742 void* write_ptr = nullptr;
743 EXPECT_EQ(MOJO_RESULT_OK,
744 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
745 MakeUserPointer(&num_bytes), false));
746 EXPECT_TRUE(write_ptr);
747 EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
748
749 // At this point, it shouldn't be writable.
750 waiter.Init();
751 ASSERT_EQ(MOJO_RESULT_OK,
752 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 1,
753 nullptr));
754 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
755 hss = HandleSignalsState();
756 dp->ProducerRemoveAwakable(&waiter, &hss);
757 EXPECT_EQ(0u, hss.satisfied_signals);
758 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
759 hss.satisfiable_signals);
760
761 // It shouldn't be readable yet either.
762 waiter.Init();
763 ASSERT_EQ(MOJO_RESULT_OK,
764 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 2,
765 nullptr));
766 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
767 hss = HandleSignalsState();
768 dp->ConsumerRemoveAwakable(&waiter, &hss);
769 EXPECT_EQ(0u, hss.satisfied_signals);
770 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
771 hss.satisfiable_signals);
772
773 static_cast<int32_t*>(write_ptr)[0] = 123;
774 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(
775 static_cast<uint32_t>(1u * sizeof(int32_t))));
776
777 // It should be writable again.
778 waiter.Init();
779 hss = HandleSignalsState();
780 EXPECT_EQ(
781 MOJO_RESULT_ALREADY_EXISTS,
782 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 3, &hss));
783 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
784 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
785 hss.satisfiable_signals);
786
787 // And readable.
788 waiter.Init();
789 hss = HandleSignalsState();
790 EXPECT_EQ(
791 MOJO_RESULT_ALREADY_EXISTS,
792 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 4, &hss));
793 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
794 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
795 hss.satisfiable_signals);
796
797 // Start another two-phase write and check that it's readable even in the
798 // middle of it.
799 num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
800 write_ptr = nullptr;
801 EXPECT_EQ(MOJO_RESULT_OK,
802 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
803 MakeUserPointer(&num_bytes), false));
804 EXPECT_TRUE(write_ptr);
805 EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
806
807 // It should be readable.
808 waiter.Init();
809 hss = HandleSignalsState();
810 EXPECT_EQ(
811 MOJO_RESULT_ALREADY_EXISTS,
812 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 5, &hss));
813 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
814 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
815 hss.satisfiable_signals);
816
817 // End the two-phase write without writing anything.
818 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
819
820 // Start a two-phase read.
821 num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
822 const void* read_ptr = nullptr;
823 EXPECT_EQ(MOJO_RESULT_OK,
824 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
825 MakeUserPointer(&num_bytes), false));
826 EXPECT_TRUE(read_ptr);
827 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(int32_t)), num_bytes);
828
829 // At this point, it should still be writable.
830 waiter.Init();
831 hss = HandleSignalsState();
832 EXPECT_EQ(
833 MOJO_RESULT_ALREADY_EXISTS,
834 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 6, &hss));
835 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
836 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
837 hss.satisfiable_signals);
838
839 // But not readable.
840 waiter.Init();
841 ASSERT_EQ(MOJO_RESULT_OK,
842 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 7,
843 nullptr));
844 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
845 hss = HandleSignalsState();
846 dp->ConsumerRemoveAwakable(&waiter, &hss);
847 EXPECT_EQ(0u, hss.satisfied_signals);
848 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
849 hss.satisfiable_signals);
850
851 // End the two-phase read without reading anything.
852 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
853
854 // It should be readable again.
855 waiter.Init();
856 hss = HandleSignalsState();
857 EXPECT_EQ(
858 MOJO_RESULT_ALREADY_EXISTS,
859 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 8, &hss));
860 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
861 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
862 hss.satisfiable_signals);
863
864 dp->ProducerClose();
865 dp->ConsumerClose();
866 }
867
868 // Test that a "may discard" data pipe is writable even when it's full.
869 TEST(LocalDataPipeTest, BasicMayDiscardWaiting) {
870 const MojoCreateDataPipeOptions options = {
871 kSizeOfOptions, // |struct_size|.
872 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
873 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
874 1 * sizeof(int32_t) // |capacity_num_bytes|.
875 };
876 MojoCreateDataPipeOptions validated_options = {0};
877 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
878 MakeUserPointer(&options), &validated_options));
879
880 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
881 Waiter waiter;
882 HandleSignalsState hss;
883
884 // Writable.
885 waiter.Init();
886 hss = HandleSignalsState();
887 EXPECT_EQ(
888 MOJO_RESULT_ALREADY_EXISTS,
889 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
890 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
891 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
892 hss.satisfiable_signals);
893
894 // Not readable.
895 waiter.Init();
896 ASSERT_EQ(MOJO_RESULT_OK,
897 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 1,
898 nullptr));
899 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
900 hss = HandleSignalsState();
901 dp->ConsumerRemoveAwakable(&waiter, &hss);
902 EXPECT_EQ(0u, hss.satisfied_signals);
903 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
904 hss.satisfiable_signals);
905
906 uint32_t num_bytes = static_cast<uint32_t>(sizeof(int32_t));
907 int32_t element = 123;
908 EXPECT_EQ(MOJO_RESULT_OK,
909 dp->ProducerWriteData(UserPointer<const void>(&element),
910 MakeUserPointer(&num_bytes), false));
911 EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
912
913 // Still writable (even though it's full).
914 waiter.Init();
915 hss = HandleSignalsState();
916 EXPECT_EQ(
917 MOJO_RESULT_ALREADY_EXISTS,
918 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 2, &hss));
919 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
920 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
921 hss.satisfiable_signals);
922
923 // Now readable.
924 waiter.Init();
925 hss = HandleSignalsState();
926 EXPECT_EQ(
927 MOJO_RESULT_ALREADY_EXISTS,
928 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 3, &hss));
929 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
930 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
931 hss.satisfiable_signals);
932
933 // Overwrite that element.
934 num_bytes = static_cast<uint32_t>(sizeof(int32_t));
935 element = 456;
936 EXPECT_EQ(MOJO_RESULT_OK,
937 dp->ProducerWriteData(UserPointer<const void>(&element),
938 MakeUserPointer(&num_bytes), false));
939 EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
940
941 // Still writable.
942 waiter.Init();
943 hss = HandleSignalsState();
944 EXPECT_EQ(
945 MOJO_RESULT_ALREADY_EXISTS,
946 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4, &hss));
947 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
948 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
949 hss.satisfiable_signals);
950
951 // And still readable.
952 waiter.Init();
953 hss = HandleSignalsState();
954 EXPECT_EQ(
955 MOJO_RESULT_ALREADY_EXISTS,
956 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 5, &hss));
957 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
958 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
959 hss.satisfiable_signals);
960
961 // Read that element.
962 num_bytes = static_cast<uint32_t>(sizeof(int32_t));
963 element = 0;
964 EXPECT_EQ(MOJO_RESULT_OK,
965 dp->ConsumerReadData(UserPointer<void>(&element),
966 MakeUserPointer(&num_bytes), false, false));
967 EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
968 EXPECT_EQ(456, element);
969
970 // Still writable.
971 waiter.Init();
972 hss = HandleSignalsState();
973 EXPECT_EQ(
974 MOJO_RESULT_ALREADY_EXISTS,
975 dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 6, &hss));
976 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
977 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
978 hss.satisfiable_signals);
979
980 // No longer readable.
981 waiter.Init();
982 ASSERT_EQ(MOJO_RESULT_OK,
983 dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 7,
984 nullptr));
985 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
986 hss = HandleSignalsState();
987 dp->ConsumerRemoveAwakable(&waiter, &hss);
988 EXPECT_EQ(0u, hss.satisfied_signals);
989 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
990 hss.satisfiable_signals);
991
992 dp->ProducerClose();
993 dp->ConsumerClose();
994 }
995
996 void Seq(int32_t start, size_t count, int32_t* out) {
997 for (size_t i = 0; i < count; i++)
998 out[i] = start + static_cast<int32_t>(i);
999 }
1000
1001 TEST(LocalDataPipeTest, MayDiscard) {
1002 const MojoCreateDataPipeOptions options = {
1003 kSizeOfOptions, // |struct_size|.
1004 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
1005 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
1006 10 * sizeof(int32_t) // |capacity_num_bytes|.
1007 };
1008 MojoCreateDataPipeOptions validated_options = {0};
1009 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1010 MakeUserPointer(&options), &validated_options));
1011
1012 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1013
1014 int32_t buffer[100] = {0};
1015 uint32_t num_bytes = 0;
1016
1017 num_bytes = 20u * sizeof(int32_t);
1018 Seq(0, arraysize(buffer), buffer);
1019 // Try writing more than capacity. (This test relies on the implementation
1020 // enforcing the capacity strictly.)
1021 EXPECT_EQ(MOJO_RESULT_OK,
1022 dp->ProducerWriteData(UserPointer<const void>(buffer),
1023 MakeUserPointer(&num_bytes), false));
1024 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
1025
1026 // Read half of what we wrote.
1027 num_bytes = 5u * sizeof(int32_t);
1028 memset(buffer, 0xab, sizeof(buffer));
1029 EXPECT_EQ(MOJO_RESULT_OK,
1030 dp->ConsumerReadData(UserPointer<void>(buffer),
1031 MakeUserPointer(&num_bytes), false, false));
1032 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1033 int32_t expected_buffer[100];
1034 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1035 Seq(0, 5u, expected_buffer);
1036 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1037 // Internally, a circular buffer would now look like:
1038 // -, -, -, -, -, 5, 6, 7, 8, 9
1039
1040 // Write a bit more than the space that's available.
1041 num_bytes = 8u * sizeof(int32_t);
1042 Seq(100, arraysize(buffer), buffer);
1043 EXPECT_EQ(MOJO_RESULT_OK,
1044 dp->ProducerWriteData(UserPointer<const void>(buffer),
1045 MakeUserPointer(&num_bytes), false));
1046 EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
1047 // Internally, a circular buffer would now look like:
1048 // 100, 101, 102, 103, 104, 105, 106, 107, 8, 9
1049
1050 // Read half of what's available.
1051 num_bytes = 5u * sizeof(int32_t);
1052 memset(buffer, 0xab, sizeof(buffer));
1053 EXPECT_EQ(MOJO_RESULT_OK,
1054 dp->ConsumerReadData(UserPointer<void>(buffer),
1055 MakeUserPointer(&num_bytes), false, false));
1056 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1057 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1058 expected_buffer[0] = 8;
1059 expected_buffer[1] = 9;
1060 expected_buffer[2] = 100;
1061 expected_buffer[3] = 101;
1062 expected_buffer[4] = 102;
1063 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1064 // Internally, a circular buffer would now look like:
1065 // -, -, -, 103, 104, 105, 106, 107, -, -
1066
1067 // Write one integer.
1068 num_bytes = 1u * sizeof(int32_t);
1069 Seq(200, arraysize(buffer), buffer);
1070 EXPECT_EQ(MOJO_RESULT_OK,
1071 dp->ProducerWriteData(UserPointer<const void>(buffer),
1072 MakeUserPointer(&num_bytes), false));
1073 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1074 // Internally, a circular buffer would now look like:
1075 // -, -, -, 103, 104, 105, 106, 107, 200, -
1076
1077 // Write five more.
1078 num_bytes = 5u * sizeof(int32_t);
1079 Seq(300, arraysize(buffer), buffer);
1080 EXPECT_EQ(MOJO_RESULT_OK,
1081 dp->ProducerWriteData(UserPointer<const void>(buffer),
1082 MakeUserPointer(&num_bytes), false));
1083 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1084 // Internally, a circular buffer would now look like:
1085 // 301, 302, 303, 304, 104, 105, 106, 107, 200, 300
1086
1087 // Read it all.
1088 num_bytes = sizeof(buffer);
1089 memset(buffer, 0xab, sizeof(buffer));
1090 EXPECT_EQ(MOJO_RESULT_OK,
1091 dp->ConsumerReadData(UserPointer<void>(buffer),
1092 MakeUserPointer(&num_bytes), false, false));
1093 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
1094 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1095 expected_buffer[0] = 104;
1096 expected_buffer[1] = 105;
1097 expected_buffer[2] = 106;
1098 expected_buffer[3] = 107;
1099 expected_buffer[4] = 200;
1100 expected_buffer[5] = 300;
1101 expected_buffer[6] = 301;
1102 expected_buffer[7] = 302;
1103 expected_buffer[8] = 303;
1104 expected_buffer[9] = 304;
1105 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1106
1107 // Test two-phase writes, including in all-or-none mode.
1108 // Note: Again, the following depends on an implementation detail -- namely
1109 // that the write pointer will point at the 5th element of the buffer (and the
1110 // buffer has exactly the capacity requested).
1111
1112 num_bytes = 0u;
1113 void* write_ptr = nullptr;
1114 EXPECT_EQ(MOJO_RESULT_OK,
1115 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1116 MakeUserPointer(&num_bytes), false));
1117 EXPECT_TRUE(write_ptr);
1118 EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
1119 Seq(400, 6, static_cast<int32_t*>(write_ptr));
1120 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(6u * sizeof(int32_t)));
1121 // Internally, a circular buffer would now look like:
1122 // -, -, -, -, 400, 401, 402, 403, 404, 405
1123
1124 // |ProducerBeginWriteData()| ignores |*num_bytes| except in "all-or-none"
1125 // mode.
1126 num_bytes = 6u * sizeof(int32_t);
1127 write_ptr = nullptr;
1128 EXPECT_EQ(MOJO_RESULT_OK,
1129 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1130 MakeUserPointer(&num_bytes), false));
1131 EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
1132 static_cast<int32_t*>(write_ptr)[0] = 500;
1133 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(1u * sizeof(int32_t)));
1134 // Internally, a circular buffer would now look like:
1135 // 500, -, -, -, 400, 401, 402, 403, 404, 405
1136
1137 // Requesting a 10-element buffer in all-or-none mode fails at this point.
1138 num_bytes = 10u * sizeof(int32_t);
1139 write_ptr = nullptr;
1140 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1141 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1142 MakeUserPointer(&num_bytes), true));
1143
1144 // But requesting, say, a 5-element (up to 9, really) buffer should be okay.
1145 // It will discard two elements.
1146 num_bytes = 5u * sizeof(int32_t);
1147 write_ptr = nullptr;
1148 EXPECT_EQ(MOJO_RESULT_OK,
1149 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1150 MakeUserPointer(&num_bytes), true));
1151 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1152 // Only write 4 elements though.
1153 Seq(600, 4, static_cast<int32_t*>(write_ptr));
1154 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(4u * sizeof(int32_t)));
1155 // Internally, a circular buffer would now look like:
1156 // 500, 600, 601, 602, 603, -, 402, 403, 404, 405
1157
1158 // Do this again. Make sure we can get a buffer all the way out to the end of
1159 // the internal buffer.
1160 num_bytes = 5u * sizeof(int32_t);
1161 write_ptr = nullptr;
1162 EXPECT_EQ(MOJO_RESULT_OK,
1163 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1164 MakeUserPointer(&num_bytes), true));
1165 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1166 // Only write 3 elements though.
1167 Seq(700, 3, static_cast<int32_t*>(write_ptr));
1168 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(3u * sizeof(int32_t)));
1169 // Internally, a circular buffer would now look like:
1170 // 500, 600, 601, 602, 603, 700, 701, 702, -, -
1171
1172 // Read everything.
1173 num_bytes = sizeof(buffer);
1174 memset(buffer, 0xab, sizeof(buffer));
1175 EXPECT_EQ(MOJO_RESULT_OK,
1176 dp->ConsumerReadData(UserPointer<void>(buffer),
1177 MakeUserPointer(&num_bytes), false, false));
1178 EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
1179 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1180 expected_buffer[0] = 500;
1181 expected_buffer[1] = 600;
1182 expected_buffer[2] = 601;
1183 expected_buffer[3] = 602;
1184 expected_buffer[4] = 603;
1185 expected_buffer[5] = 700;
1186 expected_buffer[6] = 701;
1187 expected_buffer[7] = 702;
1188 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1189
1190 dp->ProducerClose();
1191 dp->ConsumerClose();
1192 }
1193
1194 TEST(LocalDataPipeTest, AllOrNone) {
1195 const MojoCreateDataPipeOptions options = {
1196 kSizeOfOptions, // |struct_size|.
1197 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
1198 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
1199 10 * sizeof(int32_t) // |capacity_num_bytes|.
1200 };
1201 MojoCreateDataPipeOptions validated_options = {0};
1202 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1203 MakeUserPointer(&options), &validated_options));
1204
1205 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1206
1207 // Try writing way too much.
1208 uint32_t num_bytes = 20u * sizeof(int32_t);
1209 int32_t buffer[100];
1210 Seq(0, arraysize(buffer), buffer);
1211 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1212 dp->ProducerWriteData(UserPointer<const void>(buffer),
1213 MakeUserPointer(&num_bytes), true));
1214
1215 // Should still be empty.
1216 num_bytes = ~0u;
1217 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1218 EXPECT_EQ(0u, num_bytes);
1219
1220 // Write some data.
1221 num_bytes = 5u * sizeof(int32_t);
1222 Seq(100, arraysize(buffer), buffer);
1223 EXPECT_EQ(MOJO_RESULT_OK,
1224 dp->ProducerWriteData(UserPointer<const void>(buffer),
1225 MakeUserPointer(&num_bytes), true));
1226 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1227
1228 // Half full.
1229 num_bytes = 0u;
1230 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1231 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1232
1233 // Too much.
1234 num_bytes = 6u * sizeof(int32_t);
1235 Seq(200, arraysize(buffer), buffer);
1236 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1237 dp->ProducerWriteData(UserPointer<const void>(buffer),
1238 MakeUserPointer(&num_bytes), true));
1239
1240 // Try reading too much.
1241 num_bytes = 11u * sizeof(int32_t);
1242 memset(buffer, 0xab, sizeof(buffer));
1243 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1244 dp->ConsumerReadData(UserPointer<void>(buffer),
1245 MakeUserPointer(&num_bytes), true, false));
1246 int32_t expected_buffer[100];
1247 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1248 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1249
1250 // Try discarding too much.
1251 num_bytes = 11u * sizeof(int32_t);
1252 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1253 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1254
1255 // Just a little.
1256 num_bytes = 2u * sizeof(int32_t);
1257 Seq(300, arraysize(buffer), buffer);
1258 EXPECT_EQ(MOJO_RESULT_OK,
1259 dp->ProducerWriteData(UserPointer<const void>(buffer),
1260 MakeUserPointer(&num_bytes), true));
1261 EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
1262
1263 // Just right.
1264 num_bytes = 3u * sizeof(int32_t);
1265 Seq(400, arraysize(buffer), buffer);
1266 EXPECT_EQ(MOJO_RESULT_OK,
1267 dp->ProducerWriteData(UserPointer<const void>(buffer),
1268 MakeUserPointer(&num_bytes), true));
1269 EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
1270
1271 // Exactly full.
1272 num_bytes = 0u;
1273 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1274 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
1275
1276 // Read half.
1277 num_bytes = 5u * sizeof(int32_t);
1278 memset(buffer, 0xab, sizeof(buffer));
1279 EXPECT_EQ(MOJO_RESULT_OK,
1280 dp->ConsumerReadData(UserPointer<void>(buffer),
1281 MakeUserPointer(&num_bytes), true, false));
1282 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1283 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1284 Seq(100, 5, expected_buffer);
1285 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1286
1287 // Try reading too much again.
1288 num_bytes = 6u * sizeof(int32_t);
1289 memset(buffer, 0xab, sizeof(buffer));
1290 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1291 dp->ConsumerReadData(UserPointer<void>(buffer),
1292 MakeUserPointer(&num_bytes), true, false));
1293 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1294 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1295
1296 // Try discarding too much again.
1297 num_bytes = 6u * sizeof(int32_t);
1298 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1299 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1300
1301 // Discard a little.
1302 num_bytes = 2u * sizeof(int32_t);
1303 EXPECT_EQ(MOJO_RESULT_OK,
1304 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1305 EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
1306
1307 // Three left.
1308 num_bytes = 0u;
1309 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1310 EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
1311
1312 // Close the producer, then test producer-closed cases.
1313 dp->ProducerClose();
1314
1315 // Try reading too much; "failed precondition" since the producer is closed.
1316 num_bytes = 4u * sizeof(int32_t);
1317 memset(buffer, 0xab, sizeof(buffer));
1318 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1319 dp->ConsumerReadData(UserPointer<void>(buffer),
1320 MakeUserPointer(&num_bytes), true, false));
1321 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1322 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1323
1324 // Try discarding too much; "failed precondition" again.
1325 num_bytes = 4u * sizeof(int32_t);
1326 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1327 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1328
1329 // Read a little.
1330 num_bytes = 2u * sizeof(int32_t);
1331 memset(buffer, 0xab, sizeof(buffer));
1332 EXPECT_EQ(MOJO_RESULT_OK,
1333 dp->ConsumerReadData(UserPointer<void>(buffer),
1334 MakeUserPointer(&num_bytes), true, false));
1335 EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
1336 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1337 Seq(400, 2, expected_buffer);
1338 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1339
1340 // Discard the remaining element.
1341 num_bytes = 1u * sizeof(int32_t);
1342 EXPECT_EQ(MOJO_RESULT_OK,
1343 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1344 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1345
1346 // Empty again.
1347 num_bytes = ~0u;
1348 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1349 EXPECT_EQ(0u, num_bytes);
1350
1351 dp->ConsumerClose();
1352 }
1353
1354 TEST(LocalDataPipeTest, AllOrNoneMayDiscard) {
1355 const MojoCreateDataPipeOptions options = {
1356 kSizeOfOptions, // |struct_size|.
1357 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
1358 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
1359 10 * sizeof(int32_t) // |capacity_num_bytes|.
1360 };
1361 MojoCreateDataPipeOptions validated_options = {0};
1362 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1363 MakeUserPointer(&options), &validated_options));
1364
1365 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1366
1367 // Try writing way too much.
1368 uint32_t num_bytes = 20u * sizeof(int32_t);
1369 int32_t buffer[100];
1370 Seq(0, arraysize(buffer), buffer);
1371 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1372 dp->ProducerWriteData(UserPointer<const void>(buffer),
1373 MakeUserPointer(&num_bytes), true));
1374
1375 // Write some stuff.
1376 num_bytes = 5u * sizeof(int32_t);
1377 Seq(100, arraysize(buffer), buffer);
1378 EXPECT_EQ(MOJO_RESULT_OK,
1379 dp->ProducerWriteData(UserPointer<const void>(buffer),
1380 MakeUserPointer(&num_bytes), true));
1381 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1382
1383 // Write lots of stuff (discarding all but "104").
1384 num_bytes = 9u * sizeof(int32_t);
1385 Seq(200, arraysize(buffer), buffer);
1386 EXPECT_EQ(MOJO_RESULT_OK,
1387 dp->ProducerWriteData(UserPointer<const void>(buffer),
1388 MakeUserPointer(&num_bytes), true));
1389 EXPECT_EQ(9u * sizeof(int32_t), num_bytes);
1390
1391 // Read one.
1392 num_bytes = 1u * sizeof(int32_t);
1393 memset(buffer, 0xab, sizeof(buffer));
1394 EXPECT_EQ(MOJO_RESULT_OK,
1395 dp->ConsumerReadData(UserPointer<void>(buffer),
1396 MakeUserPointer(&num_bytes), true, false));
1397 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1398 int32_t expected_buffer[100];
1399 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1400 expected_buffer[0] = 104;
1401 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1402
1403 // Try reading too many.
1404 num_bytes = 10u * sizeof(int32_t);
1405 memset(buffer, 0xab, sizeof(buffer));
1406 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1407 dp->ConsumerReadData(UserPointer<void>(buffer),
1408 MakeUserPointer(&num_bytes), true, false));
1409 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1410 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1411
1412 // Try discarding too many.
1413 num_bytes = 10u * sizeof(int32_t);
1414 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1415 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1416
1417 // Discard a bunch.
1418 num_bytes = 4u * sizeof(int32_t);
1419 EXPECT_EQ(MOJO_RESULT_OK,
1420 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
1421
1422 // Half full.
1423 num_bytes = 0u;
1424 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1425 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
1426
1427 // Write as much as possible.
1428 num_bytes = 10u * sizeof(int32_t);
1429 Seq(300, arraysize(buffer), buffer);
1430 EXPECT_EQ(MOJO_RESULT_OK,
1431 dp->ProducerWriteData(UserPointer<const void>(buffer),
1432 MakeUserPointer(&num_bytes), true));
1433 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
1434
1435 // Read everything.
1436 num_bytes = 10u * sizeof(int32_t);
1437 memset(buffer, 0xab, sizeof(buffer));
1438 EXPECT_EQ(MOJO_RESULT_OK,
1439 dp->ConsumerReadData(UserPointer<void>(buffer),
1440 MakeUserPointer(&num_bytes), true, false));
1441 memset(expected_buffer, 0xab, sizeof(expected_buffer));
1442 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
1443 Seq(300, 10, expected_buffer);
1444 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
1445
1446 // Note: All-or-none two-phase writes on a "may discard" data pipe are tested
1447 // in LocalDataPipeTest.MayDiscard.
1448
1449 dp->ProducerClose();
1450 dp->ConsumerClose();
1451 }
1452
1453 TEST(LocalDataPipeTest, TwoPhaseAllOrNone) {
1454 const MojoCreateDataPipeOptions options = {
1455 kSizeOfOptions, // |struct_size|.
1456 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
1457 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
1458 10 * sizeof(int32_t) // |capacity_num_bytes|.
1459 };
1460 MojoCreateDataPipeOptions validated_options = {0};
1461 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1462 MakeUserPointer(&options), &validated_options));
1463
1464 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1465
1466 // Try writing way too much (two-phase).
1467 uint32_t num_bytes = 20u * sizeof(int32_t);
1468 void* write_ptr = nullptr;
1469 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1470 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1471 MakeUserPointer(&num_bytes), true));
1472
1473 // Try writing an amount which isn't a multiple of the element size
1474 // (two-phase).
1475 static_assert(sizeof(int32_t) > 1u, "Wow! int32_t's have size 1");
1476 num_bytes = 1u;
1477 write_ptr = nullptr;
1478 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
1479 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1480 MakeUserPointer(&num_bytes), true));
1481
1482 // Try reading way too much (two-phase).
1483 num_bytes = 20u * sizeof(int32_t);
1484 const void* read_ptr = nullptr;
1485 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1486 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1487 MakeUserPointer(&num_bytes), true));
1488
1489 // Write half (two-phase).
1490 num_bytes = 5u * sizeof(int32_t);
1491 write_ptr = nullptr;
1492 EXPECT_EQ(MOJO_RESULT_OK,
1493 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1494 MakeUserPointer(&num_bytes), true));
1495 // May provide more space than requested.
1496 EXPECT_GE(num_bytes, 5u * sizeof(int32_t));
1497 EXPECT_TRUE(write_ptr);
1498 Seq(0, 5, static_cast<int32_t*>(write_ptr));
1499 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(5u * sizeof(int32_t)));
1500
1501 // Try reading an amount which isn't a multiple of the element size
1502 // (two-phase).
1503 num_bytes = 1u;
1504 read_ptr = nullptr;
1505 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
1506 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1507 MakeUserPointer(&num_bytes), true));
1508
1509 // Read one (two-phase).
1510 num_bytes = 1u * sizeof(int32_t);
1511 read_ptr = nullptr;
1512 EXPECT_EQ(MOJO_RESULT_OK,
1513 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1514 MakeUserPointer(&num_bytes), true));
1515 EXPECT_GE(num_bytes, 1u * sizeof(int32_t));
1516 EXPECT_EQ(0, static_cast<const int32_t*>(read_ptr)[0]);
1517 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(1u * sizeof(int32_t)));
1518
1519 // We should have four left, leaving room for six.
1520 num_bytes = 0u;
1521 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1522 EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
1523
1524 // Assuming a tight circular buffer of the specified capacity, we can't do a
1525 // two-phase write of six now.
1526 num_bytes = 6u * sizeof(int32_t);
1527 write_ptr = nullptr;
1528 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1529 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1530 MakeUserPointer(&num_bytes), true));
1531
1532 // Write six elements (simple), filling the buffer.
1533 num_bytes = 6u * sizeof(int32_t);
1534 int32_t buffer[100];
1535 Seq(100, 6, buffer);
1536 EXPECT_EQ(MOJO_RESULT_OK,
1537 dp->ProducerWriteData(UserPointer<const void>(buffer),
1538 MakeUserPointer(&num_bytes), true));
1539 EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
1540
1541 // We have ten.
1542 num_bytes = 0u;
1543 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1544 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
1545
1546 // But a two-phase read of ten should fail.
1547 num_bytes = 10u * sizeof(int32_t);
1548 read_ptr = nullptr;
1549 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
1550 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1551 MakeUserPointer(&num_bytes), true));
1552
1553 // Close the producer.
1554 dp->ProducerClose();
1555
1556 // A two-phase read of nine should work.
1557 num_bytes = 9u * sizeof(int32_t);
1558 read_ptr = nullptr;
1559 EXPECT_EQ(MOJO_RESULT_OK,
1560 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1561 MakeUserPointer(&num_bytes), true));
1562 EXPECT_GE(num_bytes, 9u * sizeof(int32_t));
1563 EXPECT_EQ(1, static_cast<const int32_t*>(read_ptr)[0]);
1564 EXPECT_EQ(2, static_cast<const int32_t*>(read_ptr)[1]);
1565 EXPECT_EQ(3, static_cast<const int32_t*>(read_ptr)[2]);
1566 EXPECT_EQ(4, static_cast<const int32_t*>(read_ptr)[3]);
1567 EXPECT_EQ(100, static_cast<const int32_t*>(read_ptr)[4]);
1568 EXPECT_EQ(101, static_cast<const int32_t*>(read_ptr)[5]);
1569 EXPECT_EQ(102, static_cast<const int32_t*>(read_ptr)[6]);
1570 EXPECT_EQ(103, static_cast<const int32_t*>(read_ptr)[7]);
1571 EXPECT_EQ(104, static_cast<const int32_t*>(read_ptr)[8]);
1572 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(9u * sizeof(int32_t)));
1573
1574 // A two-phase read of two should fail, with "failed precondition".
1575 num_bytes = 2u * sizeof(int32_t);
1576 read_ptr = nullptr;
1577 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1578 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1579 MakeUserPointer(&num_bytes), true));
1580
1581 dp->ConsumerClose();
1582 }
1583
1584 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads,
1585 // respectively, as much as possible, even if it has to "wrap around" the
1586 // internal circular buffer. (Note that the two-phase write and read do not do
1587 // this.)
1588 TEST(LocalDataPipeTest, WrapAround) {
1589 unsigned char test_data[1000];
1590 for (size_t i = 0; i < arraysize(test_data); i++)
1591 test_data[i] = static_cast<unsigned char>(i);
1592
1593 const MojoCreateDataPipeOptions options = {
1594 kSizeOfOptions, // |struct_size|.
1595 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
1596 1u, // |element_num_bytes|.
1597 100u // |capacity_num_bytes|.
1598 };
1599 MojoCreateDataPipeOptions validated_options = {0};
1600 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1601 MakeUserPointer(&options), &validated_options));
1602 // This test won't be valid if |ValidateCreateOptions()| decides to give the
1603 // pipe more space.
1604 ASSERT_EQ(100u, validated_options.capacity_num_bytes);
1605
1606 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1607
1608 // Write 20 bytes.
1609 uint32_t num_bytes = 20u;
1610 EXPECT_EQ(MOJO_RESULT_OK,
1611 dp->ProducerWriteData(UserPointer<const void>(&test_data[0]),
1612 MakeUserPointer(&num_bytes), false));
1613 EXPECT_EQ(20u, num_bytes);
1614
1615 // Read 10 bytes.
1616 unsigned char read_buffer[1000] = {0};
1617 num_bytes = 10u;
1618 EXPECT_EQ(MOJO_RESULT_OK,
1619 dp->ConsumerReadData(UserPointer<void>(read_buffer),
1620 MakeUserPointer(&num_bytes), false, false));
1621 EXPECT_EQ(10u, num_bytes);
1622 EXPECT_EQ(0, memcmp(read_buffer, &test_data[0], 10u));
1623
1624 // Check that a two-phase write can now only write (at most) 80 bytes. (This
1625 // checks an implementation detail; this behavior is not guaranteed, but we
1626 // need it for this test.)
1627 void* write_buffer_ptr = nullptr;
1628 num_bytes = 0u;
1629 EXPECT_EQ(MOJO_RESULT_OK,
1630 dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
1631 MakeUserPointer(&num_bytes), false));
1632 EXPECT_TRUE(write_buffer_ptr);
1633 EXPECT_EQ(80u, num_bytes);
1634 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
1635
1636 // Write as much data as we can (using |ProducerWriteData()|). We should write
1637 // 90 bytes.
1638 num_bytes = 200u;
1639 EXPECT_EQ(MOJO_RESULT_OK,
1640 dp->ProducerWriteData(UserPointer<const void>(&test_data[20]),
1641 MakeUserPointer(&num_bytes), false));
1642 EXPECT_EQ(90u, num_bytes);
1643
1644 // Check that a two-phase read can now only read (at most) 90 bytes. (This
1645 // checks an implementation detail; this behavior is not guaranteed, but we
1646 // need it for this test.)
1647 const void* read_buffer_ptr = nullptr;
1648 num_bytes = 0u;
1649 EXPECT_EQ(MOJO_RESULT_OK,
1650 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
1651 MakeUserPointer(&num_bytes), false));
1652 EXPECT_TRUE(read_buffer_ptr);
1653 EXPECT_EQ(90u, num_bytes);
1654 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
1655
1656 // Read as much as possible (using |ConsumerReadData()|). We should read 100
1657 // bytes.
1658 num_bytes =
1659 static_cast<uint32_t>(arraysize(read_buffer) * sizeof(read_buffer[0]));
1660 memset(read_buffer, 0, num_bytes);
1661 EXPECT_EQ(MOJO_RESULT_OK,
1662 dp->ConsumerReadData(UserPointer<void>(read_buffer),
1663 MakeUserPointer(&num_bytes), false, false));
1664 EXPECT_EQ(100u, num_bytes);
1665 EXPECT_EQ(0, memcmp(read_buffer, &test_data[10], 100u));
1666
1667 dp->ProducerClose();
1668 dp->ConsumerClose();
1669 }
1670
1671 // Tests the behavior of closing the producer or consumer with respect to
1672 // writes and reads (simple and two-phase).
1673 TEST(LocalDataPipeTest, CloseWriteRead) {
1674 const char kTestData[] = "hello world";
1675 const uint32_t kTestDataSize = static_cast<uint32_t>(sizeof(kTestData));
1676
1677 const MojoCreateDataPipeOptions options = {
1678 kSizeOfOptions, // |struct_size|.
1679 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
1680 1u, // |element_num_bytes|.
1681 1000u // |capacity_num_bytes|.
1682 };
1683 MojoCreateDataPipeOptions validated_options = {0};
1684 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1685 MakeUserPointer(&options), &validated_options));
1686
1687 // Close producer first, then consumer.
1688 {
1689 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1690
1691 // Write some data, so we'll have something to read.
1692 uint32_t num_bytes = kTestDataSize;
1693 EXPECT_EQ(MOJO_RESULT_OK,
1694 dp->ProducerWriteData(UserPointer<const void>(kTestData),
1695 MakeUserPointer(&num_bytes), false));
1696 EXPECT_EQ(kTestDataSize, num_bytes);
1697
1698 // Write it again, so we'll have something left over.
1699 num_bytes = kTestDataSize;
1700 EXPECT_EQ(MOJO_RESULT_OK,
1701 dp->ProducerWriteData(UserPointer<const void>(kTestData),
1702 MakeUserPointer(&num_bytes), false));
1703 EXPECT_EQ(kTestDataSize, num_bytes);
1704
1705 // Start two-phase write.
1706 void* write_buffer_ptr = nullptr;
1707 num_bytes = 0u;
1708 EXPECT_EQ(MOJO_RESULT_OK,
1709 dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
1710 MakeUserPointer(&num_bytes), false));
1711 EXPECT_TRUE(write_buffer_ptr);
1712 EXPECT_GT(num_bytes, 0u);
1713
1714 // Start two-phase read.
1715 const void* read_buffer_ptr = nullptr;
1716 num_bytes = 0u;
1717 EXPECT_EQ(MOJO_RESULT_OK,
1718 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
1719 MakeUserPointer(&num_bytes), false));
1720 EXPECT_TRUE(read_buffer_ptr);
1721 EXPECT_EQ(2u * kTestDataSize, num_bytes);
1722
1723 // Close the producer.
1724 dp->ProducerClose();
1725
1726 // The consumer can finish its two-phase read.
1727 EXPECT_EQ(0, memcmp(read_buffer_ptr, kTestData, kTestDataSize));
1728 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(kTestDataSize));
1729
1730 // And start another.
1731 read_buffer_ptr = nullptr;
1732 num_bytes = 0u;
1733 EXPECT_EQ(MOJO_RESULT_OK,
1734 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
1735 MakeUserPointer(&num_bytes), false));
1736 EXPECT_TRUE(read_buffer_ptr);
1737 EXPECT_EQ(kTestDataSize, num_bytes);
1738
1739 // Close the consumer, which cancels the two-phase read.
1740 dp->ConsumerClose();
1741 }
1742
1743 // Close consumer first, then producer.
1744 {
1745 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1746
1747 // Write some data, so we'll have something to read.
1748 uint32_t num_bytes = kTestDataSize;
1749 EXPECT_EQ(MOJO_RESULT_OK,
1750 dp->ProducerWriteData(UserPointer<const void>(kTestData),
1751 MakeUserPointer(&num_bytes), false));
1752 EXPECT_EQ(kTestDataSize, num_bytes);
1753
1754 // Start two-phase write.
1755 void* write_buffer_ptr = nullptr;
1756 num_bytes = 0u;
1757 EXPECT_EQ(MOJO_RESULT_OK,
1758 dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
1759 MakeUserPointer(&num_bytes), false));
1760 EXPECT_TRUE(write_buffer_ptr);
1761 ASSERT_GT(num_bytes, kTestDataSize);
1762
1763 // Start two-phase read.
1764 const void* read_buffer_ptr = nullptr;
1765 num_bytes = 0u;
1766 EXPECT_EQ(MOJO_RESULT_OK,
1767 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
1768 MakeUserPointer(&num_bytes), false));
1769 EXPECT_TRUE(read_buffer_ptr);
1770 EXPECT_EQ(kTestDataSize, num_bytes);
1771
1772 // Close the consumer.
1773 dp->ConsumerClose();
1774
1775 // Actually write some data. (Note: Premature freeing of the buffer would
1776 // probably only be detected under ASAN or similar.)
1777 memcpy(write_buffer_ptr, kTestData, kTestDataSize);
1778 // Note: Even though the consumer has been closed, ending the two-phase
1779 // write will report success.
1780 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(kTestDataSize));
1781
1782 // But trying to write should result in failure.
1783 num_bytes = kTestDataSize;
1784 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1785 dp->ProducerWriteData(UserPointer<const void>(kTestData),
1786 MakeUserPointer(&num_bytes), false));
1787
1788 // As will trying to start another two-phase write.
1789 write_buffer_ptr = nullptr;
1790 num_bytes = 0u;
1791 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1792 dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
1793 MakeUserPointer(&num_bytes), false));
1794
1795 dp->ProducerClose();
1796 }
1797
1798 // Test closing the consumer first, then the producer, with an active
1799 // two-phase write.
1800 {
1801 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1802
1803 // Start two-phase write.
1804 void* write_buffer_ptr = nullptr;
1805 uint32_t num_bytes = 0u;
1806 EXPECT_EQ(MOJO_RESULT_OK,
1807 dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
1808 MakeUserPointer(&num_bytes), false));
1809 EXPECT_TRUE(write_buffer_ptr);
1810 ASSERT_GT(num_bytes, kTestDataSize);
1811
1812 dp->ConsumerClose();
1813 dp->ProducerClose();
1814 }
1815
1816 // Test closing the producer and then trying to read (with no data).
1817 {
1818 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1819
1820 // Write some data, so we'll have something to read.
1821 uint32_t num_bytes = kTestDataSize;
1822 EXPECT_EQ(MOJO_RESULT_OK,
1823 dp->ProducerWriteData(UserPointer<const void>(kTestData),
1824 MakeUserPointer(&num_bytes), false));
1825 EXPECT_EQ(kTestDataSize, num_bytes);
1826
1827 // Close the producer.
1828 dp->ProducerClose();
1829
1830 // Peek that data.
1831 char buffer[1000];
1832 num_bytes = static_cast<uint32_t>(sizeof(buffer));
1833 EXPECT_EQ(MOJO_RESULT_OK,
1834 dp->ConsumerReadData(UserPointer<void>(buffer),
1835 MakeUserPointer(&num_bytes), false, true));
1836 EXPECT_EQ(kTestDataSize, num_bytes);
1837 EXPECT_EQ(0, memcmp(buffer, kTestData, kTestDataSize));
1838
1839 // Read that data.
1840 memset(buffer, 0, 1000);
1841 num_bytes = static_cast<uint32_t>(sizeof(buffer));
1842 EXPECT_EQ(MOJO_RESULT_OK,
1843 dp->ConsumerReadData(UserPointer<void>(buffer),
1844 MakeUserPointer(&num_bytes), false, false));
1845 EXPECT_EQ(kTestDataSize, num_bytes);
1846 EXPECT_EQ(0, memcmp(buffer, kTestData, kTestDataSize));
1847
1848 // A second read should fail.
1849 num_bytes = static_cast<uint32_t>(sizeof(buffer));
1850 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1851 dp->ConsumerReadData(UserPointer<void>(buffer),
1852 MakeUserPointer(&num_bytes), false, false));
1853
1854 // A two-phase read should also fail.
1855 const void* read_buffer_ptr = nullptr;
1856 num_bytes = 0u;
1857 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1858 dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
1859 MakeUserPointer(&num_bytes), false));
1860
1861 // Ditto for discard.
1862 num_bytes = 10u;
1863 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1864 dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), false));
1865
1866 dp->ConsumerClose();
1867 }
1868 }
1869
1870 TEST(LocalDataPipeTest, TwoPhaseMoreInvalidArguments) {
1871 const MojoCreateDataPipeOptions options = {
1872 kSizeOfOptions, // |struct_size|.
1873 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
1874 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
1875 10 * sizeof(int32_t) // |capacity_num_bytes|.
1876 };
1877 MojoCreateDataPipeOptions validated_options = {0};
1878 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
1879 MakeUserPointer(&options), &validated_options));
1880
1881 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
1882
1883 // No data.
1884 uint32_t num_bytes = 1000u;
1885 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1886 EXPECT_EQ(0u, num_bytes);
1887
1888 // Try "ending" a two-phase write when one isn't active.
1889 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1890 dp->ProducerEndWriteData(1u * sizeof(int32_t)));
1891
1892 // Still no data.
1893 num_bytes = 1000u;
1894 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1895 EXPECT_EQ(0u, num_bytes);
1896
1897 // Try ending a two-phase write with an invalid amount (too much).
1898 num_bytes = 0u;
1899 void* write_ptr = nullptr;
1900 EXPECT_EQ(MOJO_RESULT_OK,
1901 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1902 MakeUserPointer(&num_bytes), false));
1903 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
1904 dp->ProducerEndWriteData(num_bytes +
1905 static_cast<uint32_t>(sizeof(int32_t))));
1906
1907 // But the two-phase write still ended.
1908 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, dp->ProducerEndWriteData(0u));
1909
1910 // Still no data.
1911 num_bytes = 1000u;
1912 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1913 EXPECT_EQ(0u, num_bytes);
1914
1915 // Try ending a two-phase write with an invalid amount (not a multiple of the
1916 // element size).
1917 num_bytes = 0u;
1918 write_ptr = nullptr;
1919 EXPECT_EQ(MOJO_RESULT_OK,
1920 dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
1921 MakeUserPointer(&num_bytes), false));
1922 EXPECT_GE(num_bytes, 1u);
1923 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dp->ProducerEndWriteData(1u));
1924
1925 // But the two-phase write still ended.
1926 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, dp->ProducerEndWriteData(0u));
1927
1928 // Still no data.
1929 num_bytes = 1000u;
1930 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1931 EXPECT_EQ(0u, num_bytes);
1932
1933 // Now write some data, so we'll be able to try reading.
1934 int32_t element = 123;
1935 num_bytes = 1u * sizeof(int32_t);
1936 EXPECT_EQ(MOJO_RESULT_OK,
1937 dp->ProducerWriteData(UserPointer<const void>(&element),
1938 MakeUserPointer(&num_bytes), false));
1939
1940 // One element available.
1941 num_bytes = 0u;
1942 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1943 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1944
1945 // Try "ending" a two-phase read when one isn't active.
1946 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1947 dp->ConsumerEndReadData(1u * sizeof(int32_t)));
1948
1949 // Still one element available.
1950 num_bytes = 0u;
1951 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1952 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1953
1954 // Try ending a two-phase read with an invalid amount (too much).
1955 num_bytes = 0u;
1956 const void* read_ptr = nullptr;
1957 EXPECT_EQ(MOJO_RESULT_OK,
1958 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1959 MakeUserPointer(&num_bytes), false));
1960 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
1961 dp->ConsumerEndReadData(num_bytes +
1962 static_cast<uint32_t>(sizeof(int32_t))));
1963
1964 // Still one element available.
1965 num_bytes = 0u;
1966 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1967 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1968
1969 // Try ending a two-phase read with an invalid amount (not a multiple of the
1970 // element size).
1971 num_bytes = 0u;
1972 read_ptr = nullptr;
1973 EXPECT_EQ(MOJO_RESULT_OK,
1974 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
1975 MakeUserPointer(&num_bytes), false));
1976 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1977 EXPECT_EQ(123, static_cast<const int32_t*>(read_ptr)[0]);
1978 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dp->ConsumerEndReadData(1u));
1979
1980 // Still one element available.
1981 num_bytes = 0u;
1982 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
1983 EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
1984
1985 dp->ProducerClose();
1986 dp->ConsumerClose();
1987 }
1988
1989 // Tests that even with "may discard", the data won't change under a two-phase
1990 // read.
1991 // TODO(vtl): crbug.com/348644: We currently don't pass this. (There are two
1992 // related issues: First, we don't recognize that the data given to
1993 // |ConsumerBeginReadData()| isn't discardable until |ConsumerEndReadData()|,
1994 // and thus we erroneously allow |ProducerWriteData()| to succeed. Second, the
1995 // |ProducerWriteData()| then changes the data underneath the two-phase read.)
1996 TEST(LocalDataPipeTest, DISABLED_MayDiscardTwoPhaseConsistent) {
1997 const MojoCreateDataPipeOptions options = {
1998 kSizeOfOptions, // |struct_size|.
1999 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
2000 1, // |element_num_bytes|.
2001 2 // |capacity_num_bytes|.
2002 };
2003 MojoCreateDataPipeOptions validated_options = {0};
2004 EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
2005 MakeUserPointer(&options), &validated_options));
2006
2007 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
2008
2009 // Write some elements.
2010 char elements[2] = {'a', 'b'};
2011 uint32_t num_bytes = 2u;
2012 EXPECT_EQ(MOJO_RESULT_OK,
2013 dp->ProducerWriteData(UserPointer<const void>(elements),
2014 MakeUserPointer(&num_bytes), false));
2015 EXPECT_EQ(2u, num_bytes);
2016
2017 // Begin reading.
2018 const void* read_ptr = nullptr;
2019 num_bytes = 2u;
2020 EXPECT_EQ(MOJO_RESULT_OK,
2021 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
2022 MakeUserPointer(&num_bytes), false));
2023 EXPECT_EQ(2u, num_bytes);
2024 EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
2025 EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
2026
2027 // Try to write some more. But nothing should be discardable right now.
2028 elements[0] = 'x';
2029 elements[1] = 'y';
2030 num_bytes = 2u;
2031 // TODO(vtl): This should be:
2032 // EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
2033 // dp->ProducerWriteData(elements, &num_bytes, false));
2034 // but we incorrectly think that the bytes being read are discardable. Letting
2035 // this through reveals the significant consequence.
2036 EXPECT_EQ(MOJO_RESULT_OK,
2037 dp->ProducerWriteData(UserPointer<const void>(elements),
2038 MakeUserPointer(&num_bytes), false));
2039
2040 // Check that our read buffer hasn't changed underneath us.
2041 EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
2042 EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
2043
2044 // End reading.
2045 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(2u));
2046
2047 // Now writing should succeed.
2048 EXPECT_EQ(MOJO_RESULT_OK,
2049 dp->ProducerWriteData(UserPointer<const void>(elements),
2050 MakeUserPointer(&num_bytes), false));
2051
2052 // And if we read, we should get the new values.
2053 read_ptr = nullptr;
2054 num_bytes = 2u;
2055 EXPECT_EQ(MOJO_RESULT_OK,
2056 dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
2057 MakeUserPointer(&num_bytes), false));
2058 EXPECT_EQ(2u, num_bytes);
2059 EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]);
2060 EXPECT_EQ('y', static_cast<const char*>(read_ptr)[1]);
2061
2062 // End reading.
2063 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(2u));
2064
2065 dp->ProducerClose();
2066 dp->ConsumerClose();
2067 }
2068
2069 } // namespace
2070 } // namespace system
2071 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/local_data_pipe.cc ('k') | mojo/edk/system/local_message_pipe_endpoint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698