Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/misc/SunMiscSignalTest.java
41145 views
1
/*
2
* Copyright (c) 2016, 2019, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
import java.util.ArrayList;
27
import java.util.List;
28
import java.util.Objects;
29
import java.util.concurrent.Semaphore;
30
import java.util.concurrent.TimeUnit;
31
32
import org.testng.Assert;
33
import org.testng.TestNG;
34
import org.testng.annotations.Test;
35
import org.testng.annotations.BeforeSuite;
36
import org.testng.annotations.DataProvider;
37
38
import jdk.test.lib.Platform;
39
import jdk.test.lib.Utils;
40
41
import sun.misc.Signal;
42
import sun.misc.SignalHandler;
43
44
/*
45
* @test
46
* @library /test/lib
47
* @modules jdk.unsupported
48
* java.base/jdk.internal.misc
49
* @build jdk.test.lib.Utils
50
* jdk.test.lib.Asserts
51
* jdk.test.lib.JDKToolFinder
52
* jdk.test.lib.JDKToolLauncher
53
* jdk.test.lib.Platform
54
* jdk.test.lib.process.*
55
* @run testng/othervm -Xrs -DXrs=true SunMiscSignalTest
56
* @run testng/othervm SunMiscSignalTest
57
* @summary sun.misc.Signal test
58
*/
59
60
@Test
61
public class SunMiscSignalTest {
62
63
// Set to true to enable additional debug output
64
static boolean debug = true;
65
66
// True to test while running with -Xrs
67
static boolean RUNNING_WITH_Xrs = Boolean.getBoolean("Xrs");
68
69
/**
70
* Print a debug message if enabled.
71
*
72
* @param format the format
73
* @param args the arguments
74
*/
75
static void printf(String format, Object... args) {
76
if (debug) {
77
System.out.printf(" " + format, args);
78
}
79
}
80
81
enum IsSupported {NO, YES}
82
83
enum CanRegister {NO, YES}
84
85
enum CanRaise {NO, YES}
86
87
enum Invoked {NO, YES}
88
89
enum RestrictedSignals {NORMAL, XRS}
90
91
@BeforeSuite
92
static void setup() {
93
System.out.printf("-Xrs: %s%n", RUNNING_WITH_Xrs);
94
}
95
96
// Provider of signals to be tested with variations for -Xrs and
97
// platform dependencies
98
// -Xrs restricted signals signals the VM will not handle SIGINT, SIGTERM, SIGHUP and others
99
@DataProvider(name = "supportedSignals")
100
static Object[][] supportedSignals() {
101
RestrictedSignals rs = RUNNING_WITH_Xrs ? RestrictedSignals.XRS : RestrictedSignals.NORMAL;
102
CanRegister registerXrs = RUNNING_WITH_Xrs ? CanRegister.NO : CanRegister.YES;
103
CanRaise raiseXrs = RUNNING_WITH_Xrs ? CanRaise.NO : CanRaise.YES;
104
Invoked invokedXrs = RUNNING_WITH_Xrs ? Invoked.NO : Invoked.YES;
105
106
Object[][] commonSignals = new Object[][]{
107
{"INT", IsSupported.YES, registerXrs, raiseXrs, invokedXrs},
108
{"TERM", IsSupported.YES, registerXrs, raiseXrs, invokedXrs},
109
{"ABRT", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
110
};
111
112
Object[][] posixSignals = {
113
{"HUP", IsSupported.YES, registerXrs, raiseXrs, invokedXrs},
114
{"QUIT", IsSupported.YES, CanRegister.NO, CanRaise.NO, Invoked.NO},
115
{"USR1", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
116
{"USR2", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
117
{"PIPE", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
118
{"ALRM", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
119
{"CHLD", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
120
{"CONT", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
121
{"TSTP", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
122
{"TTIN", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
123
{"TTOU", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
124
{"URG", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
125
{"XCPU", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
126
{"XFSZ", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
127
{"VTALRM", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
128
{"PROF", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
129
{"WINCH", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
130
{"IO", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
131
{"SYS", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
132
};
133
134
Object[][] posixNonOSXSignals = {
135
{"BUS", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
136
{"INFO", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
137
};
138
139
Object[][] posixOSXSignals = {
140
{"BUS", IsSupported.YES, CanRegister.NO, CanRaise.NO, Invoked.NO},
141
{"INFO", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs},
142
};
143
144
Object[][] windowsSignals = {
145
{"HUP", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
146
{"QUIT", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
147
{"BUS", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
148
{"USR1", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
149
{"USR2", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
150
{"PIPE", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
151
{"ALRM", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
152
{"CHLD", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
153
{"CONT", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
154
{"TSTP", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
155
{"TTIN", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
156
{"TTOU", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
157
{"URG", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
158
{"XCPU", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
159
{"XFSZ", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
160
{"VTALRM", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
161
{"PROF", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
162
{"WINCH", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
163
{"IO", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
164
{"SYS", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO},
165
};
166
167
Object[][] combinedPosixSignals = concatArrays(posixSignals,
168
(Platform.isOSX() ? posixOSXSignals : posixNonOSXSignals));
169
return concatArrays(commonSignals, (Platform.isWindows() ? windowsSignals : combinedPosixSignals));
170
}
171
172
// Provider of invalid signal names
173
@DataProvider(name = "invalidSunMiscSignalNames")
174
Object[][] invalidSunMiscSignalNames() {
175
return new Object[][]{
176
{""},
177
{"I"},
178
{"SIG"},
179
{"SIGabc"},
180
{"SIGINT"}, // prefix not allowed
181
{"abc"},
182
};
183
}
184
185
static Object[][] concatArrays(Object[][]... arrays) {
186
int l = 0;
187
for (Object[][] a : arrays) {
188
l += a.length;
189
}
190
191
Object[][] newArray = new Object[l][];
192
l = 0;
193
for (int i = 0; i < arrays.length; i++) {
194
System.arraycopy(arrays[i], 0, newArray, l, arrays[i].length);
195
l += arrays[i].length;
196
}
197
198
return newArray;
199
}
200
201
// Return true if the signal is one of the shutdown signals known to the VM
202
private static boolean isShutdownSignal(Signal signal) {
203
String name = signal.getName();
204
return name.equals("INT") || name.equals("HUP") || name.equals("TERM");
205
}
206
207
/**
208
* Quick verification of supported signals using sun.misc.Signal.
209
*
210
* @param name the signal name
211
* @throws InterruptedException would be an error if thrown
212
*/
213
@Test(dataProvider = "supportedSignals")
214
static void testSunMisc(String name, IsSupported supported, CanRegister register,
215
CanRaise raise, Invoked invoked) throws InterruptedException {
216
Handler h = new Handler();
217
SignalHandler orig = null;
218
Signal signal = null;
219
try {
220
signal = new Signal(name);
221
Assert.assertEquals(supported, IsSupported.YES, "Unexpected support for " + name);
222
223
Assert.assertEquals(signal.getName(), name, "getName() mismatch, ");
224
225
Assert.assertEquals(signal.toString(), "SIG" + name, "toString() mismatch, ");
226
227
try {
228
orig = Signal.handle(signal, h);
229
printf("oldHandler: %s%n", orig);
230
Assert.assertEquals(CanRegister.YES, register, "Unexpected handle succeeded " + name);
231
try {
232
Signal.raise(signal);
233
Assert.assertEquals(CanRaise.YES, raise, "Unexpected raise success for " + name);
234
Invoked inv = h.semaphore().tryAcquire(Utils.adjustTimeout(100L),
235
TimeUnit.MILLISECONDS) ? Invoked.YES : Invoked.NO;
236
if (!isShutdownSignal(signal)) {
237
// Normal case
238
Assert.assertEquals(inv, invoked, "handler not invoked;");
239
} else {
240
if (orig == SignalHandler.SIG_IGN) {
241
Assert.assertEquals(inv, Invoked.NO, "handler should not be invoked");
242
} else {
243
Assert.assertEquals(inv, invoked, "handler not invoked;");
244
}
245
}
246
} catch (IllegalArgumentException uoe3) {
247
Assert.assertNotEquals(CanRaise.YES, raise, "raise failed for " + name +
248
": " + uoe3.getMessage());
249
}
250
} catch (IllegalArgumentException uoe2) {
251
Assert.assertNotEquals(CanRegister.YES, register, "handle failed for: " + name +
252
": " + uoe2.getMessage());
253
}
254
} catch (IllegalArgumentException uoe) {
255
Assert.assertNotEquals(IsSupported.YES, supported, "Support missing for " + name +
256
": " + uoe.getMessage());
257
return;
258
} finally {
259
// Restore original signal handler
260
if (orig != null && signal != null) {
261
Signal.handle(signal, orig);
262
}
263
}
264
}
265
266
// Test Signal is equal to itself and not equals to others
267
@Test(dataProvider = "supportedSignals")
268
static void testEquals(String name, IsSupported supported, CanRegister register,
269
CanRaise raise, Invoked invoked) {
270
Object[][] data = supportedSignals();
271
for (int i = 0; i < data.length; i++) {
272
IsSupported otherSupported = (IsSupported) data[i][1];
273
if (supported == IsSupported.NO || otherSupported == IsSupported.NO) {
274
continue;
275
}
276
String otherName = (String) data[i][0];
277
278
Signal sig1 = new Signal(name);
279
Signal sig2 = new Signal(otherName);
280
if (name.equals(otherName)) {
281
Assert.assertEquals(sig1, sig2, "Equals failed; ");
282
Assert.assertEquals(sig1.hashCode(), sig2.hashCode(), "HashCode wrong; ");
283
} else {
284
Assert.assertNotEquals(sig1, sig2, "NotEquals failed; ");
285
Assert.assertNotEquals(sig1.hashCode(), sig2.hashCode(), "HashCode wrong; ");
286
}
287
}
288
}
289
290
@Test(dataProvider = "invalidSunMiscSignalNames")
291
static void testSunMiscIAE(String name) {
292
try {
293
new Signal(name);
294
Assert.fail("Should have thrown IAE for signal: " + name);
295
} catch (IllegalArgumentException iae) {
296
Assert.assertEquals(iae.getMessage(), "Unknown signal: " + name, "getMessage() incorrect; ");
297
}
298
}
299
300
// Note: JDK 8 did not check/throw NPE, passing null resulted in a segv
301
@Test(expectedExceptions = NullPointerException.class)
302
static void nullSignal() {
303
new Signal(null);
304
}
305
306
// Test expected exception when raising a signal when no handler defined
307
@Test
308
static void testRaiseNoConsumer() {
309
Signal signal = new Signal("INT");
310
SignalHandler orig = null;
311
try {
312
orig = Signal.handle(signal, SignalHandler.SIG_DFL);
313
printf("oldHandler: %s%n", orig);
314
if (orig == SignalHandler.SIG_IGN) {
315
// SIG_IGN for TERM means it cannot be handled
316
return;
317
}
318
Signal.raise(signal);
319
Assert.fail("Should have thrown IllegalArgumentException");
320
} catch (IllegalArgumentException iae) {
321
printf("IAE message: %s%n", iae.getMessage());
322
} finally {
323
// Restore original signal handler
324
if (orig != null && signal != null) {
325
Signal.handle(signal, orig);
326
}
327
}
328
}
329
330
/**
331
* The thread that runs the handler for sun.misc.Signal should be a
332
* Daemon thread.
333
*/
334
@Test
335
static void isDaemonThread() throws InterruptedException {
336
if (RUNNING_WITH_Xrs) {
337
return;
338
}
339
Handler handler = new Handler();
340
Signal signal = new Signal("INT");
341
SignalHandler orig = Signal.handle(signal, handler);
342
printf("oldHandler: %s%n", orig);
343
if (orig == SignalHandler.SIG_IGN) {
344
// SIG_IGN for INT means it cannot be handled
345
return;
346
}
347
348
Signal.raise(signal);
349
boolean handled = handler.semaphore()
350
.tryAcquire(Utils.adjustTimeout(100L), TimeUnit.MILLISECONDS);
351
if (!handled) {
352
// For debug try again
353
printf("Second try to see signal");
354
handled = handler.semaphore()
355
.tryAcquire(Utils.adjustTimeout(2L), TimeUnit.SECONDS);
356
}
357
Assert.assertEquals(handled, !RUNNING_WITH_Xrs,
358
"raising s.m.Signal did not get a callback;");
359
360
Assert.assertTrue(handler.wasDaemon(), "Thread.isDaemon running the handler; ");
361
}
362
363
// Check that trying to invoke SIG_DFL.handle throws UnsupportedOperationException.
364
@Test(expectedExceptions = UnsupportedOperationException.class)
365
static void cannotHandleSIGDFL() {
366
Signal signal = new Signal("INT");
367
Assert.assertNotNull(SignalHandler.SIG_DFL, "SIG_DFL null; ");
368
SignalHandler.SIG_DFL.handle(signal);
369
}
370
371
// Check that trying to invoke SIG_IGN.handle throws UnsupportedOperationException.
372
@Test(expectedExceptions = UnsupportedOperationException.class)
373
static void cannotHandleSIGIGN() {
374
Signal signal = new Signal("INT");
375
Assert.assertNotNull(SignalHandler.SIG_IGN, "SIG_IGN null; ");
376
SignalHandler.SIG_IGN.handle(signal);
377
}
378
379
// Check that setting a Signal handler returns the previous handler.
380
@Test()
381
static void checkLastHandler() {
382
if (RUNNING_WITH_Xrs) {
383
return;
384
}
385
Signal signal = new Signal("TERM");
386
Handler h1 = new Handler();
387
Handler h2 = new Handler();
388
SignalHandler orig = Signal.handle(signal, h1);
389
if (orig == SignalHandler.SIG_IGN) {
390
// SIG_IGN for TERM means it cannot be handled
391
return;
392
}
393
394
try {
395
SignalHandler prev = Signal.handle(signal, h2);
396
Assert.assertSame(prev, h1, "prev handler mismatch");
397
398
prev = Signal.handle(signal, h1);
399
Assert.assertSame(prev, h2, "prev handler mismatch");
400
} finally {
401
if (orig != null && signal != null) {
402
Signal.handle(signal, orig);
403
}
404
}
405
}
406
407
/**
408
* Test Handler, a SignalHandler for Signal notifications.
409
* Signals a semaphore when invoked and records whether
410
* the thread calling the Handler was a daemon.
411
*/
412
static class Handler implements SignalHandler {
413
// A semaphore to check for accept being called
414
Semaphore sema = new Semaphore(0);
415
416
Boolean wasDaemon = null;
417
418
Semaphore semaphore() {
419
return sema;
420
}
421
422
synchronized Boolean wasDaemon() {
423
return wasDaemon;
424
}
425
426
/**
427
* Releases the semaphore when called as SignalHandler.handle.
428
*
429
* @param signal the Signal that occurred
430
*/
431
@Override
432
public void handle(Signal signal) {
433
synchronized (this) {
434
wasDaemon = Thread.currentThread().isDaemon();
435
}
436
sema.release();
437
printf("sun.misc.handle sig: %s, num: %d%n", signal.getName(), signal.getNumber());
438
}
439
440
public String toString() {
441
return "Handler: sem: " + sema.getQueueLength() +
442
", wasDaemon: " + Objects.toString(wasDaemon());
443
}
444
}
445
446
// Main can be used to run the tests from the command line with only testng.jar.
447
@SuppressWarnings("raw_types")
448
@Test(enabled = false)
449
public static void main(String[] args) {
450
Class<?>[] testclass = {SunMiscSignalTest.class};
451
TestNG testng = new TestNG();
452
testng.setTestClasses(testclass);
453
testng.run();
454
}
455
456
}
457
458