Home | History | Annotate | Download | only in impl
      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.support.test.filters.SmallTest;
      8 
      9 import org.chromium.mojo.MojoTestCase;
     10 import org.chromium.mojo.system.Core;
     11 import org.chromium.mojo.system.Core.HandleSignals;
     12 import org.chromium.mojo.system.Core.HandleSignalsState;
     13 import org.chromium.mojo.system.Core.WaitManyResult;
     14 import org.chromium.mojo.system.Core.WaitResult;
     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.ResultAnd;
     23 import org.chromium.mojo.system.SharedBufferHandle;
     24 
     25 import java.nio.ByteBuffer;
     26 import java.util.ArrayList;
     27 import java.util.Arrays;
     28 import java.util.Collections;
     29 import java.util.List;
     30 import java.util.Random;
     31 import java.util.concurrent.Executors;
     32 import java.util.concurrent.ScheduledExecutorService;
     33 import java.util.concurrent.TimeUnit;
     34 
     35 /**
     36  * Testing the core API.
     37  */
     38 public class CoreImplTest extends MojoTestCase {
     39     private static final long RUN_LOOP_TIMEOUT_MS = 5;
     40 
     41     private static final ScheduledExecutorService WORKER =
     42             Executors.newSingleThreadScheduledExecutor();
     43 
     44     private static final HandleSignals ALL_SIGNALS =
     45             HandleSignals.none().setPeerClosed(true).setReadable(true).setWritable(true);
     46 
     47     private List<Handle> mHandlesToClose = new ArrayList<Handle>();
     48 
     49     /**
     50      * @see MojoTestCase#tearDown()
     51      */
     52     @Override
     53     protected void tearDown() throws Exception {
     54         MojoException toThrow = null;
     55         for (Handle handle : mHandlesToClose) {
     56             try {
     57                 handle.close();
     58             } catch (MojoException e) {
     59                 if (toThrow == null) {
     60                     toThrow = e;
     61                 }
     62             }
     63         }
     64         if (toThrow != null) {
     65             throw toThrow;
     66         }
     67         super.tearDown();
     68     }
     69 
     70     private void addHandleToClose(Handle handle) {
     71         mHandlesToClose.add(handle);
     72     }
     73 
     74     private void addHandlePairToClose(Pair<? extends Handle, ? extends Handle> handles) {
     75         mHandlesToClose.add(handles.first);
     76         mHandlesToClose.add(handles.second);
     77     }
     78 
     79     /**
     80      * Runnable that will close the given handle.
     81      */
     82     private static class CloseHandle implements Runnable {
     83         private Handle mHandle;
     84 
     85         CloseHandle(Handle handle) {
     86             mHandle = handle;
     87         }
     88 
     89         @Override
     90         public void run() {
     91             mHandle.close();
     92         }
     93     }
     94 
     95     private static void checkSendingMessage(MessagePipeHandle in, MessagePipeHandle out) {
     96         Random random = new Random();
     97 
     98         // Writing a random 8 bytes message.
     99         byte[] bytes = new byte[8];
    100         random.nextBytes(bytes);
    101         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
    102         buffer.put(bytes);
    103         in.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.NONE);
    104 
    105         // Try to read into a small buffer.
    106         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length / 2);
    107         ResultAnd<MessagePipeHandle.ReadMessageResult> result =
    108                 out.readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE);
    109         assertEquals(MojoResult.RESOURCE_EXHAUSTED, result.getMojoResult());
    110         assertEquals(bytes.length, result.getValue().getMessageSize());
    111         assertEquals(0, result.getValue().getHandlesCount());
    112 
    113         // Read into a correct buffer.
    114         receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
    115         result = out.readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE);
    116         assertEquals(MojoResult.OK, result.getMojoResult());
    117         assertEquals(bytes.length, result.getValue().getMessageSize());
    118         assertEquals(0, result.getValue().getHandlesCount());
    119         assertEquals(0, receiveBuffer.position());
    120         assertEquals(result.getValue().getMessageSize(), receiveBuffer.limit());
    121         byte[] receivedBytes = new byte[result.getValue().getMessageSize()];
    122         receiveBuffer.get(receivedBytes);
    123         assertTrue(Arrays.equals(bytes, receivedBytes));
    124     }
    125 
    126     private static void checkSendingData(DataPipe.ProducerHandle in, DataPipe.ConsumerHandle out) {
    127         Random random = new Random();
    128 
    129         // Writing a random 8 bytes message.
    130         byte[] bytes = new byte[8];
    131         random.nextBytes(bytes);
    132         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
    133         buffer.put(bytes);
    134         ResultAnd<Integer> result = in.writeData(buffer, DataPipe.WriteFlags.NONE);
    135         assertEquals(MojoResult.OK, result.getMojoResult());
    136         assertEquals(bytes.length, result.getValue().intValue());
    137 
    138         // Query number of bytes available.
    139         ResultAnd<Integer> readResult = out.readData(null, DataPipe.ReadFlags.none().query(true));
    140         assertEquals(MojoResult.OK, readResult.getMojoResult());
    141         assertEquals(bytes.length, readResult.getValue().intValue());
    142 
    143         // Peek data into a buffer.
    144         ByteBuffer peekBuffer = ByteBuffer.allocateDirect(bytes.length);
    145         readResult = out.readData(peekBuffer, DataPipe.ReadFlags.none().peek(true));
    146         assertEquals(MojoResult.OK, readResult.getMojoResult());
    147         assertEquals(bytes.length, readResult.getValue().intValue());
    148         assertEquals(bytes.length, peekBuffer.limit());
    149         byte[] peekBytes = new byte[bytes.length];
    150         peekBuffer.get(peekBytes);
    151         assertTrue(Arrays.equals(bytes, peekBytes));
    152 
    153         // Read into a buffer.
    154         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
    155         readResult = out.readData(receiveBuffer, DataPipe.ReadFlags.NONE);
    156         assertEquals(MojoResult.OK, readResult.getMojoResult());
    157         assertEquals(bytes.length, readResult.getValue().intValue());
    158         assertEquals(0, receiveBuffer.position());
    159         assertEquals(bytes.length, receiveBuffer.limit());
    160         byte[] receivedBytes = new byte[bytes.length];
    161         receiveBuffer.get(receivedBytes);
    162         assertTrue(Arrays.equals(bytes, receivedBytes));
    163     }
    164 
    165     private static void checkSharing(SharedBufferHandle in, SharedBufferHandle out) {
    166         Random random = new Random();
    167 
    168         ByteBuffer buffer1 = in.map(0, 8, SharedBufferHandle.MapFlags.NONE);
    169         assertEquals(8, buffer1.capacity());
    170         ByteBuffer buffer2 = out.map(0, 8, SharedBufferHandle.MapFlags.NONE);
    171         assertEquals(8, buffer2.capacity());
    172 
    173         byte[] bytes = new byte[8];
    174         random.nextBytes(bytes);
    175         buffer1.put(bytes);
    176 
    177         byte[] receivedBytes = new byte[bytes.length];
    178         buffer2.get(receivedBytes);
    179 
    180         assertTrue(Arrays.equals(bytes, receivedBytes));
    181 
    182         in.unmap(buffer1);
    183         out.unmap(buffer2);
    184     }
    185 
    186     /**
    187      * Testing {@link Core#waitMany(List, long)}.
    188      */
    189     @SmallTest
    190     public void testWaitMany() {
    191         Core core = CoreImpl.getInstance();
    192         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    193         addHandlePairToClose(handles);
    194 
    195         // Test waiting on handles of a newly created message pipe - each should be writable, but
    196         // not readable.
    197         List<Pair<Handle, Core.HandleSignals>> handlesToWaitOn =
    198                 new ArrayList<Pair<Handle, Core.HandleSignals>>();
    199         handlesToWaitOn.add(
    200                 new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE));
    201         handlesToWaitOn.add(
    202                 new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE));
    203         WaitManyResult result = core.waitMany(handlesToWaitOn, 0);
    204         assertEquals(MojoResult.OK, result.getMojoResult());
    205         assertEquals(1, result.getHandleIndex());
    206         for (HandleSignalsState state : result.getSignalStates()) {
    207             assertEquals(HandleSignals.WRITABLE, state.getSatisfiedSignals());
    208             assertEquals(ALL_SIGNALS, state.getSatisfiableSignals());
    209         }
    210 
    211         // Same test, but swap the handles around.
    212         handlesToWaitOn.clear();
    213         handlesToWaitOn.add(
    214                 new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE));
    215         handlesToWaitOn.add(
    216                 new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE));
    217         result = core.waitMany(handlesToWaitOn, 0);
    218         assertEquals(MojoResult.OK, result.getMojoResult());
    219         assertEquals(0, result.getHandleIndex());
    220         for (HandleSignalsState state : result.getSignalStates()) {
    221             assertEquals(HandleSignals.WRITABLE, state.getSatisfiedSignals());
    222             assertEquals(ALL_SIGNALS, state.getSatisfiableSignals());
    223         }
    224     }
    225 
    226     /**
    227      * Testing that Core can be retrieved from a handle.
    228      */
    229     @SmallTest
    230     public void testGetCore() {
    231         Core core = CoreImpl.getInstance();
    232 
    233         Pair<? extends Handle, ? extends Handle> handles = core.createMessagePipe(null);
    234         addHandlePairToClose(handles);
    235         assertEquals(core, handles.first.getCore());
    236         assertEquals(core, handles.second.getCore());
    237 
    238         handles = core.createDataPipe(null);
    239         addHandlePairToClose(handles);
    240         assertEquals(core, handles.first.getCore());
    241         assertEquals(core, handles.second.getCore());
    242 
    243         SharedBufferHandle handle = core.createSharedBuffer(null, 100);
    244         SharedBufferHandle handle2 = handle.duplicate(null);
    245         addHandleToClose(handle);
    246         addHandleToClose(handle2);
    247         assertEquals(core, handle.getCore());
    248         assertEquals(core, handle2.getCore());
    249     }
    250 
    251     private static void createAndCloseMessagePipe(MessagePipeHandle.CreateOptions options) {
    252         Core core = CoreImpl.getInstance();
    253         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(options);
    254         handles.first.close();
    255         handles.second.close();
    256     }
    257 
    258     /**
    259      * Testing {@link MessagePipeHandle} creation.
    260      */
    261     @SmallTest
    262     public void testMessagePipeCreation() {
    263         // Test creation with null options.
    264         createAndCloseMessagePipe(null);
    265         // Test creation with default options.
    266         createAndCloseMessagePipe(new MessagePipeHandle.CreateOptions());
    267     }
    268 
    269     /**
    270      * Testing {@link MessagePipeHandle}.
    271      */
    272     @SmallTest
    273     public void testMessagePipeEmpty() {
    274         Core core = CoreImpl.getInstance();
    275         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    276         addHandlePairToClose(handles);
    277         // Test waiting on handles of a newly created message pipe.
    278         WaitResult waitResult = handles.first.wait(
    279                 Core.HandleSignals.none().setReadable(true).setWritable(true), 0);
    280         assertEquals(MojoResult.OK, waitResult.getMojoResult());
    281         assertEquals(
    282                 HandleSignals.WRITABLE, waitResult.getHandleSignalsState().getSatisfiedSignals());
    283         assertEquals(ALL_SIGNALS, waitResult.getHandleSignalsState().getSatisfiableSignals());
    284 
    285         waitResult = handles.first.wait(Core.HandleSignals.WRITABLE, 0);
    286         assertEquals(MojoResult.OK, waitResult.getMojoResult());
    287         assertEquals(
    288                 HandleSignals.WRITABLE, waitResult.getHandleSignalsState().getSatisfiedSignals());
    289         assertEquals(ALL_SIGNALS, waitResult.getHandleSignalsState().getSatisfiableSignals());
    290 
    291         waitResult = handles.first.wait(Core.HandleSignals.READABLE, 0);
    292         assertEquals(MojoResult.DEADLINE_EXCEEDED, waitResult.getMojoResult());
    293         assertEquals(
    294                 HandleSignals.WRITABLE, waitResult.getHandleSignalsState().getSatisfiedSignals());
    295         assertEquals(ALL_SIGNALS, waitResult.getHandleSignalsState().getSatisfiableSignals());
    296 
    297         // Testing read on an empty pipe.
    298         ResultAnd<MessagePipeHandle.ReadMessageResult> readResult =
    299                 handles.first.readMessage(null, 0, MessagePipeHandle.ReadFlags.NONE);
    300         assertEquals(MojoResult.SHOULD_WAIT, readResult.getMojoResult());
    301 
    302         // Closing a pipe while waiting.
    303         WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
    304         waitResult = handles.first.wait(Core.HandleSignals.READABLE, 1000000L);
    305         assertEquals(MojoResult.CANCELLED, waitResult.getMojoResult());
    306         assertEquals(
    307                 HandleSignals.none(), waitResult.getHandleSignalsState().getSatisfiedSignals());
    308         assertEquals(
    309                 HandleSignals.none(), waitResult.getHandleSignalsState().getSatisfiableSignals());
    310 
    311         handles = core.createMessagePipe(null);
    312         addHandlePairToClose(handles);
    313 
    314         // Closing the other pipe while waiting.
    315         WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
    316         waitResult = handles.second.wait(Core.HandleSignals.READABLE, 1000000L);
    317         assertEquals(MojoResult.FAILED_PRECONDITION, waitResult.getMojoResult());
    318 
    319         // Waiting on a closed pipe.
    320         waitResult = handles.second.wait(Core.HandleSignals.READABLE, 0);
    321         assertEquals(MojoResult.FAILED_PRECONDITION, waitResult.getMojoResult());
    322         waitResult = handles.second.wait(Core.HandleSignals.WRITABLE, 0);
    323         assertEquals(MojoResult.FAILED_PRECONDITION, waitResult.getMojoResult());
    324     }
    325 
    326     /**
    327      * Testing {@link MessagePipeHandle}.
    328      */
    329     @SmallTest
    330     public void testMessagePipeSend() {
    331         Core core = CoreImpl.getInstance();
    332         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    333         addHandlePairToClose(handles);
    334 
    335         checkSendingMessage(handles.first, handles.second);
    336         checkSendingMessage(handles.second, handles.first);
    337     }
    338 
    339     /**
    340      * Testing {@link MessagePipeHandle}.
    341      */
    342     @SmallTest
    343     public void testMessagePipeReceiveOnSmallBuffer() {
    344         Random random = new Random();
    345         Core core = CoreImpl.getInstance();
    346         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    347         addHandlePairToClose(handles);
    348 
    349         // Writing a random 8 bytes message.
    350         byte[] bytes = new byte[8];
    351         random.nextBytes(bytes);
    352         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
    353         buffer.put(bytes);
    354         handles.first.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.NONE);
    355 
    356         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(1);
    357         ResultAnd<MessagePipeHandle.ReadMessageResult> result =
    358                 handles.second.readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE);
    359         assertEquals(MojoResult.RESOURCE_EXHAUSTED, result.getMojoResult());
    360         assertEquals(bytes.length, result.getValue().getMessageSize());
    361         assertEquals(0, result.getValue().getHandlesCount());
    362     }
    363 
    364     /**
    365      * Testing {@link MessagePipeHandle}.
    366      */
    367     @SmallTest
    368     public void testMessagePipeSendHandles() {
    369         Core core = CoreImpl.getInstance();
    370         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    371         Pair<MessagePipeHandle, MessagePipeHandle> handlesToShare = core.createMessagePipe(null);
    372         addHandlePairToClose(handles);
    373         addHandlePairToClose(handlesToShare);
    374 
    375         handles.first.writeMessage(null, Collections.<Handle>singletonList(handlesToShare.second),
    376                 MessagePipeHandle.WriteFlags.NONE);
    377         assertFalse(handlesToShare.second.isValid());
    378         ResultAnd<MessagePipeHandle.ReadMessageResult> readMessageResult =
    379                 handles.second.readMessage(null, 1, MessagePipeHandle.ReadFlags.NONE);
    380         assertEquals(1, readMessageResult.getValue().getHandlesCount());
    381         MessagePipeHandle newHandle =
    382                 readMessageResult.getValue().getHandles().get(0).toMessagePipeHandle();
    383         addHandleToClose(newHandle);
    384         assertTrue(newHandle.isValid());
    385         checkSendingMessage(handlesToShare.first, newHandle);
    386         checkSendingMessage(newHandle, handlesToShare.first);
    387     }
    388 
    389     private static void createAndCloseDataPipe(DataPipe.CreateOptions options) {
    390         Core core = CoreImpl.getInstance();
    391         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles =
    392                 core.createDataPipe(options);
    393         handles.first.close();
    394         handles.second.close();
    395     }
    396 
    397     /**
    398      * Testing {@link DataPipe}.
    399      */
    400     @SmallTest
    401     public void testDataPipeCreation() {
    402         // Create datapipe with null options.
    403         createAndCloseDataPipe(null);
    404         DataPipe.CreateOptions options = new DataPipe.CreateOptions();
    405         // Create datapipe with element size set.
    406         options.setElementNumBytes(24);
    407         createAndCloseDataPipe(options);
    408         // Create datapipe with capacity set.
    409         options.setCapacityNumBytes(1024 * options.getElementNumBytes());
    410         createAndCloseDataPipe(options);
    411     }
    412 
    413     /**
    414      * Testing {@link DataPipe}.
    415      */
    416     @SmallTest
    417     public void testDataPipeSend() {
    418         Core core = CoreImpl.getInstance();
    419 
    420         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
    421         addHandlePairToClose(handles);
    422 
    423         checkSendingData(handles.first, handles.second);
    424     }
    425 
    426     /**
    427      * Testing {@link DataPipe}.
    428      */
    429     @SmallTest
    430     public void testDataPipeTwoPhaseSend() {
    431         Random random = new Random();
    432         Core core = CoreImpl.getInstance();
    433         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
    434         addHandlePairToClose(handles);
    435 
    436         // Writing a random 8 bytes message.
    437         byte[] bytes = new byte[8];
    438         random.nextBytes(bytes);
    439         ByteBuffer buffer = handles.first.beginWriteData(bytes.length, DataPipe.WriteFlags.NONE);
    440         assertTrue(buffer.capacity() >= bytes.length);
    441         buffer.put(bytes);
    442         handles.first.endWriteData(bytes.length);
    443 
    444         // Read into a buffer.
    445         ByteBuffer receiveBuffer =
    446                 handles.second.beginReadData(bytes.length, DataPipe.ReadFlags.NONE);
    447         assertEquals(0, receiveBuffer.position());
    448         assertEquals(bytes.length, receiveBuffer.limit());
    449         byte[] receivedBytes = new byte[bytes.length];
    450         receiveBuffer.get(receivedBytes);
    451         assertTrue(Arrays.equals(bytes, receivedBytes));
    452         handles.second.endReadData(bytes.length);
    453     }
    454 
    455     /**
    456      * Testing {@link DataPipe}.
    457      */
    458     @SmallTest
    459     public void testDataPipeDiscard() {
    460         Random random = new Random();
    461         Core core = CoreImpl.getInstance();
    462         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
    463         addHandlePairToClose(handles);
    464 
    465         // Writing a random 8 bytes message.
    466         byte[] bytes = new byte[8];
    467         random.nextBytes(bytes);
    468         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
    469         buffer.put(bytes);
    470         ResultAnd<Integer> result = handles.first.writeData(buffer, DataPipe.WriteFlags.NONE);
    471         assertEquals(MojoResult.OK, result.getMojoResult());
    472         assertEquals(bytes.length, result.getValue().intValue());
    473 
    474         // Discard bytes.
    475         final int nbBytesToDiscard = 4;
    476         assertEquals(nbBytesToDiscard,
    477                 handles.second.discardData(nbBytesToDiscard, DataPipe.ReadFlags.NONE));
    478 
    479         // Read into a buffer.
    480         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length - nbBytesToDiscard);
    481         ResultAnd<Integer> readResult =
    482                 handles.second.readData(receiveBuffer, DataPipe.ReadFlags.NONE);
    483         assertEquals(MojoResult.OK, readResult.getMojoResult());
    484         assertEquals(bytes.length - nbBytesToDiscard, readResult.getValue().intValue());
    485         assertEquals(0, receiveBuffer.position());
    486         assertEquals(bytes.length - nbBytesToDiscard, receiveBuffer.limit());
    487         byte[] receivedBytes = new byte[bytes.length - nbBytesToDiscard];
    488         receiveBuffer.get(receivedBytes);
    489         assertTrue(Arrays.equals(
    490                 Arrays.copyOfRange(bytes, nbBytesToDiscard, bytes.length), receivedBytes));
    491     }
    492 
    493     /**
    494      * Testing {@link SharedBufferHandle}.
    495      */
    496     @SmallTest
    497     public void testSharedBufferCreation() {
    498         Core core = CoreImpl.getInstance();
    499         // Test creation with empty options.
    500         core.createSharedBuffer(null, 8).close();
    501         // Test creation with default options.
    502         core.createSharedBuffer(new SharedBufferHandle.CreateOptions(), 8).close();
    503     }
    504 
    505     /**
    506      * Testing {@link SharedBufferHandle}.
    507      */
    508     @SmallTest
    509     public void testSharedBufferDuplication() {
    510         Core core = CoreImpl.getInstance();
    511         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
    512         addHandleToClose(handle);
    513 
    514         // Test duplication with empty options.
    515         handle.duplicate(null).close();
    516         // Test creation with default options.
    517         handle.duplicate(new SharedBufferHandle.DuplicateOptions()).close();
    518     }
    519 
    520     /**
    521      * Testing {@link SharedBufferHandle}.
    522      */
    523     @SmallTest
    524     public void testSharedBufferSending() {
    525         Core core = CoreImpl.getInstance();
    526         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
    527         addHandleToClose(handle);
    528         SharedBufferHandle newHandle = handle.duplicate(null);
    529         addHandleToClose(newHandle);
    530 
    531         checkSharing(handle, newHandle);
    532         checkSharing(newHandle, handle);
    533     }
    534 
    535     /**
    536      * Testing that invalid handle can be used with this implementation.
    537      */
    538     @SmallTest
    539     public void testInvalidHandle() {
    540         Core core = CoreImpl.getInstance();
    541         Handle handle = InvalidHandle.INSTANCE;
    542 
    543         // Checking wait.
    544         boolean exception = false;
    545         try {
    546             core.wait(handle, Core.HandleSignals.WRITABLE, 0);
    547         } catch (MojoException e) {
    548             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
    549             exception = true;
    550         }
    551         assertTrue(exception);
    552 
    553         // Checking waitMany.
    554         exception = false;
    555         try {
    556             List<Pair<Handle, Core.HandleSignals>> handles =
    557                     new ArrayList<Pair<Handle, Core.HandleSignals>>();
    558             handles.add(Pair.create(handle, Core.HandleSignals.WRITABLE));
    559             core.waitMany(handles, 0);
    560         } catch (MojoException e) {
    561             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
    562             exception = true;
    563         }
    564         assertTrue(exception);
    565 
    566         // Checking sending an invalid handle.
    567         // Until the behavior is changed on the C++ side, handle gracefully 2 different use case:
    568         // - Receive a INVALID_ARGUMENT exception
    569         // - Receive an invalid handle on the other side.
    570         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    571         addHandlePairToClose(handles);
    572         try {
    573             handles.first.writeMessage(null, Collections.<Handle>singletonList(handle),
    574                     MessagePipeHandle.WriteFlags.NONE);
    575             ResultAnd<MessagePipeHandle.ReadMessageResult> readMessageResult =
    576                     handles.second.readMessage(null, 1, MessagePipeHandle.ReadFlags.NONE);
    577             assertEquals(1, readMessageResult.getValue().getHandlesCount());
    578             assertFalse(readMessageResult.getValue().getHandles().get(0).isValid());
    579         } catch (MojoException e) {
    580             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
    581         }
    582     }
    583 
    584     /**
    585      * Testing the pass method on message pipes.
    586      */
    587     @SmallTest
    588     public void testMessagePipeHandlePass() {
    589         Core core = CoreImpl.getInstance();
    590         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    591         addHandlePairToClose(handles);
    592 
    593         assertTrue(handles.first.isValid());
    594         MessagePipeHandle handleClone = handles.first.pass();
    595 
    596         addHandleToClose(handleClone);
    597 
    598         assertFalse(handles.first.isValid());
    599         assertTrue(handleClone.isValid());
    600         checkSendingMessage(handleClone, handles.second);
    601         checkSendingMessage(handles.second, handleClone);
    602     }
    603 
    604     /**
    605      * Testing the pass method on data pipes.
    606      */
    607     @SmallTest
    608     public void testDataPipeHandlePass() {
    609         Core core = CoreImpl.getInstance();
    610         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
    611         addHandlePairToClose(handles);
    612 
    613         DataPipe.ProducerHandle producerClone = handles.first.pass();
    614         DataPipe.ConsumerHandle consumerClone = handles.second.pass();
    615 
    616         addHandleToClose(producerClone);
    617         addHandleToClose(consumerClone);
    618 
    619         assertFalse(handles.first.isValid());
    620         assertFalse(handles.second.isValid());
    621         assertTrue(producerClone.isValid());
    622         assertTrue(consumerClone.isValid());
    623         checkSendingData(producerClone, consumerClone);
    624     }
    625 
    626     /**
    627      * Testing the pass method on shared buffers.
    628      */
    629     @SmallTest
    630     public void testSharedBufferPass() {
    631         Core core = CoreImpl.getInstance();
    632         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
    633         addHandleToClose(handle);
    634         SharedBufferHandle newHandle = handle.duplicate(null);
    635         addHandleToClose(newHandle);
    636 
    637         SharedBufferHandle handleClone = handle.pass();
    638         SharedBufferHandle newHandleClone = newHandle.pass();
    639 
    640         addHandleToClose(handleClone);
    641         addHandleToClose(newHandleClone);
    642 
    643         assertFalse(handle.isValid());
    644         assertTrue(handleClone.isValid());
    645         checkSharing(handleClone, newHandleClone);
    646         checkSharing(newHandleClone, handleClone);
    647     }
    648 
    649     /**
    650      * esting handle conversion to native and back.
    651      */
    652     @SmallTest
    653     public void testHandleConversion() {
    654         Core core = CoreImpl.getInstance();
    655         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
    656         addHandlePairToClose(handles);
    657 
    658         MessagePipeHandle converted =
    659                 core.acquireNativeHandle(handles.first.releaseNativeHandle()).toMessagePipeHandle();
    660         addHandleToClose(converted);
    661 
    662         assertFalse(handles.first.isValid());
    663 
    664         checkSendingMessage(converted, handles.second);
    665         checkSendingMessage(handles.second, converted);
    666     }
    667 }
    668