8301767: Convert virtual thread tests to JUnit
Reviewed-by: cstein, lancea, jpai
This commit is contained in:
parent
9af2ea203d
commit
ecf21a9a24
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
* @bug 8284161 8287008
|
||||
* @summary Basic test for jcmd Thread.dump_to_file
|
||||
* @library /test/lib
|
||||
* @run testng/othervm ThreadDumpToFileTest
|
||||
* @run junit/othervm ThreadDumpToFileTest
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
@ -37,16 +37,16 @@ import jdk.test.lib.dcmd.PidJcmdExecutor;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.threaddump.ThreadDump;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ThreadDumpToFileTest {
|
||||
class ThreadDumpToFileTest {
|
||||
|
||||
/**
|
||||
* Test thread dump, should be in plain text format.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadDump() throws IOException {
|
||||
void testThreadDump() throws IOException {
|
||||
Path file = genThreadDumpPath(".txt");
|
||||
testPlainThreadDump(file);
|
||||
}
|
||||
@ -55,7 +55,7 @@ public class ThreadDumpToFileTest {
|
||||
* Test thread dump in plain text format.
|
||||
*/
|
||||
@Test
|
||||
public void testPlainThreadDump() throws IOException {
|
||||
void testPlainThreadDump() throws IOException {
|
||||
Path file = genThreadDumpPath(".txt");
|
||||
testPlainThreadDump(file, "-format=plain");
|
||||
}
|
||||
@ -64,7 +64,7 @@ public class ThreadDumpToFileTest {
|
||||
* Test thread dump in JSON format.
|
||||
*/
|
||||
@Test
|
||||
public void testJsonThreadDump() throws IOException {
|
||||
void testJsonThreadDump() throws IOException {
|
||||
Path file = genThreadDumpPath(".json");
|
||||
threadDump(file, "-format=json").shouldMatch("Created");
|
||||
|
||||
@ -85,21 +85,21 @@ public class ThreadDumpToFileTest {
|
||||
* Test that an existing file is not overwritten.
|
||||
*/
|
||||
@Test
|
||||
public void testDoNotOverwriteFile() throws IOException {
|
||||
void testDoNotOverwriteFile() throws IOException {
|
||||
Path file = genThreadDumpPath(".txt");
|
||||
Files.writeString(file, "xxx");
|
||||
|
||||
threadDump(file, "").shouldMatch("exists");
|
||||
|
||||
// file should not be overridden
|
||||
assertEquals(Files.readString(file), "xxx");
|
||||
assertEquals("xxx", Files.readString(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test overwriting an existing file.
|
||||
*/
|
||||
@Test
|
||||
public void testOverwriteFile() throws IOException {
|
||||
void testOverwriteFile() throws IOException {
|
||||
Path file = genThreadDumpPath(".txt");
|
||||
Files.writeString(file, "xxx");
|
||||
testPlainThreadDump(file, "-overwrite");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,10 +27,10 @@
|
||||
* @summary Basic test for com.sun.management.HotSpotDiagnosticMXBean.dumpThreads
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm DumpThreads
|
||||
* @run testng/othervm -Djdk.trackAllThreads DumpThreads
|
||||
* @run testng/othervm -Djdk.trackAllThreads=true DumpThreads
|
||||
* @run testng/othervm -Djdk.trackAllThreadds=false DumpThreads
|
||||
* @run junit/othervm DumpThreads
|
||||
* @run junit/othervm -Djdk.trackAllThreads DumpThreads
|
||||
* @run junit/othervm -Djdk.trackAllThreads=true DumpThreads
|
||||
* @run junit/othervm -Djdk.trackAllThreadds=false DumpThreads
|
||||
*/
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
@ -47,10 +47,10 @@ import com.sun.management.HotSpotDiagnosticMXBean;
|
||||
import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat;
|
||||
import jdk.test.lib.threaddump.ThreadDump;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class DumpThreads {
|
||||
class DumpThreads {
|
||||
private static final boolean TRACK_ALL_THREADS;
|
||||
static {
|
||||
String s = System.getProperty("jdk.trackAllThreads");
|
||||
@ -61,7 +61,7 @@ public class DumpThreads {
|
||||
* Thread dump in plain text format.
|
||||
*/
|
||||
@Test
|
||||
public void testPlainText() throws Exception {
|
||||
void testPlainText() throws Exception {
|
||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||
Path file = genOutputPath("txt");
|
||||
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
@ -98,7 +98,7 @@ public class DumpThreads {
|
||||
* Thread dump in JSON format.
|
||||
*/
|
||||
@Test
|
||||
public void testJson() throws Exception {
|
||||
void testJson() throws Exception {
|
||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||
Path file = genOutputPath("json");
|
||||
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
@ -118,7 +118,7 @@ public class DumpThreads {
|
||||
ZonedDateTime.parse(threadDump.time());
|
||||
|
||||
// test threadDump/runtimeVersion
|
||||
assertEquals(threadDump.runtimeVersion(), Runtime.version().toString());
|
||||
assertEquals(Runtime.version().toString(), threadDump.runtimeVersion());
|
||||
|
||||
// test root container
|
||||
var rootContainer = threadDump.rootThreadContainer();
|
||||
@ -150,7 +150,7 @@ public class DumpThreads {
|
||||
* Test that dumpThreads throws if the output file already exists.
|
||||
*/
|
||||
@Test
|
||||
public void testFileAlreadyExsists() throws Exception {
|
||||
void testFileAlreadyExsists() throws Exception {
|
||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||
String file = Files.createFile(genOutputPath("txt")).toString();
|
||||
assertThrows(FileAlreadyExistsException.class,
|
||||
@ -163,7 +163,7 @@ public class DumpThreads {
|
||||
* Test that dumpThreads throws if the file path is relative.
|
||||
*/
|
||||
@Test
|
||||
public void testRelativePath() throws Exception {
|
||||
void testRelativePath() throws Exception {
|
||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> mbean.dumpThreads("threads.txt", ThreadDumpFormat.TEXT_PLAIN));
|
||||
@ -175,7 +175,7 @@ public class DumpThreads {
|
||||
* Test that dumpThreads throws with null parameters.
|
||||
*/
|
||||
@Test
|
||||
public void testNull() throws Exception {
|
||||
void testNull() throws Exception {
|
||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> mbean.dumpThreads(null, ThreadDumpFormat.TEXT_PLAIN));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,7 @@
|
||||
* @test
|
||||
* @summary Unit test for Thread.Builder
|
||||
* @enablePreview
|
||||
* @run testng BuilderTest
|
||||
* @run junit BuilderTest
|
||||
*/
|
||||
|
||||
import java.util.concurrent.*;
|
||||
@ -33,17 +33,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assumptions.*;
|
||||
|
||||
public class BuilderTest {
|
||||
class BuilderTest {
|
||||
|
||||
/**
|
||||
* Test Thread.ofPlatform to create platform threads.
|
||||
*/
|
||||
@Test
|
||||
public void testPlatformThread() throws Exception {
|
||||
void testPlatformThread() throws Exception {
|
||||
Thread parent = Thread.currentThread();
|
||||
Thread.Builder.OfPlatform builder = Thread.ofPlatform();
|
||||
|
||||
@ -94,7 +94,7 @@ public class BuilderTest {
|
||||
* Test Thread.ofVirtual to create virtual threads.
|
||||
*/
|
||||
@Test
|
||||
public void testVirtualThread() throws Exception {
|
||||
void testVirtualThread() throws Exception {
|
||||
Thread parent = Thread.currentThread();
|
||||
Thread.Builder.OfVirtual builder = Thread.ofVirtual();
|
||||
|
||||
@ -141,7 +141,7 @@ public class BuilderTest {
|
||||
* Test Thread.Builder.name.
|
||||
*/
|
||||
@Test
|
||||
public void testName1() {
|
||||
void testName1() {
|
||||
Thread.Builder builder = Thread.ofPlatform().name("duke");
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -154,7 +154,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName2() {
|
||||
void testName2() {
|
||||
Thread.Builder builder = Thread.ofVirtual().name("duke");
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -167,7 +167,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName3() {
|
||||
void testName3() {
|
||||
Thread.Builder builder = Thread.ofPlatform().name("duke-", 100);
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -189,7 +189,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName4() {
|
||||
void testName4() {
|
||||
Thread.Builder builder = Thread.ofVirtual().name("duke-", 100);
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -214,7 +214,7 @@ public class BuilderTest {
|
||||
* Test Thread.Builder.OfPlatform.group.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadGroup1() {
|
||||
void testThreadGroup1() {
|
||||
ThreadGroup group = new ThreadGroup("groupies");
|
||||
Thread.Builder builder = Thread.ofPlatform().group(group);
|
||||
|
||||
@ -240,9 +240,9 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadGroup2() {
|
||||
void testThreadGroup2() {
|
||||
ThreadGroup vgroup = Thread.ofVirtual().unstarted(() -> { }).getThreadGroup();
|
||||
assertEquals(vgroup.getName(), "VirtualThreads");
|
||||
assertEquals("VirtualThreads", vgroup.getName());
|
||||
|
||||
Thread thread1 = Thread.ofVirtual().unstarted(() -> { });
|
||||
Thread thread2 = Thread.ofVirtual().start(LockSupport::park);
|
||||
@ -261,7 +261,7 @@ public class BuilderTest {
|
||||
* Test Thread.Builder.OfPlatform.priority.
|
||||
*/
|
||||
@Test
|
||||
public void testPriority1() {
|
||||
void testPriority1() {
|
||||
int priority = Thread.currentThread().getPriority();
|
||||
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
@ -275,7 +275,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriority2() {
|
||||
void testPriority2() {
|
||||
int priority = Thread.MIN_PRIORITY;
|
||||
|
||||
Thread.Builder builder = Thread.ofPlatform().priority(priority);
|
||||
@ -289,10 +289,9 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriority3() {
|
||||
void testPriority3() {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
if (currentThread.isVirtual())
|
||||
throw new SkipException("Main test is a virtual thread");
|
||||
assumeFalse(currentThread.isVirtual(), "Main thread is a virtual thread");
|
||||
|
||||
int maxPriority = currentThread.getThreadGroup().getMaxPriority();
|
||||
int priority = Math.min(maxPriority + 1, Thread.MAX_PRIORITY);
|
||||
@ -308,14 +307,14 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriority4() {
|
||||
void testPriority4() {
|
||||
var builder = Thread.ofPlatform();
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> builder.priority(Thread.MIN_PRIORITY - 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriority5() {
|
||||
void testPriority5() {
|
||||
var builder = Thread.ofPlatform();
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> builder.priority(Thread.MAX_PRIORITY + 1));
|
||||
@ -325,7 +324,7 @@ public class BuilderTest {
|
||||
* Test Thread.Builder.OfPlatform.daemon.
|
||||
*/
|
||||
@Test
|
||||
public void testDaemon1() {
|
||||
void testDaemon1() {
|
||||
Thread.Builder builder = Thread.ofPlatform().daemon(false);
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -338,7 +337,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDaemon2() {
|
||||
void testDaemon2() {
|
||||
Thread.Builder builder = Thread.ofPlatform().daemon(true);
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -351,7 +350,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDaemon3() {
|
||||
void testDaemon3() {
|
||||
Thread.Builder builder = Thread.ofPlatform().daemon();
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -364,7 +363,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDaemon4() {
|
||||
void testDaemon4() {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -382,7 +381,7 @@ public class BuilderTest {
|
||||
* Test Thread.ofVirtual creates daemon threads.
|
||||
*/
|
||||
@Test
|
||||
public void testDaemon5() {
|
||||
void testDaemon5() {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
@ -399,7 +398,7 @@ public class BuilderTest {
|
||||
* Test Thread.Builder.OfPlatform.stackSize.
|
||||
*/
|
||||
@Test
|
||||
public void testStackSize1() {
|
||||
void testStackSize1() {
|
||||
Thread.Builder builder = Thread.ofPlatform().stackSize(1024*1024);
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
Thread thread2 = builder.start(() -> { });
|
||||
@ -407,7 +406,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackSize2() {
|
||||
void testStackSize2() {
|
||||
Thread.Builder builder = Thread.ofPlatform().stackSize(0);
|
||||
Thread thread1 = builder.unstarted(() -> { });
|
||||
Thread thread2 = builder.start(() -> { });
|
||||
@ -415,7 +414,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackSize3() {
|
||||
void testStackSize3() {
|
||||
var builder = Thread.ofPlatform();
|
||||
assertThrows(IllegalArgumentException.class, () -> builder.stackSize(-1));
|
||||
}
|
||||
@ -424,7 +423,7 @@ public class BuilderTest {
|
||||
* Test Thread.Builder.uncaughtExceptionHandler.
|
||||
*/
|
||||
@Test
|
||||
public void testUncaughtExceptionHandler1() throws Exception {
|
||||
void testUncaughtExceptionHandler1() throws Exception {
|
||||
class FooException extends RuntimeException { }
|
||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||
@ -441,7 +440,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUncaughtExceptionHandler2() throws Exception {
|
||||
void testUncaughtExceptionHandler2() throws Exception {
|
||||
class FooException extends RuntimeException { }
|
||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||
@ -458,7 +457,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUncaughtExceptionHandler3() throws Exception {
|
||||
void testUncaughtExceptionHandler3() throws Exception {
|
||||
class FooException extends RuntimeException { }
|
||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||
@ -477,7 +476,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUncaughtExceptionHandler4() throws Exception {
|
||||
void testUncaughtExceptionHandler4() throws Exception {
|
||||
class FooException extends RuntimeException { }
|
||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||
@ -563,13 +562,13 @@ public class BuilderTest {
|
||||
* Test Thread.Builder creates threads that allow thread locals.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadLocals1() throws Exception {
|
||||
void testThreadLocals1() throws Exception {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
testThreadLocals(builder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadLocals2() throws Exception {
|
||||
void testThreadLocals2() throws Exception {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
testThreadLocals(builder);
|
||||
}
|
||||
@ -579,7 +578,7 @@ public class BuilderTest {
|
||||
* thread locals.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadLocals3() throws Exception {
|
||||
void testThreadLocals3() throws Exception {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
|
||||
// disallow
|
||||
@ -592,7 +591,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadLocals4() throws Exception {
|
||||
void testThreadLocals4() throws Exception {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
|
||||
// disallow
|
||||
@ -646,7 +645,7 @@ public class BuilderTest {
|
||||
|
||||
AtomicBoolean done = new AtomicBoolean();
|
||||
Runnable task = () -> {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
done.set(true);
|
||||
};
|
||||
|
||||
@ -673,7 +672,7 @@ public class BuilderTest {
|
||||
* the initial values of inheritable thread locals.
|
||||
*/
|
||||
@Test
|
||||
public void testInheritedThreadLocals1() throws Exception {
|
||||
void testInheritedThreadLocals1() throws Exception {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
testInheritedThreadLocals(builder); // default
|
||||
|
||||
@ -687,7 +686,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInheritedThreadLocals2() throws Exception {
|
||||
void testInheritedThreadLocals2() throws Exception {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
testInheritedThreadLocals(builder); // default
|
||||
|
||||
@ -701,7 +700,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInheritedThreadLocals3() throws Exception {
|
||||
void testInheritedThreadLocals3() throws Exception {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
|
||||
// thread locals not allowed
|
||||
@ -721,7 +720,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInheritedThreadLocals4() throws Exception {
|
||||
void testInheritedThreadLocals4() throws Exception {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
|
||||
// thread locals not allowed
|
||||
@ -824,7 +823,7 @@ public class BuilderTest {
|
||||
* the thread context class loader.
|
||||
*/
|
||||
@Test
|
||||
public void testContextClassLoader1() throws Exception {
|
||||
void testContextClassLoader1() throws Exception {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
testInheritContextClassLoader(builder); // default
|
||||
|
||||
@ -838,7 +837,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextClassLoader2() throws Exception {
|
||||
void testContextClassLoader2() throws Exception {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
testInheritContextClassLoader(builder); // default
|
||||
|
||||
@ -852,7 +851,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextClassLoader3() throws Exception {
|
||||
void testContextClassLoader3() throws Exception {
|
||||
Thread.Builder builder = Thread.ofPlatform();
|
||||
|
||||
// thread locals not allowed
|
||||
@ -872,7 +871,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextClassLoader4() throws Exception {
|
||||
void testContextClassLoader4() throws Exception {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
|
||||
// thread locals not allowed
|
||||
@ -895,7 +894,7 @@ public class BuilderTest {
|
||||
* Test NullPointerException.
|
||||
*/
|
||||
@Test
|
||||
public void testNulls1() {
|
||||
void testNulls1() {
|
||||
Thread.Builder.OfPlatform builder = Thread.ofPlatform();
|
||||
assertThrows(NullPointerException.class, () -> builder.group(null));
|
||||
assertThrows(NullPointerException.class, () -> builder.name(null));
|
||||
@ -906,7 +905,7 @@ public class BuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNulls2() {
|
||||
void testNulls2() {
|
||||
Thread.Builder builder = Thread.ofVirtual();
|
||||
assertThrows(NullPointerException.class, () -> builder.name(null));
|
||||
assertThrows(NullPointerException.class, () -> builder.name(null, 0));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,22 +24,22 @@
|
||||
/**
|
||||
* @test
|
||||
* @summary Test Thread.join(Duration)
|
||||
* @run testng JoinWithDuration
|
||||
* @run junit JoinWithDuration
|
||||
*/
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class JoinWithDuration {
|
||||
class JoinWithDuration {
|
||||
/**
|
||||
* Test join on unstarted thread.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinOnUnstartedThread() {
|
||||
void testJoinOnUnstartedThread() {
|
||||
var thread = new Thread(() -> { });
|
||||
assertThrows(IllegalThreadStateException.class,
|
||||
() -> thread.join(Duration.ofNanos(-100)));
|
||||
@ -53,7 +53,7 @@ public class JoinWithDuration {
|
||||
* Test join on thread that does not terminate while waiting.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinOnRunningThread() throws Exception {
|
||||
void testJoinOnRunningThread() throws Exception {
|
||||
var thread = new Thread(LockSupport::park);
|
||||
thread.start();
|
||||
try {
|
||||
@ -76,7 +76,7 @@ public class JoinWithDuration {
|
||||
* Test join on thread that terminates while waiting.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinOnTerminatingThread() throws Exception {
|
||||
void testJoinOnTerminatingThread() throws Exception {
|
||||
var thread = new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
@ -90,7 +90,7 @@ public class JoinWithDuration {
|
||||
* Test join on terminated thread.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinOnTerminatedThread() throws Exception {
|
||||
void testJoinOnTerminatedThread() throws Exception {
|
||||
var thread = new Thread(() -> { });
|
||||
thread.start();
|
||||
thread.join();
|
||||
@ -103,7 +103,7 @@ public class JoinWithDuration {
|
||||
* Test invoking join with interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinWithInterruptStatusSet() throws Exception {
|
||||
void testJoinWithInterruptStatusSet() throws Exception {
|
||||
var thread = new Thread(LockSupport::park);
|
||||
thread.start();
|
||||
Thread.currentThread().interrupt();
|
||||
@ -122,8 +122,8 @@ public class JoinWithDuration {
|
||||
* Test interrupting join.
|
||||
*/
|
||||
@Test
|
||||
public void testInterruptJoin() throws Exception {
|
||||
// schedule current thread to interrupted after 1s
|
||||
void testInterruptJoin() throws Exception {
|
||||
// schedule current thread to be interrupted after 1s
|
||||
Thread targetThread = Thread.currentThread();
|
||||
Thread wakerThread = new Thread(() -> {
|
||||
try {
|
||||
@ -144,7 +144,9 @@ public class JoinWithDuration {
|
||||
// interrupt status should be cleared
|
||||
assertFalse(thread.isInterrupted());
|
||||
} finally {
|
||||
wakerThread.interrupt();
|
||||
LockSupport.unpark(thread);
|
||||
thread.join();
|
||||
wakerThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +154,7 @@ public class JoinWithDuration {
|
||||
* Test join on current thread.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinSelf() throws Exception {
|
||||
void testJoinSelf() throws Exception {
|
||||
Thread thread = Thread.currentThread();
|
||||
|
||||
assertFalse(thread.join(Duration.ofNanos(-100)));
|
||||
@ -169,7 +171,7 @@ public class JoinWithDuration {
|
||||
* Test join(null).
|
||||
*/
|
||||
@Test
|
||||
public void testJoinNull() throws Exception {
|
||||
void testJoinNull() throws Exception {
|
||||
var thread = new Thread(LockSupport::park);
|
||||
|
||||
// unstarted
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,22 +24,22 @@
|
||||
/**
|
||||
* @test
|
||||
* @summary Test Thread.sleep(Duration)
|
||||
* @run testng SleepWithDuration
|
||||
* @run junit SleepWithDuration
|
||||
*/
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class SleepWithDuration {
|
||||
class SleepWithDuration {
|
||||
|
||||
/**
|
||||
* Basic test for sleep(Duration).
|
||||
*/
|
||||
@Test
|
||||
public void testSleep() throws Exception {
|
||||
void testSleep() throws Exception {
|
||||
// sleep for 2 seconds
|
||||
long start = millisTime();
|
||||
Thread.sleep(Duration.ofMillis(2000));
|
||||
@ -56,7 +56,7 @@ public class SleepWithDuration {
|
||||
* Test Thread.sleep with interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testSleepWithInterruptStatusSet() throws Exception {
|
||||
void testSleepWithInterruptStatusSet() throws Exception {
|
||||
Thread.currentThread().interrupt();
|
||||
try {
|
||||
Thread.sleep(Duration.ofNanos(0));
|
||||
@ -78,8 +78,8 @@ public class SleepWithDuration {
|
||||
* Test interrupting Thread.sleep.
|
||||
*/
|
||||
@Test
|
||||
public void testInterruptSleep() throws Exception {
|
||||
// schedule current thread to interrupted after 1s
|
||||
void testInterruptSleep() throws Exception {
|
||||
// schedule current thread to be interrupted after 1s
|
||||
Thread targetThread = Thread.currentThread();
|
||||
Thread wakerThread = new Thread(() -> {
|
||||
try {
|
||||
@ -97,7 +97,7 @@ public class SleepWithDuration {
|
||||
// interrupt status should be cleared
|
||||
assertFalse(Thread.interrupted());
|
||||
} finally {
|
||||
wakerThread.interrupt();
|
||||
wakerThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,10 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
import static java.lang.System.err;
|
||||
import static java.lang.System.out;
|
||||
@ -36,35 +40,50 @@ import static java.lang.System.out;
|
||||
* @author Martin Buchholz
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.process.*
|
||||
* @run testng UncaughtExceptionsTest
|
||||
* @run junit UncaughtExceptionsTest
|
||||
*/
|
||||
public class UncaughtExceptionsTest {
|
||||
class UncaughtExceptionsTest {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] testCases() {
|
||||
return new Object[][] {
|
||||
new Object[] { "ThreadIsDeadAfterJoin",
|
||||
0,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
"Exception in thread \"Thread-\\d+\".*simulateUncaughtExitEvent"
|
||||
},
|
||||
new Object[] {
|
||||
"MainThreadAbruptTermination",
|
||||
1,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
"Exception in thread \"main\".*simulateUncaughtExitEvent"
|
||||
},
|
||||
new Object[] { "MainThreadNormalTermination", 0, UncaughtExitSimulator.EXPECTED_RESULT, ""},
|
||||
new Object[] { "DefaultUncaughtExceptionHandlerOnMainThread", 1, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
||||
new Object[] { "DefaultUncaughtExceptionHandlerOnMainThreadOverride", 1, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
||||
new Object[] { "DefaultUncaughtExceptionHandlerOnNonMainThreadOverride", 0, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
||||
new Object[] { "DefaultUncaughtExceptionHandlerOnNonMainThread", 0, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
||||
new Object[] { "ThreadGroupUncaughtExceptionHandlerOnNonMainThread", 0, UncaughtExitSimulator.EXPECTED_RESULT, "" }
|
||||
};
|
||||
private static Stream<Arguments> testCases() {
|
||||
return Stream.of(
|
||||
Arguments.of("ThreadIsDeadAfterJoin",
|
||||
0,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
"Exception in thread \"Thread-\\d+\".*simulateUncaughtExitEvent"),
|
||||
Arguments.of("MainThreadAbruptTermination",
|
||||
1,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
"Exception in thread \"main\".*simulateUncaughtExitEvent"),
|
||||
Arguments.of("MainThreadNormalTermination",
|
||||
0,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
""),
|
||||
Arguments.of("DefaultUncaughtExceptionHandlerOnMainThread",
|
||||
1,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
""),
|
||||
Arguments.of("DefaultUncaughtExceptionHandlerOnMainThreadOverride",
|
||||
1,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
""),
|
||||
Arguments.of("DefaultUncaughtExceptionHandlerOnNonMainThreadOverride",
|
||||
0,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
""),
|
||||
Arguments.of("DefaultUncaughtExceptionHandlerOnNonMainThread",
|
||||
0,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
""),
|
||||
Arguments.of("ThreadGroupUncaughtExceptionHandlerOnNonMainThread",
|
||||
0,
|
||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||
"")
|
||||
);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "testCases")
|
||||
public void test(String className, int exitValue, String stdOutMatch, String stdErrMatch) throws Throwable {
|
||||
@ParameterizedTest
|
||||
@MethodSource("testCases")
|
||||
void test(String className, int exitValue, String stdOutMatch, String stdErrMatch) throws Throwable {
|
||||
String cmd = "UncaughtExitSimulator$" + className;
|
||||
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(cmd);
|
||||
OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(processBuilder);
|
||||
@ -91,7 +110,9 @@ class UncaughtExitSimulator extends Thread implements Runnable {
|
||||
|
||||
final static String EXPECTED_RESULT = "OK";
|
||||
|
||||
public static void throwRuntimeException() { throw new RuntimeException("simulateUncaughtExitEvent"); }
|
||||
public static void throwRuntimeException() {
|
||||
throw new RuntimeException("simulateUncaughtExitEvent");
|
||||
}
|
||||
|
||||
public void run() { throwRuntimeException(); }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,22 +25,22 @@
|
||||
* @test
|
||||
* @summary Test that virtual threads are GC'ed
|
||||
* @enablePreview
|
||||
* @run testng Collectable
|
||||
* @run junit Collectable
|
||||
*/
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class Collectable {
|
||||
class Collectable {
|
||||
|
||||
/**
|
||||
* Test that an unstarted virtual thread can be GC"ed.
|
||||
*/
|
||||
@Test
|
||||
public void testUnstartedThread() {
|
||||
void testUnstartedThread() {
|
||||
var thread = Thread.ofVirtual().unstarted(() -> { });
|
||||
var ref = new WeakReference<>(thread);
|
||||
thread = null;
|
||||
@ -51,7 +51,7 @@ public class Collectable {
|
||||
* Test that a terminated virtual thread can be GC'ed.
|
||||
*/
|
||||
@Test
|
||||
public void testTerminatedThread() throws Exception {
|
||||
void testTerminatedThread() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> { });
|
||||
thread.join();
|
||||
var ref = new WeakReference<>(thread);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @requires vm.continuations
|
||||
* @modules java.base/java.lang:+open
|
||||
* @enablePreview
|
||||
* @run testng CustomScheduler
|
||||
* @run junit CustomScheduler
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@ -39,57 +39,57 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assumptions.*;
|
||||
|
||||
public class CustomScheduler {
|
||||
class CustomScheduler {
|
||||
private static final Executor DEFAULT_SCHEDULER = defaultScheduler();
|
||||
private static ExecutorService SCHEDULER_1;
|
||||
private static ExecutorService SCHEDULER_2;
|
||||
private static ExecutorService scheduler1;
|
||||
private static ExecutorService scheduler2;
|
||||
|
||||
@BeforeClass
|
||||
public void setup() {
|
||||
SCHEDULER_1 = Executors.newFixedThreadPool(1);
|
||||
SCHEDULER_2 = Executors.newFixedThreadPool(1);
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
scheduler1 = Executors.newFixedThreadPool(1);
|
||||
scheduler2 = Executors.newFixedThreadPool(1);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void shutdown() {
|
||||
SCHEDULER_1.shutdown();
|
||||
SCHEDULER_2.shutdown();
|
||||
@AfterAll
|
||||
static void shutdown() {
|
||||
scheduler1.shutdown();
|
||||
scheduler2.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test platform thread creating a virtual thread that uses a custom scheduler.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomScheduler1() throws Exception {
|
||||
void testCustomScheduler1() throws Exception {
|
||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
||||
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||
ref.set(scheduler(Thread.currentThread()));
|
||||
}).join();
|
||||
assertTrue(ref.get() == SCHEDULER_1);
|
||||
assertTrue(ref.get() == scheduler1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test virtual thread creating a virtual thread that uses a custom scheduler.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomScheduler2() throws Exception {
|
||||
void testCustomScheduler2() throws Exception {
|
||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||
Thread.ofVirtual().start(() -> {
|
||||
try {
|
||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
||||
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||
ref.set(scheduler(Thread.currentThread()));
|
||||
}).join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).join();
|
||||
assertTrue(ref.get() == SCHEDULER_1);
|
||||
assertTrue(ref.get() == scheduler1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,9 +97,9 @@ public class CustomScheduler {
|
||||
* The scheduler should be inherited.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomScheduler3() throws Exception {
|
||||
void testCustomScheduler3() throws Exception {
|
||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
||||
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||
try {
|
||||
Thread.ofVirtual().start(() -> {
|
||||
ref.set(scheduler(Thread.currentThread()));
|
||||
@ -108,7 +108,7 @@ public class CustomScheduler {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).join();
|
||||
assertTrue(ref.get() == SCHEDULER_1);
|
||||
assertTrue(ref.get() == scheduler1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,25 +116,25 @@ public class CustomScheduler {
|
||||
* that uses a different custom scheduler.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomScheduler4() throws Exception {
|
||||
void testCustomScheduler4() throws Exception {
|
||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
||||
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||
try {
|
||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_2).start(() -> {
|
||||
ThreadBuilders.virtualThreadBuilder(scheduler2).start(() -> {
|
||||
ref.set(scheduler(Thread.currentThread()));
|
||||
}).join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).join();
|
||||
assertTrue(ref.get() == SCHEDULER_2);
|
||||
assertTrue(ref.get() == scheduler2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test running task on a virtual thread, should thrown WrongThreadException.
|
||||
*/
|
||||
@Test
|
||||
public void testBadCarrier() {
|
||||
void testBadCarrier() {
|
||||
Executor scheduler = (task) -> {
|
||||
var exc = new AtomicReference<Throwable>();
|
||||
try {
|
||||
@ -160,10 +160,9 @@ public class CustomScheduler {
|
||||
* carrier thread when the task completes.
|
||||
*/
|
||||
@Test
|
||||
public void testParkWithInterruptSet() {
|
||||
void testParkWithInterruptSet() {
|
||||
Thread carrier = Thread.currentThread();
|
||||
if (carrier.isVirtual())
|
||||
throw new SkipException("Main test is a virtual thread");
|
||||
assumeFalse(carrier.isVirtual(), "Main thread is a virtual thread");
|
||||
try {
|
||||
var builder = ThreadBuilders.virtualThreadBuilder(Runnable::run);
|
||||
Thread vthread = builder.start(() -> {
|
||||
@ -182,10 +181,9 @@ public class CustomScheduler {
|
||||
* the carrier thread when the task completes.
|
||||
*/
|
||||
@Test
|
||||
public void testTerminateWithInterruptSet() {
|
||||
void testTerminateWithInterruptSet() {
|
||||
Thread carrier = Thread.currentThread();
|
||||
if (carrier.isVirtual())
|
||||
throw new SkipException("Main test is a virtual thread");
|
||||
assumeFalse(carrier.isVirtual(), "Main thread is a virtual thread");
|
||||
try {
|
||||
var builder = ThreadBuilders.virtualThreadBuilder(Runnable::run);
|
||||
Thread vthread = builder.start(() -> {
|
||||
@ -202,9 +200,8 @@ public class CustomScheduler {
|
||||
* Test running task with the carrier interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testRunWithInterruptSet() throws Exception {
|
||||
if (Thread.currentThread().isVirtual())
|
||||
throw new SkipException("Main test is a virtual thread");
|
||||
void testRunWithInterruptSet() throws Exception {
|
||||
assumeFalse(Thread.currentThread().isVirtual(), "Main thread is a virtual thread");
|
||||
Executor scheduler = (task) -> {
|
||||
Thread.currentThread().interrupt();
|
||||
task.run();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,9 +25,10 @@
|
||||
* @test
|
||||
* @summary Test Thread.getStackTrace to examine the stack trace of a virtual
|
||||
* thread and its carrier
|
||||
* @modules java.base/java.lang:+open
|
||||
* @requires vm.continuations
|
||||
* @enablePreview
|
||||
* @run testng GetStackTrace
|
||||
* @modules java.base/java.lang:+open
|
||||
* @run main GetStackTrace
|
||||
*/
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @requires vm.continuations
|
||||
* @modules java.base/java.lang:+open
|
||||
* @enablePreview
|
||||
* @run testng HoldsLock
|
||||
* @run junit HoldsLock
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -36,7 +36,7 @@
|
||||
* @requires vm.continuations & vm.debug
|
||||
* @modules java.base/java.lang:+open
|
||||
* @enablePreview
|
||||
* @run testng/othervm -XX:+UseHeavyMonitors HoldsLock
|
||||
* @run junit/othervm -XX:+UseHeavyMonitors HoldsLock
|
||||
*/
|
||||
|
||||
import java.lang.management.LockInfo;
|
||||
@ -52,15 +52,17 @@ import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class HoldsLock {
|
||||
class HoldsLock {
|
||||
static final Object LOCK1 = new Object();
|
||||
static final Object LOCK2 = new Object();
|
||||
|
||||
@Test(enabled=false) // JDK-8281642
|
||||
public void testHoldsLock() throws Exception {
|
||||
@Disabled("JDK-8281642")
|
||||
@Test
|
||||
void testHoldsLock() throws Exception {
|
||||
var q = new ArrayBlockingQueue<Runnable>(5);
|
||||
|
||||
Thread carrier = Thread.ofPlatform().start(() -> {
|
||||
@ -85,7 +87,7 @@ public class HoldsLock {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadInfo() throws Exception {
|
||||
void testThreadInfo() throws Exception {
|
||||
var q = new ArrayBlockingQueue<Runnable>(5);
|
||||
|
||||
Thread carrier = spawnCarrier(q);
|
||||
@ -123,10 +125,10 @@ public class HoldsLock {
|
||||
|
||||
if (tid == carrierId) {
|
||||
// Carrier is WAITING on vthread
|
||||
assertEquals(info.getThreadState(), Thread.State.WAITING);
|
||||
assertEquals(info.getLockInfo().getClassName(), vthread.getClass().getName());
|
||||
assertEquals(info.getLockInfo().getIdentityHashCode(), System.identityHashCode(vthread));
|
||||
assertEquals(info.getLockOwnerId(), vthreadId);
|
||||
assertTrue(info.getThreadState() == Thread.State.WAITING);
|
||||
assertEquals(vthread.getClass().getName(), info.getLockInfo().getClassName());
|
||||
assertTrue(info.getLockInfo().getIdentityHashCode() == System.identityHashCode(vthread));
|
||||
assertTrue(info.getLockOwnerId() == vthreadId);
|
||||
foundCarrier = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @requires vm.continuations
|
||||
* @modules jdk.jfr java.base/java.lang:+open
|
||||
* @enablePreview
|
||||
* @run testng/othervm JfrEvents
|
||||
* @run junit/othervm JfrEvents
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
@ -48,17 +48,17 @@ import jdk.jfr.Recording;
|
||||
import jdk.jfr.consumer.RecordedEvent;
|
||||
import jdk.jfr.consumer.RecordingFile;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class JfrEvents {
|
||||
class JfrEvents {
|
||||
private static final Object lock = new Object();
|
||||
|
||||
/**
|
||||
* Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events.
|
||||
*/
|
||||
@Test
|
||||
public void testVirtualThreadStartAndEnd() throws Exception {
|
||||
void testVirtualThreadStartAndEnd() throws Exception {
|
||||
try (Recording recording = new Recording()) {
|
||||
recording.enable("jdk.VirtualThreadStart");
|
||||
recording.enable("jdk.VirtualThreadEnd");
|
||||
@ -89,7 +89,7 @@ public class JfrEvents {
|
||||
* Test jdk.VirtualThreadPinned event.
|
||||
*/
|
||||
@Test
|
||||
public void testVirtualThreadPinned() throws Exception {
|
||||
void testVirtualThreadPinned() throws Exception {
|
||||
try (Recording recording = new Recording()) {
|
||||
recording.enable("jdk.VirtualThreadPinned")
|
||||
.withThreshold(Duration.ofMillis(500));
|
||||
@ -126,7 +126,7 @@ public class JfrEvents {
|
||||
* Test jdk.VirtualThreadSubmitFailed event.
|
||||
*/
|
||||
@Test
|
||||
public void testVirtualThreadSubmitFailed() throws Exception {
|
||||
void testVirtualThreadSubmitFailed() throws Exception {
|
||||
try (Recording recording = new Recording()) {
|
||||
recording.enable("jdk.VirtualThreadSubmitFailed");
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
* @summary Test virtual threads using java.util.concurrent locks
|
||||
* @library /test/lib
|
||||
* @enablePreview
|
||||
* @run testng Locking
|
||||
* @run junit Locking
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -34,16 +34,16 @@ import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class Locking {
|
||||
class Locking {
|
||||
|
||||
/**
|
||||
* Test lock/unlock.
|
||||
*/
|
||||
@Test
|
||||
public void testReentrantLock1() throws Exception {
|
||||
void testReentrantLock1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
assertFalse(lock.isHeldByCurrentThread());
|
||||
@ -58,7 +58,7 @@ public class Locking {
|
||||
* Test tryLock/unlock.
|
||||
*/
|
||||
@Test
|
||||
public void testReentrantLock2() throws Exception {
|
||||
void testReentrantLock2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
assertFalse(lock.isHeldByCurrentThread());
|
||||
@ -74,7 +74,7 @@ public class Locking {
|
||||
* Test lock/lock/unlock/unlock.
|
||||
*/
|
||||
@Test
|
||||
public void testReentrantLock3() throws Exception {
|
||||
void testReentrantLock3() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
assertFalse(lock.isHeldByCurrentThread());
|
||||
@ -98,7 +98,7 @@ public class Locking {
|
||||
* Test locked by platform thread, virtual thread tries to lock.
|
||||
*/
|
||||
@Test
|
||||
public void testReentrantLock4() throws Exception {
|
||||
void testReentrantLock4() throws Exception {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
var holdsLock = new AtomicBoolean();
|
||||
|
||||
@ -136,7 +136,7 @@ public class Locking {
|
||||
* Test locked by virtual thread, platform thread tries to lock.
|
||||
*/
|
||||
@Test
|
||||
public void testReentrantLock5() throws Exception {
|
||||
void testReentrantLock5() throws Exception {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
lock.lock();
|
||||
@ -170,7 +170,7 @@ public class Locking {
|
||||
* Test locked by virtual thread, another virtual thread tries to lock.
|
||||
*/
|
||||
@Test
|
||||
public void testReentrantLock6() throws Exception {
|
||||
void testReentrantLock6() throws Exception {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
var thread1 = Thread.ofVirtual().start(() -> {
|
||||
lock.lock();
|
||||
|
@ -27,17 +27,15 @@
|
||||
* @requires vm.continuations
|
||||
* @modules java.base/java.lang:+open
|
||||
* @enablePreview
|
||||
* @run testng ParkWithFixedThreadPool
|
||||
* @run main ParkWithFixedThreadPool
|
||||
*/
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import static org.testng.Assert.*;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class ParkWithFixedThreadPool {
|
||||
@Test
|
||||
public static void multipleThreadPoolParkTest() throws Exception {
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (ExecutorService scheduler = Executors.newFixedThreadPool(8)) {
|
||||
int vthreadCount = 300;
|
||||
Thread[] vthreads = new Thread[vthreadCount];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
* @summary Test virtual threads using park/unpark
|
||||
* @library /test/lib
|
||||
* @enablePreview
|
||||
* @run testng Parking
|
||||
* @run junit Parking
|
||||
*/
|
||||
|
||||
import java.time.Duration;
|
||||
@ -34,18 +34,17 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class Parking {
|
||||
class Parking {
|
||||
private static final Object lock = new Object();
|
||||
|
||||
/**
|
||||
* Park, unparked by platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testPark1() throws Exception {
|
||||
void testPark1() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(LockSupport::park);
|
||||
Thread.sleep(1000); // give time for virtual thread to park
|
||||
LockSupport.unpark(thread);
|
||||
@ -56,7 +55,7 @@ public class Parking {
|
||||
* Park, unparked by virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testPark2() throws Exception {
|
||||
void testPark2() throws Exception {
|
||||
var thread1 = Thread.ofVirtual().start(LockSupport::park);
|
||||
Thread.sleep(1000); // give time for virtual thread to park
|
||||
var thread2 = Thread.ofVirtual().start(() -> LockSupport.unpark(thread1));
|
||||
@ -68,7 +67,7 @@ public class Parking {
|
||||
* Park while holding monitor, unparked by platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testPark3() throws Exception {
|
||||
void testPark3() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
synchronized (lock) {
|
||||
LockSupport.park();
|
||||
@ -83,15 +82,15 @@ public class Parking {
|
||||
* Park with native frame on stack.
|
||||
*/
|
||||
@Test
|
||||
public void testPark4() throws Exception {
|
||||
throw new SkipException("Not implemented");
|
||||
void testPark4() throws Exception {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpark before park.
|
||||
*/
|
||||
@Test
|
||||
public void testPark5() throws Exception {
|
||||
void testPark5() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
LockSupport.unpark(Thread.currentThread());
|
||||
LockSupport.park();
|
||||
@ -103,7 +102,7 @@ public class Parking {
|
||||
* 2 x unpark before park.
|
||||
*/
|
||||
@Test
|
||||
public void testPark6() throws Exception {
|
||||
void testPark6() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
Thread me = Thread.currentThread();
|
||||
LockSupport.unpark(me);
|
||||
@ -120,7 +119,7 @@ public class Parking {
|
||||
* 2 x park and unpark by platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testPark7() throws Exception {
|
||||
void testPark7() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
LockSupport.park();
|
||||
LockSupport.park();
|
||||
@ -142,7 +141,7 @@ public class Parking {
|
||||
* Park with interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testPark8() throws Exception {
|
||||
void testPark8() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
t.interrupt();
|
||||
@ -155,7 +154,7 @@ public class Parking {
|
||||
* Thread interrupt when parked.
|
||||
*/
|
||||
@Test
|
||||
public void testPark9() throws Exception {
|
||||
void testPark9() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
scheduleInterrupt(t, 1000);
|
||||
@ -169,7 +168,7 @@ public class Parking {
|
||||
* Park while holding monitor and with interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testPark10() throws Exception {
|
||||
void testPark10() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
t.interrupt();
|
||||
@ -184,7 +183,7 @@ public class Parking {
|
||||
* Thread interrupt when parked while holding monitor
|
||||
*/
|
||||
@Test
|
||||
public void testPark11() throws Exception {
|
||||
void testPark11() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
scheduleInterrupt(t, 1000);
|
||||
@ -200,7 +199,7 @@ public class Parking {
|
||||
* parkNanos(-1) completes immediately
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos1() throws Exception {
|
||||
void testParkNanos1() throws Exception {
|
||||
VThreadRunner.run(() -> LockSupport.parkNanos(-1));
|
||||
}
|
||||
|
||||
@ -208,7 +207,7 @@ public class Parking {
|
||||
* parkNanos(0) completes immediately
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos2() throws Exception {
|
||||
void testParkNanos2() throws Exception {
|
||||
VThreadRunner.run(() -> LockSupport.parkNanos(0));
|
||||
}
|
||||
|
||||
@ -216,7 +215,7 @@ public class Parking {
|
||||
* parkNanos(1000ms) parks thread.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos3() throws Exception {
|
||||
void testParkNanos3() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
// park for 1000ms
|
||||
long nanos = TimeUnit.NANOSECONDS.convert(1000, TimeUnit.MILLISECONDS);
|
||||
@ -234,7 +233,7 @@ public class Parking {
|
||||
* Park with parkNanos, unparked by platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos4() throws Exception {
|
||||
void testParkNanos4() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
||||
LockSupport.parkNanos(nanos);
|
||||
@ -248,7 +247,7 @@ public class Parking {
|
||||
* Park with parkNanos, unparked by virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos5() throws Exception {
|
||||
void testParkNanos5() throws Exception {
|
||||
var thread1 = Thread.ofVirtual().start(() -> {
|
||||
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
||||
LockSupport.parkNanos(nanos);
|
||||
@ -263,7 +262,7 @@ public class Parking {
|
||||
* Unpark before parkNanos.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos6() throws Exception {
|
||||
void testParkNanos6() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
LockSupport.unpark(Thread.currentThread());
|
||||
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
||||
@ -275,7 +274,7 @@ public class Parking {
|
||||
* Unpark before parkNanos(0), should consume parking permit.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos7() throws Exception {
|
||||
void testParkNanos7() throws Exception {
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
LockSupport.unpark(Thread.currentThread());
|
||||
LockSupport.parkNanos(0); // should consume parking permit
|
||||
@ -291,7 +290,7 @@ public class Parking {
|
||||
* Park with parkNanos and interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos8() throws Exception {
|
||||
void testParkNanos8() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
t.interrupt();
|
||||
@ -304,7 +303,7 @@ public class Parking {
|
||||
* Thread interrupt when parked in parkNanos.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos9() throws Exception {
|
||||
void testParkNanos9() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
scheduleInterrupt(t, 1000);
|
||||
@ -318,7 +317,7 @@ public class Parking {
|
||||
* Park with parkNanos while holding monitor and with interrupt status set.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos10() throws Exception {
|
||||
void testParkNanos10() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
t.interrupt();
|
||||
@ -333,7 +332,7 @@ public class Parking {
|
||||
* Thread interrupt when parked in parkNanos and while holding monitor.
|
||||
*/
|
||||
@Test
|
||||
public void testParkNanos11() throws Exception {
|
||||
void testParkNanos11() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
scheduleInterrupt(t, 1000);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,25 +24,25 @@
|
||||
/**
|
||||
* @test
|
||||
* @summary Test that preview APIs throws exception when preview features not enabled
|
||||
* @run testng/othervm PreviewFeaturesNotEnabled
|
||||
* @run junit/othervm PreviewFeaturesNotEnabled
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class PreviewFeaturesNotEnabled {
|
||||
class PreviewFeaturesNotEnabled {
|
||||
|
||||
/**
|
||||
* Thread.ofVirtual should fail with UOE.
|
||||
*/
|
||||
@Test
|
||||
public void testOfVirtual() throws Exception {
|
||||
void testOfVirtual() throws Exception {
|
||||
Method ofVirtual = Thread.class.getDeclaredMethod("ofVirtual");
|
||||
var exc = expectThrows(InvocationTargetException.class, () -> ofVirtual.invoke(null));
|
||||
var exc = assertThrows(InvocationTargetException.class, () -> ofVirtual.invoke(null));
|
||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||
}
|
||||
|
||||
@ -50,10 +50,10 @@ public class PreviewFeaturesNotEnabled {
|
||||
* Thread.startVirtualThread should fail with UOE.
|
||||
*/
|
||||
@Test
|
||||
public void testStartVirutalThread() throws Exception {
|
||||
void testStartVirutalThread() throws Exception {
|
||||
Method startVirtualThread = Thread.class.getMethod("startVirtualThread", Runnable.class);
|
||||
Runnable task = () -> { };
|
||||
var exc = expectThrows(InvocationTargetException.class,
|
||||
var exc = assertThrows(InvocationTargetException.class,
|
||||
() -> startVirtualThread.invoke(null, task));
|
||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||
}
|
||||
@ -62,9 +62,9 @@ public class PreviewFeaturesNotEnabled {
|
||||
* Executors.newVirtualThreadPerTaskExecutor should fail with UOE.
|
||||
*/
|
||||
@Test
|
||||
public void testNewVirtualThreadPerTaskExecutor() throws Exception {
|
||||
void testNewVirtualThreadPerTaskExecutor() throws Exception {
|
||||
Method newVirtualThreadPerTaskExecutor = Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
|
||||
var exc = expectThrows(InvocationTargetException.class,
|
||||
var exc = assertThrows(InvocationTargetException.class,
|
||||
() -> newVirtualThreadPerTaskExecutor.invoke(null));
|
||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||
}
|
||||
@ -73,8 +73,8 @@ public class PreviewFeaturesNotEnabled {
|
||||
* Directly accessing internal Continuation class should fail with UOE.
|
||||
*/
|
||||
@Test
|
||||
public void testContinuationInitializer() throws Exception {
|
||||
var exc = expectThrows(ExceptionInInitializerError.class,
|
||||
void testContinuationInitializer() throws Exception {
|
||||
var exc = assertThrows(ExceptionInInitializerError.class,
|
||||
() -> Class.forName("jdk.internal.vm.Continuation"));
|
||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||
}
|
||||
@ -83,7 +83,7 @@ public class PreviewFeaturesNotEnabled {
|
||||
* Thread.isVirtual should not fail.
|
||||
*/
|
||||
@Test
|
||||
public void testIsVirtual() throws Exception {
|
||||
void testIsVirtual() throws Exception {
|
||||
boolean isVirtual = isVirtual(Thread.currentThread());
|
||||
assertFalse(isVirtual);
|
||||
}
|
||||
@ -92,7 +92,7 @@ public class PreviewFeaturesNotEnabled {
|
||||
* Thread.ofPlatform should not fail.
|
||||
*/
|
||||
@Test
|
||||
public void testOfPlatform() throws Exception {
|
||||
void testOfPlatform() throws Exception {
|
||||
Method ofPlatform = Thread.class.getDeclaredMethod("ofPlatform");
|
||||
Object builder = ofPlatform.invoke(null);
|
||||
Method startMethod = Class.forName("java.lang.Thread$Builder")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @modules java.base/java.lang:+open
|
||||
* @library /test/lib
|
||||
* @enablePreview
|
||||
* @run testng Reflection
|
||||
* @run junit Reflection
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
@ -39,17 +39,17 @@ import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assumptions.*;
|
||||
|
||||
public class Reflection {
|
||||
class Reflection {
|
||||
|
||||
/**
|
||||
* Test invoking static method.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeStatic1() throws Exception {
|
||||
void testInvokeStatic1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
int result = (int) divideMethod().invoke(null, 20, 2);
|
||||
assertTrue(result == 10);
|
||||
@ -61,7 +61,7 @@ public class Reflection {
|
||||
* exception.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeStatic2() throws Exception {
|
||||
void testInvokeStatic2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try {
|
||||
divideMethod().invoke(null, 20, 0);
|
||||
@ -77,7 +77,7 @@ public class Reflection {
|
||||
* method with bad parameters.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeStatic3() throws Exception {
|
||||
void testInvokeStatic3() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> divideMethod().invoke(null));
|
||||
@ -99,7 +99,7 @@ public class Reflection {
|
||||
* method triggers its class to be initialized and it fails with exception.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeStatic4() throws Exception {
|
||||
void testInvokeStatic4() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Method foo = BadClass1.class.getDeclaredMethod("foo");
|
||||
try {
|
||||
@ -123,7 +123,7 @@ public class Reflection {
|
||||
* class to be initialized and it fails with an error.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeStatic5() throws Exception {
|
||||
void testInvokeStatic5() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Method foo = BadClass2.class.getDeclaredMethod("foo");
|
||||
assertThrows(AbstractMethodError.class, () -> foo.invoke(null));
|
||||
@ -141,9 +141,8 @@ public class Reflection {
|
||||
* Test that invoking a static method does not pin the carrier thread.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeStatic6() throws Exception {
|
||||
if (!ThreadBuilders.supportsCustomScheduler())
|
||||
throw new SkipException("No support for custom schedulers");
|
||||
void testInvokeStatic6() throws Exception {
|
||||
assumeTrue(ThreadBuilders.supportsCustomScheduler(), "No support for custom schedulers");
|
||||
Method parkMethod = Parker.class.getDeclaredMethod("park");
|
||||
try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
|
||||
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
|
||||
@ -172,7 +171,7 @@ public class Reflection {
|
||||
* Test invoking instance method.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeInstance1() throws Exception {
|
||||
void testInvokeInstance1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
var adder = new Adder();
|
||||
Adder.addMethod().invoke(adder, 5);
|
||||
@ -185,7 +184,7 @@ public class Reflection {
|
||||
* exception.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeInstance2() throws Exception {
|
||||
void testInvokeInstance2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
var adder = new Adder();
|
||||
try {
|
||||
@ -202,7 +201,7 @@ public class Reflection {
|
||||
* trying to invoke an instance method with null or bad parameters.
|
||||
*/
|
||||
@Test
|
||||
public void testInvokeInstance3() throws Exception {
|
||||
void testInvokeInstance3() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
var adder = new Adder();
|
||||
Method addMethod = Adder.addMethod();
|
||||
@ -223,7 +222,7 @@ public class Reflection {
|
||||
* Test invoking newInstance to create an object.
|
||||
*/
|
||||
@Test
|
||||
public void testNewInstance1() throws Exception {
|
||||
void testNewInstance1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
||||
Adder adder = (Adder) ctor.newInstance(10);
|
||||
@ -236,7 +235,7 @@ public class Reflection {
|
||||
* exception.
|
||||
*/
|
||||
@Test
|
||||
public void testNewInstance2() throws Exception {
|
||||
void testNewInstance2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
||||
try {
|
||||
@ -253,7 +252,7 @@ public class Reflection {
|
||||
* with bad parameters.
|
||||
*/
|
||||
@Test
|
||||
public void testNewInstance3() throws Exception {
|
||||
void testNewInstance3() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
var adder = new Adder();
|
||||
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
||||
@ -275,7 +274,7 @@ public class Reflection {
|
||||
* triggers the class to be initialized and it fails with exception.
|
||||
*/
|
||||
@Test
|
||||
public void testNewInstance4() throws Exception {
|
||||
void testNewInstance4() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Constructor<?> ctor = BadClass3.class.getDeclaredConstructor();
|
||||
try {
|
||||
@ -299,7 +298,7 @@ public class Reflection {
|
||||
* to be initialized and it fails with an error.
|
||||
*/
|
||||
@Test
|
||||
public void testNewInstance5() throws Exception {
|
||||
void testNewInstance5() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Constructor<?> ctor = BadClass4.class.getDeclaredConstructor();
|
||||
assertThrows(AbstractMethodError.class, () -> ctor.newInstance((Object[])null));
|
||||
@ -317,9 +316,8 @@ public class Reflection {
|
||||
* Test that newInstance does not pin the carrier thread
|
||||
*/
|
||||
@Test
|
||||
public void testNewInstance6() throws Exception {
|
||||
if (!ThreadBuilders.supportsCustomScheduler())
|
||||
throw new SkipException("No support for custom schedulers");
|
||||
void testNewInstance6() throws Exception {
|
||||
assumeTrue(ThreadBuilders.supportsCustomScheduler(), "No support for custom schedulers");
|
||||
Constructor<?> ctor = Parker.class.getDeclaredConstructor();
|
||||
try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
|
||||
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,8 +29,8 @@
|
||||
* @modules java.management
|
||||
* @library /test/lib
|
||||
* @enablePreview
|
||||
* @run testng StackTraces
|
||||
* @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:+ShowCarrierFrames StackTraces
|
||||
* @run junit StackTraces
|
||||
* @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:+ShowCarrierFrames StackTraces
|
||||
*/
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
@ -40,17 +40,17 @@ import java.util.concurrent.ForkJoinPool;
|
||||
import static java.lang.StackWalker.Option.*;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class StackTraces {
|
||||
class StackTraces {
|
||||
|
||||
/**
|
||||
* Test that the stack trace in exceptions does not include the carrier thread
|
||||
* frames, except when running with -XX:+ShowCarrierFrames.
|
||||
*/
|
||||
@Test
|
||||
public void testStackTrace() throws Exception {
|
||||
void testStackTrace() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Exception e = new Exception();
|
||||
boolean found = Arrays.stream(e.getStackTrace())
|
||||
@ -64,7 +64,7 @@ public class StackTraces {
|
||||
* Test that StackWalker does not include carrier thread frames.
|
||||
*/
|
||||
@Test
|
||||
public void testStackWalker() throws Exception {
|
||||
void testStackWalker() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
StackWalker walker = StackWalker.getInstance(Set.of(RETAIN_CLASS_REFERENCE));
|
||||
boolean found = walker.walk(sf ->
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,14 +26,14 @@
|
||||
* @summary Test Virtual threads using thread locals
|
||||
* @library /test/lib
|
||||
* @enablePreview
|
||||
* @run testng ThreadLocals
|
||||
* @run junit ThreadLocals
|
||||
*/
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ThreadLocals {
|
||||
class ThreadLocals {
|
||||
static final ThreadLocal<Object> LOCAL = new ThreadLocal<>();
|
||||
static final ThreadLocal<Object> INHERITED_LOCAL = new InheritableThreadLocal<>();
|
||||
|
||||
@ -41,10 +41,10 @@ public class ThreadLocals {
|
||||
* Basic test of thread local set/get.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadLocal1() throws Exception {
|
||||
void testThreadLocal1() throws Exception {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
VThreadRunner.run(() -> {
|
||||
assertTrue(LOCAL.get() == null);
|
||||
assertNull(LOCAL.get());
|
||||
Object obj = new Object();
|
||||
LOCAL.set(obj);
|
||||
assertTrue(LOCAL.get() == obj);
|
||||
@ -56,9 +56,9 @@ public class ThreadLocals {
|
||||
* Test setting thread local before blocking operation.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadLocal2() throws Exception {
|
||||
void testThreadLocal2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
assertTrue(LOCAL.get() == null);
|
||||
assertNull(LOCAL.get());
|
||||
Object obj = new Object();
|
||||
LOCAL.set(obj);
|
||||
try { Thread.sleep(100); } catch (InterruptedException e) { }
|
||||
@ -70,7 +70,7 @@ public class ThreadLocals {
|
||||
* Test Thread that cannot set values for its copy of thread-locals.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadLocal3() throws Exception {
|
||||
void testThreadLocal3() throws Exception {
|
||||
Object INITIAL_VALUE = new Object();
|
||||
ThreadLocal<Object> LOCAL2 = new ThreadLocal<>() {
|
||||
@Override
|
||||
@ -88,7 +88,7 @@ public class ThreadLocals {
|
||||
VThreadRunner.run(VThreadRunner.NO_THREAD_LOCALS, () -> {
|
||||
assertThrows(UnsupportedOperationException.class, () -> LOCAL.set(null));
|
||||
assertThrows(UnsupportedOperationException.class, () -> LOCAL.set(new Object()));
|
||||
assertTrue(LOCAL.get() == null);
|
||||
assertNull(LOCAL.get());
|
||||
LOCAL.remove(); // should not throw
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> LOCAL2.set(null));
|
||||
@ -98,7 +98,7 @@ public class ThreadLocals {
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> INHERITED_LOCAL.set(null));
|
||||
assertThrows(UnsupportedOperationException.class, () -> INHERITED_LOCAL.set(new Object()));
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
INHERITED_LOCAL.remove(); // should not throw
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> INHERITED_LOCAL2.set(null));
|
||||
@ -112,25 +112,25 @@ public class ThreadLocals {
|
||||
* Basic test of inheritable thread local set/get, no initial value inherited.
|
||||
*/
|
||||
@Test
|
||||
public void testInheritedThreadLocal1() throws Exception {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
void testInheritedThreadLocal1() throws Exception {
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
VThreadRunner.run(() -> {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
Object obj = new Object();
|
||||
INHERITED_LOCAL.set(obj);
|
||||
assertTrue(INHERITED_LOCAL.get() == obj);
|
||||
});
|
||||
}
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test inheriting initial value of InheritableThreadLocal from platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testInheritedThreadLocal2() throws Exception {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
void testInheritedThreadLocal2() throws Exception {
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
var obj = new Object();
|
||||
INHERITED_LOCAL.set(obj);
|
||||
try {
|
||||
@ -146,8 +146,8 @@ public class ThreadLocals {
|
||||
* Test inheriting initial value of InheritableThreadLocal from virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testInheritedThreadLocal3() throws Exception {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
void testInheritedThreadLocal3() throws Exception {
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
VThreadRunner.run(() -> {
|
||||
var obj = new Object();
|
||||
INHERITED_LOCAL.set(obj);
|
||||
@ -157,7 +157,7 @@ public class ThreadLocals {
|
||||
assertTrue(INHERITED_LOCAL.get() == obj);
|
||||
|
||||
});
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,14 +165,14 @@ public class ThreadLocals {
|
||||
* from platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testInheritedThreadLocal4() throws Exception {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
void testInheritedThreadLocal4() throws Exception {
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
var obj = new Object();
|
||||
INHERITED_LOCAL.set(obj);
|
||||
try {
|
||||
int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
|
||||
VThreadRunner.run(characteristics, () -> {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
});
|
||||
} finally {
|
||||
INHERITED_LOCAL.remove();
|
||||
@ -184,18 +184,18 @@ public class ThreadLocals {
|
||||
* from virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testInheritedThreadLocal5() throws Exception {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
void testInheritedThreadLocal5() throws Exception {
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
VThreadRunner.run(() -> {
|
||||
var obj = new Object();
|
||||
INHERITED_LOCAL.set(obj);
|
||||
int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
|
||||
VThreadRunner.run(characteristics, () -> {
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
});
|
||||
assertTrue(INHERITED_LOCAL.get() == obj);
|
||||
|
||||
});
|
||||
assertTrue(INHERITED_LOCAL.get() == null);
|
||||
assertNull(INHERITED_LOCAL.get());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,8 +28,8 @@
|
||||
* @requires vm.continuations
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm -Djdk.tracePinnedThreads=full TracePinnedThreads
|
||||
* @run testng/othervm -Djdk.tracePinnedThreads=short TracePinnedThreads
|
||||
* @run junit/othervm -Djdk.tracePinnedThreads=full TracePinnedThreads
|
||||
* @run junit/othervm -Djdk.tracePinnedThreads=short TracePinnedThreads
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -38,10 +38,10 @@ import java.time.Duration;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TracePinnedThreads {
|
||||
class TracePinnedThreads {
|
||||
static final Object lock = new Object();
|
||||
|
||||
/**
|
||||
@ -62,7 +62,7 @@ public class TracePinnedThreads {
|
||||
* Test parking inside synchronized block.
|
||||
*/
|
||||
@Test
|
||||
public void testPinnedCausedBySynchronizedBlock() throws Exception {
|
||||
void testPinnedCausedBySynchronizedBlock() throws Exception {
|
||||
String output = run(() -> {
|
||||
synchronized (lock) {
|
||||
park();
|
||||
@ -76,7 +76,7 @@ public class TracePinnedThreads {
|
||||
* Test parking with native frame on stack.
|
||||
*/
|
||||
@Test
|
||||
public void testPinnedCausedByNativeMethod() throws Exception {
|
||||
void testPinnedCausedByNativeMethod() throws Exception {
|
||||
System.loadLibrary("TracePinnedThreads");
|
||||
String output = run(() -> invokePark());
|
||||
assertContains(output, "(Native Method)");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,22 +26,22 @@
|
||||
* @summary Test virtual threads using Object.wait/notifyAll
|
||||
* @library /test/lib
|
||||
* @enablePreview
|
||||
* @run testng WaitNotify
|
||||
* @run junit WaitNotify
|
||||
*/
|
||||
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class WaitNotify {
|
||||
class WaitNotify {
|
||||
|
||||
/**
|
||||
* Test virtual thread waits, notified by platform thread.
|
||||
*/
|
||||
@Test
|
||||
public void testWaitNotify1() throws Exception {
|
||||
void testWaitNotify1() throws Exception {
|
||||
var lock = new Object();
|
||||
var ready = new Semaphore(0);
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
@ -64,7 +64,7 @@ public class WaitNotify {
|
||||
* Test platform thread waits, notified by virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testWaitNotify2() throws Exception {
|
||||
void testWaitNotify2() throws Exception {
|
||||
var lock = new Object();
|
||||
var ready = new Semaphore(0);
|
||||
var thread = Thread.ofVirtual().start(() -> {
|
||||
@ -84,7 +84,7 @@ public class WaitNotify {
|
||||
* Test virtual thread waits, notified by another virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testWaitNotify3() throws Exception {
|
||||
void testWaitNotify3() throws Exception {
|
||||
var lock = new Object();
|
||||
var ready = new Semaphore(0);
|
||||
var thread1 = Thread.ofVirtual().start(() -> {
|
||||
@ -109,7 +109,7 @@ public class WaitNotify {
|
||||
* Test interrupt status set when calling Object.wait.
|
||||
*/
|
||||
@Test
|
||||
public void testWaitNotify4() throws Exception {
|
||||
void testWaitNotify4() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
t.interrupt();
|
||||
@ -130,7 +130,7 @@ public class WaitNotify {
|
||||
* Test interrupt when blocked in Object.wait.
|
||||
*/
|
||||
@Test
|
||||
public void testWaitNotify5() throws Exception {
|
||||
void testWaitNotify5() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Thread t = Thread.currentThread();
|
||||
scheduleInterrupt(t, 1000);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* @test
|
||||
* @summary Unit tests for java.lang.ThreadGroup
|
||||
* @run testng BasicTests
|
||||
* @run junit BasicTests
|
||||
*/
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
@ -34,25 +34,25 @@ import java.util.Set;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class BasicTests {
|
||||
class BasicTests {
|
||||
|
||||
@Test
|
||||
public void testGetName1() {
|
||||
void testGetName1() {
|
||||
ThreadGroup group = new ThreadGroup(null);
|
||||
assertTrue(group.getName() == null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetName2() {
|
||||
void testGetName2() {
|
||||
ThreadGroup group = new ThreadGroup("fred");
|
||||
assertEquals(group.getName(), "fred");
|
||||
assertEquals("fred", group.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetParent() {
|
||||
void testGetParent() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
||||
@ -63,7 +63,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParentOf() {
|
||||
void testParentOf() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
||||
@ -85,7 +85,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveCount1() {
|
||||
void testActiveCount1() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertTrue(group.activeCount() == 0);
|
||||
TestThread thread = TestThread.start(group, "foo");
|
||||
@ -98,7 +98,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveCount2() {
|
||||
void testActiveCount2() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
assertTrue(group1.activeCount() == 0);
|
||||
@ -124,7 +124,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enumerateThreads1() {
|
||||
void enumerateThreads1() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
Thread[] threads = new Thread[100];
|
||||
assertTrue(group.enumerate(threads) == 0);
|
||||
@ -156,7 +156,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enumerateThreads2() {
|
||||
void enumerateThreads2() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
|
||||
@ -203,12 +203,12 @@ public class BasicTests {
|
||||
try {
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group1.enumerate(threads) == 2);
|
||||
assertEquals(toSet(threads, 2), Set.of(thread1, thread2));
|
||||
assertEquals(Set.of(thread1, thread2), toSet(threads, 2));
|
||||
assertTrue(threads[2] == null);
|
||||
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group1.enumerate(threads, true) == 2);
|
||||
assertEquals(toSet(threads, 2), Set.of(thread1, thread2));
|
||||
assertEquals(Set.of(thread1, thread2), toSet(threads, 2));
|
||||
assertTrue(threads[2] == null);
|
||||
|
||||
Arrays.setAll(threads, i -> null);
|
||||
@ -261,7 +261,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enumerateThreads3() {
|
||||
void enumerateThreads3() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
||||
@ -304,20 +304,20 @@ public class BasicTests {
|
||||
try {
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group1.enumerate(threads) == 2);
|
||||
assertEquals(toSet(threads, 2), Set.of(thread2, thread3));
|
||||
assertEquals(Set.of(thread2, thread3), toSet(threads, 2));
|
||||
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group1.enumerate(threads, true) == 2);
|
||||
assertEquals(toSet(threads, 2), Set.of(thread2, thread3));
|
||||
assertEquals(Set.of(thread2, thread3), toSet(threads, 2));
|
||||
assertTrue(group1.enumerate(threads, false) == 0);
|
||||
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group2.enumerate(threads) == 2);
|
||||
assertEquals(toSet(threads, 2), Set.of(thread2, thread3));
|
||||
assertEquals(Set.of(thread2, thread3), toSet(threads, 2));
|
||||
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group2.enumerate(threads, true) == 2);
|
||||
assertEquals(toSet(threads, 2), Set.of(thread2, thread3));
|
||||
assertEquals(Set.of(thread2, thread3), toSet(threads, 2));
|
||||
|
||||
Arrays.setAll(threads, i -> null);
|
||||
assertTrue(group2.enumerate(threads, false) == 1);
|
||||
@ -391,7 +391,7 @@ public class BasicTests {
|
||||
* Test enumerate(Thread[]) with an array of insufficient size
|
||||
*/
|
||||
@Test
|
||||
public void enumerateThreads4() {
|
||||
void enumerateThreads4() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
|
||||
// array too small
|
||||
@ -418,7 +418,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveGroupCount() throws Exception {
|
||||
void testActiveGroupCount() throws Exception {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
assertTrue(group1.activeGroupCount() == 0);
|
||||
|
||||
@ -444,7 +444,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnumerateGroups1() throws Exception {
|
||||
void testEnumerateGroups1() throws Exception {
|
||||
ThreadGroup[] groups = new ThreadGroup[100];
|
||||
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
@ -477,12 +477,12 @@ public class BasicTests {
|
||||
|
||||
Arrays.setAll(groups, i -> null);
|
||||
assertTrue(group1.enumerate(groups) == 2);
|
||||
assertEquals(toSet(groups, 2), Set.of(group2, group3));
|
||||
assertEquals(Set.of(group2, group3), toSet(groups, 2));
|
||||
assertTrue(groups[2] == null);
|
||||
|
||||
Arrays.setAll(groups, i -> null);
|
||||
assertTrue(group1.enumerate(groups, true) == 2);
|
||||
assertEquals(toSet(groups, 2), Set.of(group2, group3));
|
||||
assertEquals(Set.of(group2, group3), toSet(groups, 2));
|
||||
assertTrue(groups[2] == null);
|
||||
|
||||
Arrays.setAll(groups, i -> null);
|
||||
@ -546,7 +546,7 @@ public class BasicTests {
|
||||
* Test enumerate(ThreadGroup[]) with an array of insufficient size
|
||||
*/
|
||||
@Test
|
||||
public void testEnumerateGroups2() throws Exception {
|
||||
void testEnumerateGroups2() throws Exception {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
ThreadGroup child1 = new ThreadGroup(group, "child1");
|
||||
ThreadGroup child2 = new ThreadGroup(group,"child2");
|
||||
@ -568,7 +568,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxPriority1() {
|
||||
void testMaxPriority1() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
final int maxPriority = group.getMaxPriority();
|
||||
assertTrue(maxPriority == Thread.currentThread().getThreadGroup().getMaxPriority());
|
||||
@ -592,7 +592,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxPriority2() {
|
||||
void testMaxPriority2() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
int maxPriority = group1.getMaxPriority();
|
||||
if (maxPriority > Thread.MIN_PRIORITY) {
|
||||
@ -630,7 +630,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxPriority3() {
|
||||
void testMaxPriority3() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
if (group.getMaxPriority() > Thread.MIN_PRIORITY) {
|
||||
int maxPriority = Thread.MIN_PRIORITY + 1;
|
||||
@ -656,7 +656,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterrupt1() {
|
||||
void testInterrupt1() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertTrue(group.activeCount() == 0);
|
||||
TestThread thread = TestThread.start(group, "foo");
|
||||
@ -669,7 +669,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterrupt2() {
|
||||
void testInterrupt2() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
TestThread thread1 = TestThread.start(group1, "foo");
|
||||
@ -685,7 +685,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterrupt3() {
|
||||
void testInterrupt3() {
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||
TestThread thread1 = TestThread.start(group1, "foo");
|
||||
@ -701,7 +701,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroy() {
|
||||
void testDestroy() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertFalse(group.isDestroyed());
|
||||
group.destroy(); // does nothing
|
||||
@ -709,7 +709,7 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDaemon() {
|
||||
void testDaemon() {
|
||||
boolean d = Thread.currentThread().getThreadGroup().isDaemon();
|
||||
|
||||
ThreadGroup group1 = new ThreadGroup("group1");
|
||||
@ -727,68 +727,68 @@ public class BasicTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testList() {
|
||||
void testList() {
|
||||
ThreadGroup group = new ThreadGroup("foo");
|
||||
group.list();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuspend() {
|
||||
void testSuspend() {
|
||||
ThreadGroup group = new ThreadGroup("foo");
|
||||
assertThrows(UnsupportedOperationException.class, () -> group.suspend());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResume() {
|
||||
void testResume() {
|
||||
ThreadGroup group = new ThreadGroup("foo");
|
||||
assertThrows(UnsupportedOperationException.class, () -> group.resume());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStop() {
|
||||
void testStop() {
|
||||
ThreadGroup group = new ThreadGroup("foo");
|
||||
assertThrows(UnsupportedOperationException.class, () -> group.stop());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull1() {
|
||||
void testNull1() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new ThreadGroup(null, "group"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull2() {
|
||||
void testNull2() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> group.enumerate((Thread[]) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull3() {
|
||||
void testNull3() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> group.enumerate((Thread[]) null, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull4() {
|
||||
void testNull4() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> group.enumerate((ThreadGroup[]) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull5() {
|
||||
void testNull5() {
|
||||
ThreadGroup group = new ThreadGroup("group");
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> group.enumerate((ThreadGroup[]) null, false));
|
||||
}
|
||||
|
||||
private <T> Set<T> toSet(T[] array, int len) {
|
||||
private static <T> Set<T> toSet(T[] array, int len) {
|
||||
return Arrays.stream(array, 0, len).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
static class TestThread extends Thread {
|
||||
private static class TestThread extends Thread {
|
||||
TestThread(ThreadGroup group, String name) {
|
||||
super(group, name);
|
||||
}
|
||||
@ -802,6 +802,7 @@ public class BasicTests {
|
||||
private volatile boolean done;
|
||||
private volatile boolean interrupted;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (Thread.currentThread() != this)
|
||||
throw new IllegalCallerException();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @summary Test java.lang.management.ThreadMXBean with virtual threads
|
||||
* @enablePreview
|
||||
* @modules java.base/java.lang:+open java.management
|
||||
* @run testng/othervm VirtualThreads
|
||||
* @run junit/othervm VirtualThreads
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -35,7 +35,7 @@
|
||||
* @requires vm.continuations
|
||||
* @enablePreview
|
||||
* @modules java.base/java.lang:+open java.management
|
||||
* @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations VirtualThreads
|
||||
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations VirtualThreads
|
||||
*/
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
@ -51,9 +51,9 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assumptions.*;
|
||||
|
||||
public class VirtualThreads {
|
||||
|
||||
@ -62,7 +62,7 @@ public class VirtualThreads {
|
||||
* virtual threads.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAllThreadIds() throws Exception {
|
||||
void testGetAllThreadIds() throws Exception {
|
||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||
try {
|
||||
long[] tids = ManagementFactory.getThreadMXBean().getAllThreadIds();
|
||||
@ -83,7 +83,7 @@ public class VirtualThreads {
|
||||
* Test that ThreadMXBean.getThreadInfo(long) returns null for a virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadInfo1() throws Exception {
|
||||
void testGetThreadInfo1() throws Exception {
|
||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||
try {
|
||||
long tid = vthread.threadId();
|
||||
@ -99,7 +99,7 @@ public class VirtualThreads {
|
||||
* thread with its own thread id.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadInfo2() throws Exception {
|
||||
void testGetThreadInfo2() throws Exception {
|
||||
runInVirtualThread(() -> {
|
||||
long tid = Thread.currentThread().threadId();
|
||||
ThreadInfo info = ManagementFactory.getThreadMXBean().getThreadInfo(tid);
|
||||
@ -112,9 +112,8 @@ public class VirtualThreads {
|
||||
* The stack frames of the virtual thread should not be returned.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadInfo3() throws Exception {
|
||||
if (!supportsCustomScheduler())
|
||||
throw new SkipException("No support for custom schedulers");
|
||||
void testGetThreadInfo3() throws Exception {
|
||||
assumeTrue(supportsCustomScheduler(), "No support for custom schedulers");
|
||||
try (ExecutorService pool = Executors.newFixedThreadPool(1)) {
|
||||
var carrierRef = new AtomicReference<Thread>();
|
||||
Executor scheduler = (task) -> {
|
||||
@ -157,7 +156,7 @@ public class VirtualThreads {
|
||||
* elements that correspond to a virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadInfo4() throws Exception {
|
||||
void testGetThreadInfo4() throws Exception {
|
||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||
try {
|
||||
long tid0 = Thread.currentThread().threadId();
|
||||
@ -175,7 +174,7 @@ public class VirtualThreads {
|
||||
* Test that ThreadMXBean.getThreadCpuTime(long) returns -1 for a virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadCpuTime1() {
|
||||
void testGetThreadCpuTime1() {
|
||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||
try {
|
||||
long tid = vthread.threadId();
|
||||
@ -191,7 +190,7 @@ public class VirtualThreads {
|
||||
* virtual thread with its own thread id.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadCpuTime2() throws Exception {
|
||||
void testGetThreadCpuTime2() throws Exception {
|
||||
runInVirtualThread(() -> {
|
||||
long tid = Thread.currentThread().threadId();
|
||||
long cpuTime = ManagementFactory.getThreadMXBean().getThreadCpuTime(tid);
|
||||
@ -203,7 +202,7 @@ public class VirtualThreads {
|
||||
* Test that ThreadMXBean.getThreadUserTime(long) returns -1 for a virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadUserTime1() {
|
||||
void testGetThreadUserTime1() {
|
||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||
try {
|
||||
long tid = vthread.threadId();
|
||||
@ -219,7 +218,7 @@ public class VirtualThreads {
|
||||
* virtual thread with its own thread id.
|
||||
*/
|
||||
@Test
|
||||
public void testGetThreadUserTime2() throws Exception {
|
||||
void testGetThreadUserTime2() throws Exception {
|
||||
runInVirtualThread(() -> {
|
||||
long tid = Thread.currentThread().threadId();
|
||||
long userTime = ManagementFactory.getThreadMXBean().getThreadUserTime(tid);
|
||||
@ -231,10 +230,11 @@ public class VirtualThreads {
|
||||
* Test that ThreadMXBean::getCurrentThreadCpuTime throws UOE when invoked
|
||||
* on a virtual thread.
|
||||
*/
|
||||
@Test(expectedExceptions = { UnsupportedOperationException.class })
|
||||
public void testGetCurrentThreadCpuTime() throws Exception {
|
||||
@Test
|
||||
void testGetCurrentThreadCpuTime() throws Exception {
|
||||
runInVirtualThread(() -> {
|
||||
ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
|
||||
assertThrows(UnsupportedOperationException.class,
|
||||
() -> ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime());
|
||||
});
|
||||
}
|
||||
|
||||
@ -242,10 +242,11 @@ public class VirtualThreads {
|
||||
* Test that ThreadMXBean::getCurrentThreadUserTime throws UOE when
|
||||
* invoked on a virtual thread.
|
||||
*/
|
||||
@Test(expectedExceptions = { UnsupportedOperationException.class })
|
||||
public void testGetCurrentThreadUserTime() throws Exception {
|
||||
@Test
|
||||
void testGetCurrentThreadUserTime() throws Exception {
|
||||
runInVirtualThread(() -> {
|
||||
ManagementFactory.getThreadMXBean().getCurrentThreadUserTime();
|
||||
assertThrows(UnsupportedOperationException.class,
|
||||
() -> ManagementFactory.getThreadMXBean().getCurrentThreadUserTime());
|
||||
});
|
||||
}
|
||||
|
||||
@ -254,7 +255,7 @@ public class VirtualThreads {
|
||||
* invoked on a virtual thread.
|
||||
*/
|
||||
@Test
|
||||
public void testGetCurrentThreadAllocatedBytes() throws Exception {
|
||||
void testGetCurrentThreadAllocatedBytes() throws Exception {
|
||||
runInVirtualThread(() -> {
|
||||
long allocated = ManagementFactory.getPlatformMXBean(com.sun.management.ThreadMXBean.class)
|
||||
.getCurrentThreadAllocatedBytes();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @summary Test virtual threads doing blocking I/O on java.net sockets
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm BlockingSocketOps
|
||||
* @run junit BlockingSocketOps
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -36,7 +36,7 @@
|
||||
* the I/O poller configured to use direct registration
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm -Djdk.useDirectRegister BlockingSocketOps
|
||||
* @run junit/othervm -Djdk.useDirectRegister BlockingSocketOps
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -44,7 +44,7 @@
|
||||
* @requires vm.continuations
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
|
||||
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
|
||||
*/
|
||||
|
||||
import java.io.Closeable;
|
||||
@ -62,16 +62,16 @@ import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class BlockingSocketOps {
|
||||
class BlockingSocketOps {
|
||||
|
||||
/**
|
||||
* Socket read/write, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadWrite1() throws Exception {
|
||||
void testSocketReadWrite1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s1 = connection.socket1();
|
||||
@ -94,7 +94,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketRead1() throws Exception {
|
||||
void testSocketRead1() throws Exception {
|
||||
testSocketRead(0);
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in timed read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketRead2() throws Exception {
|
||||
void testSocketRead2() throws Exception {
|
||||
testSocketRead(60_000);
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in write.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketWrite1() throws Exception {
|
||||
void testSocketWrite1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s1 = connection.socket1();
|
||||
@ -161,7 +161,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in read, peer closes connection gracefully.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadPeerClose1() throws Exception {
|
||||
void testSocketReadPeerClose1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s1 = connection.socket1();
|
||||
@ -181,7 +181,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in read, peer closes connection abruptly.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadPeerClose2() throws Exception {
|
||||
void testSocketReadPeerClose2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s1 = connection.socket1();
|
||||
@ -206,7 +206,7 @@ public class BlockingSocketOps {
|
||||
* Socket close while virtual thread blocked in read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadAsyncClose1() throws Exception {
|
||||
void testSocketReadAsyncClose1() throws Exception {
|
||||
testSocketReadAsyncClose(0);
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class BlockingSocketOps {
|
||||
* Socket close while virtual thread blocked in timed read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadAsyncClose2() throws Exception {
|
||||
void testSocketReadAsyncClose2() throws Exception {
|
||||
testSocketReadAsyncClose(0);
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in Socket read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadInterrupt1() throws Exception {
|
||||
void testSocketReadInterrupt1() throws Exception {
|
||||
testSocketReadInterrupt(0);
|
||||
}
|
||||
|
||||
@ -250,7 +250,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in Socket read with timeout
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadInterrupt2() throws Exception {
|
||||
void testSocketReadInterrupt2() throws Exception {
|
||||
testSocketReadInterrupt(60_000);
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ public class BlockingSocketOps {
|
||||
* Socket close while virtual thread blocked in write.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketWriteAsyncClose() throws Exception {
|
||||
void testSocketWriteAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s = connection.socket1();
|
||||
@ -307,7 +307,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in Socket write.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketWriteInterrupt() throws Exception {
|
||||
void testSocketWriteInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s = connection.socket1();
|
||||
@ -335,7 +335,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread reading urgent data when SO_OOBINLINE is enabled.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketReadUrgentData() throws Exception {
|
||||
void testSocketReadUrgentData() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
Socket s1 = connection.socket1();
|
||||
@ -367,7 +367,7 @@ public class BlockingSocketOps {
|
||||
* ServerSocket accept, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAccept1() throws Exception {
|
||||
void testServerSocketAccept1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var listener = new ServerSocket()) {
|
||||
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||
@ -388,7 +388,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAccept2() throws Exception {
|
||||
void testServerSocketAccept2() throws Exception {
|
||||
testServerSocketAccept(0);
|
||||
}
|
||||
|
||||
@ -396,7 +396,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in timed accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAccept3() throws Exception {
|
||||
void testServerSocketAccept3() throws Exception {
|
||||
testServerSocketAccept(60_000);
|
||||
}
|
||||
|
||||
@ -426,7 +426,7 @@ public class BlockingSocketOps {
|
||||
* ServerSocket close while virtual thread blocked in accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAcceptAsyncClose1() throws Exception {
|
||||
void testServerSocketAcceptAsyncClose1() throws Exception {
|
||||
testServerSocketAcceptAsyncClose(0);
|
||||
}
|
||||
|
||||
@ -434,7 +434,7 @@ public class BlockingSocketOps {
|
||||
* ServerSocket close while virtual thread blocked in timed accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAcceptAsyncClose2() throws Exception {
|
||||
void testServerSocketAcceptAsyncClose2() throws Exception {
|
||||
testServerSocketAcceptAsyncClose(60_000);
|
||||
}
|
||||
|
||||
@ -463,7 +463,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in ServerSocket accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAcceptInterrupt1() throws Exception {
|
||||
void testServerSocketAcceptInterrupt1() throws Exception {
|
||||
testServerSocketAcceptInterrupt(0);
|
||||
}
|
||||
|
||||
@ -471,7 +471,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in ServerSocket accept with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketAcceptInterrupt2() throws Exception {
|
||||
void testServerSocketAcceptInterrupt2() throws Exception {
|
||||
testServerSocketAcceptInterrupt(60_000);
|
||||
}
|
||||
|
||||
@ -504,7 +504,7 @@ public class BlockingSocketOps {
|
||||
* DatagramSocket receive/send, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketSendReceive1() throws Exception {
|
||||
void testDatagramSocketSendReceive1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (DatagramSocket s1 = new DatagramSocket(null);
|
||||
DatagramSocket s2 = new DatagramSocket(null)) {
|
||||
@ -523,7 +523,7 @@ public class BlockingSocketOps {
|
||||
byte[] ba = new byte[100];
|
||||
DatagramPacket p2 = new DatagramPacket(ba, ba.length);
|
||||
s2.receive(p2);
|
||||
assertEquals(p2.getSocketAddress(), s1.getLocalSocketAddress());
|
||||
assertEquals(s1.getLocalSocketAddress(), p2.getSocketAddress());
|
||||
assertTrue(ba[0] == 'X');
|
||||
}
|
||||
});
|
||||
@ -533,7 +533,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in DatagramSocket receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketSendReceive2() throws Exception {
|
||||
void testDatagramSocketSendReceive2() throws Exception {
|
||||
testDatagramSocketSendReceive(0);
|
||||
}
|
||||
|
||||
@ -541,7 +541,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in DatagramSocket receive with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketSendReceive3() throws Exception {
|
||||
void testDatagramSocketSendReceive3() throws Exception {
|
||||
testDatagramSocketSendReceive(60_000);
|
||||
}
|
||||
|
||||
@ -567,7 +567,7 @@ public class BlockingSocketOps {
|
||||
byte[] ba = new byte[100];
|
||||
DatagramPacket p2 = new DatagramPacket(ba, ba.length);
|
||||
s2.receive(p2);
|
||||
assertEquals(p2.getSocketAddress(), s1.getLocalSocketAddress());
|
||||
assertEquals(s1.getLocalSocketAddress(), p2.getSocketAddress());
|
||||
assertTrue(ba[0] == 'X');
|
||||
}
|
||||
});
|
||||
@ -577,7 +577,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread blocks in DatagramSocket receive that times out.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketReceiveTimeout() throws Exception {
|
||||
void testDatagramSocketReceiveTimeout() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (DatagramSocket s = new DatagramSocket(null)) {
|
||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||
@ -597,7 +597,7 @@ public class BlockingSocketOps {
|
||||
* DatagramSocket close while virtual thread blocked in receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketReceiveAsyncClose1() throws Exception {
|
||||
void testDatagramSocketReceiveAsyncClose1() throws Exception {
|
||||
testDatagramSocketReceiveAsyncClose(0);
|
||||
}
|
||||
|
||||
@ -605,7 +605,7 @@ public class BlockingSocketOps {
|
||||
* DatagramSocket close while virtual thread blocked with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketReceiveAsyncClose2() throws Exception {
|
||||
void testDatagramSocketReceiveAsyncClose2() throws Exception {
|
||||
testDatagramSocketReceiveAsyncClose(60_000);
|
||||
}
|
||||
|
||||
@ -636,7 +636,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in DatagramSocket receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketReceiveInterrupt1() throws Exception {
|
||||
void testDatagramSocketReceiveInterrupt1() throws Exception {
|
||||
testDatagramSocketReceiveInterrupt(0);
|
||||
}
|
||||
|
||||
@ -644,7 +644,7 @@ public class BlockingSocketOps {
|
||||
* Virtual thread interrupted while blocked in DatagramSocket receive with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketReceiveInterrupt2() throws Exception {
|
||||
void testDatagramSocketReceiveInterrupt2() throws Exception {
|
||||
testDatagramSocketReceiveInterrupt(60_000);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @summary Test virtual threads doing blocking I/O on NIO channels
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm BlockingChannelOps
|
||||
* @run junit BlockingChannelOps
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -36,7 +36,7 @@
|
||||
* the I/O poller configured to use direct registration
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm -Djdk.useDirectRegister BlockingChannelOps
|
||||
* @run junit/othervm -Djdk.useDirectRegister BlockingChannelOps
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -44,7 +44,7 @@
|
||||
* @requires vm.continuations
|
||||
* @enablePreview
|
||||
* @library /test/lib
|
||||
* @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingChannelOps
|
||||
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingChannelOps
|
||||
*/
|
||||
|
||||
import java.io.Closeable;
|
||||
@ -67,16 +67,16 @@ import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class BlockingChannelOps {
|
||||
class BlockingChannelOps {
|
||||
|
||||
/**
|
||||
* SocketChannel read/write, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelReadWrite1() throws Exception {
|
||||
void testSocketChannelReadWrite1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
SocketChannel sc1 = connection.channel1();
|
||||
@ -100,7 +100,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in SocketChannel read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelRead() throws Exception {
|
||||
void testSocketChannelRead() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
SocketChannel sc1 = connection.channel1();
|
||||
@ -123,7 +123,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in SocketChannel write.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelWrite() throws Exception {
|
||||
void testSocketChannelWrite() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
SocketChannel sc1 = connection.channel1();
|
||||
@ -151,7 +151,7 @@ public class BlockingChannelOps {
|
||||
* SocketChannel close while virtual thread blocked in read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelReadAsyncClose() throws Exception {
|
||||
void testSocketChannelReadAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
SocketChannel sc = connection.channel1();
|
||||
@ -168,7 +168,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in SocketChannel read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelReadInterrupt() throws Exception {
|
||||
void testSocketChannelReadInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var connection = new Connection()) {
|
||||
SocketChannel sc = connection.channel1();
|
||||
@ -191,7 +191,7 @@ public class BlockingChannelOps {
|
||||
* SocketChannel close while virtual thread blocked in write.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelWriteAsyncClose() throws Exception {
|
||||
void testSocketChannelWriteAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
boolean retry = true;
|
||||
while (retry) {
|
||||
@ -222,7 +222,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in SocketChannel write.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelWriteInterrupt() throws Exception {
|
||||
void testSocketChannelWriteInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
boolean retry = true;
|
||||
while (retry) {
|
||||
@ -256,7 +256,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in SocketChannel adaptor read.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketAdaptorRead1() throws Exception {
|
||||
void testSocketAdaptorRead1() throws Exception {
|
||||
testSocketAdaptorRead(0);
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in SocketChannel adaptor read with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketAdaptorRead2() throws Exception {
|
||||
void testSocketAdaptorRead2() throws Exception {
|
||||
testSocketAdaptorRead(60_000);
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ public class BlockingChannelOps {
|
||||
* ServerSocketChannel accept, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketChannelAccept1() throws Exception {
|
||||
void testServerSocketChannelAccept1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var ssc = ServerSocketChannel.open()) {
|
||||
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
@ -310,7 +310,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in ServerSocketChannel accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketChannelAccept2() throws Exception {
|
||||
void testServerSocketChannelAccept2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var ssc = ServerSocketChannel.open()) {
|
||||
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
@ -331,7 +331,7 @@ public class BlockingChannelOps {
|
||||
* SeverSocketChannel close while virtual thread blocked in accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketChannelAcceptAsyncClose() throws Exception {
|
||||
void testServerSocketChannelAcceptAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var ssc = ServerSocketChannel.open()) {
|
||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||
@ -350,7 +350,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in ServerSocketChannel accept.
|
||||
*/
|
||||
@Test
|
||||
public void testServerSocketChannelAcceptInterrupt() throws Exception {
|
||||
void testServerSocketChannelAcceptInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (var ssc = ServerSocketChannel.open()) {
|
||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||
@ -375,7 +375,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in ServerSocketChannel adaptor accept.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelAdaptorAccept1() throws Exception {
|
||||
void testSocketChannelAdaptorAccept1() throws Exception {
|
||||
testSocketChannelAdaptorAccept(0);
|
||||
}
|
||||
|
||||
@ -383,7 +383,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in ServerSocketChannel adaptor accept with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testSocketChannelAdaptorAccept2() throws Exception {
|
||||
void testSocketChannelAdaptorAccept2() throws Exception {
|
||||
testSocketChannelAdaptorAccept(60_000);
|
||||
}
|
||||
|
||||
@ -410,7 +410,7 @@ public class BlockingChannelOps {
|
||||
* DatagramChannel receive/send, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramChannelSendReceive1() throws Exception {
|
||||
void testDatagramChannelSendReceive1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (DatagramChannel dc1 = DatagramChannel.open();
|
||||
DatagramChannel dc2 = DatagramChannel.open()) {
|
||||
@ -435,7 +435,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in DatagramChannel receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramChannelSendReceive2() throws Exception {
|
||||
void testDatagramChannelSendReceive2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (DatagramChannel dc1 = DatagramChannel.open();
|
||||
DatagramChannel dc2 = DatagramChannel.open()) {
|
||||
@ -459,7 +459,7 @@ public class BlockingChannelOps {
|
||||
* DatagramChannel close while virtual thread blocked in receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramChannelReceiveAsyncClose() throws Exception {
|
||||
void testDatagramChannelReceiveAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (DatagramChannel dc = DatagramChannel.open()) {
|
||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||
@ -477,7 +477,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in DatagramChannel receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramChannelReceiveInterrupt() throws Exception {
|
||||
void testDatagramChannelReceiveInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
try (DatagramChannel dc = DatagramChannel.open()) {
|
||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||
@ -501,7 +501,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in DatagramSocket adaptor receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketAdaptorReceive1() throws Exception {
|
||||
void testDatagramSocketAdaptorReceive1() throws Exception {
|
||||
testDatagramSocketAdaptorReceive(0);
|
||||
}
|
||||
|
||||
@ -509,7 +509,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in DatagramSocket adaptor receive with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketAdaptorReceive2() throws Exception {
|
||||
void testDatagramSocketAdaptorReceive2() throws Exception {
|
||||
testDatagramSocketAdaptorReceive(60_1000);
|
||||
}
|
||||
|
||||
@ -540,7 +540,7 @@ public class BlockingChannelOps {
|
||||
* DatagramChannel close while virtual thread blocked in adaptor receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketAdaptorReceiveAsyncClose1() throws Exception {
|
||||
void testDatagramSocketAdaptorReceiveAsyncClose1() throws Exception {
|
||||
testDatagramSocketAdaptorReceiveAsyncClose(0);
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ public class BlockingChannelOps {
|
||||
* with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketAdaptorReceiveAsyncClose2() throws Exception {
|
||||
void testDatagramSocketAdaptorReceiveAsyncClose2() throws Exception {
|
||||
testDatagramSocketAdaptorReceiveAsyncClose(60_1000);
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in DatagramSocket adaptor receive.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketAdaptorReceiveInterrupt1() throws Exception {
|
||||
void testDatagramSocketAdaptorReceiveInterrupt1() throws Exception {
|
||||
testDatagramSocketAdaptorReceiveInterrupt(0);
|
||||
}
|
||||
|
||||
@ -585,7 +585,7 @@ public class BlockingChannelOps {
|
||||
* with timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testDatagramSocketAdaptorReceiveInterrupt2() throws Exception {
|
||||
void testDatagramSocketAdaptorReceiveInterrupt2() throws Exception {
|
||||
testDatagramSocketAdaptorReceiveInterrupt(60_1000);
|
||||
}
|
||||
|
||||
@ -618,7 +618,7 @@ public class BlockingChannelOps {
|
||||
* Pipe read/write, no blocking.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeReadWrite1() throws Exception {
|
||||
void testPipeReadWrite1() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Pipe p = Pipe.open();
|
||||
try (Pipe.SinkChannel sink = p.sink();
|
||||
@ -642,7 +642,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in Pipe.SourceChannel read.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeReadWrite2() throws Exception {
|
||||
void testPipeReadWrite2() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Pipe p = Pipe.open();
|
||||
try (Pipe.SinkChannel sink = p.sink();
|
||||
@ -665,7 +665,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread blocks in Pipe.SinkChannel write.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeReadWrite3() throws Exception {
|
||||
void testPipeReadWrite3() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Pipe p = Pipe.open();
|
||||
try (Pipe.SinkChannel sink = p.sink();
|
||||
@ -693,7 +693,7 @@ public class BlockingChannelOps {
|
||||
* Pipe.SourceChannel close while virtual thread blocked in read.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeReadAsyncClose() throws Exception {
|
||||
void testPipeReadAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Pipe p = Pipe.open();
|
||||
try (Pipe.SinkChannel sink = p.sink();
|
||||
@ -711,7 +711,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in Pipe.SourceChannel read.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeReadInterrupt() throws Exception {
|
||||
void testPipeReadInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
Pipe p = Pipe.open();
|
||||
try (Pipe.SinkChannel sink = p.sink();
|
||||
@ -735,7 +735,7 @@ public class BlockingChannelOps {
|
||||
* Pipe.SinkChannel close while virtual thread blocked in write.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeWriteAsyncClose() throws Exception {
|
||||
void testPipeWriteAsyncClose() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
boolean retry = true;
|
||||
while (retry) {
|
||||
@ -767,7 +767,7 @@ public class BlockingChannelOps {
|
||||
* Virtual thread interrupted while blocked in Pipe.SinkChannel write.
|
||||
*/
|
||||
@Test
|
||||
public void testPipeWriteInterrupt() throws Exception {
|
||||
void testPipeWriteInterrupt() throws Exception {
|
||||
VThreadRunner.run(() -> {
|
||||
boolean retry = true;
|
||||
while (retry) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,13 +25,13 @@
|
||||
* @test id=platform
|
||||
* @summary Basic tests for new thread-per-task executors
|
||||
* @enablePreview
|
||||
* @run testng/othervm -DthreadFactory=platform ThreadPerTaskExecutorTest
|
||||
* @run junit/othervm -DthreadFactory=platform ThreadPerTaskExecutorTest
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test id=virtual
|
||||
* @enablePreview
|
||||
* @run testng/othervm -DthreadFactory=virtual ThreadPerTaskExecutorTest
|
||||
* @run junit/othervm -DthreadFactory=virtual ThreadPerTaskExecutorTest
|
||||
*/
|
||||
|
||||
import java.time.Duration;
|
||||
@ -45,32 +45,29 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import static java.util.concurrent.Future.State.*;
|
||||
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ThreadPerTaskExecutorTest {
|
||||
class ThreadPerTaskExecutorTest {
|
||||
// long running interruptible task
|
||||
private static final Callable<Void> SLEEP_FOR_A_DAY = () -> {
|
||||
Thread.sleep(Duration.ofDays(1));
|
||||
return null;
|
||||
};
|
||||
|
||||
private ScheduledExecutorService scheduler;
|
||||
private Object[][] threadFactories;
|
||||
private static ScheduledExecutorService scheduler;
|
||||
private static List<ThreadFactory> threadFactories;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() throws Exception {
|
||||
ThreadFactory factory = (task) -> {
|
||||
Thread thread = new Thread(task);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
};
|
||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(factory);
|
||||
@BeforeAll
|
||||
static void setup() throws Exception {
|
||||
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
// thread factories
|
||||
String value = System.getProperty("threadFactory");
|
||||
@ -80,27 +77,21 @@ public class ThreadPerTaskExecutorTest {
|
||||
if (value == null || value.equals("virtual"))
|
||||
list.add(Thread.ofVirtual().factory());
|
||||
assertTrue(list.size() > 0, "No thread factories for tests");
|
||||
this.threadFactories = list.stream()
|
||||
.map(f -> new Object[] { f })
|
||||
.toArray(Object[][]::new);
|
||||
threadFactories = list;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void tearDown() {
|
||||
@AfterAll
|
||||
static void shutdown() {
|
||||
scheduler.shutdown();
|
||||
}
|
||||
|
||||
@DataProvider(name = "factories")
|
||||
public Object[][] factories() {
|
||||
return threadFactories;
|
||||
private static Stream<ThreadFactory> factories() {
|
||||
return threadFactories.stream();
|
||||
}
|
||||
|
||||
@DataProvider(name = "executors")
|
||||
public Object[][] executors() {
|
||||
return Arrays.stream(threadFactories)
|
||||
.map(f -> Executors.newThreadPerTaskExecutor((ThreadFactory) f[0]))
|
||||
.map(e -> new Object[] { e })
|
||||
.toArray(Object[][]::new);
|
||||
private static Stream<ExecutorService> executors() {
|
||||
return threadFactories.stream()
|
||||
.map(f -> Executors.newThreadPerTaskExecutor(f));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,8 +105,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test that a thread is created for each task.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testThreadPerTask(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testThreadPerTask(ThreadFactory factory) throws Exception {
|
||||
final int NUM_TASKS = 100;
|
||||
AtomicInteger threadCount = new AtomicInteger();
|
||||
|
||||
@ -135,7 +127,7 @@ public class ThreadPerTaskExecutorTest {
|
||||
}
|
||||
|
||||
assertTrue(executor.isTerminated());
|
||||
assertEquals(threadCount.get(), NUM_TASKS);
|
||||
assertEquals(NUM_TASKS, threadCount.get());
|
||||
for (int i=0; i<NUM_TASKS; i++) {
|
||||
Future<Integer> future = futures.get(i);
|
||||
assertEquals((int) future.get(), i);
|
||||
@ -146,7 +138,7 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test that newThreadPerTaskExecutor uses the specified thread factory.
|
||||
*/
|
||||
@Test
|
||||
public void testThreadFactory() throws Exception {
|
||||
void testThreadFactory() throws Exception {
|
||||
var ref1 = new AtomicReference<Thread>();
|
||||
var ref2 = new AtomicReference<Thread>();
|
||||
ThreadFactory factory = task -> {
|
||||
@ -166,8 +158,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testShutdown(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testShutdown(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
assertFalse(executor.isShutdown());
|
||||
assertFalse(executor.isTerminated());
|
||||
@ -188,8 +181,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test shutdownNow.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testShutdownNow(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testShutdownNow(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
assertFalse(executor.isShutdown());
|
||||
assertFalse(executor.isTerminated());
|
||||
@ -201,7 +195,7 @@ public class ThreadPerTaskExecutorTest {
|
||||
assertTrue(executor.isShutdown());
|
||||
assertTrue(tasks.isEmpty());
|
||||
|
||||
Throwable e = expectThrows(ExecutionException.class, result::get);
|
||||
Throwable e = assertThrows(ExecutionException.class, result::get);
|
||||
assertTrue(e.getCause() instanceof InterruptedException);
|
||||
|
||||
assertTrue(executor.awaitTermination(3, TimeUnit.SECONDS));
|
||||
@ -215,8 +209,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test close with no threads running.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testClose1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testClose1(ExecutorService executor) throws Exception {
|
||||
executor.close();
|
||||
assertTrue(executor.isShutdown());
|
||||
assertTrue(executor.isTerminated());
|
||||
@ -226,8 +221,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test close with threads running.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testClose2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testClose2(ExecutorService executor) throws Exception {
|
||||
Future<String> future;
|
||||
try (executor) {
|
||||
future = executor.submit(() -> {
|
||||
@ -244,8 +240,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Invoke close with interrupt status set, should cancel task.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testClose3(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testClose3(ExecutorService executor) throws Exception {
|
||||
Future<?> future;
|
||||
try (executor) {
|
||||
future = executor.submit(SLEEP_FOR_A_DAY);
|
||||
@ -257,14 +254,15 @@ public class ThreadPerTaskExecutorTest {
|
||||
assertTrue(executor.isShutdown());
|
||||
assertTrue(executor.isTerminated());
|
||||
assertTrue(executor.awaitTermination(10, TimeUnit.MILLISECONDS));
|
||||
expectThrows(ExecutionException.class, future::get);
|
||||
assertThrows(ExecutionException.class, future::get);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupt thread blocked in close.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testClose4(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testClose4(ExecutorService executor) throws Exception {
|
||||
Future<?> future;
|
||||
try (executor) {
|
||||
future = executor.submit(SLEEP_FOR_A_DAY);
|
||||
@ -275,14 +273,15 @@ public class ThreadPerTaskExecutorTest {
|
||||
assertTrue(executor.isShutdown());
|
||||
assertTrue(executor.isTerminated());
|
||||
assertTrue(executor.awaitTermination(10, TimeUnit.MILLISECONDS));
|
||||
expectThrows(ExecutionException.class, future::get);
|
||||
assertThrows(ExecutionException.class, future::get);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close executor that is already closed.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testClose5(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testClose5(ExecutorService executor) throws Exception {
|
||||
executor.close();
|
||||
executor.close(); // already closed
|
||||
}
|
||||
@ -290,8 +289,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test awaitTermination when not shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testAwaitTermination1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testAwaitTermination1(ExecutorService executor) throws Exception {
|
||||
assertFalse(executor.awaitTermination(100, TimeUnit.MILLISECONDS));
|
||||
executor.close();
|
||||
assertTrue(executor.awaitTermination(100, TimeUnit.MILLISECONDS));
|
||||
@ -300,8 +300,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test awaitTermination with task running.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testAwaitTermination2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testAwaitTermination2(ExecutorService executor) throws Exception {
|
||||
Phaser barrier = new Phaser(2);
|
||||
Future<?> result = executor.submit(barrier::arriveAndAwaitAdvance);
|
||||
try {
|
||||
@ -317,8 +318,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test submit when the Executor is shutdown but not terminated.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testSubmitAfterShutdown(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testSubmitAfterShutdown(ExecutorService executor) throws Exception {
|
||||
Phaser barrier = new Phaser(2);
|
||||
try (executor) {
|
||||
// submit task to prevent executor from terminating
|
||||
@ -326,7 +328,7 @@ public class ThreadPerTaskExecutorTest {
|
||||
try {
|
||||
executor.shutdown();
|
||||
assertTrue(executor.isShutdown() && !executor.isTerminated());
|
||||
expectThrows(RejectedExecutionException.class,
|
||||
assertThrows(RejectedExecutionException.class,
|
||||
() -> executor.submit(() -> { }));
|
||||
} finally {
|
||||
barrier.arriveAndAwaitAdvance();
|
||||
@ -337,24 +339,27 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test submit when the Executor is terminated.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testSubmitAfterTermination(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testSubmitAfterTermination(ExecutorService executor) throws Exception {
|
||||
executor.shutdown();
|
||||
assertTrue(executor.isShutdown() && executor.isTerminated());
|
||||
expectThrows(RejectedExecutionException.class, () -> executor.submit(() -> {}));
|
||||
assertThrows(RejectedExecutionException.class, () -> executor.submit(() -> {}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test submit with null.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testSubmitNulls1(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testSubmitNulls1(ThreadFactory factory) {
|
||||
var executor = Executors.newThreadPerTaskExecutor(factory);
|
||||
assertThrows(NullPointerException.class, () -> executor.submit((Runnable) null));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "factories")
|
||||
public void testSubmitNulls2(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testSubmitNulls2(ThreadFactory factory) {
|
||||
var executor = Executors.newThreadPerTaskExecutor(factory);
|
||||
assertThrows(NullPointerException.class, () -> executor.submit((Callable<String>) null));
|
||||
}
|
||||
@ -362,8 +367,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny where all tasks complete normally.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAny1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAny1(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> "bar";
|
||||
@ -376,8 +382,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test invokeAny where all tasks complete normally. The completion of the
|
||||
* first task should cancel remaining tasks.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAny2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAny2(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
AtomicBoolean task2Started = new AtomicBoolean();
|
||||
AtomicReference<Throwable> task2Exception = new AtomicReference<>();
|
||||
@ -408,8 +415,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny where all tasks complete with exception.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAny3(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAny3(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
class FooException extends Exception { }
|
||||
Callable<String> task1 = () -> { throw new FooException(); };
|
||||
@ -428,8 +436,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test invokeAny where all tasks complete with exception. The completion
|
||||
* of the last task is delayed.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAny4(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAny4(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
class FooException extends Exception { }
|
||||
Callable<String> task1 = () -> { throw new FooException(); };
|
||||
@ -450,8 +459,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny where some, not all, tasks complete normally.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAny5(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAny5(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
class FooException extends Exception { }
|
||||
Callable<String> task1 = () -> "foo";
|
||||
@ -465,8 +475,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test invokeAny where some, not all, tasks complete normally. The
|
||||
* completion of the first task to complete normally is delayed.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAny6(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAny6(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
class FooException extends Exception { }
|
||||
Callable<String> task1 = () -> {
|
||||
@ -482,8 +493,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test timed-invokeAny where all tasks complete normally before the timeout.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAnyWithTimeout1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAnyWithTimeout1(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> "bar";
|
||||
@ -496,8 +508,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test timed-invokeAny where one task completes normally before the timeout.
|
||||
* The remaining tests should be cancelled.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAnyWithTimeout2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAnyWithTimeout2(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
AtomicBoolean task2Started = new AtomicBoolean();
|
||||
AtomicReference<Throwable> task2Exception = new AtomicReference<>();
|
||||
@ -528,8 +541,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test timed-invokeAny where timeout expires before any task completes.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAnyWithTimeout3(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAnyWithTimeout3(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> {
|
||||
Thread.sleep(Duration.ofMinutes(1));
|
||||
@ -548,8 +562,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test invokeAny where timeout expires after some tasks have completed
|
||||
* with exception.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAnyWithTimeout4(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAnyWithTimeout4(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
class FooException extends Exception { }
|
||||
Callable<String> task1 = () -> { throw new FooException(); };
|
||||
@ -565,8 +580,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny with interrupt status set.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAnyWithInterruptSet(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAnyWithInterruptSet(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> "bar";
|
||||
@ -585,8 +601,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test interrupting a thread blocked in invokeAny.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInterruptInvokeAny(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInterruptInvokeAny(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> {
|
||||
Thread.sleep(Duration.ofMinutes(1));
|
||||
@ -611,8 +628,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny after ExecutorService has been shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAnyAfterShutdown(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAnyAfterShutdown(ExecutorService executor) throws Exception {
|
||||
executor.shutdown();
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> "bar";
|
||||
@ -623,8 +641,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny with empty collection.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAnyEmpty1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAnyEmpty1(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
assertThrows(IllegalArgumentException.class, () -> executor.invokeAny(Set.of()));
|
||||
}
|
||||
@ -633,8 +652,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test timed-invokeAny with empty collection.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAnyEmpty2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAnyEmpty2(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> executor.invokeAny(Set.of(), 1, TimeUnit.MINUTES));
|
||||
@ -644,8 +664,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny with null.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAnyNull1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAnyNull1(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
assertThrows(NullPointerException.class, () -> executor.invokeAny(null));
|
||||
}
|
||||
@ -654,8 +675,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAny with null element
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAnyNull2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAnyNull2(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
List<Callable<String>> list = new ArrayList<>();
|
||||
list.add(() -> "foo");
|
||||
@ -667,8 +689,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll where all tasks complete normally.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAll1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAll1(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> {
|
||||
@ -692,8 +715,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll where all tasks complete with exception.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAll2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAll2(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
class FooException extends Exception { }
|
||||
class BarException extends Exception { }
|
||||
@ -711,9 +735,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
assertFalse(notDone);
|
||||
|
||||
// check results
|
||||
Throwable e1 = expectThrows(ExecutionException.class, () -> list.get(0).get());
|
||||
Throwable e1 = assertThrows(ExecutionException.class, () -> list.get(0).get());
|
||||
assertTrue(e1.getCause() instanceof FooException);
|
||||
Throwable e2 = expectThrows(ExecutionException.class, () -> list.get(1).get());
|
||||
Throwable e2 = assertThrows(ExecutionException.class, () -> list.get(1).get());
|
||||
assertTrue(e2.getCause() instanceof BarException);
|
||||
}
|
||||
}
|
||||
@ -721,8 +745,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll where all tasks complete normally before the timeout expires.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAll3(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAll3(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> {
|
||||
@ -746,8 +771,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll where some tasks do not complete before the timeout expires.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAll4(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAll4(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
AtomicReference<Exception> exc = new AtomicReference<>();
|
||||
Callable<String> task1 = () -> "foo";
|
||||
@ -784,8 +810,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll with interrupt status set.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllInterrupt1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllInterrupt1(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> {
|
||||
@ -808,8 +835,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test timed-invokeAll with interrupt status set.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllInterrupt3(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllInterrupt3(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
Callable<String> task2 = () -> {
|
||||
@ -832,8 +860,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test interrupt with thread blocked in invokeAll.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllInterrupt4(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllInterrupt4(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
DelayedResult<String> task2 = new DelayedResult("bar", Duration.ofMinutes(1));
|
||||
@ -858,8 +887,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test interrupt with thread blocked in timed-invokeAll.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllInterrupt6(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllInterrupt6(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
Callable<String> task1 = () -> "foo";
|
||||
DelayedResult<String> task2 = new DelayedResult("bar", Duration.ofMinutes(1));
|
||||
@ -884,8 +914,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll after ExecutorService has been shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllAfterShutdown1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllAfterShutdown1(ExecutorService executor) throws Exception {
|
||||
executor.shutdown();
|
||||
|
||||
Callable<String> task1 = () -> "foo";
|
||||
@ -894,8 +925,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
() -> executor.invokeAll(Set.of(task1, task2)));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllAfterShutdown2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllAfterShutdown2(ExecutorService executor) throws Exception {
|
||||
executor.shutdown();
|
||||
|
||||
Callable<String> task1 = () -> "foo";
|
||||
@ -907,31 +939,35 @@ public class ThreadPerTaskExecutorTest {
|
||||
/**
|
||||
* Test invokeAll with empty collection.
|
||||
*/
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllEmpty1(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllEmpty1(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
List<Future<Object>> list = executor.invokeAll(Set.of());
|
||||
assertTrue(list.size() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "executors")
|
||||
public void testInvokeAllEmpty2(ExecutorService executor) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("executors")
|
||||
void testInvokeAllEmpty2(ExecutorService executor) throws Exception {
|
||||
try (executor) {
|
||||
List<Future<Object>> list = executor.invokeAll(Set.of(), 1, TimeUnit.SECONDS);
|
||||
assertTrue(list.size() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAllNull1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAllNull1(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
assertThrows(NullPointerException.class, () -> executor.invokeAll(null));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAllNull2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAllNull2(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
List<Callable<String>> tasks = new ArrayList<>();
|
||||
tasks.add(() -> "foo");
|
||||
@ -940,16 +976,18 @@ public class ThreadPerTaskExecutorTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAllNull3(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAllNull3(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> executor.invokeAll(null, 1, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAllNull4(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAllNull4(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
Callable<String> task = () -> "foo";
|
||||
assertThrows(NullPointerException.class,
|
||||
@ -957,8 +995,9 @@ public class ThreadPerTaskExecutorTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInvokeAllNull5(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInvokeAllNull5(ThreadFactory factory) throws Exception {
|
||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||
List<Callable<String>> tasks = new ArrayList<>();
|
||||
tasks.add(() -> "foo");
|
||||
@ -972,33 +1011,33 @@ public class ThreadPerTaskExecutorTest {
|
||||
* Test ThreadFactory that does not produce any threads
|
||||
*/
|
||||
@Test
|
||||
public void testNoThreads1() throws Exception {
|
||||
void testNoThreads1() throws Exception {
|
||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||
assertThrows(RejectedExecutionException.class, () -> executor.execute(() -> { }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoThreads2() throws Exception {
|
||||
void testNoThreads2() throws Exception {
|
||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||
assertThrows(RejectedExecutionException.class, () -> executor.submit(() -> "foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoThreads3() throws Exception {
|
||||
void testNoThreads3() throws Exception {
|
||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||
assertThrows(RejectedExecutionException.class,
|
||||
() -> executor.invokeAll(List.of(() -> "foo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoThreads4() throws Exception {
|
||||
void testNoThreads4() throws Exception {
|
||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||
assertThrows(RejectedExecutionException.class,
|
||||
() -> executor.invokeAny(List.of(() -> "foo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull() {
|
||||
void testNull() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> Executors.newThreadPerTaskExecutor(null));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,7 +28,7 @@
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @library /test/lib
|
||||
* @key randomness
|
||||
* @run testng ManyBindings
|
||||
* @run junit ManyBindings
|
||||
*/
|
||||
|
||||
import jdk.incubator.concurrent.ScopedValue;
|
||||
@ -40,11 +40,10 @@ import java.util.Random;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import jdk.test.lib.thread.VThreadRunner;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Test
|
||||
public class ManyBindings {
|
||||
class ManyBindings {
|
||||
private static final Random RND = RandomFactory.getRandom();
|
||||
|
||||
// number of scoped values to create
|
||||
@ -56,14 +55,16 @@ public class ManyBindings {
|
||||
/**
|
||||
* Stress test bindings on platform thread.
|
||||
*/
|
||||
public void testPlatformThread() {
|
||||
@Test
|
||||
void testPlatformThread() {
|
||||
test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stress test bindings on virtual thread.
|
||||
*/
|
||||
public void testVirtualThread() throws Exception {
|
||||
@Test
|
||||
void testVirtualThread() throws Exception {
|
||||
VThreadRunner.run(() -> test());
|
||||
}
|
||||
|
||||
@ -143,7 +144,7 @@ public class ManyBindings {
|
||||
if (value == null) {
|
||||
assertFalse(key.isBound());
|
||||
} else {
|
||||
assertEquals(key.get(), value);
|
||||
assertEquals(value, key.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,7 +158,7 @@ public class ManyBindings {
|
||||
Integer value = array[index].value;
|
||||
if (value != null) {
|
||||
ScopedValue<Integer> key = array[index].key;
|
||||
assertEquals(key.get(), value);
|
||||
assertEquals(value, key.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
* @summary Test ScopedValue API
|
||||
* @enablePreview
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @run testng ScopeValueAPI
|
||||
* @run junit ScopeValueAPI
|
||||
*/
|
||||
|
||||
import jdk.incubator.concurrent.ScopedValue;
|
||||
@ -35,27 +35,25 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Test
|
||||
public class ScopeValueAPI {
|
||||
class ScopeValueAPI {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] factories() {
|
||||
return new Object[][] {
|
||||
{ Thread.ofPlatform().factory() },
|
||||
{ Thread.ofVirtual().factory() },
|
||||
};
|
||||
private static Stream<ThreadFactory> factories() {
|
||||
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the run method is invoked.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testRun(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testRun(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
class Box { static boolean executed; }
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
@ -67,8 +65,9 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test the run method throwing an exception.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testRunThrows(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testRunThrows(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
class FooException extends RuntimeException { }
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
@ -81,20 +80,22 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test that the call method is invoked.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCall(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCall(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
String result = ScopedValue.where(name, "duke", name::get);
|
||||
assertEquals(result, "duke");
|
||||
assertEquals("duke", result);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the call method throwing an exception.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCallThrows(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCallThrows(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
class FooException extends RuntimeException { }
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
@ -107,8 +108,9 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test get method.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testGet(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testGet(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name1 = ScopedValue.newInstance();
|
||||
ScopedValue<String> name2 = ScopedValue.newInstance();
|
||||
@ -117,7 +119,7 @@ public class ScopeValueAPI {
|
||||
|
||||
// run
|
||||
ScopedValue.where(name1, "duke", () -> {
|
||||
assertEquals(name1.get(), "duke");
|
||||
assertEquals("duke", name1.get());
|
||||
assertThrows(NoSuchElementException.class, name2::get);
|
||||
|
||||
});
|
||||
@ -126,7 +128,7 @@ public class ScopeValueAPI {
|
||||
|
||||
// call
|
||||
ScopedValue.where(name1, "duke", () -> {
|
||||
assertEquals(name1.get(), "duke");
|
||||
assertEquals("duke", name1.get());
|
||||
assertThrows(NoSuchElementException.class, name2::get);
|
||||
return null;
|
||||
});
|
||||
@ -138,8 +140,9 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test isBound method.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testIsBound(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testIsBound(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name1 = ScopedValue.newInstance();
|
||||
ScopedValue<String> name2 = ScopedValue.newInstance();
|
||||
@ -168,23 +171,24 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test orElse method.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testOrElse(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testOrElse(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
assertTrue(name.orElse(null) == null);
|
||||
assertEquals(name.orElse("default"), "default");
|
||||
assertNull(name.orElse(null));
|
||||
assertEquals("default", name.orElse("default"));
|
||||
|
||||
// run
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertEquals(name.orElse(null), "duke");
|
||||
assertEquals(name.orElse("default"), "duke");
|
||||
assertEquals("duke", name.orElse(null));
|
||||
assertEquals("duke", name.orElse("default"));
|
||||
});
|
||||
|
||||
// call
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertEquals(name.orElse(null), "duke");
|
||||
assertEquals(name.orElse("default"), "duke");
|
||||
assertEquals("duke", name.orElse(null));
|
||||
assertEquals("duke", name.orElse("default"));
|
||||
return null;
|
||||
});
|
||||
});
|
||||
@ -193,8 +197,9 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test orElseThrow method.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testOrElseThrow(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testOrElseThrow(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
class FooException extends RuntimeException { }
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
@ -202,12 +207,12 @@ public class ScopeValueAPI {
|
||||
|
||||
// run
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertEquals(name.orElseThrow(FooException::new), "duke");
|
||||
assertEquals("duke", name.orElseThrow(FooException::new));
|
||||
});
|
||||
|
||||
// call
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertEquals(name.orElseThrow(FooException::new), "duke");
|
||||
assertEquals("duke", name.orElseThrow(FooException::new));
|
||||
return null;
|
||||
});
|
||||
});
|
||||
@ -216,8 +221,9 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test two bindings.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testTwoBindings(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testTwoBindings(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
ScopedValue<Integer> age = ScopedValue.newInstance();
|
||||
@ -226,8 +232,8 @@ public class ScopeValueAPI {
|
||||
ScopedValue.where(name, "duke").where(age, 100).run(() -> {
|
||||
assertTrue(name.isBound());
|
||||
assertTrue(age.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals((int) age.get(), 100);
|
||||
assertEquals("duke", name.get());
|
||||
assertEquals(100, (int) age.get());
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
assertFalse(age.isBound());
|
||||
@ -236,8 +242,8 @@ public class ScopeValueAPI {
|
||||
ScopedValue.where(name, "duke").where(age, 100).call(() -> {
|
||||
assertTrue(name.isBound());
|
||||
assertTrue(age.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals((int) age.get(), 100);
|
||||
assertEquals("duke", name.get());
|
||||
assertEquals(100, (int) age.get());
|
||||
return null;
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
@ -249,39 +255,40 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test rebinding.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testRebinding(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testRebinding(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
|
||||
// run
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
|
||||
ScopedValue.where(name, "duchess", () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertTrue("duchess".equals(name.get()));
|
||||
assertEquals("duchess", name.get());
|
||||
});
|
||||
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
|
||||
// call
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
|
||||
ScopedValue.where(name, "duchess", () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertTrue("duchess".equals(name.get()));
|
||||
assertEquals("duchess", name.get());
|
||||
return null;
|
||||
});
|
||||
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
return null;
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
@ -291,15 +298,16 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test rebinding from null vaue to another value.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testRebindingFromNull(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testRebindingFromNull(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
|
||||
// run
|
||||
ScopedValue.where(name, null, () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), null);
|
||||
assertNull(name.get());
|
||||
|
||||
ScopedValue.where(name, "duchess", () -> {
|
||||
assertTrue(name.isBound());
|
||||
@ -307,14 +315,14 @@ public class ScopeValueAPI {
|
||||
});
|
||||
|
||||
assertTrue(name.isBound());
|
||||
assertTrue(name.get() == null);
|
||||
assertNull(name.get());
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
|
||||
// call
|
||||
ScopedValue.where(name, null, () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), null);
|
||||
assertNull(name.get());
|
||||
|
||||
ScopedValue.where(name, "duchess", () -> {
|
||||
assertTrue(name.isBound());
|
||||
@ -323,7 +331,7 @@ public class ScopeValueAPI {
|
||||
});
|
||||
|
||||
assertTrue(name.isBound());
|
||||
assertTrue(name.get() == null);
|
||||
assertNull(name.get());
|
||||
return null;
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
@ -333,39 +341,40 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test rebinding to null value.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testRebindingToNull(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testRebindingToNull(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
|
||||
// run
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
|
||||
ScopedValue.where(name, null, () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertTrue(name.get() == null);
|
||||
assertNull(name.get());
|
||||
});
|
||||
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
|
||||
// call
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
|
||||
ScopedValue.where(name, null, () -> {
|
||||
assertTrue(name.isBound());
|
||||
assertTrue(name.get() == null);
|
||||
assertNull(name.get());
|
||||
return null;
|
||||
});
|
||||
|
||||
assertTrue(name.isBound());
|
||||
assertEquals(name.get(), "duke");
|
||||
assertEquals("duke", name.get());
|
||||
return null;
|
||||
});
|
||||
assertFalse(name.isBound());
|
||||
@ -375,28 +384,30 @@ public class ScopeValueAPI {
|
||||
/**
|
||||
* Test Carrier.get.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCarrierGet(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCarrierGet(ThreadFactory factory) throws Exception {
|
||||
test(factory, () -> {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
ScopedValue<Integer> age = ScopedValue.newInstance();
|
||||
|
||||
// one scoped value
|
||||
var carrier1 = ScopedValue.where(name, "duke");
|
||||
assertEquals(carrier1.get(name), "duke");
|
||||
assertEquals("duke", carrier1.get(name));
|
||||
assertThrows(NoSuchElementException.class, () -> carrier1.get(age));
|
||||
|
||||
// two scoped values
|
||||
var carrier2 = carrier1.where(age, 20);
|
||||
assertEquals(carrier2.get(name), "duke");
|
||||
assertEquals((int) carrier2.get(age), 20);
|
||||
assertEquals("duke", carrier2.get(name));
|
||||
assertEquals(20, (int) carrier2.get(age));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test NullPointerException.
|
||||
*/
|
||||
public void testNullPointerException() {
|
||||
@Test
|
||||
void testNullPointerException() {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
|
||||
assertThrows(NullPointerException.class, () -> ScopedValue.where(null, "value"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,19 +26,19 @@
|
||||
* @bug 8284199
|
||||
* @summary Test StructuredTaskScope without --enable-preview
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @run testng/othervm PreviewFeaturesNotEnabled
|
||||
* @run junit/othervm PreviewFeaturesNotEnabled
|
||||
*/
|
||||
|
||||
import jdk.incubator.concurrent.StructuredTaskScope;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class PreviewFeaturesNotEnabled {
|
||||
class PreviewFeaturesNotEnabled {
|
||||
/**
|
||||
* One-arg constructor needs --enable-preview.
|
||||
*/
|
||||
@Test
|
||||
public void testUnsupportedOperationException() {
|
||||
void testUnsupportedOperationException() {
|
||||
assertThrows(UnsupportedOperationException.class, StructuredTaskScope::new);
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ public class PreviewFeaturesNotEnabled {
|
||||
* Two-arg constructor does not need --enable-preview.
|
||||
*/
|
||||
@Test
|
||||
public void testNoUnsupportedOperationException() {
|
||||
void testNoUnsupportedOperationException() {
|
||||
try (var scope = new StructuredTaskScope<Object>(null, Thread::new)) {
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,14 @@
|
||||
* @summary Basic tests for StructuredTaskScope
|
||||
* @enablePreview
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @run testng/othervm -DthreadFactory=platform StructuredTaskScopeTest
|
||||
* @run junit/othervm -DthreadFactory=platform StructuredTaskScopeTest
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test id=virtual
|
||||
* @enablePreview
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @run testng/othervm -DthreadFactory=virtual StructuredTaskScopeTest
|
||||
* @run junit/othervm -DthreadFactory=virtual StructuredTaskScopeTest
|
||||
*/
|
||||
|
||||
import jdk.incubator.concurrent.StructuredTaskScope;
|
||||
@ -65,24 +65,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class StructuredTaskScopeTest {
|
||||
private ScheduledExecutorService scheduler;
|
||||
private Object[][] threadFactories;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() throws Exception {
|
||||
ThreadFactory factory = (task) -> {
|
||||
Thread thread = new Thread(task);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
};
|
||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(factory);
|
||||
class StructuredTaskScopeTest {
|
||||
private static ScheduledExecutorService scheduler;
|
||||
private static List<ThreadFactory> threadFactories;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() throws Exception {
|
||||
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
// thread factories
|
||||
String value = System.getProperty("threadFactory");
|
||||
@ -92,29 +89,24 @@ public class StructuredTaskScopeTest {
|
||||
if (value == null || value.equals("virtual"))
|
||||
list.add(Thread.ofVirtual().factory());
|
||||
assertTrue(list.size() > 0, "No thread factories for tests");
|
||||
this.threadFactories = list.stream()
|
||||
.map(f -> new Object[] { f })
|
||||
.toArray(Object[][]::new);
|
||||
threadFactories = list;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void tearDown() {
|
||||
@AfterAll
|
||||
static void shutdown() {
|
||||
scheduler.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* A provider of ThreadFactory objects for tests.
|
||||
*/
|
||||
@DataProvider
|
||||
public Object[][] factories() {
|
||||
return threadFactories;
|
||||
private static Stream<ThreadFactory> factories() {
|
||||
return threadFactories.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that each fork creates a thread.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFork1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFork1(ThreadFactory factory) throws Exception {
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
@ -128,8 +120,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test that fork uses the specified thread factory.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFork2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFork2(ThreadFactory factory) throws Exception {
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
ThreadFactory countingFactory = task -> {
|
||||
count.incrementAndGet();
|
||||
@ -147,8 +140,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test fork is confined to threads in the scope "tree".
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testForkConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testForkConfined(ThreadFactory factory) throws Exception {
|
||||
try (var scope1 = new StructuredTaskScope();
|
||||
var scope2 = new StructuredTaskScope()) {
|
||||
|
||||
@ -157,7 +151,7 @@ public class StructuredTaskScopeTest {
|
||||
scope2.fork(() -> null).get();
|
||||
return null;
|
||||
});
|
||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
|
||||
// thread in scope2 can fork thread in scope1
|
||||
@ -166,7 +160,7 @@ public class StructuredTaskScopeTest {
|
||||
return null;
|
||||
});
|
||||
future2.get();
|
||||
assertTrue(future2.resultNow() == null);
|
||||
assertNull(future2.resultNow());
|
||||
|
||||
// random thread cannot fork
|
||||
try (var pool = Executors.newCachedThreadPool(factory)) {
|
||||
@ -174,7 +168,7 @@ public class StructuredTaskScopeTest {
|
||||
scope1.fork(() -> null);
|
||||
return null;
|
||||
});
|
||||
ex = expectThrows(ExecutionException.class, future::get);
|
||||
ex = assertThrows(ExecutionException.class, future::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
}
|
||||
|
||||
@ -186,8 +180,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test fork when scope is shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testForkAfterShutdown(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testForkAfterShutdown(ThreadFactory factory) throws Exception {
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
scope.shutdown();
|
||||
@ -204,8 +199,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test fork when scope is closed.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testForkAfterClose(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testForkAfterClose(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
scope.join();
|
||||
scope.close();
|
||||
@ -217,7 +213,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test fork when the thread factory rejects creating a thread.
|
||||
*/
|
||||
@Test
|
||||
public void testForkReject() throws Exception {
|
||||
void testForkReject() throws Exception {
|
||||
ThreadFactory factory = task -> null;
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
assertThrows(RejectedExecutionException.class, () -> scope.fork(() -> null));
|
||||
@ -255,8 +251,9 @@ public class StructuredTaskScopeTest {
|
||||
* Test that handleComplete method is invoked for tasks that complete normally
|
||||
* and abnormally.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testHandleComplete1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testHandleComplete1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new CollectAll(factory)) {
|
||||
|
||||
// completes normally
|
||||
@ -275,17 +272,17 @@ public class StructuredTaskScopeTest {
|
||||
scope.join();
|
||||
|
||||
Set<Future<String>> futures = scope.futuresAsSet();
|
||||
assertEquals(futures, Set.of(future1, future2, future3));
|
||||
assertEquals(Set.of(future1, future2, future3), futures);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the handeComplete method is not invoked after the scope has been shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testHandleComplete2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testHandleComplete2(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new CollectAll(factory)) {
|
||||
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
// start task that does not respond to interrupt
|
||||
@ -322,7 +319,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test join with no threads.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinWithNoThreads() throws Exception {
|
||||
void testJoinWithNoThreads() throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
scope.join();
|
||||
}
|
||||
@ -331,30 +328,32 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test join with threads running.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinWithThreads(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinWithThreads(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofMillis(50));
|
||||
return "foo";
|
||||
});
|
||||
scope.join();
|
||||
assertEquals(future.resultNow(), "foo");
|
||||
assertEquals("foo", future.resultNow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test join is owner confined.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinConfined(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
// attempt to join on thread in scope
|
||||
Future<Void> future1 = scope.fork(() -> {
|
||||
scope.join();
|
||||
return null;
|
||||
});
|
||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
|
||||
// random thread cannot join
|
||||
@ -363,7 +362,7 @@ public class StructuredTaskScopeTest {
|
||||
scope.join();
|
||||
return null;
|
||||
});
|
||||
ex = expectThrows(ExecutionException.class, future2::get);
|
||||
ex = assertThrows(ExecutionException.class, future2::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
}
|
||||
|
||||
@ -374,11 +373,14 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test join with interrupt status set.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptJoin1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptJoin1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofMillis(100));
|
||||
latch.await();
|
||||
return "foo";
|
||||
});
|
||||
|
||||
@ -389,22 +391,28 @@ public class StructuredTaskScopeTest {
|
||||
fail("join did not throw");
|
||||
} catch (InterruptedException expected) {
|
||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||
} finally {
|
||||
// let task continue
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
// join should complete
|
||||
scope.join();
|
||||
assertEquals(future.resultNow(), "foo");
|
||||
assertEquals("foo", future.resultNow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test interrupt of thread blocked in join.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptJoin2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptJoin2(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofSeconds(3));
|
||||
latch.await();
|
||||
return "foo";
|
||||
});
|
||||
|
||||
@ -415,19 +423,23 @@ public class StructuredTaskScopeTest {
|
||||
fail("join did not throw");
|
||||
} catch (InterruptedException expected) {
|
||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||
} finally {
|
||||
// let task continue
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
// join should complete
|
||||
scope.join();
|
||||
assertEquals(future.resultNow(), "foo");
|
||||
assertEquals("foo", future.resultNow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test join when scope is already shutdown.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinWithShutdown1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinWithShutdown1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofDays(1));
|
||||
@ -444,8 +456,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test shutdown when owner is blocked in join.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinWithShutdown2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinWithShutdown2(ThreadFactory factory) throws Exception {
|
||||
class MyScope<T> extends StructuredTaskScope<T> {
|
||||
MyScope(ThreadFactory factory) {
|
||||
super(null, factory);
|
||||
@ -479,7 +492,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test join after scope is shutdown.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinAfterShutdown() throws Exception {
|
||||
void testJoinAfterShutdown() throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
scope.shutdown();
|
||||
scope.join();
|
||||
@ -490,7 +503,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test join after scope is closed.
|
||||
*/
|
||||
@Test
|
||||
public void testJoinAfterClose() throws Exception {
|
||||
void testJoinAfterClose() throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
scope.join();
|
||||
scope.close();
|
||||
@ -502,8 +515,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test joinUntil, threads finish before deadline expires.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinUntil1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinUntil1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
try {
|
||||
@ -514,7 +528,8 @@ public class StructuredTaskScopeTest {
|
||||
|
||||
long startMillis = millisTime();
|
||||
scope.joinUntil(Instant.now().plusSeconds(30));
|
||||
assertTrue(future.isDone() && future.resultNow() == null);
|
||||
assertTrue(future.isDone());
|
||||
assertNull(future.resultNow());
|
||||
expectDuration(startMillis, /*min*/1900, /*max*/20_000);
|
||||
}
|
||||
}
|
||||
@ -522,8 +537,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test joinUntil, deadline expires before threads finish.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinUntil2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinUntil2(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
try {
|
||||
@ -545,8 +561,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test joinUntil many times.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinUntil3(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinUntil3(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
try {
|
||||
@ -573,8 +590,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test joinUntil with a deadline that has already expired.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testJoinUntil4(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testJoinUntil4(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
try {
|
||||
@ -610,37 +628,46 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test joinUntil with interrupt status set.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptJoinUntil1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptJoinUntil1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofSeconds(2));
|
||||
latch.await();
|
||||
return "foo";
|
||||
});
|
||||
|
||||
// joinUntil should throw
|
||||
Thread.currentThread().interrupt();
|
||||
try {
|
||||
scope.joinUntil(Instant.now().plusSeconds(10));
|
||||
scope.joinUntil(Instant.now().plusSeconds(30));
|
||||
fail("joinUntil did not throw");
|
||||
} catch (InterruptedException expected) {
|
||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||
} finally {
|
||||
// let task continue
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
// join should complete
|
||||
scope.join();
|
||||
assertEquals(future.resultNow(), "foo");
|
||||
assertEquals("foo", future.resultNow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test interrupt of thread blocked in joinUntil.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptJoinUntil2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptJoinUntil2(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofSeconds(3));
|
||||
latch.await();
|
||||
return "foo";
|
||||
});
|
||||
|
||||
@ -651,18 +678,22 @@ public class StructuredTaskScopeTest {
|
||||
fail("joinUntil did not throw");
|
||||
} catch (InterruptedException expected) {
|
||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||
} finally {
|
||||
// let task continue
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
// join should complete
|
||||
scope.join();
|
||||
assertEquals(future.resultNow(), "foo");
|
||||
assertEquals("foo", future.resultNow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test shutdown after scope is closed.
|
||||
*/
|
||||
public void testShutdownAfterClose() throws Exception {
|
||||
@Test
|
||||
void testShutdownAfterClose() throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
scope.join();
|
||||
scope.close();
|
||||
@ -673,8 +704,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test shutdown is confined to threads in the scope "tree".
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testShutdownConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testShutdownConfined(ThreadFactory factory) throws Exception {
|
||||
try (var scope1 = new StructuredTaskScope();
|
||||
var scope2 = new StructuredTaskScope()) {
|
||||
|
||||
@ -684,7 +716,7 @@ public class StructuredTaskScopeTest {
|
||||
scope1.shutdown();
|
||||
return null;
|
||||
});
|
||||
Throwable ex = expectThrows(ExecutionException.class, future::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
}
|
||||
|
||||
@ -693,7 +725,7 @@ public class StructuredTaskScopeTest {
|
||||
scope2.shutdown();
|
||||
return null;
|
||||
});
|
||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
|
||||
// thread in scope2 can shutdown scope1
|
||||
@ -702,7 +734,7 @@ public class StructuredTaskScopeTest {
|
||||
return null;
|
||||
});
|
||||
future2.get();
|
||||
assertTrue(future2.resultNow() == null);
|
||||
assertNull(future2.resultNow());
|
||||
|
||||
scope2.join();
|
||||
scope1.join();
|
||||
@ -712,7 +744,8 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test close without join, no threads forked.
|
||||
*/
|
||||
public void testCloseWithoutJoin1() {
|
||||
@Test
|
||||
void testCloseWithoutJoin1() {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
// do nothing
|
||||
}
|
||||
@ -721,8 +754,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test close without join, threads forked.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCloseWithoutJoin2(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCloseWithoutJoin2(ThreadFactory factory) {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
Future<String> future = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofDays(1));
|
||||
@ -736,8 +770,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test close with threads forked after join.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCloseWithoutJoin3(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCloseWithoutJoin3(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
scope.fork(() -> "foo");
|
||||
scope.join();
|
||||
@ -754,15 +789,16 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test close is owner confined.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCloseConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCloseConfined(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
// attempt to close on thread in scope
|
||||
Future<Void> future1 = scope.fork(() -> {
|
||||
scope.close();
|
||||
return null;
|
||||
});
|
||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
|
||||
// random thread cannot close scope
|
||||
@ -771,7 +807,7 @@ public class StructuredTaskScopeTest {
|
||||
scope.close();
|
||||
return null;
|
||||
});
|
||||
ex = expectThrows(ExecutionException.class, future2::get);
|
||||
ex = assertThrows(ExecutionException.class, future2::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
}
|
||||
|
||||
@ -782,8 +818,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test close with interrupt status set.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptClose1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptClose1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
@ -818,8 +855,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test interrupting thread waiting in close.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptClose2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptClose2(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
@ -854,7 +892,7 @@ public class StructuredTaskScopeTest {
|
||||
* nested scope.
|
||||
*/
|
||||
@Test
|
||||
public void testStructureViolation1() throws Exception {
|
||||
void testStructureViolation1() throws Exception {
|
||||
try (var scope1 = new StructuredTaskScope()) {
|
||||
try (var scope2 = new StructuredTaskScope()) {
|
||||
|
||||
@ -881,8 +919,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test Future::get, task completes normally.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFuture1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFuture1(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
@ -890,9 +929,9 @@ public class StructuredTaskScopeTest {
|
||||
return "foo";
|
||||
});
|
||||
|
||||
assertEquals(future.get(), "foo");
|
||||
assertEquals("foo", future.get());
|
||||
assertTrue(future.state() == Future.State.SUCCESS);
|
||||
assertEquals(future.resultNow(), "foo");
|
||||
assertEquals("foo", future.resultNow());
|
||||
|
||||
scope.join();
|
||||
}
|
||||
@ -901,8 +940,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test Future::get, task completes with exception.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFuture2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFuture2(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
@ -910,7 +950,7 @@ public class StructuredTaskScopeTest {
|
||||
throw new FooException();
|
||||
});
|
||||
|
||||
Throwable ex = expectThrows(ExecutionException.class, future::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future::get);
|
||||
assertTrue(ex.getCause() instanceof FooException);
|
||||
assertTrue(future.state() == Future.State.FAILED);
|
||||
assertTrue(future.exceptionNow() instanceof FooException);
|
||||
@ -922,8 +962,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test Future::get, task is cancelled.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFuture3(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFuture3(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
|
||||
Future<String> future = scope.fork(() -> {
|
||||
@ -948,8 +989,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test scope shutdown with a thread blocked in Future::get.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFutureWithShutdown(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFutureWithShutdown(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||
|
||||
// long running task
|
||||
@ -985,8 +1027,9 @@ public class StructuredTaskScopeTest {
|
||||
/**
|
||||
* Test Future::cancel throws if invoked by a thread that is not in the tree.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testFutureCancelConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testFutureCancelConfined(ThreadFactory factory) throws Exception {
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
Future<String> future1 = scope.fork(() -> {
|
||||
Thread.sleep(Duration.ofDays(1));
|
||||
@ -999,7 +1042,7 @@ public class StructuredTaskScopeTest {
|
||||
future1.cancel(true);
|
||||
return null;
|
||||
});
|
||||
Throwable ex = expectThrows(ExecutionException.class, future2::get);
|
||||
Throwable ex = assertThrows(ExecutionException.class, future2::get);
|
||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||
} finally {
|
||||
future1.cancel(true);
|
||||
@ -1012,7 +1055,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test StructuredTaskScope::toString includes the scope name.
|
||||
*/
|
||||
@Test
|
||||
public void testToString() throws Exception {
|
||||
void testToString() throws Exception {
|
||||
ThreadFactory factory = Thread.ofVirtual().factory();
|
||||
try (var scope = new StructuredTaskScope("xxx", factory)) {
|
||||
// open
|
||||
@ -1033,7 +1076,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test for NullPointerException.
|
||||
*/
|
||||
@Test
|
||||
public void testNulls() throws Exception {
|
||||
void testNulls() throws Exception {
|
||||
assertThrows(NullPointerException.class, () -> new StructuredTaskScope("", null));
|
||||
try (var scope = new StructuredTaskScope()) {
|
||||
assertThrows(NullPointerException.class, () -> scope.fork(null));
|
||||
@ -1059,7 +1102,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnSuccess with no completed tasks.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnSuccess1() throws Exception {
|
||||
void testShutdownOnSuccess1() throws Exception {
|
||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||
assertThrows(IllegalStateException.class, () -> scope.result());
|
||||
assertThrows(IllegalStateException.class, () -> scope.result(e -> null));
|
||||
@ -1070,7 +1113,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnSuccess with tasks that completed normally.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnSuccess2() throws Exception {
|
||||
void testShutdownOnSuccess2() throws Exception {
|
||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||
|
||||
// two tasks complete normally
|
||||
@ -1079,8 +1122,8 @@ public class StructuredTaskScopeTest {
|
||||
scope.fork(() -> "bar");
|
||||
scope.join();
|
||||
|
||||
assertEquals(scope.result(), "foo");
|
||||
assertEquals(scope.result(e -> null), "foo");
|
||||
assertEquals("foo", scope.result());
|
||||
assertEquals("foo", scope.result(e -> null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1088,7 +1131,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnSuccess with tasks that completed normally and abnormally.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnSuccess3() throws Exception {
|
||||
void testShutdownOnSuccess3() throws Exception {
|
||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||
|
||||
// one task completes normally, the other with an exception
|
||||
@ -1096,8 +1139,8 @@ public class StructuredTaskScopeTest {
|
||||
scope.fork(() -> { throw new ArithmeticException(); });
|
||||
scope.join();
|
||||
|
||||
assertEquals(scope.result(), "foo");
|
||||
assertEquals(scope.result(e -> null), "foo");
|
||||
assertEquals("foo", scope.result());
|
||||
assertEquals("foo", scope.result(e -> null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1105,17 +1148,17 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnSuccess with a task that completed with an exception.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnSuccess4() throws Exception {
|
||||
void testShutdownOnSuccess4() throws Exception {
|
||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||
|
||||
// tasks completes with exception
|
||||
scope.fork(() -> { throw new ArithmeticException(); });
|
||||
scope.join();
|
||||
|
||||
Throwable ex = expectThrows(ExecutionException.class, () -> scope.result());
|
||||
Throwable ex = assertThrows(ExecutionException.class, () -> scope.result());
|
||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||
|
||||
ex = expectThrows(FooException.class, () -> scope.result(e -> new FooException(e)));
|
||||
ex = assertThrows(FooException.class, () -> scope.result(e -> new FooException(e)));
|
||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||
}
|
||||
}
|
||||
@ -1124,7 +1167,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnSuccess with a cancelled task.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnSuccess5() throws Exception {
|
||||
void testShutdownOnSuccess5() throws Exception {
|
||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||
|
||||
// cancelled task
|
||||
@ -1137,7 +1180,7 @@ public class StructuredTaskScopeTest {
|
||||
scope.join();
|
||||
|
||||
assertThrows(CancellationException.class, () -> scope.result());
|
||||
Throwable ex = expectThrows(FooException.class,
|
||||
Throwable ex = assertThrows(FooException.class,
|
||||
() -> scope.result(e -> new FooException(e)));
|
||||
assertTrue(ex.getCause() instanceof CancellationException);
|
||||
}
|
||||
@ -1147,7 +1190,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnFailure with no completed tasks.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnFailure1() throws Throwable {
|
||||
void testShutdownOnFailure1() throws Throwable {
|
||||
try (var scope = new ShutdownOnFailure()) {
|
||||
assertTrue(scope.exception().isEmpty());
|
||||
scope.throwIfFailed();
|
||||
@ -1159,7 +1202,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnFailure with tasks that completed normally.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnFailure2() throws Throwable {
|
||||
void testShutdownOnFailure2() throws Throwable {
|
||||
try (var scope = new ShutdownOnFailure()) {
|
||||
scope.fork(() -> "foo");
|
||||
scope.fork(() -> "bar");
|
||||
@ -1176,7 +1219,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnFailure with tasks that completed normally and abnormally.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnFailure3() throws Throwable {
|
||||
void testShutdownOnFailure3() throws Throwable {
|
||||
try (var scope = new ShutdownOnFailure()) {
|
||||
|
||||
// one task completes normally, the other with an exception
|
||||
@ -1187,10 +1230,10 @@ public class StructuredTaskScopeTest {
|
||||
Throwable ex = scope.exception().orElse(null);
|
||||
assertTrue(ex instanceof ArithmeticException);
|
||||
|
||||
ex = expectThrows(ExecutionException.class, () -> scope.throwIfFailed());
|
||||
ex = assertThrows(ExecutionException.class, () -> scope.throwIfFailed());
|
||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||
|
||||
ex = expectThrows(FooException.class,
|
||||
ex = assertThrows(FooException.class,
|
||||
() -> scope.throwIfFailed(e -> new FooException(e)));
|
||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||
}
|
||||
@ -1200,7 +1243,7 @@ public class StructuredTaskScopeTest {
|
||||
* Test ShutdownOnFailure with a cancelled task.
|
||||
*/
|
||||
@Test
|
||||
public void testShutdownOnFailure4() throws Throwable {
|
||||
void testShutdownOnFailure4() throws Throwable {
|
||||
try (var scope = new ShutdownOnFailure()) {
|
||||
|
||||
var future = scope.fork(() -> {
|
||||
@ -1216,7 +1259,7 @@ public class StructuredTaskScopeTest {
|
||||
|
||||
assertThrows(CancellationException.class, () -> scope.throwIfFailed());
|
||||
|
||||
ex = expectThrows(FooException.class,
|
||||
ex = assertThrows(FooException.class,
|
||||
() -> scope.throwIfFailed(e -> new FooException(e)));
|
||||
assertTrue(ex.getCause() instanceof CancellationException);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,7 +28,7 @@
|
||||
* @enablePreview
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @library /test/lib
|
||||
* @run testng/othervm StructuredThreadDumpTest
|
||||
* @run junit/othervm StructuredThreadDumpTest
|
||||
*/
|
||||
|
||||
import jdk.incubator.concurrent.StructuredTaskScope;
|
||||
@ -43,17 +43,17 @@ import java.util.stream.Stream;
|
||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||
import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat;
|
||||
import jdk.test.lib.threaddump.ThreadDump;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class StructuredThreadDumpTest {
|
||||
class StructuredThreadDumpTest {
|
||||
|
||||
/**
|
||||
* Test that a thread dump with a tree of task scopes contains a thread grouping for
|
||||
* each task scope.
|
||||
*/
|
||||
@Test
|
||||
public void testTree() throws Exception {
|
||||
void testTree() throws Exception {
|
||||
ThreadFactory factory = Thread.ofVirtual().factory();
|
||||
try (var scope = new StructuredTaskScope<>("scope", factory)) {
|
||||
Thread thread1 = fork(scope, "child-scope-A");
|
||||
@ -95,7 +95,7 @@ public class StructuredThreadDumpTest {
|
||||
* each task scope.
|
||||
*/
|
||||
@Test
|
||||
public void testNested() throws Exception {
|
||||
void testNested() throws Exception {
|
||||
ThreadFactory factory = Thread.ofVirtual().factory();
|
||||
try (var scope1 = new StructuredTaskScope<>("scope-A", factory)) {
|
||||
Thread thread1 = fork(scope1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
* @summary Basic tests for StructuredTaskScope with scoped values
|
||||
* @enablePreview
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @run testng WithScopedValue
|
||||
* @run junit WithScopedValue
|
||||
*/
|
||||
|
||||
import jdk.incubator.concurrent.ScopedValue;
|
||||
@ -35,27 +35,25 @@ import jdk.incubator.concurrent.StructureViolationException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Test
|
||||
public class WithScopedValue {
|
||||
class WithScopedValue {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] factories() {
|
||||
return new Object[][] {
|
||||
{ Thread.ofPlatform().factory() },
|
||||
{ Thread.ofVirtual().factory() },
|
||||
};
|
||||
private static Stream<ThreadFactory> factories() {
|
||||
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that fork inherits a scoped value into a child thread.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testForkInheritsScopedValue1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testForkInheritsScopedValue1(ThreadFactory factory) throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
String value = ScopedValue.where(name, "x", () -> {
|
||||
try (var scope = new StructuredTaskScope<String>(null, factory)) {
|
||||
@ -72,8 +70,9 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test that fork inherits a scoped value into a grandchild thread.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testForkInheritsScopedValue2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testForkInheritsScopedValue2(ThreadFactory factory) throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
String value = ScopedValue.where(name, "x", () -> {
|
||||
try (var scope1 = new StructuredTaskScope<String>(null, factory)) {
|
||||
@ -96,8 +95,9 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test that fork inherits a rebound scoped value into a grandchild thread.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testForkInheritsScopedValue3(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testForkInheritsScopedValue3(ThreadFactory factory) throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
String value = ScopedValue.where(name, "x", () -> {
|
||||
try (var scope1 = new StructuredTaskScope<String>(null, factory)) {
|
||||
@ -128,7 +128,8 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test exiting a dynamic scope with an open task scope.
|
||||
*/
|
||||
public void testStructureViolation1() throws Exception {
|
||||
@Test
|
||||
void testStructureViolation1() throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
class Box {
|
||||
StructuredTaskScope<Object> scope;
|
||||
@ -164,7 +165,8 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test closing a StructuredTaskScope while executing in a dynamic scope.
|
||||
*/
|
||||
public void testStructureViolation2() throws Exception {
|
||||
@Test
|
||||
void testStructureViolation2() throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
try (var scope = new StructuredTaskScope<String>()) {
|
||||
ScopedValue.where(name, "x", () -> {
|
||||
@ -176,7 +178,8 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test fork when a scoped value is bound after a StructuredTaskScope is created.
|
||||
*/
|
||||
public void testStructureViolation3() throws Exception {
|
||||
@Test
|
||||
void testStructureViolation3() throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
try (var scope = new StructuredTaskScope<String>()) {
|
||||
ScopedValue.where(name, "x", () -> {
|
||||
@ -189,7 +192,8 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test fork when a scoped value is re-bound after a StructuredTaskScope is created.
|
||||
*/
|
||||
public void testStructureViolation4() throws Exception {
|
||||
@Test
|
||||
void testStructureViolation4() throws Exception {
|
||||
ScopedValue<String> name1 = ScopedValue.newInstance();
|
||||
ScopedValue<String> name2 = ScopedValue.newInstance();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,14 +26,14 @@
|
||||
* @summary Basic tests for ThreadFlock
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @enablePreview
|
||||
* @run testng/othervm -DthreadFactory=platform ThreadFlockTest
|
||||
* @run junit/othervm -DthreadFactory=platform ThreadFlockTest
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test id=virtual
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @enablePreview
|
||||
* @run testng/othervm -DthreadFactory=virtual ThreadFlockTest
|
||||
* @run junit/othervm -DthreadFactory=virtual ThreadFlockTest
|
||||
*/
|
||||
|
||||
import java.time.Duration;
|
||||
@ -43,26 +43,23 @@ import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.internal.misc.ThreadFlock;
|
||||
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ThreadFlockTest {
|
||||
private ScheduledExecutorService scheduler;
|
||||
private Object[][] threadFactories;
|
||||
class ThreadFlockTest {
|
||||
private static ScheduledExecutorService scheduler;
|
||||
private static List<ThreadFactory> threadFactories;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() throws Exception {
|
||||
ThreadFactory factory = (task) -> {
|
||||
Thread thread = new Thread(task);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
};
|
||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(factory);
|
||||
@BeforeAll
|
||||
static void setup() throws Exception {
|
||||
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
// thread factories
|
||||
String value = System.getProperty("threadFactory");
|
||||
@ -72,35 +69,32 @@ public class ThreadFlockTest {
|
||||
if (value == null || value.equals("virtual"))
|
||||
list.add(Thread.ofVirtual().factory());
|
||||
assertTrue(list.size() > 0, "No thread factories for tests");
|
||||
this.threadFactories = list.stream()
|
||||
.map(f -> new Object[] { f })
|
||||
.toArray(Object[][]::new);
|
||||
threadFactories = list;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void tearDown() {
|
||||
@AfterAll
|
||||
static void shutdown() {
|
||||
scheduler.shutdown();
|
||||
}
|
||||
|
||||
@DataProvider(name = "factories")
|
||||
public Object[][] factories() {
|
||||
return threadFactories;
|
||||
private static Stream<ThreadFactory> factories() {
|
||||
return threadFactories.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ThreadFlock::name.
|
||||
*/
|
||||
@Test
|
||||
public void testName() {
|
||||
void testName() {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
assertEquals(flock.name(), null);
|
||||
assertNull(flock.name());
|
||||
flock.close();
|
||||
assertEquals(flock.name(), null); // after close
|
||||
assertNull(flock.name()); // after close
|
||||
}
|
||||
try (var flock = ThreadFlock.open("fetcher")) {
|
||||
assertEquals(flock.name(), "fetcher");
|
||||
assertEquals("fetcher", flock.name());
|
||||
flock.close();
|
||||
assertEquals(flock.name(), "fetcher"); // after close
|
||||
assertEquals("fetcher", flock.name()); // after close
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +102,7 @@ public class ThreadFlockTest {
|
||||
* Test ThreadFlock::owner.
|
||||
*/
|
||||
@Test
|
||||
public void testOwner() {
|
||||
void testOwner() {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
assertTrue(flock.owner() == Thread.currentThread());
|
||||
flock.close();
|
||||
@ -120,7 +114,7 @@ public class ThreadFlockTest {
|
||||
* Test ThreadFlock::isXXXX methods.
|
||||
*/
|
||||
@Test
|
||||
public void testState() {
|
||||
void testState() {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
assertFalse(flock.isShutdown());
|
||||
assertFalse(flock.isClosed());
|
||||
@ -141,8 +135,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test ThreadFlock::threads enumerates all threads.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testThreads(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testThreads(ThreadFactory factory) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
Runnable awaitLatch = () -> {
|
||||
@ -166,21 +161,22 @@ public class ThreadFlockTest {
|
||||
}
|
||||
|
||||
// check thread ThreadFlock::threads enumerates all threads
|
||||
assertEquals(threads, flock.threads().collect(Collectors.toSet()));
|
||||
assertEquals(flock.threads().collect(Collectors.toSet()), threads);
|
||||
|
||||
} finally {
|
||||
latch.countDown(); // release threads
|
||||
flock.close();
|
||||
}
|
||||
assertTrue(flock.threads().count() == 0);
|
||||
assertTrue(exception.get() == null);
|
||||
assertNull(exception.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ThreadFlock::containsThread with nested flocks.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testContainsThread1(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testContainsThread1(ThreadFactory factory) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
|
||||
@ -222,8 +218,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test ThreadFlock::containsThread with a tree of flocks.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testContainsThread2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testContainsThread2(ThreadFactory factory) throws Exception {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
|
||||
@ -276,8 +273,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test that start causes a thread to execute.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStart(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStart(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
AtomicBoolean executed = new AtomicBoolean();
|
||||
Thread thread = factory.newThread(() -> executed.set(true));
|
||||
@ -290,44 +288,48 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test that start throws IllegalStateException when shutdown
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStartAfterShutdown(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStartAfterShutdown(ThreadFactory factory) {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
flock.shutdown();
|
||||
Thread thread = factory.newThread(() -> { });
|
||||
expectThrows(IllegalStateException.class, () -> flock.start(thread));
|
||||
assertThrows(IllegalStateException.class, () -> flock.start(thread));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that start throws IllegalStateException when closed
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStartAfterClose(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStartAfterClose(ThreadFactory factory) {
|
||||
var flock = ThreadFlock.open(null);
|
||||
flock.close();;
|
||||
Thread thread = factory.newThread(() -> { });
|
||||
expectThrows(IllegalStateException.class, () -> flock.start(thread));
|
||||
assertThrows(IllegalStateException.class, () -> flock.start(thread));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that start throws IllegalThreadStateException when invoked to
|
||||
* start a thread that has already started.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStartAfterStarted(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStartAfterStarted(ThreadFactory factory) {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
Thread thread = factory.newThread(() -> { });
|
||||
flock.start(thread);
|
||||
expectThrows(IllegalThreadStateException.class, () -> flock.start(thread));
|
||||
assertThrows(IllegalThreadStateException.class, () -> flock.start(thread));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test start is confined to threads in the flock.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStartConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStartConfined(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
// thread in flock
|
||||
testStartConfined(flock, task -> {
|
||||
@ -370,7 +372,7 @@ public class ThreadFlockTest {
|
||||
thread.join();
|
||||
Throwable cause = exception.get();
|
||||
if (flock.containsThread(thread)) {
|
||||
assertTrue(cause == null);
|
||||
assertNull(cause);
|
||||
} else {
|
||||
assertTrue(cause instanceof WrongThreadException);
|
||||
}
|
||||
@ -380,7 +382,7 @@ public class ThreadFlockTest {
|
||||
* Test awaitAll with no threads.
|
||||
*/
|
||||
@Test
|
||||
public void testAwaitAllWithNoThreads() throws Exception {
|
||||
void testAwaitAllWithNoThreads() throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
assertTrue(flock.awaitAll());
|
||||
assertTrue(flock.awaitAll(Duration.ofSeconds(1)));
|
||||
@ -390,8 +392,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with threads running.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testAwaitAllWithThreads(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testAwaitAllWithThreads(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
AtomicBoolean done = new AtomicBoolean();
|
||||
Runnable task = () -> {
|
||||
@ -410,8 +413,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with timeout, threads finish before timeout expires.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testAwaitAllWithTimeout1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testAwaitAllWithTimeout1(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
Runnable task = () -> {
|
||||
try {
|
||||
@ -431,12 +435,15 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with timeout, timeout expires before threads finish.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testAwaitAllWithTimeout2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testAwaitAllWithTimeout2(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Runnable task = () -> {
|
||||
try {
|
||||
Thread.sleep(Duration.ofSeconds(30));
|
||||
latch.await();
|
||||
} catch (InterruptedException e) { }
|
||||
};
|
||||
Thread thread = factory.newThread(task);
|
||||
@ -451,7 +458,7 @@ public class ThreadFlockTest {
|
||||
checkDuration(startMillis, 1900, 4000);
|
||||
}
|
||||
} finally {
|
||||
thread.interrupt();
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -459,12 +466,15 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with timeout many times.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testAwaitAllWithTimeout3(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testAwaitAllWithTimeout3(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Runnable task = () -> {
|
||||
try {
|
||||
Thread.sleep(Duration.ofSeconds(30));
|
||||
latch.await();
|
||||
} catch (InterruptedException e) { }
|
||||
};
|
||||
Thread thread = factory.newThread(task);
|
||||
@ -478,7 +488,7 @@ public class ThreadFlockTest {
|
||||
} catch (TimeoutException expected) { }
|
||||
}
|
||||
} finally {
|
||||
thread.interrupt();
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
boolean done = flock.awaitAll();
|
||||
@ -489,12 +499,15 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with a 0 or negative timeout.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testAwaitAllWithTimeout4(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testAwaitAllWithTimeout4(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
var latch = new CountDownLatch(1);
|
||||
|
||||
Runnable task = () -> {
|
||||
try {
|
||||
Thread.sleep(Duration.ofSeconds(30));
|
||||
latch.await();
|
||||
} catch (InterruptedException e) { }
|
||||
};
|
||||
Thread thread = factory.newThread(task);
|
||||
@ -510,7 +523,7 @@ public class ThreadFlockTest {
|
||||
fail("awaitAll did not throw");
|
||||
} catch (TimeoutException expected) { }
|
||||
} finally {
|
||||
thread.interrupt();
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
boolean done = flock.awaitAll();
|
||||
@ -521,8 +534,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with interrupt status set, should interrupt thread.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptAwaitAll1(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptAwaitAll1(ThreadFactory factory) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
Runnable awaitLatch = () -> {
|
||||
@ -568,14 +582,15 @@ public class ThreadFlockTest {
|
||||
}
|
||||
|
||||
// thread should not have throw any exception
|
||||
assertTrue(exception.get() == null);
|
||||
assertNull(exception.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test interrupt of awaitAll.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptAwaitAll2(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptAwaitAll2(ThreadFactory factory) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
Runnable awaitLatch = () -> {
|
||||
@ -619,14 +634,14 @@ public class ThreadFlockTest {
|
||||
}
|
||||
|
||||
// thread should not have throw any exception
|
||||
assertTrue(exception.get() == null);
|
||||
assertNull(exception.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test awaitAll after close.
|
||||
*/
|
||||
@Test
|
||||
public void testAwaitAfterClose() throws Exception {
|
||||
void testAwaitAfterClose() throws Exception {
|
||||
var flock = ThreadFlock.open(null);
|
||||
flock.close();
|
||||
assertTrue(flock.awaitAll());
|
||||
@ -636,8 +651,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll is flock confined.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testAwaitAllConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testAwaitAllConfined(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
// thread in flock
|
||||
testAwaitAllConfined(flock, task -> {
|
||||
@ -676,8 +692,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test awaitAll with the wakeup permit.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testWakeupAwaitAll1(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testWakeupAwaitAll1(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
@ -704,8 +721,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Schedule a thread to wakeup the owner waiting in awaitAll.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testWakeupAwaitAll2(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testWakeupAwaitAll2(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
var exception = new AtomicReference<Exception>();
|
||||
@ -737,8 +755,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test wakeup is flock confined.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testWakeupConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testWakeupConfined(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
// thread in flock
|
||||
testWakeupConfined(flock, task -> {
|
||||
@ -772,7 +791,7 @@ public class ThreadFlockTest {
|
||||
thread.join();
|
||||
Throwable cause = exception.get();
|
||||
if (flock.containsThread(thread)) {
|
||||
assertTrue(cause == null);
|
||||
assertNull(cause);
|
||||
} else {
|
||||
assertTrue(cause instanceof WrongThreadException);
|
||||
}
|
||||
@ -782,7 +801,7 @@ public class ThreadFlockTest {
|
||||
* Test close with no threads running.
|
||||
*/
|
||||
@Test
|
||||
public void testCloseWithNoThreads() {
|
||||
void testCloseWithNoThreads() {
|
||||
var flock = ThreadFlock.open(null);
|
||||
flock.close();
|
||||
assertTrue(flock.isClosed());
|
||||
@ -792,8 +811,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test close with threads running.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCloseWithThreads(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCloseWithThreads(ThreadFactory factory) {
|
||||
var exception = new AtomicReference<Exception>();
|
||||
Runnable sleepTask = () -> {
|
||||
try {
|
||||
@ -811,14 +831,14 @@ public class ThreadFlockTest {
|
||||
}
|
||||
assertTrue(flock.isClosed());
|
||||
assertTrue(flock.threads().count() == 0);
|
||||
assertTrue(exception.get() == null); // no exception thrown
|
||||
assertNull(exception.get()); // no exception thrown
|
||||
}
|
||||
|
||||
/**
|
||||
* Test close after flock is closed.
|
||||
*/
|
||||
@Test
|
||||
public void testCloseAfterClose() {
|
||||
void testCloseAfterClose() {
|
||||
var flock = ThreadFlock.open(null);
|
||||
flock.close();
|
||||
assertTrue(flock.isClosed());
|
||||
@ -829,8 +849,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test close is owner confined.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testCloseConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testCloseConfined(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
// thread in flock
|
||||
testCloseConfined(flock, task -> {
|
||||
@ -869,8 +890,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test close with interrupt status set, should not interrupt threads.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptClose1(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptClose1(ThreadFactory factory) {
|
||||
var exception = new AtomicReference<Exception>();
|
||||
Runnable sleepTask = () -> {
|
||||
try {
|
||||
@ -886,14 +908,15 @@ public class ThreadFlockTest {
|
||||
} finally {
|
||||
assertTrue(Thread.interrupted()); // clear interrupt
|
||||
}
|
||||
assertTrue(exception.get() == null);
|
||||
assertNull(exception.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test interrupt thread block in close.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInterruptClose2(ThreadFactory factory) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInterruptClose2(ThreadFactory factory) {
|
||||
var exception = new AtomicReference<Exception>();
|
||||
Runnable sleepTask = () -> {
|
||||
try {
|
||||
@ -909,14 +932,15 @@ public class ThreadFlockTest {
|
||||
} finally {
|
||||
assertTrue(Thread.interrupted()); // clear interrupt
|
||||
}
|
||||
assertTrue(exception.get() == null);
|
||||
assertNull(exception.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test shutdown is confined to threads in the flock.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testShutdownConfined(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testShutdownConfined(ThreadFactory factory) throws Exception {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
// thread in flock
|
||||
testShutdownConfined(flock, task -> {
|
||||
@ -958,7 +982,7 @@ public class ThreadFlockTest {
|
||||
thread.join();
|
||||
Throwable cause = exception.get();
|
||||
if (flock.containsThread(thread)) {
|
||||
assertTrue(cause == null);
|
||||
assertNull(cause);
|
||||
} else {
|
||||
assertTrue(cause instanceof WrongThreadException);
|
||||
}
|
||||
@ -968,7 +992,7 @@ public class ThreadFlockTest {
|
||||
* Test that closing an enclosing thread flock closes a nested thread flocks.
|
||||
*/
|
||||
@Test
|
||||
public void testStructureViolation() {
|
||||
void testStructureViolation() {
|
||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||
try (var flock2 = ThreadFlock.open("flock2")) {
|
||||
try {
|
||||
@ -986,8 +1010,9 @@ public class ThreadFlockTest {
|
||||
/**
|
||||
* Test Thread exiting with an open flock. The exiting thread should close the flock.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testThreadExitWithOpenFlock(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testThreadExitWithOpenFlock(ThreadFactory factory) throws Exception {
|
||||
var flockRef = new AtomicReference<ThreadFlock>();
|
||||
var childRef = new AtomicReference<Thread>();
|
||||
|
||||
@ -1017,7 +1042,7 @@ public class ThreadFlockTest {
|
||||
* Test toString includes the flock name.
|
||||
*/
|
||||
@Test
|
||||
public void testToString() {
|
||||
void testToString() {
|
||||
try (var flock = ThreadFlock.open("xxxx")) {
|
||||
assertTrue(flock.toString().contains("xxx"));
|
||||
}
|
||||
@ -1027,11 +1052,11 @@ public class ThreadFlockTest {
|
||||
* Test for NullPointerException.
|
||||
*/
|
||||
@Test
|
||||
public void testNulls() {
|
||||
void testNulls() {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
expectThrows(NullPointerException.class, () -> flock.start(null));
|
||||
expectThrows(NullPointerException.class, () -> flock.awaitAll(null));
|
||||
expectThrows(NullPointerException.class, () -> flock.containsThread(null));
|
||||
assertThrows(NullPointerException.class, () -> flock.start(null));
|
||||
assertThrows(NullPointerException.class, () -> flock.awaitAll(null));
|
||||
assertThrows(NullPointerException.class, () -> flock.containsThread(null));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,38 +27,33 @@
|
||||
* @enablePreview
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @modules jdk.incubator.concurrent
|
||||
* @run testng WithScopedValue
|
||||
* @run junit WithScopedValue
|
||||
*/
|
||||
|
||||
import jdk.internal.misc.ThreadFlock;
|
||||
import jdk.incubator.concurrent.ScopedValue;
|
||||
import jdk.incubator.concurrent.StructureViolationException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Test
|
||||
public class WithScopedValue {
|
||||
class WithScopedValue {
|
||||
|
||||
@DataProvider(name = "factories")
|
||||
public Object[][] factories() {
|
||||
var defaultThreadFactory = Executors.defaultThreadFactory();
|
||||
var virtualThreadFactory = Thread.ofVirtual().factory();
|
||||
return new Object[][]{
|
||||
{ defaultThreadFactory, },
|
||||
{ virtualThreadFactory, },
|
||||
};
|
||||
private static Stream<ThreadFactory> factories() {
|
||||
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test inheritance of a scoped value.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testInheritsScopedValue(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testInheritsScopedValue(ThreadFactory factory) throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
String value = ScopedValue.where(name, "duke", () -> {
|
||||
var result = new AtomicReference<String>();
|
||||
@ -71,13 +66,14 @@ public class WithScopedValue {
|
||||
}
|
||||
return result.get();
|
||||
});
|
||||
assertEquals(value, "duke");
|
||||
assertEquals("duke", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test exiting a dynamic scope with open thread flocks.
|
||||
*/
|
||||
public void testStructureViolation1() {
|
||||
@Test
|
||||
void testStructureViolation1() {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
class Box {
|
||||
ThreadFlock flock1;
|
||||
@ -99,7 +95,8 @@ public class WithScopedValue {
|
||||
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
||||
* flocks. This test closes enclosing flock1.
|
||||
*/
|
||||
public void testStructureViolation2() {
|
||||
@Test
|
||||
void testStructureViolation2() {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||
ScopedValue.where(name, "x1", () -> {
|
||||
@ -130,7 +127,8 @@ public class WithScopedValue {
|
||||
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
||||
* flocks. This test closes enclosing flock2.
|
||||
*/
|
||||
public void testStructureViolation3() {
|
||||
@Test
|
||||
void testStructureViolation3() {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||
ScopedValue.where(name, "x1", () -> {
|
||||
@ -161,7 +159,8 @@ public class WithScopedValue {
|
||||
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
||||
* flocks. This test closes enclosing flock3.
|
||||
*/
|
||||
public void testStructureViolation4() {
|
||||
@Test
|
||||
void testStructureViolation4() {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||
ScopedValue.where(name, "x1", () -> {
|
||||
@ -191,13 +190,14 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test start when a scoped value is bound after a thread flock is created.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStructureViolation5(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStructureViolation5(ThreadFactory factory) throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
Thread thread = factory.newThread(() -> { });
|
||||
expectThrows(StructureViolationException.class, () -> flock.start(thread));
|
||||
assertThrows(StructureViolationException.class, () -> flock.start(thread));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -205,14 +205,15 @@ public class WithScopedValue {
|
||||
/**
|
||||
* Test start when a scoped value is re-bound after a thread flock is created.
|
||||
*/
|
||||
@Test(dataProvider = "factories")
|
||||
public void testStructureViolation6(ThreadFactory factory) throws Exception {
|
||||
@ParameterizedTest
|
||||
@MethodSource("factories")
|
||||
void testStructureViolation6(ThreadFactory factory) throws Exception {
|
||||
ScopedValue<String> name = ScopedValue.newInstance();
|
||||
ScopedValue.where(name, "duke", () -> {
|
||||
try (var flock = ThreadFlock.open(null)) {
|
||||
ScopedValue.where(name, "duchess", () -> {
|
||||
Thread thread = factory.newThread(() -> { });
|
||||
expectThrows(StructureViolationException.class, () -> flock.start(thread));
|
||||
assertThrows(StructureViolationException.class, () -> flock.start(thread));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user