Skip to content

Commit 66f1d65

Browse files
committed
Add e2e tests.
1 parent 0dc609b commit 66f1d65

File tree

6 files changed

+787
-1
lines changed

6 files changed

+787
-1
lines changed

implementation/array_view.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ class ArrayView {
122122
Iterator begin() { return Iterator{ptr(), size_, 0}; }
123123
Iterator end() { return Iterator{ptr(), size_, size_}; }
124124

125-
protected:
125+
public:
126+
// These members are protected for access by tests
126127
const jarray array_;
127128
const GetArrayElementsResult<SpanType> get_array_elements_result_;
128129
const bool copy_on_completion_;
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2024 Google LLC
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.jnibind.test;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertFalse;
21+
import static org.junit.Assert.assertTrue;
22+
23+
import org.junit.AfterClass;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
import org.junit.runners.JUnit4;
27+
28+
/** Tests for direct vs. indirect array access. */
29+
@RunWith(JUnit4.class)
30+
public class ArrayTestCritical {
31+
static {
32+
System.load(
33+
System.getenv("JAVA_RUNFILES")
34+
+ "/_main/javatests/com/jnibind/test/libarray_test_critical_jni.so");
35+
}
36+
37+
@AfterClass
38+
public static void doShutDown() {
39+
jniTearDown();
40+
}
41+
42+
static native void jniTearDown();
43+
44+
// Regular array API tests
45+
native boolean nativeRegularArrayTest(int[] intArray);
46+
native boolean nativeRegularArraySetTest(int[] intArray);
47+
48+
// Critical array API tests
49+
native boolean nativeCriticalArrayTest(int[] intArray);
50+
native boolean nativeCriticalArraySetTest(int[] intArray);
51+
52+
// Performance comparison tests
53+
native long nativeRegularArrayPerformanceTest(int[] intArray, int iterations);
54+
native long nativeCriticalArrayPerformanceTest(int[] intArray, int iterations);
55+
56+
// Direct access verification (is the array direct or pinned)
57+
native boolean nativeIsArrayDirectTest(int[] intArray);
58+
59+
@Test
60+
public void testRegularArrayAccess() {
61+
int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
62+
assertTrue(nativeRegularArrayTest(arr));
63+
}
64+
65+
@Test
66+
public void testRegularArraySet() {
67+
int[] arr = new int[10];
68+
boolean success = nativeRegularArraySetTest(arr);
69+
assertTrue(success);
70+
71+
for (int i = 0; i < arr.length; i++) {
72+
assertEquals(i * 2, arr[i]);
73+
}
74+
}
75+
76+
@Test
77+
public void testCriticalArrayAccess() {
78+
int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
79+
assertTrue(nativeCriticalArrayTest(arr));
80+
}
81+
82+
@Test
83+
public void testCriticalArraySet() {
84+
int[] arr = new int[10];
85+
boolean success = nativeCriticalArraySetTest(arr);
86+
assertTrue(success);
87+
88+
for (int i = 0; i < arr.length; i++) {
89+
assertEquals(i * 3, arr[i]);
90+
}
91+
}
92+
93+
@Test
94+
public void testArrayPerformance() {
95+
// Create a larger array for performance testing
96+
int[] arr = new int[10000];
97+
for (int i = 0; i < arr.length; i++) {
98+
arr[i] = i;
99+
}
100+
101+
int iterations = 100;
102+
103+
// Run both tests
104+
long regularTime = nativeRegularArrayPerformanceTest(arr, iterations);
105+
long criticalTime = nativeCriticalArrayPerformanceTest(arr, iterations);
106+
107+
// Print the results to the test log
108+
System.out.println("Regular array access time: " + regularTime + "ns");
109+
System.out.println("Critical array access time: " + criticalTime + "ns");
110+
111+
// We're not making assertions about which is faster, as it depends
112+
// on JVM implementation and hardware
113+
}
114+
115+
@Test
116+
public void testIsArrayDirect() {
117+
int[] arr = new int[10];
118+
119+
// We can't make assertions about whether the array is direct or not,
120+
// as it's JVM implementation dependent, but we can run the test to see
121+
// what the current JVM returns
122+
boolean isDirect = nativeIsArrayDirectTest(arr);
123+
System.out.println("Array is direct: " + isDirect);
124+
}
125+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright 2024 Google LLC
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.jnibind.test;
18+
19+
import static org.junit.Assert.assertArrayEquals;
20+
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertTrue;
22+
23+
import java.util.Arrays;
24+
import org.junit.AfterClass;
25+
import org.junit.Test;
26+
import org.junit.runner.RunWith;
27+
import org.junit.runners.JUnit4;
28+
29+
/** Tests for direct/indirect array access with multiple array types. */
30+
@RunWith(JUnit4.class)
31+
public class ArrayTestMultitype {
32+
static {
33+
System.load(
34+
System.getenv("JAVA_RUNFILES")
35+
+ "/_main/javatests/com/jnibind/test/libarray_test_multitype_jni.so");
36+
}
37+
38+
@AfterClass
39+
public static void doShutDown() {
40+
jniTearDown();
41+
}
42+
43+
static native void jniTearDown();
44+
45+
// Byte array tests
46+
native byte[] nativeProcessByteArrayRegular(byte[] array);
47+
native byte[] nativeProcessByteArrayCritical(byte[] array);
48+
49+
// Float array tests
50+
native float[] nativeProcessFloatArrayRegular(float[] array);
51+
native float[] nativeProcessFloatArrayCritical(float[] array);
52+
53+
// The copy flag tests to check if changes are copied back
54+
native void nativeModifyArrayWithCopyFlagTrue(int[] array);
55+
native void nativeModifyArrayWithCopyFlagFalse(int[] array);
56+
57+
// Matrix processing to test multi-dimensional arrays
58+
native void nativeProcessMatrixRegular(float[][] matrix);
59+
native void nativeProcessMatrixWithCritical(float[][] matrix);
60+
61+
@Test
62+
public void testByteArrayProcessing() {
63+
byte[] inputArray = new byte[100];
64+
Arrays.fill(inputArray, (byte)5);
65+
66+
// Test regular API
67+
byte[] resultRegular = nativeProcessByteArrayRegular(inputArray);
68+
for (int i = 0; i < resultRegular.length; i++) {
69+
assertEquals((byte)(5 * 2), resultRegular[i]);
70+
}
71+
72+
// Test critical API
73+
byte[] resultCritical = nativeProcessByteArrayCritical(inputArray);
74+
for (int i = 0; i < resultCritical.length; i++) {
75+
assertEquals((byte)(5 * 3), resultCritical[i]);
76+
}
77+
}
78+
79+
@Test
80+
public void testFloatArrayProcessing() {
81+
float[] inputArray = new float[100];
82+
Arrays.fill(inputArray, 3.14f);
83+
84+
// Test regular API
85+
float[] resultRegular = nativeProcessFloatArrayRegular(inputArray);
86+
for (int i = 0; i < resultRegular.length; i++) {
87+
assertEquals(3.14f * 2.0f, resultRegular[i], 0.001f);
88+
}
89+
90+
// Test critical API
91+
float[] resultCritical = nativeProcessFloatArrayCritical(inputArray);
92+
for (int i = 0; i < resultCritical.length; i++) {
93+
assertEquals(3.14f * 3.0f, resultCritical[i], 0.001f);
94+
}
95+
}
96+
97+
@Test
98+
public void testCopyFlagBehavior() {
99+
int[] array1 = new int[10];
100+
int[] array2 = new int[10];
101+
102+
// This should modify the array and copy changes back
103+
nativeModifyArrayWithCopyFlagTrue(array1);
104+
105+
// This should modify the array but not copy changes back
106+
nativeModifyArrayWithCopyFlagFalse(array2);
107+
108+
// Check results
109+
for (int i = 0; i < array1.length; i++) {
110+
assertEquals(i * 10, array1[i]);
111+
}
112+
113+
// array2 should still have all zeros
114+
for (int i = 0; i < array2.length; i++) {
115+
assertEquals(0, array2[i]);
116+
}
117+
}
118+
119+
@Test
120+
public void testMatrixProcessing() {
121+
float[][] matrix = new float[5][5];
122+
123+
// Initialize matrix
124+
for (int i = 0; i < 5; i++) {
125+
for (int j = 0; j < 5; j++) {
126+
matrix[i][j] = i + j;
127+
}
128+
}
129+
130+
// Make a copy for the second test
131+
float[][] matrix2 = new float[5][5];
132+
for (int i = 0; i < 5; i++) {
133+
System.arraycopy(matrix[i], 0, matrix2[i], 0, 5);
134+
}
135+
136+
// Process using regular access
137+
nativeProcessMatrixRegular(matrix);
138+
139+
// Process using critical access where possible
140+
nativeProcessMatrixWithCritical(matrix2);
141+
142+
// Both matrices should be processed the same way
143+
for (int i = 0; i < 5; i++) {
144+
assertArrayEquals(matrix[i], matrix2[i], 0.001f);
145+
}
146+
}
147+
}

javatests/com/jnibind/test/BUILD

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,69 @@ java_test(
600600
"@maven//:org_mockito_mockito_core",
601601
],
602602
)
603+
604+
################################################################################
605+
# Array Test: Critical vs Regular Access
606+
################################################################################
607+
cc_library(
608+
name = "array_test_critical_jni_impl",
609+
testonly = True,
610+
srcs = ["array_test_critical_jni.cc"],
611+
defines = ["ENABLE_DEBUG_OUTPUT"],
612+
deps = [
613+
"//:jni_bind",
614+
],
615+
alwayslink = True,
616+
)
617+
618+
cc_binary(
619+
name = "libarray_test_critical_jni.so",
620+
testonly = True,
621+
linkshared = True,
622+
deps = [":array_test_critical_jni_impl"],
623+
)
624+
625+
java_test(
626+
name = "ArrayTestCritical",
627+
testonly = True,
628+
srcs = ["ArrayTestCritical.java"],
629+
data = [":libarray_test_critical_jni.so"],
630+
jvm_flags = ["-Djava.library.path=./javatests/com/jnibind/test"],
631+
tags = ["nosan"],
632+
deps = [
633+
"@maven//:junit_junit",
634+
],
635+
)
636+
637+
################################################################################
638+
# Array Test: Multiple Types with Direct/Indirect Access
639+
################################################################################
640+
cc_library(
641+
name = "array_test_multitype_jni_impl",
642+
testonly = True,
643+
srcs = ["array_test_multitype_jni.cc"],
644+
defines = ["ENABLE_DEBUG_OUTPUT"],
645+
deps = [
646+
"//:jni_bind",
647+
],
648+
alwayslink = True,
649+
)
650+
651+
cc_binary(
652+
name = "libarray_test_multitype_jni.so",
653+
testonly = True,
654+
linkshared = True,
655+
deps = [":array_test_multitype_jni_impl"],
656+
)
657+
658+
java_test(
659+
name = "ArrayTestMultitype",
660+
testonly = True,
661+
srcs = ["ArrayTestMultitype.java"],
662+
data = [":libarray_test_multitype_jni.so"],
663+
jvm_flags = ["-Djava.library.path=./javatests/com/jnibind/test"],
664+
tags = ["nosan"],
665+
deps = [
666+
"@maven//:junit_junit",
667+
],
668+
)

0 commit comments

Comments
 (0)