| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.mojo.system.impl; |
| |
| import android.test.suitebuilder.annotation.SmallTest; |
| |
| import org.chromium.mojo.MojoTestCase; |
| import org.chromium.mojo.system.AsyncWaiter; |
| import org.chromium.mojo.system.AsyncWaiter.Callback; |
| import org.chromium.mojo.system.AsyncWaiter.Cancellable; |
| import org.chromium.mojo.system.Core; |
| import org.chromium.mojo.system.Core.WaitManyResult; |
| import org.chromium.mojo.system.DataPipe; |
| import org.chromium.mojo.system.Handle; |
| import org.chromium.mojo.system.InvalidHandle; |
| import org.chromium.mojo.system.MessagePipeHandle; |
| import org.chromium.mojo.system.MojoException; |
| import org.chromium.mojo.system.MojoResult; |
| import org.chromium.mojo.system.Pair; |
| import org.chromium.mojo.system.SharedBufferHandle; |
| |
| import java.nio.ByteBuffer; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Random; |
| import java.util.concurrent.Executors; |
| import java.util.concurrent.ScheduledExecutorService; |
| import java.util.concurrent.TimeUnit; |
| |
| /** |
| * Testing the core API. |
| */ |
| public class CoreImplTest extends MojoTestCase { |
| |
| private static final long RUN_LOOP_TIMEOUT_MS = 5; |
| |
| private static final ScheduledExecutorService WORKER = |
| Executors.newSingleThreadScheduledExecutor(); |
| |
| private List<Handle> mHandlesToClose = new ArrayList<Handle>(); |
| |
| /** |
| * @see MojoTestCase#tearDown() |
| */ |
| @Override |
| protected void tearDown() throws Exception { |
| MojoException toThrow = null; |
| for (Handle handle : mHandlesToClose) { |
| try { |
| handle.close(); |
| } catch (MojoException e) { |
| if (toThrow == null) { |
| toThrow = e; |
| } |
| } |
| } |
| if (toThrow != null) { |
| throw toThrow; |
| } |
| super.tearDown(); |
| } |
| |
| private void addHandleToClose(Handle handle) { |
| mHandlesToClose.add(handle); |
| } |
| |
| private void addHandlePairToClose(Pair<? extends Handle, ? extends Handle> handles) { |
| mHandlesToClose.add(handles.first); |
| mHandlesToClose.add(handles.second); |
| } |
| |
| /** |
| * Runnable that will close the given handle. |
| */ |
| private static class CloseHandle implements Runnable { |
| private Handle mHandle; |
| |
| CloseHandle(Handle handle) { |
| mHandle = handle; |
| } |
| |
| @Override |
| public void run() { |
| mHandle.close(); |
| } |
| } |
| |
| private static void checkSendingMessage(MessagePipeHandle in, MessagePipeHandle out) { |
| Random random = new Random(); |
| |
| // Writing a random 8 bytes message. |
| byte[] bytes = new byte[8]; |
| random.nextBytes(bytes); |
| ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length); |
| buffer.put(bytes); |
| in.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.NONE); |
| |
| // Try to read into a small buffer. |
| ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length / 2); |
| MessagePipeHandle.ReadMessageResult result = out.readMessage( |
| receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE); |
| assertEquals(MojoResult.RESOURCE_EXHAUSTED, result.getMojoResult()); |
| assertEquals(bytes.length, result.getMessageSize()); |
| assertEquals(0, result.getHandlesCount()); |
| |
| // Read into a correct buffer. |
| receiveBuffer = ByteBuffer.allocateDirect(bytes.length); |
| result = out.readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE); |
| assertEquals(MojoResult.OK, result.getMojoResult()); |
| assertEquals(bytes.length, result.getMessageSize()); |
| assertEquals(0, result.getHandlesCount()); |
| assertEquals(0, receiveBuffer.position()); |
| assertEquals(result.getMessageSize(), receiveBuffer.limit()); |
| byte[] receivedBytes = new byte[result.getMessageSize()]; |
| receiveBuffer.get(receivedBytes); |
| assertTrue(Arrays.equals(bytes, receivedBytes)); |
| |
| } |
| |
| private static void checkSendingData(DataPipe.ProducerHandle in, DataPipe.ConsumerHandle out) { |
| Random random = new Random(); |
| |
| // Writing a random 8 bytes message. |
| byte[] bytes = new byte[8]; |
| random.nextBytes(bytes); |
| ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length); |
| buffer.put(bytes); |
| int result = in.writeData(buffer, DataPipe.WriteFlags.NONE); |
| assertEquals(bytes.length, result); |
| |
| // Query number of bytes available. |
| result = out.readData(null, DataPipe.ReadFlags.none().query(true)); |
| assertEquals(bytes.length, result); |
| |
| // Read into a buffer. |
| ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length); |
| result = out.readData(receiveBuffer, DataPipe.ReadFlags.NONE); |
| assertEquals(bytes.length, result); |
| assertEquals(0, receiveBuffer.position()); |
| assertEquals(bytes.length, receiveBuffer.limit()); |
| byte[] receivedBytes = new byte[bytes.length]; |
| receiveBuffer.get(receivedBytes); |
| assertTrue(Arrays.equals(bytes, receivedBytes)); |
| } |
| |
| private static void checkSharing(SharedBufferHandle in, SharedBufferHandle out) { |
| Random random = new Random(); |
| |
| ByteBuffer buffer1 = in.map(0, 8, SharedBufferHandle.MapFlags.NONE); |
| assertEquals(8, buffer1.capacity()); |
| ByteBuffer buffer2 = out.map(0, 8, SharedBufferHandle.MapFlags.NONE); |
| assertEquals(8, buffer2.capacity()); |
| |
| byte[] bytes = new byte[8]; |
| random.nextBytes(bytes); |
| buffer1.put(bytes); |
| |
| byte[] receivedBytes = new byte[bytes.length]; |
| buffer2.get(receivedBytes); |
| |
| assertTrue(Arrays.equals(bytes, receivedBytes)); |
| |
| in.unmap(buffer1); |
| out.unmap(buffer2); |
| } |
| |
| /** |
| * Testing {@link Core#waitMany(List, long)}. |
| */ |
| @SmallTest |
| public void testWaitMany() { |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| List<Pair<Handle, Core.HandleSignals>> handlesToWaitOn = new ArrayList< |
| Pair<Handle, Core.HandleSignals>>(); |
| handlesToWaitOn.add( |
| new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE)); |
| handlesToWaitOn.add( |
| new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE)); |
| WaitManyResult result = core.waitMany(handlesToWaitOn, 0); |
| assertEquals(MojoResult.OK, result.getMojoResult()); |
| assertEquals(1, result.getHandleIndex()); |
| |
| handlesToWaitOn.clear(); |
| handlesToWaitOn.add( |
| new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE)); |
| handlesToWaitOn.add( |
| new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE)); |
| result = core.waitMany(handlesToWaitOn, 0); |
| assertEquals(MojoResult.OK, result.getMojoResult()); |
| assertEquals(0, result.getHandleIndex()); |
| } |
| |
| /** |
| * Testing that Core can be retrieved from a handle. |
| */ |
| @SmallTest |
| public void testGetCore() { |
| Core core = CoreImpl.getInstance(); |
| |
| Pair<? extends Handle, ? extends Handle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| assertEquals(core, handles.first.getCore()); |
| assertEquals(core, handles.second.getCore()); |
| |
| handles = core.createDataPipe(null); |
| addHandlePairToClose(handles); |
| assertEquals(core, handles.first.getCore()); |
| assertEquals(core, handles.second.getCore()); |
| |
| SharedBufferHandle handle = core.createSharedBuffer(null, 100); |
| SharedBufferHandle handle2 = handle.duplicate(null); |
| addHandleToClose(handle); |
| addHandleToClose(handle2); |
| assertEquals(core, handle.getCore()); |
| assertEquals(core, handle2.getCore()); |
| } |
| |
| private static void createAndCloseMessagePipe(MessagePipeHandle.CreateOptions options) { |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(options); |
| handles.first.close(); |
| handles.second.close(); |
| } |
| |
| /** |
| * Testing {@link MessagePipeHandle} creation. |
| */ |
| @SmallTest |
| public void testMessagePipeCreation() { |
| // Test creation with null options. |
| createAndCloseMessagePipe(null); |
| // Test creation with default options. |
| createAndCloseMessagePipe(new MessagePipeHandle.CreateOptions()); |
| } |
| |
| /** |
| * Testing {@link MessagePipeHandle}. |
| */ |
| @SmallTest |
| public void testMessagePipeEmpty() { |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| // Testing wait. |
| assertEquals(MojoResult.OK, |
| handles.first.wait(Core.HandleSignals.none().setReadable(true).setWritable(true), |
| 0)); |
| assertEquals(MojoResult.OK, handles.first.wait(Core.HandleSignals.WRITABLE, 0)); |
| assertEquals(MojoResult.DEADLINE_EXCEEDED, |
| handles.first.wait(Core.HandleSignals.READABLE, 0)); |
| |
| // Testing read on an empty pipe. |
| MessagePipeHandle.ReadMessageResult result = handles.first.readMessage(null, 0, |
| MessagePipeHandle.ReadFlags.NONE); |
| assertEquals(MojoResult.SHOULD_WAIT, result.getMojoResult()); |
| |
| // Closing a pipe while waiting. |
| WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS); |
| assertEquals(MojoResult.CANCELLED, |
| handles.first.wait(Core.HandleSignals.READABLE, 1000000L)); |
| |
| handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| // Closing the other pipe while waiting. |
| WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS); |
| assertEquals(MojoResult.FAILED_PRECONDITION, |
| handles.second.wait(Core.HandleSignals.READABLE, 1000000L)); |
| |
| // Waiting on a closed pipe. |
| assertEquals(MojoResult.FAILED_PRECONDITION, |
| handles.second.wait(Core.HandleSignals.READABLE, 0)); |
| assertEquals(MojoResult.FAILED_PRECONDITION, |
| handles.second.wait(Core.HandleSignals.WRITABLE, 0)); |
| } |
| |
| /** |
| * Testing {@link MessagePipeHandle}. |
| */ |
| @SmallTest |
| public void testMessagePipeSend() { |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| checkSendingMessage(handles.first, handles.second); |
| checkSendingMessage(handles.second, handles.first); |
| } |
| |
| /** |
| * Testing {@link MessagePipeHandle}. |
| */ |
| @SmallTest |
| public void testMessagePipeReceiveOnSmallBuffer() { |
| Random random = new Random(); |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| // Writing a random 8 bytes message. |
| byte[] bytes = new byte[8]; |
| random.nextBytes(bytes); |
| ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length); |
| buffer.put(bytes); |
| handles.first.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.NONE); |
| |
| ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(1); |
| MessagePipeHandle.ReadMessageResult result = handles.second |
| .readMessage(receiveBuffer, 0, MessagePipeHandle.ReadFlags.NONE); |
| assertEquals(MojoResult.RESOURCE_EXHAUSTED, result.getMojoResult()); |
| assertEquals(bytes.length, result.getMessageSize()); |
| assertEquals(0, result.getHandlesCount()); |
| } |
| |
| /** |
| * Testing {@link MessagePipeHandle}. |
| */ |
| @SmallTest |
| public void testMessagePipeSendHandles() { |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| Pair<MessagePipeHandle, MessagePipeHandle> handlesToShare = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| addHandlePairToClose(handlesToShare); |
| |
| handles.first.writeMessage(null, |
| Collections.<Handle> singletonList(handlesToShare.second), |
| MessagePipeHandle.WriteFlags.NONE); |
| assertFalse(handlesToShare.second.isValid()); |
| MessagePipeHandle.ReadMessageResult readMessageResult = |
| handles.second.readMessage(null, 1, MessagePipeHandle.ReadFlags.NONE); |
| assertEquals(1, readMessageResult.getHandlesCount()); |
| MessagePipeHandle newHandle = readMessageResult.getHandles().get(0) |
| .toMessagePipeHandle(); |
| addHandleToClose(newHandle); |
| assertTrue(newHandle.isValid()); |
| checkSendingMessage(handlesToShare.first, newHandle); |
| checkSendingMessage(newHandle, handlesToShare.first); |
| } |
| |
| private static void createAndCloseDataPipe(DataPipe.CreateOptions options) { |
| Core core = CoreImpl.getInstance(); |
| Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe( |
| options); |
| handles.first.close(); |
| handles.second.close(); |
| } |
| |
| /** |
| * Testing {@link DataPipe}. |
| */ |
| @SmallTest |
| public void testDataPipeCreation() { |
| // Create datapipe with null options. |
| createAndCloseDataPipe(null); |
| DataPipe.CreateOptions options = new DataPipe.CreateOptions(); |
| // Create datapipe with element size set. |
| options.setElementNumBytes(24); |
| createAndCloseDataPipe(options); |
| // Create datapipe with a flag set. |
| options.getFlags().setMayDiscard(true); |
| createAndCloseDataPipe(options); |
| // Create datapipe with capacity set. |
| options.setCapacityNumBytes(1024 * options.getElementNumBytes()); |
| createAndCloseDataPipe(options); |
| } |
| |
| /** |
| * Testing {@link DataPipe}. |
| */ |
| @SmallTest |
| public void testDataPipeSend() { |
| Core core = CoreImpl.getInstance(); |
| |
| Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null); |
| addHandlePairToClose(handles); |
| |
| checkSendingData(handles.first, handles.second); |
| } |
| |
| /** |
| * Testing {@link DataPipe}. |
| */ |
| @SmallTest |
| public void testDataPipeTwoPhaseSend() { |
| Random random = new Random(); |
| Core core = CoreImpl.getInstance(); |
| Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null); |
| addHandlePairToClose(handles); |
| |
| // Writing a random 8 bytes message. |
| byte[] bytes = new byte[8]; |
| random.nextBytes(bytes); |
| ByteBuffer buffer = handles.first.beginWriteData(bytes.length, |
| DataPipe.WriteFlags.NONE); |
| assertTrue(buffer.capacity() >= bytes.length); |
| buffer.put(bytes); |
| handles.first.endWriteData(bytes.length); |
| |
| // Read into a buffer. |
| ByteBuffer receiveBuffer = handles.second.beginReadData(bytes.length, |
| DataPipe.ReadFlags.NONE); |
| assertEquals(0, receiveBuffer.position()); |
| assertEquals(bytes.length, receiveBuffer.limit()); |
| byte[] receivedBytes = new byte[bytes.length]; |
| receiveBuffer.get(receivedBytes); |
| assertTrue(Arrays.equals(bytes, receivedBytes)); |
| handles.second.endReadData(bytes.length); |
| } |
| |
| /** |
| * Testing {@link DataPipe}. |
| */ |
| @SmallTest |
| public void testDataPipeDiscard() { |
| Random random = new Random(); |
| Core core = CoreImpl.getInstance(); |
| Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null); |
| addHandlePairToClose(handles); |
| |
| // Writing a random 8 bytes message. |
| byte[] bytes = new byte[8]; |
| random.nextBytes(bytes); |
| ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length); |
| buffer.put(bytes); |
| int result = handles.first.writeData(buffer, DataPipe.WriteFlags.NONE); |
| assertEquals(bytes.length, result); |
| |
| // Discard bytes. |
| final int nbBytesToDiscard = 4; |
| assertEquals(nbBytesToDiscard, |
| handles.second.discardData(nbBytesToDiscard, DataPipe.ReadFlags.NONE)); |
| |
| // Read into a buffer. |
| ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length - nbBytesToDiscard); |
| result = handles.second.readData(receiveBuffer, DataPipe.ReadFlags.NONE); |
| assertEquals(bytes.length - nbBytesToDiscard, result); |
| assertEquals(0, receiveBuffer.position()); |
| assertEquals(bytes.length - nbBytesToDiscard, receiveBuffer.limit()); |
| byte[] receivedBytes = new byte[bytes.length - nbBytesToDiscard]; |
| receiveBuffer.get(receivedBytes); |
| assertTrue(Arrays.equals(Arrays.copyOfRange(bytes, nbBytesToDiscard, bytes.length), |
| receivedBytes)); |
| } |
| |
| /** |
| * Testing {@link SharedBufferHandle}. |
| */ |
| @SmallTest |
| public void testSharedBufferCreation() { |
| Core core = CoreImpl.getInstance(); |
| // Test creation with empty options. |
| core.createSharedBuffer(null, 8).close(); |
| // Test creation with default options. |
| core.createSharedBuffer(new SharedBufferHandle.CreateOptions(), 8).close(); |
| } |
| |
| /** |
| * Testing {@link SharedBufferHandle}. |
| */ |
| @SmallTest |
| public void testSharedBufferDuplication() { |
| Core core = CoreImpl.getInstance(); |
| SharedBufferHandle handle = core.createSharedBuffer(null, 8); |
| addHandleToClose(handle); |
| |
| // Test duplication with empty options. |
| handle.duplicate(null).close(); |
| // Test creation with default options. |
| handle.duplicate(new SharedBufferHandle.DuplicateOptions()).close(); |
| } |
| |
| /** |
| * Testing {@link SharedBufferHandle}. |
| */ |
| @SmallTest |
| public void testSharedBufferSending() { |
| Core core = CoreImpl.getInstance(); |
| SharedBufferHandle handle = core.createSharedBuffer(null, 8); |
| addHandleToClose(handle); |
| SharedBufferHandle newHandle = handle.duplicate(null); |
| addHandleToClose(newHandle); |
| |
| checkSharing(handle, newHandle); |
| checkSharing(newHandle, handle); |
| } |
| |
| /** |
| * Testing that invalid handle can be used with this implementation. |
| */ |
| @SmallTest |
| public void testInvalidHandle() { |
| Core core = CoreImpl.getInstance(); |
| Handle handle = InvalidHandle.INSTANCE; |
| |
| // Checking wait. |
| boolean exception = false; |
| try { |
| core.wait(handle, Core.HandleSignals.WRITABLE, 0); |
| } catch (MojoException e) { |
| assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult()); |
| exception = true; |
| } |
| assertTrue(exception); |
| |
| // Checking waitMany. |
| exception = false; |
| try { |
| List<Pair<Handle, Core.HandleSignals>> handles = new ArrayList< |
| Pair<Handle, Core.HandleSignals>>(); |
| handles.add(Pair.create(handle, Core.HandleSignals.WRITABLE)); |
| core.waitMany(handles, 0); |
| } catch (MojoException e) { |
| assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult()); |
| exception = true; |
| } |
| assertTrue(exception); |
| |
| // Checking sending an invalid handle. |
| // Until the behavior is changed on the C++ side, handle gracefully 2 different use case: |
| // - Receive a INVALID_ARGUMENT exception |
| // - Receive an invalid handle on the other side. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| try { |
| handles.first.writeMessage(null, Collections.<Handle> singletonList(handle), |
| MessagePipeHandle.WriteFlags.NONE); |
| MessagePipeHandle.ReadMessageResult readMessageResult = |
| handles.second.readMessage(null, 1, MessagePipeHandle.ReadFlags.NONE); |
| assertEquals(1, readMessageResult.getHandlesCount()); |
| assertFalse(readMessageResult.getHandles().get(0).isValid()); |
| } catch (MojoException e) { |
| assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult()); |
| } |
| } |
| |
| private static class AsyncWaiterResult implements Callback { |
| private int mResult = Integer.MIN_VALUE; |
| private MojoException mException = null; |
| |
| /** |
| * @see Callback#onResult(int) |
| */ |
| @Override |
| public void onResult(int result) { |
| this.mResult = result; |
| } |
| |
| /** |
| * @see Callback#onError(MojoException) |
| */ |
| @Override |
| public void onError(MojoException exception) { |
| this.mException = exception; |
| } |
| |
| /** |
| * @return the result |
| */ |
| public int getResult() { |
| return mResult; |
| } |
| |
| /** |
| * @return the exception |
| */ |
| public MojoException getException() { |
| return mException; |
| } |
| |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterCorrectResult() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Checking a correct result. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE, |
| Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| handles.second.writeMessage(ByteBuffer.allocateDirect(1), null, |
| MessagePipeHandle.WriteFlags.NONE); |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertNull(asyncWaiterResult.getException()); |
| assertEquals(MojoResult.OK, asyncWaiterResult.getResult()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterClosingPeerHandle() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Closing the peer handle. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE, |
| Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| handles.second.close(); |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertNull(asyncWaiterResult.getException()); |
| assertEquals(MojoResult.FAILED_PRECONDITION, asyncWaiterResult.getResult()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterClosingWaitingHandle() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Closing the peer handle. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE, |
| Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| handles.first.close(); |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| // TODO(qsr) Re-enable when MojoWaitMany handles it correctly. |
| // assertNull(asyncWaiterResult.getException()); |
| // assertEquals(MojoResult.CANCELLED, asyncWaiterResult.getResult()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterWaitingOnInvalidHandle() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Closing the peer handle. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| handles.first.close(); |
| core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE, |
| Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertNotNull(asyncWaiterResult.getException()); |
| assertEquals(MojoResult.INVALID_ARGUMENT, |
| asyncWaiterResult.getException().getMojoResult()); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterWaitingOnDefaultInvalidHandle() { |
| Core core = CoreImpl.getInstance(); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| core.getDefaultAsyncWaiter().asyncWait(InvalidHandle.INSTANCE, Core.HandleSignals.READABLE, |
| Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertNotNull(asyncWaiterResult.getException()); |
| assertEquals(MojoResult.INVALID_ARGUMENT, asyncWaiterResult.getException().getMojoResult()); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterWaitingWithTimeout() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Closing the peer handle. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| core.getDefaultAsyncWaiter().asyncWait(handles.first, Core.HandleSignals.READABLE, |
| RUN_LOOP_TIMEOUT_MS, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| nativeRunLoop(10 * RUN_LOOP_TIMEOUT_MS); |
| assertNull(asyncWaiterResult.getException()); |
| assertEquals(MojoResult.DEADLINE_EXCEEDED, asyncWaiterResult.getResult()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterCancelWaiting() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Closing the peer handle. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| Cancellable cancellable = core.getDefaultAsyncWaiter().asyncWait(handles.first, |
| Core.HandleSignals.READABLE, Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| cancellable.cancel(); |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| handles.second.writeMessage(ByteBuffer.allocateDirect(1), null, |
| MessagePipeHandle.WriteFlags.NONE); |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| } |
| |
| /** |
| * Testing core {@link AsyncWaiter} implementation. |
| */ |
| @SmallTest |
| public void testAsyncWaiterImmediateCancelOnInvalidHandle() { |
| Core core = CoreImpl.getInstance(); |
| |
| // Closing the peer handle. |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| final AsyncWaiterResult asyncWaiterResult = new AsyncWaiterResult(); |
| handles.first.close(); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| |
| Cancellable cancellable = core.getDefaultAsyncWaiter().asyncWait(handles.first, |
| Core.HandleSignals.READABLE, Core.DEADLINE_INFINITE, asyncWaiterResult); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| cancellable.cancel(); |
| |
| nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
| assertEquals(Integer.MIN_VALUE, asyncWaiterResult.getResult()); |
| assertEquals(null, asyncWaiterResult.getException()); |
| } |
| |
| /** |
| * Testing the pass method on message pipes. |
| */ |
| @SmallTest |
| public void testMessagePipeHandlePass() { |
| Core core = CoreImpl.getInstance(); |
| Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null); |
| addHandlePairToClose(handles); |
| |
| assertTrue(handles.first.isValid()); |
| MessagePipeHandle handleClone = handles.first.pass(); |
| |
| addHandleToClose(handleClone); |
| |
| assertFalse(handles.first.isValid()); |
| assertTrue(handleClone.isValid()); |
| checkSendingMessage(handleClone, handles.second); |
| checkSendingMessage(handles.second, handleClone); |
| } |
| |
| /** |
| * Testing the pass method on data pipes. |
| */ |
| @SmallTest |
| public void testDataPipeHandlePass() { |
| Core core = CoreImpl.getInstance(); |
| Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null); |
| addHandlePairToClose(handles); |
| |
| DataPipe.ProducerHandle producerClone = handles.first.pass(); |
| DataPipe.ConsumerHandle consumerClone = handles.second.pass(); |
| |
| addHandleToClose(producerClone); |
| addHandleToClose(consumerClone); |
| |
| assertFalse(handles.first.isValid()); |
| assertFalse(handles.second.isValid()); |
| assertTrue(producerClone.isValid()); |
| assertTrue(consumerClone.isValid()); |
| checkSendingData(producerClone, consumerClone); |
| } |
| |
| /** |
| * Testing the pass method on shared buffers. |
| */ |
| @SmallTest |
| public void testSharedBufferPass() { |
| Core core = CoreImpl.getInstance(); |
| SharedBufferHandle handle = core.createSharedBuffer(null, 8); |
| addHandleToClose(handle); |
| SharedBufferHandle newHandle = handle.duplicate(null); |
| addHandleToClose(newHandle); |
| |
| SharedBufferHandle handleClone = handle.pass(); |
| SharedBufferHandle newHandleClone = newHandle.pass(); |
| |
| addHandleToClose(handleClone); |
| addHandleToClose(newHandleClone); |
| |
| assertFalse(handle.isValid()); |
| assertTrue(handleClone.isValid()); |
| checkSharing(handleClone, newHandleClone); |
| checkSharing(newHandleClone, handleClone); |
| } |
| |
| } |