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