Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/descriptor/DescriptorTest.java
38838 views
1
/*
2
* Copyright (c) 2004, 2005, 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
/*
25
* @test
26
* @bug 6204469 6273765
27
* @summary Test various aspects of the Descriptor interface
28
* @author Eamonn McManus
29
* @run clean DescriptorTest
30
* @run build DescriptorTest
31
* @run main DescriptorTest
32
*/
33
34
import java.io.*;
35
import java.lang.reflect.*;
36
import java.util.*;
37
import javax.management.*;
38
39
public class DescriptorTest {
40
private static String failureMessage;
41
42
// Warning: many tests here know the contents of these variables
43
// so if you change them you must change the tests
44
private static final String[] testFieldNames = {
45
"a", "C", "aa", "int", "nul",
46
};
47
private static final Object[] testFieldValues = {
48
"b", "D", "bb", 5, null,
49
};
50
private static final String[] testFieldStrings = {
51
"a=b", "C=D", "aa=bb", "int=(5)", "nul=",
52
};
53
54
public static void main(String[] args) throws Exception {
55
genericTests(ImmutableDescriptor.class);
56
genericTests(javax.management.modelmbean.DescriptorSupport.class);
57
if (failureMessage != null)
58
throw new Exception("TEST FAILED: " + failureMessage);
59
else
60
System.out.println("Test passed");
61
}
62
63
private static void genericTests(Class<? extends Descriptor> descrClass) {
64
System.out.println("--- generic tests for " + descrClass.getName() +
65
" ---");
66
for (Case<Class<? extends Descriptor>, ?, ?> test :
67
genericDescriptorTests)
68
test.run(descrClass);
69
}
70
71
/*
72
Testing has three parts. We take the input parameter, of type P,
73
and give it to the "prepare" method. That returns us a test
74
parameter, of type T. We give that to the "test" method. That
75
in turn returns us a check value, of type C. We give this to the
76
"check" method. If the "check" method returns null, the test passes.
77
If the "check" method returns a string, that string explains the
78
test failure. If any of the methods throws an exception, the
79
test fails.
80
*/
81
private static abstract class Case<P, T, C> {
82
Case(String name) {
83
this.name = name;
84
}
85
86
void run(P p) {
87
System.out.println("test: " + name);
88
try {
89
T t = prepare(p);
90
C c = test(t);
91
String failed = check(c);
92
if (failed != null) {
93
System.out.println("FAILED: " + name + ": " + failed);
94
failureMessage = failed;
95
}
96
} catch (Exception e) {
97
System.out.println("FAILED: " + name + ": exception:");
98
e.printStackTrace(System.out);
99
failureMessage = e.toString();
100
}
101
}
102
103
abstract T prepare(P p) throws Exception;
104
abstract C test(T t) throws Exception;
105
abstract String check(C c) throws Exception;
106
107
private final String name;
108
}
109
110
/*
111
Test case where the preparation step consists of constructing an
112
instance of the given Descriptor subclass containing test values,
113
then giving that to the "test" method.
114
*/
115
private static abstract class ProtoCase<C>
116
extends Case<Class<? extends Descriptor>, Descriptor, C> {
117
118
ProtoCase(String name) {
119
super(name);
120
}
121
122
Descriptor prepare(Class<? extends Descriptor> descrClass)
123
throws Exception {
124
Constructor<? extends Descriptor> con =
125
descrClass.getConstructor(String[].class, Object[].class);
126
return con.newInstance(testFieldNames, testFieldValues);
127
}
128
}
129
130
/*
131
Test case where the "test" method must return a value of type C
132
which we will compare against the testValue parameter given to
133
the test constructor.
134
*/
135
private static abstract class ValueProtoCase<C> extends ProtoCase<C> {
136
ValueProtoCase(String name, C testValue) {
137
super(name);
138
this.testValue = testValue;
139
}
140
141
String check(C c) {
142
final boolean array = (testValue instanceof Object[]);
143
final boolean equal =
144
array ?
145
Arrays.deepEquals((Object[]) testValue, (Object[]) c) :
146
testValue.equals(c);
147
if (equal)
148
return null;
149
return "wrong value: " + string(c) + " should be " +
150
string(testValue);
151
}
152
153
private final C testValue;
154
}
155
156
/*
157
Test case where the dontChange method does some operation on the
158
test Descriptor that is not supposed to change the contents of
159
the Descriptor. This should work for both mutable and immutable
160
Descriptors, since immutable Descriptors are supposed to do
161
nothing (rather than throw an exception) for mutation operations
162
that would not in fact change the contents.
163
*/
164
private static abstract class UnchangedCase extends ProtoCase<Descriptor> {
165
UnchangedCase(String name) {
166
super(name);
167
}
168
169
Descriptor test(Descriptor d) {
170
dontChange(d);
171
return d;
172
}
173
174
String check(Descriptor d) {
175
String[] dnames = d.getFieldNames();
176
if (!strings(dnames).equals(strings(testFieldNames)))
177
return "descriptor names changed: " + strings(dnames);
178
Object[] values = d.getFieldValues(testFieldNames);
179
if (values.length != testFieldValues.length)
180
return "getFieldValues: bogus length: " + values.length;
181
for (int i = 0; i < values.length; i++) {
182
Object expected = testFieldValues[i];
183
Object found = values[i];
184
if ((expected == null) ?
185
found != null :
186
!expected.equals(found))
187
return "descriptor value changed: " + testFieldNames[i] +
188
" was " + expected + " now " + found;
189
}
190
return null;
191
}
192
193
abstract void dontChange(Descriptor d);
194
}
195
196
/*
197
Test case where the change(d) method attempts to make some
198
change to the Descriptor d. The behaviour depends on whether
199
the Descriptor is mutable or not. If the Descriptor is
200
immutable, then the change attempt must throw a
201
RuntimeOperationsException wrapping an
202
UnsupportedOperationException. If the Descriptor is mutable,
203
then the change attempt must succeed, and the Descriptor must
204
then look like the fieldsAndValues parameter to the constructor.
205
This is simply an alternating set of field names and corresponding
206
values. So for example if it is
207
208
"a", "b", "x", 5
209
210
that represents a Descriptor with fields "a" and "x" whose
211
corresponding values are "x" and Integer.valueOf(5).
212
*/
213
private static abstract class ChangedCase extends ProtoCase<Object> {
214
ChangedCase(String name, Object... fieldsAndValues) {
215
super(name);
216
if (fieldsAndValues.length % 2 != 0)
217
throw new AssertionError("test wrong: odd fieldsAndValues");
218
this.fieldsAndValues = fieldsAndValues;
219
this.immutableTest = new UnsupportedExceptionCase(name) {
220
void provoke(Descriptor d) {
221
ChangedCase.this.change(d);
222
}
223
};
224
}
225
226
Object test(Descriptor d) {
227
if (immutable(d))
228
return immutableTest.test(d);
229
else {
230
change(d);
231
return d;
232
}
233
}
234
235
String check(Object c) {
236
if (c instanceof Exception)
237
return immutableTest.check((Exception) c);
238
else if (!(c instanceof Descriptor)) {
239
return "test returned strange value: " +
240
c.getClass() + ": " + c;
241
} else {
242
Descriptor d = (Descriptor) c;
243
String[] names = new String[fieldsAndValues.length / 2];
244
Object[] expected = new Object[names.length];
245
for (int i = 0; i < fieldsAndValues.length; i += 2) {
246
names[i / 2] = (String) fieldsAndValues[i];
247
expected[i / 2] = fieldsAndValues[i + 1];
248
}
249
String[] foundNames = d.getFieldNames();
250
if (!strings(foundNames).equals(strings(names))) {
251
return "wrong field names after change: found " +
252
strings(foundNames) + ", expected " + strings(names);
253
}
254
Object[] found = d.getFieldValues(names);
255
if (!Arrays.deepEquals(expected, found)) {
256
return "wrong value after change: for fields " +
257
Arrays.asList(names) + " values are " +
258
Arrays.asList(found) + ", should be " +
259
Arrays.asList(expected);
260
}
261
return null;
262
}
263
}
264
265
abstract void change(Descriptor d);
266
267
private final Object[] fieldsAndValues;
268
private final ExceptionCase immutableTest;
269
}
270
271
/*
272
Test case where an operation provoke(d) on the test Descriptor d
273
is supposed to provoke an exception. The exception must be a
274
RuntimeOperationsException wrapping another exception whose type
275
is determined by the exceptionClass() method.
276
*/
277
private static abstract class ExceptionCase extends ProtoCase<Exception> {
278
279
ExceptionCase(String name) {
280
super(name);
281
}
282
283
Exception test(Descriptor d) {
284
try {
285
provoke(d);
286
return null;
287
} catch (Exception e) {
288
return e;
289
}
290
}
291
292
String check(Exception e) {
293
if (e == null)
294
return "did not throw exception: " + expected();
295
if (!(e instanceof RuntimeOperationsException)) {
296
StringWriter sw = new StringWriter();
297
PrintWriter pw = new PrintWriter(sw);
298
e.printStackTrace(pw);
299
pw.flush();
300
return "wrong exception: " + expected() + ": found: " + sw;
301
}
302
Throwable cause = e.getCause();
303
if (!exceptionClass().isInstance(cause))
304
return "wrong wrapped exception: " + cause + ": " + expected();
305
return null;
306
}
307
308
String expected() {
309
return "expected " + RuntimeOperationsException.class.getName() +
310
" wrapping " + exceptionClass().getName();
311
}
312
313
abstract Class<? extends Exception> exceptionClass();
314
abstract void provoke(Descriptor d);
315
}
316
317
private static abstract class IllegalExceptionCase extends ExceptionCase {
318
IllegalExceptionCase(String name) {
319
super(name);
320
}
321
322
Class<IllegalArgumentException> exceptionClass() {
323
return IllegalArgumentException.class;
324
}
325
}
326
327
private static abstract class UnsupportedExceptionCase
328
extends ExceptionCase {
329
UnsupportedExceptionCase(String name) {
330
super(name);
331
}
332
333
Class<UnsupportedOperationException> exceptionClass() {
334
return UnsupportedOperationException.class;
335
}
336
}
337
338
/*
339
List of test cases. We will run through these once for
340
ImmutableDescriptor and once for DescriptorSupport.
341
342
Expect a compiler [unchecked] warning for this initialization.
343
Writing
344
345
new Case<Class<? extends Descriptor>, ?, ?>[] = {...}
346
347
would cause a compiler error since you can't have arrays of
348
parameterized types unless all the parameters are just "?".
349
This hack with varargs gives us a compiler warning instead.
350
Writing just:
351
352
new Case<?, ?, ?>[] = {...}
353
354
would compile here, but not where we call test.run, since you
355
cannot pass an object to the run(P) method if P is "?".
356
*/
357
private static final Case<Class<? extends Descriptor>, ?, ?>
358
genericDescriptorTests[] = constantArray(
359
360
// TEST VALUES RETURNED BY GETTERS
361
362
new Case<Class<? extends Descriptor>, Descriptor, Object[]>(
363
"getFieldValues on empty Descriptor") {
364
Descriptor prepare(Class<? extends Descriptor> c)
365
throws Exception {
366
Constructor<? extends Descriptor> con =
367
c.getConstructor(String[].class);
368
return con.newInstance(new Object[] {new String[0]});
369
}
370
Object[] test(Descriptor d) {
371
return d.getFieldValues("foo", "bar");
372
}
373
String check(Object[] v) {
374
if (v.length == 2 && v[0] == null && v[1] == null)
375
return null;
376
return "value should be array with null elements: " +
377
Arrays.deepToString(v);
378
}
379
},
380
381
new ValueProtoCase<Set<String>>("getFieldNames",
382
strings(testFieldNames)) {
383
Set<String> test(Descriptor d) {
384
return set(d.getFieldNames());
385
}
386
},
387
new ValueProtoCase<Set<String>>("getFields",
388
strings(testFieldStrings)) {
389
Set<String> test(Descriptor d) {
390
return set(d.getFields());
391
}
392
},
393
new ValueProtoCase<Object>("getFieldValue with exact case", "b") {
394
Object test(Descriptor d) {
395
return d.getFieldValue("a");
396
}
397
},
398
new ValueProtoCase<Object>("getFieldValue with lower case for upper",
399
"D") {
400
Object test(Descriptor d) {
401
return d.getFieldValue("c");
402
}
403
},
404
new ValueProtoCase<Object>("getFieldValue with upper case for lower",
405
"bb") {
406
Object test(Descriptor d) {
407
return d.getFieldValue("AA");
408
}
409
},
410
new ValueProtoCase<Object>("getFieldValue with mixed case for lower",
411
"bb") {
412
Object test(Descriptor d) {
413
return d.getFieldValue("aA");
414
}
415
},
416
new ValueProtoCase<Set<?>>("getFieldValues with null arg",
417
set(testFieldValues)) {
418
Set<?> test(Descriptor d) {
419
return set(d.getFieldValues((String[]) null));
420
}
421
},
422
new ValueProtoCase<Object[]>("getFieldValues with not all values",
423
new Object[] {"b", "D", 5}) {
424
Object[] test(Descriptor d) {
425
return d.getFieldValues("a", "c", "int");
426
}
427
},
428
new ValueProtoCase<Object[]>("getFieldValues with all values " +
429
"lower case",
430
new Object[]{"bb", "D", "b", 5}) {
431
Object[] test(Descriptor d) {
432
return d.getFieldValues("aa", "c", "a", "int");
433
}
434
},
435
new ValueProtoCase<Object[]>("getFieldValues with all values " +
436
"upper case",
437
new Object[] {5, "b", "D", "bb"}) {
438
Object[] test(Descriptor d) {
439
return d.getFieldValues("int", "A", "C", "AA");
440
}
441
},
442
new ValueProtoCase<Object[]>("getFieldValues with null name",
443
new Object[] {null}) {
444
Object[] test(Descriptor d) {
445
return d.getFieldValues((String) null);
446
}
447
},
448
new ValueProtoCase<Object[]>("getFieldValues with empty name",
449
new Object[] {null}) {
450
Object[] test(Descriptor d) {
451
return d.getFieldValues("");
452
}
453
},
454
new ValueProtoCase<Object[]>("getFieldValues with no names",
455
new Object[0]) {
456
Object[] test(Descriptor d) {
457
return d.getFieldValues();
458
}
459
},
460
461
// TEST OPERATIONS THAT DON'T CHANGE THE DESCRIPTOR
462
// Even for immutable descriptors, these are allowed
463
464
new UnchangedCase("removeField with nonexistent field") {
465
void dontChange(Descriptor d) {
466
d.removeField("noddy");
467
}
468
},
469
new UnchangedCase("removeField with null field") {
470
void dontChange(Descriptor d) {
471
d.removeField(null);
472
}
473
},
474
new UnchangedCase("removeField with empty field") {
475
void dontChange(Descriptor d) {
476
d.removeField("");
477
}
478
},
479
new UnchangedCase("setField leaving string unchanged") {
480
void dontChange(Descriptor d) {
481
d.setField("a", "b");
482
}
483
},
484
new UnchangedCase("setField leaving int unchanged") {
485
void dontChange(Descriptor d) {
486
d.setField("int", 5);
487
}
488
},
489
// We do not test whether you can do a setField/s with an
490
// unchanged value but the case of the name different.
491
// From the spec, that should probably be illegal, but
492
// it's such a corner case that we leave it alone.
493
494
new UnchangedCase("setFields with empty arrays") {
495
void dontChange(Descriptor d) {
496
d.setFields(new String[0], new Object[0]);
497
}
498
},
499
new UnchangedCase("setFields with unchanged values") {
500
void dontChange(Descriptor d) {
501
d.setFields(new String[] {"a", "int"},
502
new Object[] {"b", 5});
503
}
504
},
505
506
// TEST OPERATIONS THAT DO CHANGE THE DESCRIPTOR
507
// For immutable descriptors, these should provoke an exception
508
509
new ChangedCase("removeField with exact case",
510
"a", "b", "C", "D", "int", 5, "nul", null) {
511
void change(Descriptor d) {
512
d.removeField("aa");
513
}
514
},
515
new ChangedCase("removeField with upper case for lower",
516
"a", "b", "C", "D", "int", 5, "nul", null) {
517
void change(Descriptor d) {
518
d.removeField("AA");
519
}
520
},
521
new ChangedCase("removeField with lower case for upper",
522
"a", "b", "aa", "bb", "int", 5, "nul", null) {
523
void change(Descriptor d) {
524
d.removeField("c");
525
}
526
},
527
new ChangedCase("setField keeping lower case",
528
"a", "x", "C", "D", "aa", "bb", "int", 5,
529
"nul", null) {
530
void change(Descriptor d) {
531
d.setField("a", "x");
532
}
533
},
534
535
// spec says we should conserve the original case of the field name:
536
new ChangedCase("setField changing lower case to upper",
537
"a", "x", "C", "D", "aa", "bb", "int", 5,
538
"nul", null) {
539
void change(Descriptor d) {
540
d.setField("A", "x");
541
}
542
},
543
new ChangedCase("setField changing upper case to lower",
544
"a", "b", "C", "x", "aa", "bb", "int", 5,
545
"nul", null) {
546
void change(Descriptor d) {
547
d.setField("c", "x");
548
}
549
},
550
new ChangedCase("setField adding new field",
551
"a", "b", "C", "D", "aa", "bb", "int", 5, "xX", "yY",
552
"nul", null) {
553
void change(Descriptor d) {
554
d.setField("xX", "yY");
555
}
556
},
557
new ChangedCase("setField changing type of field",
558
"a", true, "C", "D", "aa", "bb", "int", 5,
559
"nul", null) {
560
void change(Descriptor d) {
561
d.setField("a", true);
562
}
563
},
564
new ChangedCase("setField changing non-null to null",
565
"a", null, "C", "D", "aa", "bb", "int", 5,
566
"nul", null) {
567
void change(Descriptor d) {
568
d.setField("a", null);
569
}
570
},
571
new ChangedCase("setField changing null to non-null",
572
"a", "b", "C", "D", "aa", "bb", "int", 5,
573
"nul", 3.14) {
574
void change(Descriptor d) {
575
d.setField("nul", 3.14);
576
}
577
},
578
579
// TEST EXCEPTION BEHAVIOUR COMMON BETWEEN MUTABLE AND IMMUTABLE
580
581
new IllegalExceptionCase("getFieldValue with null name") {
582
void provoke(Descriptor d) {
583
d.getFieldValue(null);
584
}
585
},
586
new IllegalExceptionCase("getFieldValue with empty name") {
587
void provoke(Descriptor d) {
588
d.getFieldValue("");
589
}
590
},
591
new IllegalExceptionCase("setField with null name") {
592
void provoke(Descriptor d) {
593
d.setField(null, "x");
594
}
595
},
596
new IllegalExceptionCase("setField with empty name") {
597
void provoke(Descriptor d) {
598
d.setField("", "x");
599
}
600
},
601
new IllegalExceptionCase("setFields with null fieldNames") {
602
void provoke(Descriptor d) {
603
d.setFields(null, new Object[] {"X"});
604
}
605
},
606
new IllegalExceptionCase("setFields with null fieldValues") {
607
void provoke(Descriptor d) {
608
d.setFields(new String[] {"X"}, null);
609
}
610
},
611
new IllegalExceptionCase("setFields with null fieldNames and " +
612
"fieldValues") {
613
void provoke(Descriptor d) {
614
d.setFields(null, null);
615
}
616
},
617
new IllegalExceptionCase("setFields with more fieldNames than " +
618
"fieldValues") {
619
void provoke(Descriptor d) {
620
d.setFields(new String[] {"A", "B"}, new String[] {"C"});
621
}
622
},
623
new IllegalExceptionCase("setFields with more fieldValues than " +
624
"fieldNames") {
625
void provoke(Descriptor d) {
626
d.setFields(new String[] {"A"}, new String[] {"B", "C"});
627
}
628
},
629
new IllegalExceptionCase("setFields with null element of fieldNames") {
630
void provoke(Descriptor d) {
631
d.setFields(new String[] {null}, new String[] {"X"});
632
}
633
}
634
635
);
636
637
static <T> T[] constantArray(T... array) {
638
return array;
639
}
640
641
static String string(Object x) {
642
if (x instanceof Object[])
643
return Arrays.asList((Object[]) x).toString();
644
else
645
return String.valueOf(x);
646
}
647
648
static Set<String> strings(String... values) {
649
return new TreeSet<String>(Arrays.asList(values));
650
}
651
652
static <T> Set<T> set(T[] values) {
653
return new HashSet<T>(Arrays.asList(values));
654
}
655
656
static boolean immutable(Descriptor d) {
657
return (d instanceof ImmutableDescriptor);
658
// good enough for our purposes
659
}
660
}
661
662