1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.art.libnativehelper;
18 
19 import android.test.AndroidTestCase;
20 
21 import java.io.FileDescriptor;
22 import java.io.IOException;
23 import java.lang.ref.Reference;
24 import java.lang.ref.SoftReference;
25 import java.nio.Buffer;
26 import java.nio.ByteBuffer;
27 import java.nio.ShortBuffer;
28 import java.nio.IntBuffer;
29 import java.nio.FloatBuffer;
30 import java.nio.DoubleBuffer;
31 
32 import android.system.ErrnoException;
33 
34 import org.junit.Assert;
35 
36 public class JniHelpTest extends AndroidTestCase {
throwException(String className, String message)37     private static native void throwException(String className, String message);
throwExceptionWithIntFormat(String className, String format, int value)38     private static native void throwExceptionWithIntFormat(String className,
39                                                            String format,
40                                                            int value);
throwNullPointerException(String message)41     private static native void throwNullPointerException(String message);
throwRuntimeException(String message)42     private static native void throwRuntimeException(String message);
throwIOException(int cause)43     private static native void throwIOException(int cause) throws IOException;
throwErrnoException(String fileName, int cause)44     private static native void throwErrnoException(String fileName, int cause) throws ErrnoException;
logException(Throwable throwable)45     private static native void logException(Throwable throwable);
46 
fileDescriptorCreate(int unixFd)47     private static native FileDescriptor fileDescriptorCreate(int unixFd);
fileDescriptorGetFD(FileDescriptor jiofd)48     private static native int fileDescriptorGetFD(FileDescriptor jiofd);
fileDescriptorSetFD(FileDescriptor jiofd, int unixFd)49     private static native void fileDescriptorSetFD(FileDescriptor jiofd, int unixFd);
50 
createString(String input)51     private static native String createString(String input);
52 
testThrowException()53     public void testThrowException() {
54         final String message = "Because test";
55         try {
56             throwException("java/lang/RuntimeException", message);
57             fail("Unreachable");
58         } catch (RuntimeException e) {
59             assertEquals(message, e.getMessage());
60         }
61     }
62 
testThrowExceptionWithIntFormat()63     public void testThrowExceptionWithIntFormat() {
64         final String format = "Because test %d";
65         try {
66             throwExceptionWithIntFormat("java/lang/RuntimeException", format, 101);
67             fail("Unreachable");
68         } catch (RuntimeException e) {
69             assertEquals("Because test 101", e.getMessage());
70         }
71     }
72 
testThrowNullPointerException()73     public void testThrowNullPointerException() {
74         final String message = "Because another test";
75         try {
76             throwNullPointerException(message);
77             fail("Unreachable");
78         } catch (NullPointerException e) {
79             assertEquals(message, e.getMessage());
80         }
81     }
82 
testThrowRuntimeException()83     public void testThrowRuntimeException() {
84         final String message = "Because test again";
85         try {
86             throwRuntimeException(message);
87             fail("Unreachable");
88         } catch (RuntimeException e) {
89             assertEquals(message, e.getMessage());
90         }
91     }
92 
testIOException()93     public void testIOException() {
94         String s1 = null;
95         try {
96             throwIOException(70);
97             fail("Unreachable");
98         } catch (IOException e) {
99             s1 = e.getMessage();
100         }
101         assertNotNull(s1);
102 
103         String s2 = null;
104         try {
105             throwIOException(71);
106             fail("Unreachable");
107         } catch (IOException e) {
108             s2 = e.getMessage();
109         }
110         assertNotNull(s2);
111 
112         assertFalse(s1.equals(s2));
113     }
114 
testErrnoException()115     public void testErrnoException() {
116         final String functionName = "execve";
117         final int err = 42;
118         try {
119             throwErrnoException(functionName, err);
120             fail("Unreachable");
121         } catch (ErrnoException e) {
122             // The message contains the function name as well as the string for the errno, just only
123             // check the first part of the message
124             assertTrue("Function name", e.getMessage().startsWith(functionName));
125             assertEquals(err, e.errno);
126         }
127     }
128 
testLogException()129     public void testLogException() {
130         try {
131             throw new RuntimeException("Exception for logging test");
132         } catch (RuntimeException e) {
133             // TODO: Mock/redirect logcat to test output is logged appropriately.
134             // Or add extend JNIHelp API to write to a buffer or file.
135             logException(e);
136         }
137     }
138 
testFileDescriptorCreate()139     public void testFileDescriptorCreate() {
140         int [] unix_fds = { -999, -1, 0, 1, 1000 };
141         for (int unix_fd : unix_fds) {
142             FileDescriptor f0 = fileDescriptorCreate(unix_fd);
143             assertNotNull(f0);
144             assertSame(f0.getClass(), FileDescriptor.class);
145         }
146     }
147 
testFileDescriptorGetNull()148     public void testFileDescriptorGetNull() {
149         assertEquals(-1, fileDescriptorGetFD(null));
150     }
151 
testFileDescriptorGetNonNull()152     public void testFileDescriptorGetNonNull() {
153         final int UNIX_FD = 77;
154         FileDescriptor jiofd = fileDescriptorCreate(UNIX_FD);
155         assertEquals(UNIX_FD, fileDescriptorGetFD(jiofd));
156     }
157 
testFileDescriptorSetNull()158     public void testFileDescriptorSetNull() {
159         try {
160             fileDescriptorSetFD(null, 1);
161             fail("Expected NullPointerException to be thrown.");
162         } catch (NullPointerException e) {}
163     }
164 
testFileDescriptorSetNonNull()165     public void testFileDescriptorSetNonNull() {
166         final int UNIX_FD = 127;
167         FileDescriptor jiofd = fileDescriptorCreate(0);
168         fileDescriptorSetFD(jiofd, UNIX_FD);
169         assertEquals(UNIX_FD, fileDescriptorGetFD(jiofd));
170     }
171 
testCreateString()172     public void testCreateString() {
173         String input = "The treacherous mountain path lay ahead.";
174         String output = createString(input);
175         assertEquals(input, output);
176         assertNotSame(input, output);
177     }
178 }
179