blob: 97bab765d79b98086b15d0d1d2aa6eb7254d6e86 [file] [log] [blame]
// 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());
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);
// 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 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);
}
}