Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / mojo / android / javatests / src / org / chromium / mojo / system / impl / CoreImplTest.java
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.mojo.system.impl;
6
7 import android.test.suitebuilder.annotation.SmallTest;
8
9 import org.chromium.mojo.MojoTestCase;
10 import org.chromium.mojo.system.AsyncWaiter;
11 import org.chromium.mojo.system.AsyncWaiter.Callback;
12 import org.chromium.mojo.system.AsyncWaiter.Cancellable;
13 import org.chromium.mojo.system.Core;
14 import org.chromium.mojo.system.Core.WaitManyResult;
15 import org.chromium.mojo.system.DataPipe;
16 import org.chromium.mojo.system.Handle;
17 import org.chromium.mojo.system.InvalidHandle;
18 import org.chromium.mojo.system.MessagePipeHandle;
19 import org.chromium.mojo.system.MojoException;
20 import org.chromium.mojo.system.MojoResult;
21 import org.chromium.mojo.system.Pair;
22 import org.chromium.mojo.system.SharedBufferHandle;
23
24 import java.nio.ByteBuffer;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Random;
30 import java.util.concurrent.Executors;
31 import java.util.concurrent.ScheduledExecutorService;
32 import java.util.concurrent.TimeUnit;
33
34 /**
35  * Testing the core API.
36  */
37 public class CoreImplTest extends MojoTestCase {
38
39     private static final long RUN_LOOP_TIMEOUT_MS = 5;
40
41     private static final ScheduledExecutorService WORKER =
42             Executors.newSingleThreadScheduledExecutor();
43
44     private List<Handle> mHandlesToClose = new ArrayList<Handle>();
45
46     /**
47      * @see MojoTestCase#tearDown()
48      */
49     @Override
50     protected void tearDown() throws Exception {
51         MojoException toThrow = null;
52         for (Handle handle : mHandlesToClose) {
53             try {
54                 handle.close();
55             } catch (MojoException e) {
56                 if (toThrow == null) {
57                     toThrow = e;
58                 }
59             }
60         }
61         if (toThrow != null) {
62             throw toThrow;
63         }
64         super.tearDown();
65     }
66
67     private void addHandleToClose(Handle handle) {
68         mHandlesToClose.add(handle);
69     }
70
71     private void addHandlePairToClose(Pair<? extends Handle, ? extends Handle> handles) {
72         mHandlesToClose.add(handles.first);
73         mHandlesToClose.add(handles.second);
74     }
75
76     /**
77      * Runnable that will close the given handle.
78      */
79     private static class CloseHandle implements Runnable {
80         private Handle mHandle;
81
82         CloseHandle(Handle handle) {
83             mHandle = handle;
84         }
85
86         @Override
87         public void run() {
88             mHandle.close();
89         }
90     }
91
92     private static void checkSendingMessage(MessagePipeHandle in, MessagePipeHandle out) {
93         Random random = new Random();
94
95         // Writing a random 8 bytes message.
96         byte[] bytes = new byte[8];
97         random.nextBytes(bytes);
98         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
99         buffer.put(bytes);
100         in.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.NONE);
101
102         // Try to read into a small buffer.
103         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length / 2);
104         MessagePipeHandle.ReadMessageResult result = out.readMessage(
105                 receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE);
106         assertEquals(MojoResult.RESOURCE_EXHAUSTED, result.getMojoResult());
107         assertEquals(bytes.length, result.getMessageSize());
108         assertEquals(0, result.getHandlesCount());
109
110         // Read into a correct buffer.
111         receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
112         result = out.readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE);
113         assertEquals(MojoResult.OK, result.getMojoResult());
114         assertEquals(bytes.length, result.getMessageSize());
115         assertEquals(0, result.getHandlesCount());
116         assertEquals(0, receiveBuffer.position());
117         assertEquals(result.getMessageSize(), receiveBuffer.limit());
118         byte[] receivedBytes = new byte[result.getMessageSize()];
119         receiveBuffer.get(receivedBytes);
120         assertTrue(Arrays.equals(bytes, receivedBytes));
121
122     }
123
124     private static void checkSendingData(DataPipe.ProducerHandle in, DataPipe.ConsumerHandle out) {
125         Random random = new Random();
126
127         // Writing a random 8 bytes message.
128         byte[] bytes = new byte[8];
129         random.nextBytes(bytes);
130         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
131         buffer.put(bytes);
132         int result = in.writeData(buffer, DataPipe.WriteFlags.NONE);
133         assertEquals(bytes.length, result);
134
135         // Query number of bytes available.
136         result = out.readData(null, DataPipe.ReadFlags.none().query(true));
137         assertEquals(bytes.length, result);
138
139         // Read into a buffer.
140         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
141         result = out.readData(receiveBuffer, DataPipe.ReadFlags.NONE);
142         assertEquals(bytes.length, result);
143         assertEquals(0, receiveBuffer.position());
144         assertEquals(bytes.length, receiveBuffer.limit());
145         byte[] receivedBytes = new byte[bytes.length];
146         receiveBuffer.get(receivedBytes);
147         assertTrue(Arrays.equals(bytes, receivedBytes));
148     }
149
150     private static void checkSharing(SharedBufferHandle in, SharedBufferHandle out) {
151         Random random = new Random();
152
153         ByteBuffer buffer1 = in.map(0, 8, SharedBufferHandle.MapFlags.NONE);
154         assertEquals(8, buffer1.capacity());
155         ByteBuffer buffer2 = out.map(0, 8, SharedBufferHandle.MapFlags.NONE);
156         assertEquals(8, buffer2.capacity());
157
158         byte[] bytes = new byte[8];
159         random.nextBytes(bytes);
160         buffer1.put(bytes);
161
162         byte[] receivedBytes = new byte[bytes.length];
163         buffer2.get(receivedBytes);
164
165         assertTrue(Arrays.equals(bytes, receivedBytes));
166
167         in.unmap(buffer1);
168         out.unmap(buffer2);
169     }
170
171     /**
172      * Testing {@link Core#waitMany(List, long)}.
173      */
174     @SmallTest
175     public void testWaitMany() {
176         Core core = CoreImpl.getInstance();
177         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
178         addHandlePairToClose(handles);
179
180         List<Pair<Handle, Core.HandleSignals>> handlesToWaitOn = new ArrayList<
181                 Pair<Handle, Core.HandleSignals>>();
182         handlesToWaitOn.add(
183                 new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE));
184         handlesToWaitOn.add(
185                 new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE));
186         WaitManyResult result = core.waitMany(handlesToWaitOn, 0);
187         assertEquals(MojoResult.OK, result.getMojoResult());
188         assertEquals(1, result.getHandleIndex());
189
190         handlesToWaitOn.clear();
191         handlesToWaitOn.add(
192                 new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE));
193         handlesToWaitOn.add(
194                 new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE));
195         result = core.waitMany(handlesToWaitOn, 0);
196         assertEquals(MojoResult.OK, result.getMojoResult());
197         assertEquals(0, result.getHandleIndex());
198     }
199
200     /**
201      * Testing that Core can be retrieved from a handle.
202      */
203     @SmallTest
204     public void testGetCore() {
205         Core core = CoreImpl.getInstance();
206
207         Pair<? extends Handle, ? extends Handle> handles = core.createMessagePipe(null);
208         addHandlePairToClose(handles);
209         assertEquals(core, handles.first.getCore());
210         assertEquals(core, handles.second.getCore());
211
212         handles = core.createDataPipe(null);
213         addHandlePairToClose(handles);
214         assertEquals(core, handles.first.getCore());
215         assertEquals(core, handles.second.getCore());
216
217         SharedBufferHandle handle = core.createSharedBuffer(null, 100);
218         SharedBufferHandle handle2 = handle.duplicate(null);
219         addHandleToClose(handle);
220         addHandleToClose(handle2);
221         assertEquals(core, handle.getCore());
222         assertEquals(core, handle2.getCore());
223     }
224
225     private static void createAndCloseMessagePipe(MessagePipeHandle.CreateOptions options) {
226         Core core = CoreImpl.getInstance();
227         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(options);
228         handles.first.close();
229         handles.second.close();
230     }
231
232     /**
233      * Testing {@link MessagePipeHandle} creation.
234      */
235     @SmallTest
236     public void testMessagePipeCreation() {
237         // Test creation with null options.
238         createAndCloseMessagePipe(null);
239         // Test creation with default options.
240         createAndCloseMessagePipe(new MessagePipeHandle.CreateOptions());
241     }
242
243     /**
244      * Testing {@link MessagePipeHandle}.
245      */
246     @SmallTest
247     public void testMessagePipeEmpty() {
248         Core core = CoreImpl.getInstance();
249         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
250         addHandlePairToClose(handles);
251         // Testing wait.
252         assertEquals(MojoResult.OK,
253                 handles.first.wait(Core.HandleSignals.none().setReadable(true).setWritable(true),
254                         0));
255         assertEquals(MojoResult.OK, handles.first.wait(Core.HandleSignals.WRITABLE, 0));
256         assertEquals(MojoResult.DEADLINE_EXCEEDED,
257                 handles.first.wait(Core.HandleSignals.READABLE, 0));
258
259         // Testing read on an empty pipe.
260         MessagePipeHandle.ReadMessageResult result = handles.first.readMessage(null, 0,
261                 MessagePipeHandle.ReadFlags.NONE);
262         assertEquals(MojoResult.SHOULD_WAIT, result.getMojoResult());
263
264         // Closing a pipe while waiting.
265         WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
266         assertEquals(MojoResult.CANCELLED,
267                 handles.first.wait(Core.HandleSignals.READABLE, 1000000L));
268
269         handles = core.createMessagePipe(null);
270         addHandlePairToClose(handles);
271
272         // Closing the other pipe while waiting.
273         WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
274         assertEquals(MojoResult.FAILED_PRECONDITION,
275                 handles.second.wait(Core.HandleSignals.READABLE, 1000000L));
276
277         // Waiting on a closed pipe.
278         assertEquals(MojoResult.FAILED_PRECONDITION,
279                 handles.second.wait(Core.HandleSignals.READABLE, 0));
280         assertEquals(MojoResult.FAILED_PRECONDITION,
281                 handles.second.wait(Core.HandleSignals.WRITABLE, 0));
282     }
283
284     /**
285      * Testing {@link MessagePipeHandle}.
286      */
287     @SmallTest
288     public void testMessagePipeSend() {
289         Core core = CoreImpl.getInstance();
290         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
291         addHandlePairToClose(handles);
292
293         checkSendingMessage(handles.first, handles.second);
294         checkSendingMessage(handles.second, handles.first);
295     }
296
297     /**
298      * Testing {@link MessagePipeHandle}.
299      */
300     @SmallTest
301     public void testMessagePipeReceiveOnSmallBuffer() {
302         Random random = new Random();
303         Core core = CoreImpl.getInstance();
304         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
305         addHandlePairToClose(handles);
306
307         // Writing a random 8 bytes message.
308         byte[] bytes = new byte[8];
309         random.nextBytes(bytes);
310         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
311         buffer.put(bytes);
312         handles.first.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.NONE);
313
314         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(1);
315         MessagePipeHandle.ReadMessageResult result = handles.second
316                 .readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE);
317         assertEquals(MojoResult.RESOURCE_EXHAUSTED, result.getMojoResult());
318         assertEquals(bytes.length, result.getMessageSize());
319         assertEquals(0, result.getHandlesCount());
320     }
321
322     /**
323      * Testing {@link MessagePipeHandle}.
324      */
325     @SmallTest
326     public void testMessagePipeSendHandles() {
327         Core core = CoreImpl.getInstance();
328         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
329         Pair<MessagePipeHandle, MessagePipeHandle> handlesToShare = core.createMessagePipe(null);
330         addHandlePairToClose(handles);
331         addHandlePairToClose(handlesToShare);
332
333         handles.first.writeMessage(null,
334                 Collections.<Handle> singletonList(handlesToShare.second),
335                 MessagePipeHandle.WriteFlags.NONE);
336         assertFalse(handlesToShare.second.isValid());
337         MessagePipeHandle.ReadMessageResult readMessageResult =
338                 handles.second.readMessage(null, 1, MessagePipeHandle.ReadFlags.NONE);
339         assertEquals(1, readMessageResult.getHandlesCount());
340         MessagePipeHandle newHandle = readMessageResult.getHandles().get(0)
341                 .toMessagePipeHandle();
342         addHandleToClose(newHandle);
343         assertTrue(newHandle.isValid());
344         checkSendingMessage(handlesToShare.first, newHandle);
345         checkSendingMessage(newHandle, handlesToShare.first);
346     }
347
348     private static void createAndCloseDataPipe(DataPipe.CreateOptions options) {
349         Core core = CoreImpl.getInstance();
350         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(
351                 options);
352         handles.first.close();
353         handles.second.close();
354     }
355
356     /**
357      * Testing {@link DataPipe}.
358      */
359     @SmallTest
360     public void testDataPipeCreation() {
361         // Create datapipe with null options.
362         createAndCloseDataPipe(null);
363         DataPipe.CreateOptions options = new DataPipe.CreateOptions();
364         // Create datapipe with element size set.
365         options.setElementNumBytes(24);
366         createAndCloseDataPipe(options);
367         // Create datapipe with a flag set.
368         options.getFlags().setMayDiscard(true);
369         createAndCloseDataPipe(options);
370         // Create datapipe with capacity set.
371         options.setCapacityNumBytes(1024 * options.getElementNumBytes());
372         createAndCloseDataPipe(options);
373     }
374
375     /**
376      * Testing {@link DataPipe}.
377      */
378     @SmallTest
379     public void testDataPipeSend() {
380         Core core = CoreImpl.getInstance();
381
382         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
383         addHandlePairToClose(handles);
384
385         checkSendingData(handles.first, handles.second);
386     }
387
388     /**
389      * Testing {@link DataPipe}.
390      */
391     @SmallTest
392     public void testDataPipeTwoPhaseSend() {
393         Random random = new Random();
394         Core core = CoreImpl.getInstance();
395         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
396         addHandlePairToClose(handles);
397
398         // Writing a random 8 bytes message.
399         byte[] bytes = new byte[8];
400         random.nextBytes(bytes);
401         ByteBuffer buffer = handles.first.beginWriteData(bytes.length,
402                 DataPipe.WriteFlags.NONE);
403         assertTrue(buffer.capacity() >= bytes.length);
404         buffer.put(bytes);
405         handles.first.endWriteData(bytes.length);
406
407         // Read into a buffer.
408         ByteBuffer receiveBuffer = handles.second.beginReadData(bytes.length,
409                 DataPipe.ReadFlags.NONE);
410         assertEquals(0, receiveBuffer.position());
411         assertEquals(bytes.length, receiveBuffer.limit());
412         byte[] receivedBytes = new byte[bytes.length];
413         receiveBuffer.get(receivedBytes);
414         assertTrue(Arrays.equals(bytes, receivedBytes));
415         handles.second.endReadData(bytes.length);
416     }
417
418     /**
419      * Testing {@link DataPipe}.
420      */
421     @SmallTest
422     public void testDataPipeDiscard() {
423         Random random = new Random();
424         Core core = CoreImpl.getInstance();
425         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
426         addHandlePairToClose(handles);
427
428         // Writing a random 8 bytes message.
429         byte[] bytes = new byte[8];
430         random.nextBytes(bytes);
431         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
432         buffer.put(bytes);
433         int result = handles.first.writeData(buffer, DataPipe.WriteFlags.NONE);
434         assertEquals(bytes.length, result);
435
436         // Discard bytes.
437         final int nbBytesToDiscard = 4;
438         assertEquals(nbBytesToDiscard,
439                 handles.second.discardData(nbBytesToDiscard, DataPipe.ReadFlags.NONE));
440
441         // Read into a buffer.
442         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length - nbBytesToDiscard);
443         result = handles.second.readData(receiveBuffer, DataPipe.ReadFlags.NONE);
444         assertEquals(bytes.length - nbBytesToDiscard, result);
445         assertEquals(0, receiveBuffer.position());
446         assertEquals(bytes.length - nbBytesToDiscard, receiveBuffer.limit());
447         byte[] receivedBytes = new byte[bytes.length - nbBytesToDiscard];
448         receiveBuffer.get(receivedBytes);
449         assertTrue(Arrays.equals(Arrays.copyOfRange(bytes, nbBytesToDiscard, bytes.length),
450                 receivedBytes));
451     }
452
453     /**
454      * Testing {@link SharedBufferHandle}.
455      */
456     @SmallTest
457     public void testSharedBufferCreation() {
458         Core core = CoreImpl.getInstance();
459         // Test creation with empty options.
460         core.createSharedBuffer(null, 8).close();
461         // Test creation with default options.
462         core.createSharedBuffer(new SharedBufferHandle.CreateOptions(), 8).close();
463     }
464
465     /**
466      * Testing {@link SharedBufferHandle}.
467      */
468     @SmallTest
469     public void testSharedBufferDuplication() {
470         Core core = CoreImpl.getInstance();
471         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
472         addHandleToClose(handle);
473
474         // Test duplication with empty options.
475         handle.duplicate(null).close();
476         // Test creation with default options.
477         handle.duplicate(new SharedBufferHandle.DuplicateOptions()).close();
478     }
479
480     /**
481      * Testing {@link SharedBufferHandle}.
482      */
483     @SmallTest
484     public void testSharedBufferSending() {
485         Core core = CoreImpl.getInstance();
486         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
487         addHandleToClose(handle);
488         SharedBufferHandle newHandle = handle.duplicate(null);
489         addHandleToClose(newHandle);
490
491         checkSharing(handle, newHandle);
492         checkSharing(newHandle, handle);
493     }
494
495     /**
496      * Testing that invalid handle can be used with this implementation.
497      */
498     @SmallTest
499     public void testInvalidHandle() {
500         Core core = CoreImpl.getInstance();
501         Handle handle = InvalidHandle.INSTANCE;
502
503         // Checking wait.
504         boolean exception = false;
505         try {
506             core.wait(handle, Core.HandleSignals.WRITABLE, 0);
507         } catch (MojoException e) {
508             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
509             exception = true;
510         }
511         assertTrue(exception);
512
513         // Checking waitMany.
514         exception = false;
515         try {
516             List<Pair<Handle, Core.HandleSignals>> handles = new ArrayList<
517                     Pair<Handle, Core.HandleSignals>>();
518             handles.add(Pair.create(handle, Core.HandleSignals.WRITABLE));
519             core.waitMany(handles, 0);
520         } catch (MojoException e) {
521             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
522             exception = true;
523         }
524         assertTrue(exception);
525
526         // Checking sending an invalid handle.
527         // Until the behavior is changed on the C++ side, handle gracefully 2 different use case:
528         // - Receive a INVALID_ARGUMENT exception
529         // - Receive an invalid handle on the other side.
530         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
531         addHandlePairToClose(handles);
532         try {
533             handles.first.writeMessage(null, Collections.<Handle> singletonList(handle),
534                     MessagePipeHandle.WriteFlags.NONE);
535             MessagePipeHandle.ReadMessageResult readMessageResult =
536                     handles.second.readMessage(null, 1, MessagePipeHandle.ReadFlags.NONE);
537             assertEquals(1, readMessageResult.getHandlesCount());
538             assertFalse(readMessageResult.getHandles().get(0).isValid());
539         } catch (MojoException e) {
540             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
541         }
542     }
543
544     private static class AsyncWaiterResult implements Callback {
545         private int mResult = Integer.MIN_VALUE;
546         private MojoException mException = null;
547
548         /**
549          * @see Callback#onResult(int)
550          */
551         @Override
552         public void onResult(int result) {
553             this.mResult = result;
554         }
555
556         /**
557          * @see Callback#onError(MojoException)
558          */
559         @Override
560         public void onError(MojoException exception) {
561             this.mException = exception;
562         }
563
564         /**
565          * @return the result
566          */
567         public int getResult() {
568             return mResult;
569         }
570
571         /**
572          * @return the exception
573          */
574         public MojoException getException() {
575             return mException;
576         }
577
578     }
579
580     /**
581      * Testing core {@link AsyncWaiter} implementation.
582      */
583     @SmallTest
584     public void testAsyncWaiterCorrectResult() {
585         Core core = CoreImpl.getInstance();
586
587         // Checking a correct result.
588         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
589         addHandlePairToClose(handles);
590         final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult();
591         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
592         assertEquals(null, asyncWaiterResult.getException());
593
594         core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE,
595                 Core.DEADLINE_INFINITE, asyncWaiterResult);
596         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
597         assertEquals(null, asyncWaiterResult.getException());
598
599         handles.second.writeMessage(ByteBuffer.allocateDirect(1), null,
600                 MessagePipeHandle.WriteFlags.NONE);
601         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
602         assertNull(asyncWaiterResult.getException());
603         assertEquals(MojoResult.OK, asyncWaiterResult.getResult());
604     }
605
606     /**
607      * Testing core {@link AsyncWaiter} implementation.
608      */
609     @SmallTest
610     public void testAsyncWaiterClosingPeerHandle() {
611         Core core = CoreImpl.getInstance();
612
613         // Closing the peer handle.
614         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
615         addHandlePairToClose(handles);
616
617         final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult();
618         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
619         assertEquals(null, asyncWaiterResult.getException());
620
621         core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE,
622                 Core.DEADLINE_INFINITE, asyncWaiterResult);
623         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
624         assertEquals(null, asyncWaiterResult.getException());
625
626         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
627         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
628         assertEquals(null, asyncWaiterResult.getException());
629
630         handles.second.close();
631         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
632         assertNull(asyncWaiterResult.getException());
633         assertEquals(MojoResult.FAILED_PRECONDITION, asyncWaiterResult.getResult());
634     }
635
636     /**
637      * Testing core {@link AsyncWaiter} implementation.
638      */
639     @SmallTest
640     public void testAsyncWaiterClosingWaitingHandle() {
641         Core core = CoreImpl.getInstance();
642
643         // Closing the peer handle.
644         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
645         addHandlePairToClose(handles);
646
647         final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult();
648         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
649         assertEquals(null, asyncWaiterResult.getException());
650
651         Cancellable cancellable = core.getDefaultAsyncWaiter().asyncWait(handles.first,
652                 Core.HandleSignals.READABLE, Core.DEADLINE_INFINITE, asyncWaiterResult);
653         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
654         assertEquals(null, asyncWaiterResult.getException());
655
656         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
657         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
658         assertEquals(null, asyncWaiterResult.getException());
659
660         cancellable.cancel();
661         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
662         // TODO(qsr) Re-enable when MojoWaitMany handles it correctly.
663         // assertNull(asyncWaiterResult.getException());
664         // assertEquals(MojoResult.CANCELLED, asyncWaiterResult.getResult());
665     }
666
667     /**
668      * Testing core {@link AsyncWaiter} implementation.
669      */
670     @SmallTest
671     public void testAsyncWaiterWaitingWithTimeout() {
672         Core core = CoreImpl.getInstance();
673
674         // Closing the peer handle.
675         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
676         addHandlePairToClose(handles);
677
678         final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult();
679         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
680         assertEquals(null, asyncWaiterResult.getException());
681
682         core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE,
683                 RUN_LOOP_TIMEOUT_MS, asyncWaiterResult);
684         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
685         assertEquals(null, asyncWaiterResult.getException());
686
687         nativeRunLoop(10 * RUN_LOOP_TIMEOUT_MS);
688         assertNull(asyncWaiterResult.getException());
689         assertEquals(MojoResult.DEADLINE_EXCEEDED, asyncWaiterResult.getResult());
690     }
691
692     /**
693      * Testing core {@link AsyncWaiter} implementation.
694      */
695     @SmallTest
696     public void testAsyncWaiterCancelWaiting() {
697         Core core = CoreImpl.getInstance();
698
699         // Closing the peer handle.
700         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
701         addHandlePairToClose(handles);
702
703         final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult();
704         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
705         assertEquals(null, asyncWaiterResult.getException());
706
707         Cancellable cancellable = core.getDefaultAsyncWaiter().asyncWait(handles.first,
708                 Core.HandleSignals.READABLE, Core.DEADLINE_INFINITE, asyncWaiterResult);
709         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
710         assertEquals(null, asyncWaiterResult.getException());
711
712         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
713         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
714         assertEquals(null, asyncWaiterResult.getException());
715
716         cancellable.cancel();
717         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
718         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
719         assertEquals(null, asyncWaiterResult.getException());
720
721         handles.second.writeMessage(ByteBuffer.allocateDirect(1), null,
722                 MessagePipeHandle.WriteFlags.NONE);
723         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
724         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
725         assertEquals(null, asyncWaiterResult.getException());
726     }
727
728     /**
729      * Testing core {@link AsyncWaiter} implementation.
730      */
731     @SmallTest
732     public void testAsyncWaiterImmediateCancelOnInvalidHandle() {
733         Core core = CoreImpl.getInstance();
734
735         // Closing the peer handle.
736         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
737         addHandlePairToClose(handles);
738
739         final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult();
740         handles.first.close();
741         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
742         assertEquals(null, asyncWaiterResult.getException());
743
744         Cancellable cancellable = core.getDefaultAsyncWaiter().asyncWait(handles.first,
745                 Core.HandleSignals.READABLE, Core.DEADLINE_INFINITE, asyncWaiterResult);
746         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
747         assertEquals(null, asyncWaiterResult.getException());
748         cancellable.cancel();
749
750         nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
751         assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult());
752         assertEquals(null, asyncWaiterResult.getException());
753     }
754
755     /**
756      * Testing the pass method on message pipes.
757      */
758     @SmallTest
759     public void testMessagePipeHandlePass() {
760         Core core = CoreImpl.getInstance();
761         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
762         addHandlePairToClose(handles);
763
764         assertTrue(handles.first.isValid());
765         MessagePipeHandle handleClone = handles.first.pass();
766
767         addHandleToClose(handleClone);
768
769         assertFalse(handles.first.isValid());
770         assertTrue(handleClone.isValid());
771         checkSendingMessage(handleClone, handles.second);
772         checkSendingMessage(handles.second, handleClone);
773     }
774
775     /**
776      * Testing the pass method on data pipes.
777      */
778     @SmallTest
779     public void testDataPipeHandlePass() {
780         Core core = CoreImpl.getInstance();
781         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
782         addHandlePairToClose(handles);
783
784         DataPipe.ProducerHandle producerClone = handles.first.pass();
785         DataPipe.ConsumerHandle consumerClone = handles.second.pass();
786
787         addHandleToClose(producerClone);
788         addHandleToClose(consumerClone);
789
790         assertFalse(handles.first.isValid());
791         assertFalse(handles.second.isValid());
792         assertTrue(producerClone.isValid());
793         assertTrue(consumerClone.isValid());
794         checkSendingData(producerClone, consumerClone);
795     }
796
797     /**
798      * Testing the pass method on shared buffers.
799      */
800     @SmallTest
801     public void testSharedBufferPass() {
802         Core core = CoreImpl.getInstance();
803         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
804         addHandleToClose(handle);
805         SharedBufferHandle newHandle = handle.duplicate(null);
806         addHandleToClose(newHandle);
807
808         SharedBufferHandle handleClone = handle.pass();
809         SharedBufferHandle newHandleClone = newHandle.pass();
810
811         addHandleToClose(handleClone);
812         addHandleToClose(newHandleClone);
813
814         assertFalse(handle.isValid());
815         assertTrue(handleClone.isValid());
816         checkSharing(handleClone, newHandleClone);
817         checkSharing(newHandleClone, handleClone);
818     }
819
820 }