< prev index next >

test/jdk/java/foreign/TestNulls.java

Print this page

 43 import java.lang.invoke.MethodType;
 44 import java.lang.invoke.VarHandle;
 45 import java.lang.ref.Cleaner;
 46 import java.lang.reflect.Array;
 47 import java.lang.reflect.InvocationTargetException;
 48 import java.lang.reflect.Method;
 49 import java.lang.reflect.Modifier;
 50 import java.nio.ByteBuffer;
 51 import java.nio.ByteOrder;
 52 import java.nio.channels.FileChannel;
 53 import java.nio.charset.Charset;
 54 import java.nio.file.Path;
 55 import java.util.*;
 56 import java.util.concurrent.atomic.AtomicReference;
 57 import java.util.function.Consumer;
 58 import java.util.function.Supplier;
 59 import java.util.function.UnaryOperator;
 60 import java.util.stream.Collectors;
 61 import java.util.stream.Stream;
 62 


 63 import static org.testng.Assert.*;
 64 import static org.testng.Assert.fail;
 65 
 66 /**
 67  * This test makes sure that public API classes (listed in {@link TestNulls#CLASSES}) throws NPEs whenever
 68  * nulls are provided. The test looks at all the public methods in all the listed classes, and injects
 69  * values automatically. If an API takes a reference, the test will try to inject nulls. For APIs taking
 70  * either reference arrays, or collections, the framework will also generate additional <em>replacements</em>
 71  * (e.g. other than just replacing the array, or collection with null), such as an array or collection
 72  * with null elements. The test can be customized by adding/removing classes to the {@link #CLASSES} array,
 73  * by adding/removing default mappings for standard carrier types (see {@link #DEFAULT_VALUES} or by
 74  * adding/removing custom replacements (see {@link #REPLACEMENT_VALUES}).
 75  */
 76 public class TestNulls {
 77 
 78     static final Class<?>[] CLASSES = new Class<?>[] {
 79             MemorySegment.class,
 80             MemoryAddress.class,
 81             MemoryLayout.class,
 82             MemoryLayout.PathElement.class,
 83             SequenceLayout.class,
 84             ValueLayout.class,









 85             GroupLayout.class,
 86             Addressable.class,
 87             SymbolLookup.class,
 88             MemoryAccess.class,
 89             MemoryLayouts.class,
 90             MemoryHandles.class,
 91             CLinker.class,
 92             CLinker.VaList.class,
 93             CLinker.VaList.Builder.class,
 94             FunctionDescriptor.class,
 95             SegmentAllocator.class,
 96             ResourceScope.class

 97     };
 98 
 99     static final Set<String> EXCLUDE_LIST = Set.of(


100             "jdk.incubator.foreign.MemoryLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
101             "jdk.incubator.foreign.MemoryAddress/asSegment(long,java.lang.Runnable,java.lang.Object)/1/0",
102             "jdk.incubator.foreign.MemoryAddress/asSegment(long,java.lang.Runnable,java.lang.Object)/2/0",
103             "jdk.incubator.foreign.MemoryAddress/asSegment(long,java.lang.Runnable,jdk.incubator.foreign.ResourceScope)/1/0",
104             "jdk.incubator.foreign.SequenceLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
105             "jdk.incubator.foreign.ValueLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",









106             "jdk.incubator.foreign.GroupLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
107             "jdk.incubator.foreign.MemoryHandles/insertCoordinates(java.lang.invoke.VarHandle,int,java.lang.Object[])/2/1",
108             "jdk.incubator.foreign.FunctionDescriptor/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0"
109     );
110 
111     static final Set<String> OBJECT_METHODS = Stream.of(Object.class.getMethods())
112             .map(Method::getName)
113             .collect(Collectors.toSet());
114 
115     static final Map<Class<?>, Object> DEFAULT_VALUES = new HashMap<>();
116 
117     static <Z> void addDefaultMapping(Class<Z> carrier, Z value) {
118         DEFAULT_VALUES.put(carrier, value);
119     }
120 
121     static {
122         addDefaultMapping(char.class, (char)0);
123         addDefaultMapping(byte.class, (byte)0);
124         addDefaultMapping(short.class, (short)0);
125         addDefaultMapping(int.class, 0);
126         addDefaultMapping(float.class, 0f);
127         addDefaultMapping(long.class, 0L);
128         addDefaultMapping(double.class, 0d);
129         addDefaultMapping(boolean.class, true);
130         addDefaultMapping(ByteOrder.class, ByteOrder.nativeOrder());
131         addDefaultMapping(Thread.class, Thread.currentThread());
132         addDefaultMapping(Cleaner.class, CleanerFactory.cleaner());
133         addDefaultMapping(ByteBuffer.class, ByteBuffer.wrap(new byte[10]));
134         addDefaultMapping(Path.class, Path.of("nonExistent"));
135         addDefaultMapping(FileChannel.MapMode.class, FileChannel.MapMode.PRIVATE);
136         addDefaultMapping(UnaryOperator.class, UnaryOperator.identity());
137         addDefaultMapping(String.class, "Hello!");
138         addDefaultMapping(Constable.class, "Hello!");
139         addDefaultMapping(Class.class, String.class);
140         addDefaultMapping(Runnable.class, () -> {});
141         addDefaultMapping(Object.class, new Object());
142         addDefaultMapping(VarHandle.class, MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()));
143         addDefaultMapping(MethodHandle.class, MethodHandles.identity(int.class));
144         addDefaultMapping(List.class, List.of());
145         addDefaultMapping(Charset.class, Charset.defaultCharset());
146         addDefaultMapping(Consumer.class, x -> {});
147         addDefaultMapping(MethodType.class, MethodType.methodType(void.class));
148         addDefaultMapping(MemoryAddress.class, MemoryAddress.ofLong(1));
149         addDefaultMapping(Addressable.class, MemoryAddress.ofLong(1));
150         addDefaultMapping(MemoryLayout.class, MemoryLayouts.JAVA_INT);
151         addDefaultMapping(ValueLayout.class, MemoryLayouts.JAVA_INT);
152         addDefaultMapping(GroupLayout.class, MemoryLayout.structLayout(MemoryLayouts.JAVA_INT));
153         addDefaultMapping(SequenceLayout.class, MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT));









