8301767: Convert virtual thread tests to JUnit

Reviewed-by: cstein, lancea, jpai
This commit is contained in:
Alan Bateman 2023-02-08 14:56:28 +00:00
parent 9af2ea203d
commit ecf21a9a24
34 changed files with 1369 additions and 1244 deletions

View File

@ -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");

View File

@ -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));

View File

@ -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));

View File

@ -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

View File

@ -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();
}
}

View File

@ -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(); }

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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");

View File

@ -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();

View File

@ -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];

View File

@ -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);

View File

@ -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")

View File

@ -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);

View File

@ -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

View File

@ -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());
}
}

View File

@ -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)");

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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);
}

View File

@ -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) {

View File

@ -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));
}

View File

@ -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());
}
}
}

View File

@ -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"));

View File

@ -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)) {
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();

View File

@ -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));
}
}

View File

@ -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));
});
}
});