Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / android / javatests / src / org / chromium / mojo / system / CoreTest.java
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.mojo.system;
6
7 import android.content.Context;
8 import android.test.InstrumentationTestCase;
9 import android.test.suitebuilder.annotation.SmallTest;
10
11 import org.chromium.base.JNINamespace;
12 import org.chromium.base.library_loader.LibraryLoader;
13 import org.chromium.mojo.system.Core.WaitFlags;
14 import org.chromium.mojo.system.Core.WaitManyResult;
15 import org.chromium.mojo.system.MessagePipeHandle.ReadFlags;
16 import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
17 import org.chromium.mojo.system.MessagePipeHandle.WriteFlags;
18 import org.chromium.mojo.system.SharedBufferHandle.MapFlags;
19
20 import java.nio.ByteBuffer;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Random;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.TimeUnit;
29
30 /**
31  * Testing the core API.
32  */
33 @JNINamespace("mojo::android")
34 public class CoreTest extends InstrumentationTestCase {
35
36     private static final ScheduledExecutorService WORKER =
37             Executors.newSingleThreadScheduledExecutor();
38
39     /**
40      * @see junit.framework.TestCase#setUp()
41      */
42     @Override
43     protected void setUp() throws Exception {
44         LibraryLoader.ensureInitialized();
45         nativeInitApplicationContext(getInstrumentation().getTargetContext());
46     }
47
48     /**
49      * Runnable that will close the given handle.
50      */
51     private static class CloseHandle implements Runnable {
52         private Handle mHandle;
53
54         CloseHandle(Handle handle) {
55             mHandle = handle;
56         }
57
58         @Override
59         public void run() {
60             mHandle.close();
61         }
62     }
63
64     private static void checkSendingMessage(MessagePipeHandle in, MessagePipeHandle out) {
65         Random random = new Random();
66
67         // Writing a random 8 bytes message.
68         byte[] bytes = new byte[8];
69         random.nextBytes(bytes);
70         ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
71         buffer.put(bytes);
72         in.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.none());
73
74         // Try to read into a small buffer.
75         ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length / 2);
76         MessagePipeHandle.ReadMessageResult result = out.readMessage(receiveBuffer, 0,
77                 MessagePipeHandle.ReadFlags.none());
78         assertFalse(result.getWasMessageRead());
79         assertEquals(bytes.length, result.getMessageSize());
80         assertEquals(0, result.getHandlesCount());
81
82         // Read into a correct buffer.
83         receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
84         result = out.readMessage(receiveBuffer, 0,
85                 MessagePipeHandle.ReadFlags.none());
86         assertTrue(result.getWasMessageRead());
87         assertEquals(bytes.length, result.getMessageSize());
88         assertEquals(0, result.getHandlesCount());
89         assertEquals(0, receiveBuffer.position());
90         assertEquals(result.getMessageSize(), receiveBuffer.limit());
91         byte[] receivedBytes = new byte[result.getMessageSize()];
92         receiveBuffer.get(receivedBytes);
93         assertTrue(Arrays.equals(bytes, receivedBytes));
94
95     }
96
97     /**
98      * Testing {@link Core#waitMany(List, long)}.
99      */
100     @SmallTest
101     public void testWaitMany() {
102         Core core = CoreImpl.getInstance();
103         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
104
105         try {
106             List<Pair<Handle, WaitFlags>> handlesToWaitOn = new ArrayList<
107                     Pair<Handle, WaitFlags>>();
108
109             handlesToWaitOn.add(
110                     new Pair<Handle, WaitFlags>(handles.second,
111                             WaitFlags.none().setReadable(true)));
112             handlesToWaitOn.add(
113                     new Pair<Handle, WaitFlags>(handles.first, WaitFlags.none().setWritable(true)));
114             WaitManyResult result = core.waitMany(handlesToWaitOn, 0);
115             assertEquals(MojoResult.OK, result.getMojoResult());
116             assertEquals(1, result.getHandleIndex());
117
118             handlesToWaitOn.clear();
119             handlesToWaitOn.add(
120                     new Pair<Handle, WaitFlags>(handles.first, WaitFlags.none().setWritable(true)));
121             handlesToWaitOn.add(
122                     new Pair<Handle, WaitFlags>(handles.second,
123                             WaitFlags.none().setReadable(true)));
124             result = core.waitMany(handlesToWaitOn, 0);
125             assertEquals(MojoResult.OK, result.getMojoResult());
126             assertEquals(0, result.getHandleIndex());
127         } finally {
128             handles.first.close();
129             handles.second.close();
130         }
131     }
132
133     /**
134      * Testing {@link MessagePipeHandle}.
135      */
136     @SmallTest
137     public void testMessagePipeEmpty() {
138         Core core = CoreImpl.getInstance();
139         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
140
141         try {
142             // Testing wait.
143             assertEquals(MojoResult.OK, handles.first.wait(WaitFlags.all(), 0));
144             assertEquals(MojoResult.OK, handles.first.wait(WaitFlags.none().setWritable(true), 0));
145             assertEquals(MojoResult.DEADLINE_EXCEEDED,
146                     handles.first.wait(WaitFlags.none().setReadable(true), 0));
147
148             // Testing read on an empty pipe.
149             boolean exception = false;
150             try {
151                 handles.first.readMessage(null, 0, MessagePipeHandle.ReadFlags.none());
152             } catch (MojoException e) {
153                 assertEquals(MojoResult.SHOULD_WAIT, e.getMojoResult());
154                 exception = true;
155             }
156             assertTrue(exception);
157
158             // Closing a pipe while waiting.
159             WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
160             assertEquals(MojoResult.CANCELLED,
161                     handles.first.wait(WaitFlags.none().setReadable(true), 1000000L));
162         } finally {
163             handles.first.close();
164             handles.second.close();
165         }
166
167         handles = core.createMessagePipe();
168
169         try {
170             // Closing the other pipe while waiting.
171             WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
172             assertEquals(MojoResult.FAILED_PRECONDITION,
173                     handles.second.wait(WaitFlags.none().setReadable(true), 1000000L));
174
175             // Waiting on a closed pipe.
176             assertEquals(MojoResult.FAILED_PRECONDITION,
177                     handles.second.wait(WaitFlags.none().setReadable(true), 0));
178             assertEquals(MojoResult.FAILED_PRECONDITION,
179                     handles.second.wait(WaitFlags.none().setWritable(true), 0));
180         } finally {
181             handles.first.close();
182             handles.second.close();
183         }
184
185     }
186
187     /**
188      * Testing {@link MessagePipeHandle}.
189      */
190     @SmallTest
191     public void testMessagePipeSend() {
192         Core core = CoreImpl.getInstance();
193         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
194
195         try {
196             checkSendingMessage(handles.first, handles.second);
197             checkSendingMessage(handles.second, handles.first);
198         } finally {
199             handles.first.close();
200             handles.second.close();
201         }
202     }
203
204     /**
205      * Testing {@link MessagePipeHandle}.
206      */
207     @SmallTest
208     public void testMessagePipeReceiveOnSmallBuffer() {
209         Random random = new Random();
210         Core core = CoreImpl.getInstance();
211         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
212
213         try {
214             // Writing a random 8 bytes message.
215             byte[] bytes = new byte[8];
216             random.nextBytes(bytes);
217             ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
218             buffer.put(bytes);
219             handles.first.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.none());
220
221             ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(1);
222             MessagePipeHandle.ReadMessageResult result = handles.second.readMessage(receiveBuffer,
223                     0,
224                     MessagePipeHandle.ReadFlags.none());
225             assertFalse(result.getWasMessageRead());
226             assertEquals(bytes.length, result.getMessageSize());
227             assertEquals(0, result.getHandlesCount());
228         } finally {
229             handles.first.close();
230             handles.second.close();
231         }
232     }
233
234     /**
235      * Testing {@link MessagePipeHandle}.
236      */
237     @SmallTest
238     public void testMessagePipeSendHandles() {
239         Core core = CoreImpl.getInstance();
240         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
241         Pair<MessagePipeHandle, MessagePipeHandle> handlesToShare = core.createMessagePipe();
242
243         try {
244             handles.first.writeMessage(null,
245                     Collections.<Handle> singletonList(handlesToShare.second),
246                     WriteFlags.none());
247             assertFalse(handlesToShare.second.isValid());
248             ReadMessageResult readMessageResult = handles.second.readMessage(null, 1,
249                     ReadFlags.none());
250             assertEquals(1, readMessageResult.getHandlesCount());
251             MessagePipeHandle newHandle = readMessageResult.getHandles().get(0)
252                     .toMessagePipeHandle();
253             try {
254                 assertTrue(newHandle.isValid());
255                 checkSendingMessage(handlesToShare.first, newHandle);
256                 checkSendingMessage(newHandle, handlesToShare.first);
257             } finally {
258                 newHandle.close();
259             }
260         } finally {
261             handles.first.close();
262             handles.second.close();
263             handlesToShare.first.close();
264             handlesToShare.second.close();
265         }
266     }
267
268     private static void createAndCloseDataPipe(DataPipe.CreateOptions options) {
269         Core core = CoreImpl.getInstance();
270         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(
271                 options);
272         handles.first.close();
273         handles.second.close();
274     }
275
276     /**
277      * Testing {@link DataPipe}.
278      */
279     @SmallTest
280     public void testDataPipeCreation() {
281         // Create datapipe with null options.
282         createAndCloseDataPipe(null);
283         DataPipe.CreateOptions options = new DataPipe.CreateOptions();
284         // Create datapipe with element size set.
285         options.setElementNumBytes(24);
286         createAndCloseDataPipe(options);
287         // Create datapipe with a flag set.
288         options.getFlags().setMayDiscard(true);
289         createAndCloseDataPipe(options);
290         // Create datapipe with capacity set.
291         options.setCapacityNumBytes(1024 * options.getElementNumBytes());
292         createAndCloseDataPipe(options);
293     }
294
295     /**
296      * Testing {@link DataPipe}.
297      */
298     @SmallTest
299     public void testDataPipeSend() {
300         Core core = CoreImpl.getInstance();
301         Random random = new Random();
302
303         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
304         try {
305             // Writing a random 8 bytes message.
306             byte[] bytes = new byte[8];
307             random.nextBytes(bytes);
308             ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
309             buffer.put(bytes);
310             int result = handles.first.writeData(buffer, DataPipe.WriteFlags.none());
311             assertEquals(bytes.length, result);
312
313             // Query number of bytes available.
314             result = handles.second.readData(null,
315                     DataPipe.ReadFlags.none().query(true));
316             assertEquals(bytes.length, result);
317
318             // Read into a buffer.
319             ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
320             result = handles.second.readData(receiveBuffer,
321                     DataPipe.ReadFlags.none());
322             assertEquals(bytes.length, result);
323             assertEquals(0, receiveBuffer.position());
324             assertEquals(bytes.length, receiveBuffer.limit());
325             byte[] receivedBytes = new byte[bytes.length];
326             receiveBuffer.get(receivedBytes);
327             assertTrue(Arrays.equals(bytes, receivedBytes));
328         } finally {
329             handles.first.close();
330             handles.second.close();
331         }
332     }
333
334     /**
335      * Testing {@link DataPipe}.
336      */
337     @SmallTest
338     public void testDataPipeTwoPhaseSend() {
339         Random random = new Random();
340         Core core = CoreImpl.getInstance();
341         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
342
343         try {
344             // Writing a random 8 bytes message.
345             byte[] bytes = new byte[8];
346             random.nextBytes(bytes);
347             ByteBuffer buffer = handles.first.beginWriteData(bytes.length,
348                     DataPipe.WriteFlags.none());
349             assertTrue(buffer.capacity() >= bytes.length);
350             buffer.put(bytes);
351             handles.first.endWriteData(bytes.length);
352
353             // Read into a buffer.
354             ByteBuffer receiveBuffer = handles.second.beginReadData(bytes.length,
355                     DataPipe.ReadFlags.none());
356             assertEquals(0, receiveBuffer.position());
357             assertEquals(bytes.length, receiveBuffer.limit());
358             byte[] receivedBytes = new byte[bytes.length];
359             receiveBuffer.get(receivedBytes);
360             assertTrue(Arrays.equals(bytes, receivedBytes));
361             handles.second.endReadData(bytes.length);
362         } finally {
363             handles.first.close();
364             handles.second.close();
365         }
366     }
367
368     /**
369      * Testing {@link DataPipe}.
370      */
371     @SmallTest
372     public void testDataPipeDiscard() {
373         Random random = new Random();
374         Core core = CoreImpl.getInstance();
375         Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
376
377         try {
378             // Writing a random 8 bytes message.
379             byte[] bytes = new byte[8];
380             random.nextBytes(bytes);
381             ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
382             buffer.put(bytes);
383             int result = handles.first.writeData(buffer, DataPipe.WriteFlags.none());
384             assertEquals(bytes.length, result);
385
386             // Discard bytes.
387             final int nbBytesToDiscard = 4;
388             assertEquals(nbBytesToDiscard,
389                     handles.second.discardData(nbBytesToDiscard, DataPipe.ReadFlags.none()));
390
391             // Read into a buffer.
392             ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length - nbBytesToDiscard);
393             result = handles.second.readData(receiveBuffer,
394                     DataPipe.ReadFlags.none());
395             assertEquals(bytes.length - nbBytesToDiscard, result);
396             assertEquals(0, receiveBuffer.position());
397             assertEquals(bytes.length - nbBytesToDiscard, receiveBuffer.limit());
398             byte[] receivedBytes = new byte[bytes.length - nbBytesToDiscard];
399             receiveBuffer.get(receivedBytes);
400             assertTrue(Arrays.equals(Arrays.copyOfRange(bytes, nbBytesToDiscard, bytes.length),
401                     receivedBytes));
402         } finally {
403             handles.first.close();
404             handles.second.close();
405         }
406     }
407
408     /**
409      * Testing {@link SharedBufferHandle}.
410      */
411     @SmallTest
412     public void testSharedBufferCreation() {
413         Core core = CoreImpl.getInstance();
414         // Test creation with empty options.
415         core.createSharedBuffer(null, 8).close();
416         // Test creation with default options.
417         core.createSharedBuffer(new SharedBufferHandle.CreateOptions(), 8);
418     }
419
420     /**
421      * Testing {@link SharedBufferHandle}.
422      */
423     @SmallTest
424     public void testSharedBufferDuplication() {
425         Core core = CoreImpl.getInstance();
426         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
427         try {
428             // Test duplication with empty options.
429             handle.duplicate(null).close();
430             // Test creation with default options.
431             handle.duplicate(new SharedBufferHandle.DuplicateOptions()).close();
432         } finally {
433             handle.close();
434         }
435     }
436
437     /**
438      * Testing {@link SharedBufferHandle}.
439      */
440     @SmallTest
441     public void testSharedBufferSending() {
442         Random random = new Random();
443         Core core = CoreImpl.getInstance();
444         SharedBufferHandle handle = core.createSharedBuffer(null, 8);
445         SharedBufferHandle newHandle = handle.duplicate(null);
446
447         try {
448             ByteBuffer buffer1 = handle.map(0, 8, MapFlags.none());
449             assertEquals(8, buffer1.capacity());
450             ByteBuffer buffer2 = newHandle.map(0, 8, MapFlags.none());
451             assertEquals(8, buffer2.capacity());
452
453             byte[] bytes = new byte[8];
454             random.nextBytes(bytes);
455             buffer1.put(bytes);
456
457             byte[] receivedBytes = new byte[bytes.length];
458             buffer2.get(receivedBytes);
459
460             assertTrue(Arrays.equals(bytes, receivedBytes));
461
462             handle.unmap(buffer1);
463             newHandle.unmap(buffer2);
464         } finally {
465             handle.close();
466             newHandle.close();
467         }
468     }
469
470     /**
471      * Testing that invalid handle can be used with this implementation.
472      */
473     @SmallTest
474     public void testInvalidHandle() {
475         Core core = CoreImpl.getInstance();
476         Handle handle = new InvalidHandle();
477
478         // Checking wait.
479         boolean exception = false;
480         try {
481             core.wait(handle, WaitFlags.all(), 0);
482         } catch (MojoException e) {
483             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
484             exception = true;
485         }
486         assertTrue(exception);
487
488         // Checking waitMany.
489         exception = false;
490         try {
491             List<Pair<Handle, WaitFlags>> handles = new ArrayList<Pair<Handle, WaitFlags>>();
492             handles.add(Pair.create(handle, WaitFlags.all()));
493             core.waitMany(handles, 0);
494         } catch (MojoException e) {
495             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
496             exception = true;
497         }
498         assertTrue(exception);
499
500         // Checking sending an invalid handle.
501         // Until the behavior is changed on the C++ side, handle gracefully 2 different use case:
502         // - Receive a INVALID_ARGUMENT exception
503         // - Receive an invalid handle on the other side.
504         Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
505         try {
506             handles.first.writeMessage(null,
507                     Collections.<Handle> singletonList(handle),
508                     WriteFlags.none());
509             ReadMessageResult readMessageResult = handles.second.readMessage(null, 1,
510                     ReadFlags.none());
511             assertEquals(1, readMessageResult.getHandlesCount());
512             assertFalse(readMessageResult.getHandles().get(0).isValid());
513         } catch (MojoException e) {
514             assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
515         } finally {
516             handles.first.close();
517             handles.second.close();
518         }
519     }
520
521     private native void nativeInitApplicationContext(Context context);
522 }