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