Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/shared/DefMethTest.java
41161 views
1
/*
2
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
package vm.runtime.defmeth.shared;
25
26
import java.lang.reflect.InvocationTargetException;
27
import java.lang.reflect.Method;
28
import java.lang.reflect.Modifier;
29
import java.lang.reflect.Parameter;
30
import java.util.*;
31
import java.util.regex.Pattern;
32
import nsk.share.TestFailure;
33
import nsk.share.log.Log;
34
import nsk.share.test.TestBase;
35
import vm.runtime.defmeth.AccessibilityFlagsTest;
36
import vm.runtime.defmeth.BasicTest;
37
import vm.runtime.defmeth.ConflictingDefaultsTest;
38
import vm.runtime.defmeth.DefaultVsAbstractTest;
39
import vm.runtime.defmeth.MethodResolutionTest;
40
import vm.runtime.defmeth.ObjectMethodOverridesTest;
41
import vm.runtime.defmeth.PrivateMethodsTest;
42
import vm.runtime.defmeth.StaticMethodsTest;
43
import vm.runtime.defmeth.SuperCallTest;
44
import vm.runtime.defmeth.shared.annotation.NotApplicableFor;
45
import vm.runtime.defmeth.shared.builder.TestBuilder;
46
import vm.runtime.defmeth.shared.builder.TestBuilderFactory;
47
import vm.share.options.Option;
48
import vm.share.options.OptionSupport;
49
import vm.share.options.Options;
50
import static java.lang.String.format;
51
import static jdk.internal.org.objectweb.asm.Opcodes.V17;
52
import static jdk.internal.org.objectweb.asm.Opcodes.V1_5;
53
54
import vm.runtime.defmeth.RedefineTest;
55
56
/**
57
* Parent class for all default method tests.
58
*
59
* Contains common settings and code to run individual tests.
60
*
61
* Provides command-line interface to run arbitrary subset of
62
* tests on default methods with some customizations.
63
*/
64
public abstract class DefMethTest extends TestBase {
65
/** Classes that contain tests on default methods */
66
static private final List<Class<? extends DefMethTest>> classes;
67
68
// the number of tests has failed
69
// note that if more than one sub-test has failed within a test,
70
// it will be counted as 1 failure for that test
71
private int numFailures;
72
73
static {
74
List<Class<? extends DefMethTest>> intlList = new ArrayList<>();
75
76
intlList.add(AccessibilityFlagsTest.class);
77
intlList.add(BasicTest.class);
78
intlList.add(ConflictingDefaultsTest.class);
79
intlList.add(DefaultVsAbstractTest.class);
80
intlList.add(MethodResolutionTest.class);
81
intlList.add(ObjectMethodOverridesTest.class);
82
intlList.add(SuperCallTest.class);
83
intlList.add(PrivateMethodsTest.class);
84
intlList.add(StaticMethodsTest.class);
85
intlList.add(RedefineTest.class);
86
87
classes = Collections.unmodifiableList(intlList);
88
}
89
90
public static List<Class<? extends DefMethTest>> getTests() {
91
return classes;
92
}
93
94
@Option(name="list", default_value="false", description="list tests w/o executing them")
95
boolean listTests;
96
97
@Option(name="filter", default_value="", description="filter executed tests")
98
String filterString;
99
100
@Option(name="silent", default_value="false", description="silent mode - don't print anything")
101
boolean isSilent;
102
103
@Option(name="failfast", default_value="false", description="fail the whole set of test on first failure")
104
boolean failFast;
105
106
@Option(name="testAllModes", default_value="false", description="run each test in all possible modes")
107
boolean testAllModes;
108
109
@Option(name="mode", description="invocation mode (direct, reflect, invoke)", default_value="direct")
110
String mode;
111
112
private Pattern filter; // Precompiled pattern for filterString
113
114
public static final int MIN_MAJOR_VER = V1_5;
115
public static final int MAX_MAJOR_VER = V17;
116
117
/**
118
* Used from individual tests to get TestBuilder instances,
119
* which is aware of current testing configuration
120
*/
121
@Options
122
protected TestBuilderFactory factory = new TestBuilderFactory(this);
123
124
private void init() {
125
if (isSilent) {
126
getLog().setInfoEnabled(false);
127
getLog().setWarnEnabled(false);
128
getLog().setDebugEnabled(false);
129
}
130
131
if (filterString != null && !"".equals(filterString)) {
132
filter = Pattern.compile(".*" + filterString + ".*");
133
} else {
134
filter = Pattern.compile(".*"); // match everything
135
}
136
137
// Test-specific config
138
configure();
139
}
140
141
@Override
142
public final void run() {
143
init();
144
145
boolean success = runTest();
146
if (!success) {
147
getLog().info("TEST FAILED");
148
setFailed(true);
149
} else {
150
getLog().info("TEST PASSED");
151
}
152
}
153
154
protected void configure() {
155
// Is overriden by specific tests to do test-specific setup
156
}
157
158
public Log getLog() {
159
return log;
160
}
161
162
@Override
163
public String toString() {
164
return format("%s%s",
165
getClass().getSimpleName(), factory);
166
}
167
168
/** Enumerate invocation modes to be tested */
169
private ExecutionMode[] getInvocationModes() {
170
if (factory.getExecutionMode() != null) {
171
return new ExecutionMode[] { ExecutionMode.valueOf(factory.getExecutionMode()) };
172
}
173
174
if (testAllModes) {
175
return ExecutionMode.values();
176
}
177
178
switch(mode) {
179
case "direct": return new ExecutionMode[] { ExecutionMode.DIRECT };
180
case "reflect": return new ExecutionMode[] { ExecutionMode.REFLECTION };
181
case "invoke_exact": return new ExecutionMode[] { ExecutionMode.INVOKE_EXACT };
182
case "invoke_generic": return new ExecutionMode[] { ExecutionMode.INVOKE_GENERIC };
183
case "indy": return new ExecutionMode[] { ExecutionMode.INDY };
184
case "invoke": return new ExecutionMode[] { ExecutionMode.INVOKE_WITH_ARGS,
185
ExecutionMode.INVOKE_EXACT,
186
ExecutionMode.INVOKE_GENERIC,
187
ExecutionMode.INDY };
188
case "redefinition":
189
throw new Error("redefinition is only a pseudo-mode");
190
default:
191
throw new Error("Unknown mode: " + mode);
192
}
193
}
194
195
// Check whether the test is applicable to selected execution mode
196
private boolean shouldExecute(Method m, ExecutionMode mode) {
197
Class<? extends DefMethTest> test = this.getClass();
198
199
int acc = m.getModifiers();
200
if (!Modifier.isPublic(acc) || Modifier.isStatic(acc) ||
201
m.getParameterTypes().length != 0 && !requiresTestBuilder(m)) {
202
return false; // not a test
203
}
204
205
String testName = format("%s.%s", test.getName(), m.getName());
206
if (!filter.matcher(testName).matches()) {
207
return false; // test is filtered out
208
}
209
210
if (m.isAnnotationPresent(NotApplicableFor.class)) {
211
for (ExecutionMode excludeFromMode : m.getAnnotation(NotApplicableFor.class).modes()) {
212
if (mode == excludeFromMode) {
213
return false; // not applicable to current execution mode
214
} else if (excludeFromMode == ExecutionMode.REDEFINITION &&
215
(factory.isRedefineClasses() || factory.isRetransformClasses())) {
216
return false; // Can't redefine some tests.
217
}
218
219
}
220
}
221
222
return true;
223
}
224
225
private boolean requiresTestBuilder(Method m) {
226
Parameter[] params = m.getParameters();
227
return params.length == 1 && (params[0].getType() == TestBuilder.class);
228
}
229
230
/** Information about the test being executed */
231
public String shortTestName;
232
233
public static class ComparableMethod implements Comparable<ComparableMethod> {
234
final java.lang.reflect.Method m;
235
ComparableMethod(java.lang.reflect.Method m) { this.m = m; }
236
public int compareTo(ComparableMethod mo) {
237
String name = m.getName();
238
String mo_name = mo.m.getName();
239
return name.compareTo(mo_name);
240
}
241
}
242
243
/** helper method for subclass to report the number of test failures.
244
* It is more important for the reflection case as an exception thrown
245
* deep in the call stack may not be propagated to this level.
246
*
247
* @param failures
248
*/
249
public void addFailureCount(int failures) {
250
numFailures += failures;
251
}
252
253
/**
254
* Execute all tests from current class and report status.
255
*
256
* The following execution customization is supported:
257
* - filter tests by name using regex
258
*
259
* @return any failures occurred?
260
*/
261
public final boolean runTest() {
262
ExecutionMode[] invocationModes = getInvocationModes();
263
264
try {
265
int totalTests = 0;
266
267
Class<? extends DefMethTest> test = this.getClass();
268
269
getLog().info(format("\n%s %s", test.getSimpleName(), factory.toString()));
270
271
TreeSet<ComparableMethod> ts = new TreeSet<ComparableMethod>();
272
for (java.lang.reflect.Method m : test.getDeclaredMethods()) {
273
ts.add(new ComparableMethod(m));
274
}
275
276
for (ComparableMethod cm : ts) {
277
java.lang.reflect.Method m = cm.m;
278
for (ExecutionMode mode : invocationModes) {
279
shortTestName = format("%s.%s", test.getSimpleName(), m.getName());
280
281
if (!shouldExecute(m, mode)) {
282
continue; // skip the test due to current configuration
283
}
284
285
totalTests++;
286
287
getLog().info(shortTestName);
288
289
if (listTests) {
290
continue; // just print test info
291
}
292
293
// Iterate over all test modes
294
try {
295
factory.setExecutionMode(mode.name());
296
getLog().info(format(" %s: ", mode));
297
if (requiresTestBuilder(m)) {
298
TestBuilder b = factory.getBuilder();
299
m.invoke(this, b);
300
b.run();
301
} else {
302
m.invoke(this);
303
}
304
} catch (IllegalAccessException | IllegalArgumentException e) {
305
throw new TestFailure(e);
306
} catch (InvocationTargetException e) {
307
if (e.getCause() instanceof TestFailure) {
308
// Failure details were printed in GeneratedTest.run()/ReflectionTest.run()
309
} else {
310
if (Constants.PRINT_STACK_TRACE) {
311
e.printStackTrace();
312
}
313
}
314
addFailureCount(1);
315
if (failFast) {
316
throw new TestFailure(e.getCause());
317
}
318
}
319
}
320
}
321
322
int passedTests = totalTests - numFailures;
323
getLog().info(format("%d test run: %d passed, %d failed", totalTests, passedTests, numFailures));
324
if (numFailures == 0) {
325
return true;
326
} else {
327
return false;
328
}
329
} catch (Exception | Error e) {
330
throw new RuntimeException(e);
331
}
332
}
333
334
public static void runTest(Class<? extends DefMethTest> testClass,
335
Set<Integer> majorVerValues,
336
Set<Integer> flagsValues,
337
Set<Boolean> redefineValues,
338
Set<ExecutionMode> execModes) {
339
for (int majorVer : majorVerValues) {
340
for (int flags : flagsValues) {
341
for (boolean redefine : redefineValues) {
342
for (ExecutionMode mode : execModes) {
343
try {
344
DefMethTest test = testClass.getDeclaredConstructor().newInstance();
345
346
OptionSupport.setup(test, new String[]{
347
"-execMode", mode.toString(),
348
"-ver", Integer.toString(majorVer),
349
"-flags", Integer.toString(flags),
350
"-redefine", Boolean.toString(redefine)
351
});
352
353
test.run();
354
} catch (ReflectiveOperationException e) {
355
throw new TestFailure(e);
356
}
357
}
358
}
359
}
360
}
361
}
362
363
/** Command-line interface to initiate test run */
364
public static void main(String[] args) {
365
for (Class<? extends DefMethTest> clz : classes) {
366
try {
367
DefMethTest test = clz.newInstance();
368
OptionSupport.setupAndRun(test, args);
369
} catch (InstantiationException | IllegalAccessException e) {
370
throw new TestFailure(e);
371
}
372
}
373
}
374
}
375
376