154         addDefaultMapping(MemorySegment.class, MemorySegment.ofArray(new byte[10]));
155         addDefaultMapping(FunctionDescriptor.class, FunctionDescriptor.ofVoid());
156         addDefaultMapping(CLinker.class, CLinker.getInstance());
157         addDefaultMapping(CLinker.VaList.class, VaListHelper.vaList);
158         addDefaultMapping(CLinker.VaList.Builder.class, VaListHelper.vaListBuilder);
159         addDefaultMapping(ResourceScope.class, ResourceScope.newImplicitScope());
160         addDefaultMapping(SegmentAllocator.class, (size, align) -> null);
161         addDefaultMapping(Supplier.class, () -> null);
162         addDefaultMapping(ResourceScope.Handle.class, ResourceScope.globalScope().acquire());
163         addDefaultMapping(ClassLoader.class, TestNulls.class.getClassLoader());
164         addDefaultMapping(SymbolLookup.class, CLinker.systemLookup());

165     }
166 
167     static class VaListHelper {
168         static final CLinker.VaList vaList;
169         static final CLinker.VaList.Builder vaListBuilder;
170 
171         static {
172             AtomicReference<CLinker.VaList.Builder> builderRef = new AtomicReference<>();
173             vaList = CLinker.VaList.make(b -> {
174                 builderRef.set(b);
175                 b.vargFromLong(CLinker.C_LONG_LONG, 42L);
176             }, ResourceScope.newImplicitScope());
177             vaListBuilder = builderRef.get();
178         }
179     }
180 
181     static final Map<Class<?>, Object[]> REPLACEMENT_VALUES = new HashMap<>();
182 
183     @SafeVarargs
184     static <Z> void addReplacements(Class<Z> carrier, Z... value) {
185         REPLACEMENT_VALUES.put(carrier, value);
186     }
187 
188     static {
189         addReplacements(Collection.class, null, Stream.of(new Object[] { null }).collect(Collectors.toList()));
190         addReplacements(List.class, null, Stream.of(new Object[] { null }).collect(Collectors.toList()));
191         addReplacements(Set.class, null, Stream.of(new Object[] { null }).collect(Collectors.toSet()));
192     }
193 
194     @Test(dataProvider = "cases")
195     public void testNulls(String testName, @NoInjection Method meth, Object receiver, Object[] args) {

 43 import java.lang.invoke.MethodType;
 44 import java.lang.invoke.VarHandle;
 45 import java.lang.ref.Cleaner;
 46 import java.lang.reflect.Array;
 47 import java.lang.reflect.InvocationTargetException;
 48 import java.lang.reflect.Method;
 49 import java.lang.reflect.Modifier;
 50 import java.nio.ByteBuffer;
 51 import java.nio.ByteOrder;
 52 import java.nio.channels.FileChannel;
 53 import java.nio.charset.Charset;
 54 import java.nio.file.Path;
 55 import java.util.*;
 56 import java.util.concurrent.atomic.AtomicReference;
 57 import java.util.function.Consumer;
 58 import java.util.function.Supplier;
 59 import java.util.function.UnaryOperator;
 60 import java.util.stream.Collectors;
 61 import java.util.stream.Stream;
 62 
 63 import static jdk.incubator.foreign.ValueLayout.JAVA_INT;
 64 import static jdk.incubator.foreign.ValueLayout.JAVA_LONG;
 65 import static org.testng.Assert.*;
 66 import static org.testng.Assert.fail;
 67 
 68 /**
 69  * This test makes sure that public API classes (listed in {@link TestNulls#CLASSES}) throws NPEs whenever
 70  * nulls are provided. The test looks at all the public methods in all the listed classes, and injects
 71  * values automatically. If an API takes a reference, the test will try to inject nulls. For APIs taking
 72  * either reference arrays, or collections, the framework will also generate additional <em>replacements</em>
 73  * (e.g. other than just replacing the array, or collection with null), such as an array or collection
 74  * with null elements. The test can be customized by adding/removing classes to the {@link #CLASSES} array,
 75  * by adding/removing default mappings for standard carrier types (see {@link #DEFAULT_VALUES} or by
 76  * adding/removing custom replacements (see {@link #REPLACEMENT_VALUES}).
 77  */
 78 public class TestNulls {
 79 
 80     static final Class<?>[] CLASSES = new Class<?>[] {
 81             MemorySegment.class,
 82             MemoryAddress.class,
 83             MemoryLayout.class,
 84             MemoryLayout.PathElement.class,
 85             SequenceLayout.class,
 86             ValueLayout.class,
 87             ValueLayout.OfBoolean.class,
 88             ValueLayout.OfByte.class,
 89             ValueLayout.OfChar.class,
 90             ValueLayout.OfShort.class,
 91             ValueLayout.OfInt.class,
 92             ValueLayout.OfFloat.class,
 93             ValueLayout.OfLong.class,
 94             ValueLayout.OfDouble.class,
 95             ValueLayout.OfAddress.class,
 96             GroupLayout.class,
 97             Addressable.class,
 98             SymbolLookup.class,


 99             MemoryHandles.class,
100             CLinker.class,
101             VaList.class,
102             VaList.Builder.class,
103             FunctionDescriptor.class,
104             SegmentAllocator.class,
105             ResourceScope.class,
106             NativeSymbol.class
107     };
108 
109     static final Set<String> EXCLUDE_LIST = Set.of(
110             "jdk.incubator.foreign.ResourceScope/newConfinedScope(java.lang.ref.Cleaner)/0/0",
111             "jdk.incubator.foreign.ResourceScope/newSharedScope(java.lang.ref.Cleaner)/0/0",
112             "jdk.incubator.foreign.MemoryLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",



113             "jdk.incubator.foreign.SequenceLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
114             "jdk.incubator.foreign.ValueLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
115             "jdk.incubator.foreign.ValueLayout$OfAddress/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
116             "jdk.incubator.foreign.ValueLayout$OfBoolean/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
117             "jdk.incubator.foreign.ValueLayout$OfByte/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
118             "jdk.incubator.foreign.ValueLayout$OfChar/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
119             "jdk.incubator.foreign.ValueLayout$OfShort/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
120             "jdk.incubator.foreign.ValueLayout$OfInt/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
121             "jdk.incubator.foreign.ValueLayout$OfFloat/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
122             "jdk.incubator.foreign.ValueLayout$OfLong/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
123             "jdk.incubator.foreign.ValueLayout$OfDouble/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
124             "jdk.incubator.foreign.GroupLayout/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0",
125             "jdk.incubator.foreign.MemoryHandles/insertCoordinates(java.lang.invoke.VarHandle,int,java.lang.Object[])/2/1",
126             "jdk.incubator.foreign.FunctionDescriptor/withAttribute(java.lang.String,java.lang.constant.Constable)/1/0"
127     );
128 
129     static final Set<String> OBJECT_METHODS = Stream.of(Object.class.getMethods())
130             .map(Method::getName)
131             .collect(Collectors.toSet());
132 
133     static final Map<Class<?>, Object> DEFAULT_VALUES = new HashMap<>();
134 
135     static <Z> void addDefaultMapping(Class<Z> carrier, Z value) {
136         DEFAULT_VALUES.put(carrier, value);
137     }
138 
139     static {
140         addDefaultMapping(char.class, (char)0);
141         addDefaultMapping(byte.class, (byte)0);
142         addDefaultMapping(short.class, (short)0);
143         addDefaultMapping(int.class, 0);
144         addDefaultMapping(float.class, 0f);
145         addDefaultMapping(long.class, 0L);
146         addDefaultMapping(double.class, 0d);
147         addDefaultMapping(boolean.class, true);
148         addDefaultMapping(ByteOrder.class, ByteOrder.nativeOrder());
149         addDefaultMapping(Thread.class, Thread.currentThread());
150         addDefaultMapping(Cleaner.class, CleanerFactory.cleaner());
151         addDefaultMapping(ByteBuffer.class, ByteBuffer.wrap(new byte[10]));
152         addDefaultMapping(Path.class, Path.of("nonExistent"));
153         addDefaultMapping(FileChannel.MapMode.class, FileChannel.MapMode.PRIVATE);
154         addDefaultMapping(UnaryOperator.class, UnaryOperator.identity());
155         addDefaultMapping(String.class, "Hello!");
156         addDefaultMapping(Constable.class, "Hello!");
157         addDefaultMapping(Class.class, String.class);
158         addDefaultMapping(Runnable.class, () -> {});
159         addDefaultMapping(Object.class, new Object());
160         addDefaultMapping(VarHandle.class, MemoryHandles.varHandle(JAVA_INT));
161         addDefaultMapping(MethodHandle.class, MethodHandles.identity(int.class));
162         addDefaultMapping(List.class, List.of());
163         addDefaultMapping(Charset.class, Charset.defaultCharset());
164         addDefaultMapping(Consumer.class, x -> {});
165         addDefaultMapping(MethodType.class, MethodType.methodType(void.class));
166         addDefaultMapping(MemoryAddress.class, MemoryAddress.ofLong(1));
167         addDefaultMapping(Addressable.class, MemoryAddress.ofLong(1));
168         addDefaultMapping(MemoryLayout.class, ValueLayout.JAVA_INT);
169         addDefaultMapping(ValueLayout.class, ValueLayout.JAVA_INT);
170         addDefaultMapping(ValueLayout.OfAddress.class, ValueLayout.ADDRESS);
171         addDefaultMapping(ValueLayout.OfByte.class, ValueLayout.JAVA_BYTE);
172         addDefaultMapping(ValueLayout.OfBoolean.class, ValueLayout.JAVA_BOOLEAN);
173         addDefaultMapping(ValueLayout.OfChar.class, ValueLayout.JAVA_CHAR);
174         addDefaultMapping(ValueLayout.OfShort.class, ValueLayout.JAVA_SHORT);
175         addDefaultMapping(ValueLayout.OfInt.class, ValueLayout.JAVA_INT);
176         addDefaultMapping(ValueLayout.OfFloat.class, ValueLayout.JAVA_FLOAT);
177         addDefaultMapping(ValueLayout.OfLong.class, JAVA_LONG);
178         addDefaultMapping(ValueLayout.OfDouble.class, ValueLayout.JAVA_DOUBLE);
179         addDefaultMapping(GroupLayout.class, MemoryLayout.structLayout(ValueLayout.JAVA_INT));
180         addDefaultMapping(SequenceLayout.class, MemoryLayout.sequenceLayout(ValueLayout.JAVA_INT));
181         addDefaultMapping(MemorySegment.class, MemorySegment.ofArray(new byte[10]));
182         addDefaultMapping(FunctionDescriptor.class, FunctionDescriptor.ofVoid());
183         addDefaultMapping(CLinker.class, CLinker.systemCLinker());
184         addDefaultMapping(VaList.class, VaListHelper.vaList);
185         addDefaultMapping(VaList.Builder.class, VaListHelper.vaListBuilder);
186         addDefaultMapping(ResourceScope.class, ResourceScope.newSharedScope());
187         addDefaultMapping(SegmentAllocator.class, SegmentAllocator.prefixAllocator(MemorySegment.ofArray(new byte[10])));
188         addDefaultMapping(Supplier.class, () -> null);

189         addDefaultMapping(ClassLoader.class, TestNulls.class.getClassLoader());
190         addDefaultMapping(SymbolLookup.class, CLinker.systemCLinker());
191         addDefaultMapping(NativeSymbol.class, NativeSymbol.ofAddress("dummy", MemoryAddress.ofLong(1), ResourceScope.globalScope()));
192     }
193 
194     static class VaListHelper {
195         static final VaList vaList;
196         static final VaList.Builder vaListBuilder;
197 
198         static {
199             AtomicReference<VaList.Builder> builderRef = new AtomicReference<>();
200             vaList = VaList.make(b -> {
201                 builderRef.set(b);
202                 b.addVarg(JAVA_LONG, 42L);
203             }, ResourceScope.newImplicitScope());
204             vaListBuilder = builderRef.get();
205         }
206     }
207 
208     static final Map<Class<?>, Object[]> REPLACEMENT_VALUES = new HashMap<>();
209 
210     @SafeVarargs
211     static <Z> void addReplacements(Class<Z> carrier, Z... value) {
212         REPLACEMENT_VALUES.put(carrier, value);
213     }
214 
215     static {
216         addReplacements(Collection.class, null, Stream.of(new Object[] { null }).collect(Collectors.toList()));
217         addReplacements(List.class, null, Stream.of(new Object[] { null }).collect(Collectors.toList()));
218         addReplacements(Set.class, null, Stream.of(new Object[] { null }).collect(Collectors.toSet()));
219     }
220 
221     @Test(dataProvider = "cases")
222     public void testNulls(String testName, @NoInjection Method meth, Object receiver, Object[] args) {
< prev index next >