Skip to content

Commit 946325a

Browse files
authored
add UT for foreign memory api (#17107)
1 parent d92d114 commit 946325a

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package com.baeldung.foreign.api;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.lang.foreign.Arena;
6+
import java.lang.foreign.FunctionDescriptor;
7+
import java.lang.foreign.Linker;
8+
import java.lang.foreign.MemoryLayout;
9+
import java.lang.foreign.MemorySegment;
10+
import java.lang.foreign.SequenceLayout;
11+
import java.lang.foreign.ValueLayout;
12+
import java.lang.invoke.MethodHandle;
13+
import java.lang.invoke.VarHandle;
14+
import java.nio.ByteBuffer;
15+
16+
import static org.junit.jupiter.api.Assertions.*;
17+
18+
public class ForeignMemoryUnitTest {
19+
20+
@Test
21+
void whenGlobalArenaClosed_thenThrowsException() {
22+
Arena global = Arena.global();
23+
24+
assertThrowsExactly(UnsupportedOperationException.class, () -> global.close());
25+
}
26+
27+
@Test
28+
void whenSharedArenaCreated_thenAccessByMultipleThreads() {
29+
Arena sharedArena = Arena.ofShared();
30+
31+
new Thread(() -> {
32+
sharedArena.allocate(20);
33+
});
34+
35+
new Thread(() -> {
36+
sharedArena.allocate(20);
37+
}).start();
38+
}
39+
40+
@Test
41+
void whenConfinedArenaCreated_thenAccessByOwnerThread() {
42+
Arena confiedArena = Arena.ofConfined();
43+
44+
new Thread(() -> {
45+
confiedArena.allocate(20);
46+
});
47+
48+
new Thread(() -> assertThrows(WrongThreadException.class, () -> confiedArena.allocate(10))).start();
49+
}
50+
51+
@Test
52+
void whenNativeMemorySegmentSet_thenAccessTheValue() {
53+
Arena arena = Arena.ofAuto();
54+
MemorySegment segment = arena.allocate(20);
55+
56+
ByteBuffer buffer = segment.asByteBuffer();
57+
58+
buffer.putInt(0, 42);
59+
int value = buffer.getInt(0);
60+
61+
assertEquals(42, value);
62+
}
63+
64+
@Test
65+
void whenArraySegmentSet_thenAccessTheValue() {
66+
MemorySegment segment = MemorySegment.ofArray(new int[20]);
67+
68+
segment.set(ValueLayout.JAVA_INT, 0, 42);
69+
int value = segment.get(ValueLayout.JAVA_INT, 0);
70+
71+
assertEquals(42, value);
72+
}
73+
74+
@Test
75+
void whenByteBufferMemorySegmentSet_thenAccessTheValue() {
76+
MemorySegment segment = MemorySegment.ofBuffer(ByteBuffer.allocate(20));
77+
78+
segment.set(ValueLayout.JAVA_BOOLEAN, 0, true);
79+
boolean value = segment.get(ValueLayout.JAVA_BOOLEAN, 0);
80+
81+
assertTrue(value);
82+
}
83+
84+
@Test
85+
void whenSlicingMemorySegmentAndSet_thenAccessTheValue() {
86+
Arena arena = Arena.ofAuto();
87+
MemorySegment memorySegment;
88+
memorySegment = arena.allocate(20);
89+
90+
MemorySegment segment1 = memorySegment.asSlice(0, 4);
91+
MemorySegment segment2 = memorySegment.asSlice(4, 4);
92+
MemorySegment segment3 = memorySegment.asSlice(8, 4);
93+
94+
VarHandle intHandle = ValueLayout.JAVA_INT.varHandle();
95+
96+
intHandle.set(segment1, 0, Integer.MIN_VALUE);
97+
intHandle.set(segment2, 0, 0);
98+
intHandle.set(segment3, 0, Integer.MAX_VALUE);
99+
100+
assertEquals(intHandle.get(segment1, 0), Integer.MIN_VALUE);
101+
assertEquals(intHandle.get(segment2, 0), 0);
102+
assertEquals(intHandle.get(segment3, 0), Integer.MAX_VALUE);
103+
}
104+
105+
@Test
106+
void whenCreatingMemoryLayout_thenNotNull() {
107+
int numberOfPoints = 10;
108+
MemoryLayout pointLayout = MemoryLayout.structLayout(ValueLayout.JAVA_INT.withName("x"),
109+
ValueLayout.JAVA_INT.withName("y"));
110+
SequenceLayout pointsLayout = MemoryLayout.sequenceLayout(numberOfPoints, pointLayout);
111+
112+
assertNotNull(pointsLayout);
113+
}
114+
115+
@Test
116+
void whenValueLayoutCreated_thenCheckSize() {
117+
ValueLayout intLayout = ValueLayout.JAVA_INT;
118+
ValueLayout charLayout = ValueLayout.JAVA_CHAR;
119+
120+
assertEquals(intLayout.byteSize(), 4);
121+
assertEquals(charLayout.byteSize(), 2);
122+
}
123+
124+
@Test
125+
void whenSequenceLayoutCreated_thenCheckElementCount() {
126+
SequenceLayout sequenceLayout = MemoryLayout.sequenceLayout(10, ValueLayout.JAVA_INT);
127+
128+
assertEquals(10, sequenceLayout.elementCount());
129+
}
130+
131+
@Test
132+
void whenGroupLayoutCreated_thenCheckNotNull() {
133+
MemoryLayout memoryLayout1 = ValueLayout.JAVA_INT;
134+
MemoryLayout memoryLayout2 = MemoryLayout.structLayout(ValueLayout.JAVA_LONG);
135+
MemoryLayout complexLayout = MemoryLayout.structLayout(memoryLayout1, MemoryLayout.paddingLayout(4), memoryLayout2);
136+
137+
assertNotNull(complexLayout);
138+
}
139+
140+
@Test
141+
void whenVarHandleCreatedAndSet_thenAccessTheValue() {
142+
int value = 10;
143+
MemoryLayout pointLayout = MemoryLayout.structLayout(ValueLayout.JAVA_INT.withName("x"),
144+
ValueLayout.JAVA_INT.withName("y"));
145+
VarHandle xHandle = pointLayout.varHandle(MemoryLayout.PathElement.groupElement("x"));
146+
147+
Arena arena = Arena.ofAuto();
148+
MemorySegment segment = arena.allocate(pointLayout);
149+
150+
xHandle.set(segment, 0, (int) value);
151+
int xValue = (int) xHandle.get(segment, 0);
152+
153+
assertEquals(xValue, value);
154+
}
155+
156+
@Test
157+
void whenVarHandleCreatedAndSet_thenAccessAll() {
158+
int numberOfPoints = 10;
159+
MemoryLayout pointLayout = MemoryLayout.structLayout(ValueLayout.JAVA_INT.withName("x"),
160+
ValueLayout.JAVA_INT.withName("y"));
161+
162+
SequenceLayout pointsLayout = MemoryLayout.sequenceLayout(numberOfPoints, pointLayout);
163+
VarHandle xHandle = pointsLayout.varHandle(MemoryLayout.PathElement.sequenceElement(),
164+
MemoryLayout.PathElement.groupElement("x"));
165+
166+
Arena arena = Arena.ofAuto();
167+
MemorySegment segment = arena.allocate(pointsLayout);
168+
169+
for (int i = 0; i < numberOfPoints; i++) {
170+
xHandle.set(segment, 0, i, i);
171+
}
172+
173+
for (int i = 0; i < numberOfPoints; i++) {
174+
assertEquals(i, xHandle.get(segment, 0, i));
175+
}
176+
}
177+
178+
@Test
179+
void whenInvokeNativeFunction_thenCheckEqual() throws Throwable {
180+
Linker linker = Linker.nativeLinker();
181+
var symbol = linker.defaultLookup().find("strlen").orElseThrow();
182+
MethodHandle strlen = linker.downcallHandle(symbol, FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
183+
184+
Arena arena = Arena.ofAuto();
185+
MemorySegment str = arena.allocateFrom("Hello");
186+
187+
long len = (long) strlen.invoke(str);
188+
assertEquals(5, len);
189+
}
190+
191+
}

0 commit comments

Comments
 (0)