8301767: Convert virtual thread tests to JUnit
Reviewed-by: cstein, lancea, jpai
This commit is contained in:
parent
9af2ea203d
commit
ecf21a9a24
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,7 +26,7 @@
|
|||||||
* @bug 8284161 8287008
|
* @bug 8284161 8287008
|
||||||
* @summary Basic test for jcmd Thread.dump_to_file
|
* @summary Basic test for jcmd Thread.dump_to_file
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm ThreadDumpToFileTest
|
* @run junit/othervm ThreadDumpToFileTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -37,16 +37,16 @@ import jdk.test.lib.dcmd.PidJcmdExecutor;
|
|||||||
import jdk.test.lib.process.OutputAnalyzer;
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
import jdk.test.lib.threaddump.ThreadDump;
|
import jdk.test.lib.threaddump.ThreadDump;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class ThreadDumpToFileTest {
|
class ThreadDumpToFileTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test thread dump, should be in plain text format.
|
* Test thread dump, should be in plain text format.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadDump() throws IOException {
|
void testThreadDump() throws IOException {
|
||||||
Path file = genThreadDumpPath(".txt");
|
Path file = genThreadDumpPath(".txt");
|
||||||
testPlainThreadDump(file);
|
testPlainThreadDump(file);
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ public class ThreadDumpToFileTest {
|
|||||||
* Test thread dump in plain text format.
|
* Test thread dump in plain text format.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPlainThreadDump() throws IOException {
|
void testPlainThreadDump() throws IOException {
|
||||||
Path file = genThreadDumpPath(".txt");
|
Path file = genThreadDumpPath(".txt");
|
||||||
testPlainThreadDump(file, "-format=plain");
|
testPlainThreadDump(file, "-format=plain");
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ public class ThreadDumpToFileTest {
|
|||||||
* Test thread dump in JSON format.
|
* Test thread dump in JSON format.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJsonThreadDump() throws IOException {
|
void testJsonThreadDump() throws IOException {
|
||||||
Path file = genThreadDumpPath(".json");
|
Path file = genThreadDumpPath(".json");
|
||||||
threadDump(file, "-format=json").shouldMatch("Created");
|
threadDump(file, "-format=json").shouldMatch("Created");
|
||||||
|
|
||||||
@ -85,21 +85,21 @@ public class ThreadDumpToFileTest {
|
|||||||
* Test that an existing file is not overwritten.
|
* Test that an existing file is not overwritten.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoNotOverwriteFile() throws IOException {
|
void testDoNotOverwriteFile() throws IOException {
|
||||||
Path file = genThreadDumpPath(".txt");
|
Path file = genThreadDumpPath(".txt");
|
||||||
Files.writeString(file, "xxx");
|
Files.writeString(file, "xxx");
|
||||||
|
|
||||||
threadDump(file, "").shouldMatch("exists");
|
threadDump(file, "").shouldMatch("exists");
|
||||||
|
|
||||||
// file should not be overridden
|
// file should not be overridden
|
||||||
assertEquals(Files.readString(file), "xxx");
|
assertEquals("xxx", Files.readString(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test overwriting an existing file.
|
* Test overwriting an existing file.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOverwriteFile() throws IOException {
|
void testOverwriteFile() throws IOException {
|
||||||
Path file = genThreadDumpPath(".txt");
|
Path file = genThreadDumpPath(".txt");
|
||||||
Files.writeString(file, "xxx");
|
Files.writeString(file, "xxx");
|
||||||
testPlainThreadDump(file, "-overwrite");
|
testPlainThreadDump(file, "-overwrite");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Basic test for com.sun.management.HotSpotDiagnosticMXBean.dumpThreads
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm DumpThreads
|
* @run junit/othervm DumpThreads
|
||||||
* @run testng/othervm -Djdk.trackAllThreads DumpThreads
|
* @run junit/othervm -Djdk.trackAllThreads DumpThreads
|
||||||
* @run testng/othervm -Djdk.trackAllThreads=true DumpThreads
|
* @run junit/othervm -Djdk.trackAllThreads=true DumpThreads
|
||||||
* @run testng/othervm -Djdk.trackAllThreadds=false DumpThreads
|
* @run junit/othervm -Djdk.trackAllThreadds=false DumpThreads
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
@ -47,10 +47,10 @@ import com.sun.management.HotSpotDiagnosticMXBean;
|
|||||||
import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat;
|
import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat;
|
||||||
import jdk.test.lib.threaddump.ThreadDump;
|
import jdk.test.lib.threaddump.ThreadDump;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class DumpThreads {
|
class DumpThreads {
|
||||||
private static final boolean TRACK_ALL_THREADS;
|
private static final boolean TRACK_ALL_THREADS;
|
||||||
static {
|
static {
|
||||||
String s = System.getProperty("jdk.trackAllThreads");
|
String s = System.getProperty("jdk.trackAllThreads");
|
||||||
@ -61,7 +61,7 @@ public class DumpThreads {
|
|||||||
* Thread dump in plain text format.
|
* Thread dump in plain text format.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPlainText() throws Exception {
|
void testPlainText() throws Exception {
|
||||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||||
Path file = genOutputPath("txt");
|
Path file = genOutputPath("txt");
|
||||||
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||||
@ -98,7 +98,7 @@ public class DumpThreads {
|
|||||||
* Thread dump in JSON format.
|
* Thread dump in JSON format.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJson() throws Exception {
|
void testJson() throws Exception {
|
||||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||||
Path file = genOutputPath("json");
|
Path file = genOutputPath("json");
|
||||||
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||||
@ -118,7 +118,7 @@ public class DumpThreads {
|
|||||||
ZonedDateTime.parse(threadDump.time());
|
ZonedDateTime.parse(threadDump.time());
|
||||||
|
|
||||||
// test threadDump/runtimeVersion
|
// test threadDump/runtimeVersion
|
||||||
assertEquals(threadDump.runtimeVersion(), Runtime.version().toString());
|
assertEquals(Runtime.version().toString(), threadDump.runtimeVersion());
|
||||||
|
|
||||||
// test root container
|
// test root container
|
||||||
var rootContainer = threadDump.rootThreadContainer();
|
var rootContainer = threadDump.rootThreadContainer();
|
||||||
@ -150,7 +150,7 @@ public class DumpThreads {
|
|||||||
* Test that dumpThreads throws if the output file already exists.
|
* Test that dumpThreads throws if the output file already exists.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testFileAlreadyExsists() throws Exception {
|
void testFileAlreadyExsists() throws Exception {
|
||||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||||
String file = Files.createFile(genOutputPath("txt")).toString();
|
String file = Files.createFile(genOutputPath("txt")).toString();
|
||||||
assertThrows(FileAlreadyExistsException.class,
|
assertThrows(FileAlreadyExistsException.class,
|
||||||
@ -163,7 +163,7 @@ public class DumpThreads {
|
|||||||
* Test that dumpThreads throws if the file path is relative.
|
* Test that dumpThreads throws if the file path is relative.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRelativePath() throws Exception {
|
void testRelativePath() throws Exception {
|
||||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> mbean.dumpThreads("threads.txt", ThreadDumpFormat.TEXT_PLAIN));
|
() -> mbean.dumpThreads("threads.txt", ThreadDumpFormat.TEXT_PLAIN));
|
||||||
@ -175,7 +175,7 @@ public class DumpThreads {
|
|||||||
* Test that dumpThreads throws with null parameters.
|
* Test that dumpThreads throws with null parameters.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNull() throws Exception {
|
void testNull() throws Exception {
|
||||||
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> mbean.dumpThreads(null, ThreadDumpFormat.TEXT_PLAIN));
|
() -> mbean.dumpThreads(null, ThreadDumpFormat.TEXT_PLAIN));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,7 +25,7 @@
|
|||||||
* @test
|
* @test
|
||||||
* @summary Unit test for Thread.Builder
|
* @summary Unit test for Thread.Builder
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng BuilderTest
|
* @run junit BuilderTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
@ -33,17 +33,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.testng.SkipException;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assumptions.*;
|
||||||
|
|
||||||
public class BuilderTest {
|
class BuilderTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Thread.ofPlatform to create platform threads.
|
* Test Thread.ofPlatform to create platform threads.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPlatformThread() throws Exception {
|
void testPlatformThread() throws Exception {
|
||||||
Thread parent = Thread.currentThread();
|
Thread parent = Thread.currentThread();
|
||||||
Thread.Builder.OfPlatform builder = Thread.ofPlatform();
|
Thread.Builder.OfPlatform builder = Thread.ofPlatform();
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.ofVirtual to create virtual threads.
|
* Test Thread.ofVirtual to create virtual threads.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testVirtualThread() throws Exception {
|
void testVirtualThread() throws Exception {
|
||||||
Thread parent = Thread.currentThread();
|
Thread parent = Thread.currentThread();
|
||||||
Thread.Builder.OfVirtual builder = Thread.ofVirtual();
|
Thread.Builder.OfVirtual builder = Thread.ofVirtual();
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder.name.
|
* Test Thread.Builder.name.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testName1() {
|
void testName1() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().name("duke");
|
Thread.Builder builder = Thread.ofPlatform().name("duke");
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -154,7 +154,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testName2() {
|
void testName2() {
|
||||||
Thread.Builder builder = Thread.ofVirtual().name("duke");
|
Thread.Builder builder = Thread.ofVirtual().name("duke");
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -167,7 +167,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testName3() {
|
void testName3() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().name("duke-", 100);
|
Thread.Builder builder = Thread.ofPlatform().name("duke-", 100);
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -189,7 +189,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testName4() {
|
void testName4() {
|
||||||
Thread.Builder builder = Thread.ofVirtual().name("duke-", 100);
|
Thread.Builder builder = Thread.ofVirtual().name("duke-", 100);
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -214,7 +214,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder.OfPlatform.group.
|
* Test Thread.Builder.OfPlatform.group.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadGroup1() {
|
void testThreadGroup1() {
|
||||||
ThreadGroup group = new ThreadGroup("groupies");
|
ThreadGroup group = new ThreadGroup("groupies");
|
||||||
Thread.Builder builder = Thread.ofPlatform().group(group);
|
Thread.Builder builder = Thread.ofPlatform().group(group);
|
||||||
|
|
||||||
@ -240,9 +240,9 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThreadGroup2() {
|
void testThreadGroup2() {
|
||||||
ThreadGroup vgroup = Thread.ofVirtual().unstarted(() -> { }).getThreadGroup();
|
ThreadGroup vgroup = Thread.ofVirtual().unstarted(() -> { }).getThreadGroup();
|
||||||
assertEquals(vgroup.getName(), "VirtualThreads");
|
assertEquals("VirtualThreads", vgroup.getName());
|
||||||
|
|
||||||
Thread thread1 = Thread.ofVirtual().unstarted(() -> { });
|
Thread thread1 = Thread.ofVirtual().unstarted(() -> { });
|
||||||
Thread thread2 = Thread.ofVirtual().start(LockSupport::park);
|
Thread thread2 = Thread.ofVirtual().start(LockSupport::park);
|
||||||
@ -261,7 +261,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder.OfPlatform.priority.
|
* Test Thread.Builder.OfPlatform.priority.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPriority1() {
|
void testPriority1() {
|
||||||
int priority = Thread.currentThread().getPriority();
|
int priority = Thread.currentThread().getPriority();
|
||||||
|
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
@ -275,7 +275,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPriority2() {
|
void testPriority2() {
|
||||||
int priority = Thread.MIN_PRIORITY;
|
int priority = Thread.MIN_PRIORITY;
|
||||||
|
|
||||||
Thread.Builder builder = Thread.ofPlatform().priority(priority);
|
Thread.Builder builder = Thread.ofPlatform().priority(priority);
|
||||||
@ -289,10 +289,9 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPriority3() {
|
void testPriority3() {
|
||||||
Thread currentThread = Thread.currentThread();
|
Thread currentThread = Thread.currentThread();
|
||||||
if (currentThread.isVirtual())
|
assumeFalse(currentThread.isVirtual(), "Main thread is a virtual thread");
|
||||||
throw new SkipException("Main test is a virtual thread");
|
|
||||||
|
|
||||||
int maxPriority = currentThread.getThreadGroup().getMaxPriority();
|
int maxPriority = currentThread.getThreadGroup().getMaxPriority();
|
||||||
int priority = Math.min(maxPriority + 1, Thread.MAX_PRIORITY);
|
int priority = Math.min(maxPriority + 1, Thread.MAX_PRIORITY);
|
||||||
@ -308,14 +307,14 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPriority4() {
|
void testPriority4() {
|
||||||
var builder = Thread.ofPlatform();
|
var builder = Thread.ofPlatform();
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> builder.priority(Thread.MIN_PRIORITY - 1));
|
() -> builder.priority(Thread.MIN_PRIORITY - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPriority5() {
|
void testPriority5() {
|
||||||
var builder = Thread.ofPlatform();
|
var builder = Thread.ofPlatform();
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> builder.priority(Thread.MAX_PRIORITY + 1));
|
() -> builder.priority(Thread.MAX_PRIORITY + 1));
|
||||||
@ -325,7 +324,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder.OfPlatform.daemon.
|
* Test Thread.Builder.OfPlatform.daemon.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDaemon1() {
|
void testDaemon1() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().daemon(false);
|
Thread.Builder builder = Thread.ofPlatform().daemon(false);
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -338,7 +337,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDaemon2() {
|
void testDaemon2() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().daemon(true);
|
Thread.Builder builder = Thread.ofPlatform().daemon(true);
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -351,7 +350,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDaemon3() {
|
void testDaemon3() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().daemon();
|
Thread.Builder builder = Thread.ofPlatform().daemon();
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -364,7 +363,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDaemon4() {
|
void testDaemon4() {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -382,7 +381,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.ofVirtual creates daemon threads.
|
* Test Thread.ofVirtual creates daemon threads.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDaemon5() {
|
void testDaemon5() {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
|
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
@ -399,7 +398,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder.OfPlatform.stackSize.
|
* Test Thread.Builder.OfPlatform.stackSize.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStackSize1() {
|
void testStackSize1() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().stackSize(1024*1024);
|
Thread.Builder builder = Thread.ofPlatform().stackSize(1024*1024);
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
Thread thread2 = builder.start(() -> { });
|
Thread thread2 = builder.start(() -> { });
|
||||||
@ -407,7 +406,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStackSize2() {
|
void testStackSize2() {
|
||||||
Thread.Builder builder = Thread.ofPlatform().stackSize(0);
|
Thread.Builder builder = Thread.ofPlatform().stackSize(0);
|
||||||
Thread thread1 = builder.unstarted(() -> { });
|
Thread thread1 = builder.unstarted(() -> { });
|
||||||
Thread thread2 = builder.start(() -> { });
|
Thread thread2 = builder.start(() -> { });
|
||||||
@ -415,7 +414,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStackSize3() {
|
void testStackSize3() {
|
||||||
var builder = Thread.ofPlatform();
|
var builder = Thread.ofPlatform();
|
||||||
assertThrows(IllegalArgumentException.class, () -> builder.stackSize(-1));
|
assertThrows(IllegalArgumentException.class, () -> builder.stackSize(-1));
|
||||||
}
|
}
|
||||||
@ -424,7 +423,7 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder.uncaughtExceptionHandler.
|
* Test Thread.Builder.uncaughtExceptionHandler.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUncaughtExceptionHandler1() throws Exception {
|
void testUncaughtExceptionHandler1() throws Exception {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||||
@ -441,7 +440,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUncaughtExceptionHandler2() throws Exception {
|
void testUncaughtExceptionHandler2() throws Exception {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||||
@ -458,7 +457,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUncaughtExceptionHandler3() throws Exception {
|
void testUncaughtExceptionHandler3() throws Exception {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||||
@ -477,7 +476,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUncaughtExceptionHandler4() throws Exception {
|
void testUncaughtExceptionHandler4() throws Exception {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
AtomicReference<Thread> threadRef = new AtomicReference<>();
|
||||||
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
|
||||||
@ -563,13 +562,13 @@ public class BuilderTest {
|
|||||||
* Test Thread.Builder creates threads that allow thread locals.
|
* Test Thread.Builder creates threads that allow thread locals.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocals1() throws Exception {
|
void testThreadLocals1() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
testThreadLocals(builder);
|
testThreadLocals(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocals2() throws Exception {
|
void testThreadLocals2() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
testThreadLocals(builder);
|
testThreadLocals(builder);
|
||||||
}
|
}
|
||||||
@ -579,7 +578,7 @@ public class BuilderTest {
|
|||||||
* thread locals.
|
* thread locals.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocals3() throws Exception {
|
void testThreadLocals3() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
|
|
||||||
// disallow
|
// disallow
|
||||||
@ -592,7 +591,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocals4() throws Exception {
|
void testThreadLocals4() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
|
|
||||||
// disallow
|
// disallow
|
||||||
@ -646,7 +645,7 @@ public class BuilderTest {
|
|||||||
|
|
||||||
AtomicBoolean done = new AtomicBoolean();
|
AtomicBoolean done = new AtomicBoolean();
|
||||||
Runnable task = () -> {
|
Runnable task = () -> {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
done.set(true);
|
done.set(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -673,7 +672,7 @@ public class BuilderTest {
|
|||||||
* the initial values of inheritable thread locals.
|
* the initial values of inheritable thread locals.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocals1() throws Exception {
|
void testInheritedThreadLocals1() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
testInheritedThreadLocals(builder); // default
|
testInheritedThreadLocals(builder); // default
|
||||||
|
|
||||||
@ -687,7 +686,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocals2() throws Exception {
|
void testInheritedThreadLocals2() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
testInheritedThreadLocals(builder); // default
|
testInheritedThreadLocals(builder); // default
|
||||||
|
|
||||||
@ -701,7 +700,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocals3() throws Exception {
|
void testInheritedThreadLocals3() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
|
|
||||||
// thread locals not allowed
|
// thread locals not allowed
|
||||||
@ -721,7 +720,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocals4() throws Exception {
|
void testInheritedThreadLocals4() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
|
|
||||||
// thread locals not allowed
|
// thread locals not allowed
|
||||||
@ -824,7 +823,7 @@ public class BuilderTest {
|
|||||||
* the thread context class loader.
|
* the thread context class loader.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testContextClassLoader1() throws Exception {
|
void testContextClassLoader1() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
testInheritContextClassLoader(builder); // default
|
testInheritContextClassLoader(builder); // default
|
||||||
|
|
||||||
@ -838,7 +837,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContextClassLoader2() throws Exception {
|
void testContextClassLoader2() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
testInheritContextClassLoader(builder); // default
|
testInheritContextClassLoader(builder); // default
|
||||||
|
|
||||||
@ -852,7 +851,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContextClassLoader3() throws Exception {
|
void testContextClassLoader3() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofPlatform();
|
Thread.Builder builder = Thread.ofPlatform();
|
||||||
|
|
||||||
// thread locals not allowed
|
// thread locals not allowed
|
||||||
@ -872,7 +871,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContextClassLoader4() throws Exception {
|
void testContextClassLoader4() throws Exception {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
|
|
||||||
// thread locals not allowed
|
// thread locals not allowed
|
||||||
@ -895,7 +894,7 @@ public class BuilderTest {
|
|||||||
* Test NullPointerException.
|
* Test NullPointerException.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNulls1() {
|
void testNulls1() {
|
||||||
Thread.Builder.OfPlatform builder = Thread.ofPlatform();
|
Thread.Builder.OfPlatform builder = Thread.ofPlatform();
|
||||||
assertThrows(NullPointerException.class, () -> builder.group(null));
|
assertThrows(NullPointerException.class, () -> builder.group(null));
|
||||||
assertThrows(NullPointerException.class, () -> builder.name(null));
|
assertThrows(NullPointerException.class, () -> builder.name(null));
|
||||||
@ -906,7 +905,7 @@ public class BuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNulls2() {
|
void testNulls2() {
|
||||||
Thread.Builder builder = Thread.ofVirtual();
|
Thread.Builder builder = Thread.ofVirtual();
|
||||||
assertThrows(NullPointerException.class, () -> builder.name(null));
|
assertThrows(NullPointerException.class, () -> builder.name(null));
|
||||||
assertThrows(NullPointerException.class, () -> builder.name(null, 0));
|
assertThrows(NullPointerException.class, () -> builder.name(null, 0));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,22 +24,22 @@
|
|||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @summary Test Thread.join(Duration)
|
* @summary Test Thread.join(Duration)
|
||||||
* @run testng JoinWithDuration
|
* @run junit JoinWithDuration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class JoinWithDuration {
|
class JoinWithDuration {
|
||||||
/**
|
/**
|
||||||
* Test join on unstarted thread.
|
* Test join on unstarted thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinOnUnstartedThread() {
|
void testJoinOnUnstartedThread() {
|
||||||
var thread = new Thread(() -> { });
|
var thread = new Thread(() -> { });
|
||||||
assertThrows(IllegalThreadStateException.class,
|
assertThrows(IllegalThreadStateException.class,
|
||||||
() -> thread.join(Duration.ofNanos(-100)));
|
() -> thread.join(Duration.ofNanos(-100)));
|
||||||
@ -53,7 +53,7 @@ public class JoinWithDuration {
|
|||||||
* Test join on thread that does not terminate while waiting.
|
* Test join on thread that does not terminate while waiting.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinOnRunningThread() throws Exception {
|
void testJoinOnRunningThread() throws Exception {
|
||||||
var thread = new Thread(LockSupport::park);
|
var thread = new Thread(LockSupport::park);
|
||||||
thread.start();
|
thread.start();
|
||||||
try {
|
try {
|
||||||
@ -76,7 +76,7 @@ public class JoinWithDuration {
|
|||||||
* Test join on thread that terminates while waiting.
|
* Test join on thread that terminates while waiting.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinOnTerminatingThread() throws Exception {
|
void testJoinOnTerminatingThread() throws Exception {
|
||||||
var thread = new Thread(() -> {
|
var thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(50);
|
Thread.sleep(50);
|
||||||
@ -90,7 +90,7 @@ public class JoinWithDuration {
|
|||||||
* Test join on terminated thread.
|
* Test join on terminated thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinOnTerminatedThread() throws Exception {
|
void testJoinOnTerminatedThread() throws Exception {
|
||||||
var thread = new Thread(() -> { });
|
var thread = new Thread(() -> { });
|
||||||
thread.start();
|
thread.start();
|
||||||
thread.join();
|
thread.join();
|
||||||
@ -103,7 +103,7 @@ public class JoinWithDuration {
|
|||||||
* Test invoking join with interrupt status set.
|
* Test invoking join with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinWithInterruptStatusSet() throws Exception {
|
void testJoinWithInterruptStatusSet() throws Exception {
|
||||||
var thread = new Thread(LockSupport::park);
|
var thread = new Thread(LockSupport::park);
|
||||||
thread.start();
|
thread.start();
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
@ -122,8 +122,8 @@ public class JoinWithDuration {
|
|||||||
* Test interrupting join.
|
* Test interrupting join.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInterruptJoin() throws Exception {
|
void testInterruptJoin() throws Exception {
|
||||||
// schedule current thread to interrupted after 1s
|
// schedule current thread to be interrupted after 1s
|
||||||
Thread targetThread = Thread.currentThread();
|
Thread targetThread = Thread.currentThread();
|
||||||
Thread wakerThread = new Thread(() -> {
|
Thread wakerThread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
@ -144,7 +144,9 @@ public class JoinWithDuration {
|
|||||||
// interrupt status should be cleared
|
// interrupt status should be cleared
|
||||||
assertFalse(thread.isInterrupted());
|
assertFalse(thread.isInterrupted());
|
||||||
} finally {
|
} finally {
|
||||||
wakerThread.interrupt();
|
LockSupport.unpark(thread);
|
||||||
|
thread.join();
|
||||||
|
wakerThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +154,7 @@ public class JoinWithDuration {
|
|||||||
* Test join on current thread.
|
* Test join on current thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinSelf() throws Exception {
|
void testJoinSelf() throws Exception {
|
||||||
Thread thread = Thread.currentThread();
|
Thread thread = Thread.currentThread();
|
||||||
|
|
||||||
assertFalse(thread.join(Duration.ofNanos(-100)));
|
assertFalse(thread.join(Duration.ofNanos(-100)));
|
||||||
@ -169,7 +171,7 @@ public class JoinWithDuration {
|
|||||||
* Test join(null).
|
* Test join(null).
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinNull() throws Exception {
|
void testJoinNull() throws Exception {
|
||||||
var thread = new Thread(LockSupport::park);
|
var thread = new Thread(LockSupport::park);
|
||||||
|
|
||||||
// unstarted
|
// unstarted
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,22 +24,22 @@
|
|||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @summary Test Thread.sleep(Duration)
|
* @summary Test Thread.sleep(Duration)
|
||||||
* @run testng SleepWithDuration
|
* @run junit SleepWithDuration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class SleepWithDuration {
|
class SleepWithDuration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic test for sleep(Duration).
|
* Basic test for sleep(Duration).
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSleep() throws Exception {
|
void testSleep() throws Exception {
|
||||||
// sleep for 2 seconds
|
// sleep for 2 seconds
|
||||||
long start = millisTime();
|
long start = millisTime();
|
||||||
Thread.sleep(Duration.ofMillis(2000));
|
Thread.sleep(Duration.ofMillis(2000));
|
||||||
@ -56,7 +56,7 @@ public class SleepWithDuration {
|
|||||||
* Test Thread.sleep with interrupt status set.
|
* Test Thread.sleep with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSleepWithInterruptStatusSet() throws Exception {
|
void testSleepWithInterruptStatusSet() throws Exception {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Duration.ofNanos(0));
|
Thread.sleep(Duration.ofNanos(0));
|
||||||
@ -78,8 +78,8 @@ public class SleepWithDuration {
|
|||||||
* Test interrupting Thread.sleep.
|
* Test interrupting Thread.sleep.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInterruptSleep() throws Exception {
|
void testInterruptSleep() throws Exception {
|
||||||
// schedule current thread to interrupted after 1s
|
// schedule current thread to be interrupted after 1s
|
||||||
Thread targetThread = Thread.currentThread();
|
Thread targetThread = Thread.currentThread();
|
||||||
Thread wakerThread = new Thread(() -> {
|
Thread wakerThread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
@ -97,7 +97,7 @@ public class SleepWithDuration {
|
|||||||
// interrupt status should be cleared
|
// interrupt status should be cleared
|
||||||
assertFalse(Thread.interrupted());
|
assertFalse(Thread.interrupted());
|
||||||
} finally {
|
} finally {
|
||||||
wakerThread.interrupt();
|
wakerThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -21,10 +21,14 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import jdk.test.lib.process.OutputAnalyzer;
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
import jdk.test.lib.process.ProcessTools;
|
import jdk.test.lib.process.ProcessTools;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.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.err;
|
||||||
import static java.lang.System.out;
|
import static java.lang.System.out;
|
||||||
@ -36,35 +40,50 @@ import static java.lang.System.out;
|
|||||||
* @author Martin Buchholz
|
* @author Martin Buchholz
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @build jdk.test.lib.process.*
|
* @build jdk.test.lib.process.*
|
||||||
* @run testng UncaughtExceptionsTest
|
* @run junit UncaughtExceptionsTest
|
||||||
*/
|
*/
|
||||||
public class UncaughtExceptionsTest {
|
class UncaughtExceptionsTest {
|
||||||
|
|
||||||
@DataProvider
|
private static Stream<Arguments> testCases() {
|
||||||
public Object[][] testCases() {
|
return Stream.of(
|
||||||
return new Object[][] {
|
Arguments.of("ThreadIsDeadAfterJoin",
|
||||||
new Object[] { "ThreadIsDeadAfterJoin",
|
0,
|
||||||
0,
|
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
"Exception in thread \"Thread-\\d+\".*simulateUncaughtExitEvent"),
|
||||||
"Exception in thread \"Thread-\\d+\".*simulateUncaughtExitEvent"
|
Arguments.of("MainThreadAbruptTermination",
|
||||||
},
|
1,
|
||||||
new Object[] {
|
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||||
"MainThreadAbruptTermination",
|
"Exception in thread \"main\".*simulateUncaughtExitEvent"),
|
||||||
1,
|
Arguments.of("MainThreadNormalTermination",
|
||||||
UncaughtExitSimulator.EXPECTED_RESULT,
|
0,
|
||||||
"Exception in thread \"main\".*simulateUncaughtExitEvent"
|
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||||
},
|
""),
|
||||||
new Object[] { "MainThreadNormalTermination", 0, UncaughtExitSimulator.EXPECTED_RESULT, ""},
|
Arguments.of("DefaultUncaughtExceptionHandlerOnMainThread",
|
||||||
new Object[] { "DefaultUncaughtExceptionHandlerOnMainThread", 1, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
1,
|
||||||
new Object[] { "DefaultUncaughtExceptionHandlerOnMainThreadOverride", 1, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
UncaughtExitSimulator.EXPECTED_RESULT,
|
||||||
new Object[] { "DefaultUncaughtExceptionHandlerOnNonMainThreadOverride", 0, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
""),
|
||||||
new Object[] { "DefaultUncaughtExceptionHandlerOnNonMainThread", 0, UncaughtExitSimulator.EXPECTED_RESULT, "" },
|
Arguments.of("DefaultUncaughtExceptionHandlerOnMainThreadOverride",
|
||||||
new Object[] { "ThreadGroupUncaughtExceptionHandlerOnNonMainThread", 0, UncaughtExitSimulator.EXPECTED_RESULT, "" }
|
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")
|
@ParameterizedTest
|
||||||
public void test(String className, int exitValue, String stdOutMatch, String stdErrMatch) throws Throwable {
|
@MethodSource("testCases")
|
||||||
|
void test(String className, int exitValue, String stdOutMatch, String stdErrMatch) throws Throwable {
|
||||||
String cmd = "UncaughtExitSimulator$" + className;
|
String cmd = "UncaughtExitSimulator$" + className;
|
||||||
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(cmd);
|
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(cmd);
|
||||||
OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(processBuilder);
|
OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(processBuilder);
|
||||||
@ -91,7 +110,9 @@ class UncaughtExitSimulator extends Thread implements Runnable {
|
|||||||
|
|
||||||
final static String EXPECTED_RESULT = "OK";
|
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(); }
|
public void run() { throwRuntimeException(); }
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,22 +25,22 @@
|
|||||||
* @test
|
* @test
|
||||||
* @summary Test that virtual threads are GC'ed
|
* @summary Test that virtual threads are GC'ed
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng Collectable
|
* @run junit Collectable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class Collectable {
|
class Collectable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that an unstarted virtual thread can be GC"ed.
|
* Test that an unstarted virtual thread can be GC"ed.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUnstartedThread() {
|
void testUnstartedThread() {
|
||||||
var thread = Thread.ofVirtual().unstarted(() -> { });
|
var thread = Thread.ofVirtual().unstarted(() -> { });
|
||||||
var ref = new WeakReference<>(thread);
|
var ref = new WeakReference<>(thread);
|
||||||
thread = null;
|
thread = null;
|
||||||
@ -51,7 +51,7 @@ public class Collectable {
|
|||||||
* Test that a terminated virtual thread can be GC'ed.
|
* Test that a terminated virtual thread can be GC'ed.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTerminatedThread() throws Exception {
|
void testTerminatedThread() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> { });
|
var thread = Thread.ofVirtual().start(() -> { });
|
||||||
thread.join();
|
thread.join();
|
||||||
var ref = new WeakReference<>(thread);
|
var ref = new WeakReference<>(thread);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,7 +27,7 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @modules java.base/java.lang:+open
|
* @modules java.base/java.lang:+open
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng CustomScheduler
|
* @run junit CustomScheduler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
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.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.testng.SkipException;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.testng.annotations.Test;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assumptions.*;
|
||||||
|
|
||||||
public class CustomScheduler {
|
class CustomScheduler {
|
||||||
private static final Executor DEFAULT_SCHEDULER = defaultScheduler();
|
private static final Executor DEFAULT_SCHEDULER = defaultScheduler();
|
||||||
private static ExecutorService SCHEDULER_1;
|
private static ExecutorService scheduler1;
|
||||||
private static ExecutorService SCHEDULER_2;
|
private static ExecutorService scheduler2;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeAll
|
||||||
public void setup() {
|
static void setup() {
|
||||||
SCHEDULER_1 = Executors.newFixedThreadPool(1);
|
scheduler1 = Executors.newFixedThreadPool(1);
|
||||||
SCHEDULER_2 = Executors.newFixedThreadPool(1);
|
scheduler2 = Executors.newFixedThreadPool(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterAll
|
||||||
public void shutdown() {
|
static void shutdown() {
|
||||||
SCHEDULER_1.shutdown();
|
scheduler1.shutdown();
|
||||||
SCHEDULER_2.shutdown();
|
scheduler2.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test platform thread creating a virtual thread that uses a custom scheduler.
|
* Test platform thread creating a virtual thread that uses a custom scheduler.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCustomScheduler1() throws Exception {
|
void testCustomScheduler1() throws Exception {
|
||||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||||
ref.set(scheduler(Thread.currentThread()));
|
ref.set(scheduler(Thread.currentThread()));
|
||||||
}).join();
|
}).join();
|
||||||
assertTrue(ref.get() == SCHEDULER_1);
|
assertTrue(ref.get() == scheduler1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test virtual thread creating a virtual thread that uses a custom scheduler.
|
* Test virtual thread creating a virtual thread that uses a custom scheduler.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCustomScheduler2() throws Exception {
|
void testCustomScheduler2() throws Exception {
|
||||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||||
Thread.ofVirtual().start(() -> {
|
Thread.ofVirtual().start(() -> {
|
||||||
try {
|
try {
|
||||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||||
ref.set(scheduler(Thread.currentThread()));
|
ref.set(scheduler(Thread.currentThread()));
|
||||||
}).join();
|
}).join();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}).join();
|
}).join();
|
||||||
assertTrue(ref.get() == SCHEDULER_1);
|
assertTrue(ref.get() == scheduler1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,9 +97,9 @@ public class CustomScheduler {
|
|||||||
* The scheduler should be inherited.
|
* The scheduler should be inherited.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCustomScheduler3() throws Exception {
|
void testCustomScheduler3() throws Exception {
|
||||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.ofVirtual().start(() -> {
|
Thread.ofVirtual().start(() -> {
|
||||||
ref.set(scheduler(Thread.currentThread()));
|
ref.set(scheduler(Thread.currentThread()));
|
||||||
@ -108,7 +108,7 @@ public class CustomScheduler {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}).join();
|
}).join();
|
||||||
assertTrue(ref.get() == SCHEDULER_1);
|
assertTrue(ref.get() == scheduler1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,25 +116,25 @@ public class CustomScheduler {
|
|||||||
* that uses a different custom scheduler.
|
* that uses a different custom scheduler.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCustomScheduler4() throws Exception {
|
void testCustomScheduler4() throws Exception {
|
||||||
AtomicReference<Executor> ref = new AtomicReference<>();
|
AtomicReference<Executor> ref = new AtomicReference<>();
|
||||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_1).start(() -> {
|
ThreadBuilders.virtualThreadBuilder(scheduler1).start(() -> {
|
||||||
try {
|
try {
|
||||||
ThreadBuilders.virtualThreadBuilder(SCHEDULER_2).start(() -> {
|
ThreadBuilders.virtualThreadBuilder(scheduler2).start(() -> {
|
||||||
ref.set(scheduler(Thread.currentThread()));
|
ref.set(scheduler(Thread.currentThread()));
|
||||||
}).join();
|
}).join();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}).join();
|
}).join();
|
||||||
assertTrue(ref.get() == SCHEDULER_2);
|
assertTrue(ref.get() == scheduler2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test running task on a virtual thread, should thrown WrongThreadException.
|
* Test running task on a virtual thread, should thrown WrongThreadException.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBadCarrier() {
|
void testBadCarrier() {
|
||||||
Executor scheduler = (task) -> {
|
Executor scheduler = (task) -> {
|
||||||
var exc = new AtomicReference<Throwable>();
|
var exc = new AtomicReference<Throwable>();
|
||||||
try {
|
try {
|
||||||
@ -160,10 +160,9 @@ public class CustomScheduler {
|
|||||||
* carrier thread when the task completes.
|
* carrier thread when the task completes.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkWithInterruptSet() {
|
void testParkWithInterruptSet() {
|
||||||
Thread carrier = Thread.currentThread();
|
Thread carrier = Thread.currentThread();
|
||||||
if (carrier.isVirtual())
|
assumeFalse(carrier.isVirtual(), "Main thread is a virtual thread");
|
||||||
throw new SkipException("Main test is a virtual thread");
|
|
||||||
try {
|
try {
|
||||||
var builder = ThreadBuilders.virtualThreadBuilder(Runnable::run);
|
var builder = ThreadBuilders.virtualThreadBuilder(Runnable::run);
|
||||||
Thread vthread = builder.start(() -> {
|
Thread vthread = builder.start(() -> {
|
||||||
@ -182,10 +181,9 @@ public class CustomScheduler {
|
|||||||
* the carrier thread when the task completes.
|
* the carrier thread when the task completes.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTerminateWithInterruptSet() {
|
void testTerminateWithInterruptSet() {
|
||||||
Thread carrier = Thread.currentThread();
|
Thread carrier = Thread.currentThread();
|
||||||
if (carrier.isVirtual())
|
assumeFalse(carrier.isVirtual(), "Main thread is a virtual thread");
|
||||||
throw new SkipException("Main test is a virtual thread");
|
|
||||||
try {
|
try {
|
||||||
var builder = ThreadBuilders.virtualThreadBuilder(Runnable::run);
|
var builder = ThreadBuilders.virtualThreadBuilder(Runnable::run);
|
||||||
Thread vthread = builder.start(() -> {
|
Thread vthread = builder.start(() -> {
|
||||||
@ -202,9 +200,8 @@ public class CustomScheduler {
|
|||||||
* Test running task with the carrier interrupt status set.
|
* Test running task with the carrier interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRunWithInterruptSet() throws Exception {
|
void testRunWithInterruptSet() throws Exception {
|
||||||
if (Thread.currentThread().isVirtual())
|
assumeFalse(Thread.currentThread().isVirtual(), "Main thread is a virtual thread");
|
||||||
throw new SkipException("Main test is a virtual thread");
|
|
||||||
Executor scheduler = (task) -> {
|
Executor scheduler = (task) -> {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
task.run();
|
task.run();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,9 +25,10 @@
|
|||||||
* @test
|
* @test
|
||||||
* @summary Test Thread.getStackTrace to examine the stack trace of a virtual
|
* @summary Test Thread.getStackTrace to examine the stack trace of a virtual
|
||||||
* thread and its carrier
|
* thread and its carrier
|
||||||
* @modules java.base/java.lang:+open
|
* @requires vm.continuations
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng GetStackTrace
|
* @modules java.base/java.lang:+open
|
||||||
|
* @run main GetStackTrace
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,7 +27,7 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @modules java.base/java.lang:+open
|
* @modules java.base/java.lang:+open
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng HoldsLock
|
* @run junit HoldsLock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@
|
|||||||
* @requires vm.continuations & vm.debug
|
* @requires vm.continuations & vm.debug
|
||||||
* @modules java.base/java.lang:+open
|
* @modules java.base/java.lang:+open
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng/othervm -XX:+UseHeavyMonitors HoldsLock
|
* @run junit/othervm -XX:+UseHeavyMonitors HoldsLock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.management.LockInfo;
|
import java.lang.management.LockInfo;
|
||||||
@ -52,15 +52,17 @@ import java.util.concurrent.RejectedExecutionException;
|
|||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
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 LOCK1 = new Object();
|
||||||
static final Object LOCK2 = new Object();
|
static final Object LOCK2 = new Object();
|
||||||
|
|
||||||
@Test(enabled=false) // JDK-8281642
|
@Disabled("JDK-8281642")
|
||||||
public void testHoldsLock() throws Exception {
|
@Test
|
||||||
|
void testHoldsLock() throws Exception {
|
||||||
var q = new ArrayBlockingQueue<Runnable>(5);
|
var q = new ArrayBlockingQueue<Runnable>(5);
|
||||||
|
|
||||||
Thread carrier = Thread.ofPlatform().start(() -> {
|
Thread carrier = Thread.ofPlatform().start(() -> {
|
||||||
@ -85,7 +87,7 @@ public class HoldsLock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThreadInfo() throws Exception {
|
void testThreadInfo() throws Exception {
|
||||||
var q = new ArrayBlockingQueue<Runnable>(5);
|
var q = new ArrayBlockingQueue<Runnable>(5);
|
||||||
|
|
||||||
Thread carrier = spawnCarrier(q);
|
Thread carrier = spawnCarrier(q);
|
||||||
@ -123,10 +125,10 @@ public class HoldsLock {
|
|||||||
|
|
||||||
if (tid == carrierId) {
|
if (tid == carrierId) {
|
||||||
// Carrier is WAITING on vthread
|
// Carrier is WAITING on vthread
|
||||||
assertEquals(info.getThreadState(), Thread.State.WAITING);
|
assertTrue(info.getThreadState() == Thread.State.WAITING);
|
||||||
assertEquals(info.getLockInfo().getClassName(), vthread.getClass().getName());
|
assertEquals(vthread.getClass().getName(), info.getLockInfo().getClassName());
|
||||||
assertEquals(info.getLockInfo().getIdentityHashCode(), System.identityHashCode(vthread));
|
assertTrue(info.getLockInfo().getIdentityHashCode() == System.identityHashCode(vthread));
|
||||||
assertEquals(info.getLockOwnerId(), vthreadId);
|
assertTrue(info.getLockOwnerId() == vthreadId);
|
||||||
foundCarrier = true;
|
foundCarrier = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,7 +27,7 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @modules jdk.jfr java.base/java.lang:+open
|
* @modules jdk.jfr java.base/java.lang:+open
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng/othervm JfrEvents
|
* @run junit/othervm JfrEvents
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -48,17 +48,17 @@ import jdk.jfr.Recording;
|
|||||||
import jdk.jfr.consumer.RecordedEvent;
|
import jdk.jfr.consumer.RecordedEvent;
|
||||||
import jdk.jfr.consumer.RecordingFile;
|
import jdk.jfr.consumer.RecordingFile;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class JfrEvents {
|
class JfrEvents {
|
||||||
private static final Object lock = new Object();
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events.
|
* Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testVirtualThreadStartAndEnd() throws Exception {
|
void testVirtualThreadStartAndEnd() throws Exception {
|
||||||
try (Recording recording = new Recording()) {
|
try (Recording recording = new Recording()) {
|
||||||
recording.enable("jdk.VirtualThreadStart");
|
recording.enable("jdk.VirtualThreadStart");
|
||||||
recording.enable("jdk.VirtualThreadEnd");
|
recording.enable("jdk.VirtualThreadEnd");
|
||||||
@ -89,7 +89,7 @@ public class JfrEvents {
|
|||||||
* Test jdk.VirtualThreadPinned event.
|
* Test jdk.VirtualThreadPinned event.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testVirtualThreadPinned() throws Exception {
|
void testVirtualThreadPinned() throws Exception {
|
||||||
try (Recording recording = new Recording()) {
|
try (Recording recording = new Recording()) {
|
||||||
recording.enable("jdk.VirtualThreadPinned")
|
recording.enable("jdk.VirtualThreadPinned")
|
||||||
.withThreshold(Duration.ofMillis(500));
|
.withThreshold(Duration.ofMillis(500));
|
||||||
@ -126,7 +126,7 @@ public class JfrEvents {
|
|||||||
* Test jdk.VirtualThreadSubmitFailed event.
|
* Test jdk.VirtualThreadSubmitFailed event.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testVirtualThreadSubmitFailed() throws Exception {
|
void testVirtualThreadSubmitFailed() throws Exception {
|
||||||
try (Recording recording = new Recording()) {
|
try (Recording recording = new Recording()) {
|
||||||
recording.enable("jdk.VirtualThreadSubmitFailed");
|
recording.enable("jdk.VirtualThreadSubmitFailed");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Test virtual threads using java.util.concurrent locks
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng Locking
|
* @run junit Locking
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@ -34,16 +34,16 @@ import java.util.concurrent.locks.LockSupport;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class Locking {
|
class Locking {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test lock/unlock.
|
* Test lock/unlock.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReentrantLock1() throws Exception {
|
void testReentrantLock1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
assertFalse(lock.isHeldByCurrentThread());
|
assertFalse(lock.isHeldByCurrentThread());
|
||||||
@ -58,7 +58,7 @@ public class Locking {
|
|||||||
* Test tryLock/unlock.
|
* Test tryLock/unlock.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReentrantLock2() throws Exception {
|
void testReentrantLock2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
assertFalse(lock.isHeldByCurrentThread());
|
assertFalse(lock.isHeldByCurrentThread());
|
||||||
@ -74,7 +74,7 @@ public class Locking {
|
|||||||
* Test lock/lock/unlock/unlock.
|
* Test lock/lock/unlock/unlock.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReentrantLock3() throws Exception {
|
void testReentrantLock3() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
assertFalse(lock.isHeldByCurrentThread());
|
assertFalse(lock.isHeldByCurrentThread());
|
||||||
@ -98,7 +98,7 @@ public class Locking {
|
|||||||
* Test locked by platform thread, virtual thread tries to lock.
|
* Test locked by platform thread, virtual thread tries to lock.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReentrantLock4() throws Exception {
|
void testReentrantLock4() throws Exception {
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
var holdsLock = new AtomicBoolean();
|
var holdsLock = new AtomicBoolean();
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ public class Locking {
|
|||||||
* Test locked by virtual thread, platform thread tries to lock.
|
* Test locked by virtual thread, platform thread tries to lock.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReentrantLock5() throws Exception {
|
void testReentrantLock5() throws Exception {
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
@ -170,7 +170,7 @@ public class Locking {
|
|||||||
* Test locked by virtual thread, another virtual thread tries to lock.
|
* Test locked by virtual thread, another virtual thread tries to lock.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReentrantLock6() throws Exception {
|
void testReentrantLock6() throws Exception {
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
var thread1 = Thread.ofVirtual().start(() -> {
|
var thread1 = Thread.ofVirtual().start(() -> {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
@ -27,17 +27,15 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @modules java.base/java.lang:+open
|
* @modules java.base/java.lang:+open
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng ParkWithFixedThreadPool
|
* @run main ParkWithFixedThreadPool
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
import static org.testng.Assert.*;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
public class ParkWithFixedThreadPool {
|
public class ParkWithFixedThreadPool {
|
||||||
@Test
|
public static void main(String[] args) throws Exception {
|
||||||
public static void multipleThreadPoolParkTest() throws Exception {
|
|
||||||
try (ExecutorService scheduler = Executors.newFixedThreadPool(8)) {
|
try (ExecutorService scheduler = Executors.newFixedThreadPool(8)) {
|
||||||
int vthreadCount = 300;
|
int vthreadCount = 300;
|
||||||
Thread[] vthreads = new Thread[vthreadCount];
|
Thread[] vthreads = new Thread[vthreadCount];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,7 +26,7 @@
|
|||||||
* @summary Test virtual threads using park/unpark
|
* @summary Test virtual threads using park/unpark
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng Parking
|
* @run junit Parking
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -34,18 +34,17 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.SkipException;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.testng.Assert.*;
|
|
||||||
|
|
||||||
public class Parking {
|
class Parking {
|
||||||
private static final Object lock = new Object();
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Park, unparked by platform thread.
|
* Park, unparked by platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark1() throws Exception {
|
void testPark1() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(LockSupport::park);
|
var thread = Thread.ofVirtual().start(LockSupport::park);
|
||||||
Thread.sleep(1000); // give time for virtual thread to park
|
Thread.sleep(1000); // give time for virtual thread to park
|
||||||
LockSupport.unpark(thread);
|
LockSupport.unpark(thread);
|
||||||
@ -56,7 +55,7 @@ public class Parking {
|
|||||||
* Park, unparked by virtual thread.
|
* Park, unparked by virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark2() throws Exception {
|
void testPark2() throws Exception {
|
||||||
var thread1 = Thread.ofVirtual().start(LockSupport::park);
|
var thread1 = Thread.ofVirtual().start(LockSupport::park);
|
||||||
Thread.sleep(1000); // give time for virtual thread to park
|
Thread.sleep(1000); // give time for virtual thread to park
|
||||||
var thread2 = Thread.ofVirtual().start(() -> LockSupport.unpark(thread1));
|
var thread2 = Thread.ofVirtual().start(() -> LockSupport.unpark(thread1));
|
||||||
@ -68,7 +67,7 @@ public class Parking {
|
|||||||
* Park while holding monitor, unparked by platform thread.
|
* Park while holding monitor, unparked by platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark3() throws Exception {
|
void testPark3() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
@ -83,15 +82,15 @@ public class Parking {
|
|||||||
* Park with native frame on stack.
|
* Park with native frame on stack.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark4() throws Exception {
|
void testPark4() throws Exception {
|
||||||
throw new SkipException("Not implemented");
|
// not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unpark before park.
|
* Unpark before park.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark5() throws Exception {
|
void testPark5() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
LockSupport.unpark(Thread.currentThread());
|
LockSupport.unpark(Thread.currentThread());
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
@ -103,7 +102,7 @@ public class Parking {
|
|||||||
* 2 x unpark before park.
|
* 2 x unpark before park.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark6() throws Exception {
|
void testPark6() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
Thread me = Thread.currentThread();
|
Thread me = Thread.currentThread();
|
||||||
LockSupport.unpark(me);
|
LockSupport.unpark(me);
|
||||||
@ -120,7 +119,7 @@ public class Parking {
|
|||||||
* 2 x park and unpark by platform thread.
|
* 2 x park and unpark by platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark7() throws Exception {
|
void testPark7() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
@ -142,7 +141,7 @@ public class Parking {
|
|||||||
* Park with interrupt status set.
|
* Park with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark8() throws Exception {
|
void testPark8() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
@ -155,7 +154,7 @@ public class Parking {
|
|||||||
* Thread interrupt when parked.
|
* Thread interrupt when parked.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark9() throws Exception {
|
void testPark9() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
scheduleInterrupt(t, 1000);
|
scheduleInterrupt(t, 1000);
|
||||||
@ -169,7 +168,7 @@ public class Parking {
|
|||||||
* Park while holding monitor and with interrupt status set.
|
* Park while holding monitor and with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark10() throws Exception {
|
void testPark10() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
@ -184,7 +183,7 @@ public class Parking {
|
|||||||
* Thread interrupt when parked while holding monitor
|
* Thread interrupt when parked while holding monitor
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPark11() throws Exception {
|
void testPark11() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
scheduleInterrupt(t, 1000);
|
scheduleInterrupt(t, 1000);
|
||||||
@ -200,7 +199,7 @@ public class Parking {
|
|||||||
* parkNanos(-1) completes immediately
|
* parkNanos(-1) completes immediately
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos1() throws Exception {
|
void testParkNanos1() throws Exception {
|
||||||
VThreadRunner.run(() -> LockSupport.parkNanos(-1));
|
VThreadRunner.run(() -> LockSupport.parkNanos(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +207,7 @@ public class Parking {
|
|||||||
* parkNanos(0) completes immediately
|
* parkNanos(0) completes immediately
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos2() throws Exception {
|
void testParkNanos2() throws Exception {
|
||||||
VThreadRunner.run(() -> LockSupport.parkNanos(0));
|
VThreadRunner.run(() -> LockSupport.parkNanos(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +215,7 @@ public class Parking {
|
|||||||
* parkNanos(1000ms) parks thread.
|
* parkNanos(1000ms) parks thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos3() throws Exception {
|
void testParkNanos3() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
// park for 1000ms
|
// park for 1000ms
|
||||||
long nanos = TimeUnit.NANOSECONDS.convert(1000, TimeUnit.MILLISECONDS);
|
long nanos = TimeUnit.NANOSECONDS.convert(1000, TimeUnit.MILLISECONDS);
|
||||||
@ -234,7 +233,7 @@ public class Parking {
|
|||||||
* Park with parkNanos, unparked by platform thread.
|
* Park with parkNanos, unparked by platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos4() throws Exception {
|
void testParkNanos4() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
||||||
LockSupport.parkNanos(nanos);
|
LockSupport.parkNanos(nanos);
|
||||||
@ -248,7 +247,7 @@ public class Parking {
|
|||||||
* Park with parkNanos, unparked by virtual thread.
|
* Park with parkNanos, unparked by virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos5() throws Exception {
|
void testParkNanos5() throws Exception {
|
||||||
var thread1 = Thread.ofVirtual().start(() -> {
|
var thread1 = Thread.ofVirtual().start(() -> {
|
||||||
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
||||||
LockSupport.parkNanos(nanos);
|
LockSupport.parkNanos(nanos);
|
||||||
@ -263,7 +262,7 @@ public class Parking {
|
|||||||
* Unpark before parkNanos.
|
* Unpark before parkNanos.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos6() throws Exception {
|
void testParkNanos6() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
LockSupport.unpark(Thread.currentThread());
|
LockSupport.unpark(Thread.currentThread());
|
||||||
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
long nanos = TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
|
||||||
@ -275,7 +274,7 @@ public class Parking {
|
|||||||
* Unpark before parkNanos(0), should consume parking permit.
|
* Unpark before parkNanos(0), should consume parking permit.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos7() throws Exception {
|
void testParkNanos7() throws Exception {
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
LockSupport.unpark(Thread.currentThread());
|
LockSupport.unpark(Thread.currentThread());
|
||||||
LockSupport.parkNanos(0); // should consume parking permit
|
LockSupport.parkNanos(0); // should consume parking permit
|
||||||
@ -291,7 +290,7 @@ public class Parking {
|
|||||||
* Park with parkNanos and interrupt status set.
|
* Park with parkNanos and interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos8() throws Exception {
|
void testParkNanos8() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
@ -304,7 +303,7 @@ public class Parking {
|
|||||||
* Thread interrupt when parked in parkNanos.
|
* Thread interrupt when parked in parkNanos.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos9() throws Exception {
|
void testParkNanos9() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
scheduleInterrupt(t, 1000);
|
scheduleInterrupt(t, 1000);
|
||||||
@ -318,7 +317,7 @@ public class Parking {
|
|||||||
* Park with parkNanos while holding monitor and with interrupt status set.
|
* Park with parkNanos while holding monitor and with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos10() throws Exception {
|
void testParkNanos10() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
@ -333,7 +332,7 @@ public class Parking {
|
|||||||
* Thread interrupt when parked in parkNanos and while holding monitor.
|
* Thread interrupt when parked in parkNanos and while holding monitor.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParkNanos11() throws Exception {
|
void testParkNanos11() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
scheduleInterrupt(t, 1000);
|
scheduleInterrupt(t, 1000);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,25 +24,25 @@
|
|||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @summary Test that preview APIs throws exception when preview features not enabled
|
* @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.Method;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class PreviewFeaturesNotEnabled {
|
class PreviewFeaturesNotEnabled {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread.ofVirtual should fail with UOE.
|
* Thread.ofVirtual should fail with UOE.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOfVirtual() throws Exception {
|
void testOfVirtual() throws Exception {
|
||||||
Method ofVirtual = Thread.class.getDeclaredMethod("ofVirtual");
|
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);
|
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,10 +50,10 @@ public class PreviewFeaturesNotEnabled {
|
|||||||
* Thread.startVirtualThread should fail with UOE.
|
* Thread.startVirtualThread should fail with UOE.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStartVirutalThread() throws Exception {
|
void testStartVirutalThread() throws Exception {
|
||||||
Method startVirtualThread = Thread.class.getMethod("startVirtualThread", Runnable.class);
|
Method startVirtualThread = Thread.class.getMethod("startVirtualThread", Runnable.class);
|
||||||
Runnable task = () -> { };
|
Runnable task = () -> { };
|
||||||
var exc = expectThrows(InvocationTargetException.class,
|
var exc = assertThrows(InvocationTargetException.class,
|
||||||
() -> startVirtualThread.invoke(null, task));
|
() -> startVirtualThread.invoke(null, task));
|
||||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||||
}
|
}
|
||||||
@ -62,9 +62,9 @@ public class PreviewFeaturesNotEnabled {
|
|||||||
* Executors.newVirtualThreadPerTaskExecutor should fail with UOE.
|
* Executors.newVirtualThreadPerTaskExecutor should fail with UOE.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewVirtualThreadPerTaskExecutor() throws Exception {
|
void testNewVirtualThreadPerTaskExecutor() throws Exception {
|
||||||
Method newVirtualThreadPerTaskExecutor = Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
|
Method newVirtualThreadPerTaskExecutor = Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
|
||||||
var exc = expectThrows(InvocationTargetException.class,
|
var exc = assertThrows(InvocationTargetException.class,
|
||||||
() -> newVirtualThreadPerTaskExecutor.invoke(null));
|
() -> newVirtualThreadPerTaskExecutor.invoke(null));
|
||||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||||
}
|
}
|
||||||
@ -73,8 +73,8 @@ public class PreviewFeaturesNotEnabled {
|
|||||||
* Directly accessing internal Continuation class should fail with UOE.
|
* Directly accessing internal Continuation class should fail with UOE.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testContinuationInitializer() throws Exception {
|
void testContinuationInitializer() throws Exception {
|
||||||
var exc = expectThrows(ExceptionInInitializerError.class,
|
var exc = assertThrows(ExceptionInInitializerError.class,
|
||||||
() -> Class.forName("jdk.internal.vm.Continuation"));
|
() -> Class.forName("jdk.internal.vm.Continuation"));
|
||||||
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
assertTrue(exc.getCause() instanceof UnsupportedOperationException);
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ public class PreviewFeaturesNotEnabled {
|
|||||||
* Thread.isVirtual should not fail.
|
* Thread.isVirtual should not fail.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testIsVirtual() throws Exception {
|
void testIsVirtual() throws Exception {
|
||||||
boolean isVirtual = isVirtual(Thread.currentThread());
|
boolean isVirtual = isVirtual(Thread.currentThread());
|
||||||
assertFalse(isVirtual);
|
assertFalse(isVirtual);
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ public class PreviewFeaturesNotEnabled {
|
|||||||
* Thread.ofPlatform should not fail.
|
* Thread.ofPlatform should not fail.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOfPlatform() throws Exception {
|
void testOfPlatform() throws Exception {
|
||||||
Method ofPlatform = Thread.class.getDeclaredMethod("ofPlatform");
|
Method ofPlatform = Thread.class.getDeclaredMethod("ofPlatform");
|
||||||
Object builder = ofPlatform.invoke(null);
|
Object builder = ofPlatform.invoke(null);
|
||||||
Method startMethod = Class.forName("java.lang.Thread$Builder")
|
Method startMethod = Class.forName("java.lang.Thread$Builder")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,7 +27,7 @@
|
|||||||
* @modules java.base/java.lang:+open
|
* @modules java.base/java.lang:+open
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng Reflection
|
* @run junit Reflection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
@ -39,17 +39,17 @@ import java.util.concurrent.ThreadFactory;
|
|||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.SkipException;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assumptions.*;
|
||||||
|
|
||||||
public class Reflection {
|
class Reflection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test invoking static method.
|
* Test invoking static method.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeStatic1() throws Exception {
|
void testInvokeStatic1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
int result = (int) divideMethod().invoke(null, 20, 2);
|
int result = (int) divideMethod().invoke(null, 20, 2);
|
||||||
assertTrue(result == 10);
|
assertTrue(result == 10);
|
||||||
@ -61,7 +61,7 @@ public class Reflection {
|
|||||||
* exception.
|
* exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeStatic2() throws Exception {
|
void testInvokeStatic2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try {
|
try {
|
||||||
divideMethod().invoke(null, 20, 0);
|
divideMethod().invoke(null, 20, 0);
|
||||||
@ -77,7 +77,7 @@ public class Reflection {
|
|||||||
* method with bad parameters.
|
* method with bad parameters.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeStatic3() throws Exception {
|
void testInvokeStatic3() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> divideMethod().invoke(null));
|
() -> divideMethod().invoke(null));
|
||||||
@ -99,7 +99,7 @@ public class Reflection {
|
|||||||
* method triggers its class to be initialized and it fails with exception.
|
* method triggers its class to be initialized and it fails with exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeStatic4() throws Exception {
|
void testInvokeStatic4() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Method foo = BadClass1.class.getDeclaredMethod("foo");
|
Method foo = BadClass1.class.getDeclaredMethod("foo");
|
||||||
try {
|
try {
|
||||||
@ -123,7 +123,7 @@ public class Reflection {
|
|||||||
* class to be initialized and it fails with an error.
|
* class to be initialized and it fails with an error.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeStatic5() throws Exception {
|
void testInvokeStatic5() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Method foo = BadClass2.class.getDeclaredMethod("foo");
|
Method foo = BadClass2.class.getDeclaredMethod("foo");
|
||||||
assertThrows(AbstractMethodError.class, () -> foo.invoke(null));
|
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 that invoking a static method does not pin the carrier thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeStatic6() throws Exception {
|
void testInvokeStatic6() throws Exception {
|
||||||
if (!ThreadBuilders.supportsCustomScheduler())
|
assumeTrue(ThreadBuilders.supportsCustomScheduler(), "No support for custom schedulers");
|
||||||
throw new SkipException("No support for custom schedulers");
|
|
||||||
Method parkMethod = Parker.class.getDeclaredMethod("park");
|
Method parkMethod = Parker.class.getDeclaredMethod("park");
|
||||||
try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
|
try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
|
||||||
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
|
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
|
||||||
@ -172,7 +171,7 @@ public class Reflection {
|
|||||||
* Test invoking instance method.
|
* Test invoking instance method.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeInstance1() throws Exception {
|
void testInvokeInstance1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
var adder = new Adder();
|
var adder = new Adder();
|
||||||
Adder.addMethod().invoke(adder, 5);
|
Adder.addMethod().invoke(adder, 5);
|
||||||
@ -185,7 +184,7 @@ public class Reflection {
|
|||||||
* exception.
|
* exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeInstance2() throws Exception {
|
void testInvokeInstance2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
var adder = new Adder();
|
var adder = new Adder();
|
||||||
try {
|
try {
|
||||||
@ -202,7 +201,7 @@ public class Reflection {
|
|||||||
* trying to invoke an instance method with null or bad parameters.
|
* trying to invoke an instance method with null or bad parameters.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeInstance3() throws Exception {
|
void testInvokeInstance3() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
var adder = new Adder();
|
var adder = new Adder();
|
||||||
Method addMethod = Adder.addMethod();
|
Method addMethod = Adder.addMethod();
|
||||||
@ -223,7 +222,7 @@ public class Reflection {
|
|||||||
* Test invoking newInstance to create an object.
|
* Test invoking newInstance to create an object.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewInstance1() throws Exception {
|
void testNewInstance1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
||||||
Adder adder = (Adder) ctor.newInstance(10);
|
Adder adder = (Adder) ctor.newInstance(10);
|
||||||
@ -236,7 +235,7 @@ public class Reflection {
|
|||||||
* exception.
|
* exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewInstance2() throws Exception {
|
void testNewInstance2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
||||||
try {
|
try {
|
||||||
@ -253,7 +252,7 @@ public class Reflection {
|
|||||||
* with bad parameters.
|
* with bad parameters.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewInstance3() throws Exception {
|
void testNewInstance3() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
var adder = new Adder();
|
var adder = new Adder();
|
||||||
Constructor<?> ctor = Adder.class.getDeclaredConstructor(long.class);
|
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.
|
* triggers the class to be initialized and it fails with exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewInstance4() throws Exception {
|
void testNewInstance4() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Constructor<?> ctor = BadClass3.class.getDeclaredConstructor();
|
Constructor<?> ctor = BadClass3.class.getDeclaredConstructor();
|
||||||
try {
|
try {
|
||||||
@ -299,7 +298,7 @@ public class Reflection {
|
|||||||
* to be initialized and it fails with an error.
|
* to be initialized and it fails with an error.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewInstance5() throws Exception {
|
void testNewInstance5() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Constructor<?> ctor = BadClass4.class.getDeclaredConstructor();
|
Constructor<?> ctor = BadClass4.class.getDeclaredConstructor();
|
||||||
assertThrows(AbstractMethodError.class, () -> ctor.newInstance((Object[])null));
|
assertThrows(AbstractMethodError.class, () -> ctor.newInstance((Object[])null));
|
||||||
@ -317,9 +316,8 @@ public class Reflection {
|
|||||||
* Test that newInstance does not pin the carrier thread
|
* Test that newInstance does not pin the carrier thread
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewInstance6() throws Exception {
|
void testNewInstance6() throws Exception {
|
||||||
if (!ThreadBuilders.supportsCustomScheduler())
|
assumeTrue(ThreadBuilders.supportsCustomScheduler(), "No support for custom schedulers");
|
||||||
throw new SkipException("No support for custom schedulers");
|
|
||||||
Constructor<?> ctor = Parker.class.getDeclaredConstructor();
|
Constructor<?> ctor = Parker.class.getDeclaredConstructor();
|
||||||
try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
|
try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
|
||||||
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
|
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,8 +29,8 @@
|
|||||||
* @modules java.management
|
* @modules java.management
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng StackTraces
|
* @run junit StackTraces
|
||||||
* @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:+ShowCarrierFrames StackTraces
|
* @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:+ShowCarrierFrames StackTraces
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
@ -40,17 +40,17 @@ import java.util.concurrent.ForkJoinPool;
|
|||||||
import static java.lang.StackWalker.Option.*;
|
import static java.lang.StackWalker.Option.*;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
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
|
* Test that the stack trace in exceptions does not include the carrier thread
|
||||||
* frames, except when running with -XX:+ShowCarrierFrames.
|
* frames, except when running with -XX:+ShowCarrierFrames.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStackTrace() throws Exception {
|
void testStackTrace() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Exception e = new Exception();
|
Exception e = new Exception();
|
||||||
boolean found = Arrays.stream(e.getStackTrace())
|
boolean found = Arrays.stream(e.getStackTrace())
|
||||||
@ -64,7 +64,7 @@ public class StackTraces {
|
|||||||
* Test that StackWalker does not include carrier thread frames.
|
* Test that StackWalker does not include carrier thread frames.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStackWalker() throws Exception {
|
void testStackWalker() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
StackWalker walker = StackWalker.getInstance(Set.of(RETAIN_CLASS_REFERENCE));
|
StackWalker walker = StackWalker.getInstance(Set.of(RETAIN_CLASS_REFERENCE));
|
||||||
boolean found = walker.walk(sf ->
|
boolean found = walker.walk(sf ->
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,14 +26,14 @@
|
|||||||
* @summary Test Virtual threads using thread locals
|
* @summary Test Virtual threads using thread locals
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng ThreadLocals
|
* @run junit ThreadLocals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class ThreadLocals {
|
class ThreadLocals {
|
||||||
static final ThreadLocal<Object> LOCAL = new ThreadLocal<>();
|
static final ThreadLocal<Object> LOCAL = new ThreadLocal<>();
|
||||||
static final ThreadLocal<Object> INHERITED_LOCAL = new InheritableThreadLocal<>();
|
static final ThreadLocal<Object> INHERITED_LOCAL = new InheritableThreadLocal<>();
|
||||||
|
|
||||||
@ -41,10 +41,10 @@ public class ThreadLocals {
|
|||||||
* Basic test of thread local set/get.
|
* Basic test of thread local set/get.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocal1() throws Exception {
|
void testThreadLocal1() throws Exception {
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
assertTrue(LOCAL.get() == null);
|
assertNull(LOCAL.get());
|
||||||
Object obj = new Object();
|
Object obj = new Object();
|
||||||
LOCAL.set(obj);
|
LOCAL.set(obj);
|
||||||
assertTrue(LOCAL.get() == obj);
|
assertTrue(LOCAL.get() == obj);
|
||||||
@ -56,9 +56,9 @@ public class ThreadLocals {
|
|||||||
* Test setting thread local before blocking operation.
|
* Test setting thread local before blocking operation.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocal2() throws Exception {
|
void testThreadLocal2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
assertTrue(LOCAL.get() == null);
|
assertNull(LOCAL.get());
|
||||||
Object obj = new Object();
|
Object obj = new Object();
|
||||||
LOCAL.set(obj);
|
LOCAL.set(obj);
|
||||||
try { Thread.sleep(100); } catch (InterruptedException e) { }
|
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 Thread that cannot set values for its copy of thread-locals.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadLocal3() throws Exception {
|
void testThreadLocal3() throws Exception {
|
||||||
Object INITIAL_VALUE = new Object();
|
Object INITIAL_VALUE = new Object();
|
||||||
ThreadLocal<Object> LOCAL2 = new ThreadLocal<>() {
|
ThreadLocal<Object> LOCAL2 = new ThreadLocal<>() {
|
||||||
@Override
|
@Override
|
||||||
@ -88,7 +88,7 @@ public class ThreadLocals {
|
|||||||
VThreadRunner.run(VThreadRunner.NO_THREAD_LOCALS, () -> {
|
VThreadRunner.run(VThreadRunner.NO_THREAD_LOCALS, () -> {
|
||||||
assertThrows(UnsupportedOperationException.class, () -> LOCAL.set(null));
|
assertThrows(UnsupportedOperationException.class, () -> LOCAL.set(null));
|
||||||
assertThrows(UnsupportedOperationException.class, () -> LOCAL.set(new Object()));
|
assertThrows(UnsupportedOperationException.class, () -> LOCAL.set(new Object()));
|
||||||
assertTrue(LOCAL.get() == null);
|
assertNull(LOCAL.get());
|
||||||
LOCAL.remove(); // should not throw
|
LOCAL.remove(); // should not throw
|
||||||
|
|
||||||
assertThrows(UnsupportedOperationException.class, () -> LOCAL2.set(null));
|
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(null));
|
||||||
assertThrows(UnsupportedOperationException.class, () -> INHERITED_LOCAL.set(new Object()));
|
assertThrows(UnsupportedOperationException.class, () -> INHERITED_LOCAL.set(new Object()));
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
INHERITED_LOCAL.remove(); // should not throw
|
INHERITED_LOCAL.remove(); // should not throw
|
||||||
|
|
||||||
assertThrows(UnsupportedOperationException.class, () -> INHERITED_LOCAL2.set(null));
|
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.
|
* Basic test of inheritable thread local set/get, no initial value inherited.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocal1() throws Exception {
|
void testInheritedThreadLocal1() throws Exception {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
Object obj = new Object();
|
Object obj = new Object();
|
||||||
INHERITED_LOCAL.set(obj);
|
INHERITED_LOCAL.set(obj);
|
||||||
assertTrue(INHERITED_LOCAL.get() == 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 inheriting initial value of InheritableThreadLocal from platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocal2() throws Exception {
|
void testInheritedThreadLocal2() throws Exception {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
var obj = new Object();
|
var obj = new Object();
|
||||||
INHERITED_LOCAL.set(obj);
|
INHERITED_LOCAL.set(obj);
|
||||||
try {
|
try {
|
||||||
@ -146,8 +146,8 @@ public class ThreadLocals {
|
|||||||
* Test inheriting initial value of InheritableThreadLocal from virtual thread.
|
* Test inheriting initial value of InheritableThreadLocal from virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocal3() throws Exception {
|
void testInheritedThreadLocal3() throws Exception {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
var obj = new Object();
|
var obj = new Object();
|
||||||
INHERITED_LOCAL.set(obj);
|
INHERITED_LOCAL.set(obj);
|
||||||
@ -157,7 +157,7 @@ public class ThreadLocals {
|
|||||||
assertTrue(INHERITED_LOCAL.get() == obj);
|
assertTrue(INHERITED_LOCAL.get() == obj);
|
||||||
|
|
||||||
});
|
});
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,14 +165,14 @@ public class ThreadLocals {
|
|||||||
* from platform thread.
|
* from platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocal4() throws Exception {
|
void testInheritedThreadLocal4() throws Exception {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
var obj = new Object();
|
var obj = new Object();
|
||||||
INHERITED_LOCAL.set(obj);
|
INHERITED_LOCAL.set(obj);
|
||||||
try {
|
try {
|
||||||
int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
|
int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
|
||||||
VThreadRunner.run(characteristics, () -> {
|
VThreadRunner.run(characteristics, () -> {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
INHERITED_LOCAL.remove();
|
INHERITED_LOCAL.remove();
|
||||||
@ -184,18 +184,18 @@ public class ThreadLocals {
|
|||||||
* from virtual thread.
|
* from virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInheritedThreadLocal5() throws Exception {
|
void testInheritedThreadLocal5() throws Exception {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
var obj = new Object();
|
var obj = new Object();
|
||||||
INHERITED_LOCAL.set(obj);
|
INHERITED_LOCAL.set(obj);
|
||||||
int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
|
int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
|
||||||
VThreadRunner.run(characteristics, () -> {
|
VThreadRunner.run(characteristics, () -> {
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
});
|
});
|
||||||
assertTrue(INHERITED_LOCAL.get() == obj);
|
assertTrue(INHERITED_LOCAL.get() == obj);
|
||||||
|
|
||||||
});
|
});
|
||||||
assertTrue(INHERITED_LOCAL.get() == null);
|
assertNull(INHERITED_LOCAL.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,8 +28,8 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm -Djdk.tracePinnedThreads=full TracePinnedThreads
|
* @run junit/othervm -Djdk.tracePinnedThreads=full TracePinnedThreads
|
||||||
* @run testng/othervm -Djdk.tracePinnedThreads=short TracePinnedThreads
|
* @run junit/othervm -Djdk.tracePinnedThreads=short TracePinnedThreads
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@ -38,10 +38,10 @@ import java.time.Duration;
|
|||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class TracePinnedThreads {
|
class TracePinnedThreads {
|
||||||
static final Object lock = new Object();
|
static final Object lock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +62,7 @@ public class TracePinnedThreads {
|
|||||||
* Test parking inside synchronized block.
|
* Test parking inside synchronized block.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPinnedCausedBySynchronizedBlock() throws Exception {
|
void testPinnedCausedBySynchronizedBlock() throws Exception {
|
||||||
String output = run(() -> {
|
String output = run(() -> {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
park();
|
park();
|
||||||
@ -76,7 +76,7 @@ public class TracePinnedThreads {
|
|||||||
* Test parking with native frame on stack.
|
* Test parking with native frame on stack.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPinnedCausedByNativeMethod() throws Exception {
|
void testPinnedCausedByNativeMethod() throws Exception {
|
||||||
System.loadLibrary("TracePinnedThreads");
|
System.loadLibrary("TracePinnedThreads");
|
||||||
String output = run(() -> invokePark());
|
String output = run(() -> invokePark());
|
||||||
assertContains(output, "(Native Method)");
|
assertContains(output, "(Native Method)");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Test virtual threads using Object.wait/notifyAll
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng WaitNotify
|
* @run junit WaitNotify
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class WaitNotify {
|
class WaitNotify {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test virtual thread waits, notified by platform thread.
|
* Test virtual thread waits, notified by platform thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWaitNotify1() throws Exception {
|
void testWaitNotify1() throws Exception {
|
||||||
var lock = new Object();
|
var lock = new Object();
|
||||||
var ready = new Semaphore(0);
|
var ready = new Semaphore(0);
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
@ -64,7 +64,7 @@ public class WaitNotify {
|
|||||||
* Test platform thread waits, notified by virtual thread.
|
* Test platform thread waits, notified by virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWaitNotify2() throws Exception {
|
void testWaitNotify2() throws Exception {
|
||||||
var lock = new Object();
|
var lock = new Object();
|
||||||
var ready = new Semaphore(0);
|
var ready = new Semaphore(0);
|
||||||
var thread = Thread.ofVirtual().start(() -> {
|
var thread = Thread.ofVirtual().start(() -> {
|
||||||
@ -84,7 +84,7 @@ public class WaitNotify {
|
|||||||
* Test virtual thread waits, notified by another virtual thread.
|
* Test virtual thread waits, notified by another virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWaitNotify3() throws Exception {
|
void testWaitNotify3() throws Exception {
|
||||||
var lock = new Object();
|
var lock = new Object();
|
||||||
var ready = new Semaphore(0);
|
var ready = new Semaphore(0);
|
||||||
var thread1 = Thread.ofVirtual().start(() -> {
|
var thread1 = Thread.ofVirtual().start(() -> {
|
||||||
@ -109,7 +109,7 @@ public class WaitNotify {
|
|||||||
* Test interrupt status set when calling Object.wait.
|
* Test interrupt status set when calling Object.wait.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWaitNotify4() throws Exception {
|
void testWaitNotify4() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
@ -130,7 +130,7 @@ public class WaitNotify {
|
|||||||
* Test interrupt when blocked in Object.wait.
|
* Test interrupt when blocked in Object.wait.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWaitNotify5() throws Exception {
|
void testWaitNotify5() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
scheduleInterrupt(t, 1000);
|
scheduleInterrupt(t, 1000);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,7 @@
|
|||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @summary Unit tests for java.lang.ThreadGroup
|
* @summary Unit tests for java.lang.ThreadGroup
|
||||||
* @run testng BasicTests
|
* @run junit BasicTests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@ -34,25 +34,25 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class BasicTests {
|
class BasicTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetName1() {
|
void testGetName1() {
|
||||||
ThreadGroup group = new ThreadGroup(null);
|
ThreadGroup group = new ThreadGroup(null);
|
||||||
assertTrue(group.getName() == null);
|
assertTrue(group.getName() == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetName2() {
|
void testGetName2() {
|
||||||
ThreadGroup group = new ThreadGroup("fred");
|
ThreadGroup group = new ThreadGroup("fred");
|
||||||
assertEquals(group.getName(), "fred");
|
assertEquals("fred", group.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetParent() {
|
void testGetParent() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
||||||
@ -63,7 +63,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParentOf() {
|
void testParentOf() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
||||||
@ -85,7 +85,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActiveCount1() {
|
void testActiveCount1() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertTrue(group.activeCount() == 0);
|
assertTrue(group.activeCount() == 0);
|
||||||
TestThread thread = TestThread.start(group, "foo");
|
TestThread thread = TestThread.start(group, "foo");
|
||||||
@ -98,7 +98,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActiveCount2() {
|
void testActiveCount2() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
assertTrue(group1.activeCount() == 0);
|
assertTrue(group1.activeCount() == 0);
|
||||||
@ -124,7 +124,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void enumerateThreads1() {
|
void enumerateThreads1() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
Thread[] threads = new Thread[100];
|
Thread[] threads = new Thread[100];
|
||||||
assertTrue(group.enumerate(threads) == 0);
|
assertTrue(group.enumerate(threads) == 0);
|
||||||
@ -156,7 +156,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void enumerateThreads2() {
|
void enumerateThreads2() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
|
|
||||||
@ -203,12 +203,12 @@ public class BasicTests {
|
|||||||
try {
|
try {
|
||||||
Arrays.setAll(threads, i -> null);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group1.enumerate(threads) == 2);
|
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);
|
assertTrue(threads[2] == null);
|
||||||
|
|
||||||
Arrays.setAll(threads, i -> null);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group1.enumerate(threads, true) == 2);
|
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);
|
assertTrue(threads[2] == null);
|
||||||
|
|
||||||
Arrays.setAll(threads, i -> null);
|
Arrays.setAll(threads, i -> null);
|
||||||
@ -261,7 +261,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void enumerateThreads3() {
|
void enumerateThreads3() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
ThreadGroup group3 = new ThreadGroup(group2, "group3");
|
||||||
@ -304,20 +304,20 @@ public class BasicTests {
|
|||||||
try {
|
try {
|
||||||
Arrays.setAll(threads, i -> null);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group1.enumerate(threads) == 2);
|
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);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group1.enumerate(threads, true) == 2);
|
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);
|
assertTrue(group1.enumerate(threads, false) == 0);
|
||||||
|
|
||||||
Arrays.setAll(threads, i -> null);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group2.enumerate(threads) == 2);
|
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);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group2.enumerate(threads, true) == 2);
|
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);
|
Arrays.setAll(threads, i -> null);
|
||||||
assertTrue(group2.enumerate(threads, false) == 1);
|
assertTrue(group2.enumerate(threads, false) == 1);
|
||||||
@ -391,7 +391,7 @@ public class BasicTests {
|
|||||||
* Test enumerate(Thread[]) with an array of insufficient size
|
* Test enumerate(Thread[]) with an array of insufficient size
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void enumerateThreads4() {
|
void enumerateThreads4() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
|
|
||||||
// array too small
|
// array too small
|
||||||
@ -418,7 +418,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActiveGroupCount() throws Exception {
|
void testActiveGroupCount() throws Exception {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
assertTrue(group1.activeGroupCount() == 0);
|
assertTrue(group1.activeGroupCount() == 0);
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnumerateGroups1() throws Exception {
|
void testEnumerateGroups1() throws Exception {
|
||||||
ThreadGroup[] groups = new ThreadGroup[100];
|
ThreadGroup[] groups = new ThreadGroup[100];
|
||||||
|
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
@ -477,12 +477,12 @@ public class BasicTests {
|
|||||||
|
|
||||||
Arrays.setAll(groups, i -> null);
|
Arrays.setAll(groups, i -> null);
|
||||||
assertTrue(group1.enumerate(groups) == 2);
|
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);
|
assertTrue(groups[2] == null);
|
||||||
|
|
||||||
Arrays.setAll(groups, i -> null);
|
Arrays.setAll(groups, i -> null);
|
||||||
assertTrue(group1.enumerate(groups, true) == 2);
|
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);
|
assertTrue(groups[2] == null);
|
||||||
|
|
||||||
Arrays.setAll(groups, i -> null);
|
Arrays.setAll(groups, i -> null);
|
||||||
@ -546,7 +546,7 @@ public class BasicTests {
|
|||||||
* Test enumerate(ThreadGroup[]) with an array of insufficient size
|
* Test enumerate(ThreadGroup[]) with an array of insufficient size
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testEnumerateGroups2() throws Exception {
|
void testEnumerateGroups2() throws Exception {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
ThreadGroup child1 = new ThreadGroup(group, "child1");
|
ThreadGroup child1 = new ThreadGroup(group, "child1");
|
||||||
ThreadGroup child2 = new ThreadGroup(group,"child2");
|
ThreadGroup child2 = new ThreadGroup(group,"child2");
|
||||||
@ -568,7 +568,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxPriority1() {
|
void testMaxPriority1() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
final int maxPriority = group.getMaxPriority();
|
final int maxPriority = group.getMaxPriority();
|
||||||
assertTrue(maxPriority == Thread.currentThread().getThreadGroup().getMaxPriority());
|
assertTrue(maxPriority == Thread.currentThread().getThreadGroup().getMaxPriority());
|
||||||
@ -592,7 +592,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxPriority2() {
|
void testMaxPriority2() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
int maxPriority = group1.getMaxPriority();
|
int maxPriority = group1.getMaxPriority();
|
||||||
if (maxPriority > Thread.MIN_PRIORITY) {
|
if (maxPriority > Thread.MIN_PRIORITY) {
|
||||||
@ -630,7 +630,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxPriority3() {
|
void testMaxPriority3() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
if (group.getMaxPriority() > Thread.MIN_PRIORITY) {
|
if (group.getMaxPriority() > Thread.MIN_PRIORITY) {
|
||||||
int maxPriority = Thread.MIN_PRIORITY + 1;
|
int maxPriority = Thread.MIN_PRIORITY + 1;
|
||||||
@ -656,7 +656,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInterrupt1() {
|
void testInterrupt1() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertTrue(group.activeCount() == 0);
|
assertTrue(group.activeCount() == 0);
|
||||||
TestThread thread = TestThread.start(group, "foo");
|
TestThread thread = TestThread.start(group, "foo");
|
||||||
@ -669,7 +669,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInterrupt2() {
|
void testInterrupt2() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
TestThread thread1 = TestThread.start(group1, "foo");
|
TestThread thread1 = TestThread.start(group1, "foo");
|
||||||
@ -685,7 +685,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInterrupt3() {
|
void testInterrupt3() {
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
ThreadGroup group2 = new ThreadGroup(group1, "group2");
|
||||||
TestThread thread1 = TestThread.start(group1, "foo");
|
TestThread thread1 = TestThread.start(group1, "foo");
|
||||||
@ -701,7 +701,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDestroy() {
|
void testDestroy() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertFalse(group.isDestroyed());
|
assertFalse(group.isDestroyed());
|
||||||
group.destroy(); // does nothing
|
group.destroy(); // does nothing
|
||||||
@ -709,7 +709,7 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDaemon() {
|
void testDaemon() {
|
||||||
boolean d = Thread.currentThread().getThreadGroup().isDaemon();
|
boolean d = Thread.currentThread().getThreadGroup().isDaemon();
|
||||||
|
|
||||||
ThreadGroup group1 = new ThreadGroup("group1");
|
ThreadGroup group1 = new ThreadGroup("group1");
|
||||||
@ -727,68 +727,68 @@ public class BasicTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testList() {
|
void testList() {
|
||||||
ThreadGroup group = new ThreadGroup("foo");
|
ThreadGroup group = new ThreadGroup("foo");
|
||||||
group.list();
|
group.list();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuspend() {
|
void testSuspend() {
|
||||||
ThreadGroup group = new ThreadGroup("foo");
|
ThreadGroup group = new ThreadGroup("foo");
|
||||||
assertThrows(UnsupportedOperationException.class, () -> group.suspend());
|
assertThrows(UnsupportedOperationException.class, () -> group.suspend());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResume() {
|
void testResume() {
|
||||||
ThreadGroup group = new ThreadGroup("foo");
|
ThreadGroup group = new ThreadGroup("foo");
|
||||||
assertThrows(UnsupportedOperationException.class, () -> group.resume());
|
assertThrows(UnsupportedOperationException.class, () -> group.resume());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStop() {
|
void testStop() {
|
||||||
ThreadGroup group = new ThreadGroup("foo");
|
ThreadGroup group = new ThreadGroup("foo");
|
||||||
assertThrows(UnsupportedOperationException.class, () -> group.stop());
|
assertThrows(UnsupportedOperationException.class, () -> group.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNull1() {
|
void testNull1() {
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> new ThreadGroup(null, "group"));
|
() -> new ThreadGroup(null, "group"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNull2() {
|
void testNull2() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> group.enumerate((Thread[]) null));
|
() -> group.enumerate((Thread[]) null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNull3() {
|
void testNull3() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> group.enumerate((Thread[]) null, false));
|
() -> group.enumerate((Thread[]) null, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNull4() {
|
void testNull4() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> group.enumerate((ThreadGroup[]) null));
|
() -> group.enumerate((ThreadGroup[]) null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNull5() {
|
void testNull5() {
|
||||||
ThreadGroup group = new ThreadGroup("group");
|
ThreadGroup group = new ThreadGroup("group");
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> group.enumerate((ThreadGroup[]) null, false));
|
() -> 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());
|
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) {
|
TestThread(ThreadGroup group, String name) {
|
||||||
super(group, name);
|
super(group, name);
|
||||||
}
|
}
|
||||||
@ -802,6 +802,7 @@ public class BasicTests {
|
|||||||
private volatile boolean done;
|
private volatile boolean done;
|
||||||
private volatile boolean interrupted;
|
private volatile boolean interrupted;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (Thread.currentThread() != this)
|
if (Thread.currentThread() != this)
|
||||||
throw new IllegalCallerException();
|
throw new IllegalCallerException();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Test java.lang.management.ThreadMXBean with virtual threads
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules java.base/java.lang:+open java.management
|
* @modules java.base/java.lang:+open java.management
|
||||||
* @run testng/othervm VirtualThreads
|
* @run junit/othervm VirtualThreads
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,7 +35,7 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules java.base/java.lang:+open java.management
|
* @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;
|
import java.lang.management.ManagementFactory;
|
||||||
@ -51,9 +51,9 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.testng.SkipException;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assumptions.*;
|
||||||
|
|
||||||
public class VirtualThreads {
|
public class VirtualThreads {
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public class VirtualThreads {
|
|||||||
* virtual threads.
|
* virtual threads.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAllThreadIds() throws Exception {
|
void testGetAllThreadIds() throws Exception {
|
||||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||||
try {
|
try {
|
||||||
long[] tids = ManagementFactory.getThreadMXBean().getAllThreadIds();
|
long[] tids = ManagementFactory.getThreadMXBean().getAllThreadIds();
|
||||||
@ -83,7 +83,7 @@ public class VirtualThreads {
|
|||||||
* Test that ThreadMXBean.getThreadInfo(long) returns null for a virtual thread.
|
* Test that ThreadMXBean.getThreadInfo(long) returns null for a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadInfo1() throws Exception {
|
void testGetThreadInfo1() throws Exception {
|
||||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||||
try {
|
try {
|
||||||
long tid = vthread.threadId();
|
long tid = vthread.threadId();
|
||||||
@ -99,7 +99,7 @@ public class VirtualThreads {
|
|||||||
* thread with its own thread id.
|
* thread with its own thread id.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadInfo2() throws Exception {
|
void testGetThreadInfo2() throws Exception {
|
||||||
runInVirtualThread(() -> {
|
runInVirtualThread(() -> {
|
||||||
long tid = Thread.currentThread().threadId();
|
long tid = Thread.currentThread().threadId();
|
||||||
ThreadInfo info = ManagementFactory.getThreadMXBean().getThreadInfo(tid);
|
ThreadInfo info = ManagementFactory.getThreadMXBean().getThreadInfo(tid);
|
||||||
@ -112,9 +112,8 @@ public class VirtualThreads {
|
|||||||
* The stack frames of the virtual thread should not be returned.
|
* The stack frames of the virtual thread should not be returned.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadInfo3() throws Exception {
|
void testGetThreadInfo3() throws Exception {
|
||||||
if (!supportsCustomScheduler())
|
assumeTrue(supportsCustomScheduler(), "No support for custom schedulers");
|
||||||
throw new SkipException("No support for custom schedulers");
|
|
||||||
try (ExecutorService pool = Executors.newFixedThreadPool(1)) {
|
try (ExecutorService pool = Executors.newFixedThreadPool(1)) {
|
||||||
var carrierRef = new AtomicReference<Thread>();
|
var carrierRef = new AtomicReference<Thread>();
|
||||||
Executor scheduler = (task) -> {
|
Executor scheduler = (task) -> {
|
||||||
@ -157,7 +156,7 @@ public class VirtualThreads {
|
|||||||
* elements that correspond to a virtual thread.
|
* elements that correspond to a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadInfo4() throws Exception {
|
void testGetThreadInfo4() throws Exception {
|
||||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||||
try {
|
try {
|
||||||
long tid0 = Thread.currentThread().threadId();
|
long tid0 = Thread.currentThread().threadId();
|
||||||
@ -175,7 +174,7 @@ public class VirtualThreads {
|
|||||||
* Test that ThreadMXBean.getThreadCpuTime(long) returns -1 for a virtual thread.
|
* Test that ThreadMXBean.getThreadCpuTime(long) returns -1 for a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadCpuTime1() {
|
void testGetThreadCpuTime1() {
|
||||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||||
try {
|
try {
|
||||||
long tid = vthread.threadId();
|
long tid = vthread.threadId();
|
||||||
@ -191,7 +190,7 @@ public class VirtualThreads {
|
|||||||
* virtual thread with its own thread id.
|
* virtual thread with its own thread id.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadCpuTime2() throws Exception {
|
void testGetThreadCpuTime2() throws Exception {
|
||||||
runInVirtualThread(() -> {
|
runInVirtualThread(() -> {
|
||||||
long tid = Thread.currentThread().threadId();
|
long tid = Thread.currentThread().threadId();
|
||||||
long cpuTime = ManagementFactory.getThreadMXBean().getThreadCpuTime(tid);
|
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 that ThreadMXBean.getThreadUserTime(long) returns -1 for a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadUserTime1() {
|
void testGetThreadUserTime1() {
|
||||||
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
Thread vthread = Thread.startVirtualThread(LockSupport::park);
|
||||||
try {
|
try {
|
||||||
long tid = vthread.threadId();
|
long tid = vthread.threadId();
|
||||||
@ -219,7 +218,7 @@ public class VirtualThreads {
|
|||||||
* virtual thread with its own thread id.
|
* virtual thread with its own thread id.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetThreadUserTime2() throws Exception {
|
void testGetThreadUserTime2() throws Exception {
|
||||||
runInVirtualThread(() -> {
|
runInVirtualThread(() -> {
|
||||||
long tid = Thread.currentThread().threadId();
|
long tid = Thread.currentThread().threadId();
|
||||||
long userTime = ManagementFactory.getThreadMXBean().getThreadUserTime(tid);
|
long userTime = ManagementFactory.getThreadMXBean().getThreadUserTime(tid);
|
||||||
@ -231,10 +230,11 @@ public class VirtualThreads {
|
|||||||
* Test that ThreadMXBean::getCurrentThreadCpuTime throws UOE when invoked
|
* Test that ThreadMXBean::getCurrentThreadCpuTime throws UOE when invoked
|
||||||
* on a virtual thread.
|
* on a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test(expectedExceptions = { UnsupportedOperationException.class })
|
@Test
|
||||||
public void testGetCurrentThreadCpuTime() throws Exception {
|
void testGetCurrentThreadCpuTime() throws Exception {
|
||||||
runInVirtualThread(() -> {
|
runInVirtualThread(() -> {
|
||||||
ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
|
assertThrows(UnsupportedOperationException.class,
|
||||||
|
() -> ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,10 +242,11 @@ public class VirtualThreads {
|
|||||||
* Test that ThreadMXBean::getCurrentThreadUserTime throws UOE when
|
* Test that ThreadMXBean::getCurrentThreadUserTime throws UOE when
|
||||||
* invoked on a virtual thread.
|
* invoked on a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test(expectedExceptions = { UnsupportedOperationException.class })
|
@Test
|
||||||
public void testGetCurrentThreadUserTime() throws Exception {
|
void testGetCurrentThreadUserTime() throws Exception {
|
||||||
runInVirtualThread(() -> {
|
runInVirtualThread(() -> {
|
||||||
ManagementFactory.getThreadMXBean().getCurrentThreadUserTime();
|
assertThrows(UnsupportedOperationException.class,
|
||||||
|
() -> ManagementFactory.getThreadMXBean().getCurrentThreadUserTime());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +255,7 @@ public class VirtualThreads {
|
|||||||
* invoked on a virtual thread.
|
* invoked on a virtual thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetCurrentThreadAllocatedBytes() throws Exception {
|
void testGetCurrentThreadAllocatedBytes() throws Exception {
|
||||||
runInVirtualThread(() -> {
|
runInVirtualThread(() -> {
|
||||||
long allocated = ManagementFactory.getPlatformMXBean(com.sun.management.ThreadMXBean.class)
|
long allocated = ManagementFactory.getPlatformMXBean(com.sun.management.ThreadMXBean.class)
|
||||||
.getCurrentThreadAllocatedBytes();
|
.getCurrentThreadAllocatedBytes();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Test virtual threads doing blocking I/O on java.net sockets
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm BlockingSocketOps
|
* @run junit BlockingSocketOps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@
|
|||||||
* the I/O poller configured to use direct registration
|
* the I/O poller configured to use direct registration
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm -Djdk.useDirectRegister BlockingSocketOps
|
* @run junit/othervm -Djdk.useDirectRegister BlockingSocketOps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
|
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
@ -62,16 +62,16 @@ import java.net.SocketException;
|
|||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class BlockingSocketOps {
|
class BlockingSocketOps {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Socket read/write, no blocking.
|
* Socket read/write, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadWrite1() throws Exception {
|
void testSocketReadWrite1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s1 = connection.socket1();
|
Socket s1 = connection.socket1();
|
||||||
@ -94,7 +94,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in read.
|
* Virtual thread blocks in read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketRead1() throws Exception {
|
void testSocketRead1() throws Exception {
|
||||||
testSocketRead(0);
|
testSocketRead(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in timed read.
|
* Virtual thread blocks in timed read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketRead2() throws Exception {
|
void testSocketRead2() throws Exception {
|
||||||
testSocketRead(60_000);
|
testSocketRead(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in write.
|
* Virtual thread blocks in write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketWrite1() throws Exception {
|
void testSocketWrite1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s1 = connection.socket1();
|
Socket s1 = connection.socket1();
|
||||||
@ -161,7 +161,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in read, peer closes connection gracefully.
|
* Virtual thread blocks in read, peer closes connection gracefully.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadPeerClose1() throws Exception {
|
void testSocketReadPeerClose1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s1 = connection.socket1();
|
Socket s1 = connection.socket1();
|
||||||
@ -181,7 +181,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in read, peer closes connection abruptly.
|
* Virtual thread blocks in read, peer closes connection abruptly.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadPeerClose2() throws Exception {
|
void testSocketReadPeerClose2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s1 = connection.socket1();
|
Socket s1 = connection.socket1();
|
||||||
@ -206,7 +206,7 @@ public class BlockingSocketOps {
|
|||||||
* Socket close while virtual thread blocked in read.
|
* Socket close while virtual thread blocked in read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadAsyncClose1() throws Exception {
|
void testSocketReadAsyncClose1() throws Exception {
|
||||||
testSocketReadAsyncClose(0);
|
testSocketReadAsyncClose(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ public class BlockingSocketOps {
|
|||||||
* Socket close while virtual thread blocked in timed read.
|
* Socket close while virtual thread blocked in timed read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadAsyncClose2() throws Exception {
|
void testSocketReadAsyncClose2() throws Exception {
|
||||||
testSocketReadAsyncClose(0);
|
testSocketReadAsyncClose(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in Socket read.
|
* Virtual thread interrupted while blocked in Socket read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadInterrupt1() throws Exception {
|
void testSocketReadInterrupt1() throws Exception {
|
||||||
testSocketReadInterrupt(0);
|
testSocketReadInterrupt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in Socket read with timeout
|
* Virtual thread interrupted while blocked in Socket read with timeout
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadInterrupt2() throws Exception {
|
void testSocketReadInterrupt2() throws Exception {
|
||||||
testSocketReadInterrupt(60_000);
|
testSocketReadInterrupt(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ public class BlockingSocketOps {
|
|||||||
* Socket close while virtual thread blocked in write.
|
* Socket close while virtual thread blocked in write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketWriteAsyncClose() throws Exception {
|
void testSocketWriteAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s = connection.socket1();
|
Socket s = connection.socket1();
|
||||||
@ -307,7 +307,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in Socket write.
|
* Virtual thread interrupted while blocked in Socket write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketWriteInterrupt() throws Exception {
|
void testSocketWriteInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s = connection.socket1();
|
Socket s = connection.socket1();
|
||||||
@ -335,7 +335,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread reading urgent data when SO_OOBINLINE is enabled.
|
* Virtual thread reading urgent data when SO_OOBINLINE is enabled.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketReadUrgentData() throws Exception {
|
void testSocketReadUrgentData() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
Socket s1 = connection.socket1();
|
Socket s1 = connection.socket1();
|
||||||
@ -367,7 +367,7 @@ public class BlockingSocketOps {
|
|||||||
* ServerSocket accept, no blocking.
|
* ServerSocket accept, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAccept1() throws Exception {
|
void testServerSocketAccept1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var listener = new ServerSocket()) {
|
try (var listener = new ServerSocket()) {
|
||||||
InetAddress loopback = InetAddress.getLoopbackAddress();
|
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||||
@ -388,7 +388,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in accept.
|
* Virtual thread blocks in accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAccept2() throws Exception {
|
void testServerSocketAccept2() throws Exception {
|
||||||
testServerSocketAccept(0);
|
testServerSocketAccept(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +396,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in timed accept.
|
* Virtual thread blocks in timed accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAccept3() throws Exception {
|
void testServerSocketAccept3() throws Exception {
|
||||||
testServerSocketAccept(60_000);
|
testServerSocketAccept(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ public class BlockingSocketOps {
|
|||||||
* ServerSocket close while virtual thread blocked in accept.
|
* ServerSocket close while virtual thread blocked in accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAcceptAsyncClose1() throws Exception {
|
void testServerSocketAcceptAsyncClose1() throws Exception {
|
||||||
testServerSocketAcceptAsyncClose(0);
|
testServerSocketAcceptAsyncClose(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ public class BlockingSocketOps {
|
|||||||
* ServerSocket close while virtual thread blocked in timed accept.
|
* ServerSocket close while virtual thread blocked in timed accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAcceptAsyncClose2() throws Exception {
|
void testServerSocketAcceptAsyncClose2() throws Exception {
|
||||||
testServerSocketAcceptAsyncClose(60_000);
|
testServerSocketAcceptAsyncClose(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,7 +463,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in ServerSocket accept.
|
* Virtual thread interrupted while blocked in ServerSocket accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAcceptInterrupt1() throws Exception {
|
void testServerSocketAcceptInterrupt1() throws Exception {
|
||||||
testServerSocketAcceptInterrupt(0);
|
testServerSocketAcceptInterrupt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +471,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in ServerSocket accept with timeout.
|
* Virtual thread interrupted while blocked in ServerSocket accept with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketAcceptInterrupt2() throws Exception {
|
void testServerSocketAcceptInterrupt2() throws Exception {
|
||||||
testServerSocketAcceptInterrupt(60_000);
|
testServerSocketAcceptInterrupt(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +504,7 @@ public class BlockingSocketOps {
|
|||||||
* DatagramSocket receive/send, no blocking.
|
* DatagramSocket receive/send, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketSendReceive1() throws Exception {
|
void testDatagramSocketSendReceive1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (DatagramSocket s1 = new DatagramSocket(null);
|
try (DatagramSocket s1 = new DatagramSocket(null);
|
||||||
DatagramSocket s2 = new DatagramSocket(null)) {
|
DatagramSocket s2 = new DatagramSocket(null)) {
|
||||||
@ -523,7 +523,7 @@ public class BlockingSocketOps {
|
|||||||
byte[] ba = new byte[100];
|
byte[] ba = new byte[100];
|
||||||
DatagramPacket p2 = new DatagramPacket(ba, ba.length);
|
DatagramPacket p2 = new DatagramPacket(ba, ba.length);
|
||||||
s2.receive(p2);
|
s2.receive(p2);
|
||||||
assertEquals(p2.getSocketAddress(), s1.getLocalSocketAddress());
|
assertEquals(s1.getLocalSocketAddress(), p2.getSocketAddress());
|
||||||
assertTrue(ba[0] == 'X');
|
assertTrue(ba[0] == 'X');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -533,7 +533,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in DatagramSocket receive.
|
* Virtual thread blocks in DatagramSocket receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketSendReceive2() throws Exception {
|
void testDatagramSocketSendReceive2() throws Exception {
|
||||||
testDatagramSocketSendReceive(0);
|
testDatagramSocketSendReceive(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +541,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in DatagramSocket receive with timeout.
|
* Virtual thread blocks in DatagramSocket receive with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketSendReceive3() throws Exception {
|
void testDatagramSocketSendReceive3() throws Exception {
|
||||||
testDatagramSocketSendReceive(60_000);
|
testDatagramSocketSendReceive(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,7 +567,7 @@ public class BlockingSocketOps {
|
|||||||
byte[] ba = new byte[100];
|
byte[] ba = new byte[100];
|
||||||
DatagramPacket p2 = new DatagramPacket(ba, ba.length);
|
DatagramPacket p2 = new DatagramPacket(ba, ba.length);
|
||||||
s2.receive(p2);
|
s2.receive(p2);
|
||||||
assertEquals(p2.getSocketAddress(), s1.getLocalSocketAddress());
|
assertEquals(s1.getLocalSocketAddress(), p2.getSocketAddress());
|
||||||
assertTrue(ba[0] == 'X');
|
assertTrue(ba[0] == 'X');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -577,7 +577,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread blocks in DatagramSocket receive that times out.
|
* Virtual thread blocks in DatagramSocket receive that times out.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketReceiveTimeout() throws Exception {
|
void testDatagramSocketReceiveTimeout() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (DatagramSocket s = new DatagramSocket(null)) {
|
try (DatagramSocket s = new DatagramSocket(null)) {
|
||||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||||
@ -597,7 +597,7 @@ public class BlockingSocketOps {
|
|||||||
* DatagramSocket close while virtual thread blocked in receive.
|
* DatagramSocket close while virtual thread blocked in receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketReceiveAsyncClose1() throws Exception {
|
void testDatagramSocketReceiveAsyncClose1() throws Exception {
|
||||||
testDatagramSocketReceiveAsyncClose(0);
|
testDatagramSocketReceiveAsyncClose(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +605,7 @@ public class BlockingSocketOps {
|
|||||||
* DatagramSocket close while virtual thread blocked with timeout.
|
* DatagramSocket close while virtual thread blocked with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketReceiveAsyncClose2() throws Exception {
|
void testDatagramSocketReceiveAsyncClose2() throws Exception {
|
||||||
testDatagramSocketReceiveAsyncClose(60_000);
|
testDatagramSocketReceiveAsyncClose(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,7 +636,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in DatagramSocket receive.
|
* Virtual thread interrupted while blocked in DatagramSocket receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketReceiveInterrupt1() throws Exception {
|
void testDatagramSocketReceiveInterrupt1() throws Exception {
|
||||||
testDatagramSocketReceiveInterrupt(0);
|
testDatagramSocketReceiveInterrupt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,7 +644,7 @@ public class BlockingSocketOps {
|
|||||||
* Virtual thread interrupted while blocked in DatagramSocket receive with timeout.
|
* Virtual thread interrupted while blocked in DatagramSocket receive with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketReceiveInterrupt2() throws Exception {
|
void testDatagramSocketReceiveInterrupt2() throws Exception {
|
||||||
testDatagramSocketReceiveInterrupt(60_000);
|
testDatagramSocketReceiveInterrupt(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Test virtual threads doing blocking I/O on NIO channels
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm BlockingChannelOps
|
* @run junit BlockingChannelOps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@
|
|||||||
* the I/O poller configured to use direct registration
|
* the I/O poller configured to use direct registration
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm -Djdk.useDirectRegister BlockingChannelOps
|
* @run junit/othervm -Djdk.useDirectRegister BlockingChannelOps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@
|
|||||||
* @requires vm.continuations
|
* @requires vm.continuations
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingChannelOps
|
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingChannelOps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
@ -67,16 +67,16 @@ import java.nio.channels.SocketChannel;
|
|||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class BlockingChannelOps {
|
class BlockingChannelOps {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SocketChannel read/write, no blocking.
|
* SocketChannel read/write, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelReadWrite1() throws Exception {
|
void testSocketChannelReadWrite1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
SocketChannel sc1 = connection.channel1();
|
SocketChannel sc1 = connection.channel1();
|
||||||
@ -100,7 +100,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in SocketChannel read.
|
* Virtual thread blocks in SocketChannel read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelRead() throws Exception {
|
void testSocketChannelRead() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
SocketChannel sc1 = connection.channel1();
|
SocketChannel sc1 = connection.channel1();
|
||||||
@ -123,7 +123,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in SocketChannel write.
|
* Virtual thread blocks in SocketChannel write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelWrite() throws Exception {
|
void testSocketChannelWrite() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
SocketChannel sc1 = connection.channel1();
|
SocketChannel sc1 = connection.channel1();
|
||||||
@ -151,7 +151,7 @@ public class BlockingChannelOps {
|
|||||||
* SocketChannel close while virtual thread blocked in read.
|
* SocketChannel close while virtual thread blocked in read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelReadAsyncClose() throws Exception {
|
void testSocketChannelReadAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
SocketChannel sc = connection.channel1();
|
SocketChannel sc = connection.channel1();
|
||||||
@ -168,7 +168,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in SocketChannel read.
|
* Virtual thread interrupted while blocked in SocketChannel read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelReadInterrupt() throws Exception {
|
void testSocketChannelReadInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var connection = new Connection()) {
|
try (var connection = new Connection()) {
|
||||||
SocketChannel sc = connection.channel1();
|
SocketChannel sc = connection.channel1();
|
||||||
@ -191,7 +191,7 @@ public class BlockingChannelOps {
|
|||||||
* SocketChannel close while virtual thread blocked in write.
|
* SocketChannel close while virtual thread blocked in write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelWriteAsyncClose() throws Exception {
|
void testSocketChannelWriteAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
boolean retry = true;
|
boolean retry = true;
|
||||||
while (retry) {
|
while (retry) {
|
||||||
@ -222,7 +222,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in SocketChannel write.
|
* Virtual thread interrupted while blocked in SocketChannel write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelWriteInterrupt() throws Exception {
|
void testSocketChannelWriteInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
boolean retry = true;
|
boolean retry = true;
|
||||||
while (retry) {
|
while (retry) {
|
||||||
@ -256,7 +256,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in SocketChannel adaptor read.
|
* Virtual thread blocks in SocketChannel adaptor read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketAdaptorRead1() throws Exception {
|
void testSocketAdaptorRead1() throws Exception {
|
||||||
testSocketAdaptorRead(0);
|
testSocketAdaptorRead(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in SocketChannel adaptor read with timeout.
|
* Virtual thread blocks in SocketChannel adaptor read with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketAdaptorRead2() throws Exception {
|
void testSocketAdaptorRead2() throws Exception {
|
||||||
testSocketAdaptorRead(60_000);
|
testSocketAdaptorRead(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ public class BlockingChannelOps {
|
|||||||
* ServerSocketChannel accept, no blocking.
|
* ServerSocketChannel accept, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketChannelAccept1() throws Exception {
|
void testServerSocketChannelAccept1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var ssc = ServerSocketChannel.open()) {
|
try (var ssc = ServerSocketChannel.open()) {
|
||||||
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||||
@ -310,7 +310,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in ServerSocketChannel accept.
|
* Virtual thread blocks in ServerSocketChannel accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketChannelAccept2() throws Exception {
|
void testServerSocketChannelAccept2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var ssc = ServerSocketChannel.open()) {
|
try (var ssc = ServerSocketChannel.open()) {
|
||||||
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||||
@ -331,7 +331,7 @@ public class BlockingChannelOps {
|
|||||||
* SeverSocketChannel close while virtual thread blocked in accept.
|
* SeverSocketChannel close while virtual thread blocked in accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketChannelAcceptAsyncClose() throws Exception {
|
void testServerSocketChannelAcceptAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var ssc = ServerSocketChannel.open()) {
|
try (var ssc = ServerSocketChannel.open()) {
|
||||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||||
@ -350,7 +350,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in ServerSocketChannel accept.
|
* Virtual thread interrupted while blocked in ServerSocketChannel accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testServerSocketChannelAcceptInterrupt() throws Exception {
|
void testServerSocketChannelAcceptInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (var ssc = ServerSocketChannel.open()) {
|
try (var ssc = ServerSocketChannel.open()) {
|
||||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||||
@ -375,7 +375,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in ServerSocketChannel adaptor accept.
|
* Virtual thread blocks in ServerSocketChannel adaptor accept.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelAdaptorAccept1() throws Exception {
|
void testSocketChannelAdaptorAccept1() throws Exception {
|
||||||
testSocketChannelAdaptorAccept(0);
|
testSocketChannelAdaptorAccept(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +383,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in ServerSocketChannel adaptor accept with timeout.
|
* Virtual thread blocks in ServerSocketChannel adaptor accept with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocketChannelAdaptorAccept2() throws Exception {
|
void testSocketChannelAdaptorAccept2() throws Exception {
|
||||||
testSocketChannelAdaptorAccept(60_000);
|
testSocketChannelAdaptorAccept(60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ public class BlockingChannelOps {
|
|||||||
* DatagramChannel receive/send, no blocking.
|
* DatagramChannel receive/send, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramChannelSendReceive1() throws Exception {
|
void testDatagramChannelSendReceive1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (DatagramChannel dc1 = DatagramChannel.open();
|
try (DatagramChannel dc1 = DatagramChannel.open();
|
||||||
DatagramChannel dc2 = DatagramChannel.open()) {
|
DatagramChannel dc2 = DatagramChannel.open()) {
|
||||||
@ -435,7 +435,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in DatagramChannel receive.
|
* Virtual thread blocks in DatagramChannel receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramChannelSendReceive2() throws Exception {
|
void testDatagramChannelSendReceive2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (DatagramChannel dc1 = DatagramChannel.open();
|
try (DatagramChannel dc1 = DatagramChannel.open();
|
||||||
DatagramChannel dc2 = DatagramChannel.open()) {
|
DatagramChannel dc2 = DatagramChannel.open()) {
|
||||||
@ -459,7 +459,7 @@ public class BlockingChannelOps {
|
|||||||
* DatagramChannel close while virtual thread blocked in receive.
|
* DatagramChannel close while virtual thread blocked in receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramChannelReceiveAsyncClose() throws Exception {
|
void testDatagramChannelReceiveAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (DatagramChannel dc = DatagramChannel.open()) {
|
try (DatagramChannel dc = DatagramChannel.open()) {
|
||||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||||
@ -477,7 +477,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in DatagramChannel receive.
|
* Virtual thread interrupted while blocked in DatagramChannel receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramChannelReceiveInterrupt() throws Exception {
|
void testDatagramChannelReceiveInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
try (DatagramChannel dc = DatagramChannel.open()) {
|
try (DatagramChannel dc = DatagramChannel.open()) {
|
||||||
InetAddress lh = InetAddress.getLoopbackAddress();
|
InetAddress lh = InetAddress.getLoopbackAddress();
|
||||||
@ -501,7 +501,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in DatagramSocket adaptor receive.
|
* Virtual thread blocks in DatagramSocket adaptor receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketAdaptorReceive1() throws Exception {
|
void testDatagramSocketAdaptorReceive1() throws Exception {
|
||||||
testDatagramSocketAdaptorReceive(0);
|
testDatagramSocketAdaptorReceive(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in DatagramSocket adaptor receive with timeout.
|
* Virtual thread blocks in DatagramSocket adaptor receive with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketAdaptorReceive2() throws Exception {
|
void testDatagramSocketAdaptorReceive2() throws Exception {
|
||||||
testDatagramSocketAdaptorReceive(60_1000);
|
testDatagramSocketAdaptorReceive(60_1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +540,7 @@ public class BlockingChannelOps {
|
|||||||
* DatagramChannel close while virtual thread blocked in adaptor receive.
|
* DatagramChannel close while virtual thread blocked in adaptor receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketAdaptorReceiveAsyncClose1() throws Exception {
|
void testDatagramSocketAdaptorReceiveAsyncClose1() throws Exception {
|
||||||
testDatagramSocketAdaptorReceiveAsyncClose(0);
|
testDatagramSocketAdaptorReceiveAsyncClose(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +549,7 @@ public class BlockingChannelOps {
|
|||||||
* with timeout.
|
* with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketAdaptorReceiveAsyncClose2() throws Exception {
|
void testDatagramSocketAdaptorReceiveAsyncClose2() throws Exception {
|
||||||
testDatagramSocketAdaptorReceiveAsyncClose(60_1000);
|
testDatagramSocketAdaptorReceiveAsyncClose(60_1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +576,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in DatagramSocket adaptor receive.
|
* Virtual thread interrupted while blocked in DatagramSocket adaptor receive.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketAdaptorReceiveInterrupt1() throws Exception {
|
void testDatagramSocketAdaptorReceiveInterrupt1() throws Exception {
|
||||||
testDatagramSocketAdaptorReceiveInterrupt(0);
|
testDatagramSocketAdaptorReceiveInterrupt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +585,7 @@ public class BlockingChannelOps {
|
|||||||
* with timeout.
|
* with timeout.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatagramSocketAdaptorReceiveInterrupt2() throws Exception {
|
void testDatagramSocketAdaptorReceiveInterrupt2() throws Exception {
|
||||||
testDatagramSocketAdaptorReceiveInterrupt(60_1000);
|
testDatagramSocketAdaptorReceiveInterrupt(60_1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +618,7 @@ public class BlockingChannelOps {
|
|||||||
* Pipe read/write, no blocking.
|
* Pipe read/write, no blocking.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeReadWrite1() throws Exception {
|
void testPipeReadWrite1() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Pipe p = Pipe.open();
|
Pipe p = Pipe.open();
|
||||||
try (Pipe.SinkChannel sink = p.sink();
|
try (Pipe.SinkChannel sink = p.sink();
|
||||||
@ -642,7 +642,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in Pipe.SourceChannel read.
|
* Virtual thread blocks in Pipe.SourceChannel read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeReadWrite2() throws Exception {
|
void testPipeReadWrite2() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Pipe p = Pipe.open();
|
Pipe p = Pipe.open();
|
||||||
try (Pipe.SinkChannel sink = p.sink();
|
try (Pipe.SinkChannel sink = p.sink();
|
||||||
@ -665,7 +665,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread blocks in Pipe.SinkChannel write.
|
* Virtual thread blocks in Pipe.SinkChannel write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeReadWrite3() throws Exception {
|
void testPipeReadWrite3() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Pipe p = Pipe.open();
|
Pipe p = Pipe.open();
|
||||||
try (Pipe.SinkChannel sink = p.sink();
|
try (Pipe.SinkChannel sink = p.sink();
|
||||||
@ -693,7 +693,7 @@ public class BlockingChannelOps {
|
|||||||
* Pipe.SourceChannel close while virtual thread blocked in read.
|
* Pipe.SourceChannel close while virtual thread blocked in read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeReadAsyncClose() throws Exception {
|
void testPipeReadAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Pipe p = Pipe.open();
|
Pipe p = Pipe.open();
|
||||||
try (Pipe.SinkChannel sink = p.sink();
|
try (Pipe.SinkChannel sink = p.sink();
|
||||||
@ -711,7 +711,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in Pipe.SourceChannel read.
|
* Virtual thread interrupted while blocked in Pipe.SourceChannel read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeReadInterrupt() throws Exception {
|
void testPipeReadInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
Pipe p = Pipe.open();
|
Pipe p = Pipe.open();
|
||||||
try (Pipe.SinkChannel sink = p.sink();
|
try (Pipe.SinkChannel sink = p.sink();
|
||||||
@ -735,7 +735,7 @@ public class BlockingChannelOps {
|
|||||||
* Pipe.SinkChannel close while virtual thread blocked in write.
|
* Pipe.SinkChannel close while virtual thread blocked in write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeWriteAsyncClose() throws Exception {
|
void testPipeWriteAsyncClose() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
boolean retry = true;
|
boolean retry = true;
|
||||||
while (retry) {
|
while (retry) {
|
||||||
@ -767,7 +767,7 @@ public class BlockingChannelOps {
|
|||||||
* Virtual thread interrupted while blocked in Pipe.SinkChannel write.
|
* Virtual thread interrupted while blocked in Pipe.SinkChannel write.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPipeWriteInterrupt() throws Exception {
|
void testPipeWriteInterrupt() throws Exception {
|
||||||
VThreadRunner.run(() -> {
|
VThreadRunner.run(() -> {
|
||||||
boolean retry = true;
|
boolean retry = true;
|
||||||
while (retry) {
|
while (retry) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,13 +25,13 @@
|
|||||||
* @test id=platform
|
* @test id=platform
|
||||||
* @summary Basic tests for new thread-per-task executors
|
* @summary Basic tests for new thread-per-task executors
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng/othervm -DthreadFactory=platform ThreadPerTaskExecutorTest
|
* @run junit/othervm -DthreadFactory=platform ThreadPerTaskExecutorTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test id=virtual
|
* @test id=virtual
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng/othervm -DthreadFactory=virtual ThreadPerTaskExecutorTest
|
* @run junit/othervm -DthreadFactory=virtual ThreadPerTaskExecutorTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.time.Duration;
|
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.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import static java.util.concurrent.Future.State.*;
|
import static java.util.concurrent.Future.State.*;
|
||||||
|
|
||||||
import org.testng.annotations.AfterClass;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import static org.testng.Assert.*;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class ThreadPerTaskExecutorTest {
|
class ThreadPerTaskExecutorTest {
|
||||||
// long running interruptible task
|
// long running interruptible task
|
||||||
private static final Callable<Void> SLEEP_FOR_A_DAY = () -> {
|
private static final Callable<Void> SLEEP_FOR_A_DAY = () -> {
|
||||||
Thread.sleep(Duration.ofDays(1));
|
Thread.sleep(Duration.ofDays(1));
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
private ScheduledExecutorService scheduler;
|
private static ScheduledExecutorService scheduler;
|
||||||
private Object[][] threadFactories;
|
private static List<ThreadFactory> threadFactories;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeAll
|
||||||
public void setUp() throws Exception {
|
static void setup() throws Exception {
|
||||||
ThreadFactory factory = (task) -> {
|
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
Thread thread = new Thread(task);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
};
|
|
||||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(factory);
|
|
||||||
|
|
||||||
// thread factories
|
// thread factories
|
||||||
String value = System.getProperty("threadFactory");
|
String value = System.getProperty("threadFactory");
|
||||||
@ -80,27 +77,21 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
if (value == null || value.equals("virtual"))
|
if (value == null || value.equals("virtual"))
|
||||||
list.add(Thread.ofVirtual().factory());
|
list.add(Thread.ofVirtual().factory());
|
||||||
assertTrue(list.size() > 0, "No thread factories for tests");
|
assertTrue(list.size() > 0, "No thread factories for tests");
|
||||||
this.threadFactories = list.stream()
|
threadFactories = list;
|
||||||
.map(f -> new Object[] { f })
|
|
||||||
.toArray(Object[][]::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterAll
|
||||||
public void tearDown() {
|
static void shutdown() {
|
||||||
scheduler.shutdown();
|
scheduler.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataProvider(name = "factories")
|
private static Stream<ThreadFactory> factories() {
|
||||||
public Object[][] factories() {
|
return threadFactories.stream();
|
||||||
return threadFactories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataProvider(name = "executors")
|
private static Stream<ExecutorService> executors() {
|
||||||
public Object[][] executors() {
|
return threadFactories.stream()
|
||||||
return Arrays.stream(threadFactories)
|
.map(f -> Executors.newThreadPerTaskExecutor(f));
|
||||||
.map(f -> Executors.newThreadPerTaskExecutor((ThreadFactory) f[0]))
|
|
||||||
.map(e -> new Object[] { e })
|
|
||||||
.toArray(Object[][]::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,8 +105,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test that a thread is created for each task.
|
* Test that a thread is created for each task.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testThreadPerTask(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testThreadPerTask(ThreadFactory factory) throws Exception {
|
||||||
final int NUM_TASKS = 100;
|
final int NUM_TASKS = 100;
|
||||||
AtomicInteger threadCount = new AtomicInteger();
|
AtomicInteger threadCount = new AtomicInteger();
|
||||||
|
|
||||||
@ -135,7 +127,7 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(executor.isTerminated());
|
assertTrue(executor.isTerminated());
|
||||||
assertEquals(threadCount.get(), NUM_TASKS);
|
assertEquals(NUM_TASKS, threadCount.get());
|
||||||
for (int i=0; i<NUM_TASKS; i++) {
|
for (int i=0; i<NUM_TASKS; i++) {
|
||||||
Future<Integer> future = futures.get(i);
|
Future<Integer> future = futures.get(i);
|
||||||
assertEquals((int) future.get(), i);
|
assertEquals((int) future.get(), i);
|
||||||
@ -146,7 +138,7 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test that newThreadPerTaskExecutor uses the specified thread factory.
|
* Test that newThreadPerTaskExecutor uses the specified thread factory.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testThreadFactory() throws Exception {
|
void testThreadFactory() throws Exception {
|
||||||
var ref1 = new AtomicReference<Thread>();
|
var ref1 = new AtomicReference<Thread>();
|
||||||
var ref2 = new AtomicReference<Thread>();
|
var ref2 = new AtomicReference<Thread>();
|
||||||
ThreadFactory factory = task -> {
|
ThreadFactory factory = task -> {
|
||||||
@ -166,8 +158,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test shutdown.
|
* Test shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testShutdown(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testShutdown(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
assertFalse(executor.isShutdown());
|
assertFalse(executor.isShutdown());
|
||||||
assertFalse(executor.isTerminated());
|
assertFalse(executor.isTerminated());
|
||||||
@ -188,8 +181,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test shutdownNow.
|
* Test shutdownNow.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testShutdownNow(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testShutdownNow(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
assertFalse(executor.isShutdown());
|
assertFalse(executor.isShutdown());
|
||||||
assertFalse(executor.isTerminated());
|
assertFalse(executor.isTerminated());
|
||||||
@ -201,7 +195,7 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
assertTrue(executor.isShutdown());
|
assertTrue(executor.isShutdown());
|
||||||
assertTrue(tasks.isEmpty());
|
assertTrue(tasks.isEmpty());
|
||||||
|
|
||||||
Throwable e = expectThrows(ExecutionException.class, result::get);
|
Throwable e = assertThrows(ExecutionException.class, result::get);
|
||||||
assertTrue(e.getCause() instanceof InterruptedException);
|
assertTrue(e.getCause() instanceof InterruptedException);
|
||||||
|
|
||||||
assertTrue(executor.awaitTermination(3, TimeUnit.SECONDS));
|
assertTrue(executor.awaitTermination(3, TimeUnit.SECONDS));
|
||||||
@ -215,8 +209,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test close with no threads running.
|
* Test close with no threads running.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testClose1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testClose1(ExecutorService executor) throws Exception {
|
||||||
executor.close();
|
executor.close();
|
||||||
assertTrue(executor.isShutdown());
|
assertTrue(executor.isShutdown());
|
||||||
assertTrue(executor.isTerminated());
|
assertTrue(executor.isTerminated());
|
||||||
@ -226,8 +221,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test close with threads running.
|
* Test close with threads running.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testClose2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testClose2(ExecutorService executor) throws Exception {
|
||||||
Future<String> future;
|
Future<String> future;
|
||||||
try (executor) {
|
try (executor) {
|
||||||
future = executor.submit(() -> {
|
future = executor.submit(() -> {
|
||||||
@ -244,8 +240,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Invoke close with interrupt status set, should cancel task.
|
* Invoke close with interrupt status set, should cancel task.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testClose3(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testClose3(ExecutorService executor) throws Exception {
|
||||||
Future<?> future;
|
Future<?> future;
|
||||||
try (executor) {
|
try (executor) {
|
||||||
future = executor.submit(SLEEP_FOR_A_DAY);
|
future = executor.submit(SLEEP_FOR_A_DAY);
|
||||||
@ -257,14 +254,15 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
assertTrue(executor.isShutdown());
|
assertTrue(executor.isShutdown());
|
||||||
assertTrue(executor.isTerminated());
|
assertTrue(executor.isTerminated());
|
||||||
assertTrue(executor.awaitTermination(10, TimeUnit.MILLISECONDS));
|
assertTrue(executor.awaitTermination(10, TimeUnit.MILLISECONDS));
|
||||||
expectThrows(ExecutionException.class, future::get);
|
assertThrows(ExecutionException.class, future::get);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interrupt thread blocked in close.
|
* Interrupt thread blocked in close.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testClose4(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testClose4(ExecutorService executor) throws Exception {
|
||||||
Future<?> future;
|
Future<?> future;
|
||||||
try (executor) {
|
try (executor) {
|
||||||
future = executor.submit(SLEEP_FOR_A_DAY);
|
future = executor.submit(SLEEP_FOR_A_DAY);
|
||||||
@ -275,14 +273,15 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
assertTrue(executor.isShutdown());
|
assertTrue(executor.isShutdown());
|
||||||
assertTrue(executor.isTerminated());
|
assertTrue(executor.isTerminated());
|
||||||
assertTrue(executor.awaitTermination(10, TimeUnit.MILLISECONDS));
|
assertTrue(executor.awaitTermination(10, TimeUnit.MILLISECONDS));
|
||||||
expectThrows(ExecutionException.class, future::get);
|
assertThrows(ExecutionException.class, future::get);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close executor that is already closed.
|
* Close executor that is already closed.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testClose5(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testClose5(ExecutorService executor) throws Exception {
|
||||||
executor.close();
|
executor.close();
|
||||||
executor.close(); // already closed
|
executor.close(); // already closed
|
||||||
}
|
}
|
||||||
@ -290,8 +289,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitTermination when not shutdown.
|
* Test awaitTermination when not shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testAwaitTermination1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testAwaitTermination1(ExecutorService executor) throws Exception {
|
||||||
assertFalse(executor.awaitTermination(100, TimeUnit.MILLISECONDS));
|
assertFalse(executor.awaitTermination(100, TimeUnit.MILLISECONDS));
|
||||||
executor.close();
|
executor.close();
|
||||||
assertTrue(executor.awaitTermination(100, TimeUnit.MILLISECONDS));
|
assertTrue(executor.awaitTermination(100, TimeUnit.MILLISECONDS));
|
||||||
@ -300,8 +300,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitTermination with task running.
|
* Test awaitTermination with task running.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testAwaitTermination2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testAwaitTermination2(ExecutorService executor) throws Exception {
|
||||||
Phaser barrier = new Phaser(2);
|
Phaser barrier = new Phaser(2);
|
||||||
Future<?> result = executor.submit(barrier::arriveAndAwaitAdvance);
|
Future<?> result = executor.submit(barrier::arriveAndAwaitAdvance);
|
||||||
try {
|
try {
|
||||||
@ -317,8 +318,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test submit when the Executor is shutdown but not terminated.
|
* Test submit when the Executor is shutdown but not terminated.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testSubmitAfterShutdown(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testSubmitAfterShutdown(ExecutorService executor) throws Exception {
|
||||||
Phaser barrier = new Phaser(2);
|
Phaser barrier = new Phaser(2);
|
||||||
try (executor) {
|
try (executor) {
|
||||||
// submit task to prevent executor from terminating
|
// submit task to prevent executor from terminating
|
||||||
@ -326,7 +328,7 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
try {
|
try {
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
assertTrue(executor.isShutdown() && !executor.isTerminated());
|
assertTrue(executor.isShutdown() && !executor.isTerminated());
|
||||||
expectThrows(RejectedExecutionException.class,
|
assertThrows(RejectedExecutionException.class,
|
||||||
() -> executor.submit(() -> { }));
|
() -> executor.submit(() -> { }));
|
||||||
} finally {
|
} finally {
|
||||||
barrier.arriveAndAwaitAdvance();
|
barrier.arriveAndAwaitAdvance();
|
||||||
@ -337,24 +339,27 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test submit when the Executor is terminated.
|
* Test submit when the Executor is terminated.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testSubmitAfterTermination(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testSubmitAfterTermination(ExecutorService executor) throws Exception {
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
assertTrue(executor.isShutdown() && executor.isTerminated());
|
assertTrue(executor.isShutdown() && executor.isTerminated());
|
||||||
expectThrows(RejectedExecutionException.class, () -> executor.submit(() -> {}));
|
assertThrows(RejectedExecutionException.class, () -> executor.submit(() -> {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test submit with null.
|
* Test submit with null.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testSubmitNulls1(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testSubmitNulls1(ThreadFactory factory) {
|
||||||
var executor = Executors.newThreadPerTaskExecutor(factory);
|
var executor = Executors.newThreadPerTaskExecutor(factory);
|
||||||
assertThrows(NullPointerException.class, () -> executor.submit((Runnable) null));
|
assertThrows(NullPointerException.class, () -> executor.submit((Runnable) null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testSubmitNulls2(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testSubmitNulls2(ThreadFactory factory) {
|
||||||
var executor = Executors.newThreadPerTaskExecutor(factory);
|
var executor = Executors.newThreadPerTaskExecutor(factory);
|
||||||
assertThrows(NullPointerException.class, () -> executor.submit((Callable<String>) null));
|
assertThrows(NullPointerException.class, () -> executor.submit((Callable<String>) null));
|
||||||
}
|
}
|
||||||
@ -362,8 +367,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny where all tasks complete normally.
|
* Test invokeAny where all tasks complete normally.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAny1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAny1(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> "bar";
|
Callable<String> task2 = () -> "bar";
|
||||||
@ -376,8 +382,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test invokeAny where all tasks complete normally. The completion of the
|
* Test invokeAny where all tasks complete normally. The completion of the
|
||||||
* first task should cancel remaining tasks.
|
* first task should cancel remaining tasks.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAny2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAny2(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
AtomicBoolean task2Started = new AtomicBoolean();
|
AtomicBoolean task2Started = new AtomicBoolean();
|
||||||
AtomicReference<Throwable> task2Exception = new AtomicReference<>();
|
AtomicReference<Throwable> task2Exception = new AtomicReference<>();
|
||||||
@ -408,8 +415,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny where all tasks complete with exception.
|
* Test invokeAny where all tasks complete with exception.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAny3(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAny3(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
class FooException extends Exception { }
|
class FooException extends Exception { }
|
||||||
Callable<String> task1 = () -> { throw new FooException(); };
|
Callable<String> task1 = () -> { throw new FooException(); };
|
||||||
@ -428,8 +436,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test invokeAny where all tasks complete with exception. The completion
|
* Test invokeAny where all tasks complete with exception. The completion
|
||||||
* of the last task is delayed.
|
* of the last task is delayed.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAny4(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAny4(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
class FooException extends Exception { }
|
class FooException extends Exception { }
|
||||||
Callable<String> task1 = () -> { throw new FooException(); };
|
Callable<String> task1 = () -> { throw new FooException(); };
|
||||||
@ -450,8 +459,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny where some, not all, tasks complete normally.
|
* Test invokeAny where some, not all, tasks complete normally.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAny5(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAny5(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
class FooException extends Exception { }
|
class FooException extends Exception { }
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
@ -465,8 +475,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test invokeAny where some, not all, tasks complete normally. The
|
* Test invokeAny where some, not all, tasks complete normally. The
|
||||||
* completion of the first task to complete normally is delayed.
|
* completion of the first task to complete normally is delayed.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAny6(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAny6(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
class FooException extends Exception { }
|
class FooException extends Exception { }
|
||||||
Callable<String> task1 = () -> {
|
Callable<String> task1 = () -> {
|
||||||
@ -482,8 +493,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test timed-invokeAny where all tasks complete normally before the timeout.
|
* Test timed-invokeAny where all tasks complete normally before the timeout.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyWithTimeout1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAnyWithTimeout1(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> "bar";
|
Callable<String> task2 = () -> "bar";
|
||||||
@ -496,8 +508,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test timed-invokeAny where one task completes normally before the timeout.
|
* Test timed-invokeAny where one task completes normally before the timeout.
|
||||||
* The remaining tests should be cancelled.
|
* The remaining tests should be cancelled.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyWithTimeout2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAnyWithTimeout2(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
AtomicBoolean task2Started = new AtomicBoolean();
|
AtomicBoolean task2Started = new AtomicBoolean();
|
||||||
AtomicReference<Throwable> task2Exception = new AtomicReference<>();
|
AtomicReference<Throwable> task2Exception = new AtomicReference<>();
|
||||||
@ -528,8 +541,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test timed-invokeAny where timeout expires before any task completes.
|
* Test timed-invokeAny where timeout expires before any task completes.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyWithTimeout3(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAnyWithTimeout3(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> {
|
Callable<String> task1 = () -> {
|
||||||
Thread.sleep(Duration.ofMinutes(1));
|
Thread.sleep(Duration.ofMinutes(1));
|
||||||
@ -548,8 +562,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test invokeAny where timeout expires after some tasks have completed
|
* Test invokeAny where timeout expires after some tasks have completed
|
||||||
* with exception.
|
* with exception.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyWithTimeout4(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAnyWithTimeout4(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
class FooException extends Exception { }
|
class FooException extends Exception { }
|
||||||
Callable<String> task1 = () -> { throw new FooException(); };
|
Callable<String> task1 = () -> { throw new FooException(); };
|
||||||
@ -565,8 +580,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny with interrupt status set.
|
* Test invokeAny with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyWithInterruptSet(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAnyWithInterruptSet(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> "bar";
|
Callable<String> task2 = () -> "bar";
|
||||||
@ -585,8 +601,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test interrupting a thread blocked in invokeAny.
|
* Test interrupting a thread blocked in invokeAny.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInterruptInvokeAny(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInterruptInvokeAny(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> {
|
Callable<String> task1 = () -> {
|
||||||
Thread.sleep(Duration.ofMinutes(1));
|
Thread.sleep(Duration.ofMinutes(1));
|
||||||
@ -611,8 +628,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny after ExecutorService has been shutdown.
|
* Test invokeAny after ExecutorService has been shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyAfterShutdown(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAnyAfterShutdown(ExecutorService executor) throws Exception {
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> "bar";
|
Callable<String> task2 = () -> "bar";
|
||||||
@ -623,8 +641,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny with empty collection.
|
* Test invokeAny with empty collection.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyEmpty1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAnyEmpty1(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
assertThrows(IllegalArgumentException.class, () -> executor.invokeAny(Set.of()));
|
assertThrows(IllegalArgumentException.class, () -> executor.invokeAny(Set.of()));
|
||||||
}
|
}
|
||||||
@ -633,8 +652,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test timed-invokeAny with empty collection.
|
* Test timed-invokeAny with empty collection.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyEmpty2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAnyEmpty2(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> executor.invokeAny(Set.of(), 1, TimeUnit.MINUTES));
|
() -> executor.invokeAny(Set.of(), 1, TimeUnit.MINUTES));
|
||||||
@ -644,8 +664,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny with null.
|
* Test invokeAny with null.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyNull1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAnyNull1(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
assertThrows(NullPointerException.class, () -> executor.invokeAny(null));
|
assertThrows(NullPointerException.class, () -> executor.invokeAny(null));
|
||||||
}
|
}
|
||||||
@ -654,8 +675,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAny with null element
|
* Test invokeAny with null element
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAnyNull2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAnyNull2(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
List<Callable<String>> list = new ArrayList<>();
|
List<Callable<String>> list = new ArrayList<>();
|
||||||
list.add(() -> "foo");
|
list.add(() -> "foo");
|
||||||
@ -667,8 +689,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll where all tasks complete normally.
|
* Test invokeAll where all tasks complete normally.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAll1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAll1(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> {
|
Callable<String> task2 = () -> {
|
||||||
@ -692,8 +715,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll where all tasks complete with exception.
|
* Test invokeAll where all tasks complete with exception.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAll2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAll2(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
class FooException extends Exception { }
|
class FooException extends Exception { }
|
||||||
class BarException extends Exception { }
|
class BarException extends Exception { }
|
||||||
@ -711,9 +735,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
assertFalse(notDone);
|
assertFalse(notDone);
|
||||||
|
|
||||||
// check results
|
// 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);
|
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);
|
assertTrue(e2.getCause() instanceof BarException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -721,8 +745,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll where all tasks complete normally before the timeout expires.
|
* Test invokeAll where all tasks complete normally before the timeout expires.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAll3(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAll3(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> {
|
Callable<String> task2 = () -> {
|
||||||
@ -746,8 +771,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll where some tasks do not complete before the timeout expires.
|
* Test invokeAll where some tasks do not complete before the timeout expires.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAll4(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAll4(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
AtomicReference<Exception> exc = new AtomicReference<>();
|
AtomicReference<Exception> exc = new AtomicReference<>();
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
@ -784,8 +810,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll with interrupt status set.
|
* Test invokeAll with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllInterrupt1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllInterrupt1(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> {
|
Callable<String> task2 = () -> {
|
||||||
@ -808,8 +835,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test timed-invokeAll with interrupt status set.
|
* Test timed-invokeAll with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllInterrupt3(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllInterrupt3(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
Callable<String> task2 = () -> {
|
Callable<String> task2 = () -> {
|
||||||
@ -832,8 +860,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test interrupt with thread blocked in invokeAll.
|
* Test interrupt with thread blocked in invokeAll.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllInterrupt4(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllInterrupt4(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
DelayedResult<String> task2 = new DelayedResult("bar", Duration.ofMinutes(1));
|
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 interrupt with thread blocked in timed-invokeAll.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllInterrupt6(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllInterrupt6(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
DelayedResult<String> task2 = new DelayedResult("bar", Duration.ofMinutes(1));
|
DelayedResult<String> task2 = new DelayedResult("bar", Duration.ofMinutes(1));
|
||||||
@ -884,8 +914,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll after ExecutorService has been shutdown.
|
* Test invokeAll after ExecutorService has been shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllAfterShutdown1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllAfterShutdown1(ExecutorService executor) throws Exception {
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
|
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
@ -894,8 +925,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
() -> executor.invokeAll(Set.of(task1, task2)));
|
() -> executor.invokeAll(Set.of(task1, task2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllAfterShutdown2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllAfterShutdown2(ExecutorService executor) throws Exception {
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
|
|
||||||
Callable<String> task1 = () -> "foo";
|
Callable<String> task1 = () -> "foo";
|
||||||
@ -907,31 +939,35 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
/**
|
/**
|
||||||
* Test invokeAll with empty collection.
|
* Test invokeAll with empty collection.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllEmpty1(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllEmpty1(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
List<Future<Object>> list = executor.invokeAll(Set.of());
|
List<Future<Object>> list = executor.invokeAll(Set.of());
|
||||||
assertTrue(list.size() == 0);
|
assertTrue(list.size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "executors")
|
@ParameterizedTest
|
||||||
public void testInvokeAllEmpty2(ExecutorService executor) throws Exception {
|
@MethodSource("executors")
|
||||||
|
void testInvokeAllEmpty2(ExecutorService executor) throws Exception {
|
||||||
try (executor) {
|
try (executor) {
|
||||||
List<Future<Object>> list = executor.invokeAll(Set.of(), 1, TimeUnit.SECONDS);
|
List<Future<Object>> list = executor.invokeAll(Set.of(), 1, TimeUnit.SECONDS);
|
||||||
assertTrue(list.size() == 0);
|
assertTrue(list.size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAllNull1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAllNull1(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
assertThrows(NullPointerException.class, () -> executor.invokeAll(null));
|
assertThrows(NullPointerException.class, () -> executor.invokeAll(null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAllNull2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAllNull2(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
List<Callable<String>> tasks = new ArrayList<>();
|
List<Callable<String>> tasks = new ArrayList<>();
|
||||||
tasks.add(() -> "foo");
|
tasks.add(() -> "foo");
|
||||||
@ -940,16 +976,18 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAllNull3(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAllNull3(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> executor.invokeAll(null, 1, TimeUnit.SECONDS));
|
() -> executor.invokeAll(null, 1, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAllNull4(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAllNull4(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
Callable<String> task = () -> "foo";
|
Callable<String> task = () -> "foo";
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
@ -957,8 +995,9 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInvokeAllNull5(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInvokeAllNull5(ThreadFactory factory) throws Exception {
|
||||||
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
|
||||||
List<Callable<String>> tasks = new ArrayList<>();
|
List<Callable<String>> tasks = new ArrayList<>();
|
||||||
tasks.add(() -> "foo");
|
tasks.add(() -> "foo");
|
||||||
@ -972,33 +1011,33 @@ public class ThreadPerTaskExecutorTest {
|
|||||||
* Test ThreadFactory that does not produce any threads
|
* Test ThreadFactory that does not produce any threads
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNoThreads1() throws Exception {
|
void testNoThreads1() throws Exception {
|
||||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||||
assertThrows(RejectedExecutionException.class, () -> executor.execute(() -> { }));
|
assertThrows(RejectedExecutionException.class, () -> executor.execute(() -> { }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoThreads2() throws Exception {
|
void testNoThreads2() throws Exception {
|
||||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||||
assertThrows(RejectedExecutionException.class, () -> executor.submit(() -> "foo"));
|
assertThrows(RejectedExecutionException.class, () -> executor.submit(() -> "foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoThreads3() throws Exception {
|
void testNoThreads3() throws Exception {
|
||||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||||
assertThrows(RejectedExecutionException.class,
|
assertThrows(RejectedExecutionException.class,
|
||||||
() -> executor.invokeAll(List.of(() -> "foo")));
|
() -> executor.invokeAll(List.of(() -> "foo")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoThreads4() throws Exception {
|
void testNoThreads4() throws Exception {
|
||||||
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
ExecutorService executor = Executors.newThreadPerTaskExecutor(task -> null);
|
||||||
assertThrows(RejectedExecutionException.class,
|
assertThrows(RejectedExecutionException.class,
|
||||||
() -> executor.invokeAny(List.of(() -> "foo")));
|
() -> executor.invokeAny(List.of(() -> "foo")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNull() {
|
void testNull() {
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
() -> Executors.newThreadPerTaskExecutor(null));
|
() -> Executors.newThreadPerTaskExecutor(null));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,7 +28,7 @@
|
|||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @key randomness
|
* @key randomness
|
||||||
* @run testng ManyBindings
|
* @run junit ManyBindings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.incubator.concurrent.ScopedValue;
|
import jdk.incubator.concurrent.ScopedValue;
|
||||||
@ -40,11 +40,10 @@ import java.util.Random;
|
|||||||
import jdk.test.lib.RandomFactory;
|
import jdk.test.lib.RandomFactory;
|
||||||
import jdk.test.lib.thread.VThreadRunner;
|
import jdk.test.lib.thread.VThreadRunner;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@Test
|
class ManyBindings {
|
||||||
public class ManyBindings {
|
|
||||||
private static final Random RND = RandomFactory.getRandom();
|
private static final Random RND = RandomFactory.getRandom();
|
||||||
|
|
||||||
// number of scoped values to create
|
// number of scoped values to create
|
||||||
@ -56,14 +55,16 @@ public class ManyBindings {
|
|||||||
/**
|
/**
|
||||||
* Stress test bindings on platform thread.
|
* Stress test bindings on platform thread.
|
||||||
*/
|
*/
|
||||||
public void testPlatformThread() {
|
@Test
|
||||||
|
void testPlatformThread() {
|
||||||
test();
|
test();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stress test bindings on virtual thread.
|
* Stress test bindings on virtual thread.
|
||||||
*/
|
*/
|
||||||
public void testVirtualThread() throws Exception {
|
@Test
|
||||||
|
void testVirtualThread() throws Exception {
|
||||||
VThreadRunner.run(() -> test());
|
VThreadRunner.run(() -> test());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ public class ManyBindings {
|
|||||||
if (value == null) {
|
if (value == null) {
|
||||||
assertFalse(key.isBound());
|
assertFalse(key.isBound());
|
||||||
} else {
|
} else {
|
||||||
assertEquals(key.get(), value);
|
assertEquals(value, key.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +158,7 @@ public class ManyBindings {
|
|||||||
Integer value = array[index].value;
|
Integer value = array[index].value;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
ScopedValue<Integer> key = array[index].key;
|
ScopedValue<Integer> key = array[index].key;
|
||||||
assertEquals(key.get(), value);
|
assertEquals(value, key.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,7 +26,7 @@
|
|||||||
* @summary Test ScopedValue API
|
* @summary Test ScopedValue API
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @run testng ScopeValueAPI
|
* @run junit ScopeValueAPI
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.incubator.concurrent.ScopedValue;
|
import jdk.incubator.concurrent.ScopedValue;
|
||||||
@ -35,27 +35,25 @@ import java.util.concurrent.Callable;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.testng.annotations.DataProvider;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import static org.testng.Assert.*;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@Test
|
class ScopeValueAPI {
|
||||||
public class ScopeValueAPI {
|
|
||||||
|
|
||||||
@DataProvider
|
private static Stream<ThreadFactory> factories() {
|
||||||
public Object[][] factories() {
|
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
|
||||||
return new Object[][] {
|
|
||||||
{ Thread.ofPlatform().factory() },
|
|
||||||
{ Thread.ofVirtual().factory() },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the run method is invoked.
|
* Test that the run method is invoked.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testRun(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testRun(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
class Box { static boolean executed; }
|
class Box { static boolean executed; }
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
@ -67,8 +65,9 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test the run method throwing an exception.
|
* Test the run method throwing an exception.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testRunThrows(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testRunThrows(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
@ -81,20 +80,22 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test that the call method is invoked.
|
* Test that the call method is invoked.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCall(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testCall(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
String result = ScopedValue.where(name, "duke", name::get);
|
String result = ScopedValue.where(name, "duke", name::get);
|
||||||
assertEquals(result, "duke");
|
assertEquals("duke", result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the call method throwing an exception.
|
* Test the call method throwing an exception.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCallThrows(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testCallThrows(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
@ -107,8 +108,9 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test get method.
|
* Test get method.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testGet(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testGet(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name1 = ScopedValue.newInstance();
|
ScopedValue<String> name1 = ScopedValue.newInstance();
|
||||||
ScopedValue<String> name2 = ScopedValue.newInstance();
|
ScopedValue<String> name2 = ScopedValue.newInstance();
|
||||||
@ -117,7 +119,7 @@ public class ScopeValueAPI {
|
|||||||
|
|
||||||
// run
|
// run
|
||||||
ScopedValue.where(name1, "duke", () -> {
|
ScopedValue.where(name1, "duke", () -> {
|
||||||
assertEquals(name1.get(), "duke");
|
assertEquals("duke", name1.get());
|
||||||
assertThrows(NoSuchElementException.class, name2::get);
|
assertThrows(NoSuchElementException.class, name2::get);
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -126,7 +128,7 @@ public class ScopeValueAPI {
|
|||||||
|
|
||||||
// call
|
// call
|
||||||
ScopedValue.where(name1, "duke", () -> {
|
ScopedValue.where(name1, "duke", () -> {
|
||||||
assertEquals(name1.get(), "duke");
|
assertEquals("duke", name1.get());
|
||||||
assertThrows(NoSuchElementException.class, name2::get);
|
assertThrows(NoSuchElementException.class, name2::get);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@ -138,8 +140,9 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test isBound method.
|
* Test isBound method.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testIsBound(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testIsBound(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name1 = ScopedValue.newInstance();
|
ScopedValue<String> name1 = ScopedValue.newInstance();
|
||||||
ScopedValue<String> name2 = ScopedValue.newInstance();
|
ScopedValue<String> name2 = ScopedValue.newInstance();
|
||||||
@ -168,23 +171,24 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test orElse method.
|
* Test orElse method.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testOrElse(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testOrElse(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
assertTrue(name.orElse(null) == null);
|
assertNull(name.orElse(null));
|
||||||
assertEquals(name.orElse("default"), "default");
|
assertEquals("default", name.orElse("default"));
|
||||||
|
|
||||||
// run
|
// run
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertEquals(name.orElse(null), "duke");
|
assertEquals("duke", name.orElse(null));
|
||||||
assertEquals(name.orElse("default"), "duke");
|
assertEquals("duke", name.orElse("default"));
|
||||||
});
|
});
|
||||||
|
|
||||||
// call
|
// call
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertEquals(name.orElse(null), "duke");
|
assertEquals("duke", name.orElse(null));
|
||||||
assertEquals(name.orElse("default"), "duke");
|
assertEquals("duke", name.orElse("default"));
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -193,8 +197,9 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test orElseThrow method.
|
* Test orElseThrow method.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testOrElseThrow(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testOrElseThrow(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
class FooException extends RuntimeException { }
|
class FooException extends RuntimeException { }
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
@ -202,12 +207,12 @@ public class ScopeValueAPI {
|
|||||||
|
|
||||||
// run
|
// run
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertEquals(name.orElseThrow(FooException::new), "duke");
|
assertEquals("duke", name.orElseThrow(FooException::new));
|
||||||
});
|
});
|
||||||
|
|
||||||
// call
|
// call
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertEquals(name.orElseThrow(FooException::new), "duke");
|
assertEquals("duke", name.orElseThrow(FooException::new));
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -216,8 +221,9 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test two bindings.
|
* Test two bindings.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testTwoBindings(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testTwoBindings(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
ScopedValue<Integer> age = ScopedValue.newInstance();
|
ScopedValue<Integer> age = ScopedValue.newInstance();
|
||||||
@ -226,8 +232,8 @@ public class ScopeValueAPI {
|
|||||||
ScopedValue.where(name, "duke").where(age, 100).run(() -> {
|
ScopedValue.where(name, "duke").where(age, 100).run(() -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue(age.isBound());
|
assertTrue(age.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
assertEquals((int) age.get(), 100);
|
assertEquals(100, (int) age.get());
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
assertFalse(age.isBound());
|
assertFalse(age.isBound());
|
||||||
@ -236,8 +242,8 @@ public class ScopeValueAPI {
|
|||||||
ScopedValue.where(name, "duke").where(age, 100).call(() -> {
|
ScopedValue.where(name, "duke").where(age, 100).call(() -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue(age.isBound());
|
assertTrue(age.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
assertEquals((int) age.get(), 100);
|
assertEquals(100, (int) age.get());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
@ -249,39 +255,40 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test rebinding.
|
* Test rebinding.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testRebinding(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testRebinding(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
|
|
||||||
// run
|
// run
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
|
|
||||||
ScopedValue.where(name, "duchess", () -> {
|
ScopedValue.where(name, "duchess", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue("duchess".equals(name.get()));
|
assertEquals("duchess", name.get());
|
||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
|
|
||||||
// call
|
// call
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
|
|
||||||
ScopedValue.where(name, "duchess", () -> {
|
ScopedValue.where(name, "duchess", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue("duchess".equals(name.get()));
|
assertEquals("duchess", name.get());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
@ -291,15 +298,16 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test rebinding from null vaue to another value.
|
* Test rebinding from null vaue to another value.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testRebindingFromNull(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testRebindingFromNull(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
|
|
||||||
// run
|
// run
|
||||||
ScopedValue.where(name, null, () -> {
|
ScopedValue.where(name, null, () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), null);
|
assertNull(name.get());
|
||||||
|
|
||||||
ScopedValue.where(name, "duchess", () -> {
|
ScopedValue.where(name, "duchess", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
@ -307,14 +315,14 @@ public class ScopeValueAPI {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue(name.get() == null);
|
assertNull(name.get());
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
|
|
||||||
// call
|
// call
|
||||||
ScopedValue.where(name, null, () -> {
|
ScopedValue.where(name, null, () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), null);
|
assertNull(name.get());
|
||||||
|
|
||||||
ScopedValue.where(name, "duchess", () -> {
|
ScopedValue.where(name, "duchess", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
@ -323,7 +331,7 @@ public class ScopeValueAPI {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue(name.get() == null);
|
assertNull(name.get());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
@ -333,39 +341,40 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test rebinding to null value.
|
* Test rebinding to null value.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testRebindingToNull(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testRebindingToNull(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
|
|
||||||
// run
|
// run
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
|
|
||||||
ScopedValue.where(name, null, () -> {
|
ScopedValue.where(name, null, () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue(name.get() == null);
|
assertNull(name.get());
|
||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
|
|
||||||
// call
|
// call
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
|
|
||||||
ScopedValue.where(name, null, () -> {
|
ScopedValue.where(name, null, () -> {
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertTrue(name.get() == null);
|
assertNull(name.get());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(name.isBound());
|
assertTrue(name.isBound());
|
||||||
assertEquals(name.get(), "duke");
|
assertEquals("duke", name.get());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
assertFalse(name.isBound());
|
assertFalse(name.isBound());
|
||||||
@ -375,28 +384,30 @@ public class ScopeValueAPI {
|
|||||||
/**
|
/**
|
||||||
* Test Carrier.get.
|
* Test Carrier.get.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCarrierGet(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testCarrierGet(ThreadFactory factory) throws Exception {
|
||||||
test(factory, () -> {
|
test(factory, () -> {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
ScopedValue<Integer> age = ScopedValue.newInstance();
|
ScopedValue<Integer> age = ScopedValue.newInstance();
|
||||||
|
|
||||||
// one scoped value
|
// one scoped value
|
||||||
var carrier1 = ScopedValue.where(name, "duke");
|
var carrier1 = ScopedValue.where(name, "duke");
|
||||||
assertEquals(carrier1.get(name), "duke");
|
assertEquals("duke", carrier1.get(name));
|
||||||
assertThrows(NoSuchElementException.class, () -> carrier1.get(age));
|
assertThrows(NoSuchElementException.class, () -> carrier1.get(age));
|
||||||
|
|
||||||
// two scoped values
|
// two scoped values
|
||||||
var carrier2 = carrier1.where(age, 20);
|
var carrier2 = carrier1.where(age, 20);
|
||||||
assertEquals(carrier2.get(name), "duke");
|
assertEquals("duke", carrier2.get(name));
|
||||||
assertEquals((int) carrier2.get(age), 20);
|
assertEquals(20, (int) carrier2.get(age));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test NullPointerException.
|
* Test NullPointerException.
|
||||||
*/
|
*/
|
||||||
public void testNullPointerException() {
|
@Test
|
||||||
|
void testNullPointerException() {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
|
|
||||||
assertThrows(NullPointerException.class, () -> ScopedValue.where(null, "value"));
|
assertThrows(NullPointerException.class, () -> ScopedValue.where(null, "value"));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,19 +26,19 @@
|
|||||||
* @bug 8284199
|
* @bug 8284199
|
||||||
* @summary Test StructuredTaskScope without --enable-preview
|
* @summary Test StructuredTaskScope without --enable-preview
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @run testng/othervm PreviewFeaturesNotEnabled
|
* @run junit/othervm PreviewFeaturesNotEnabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.incubator.concurrent.StructuredTaskScope;
|
import jdk.incubator.concurrent.StructuredTaskScope;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class PreviewFeaturesNotEnabled {
|
class PreviewFeaturesNotEnabled {
|
||||||
/**
|
/**
|
||||||
* One-arg constructor needs --enable-preview.
|
* One-arg constructor needs --enable-preview.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUnsupportedOperationException() {
|
void testUnsupportedOperationException() {
|
||||||
assertThrows(UnsupportedOperationException.class, StructuredTaskScope::new);
|
assertThrows(UnsupportedOperationException.class, StructuredTaskScope::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ public class PreviewFeaturesNotEnabled {
|
|||||||
* Two-arg constructor does not need --enable-preview.
|
* Two-arg constructor does not need --enable-preview.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNoUnsupportedOperationException() {
|
void testNoUnsupportedOperationException() {
|
||||||
try (var scope = new StructuredTaskScope<Object>(null, Thread::new)) {
|
try (var scope = new StructuredTaskScope<Object>(null, Thread::new)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,14 @@
|
|||||||
* @summary Basic tests for StructuredTaskScope
|
* @summary Basic tests for StructuredTaskScope
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @run testng/othervm -DthreadFactory=platform StructuredTaskScopeTest
|
* @run junit/othervm -DthreadFactory=platform StructuredTaskScopeTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test id=virtual
|
* @test id=virtual
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @run testng/othervm -DthreadFactory=virtual StructuredTaskScopeTest
|
* @run junit/othervm -DthreadFactory=virtual StructuredTaskScopeTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.incubator.concurrent.StructuredTaskScope;
|
import jdk.incubator.concurrent.StructuredTaskScope;
|
||||||
@ -65,24 +65,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
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 {
|
import org.junit.jupiter.api.Test;
|
||||||
private ScheduledExecutorService scheduler;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
private Object[][] threadFactories;
|
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
|
class StructuredTaskScopeTest {
|
||||||
public void setUp() throws Exception {
|
private static ScheduledExecutorService scheduler;
|
||||||
ThreadFactory factory = (task) -> {
|
private static List<ThreadFactory> threadFactories;
|
||||||
Thread thread = new Thread(task);
|
|
||||||
thread.setDaemon(true);
|
@BeforeAll
|
||||||
return thread;
|
static void setup() throws Exception {
|
||||||
};
|
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(factory);
|
|
||||||
|
|
||||||
// thread factories
|
// thread factories
|
||||||
String value = System.getProperty("threadFactory");
|
String value = System.getProperty("threadFactory");
|
||||||
@ -92,29 +89,24 @@ public class StructuredTaskScopeTest {
|
|||||||
if (value == null || value.equals("virtual"))
|
if (value == null || value.equals("virtual"))
|
||||||
list.add(Thread.ofVirtual().factory());
|
list.add(Thread.ofVirtual().factory());
|
||||||
assertTrue(list.size() > 0, "No thread factories for tests");
|
assertTrue(list.size() > 0, "No thread factories for tests");
|
||||||
this.threadFactories = list.stream()
|
threadFactories = list;
|
||||||
.map(f -> new Object[] { f })
|
|
||||||
.toArray(Object[][]::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterAll
|
||||||
public void tearDown() {
|
static void shutdown() {
|
||||||
scheduler.shutdown();
|
scheduler.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static Stream<ThreadFactory> factories() {
|
||||||
* A provider of ThreadFactory objects for tests.
|
return threadFactories.stream();
|
||||||
*/
|
|
||||||
@DataProvider
|
|
||||||
public Object[][] factories() {
|
|
||||||
return threadFactories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that each fork creates a thread.
|
* Test that each fork creates a thread.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFork1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFork1(ThreadFactory factory) throws Exception {
|
||||||
AtomicInteger count = new AtomicInteger();
|
AtomicInteger count = new AtomicInteger();
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
@ -128,8 +120,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test that fork uses the specified thread factory.
|
* Test that fork uses the specified thread factory.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFork2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFork2(ThreadFactory factory) throws Exception {
|
||||||
AtomicInteger count = new AtomicInteger();
|
AtomicInteger count = new AtomicInteger();
|
||||||
ThreadFactory countingFactory = task -> {
|
ThreadFactory countingFactory = task -> {
|
||||||
count.incrementAndGet();
|
count.incrementAndGet();
|
||||||
@ -147,8 +140,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test fork is confined to threads in the scope "tree".
|
* Test fork is confined to threads in the scope "tree".
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testForkConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testForkConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var scope1 = new StructuredTaskScope();
|
try (var scope1 = new StructuredTaskScope();
|
||||||
var scope2 = new StructuredTaskScope()) {
|
var scope2 = new StructuredTaskScope()) {
|
||||||
|
|
||||||
@ -157,7 +151,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope2.fork(() -> null).get();
|
scope2.fork(() -> null).get();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
|
|
||||||
// thread in scope2 can fork thread in scope1
|
// thread in scope2 can fork thread in scope1
|
||||||
@ -166,7 +160,7 @@ public class StructuredTaskScopeTest {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
future2.get();
|
future2.get();
|
||||||
assertTrue(future2.resultNow() == null);
|
assertNull(future2.resultNow());
|
||||||
|
|
||||||
// random thread cannot fork
|
// random thread cannot fork
|
||||||
try (var pool = Executors.newCachedThreadPool(factory)) {
|
try (var pool = Executors.newCachedThreadPool(factory)) {
|
||||||
@ -174,7 +168,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope1.fork(() -> null);
|
scope1.fork(() -> null);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
ex = expectThrows(ExecutionException.class, future::get);
|
ex = assertThrows(ExecutionException.class, future::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +180,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test fork when scope is shutdown.
|
* Test fork when scope is shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testForkAfterShutdown(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testForkAfterShutdown(ThreadFactory factory) throws Exception {
|
||||||
AtomicInteger count = new AtomicInteger();
|
AtomicInteger count = new AtomicInteger();
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
scope.shutdown();
|
scope.shutdown();
|
||||||
@ -204,8 +199,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test fork when scope is closed.
|
* Test fork when scope is closed.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testForkAfterClose(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testForkAfterClose(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
scope.join();
|
scope.join();
|
||||||
scope.close();
|
scope.close();
|
||||||
@ -217,7 +213,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test fork when the thread factory rejects creating a thread.
|
* Test fork when the thread factory rejects creating a thread.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testForkReject() throws Exception {
|
void testForkReject() throws Exception {
|
||||||
ThreadFactory factory = task -> null;
|
ThreadFactory factory = task -> null;
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
assertThrows(RejectedExecutionException.class, () -> scope.fork(() -> null));
|
assertThrows(RejectedExecutionException.class, () -> scope.fork(() -> null));
|
||||||
@ -255,8 +251,9 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test that handleComplete method is invoked for tasks that complete normally
|
* Test that handleComplete method is invoked for tasks that complete normally
|
||||||
* and abnormally.
|
* and abnormally.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testHandleComplete1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testHandleComplete1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new CollectAll(factory)) {
|
try (var scope = new CollectAll(factory)) {
|
||||||
|
|
||||||
// completes normally
|
// completes normally
|
||||||
@ -275,17 +272,17 @@ public class StructuredTaskScopeTest {
|
|||||||
scope.join();
|
scope.join();
|
||||||
|
|
||||||
Set<Future<String>> futures = scope.futuresAsSet();
|
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 that the handeComplete method is not invoked after the scope has been shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testHandleComplete2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testHandleComplete2(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new CollectAll(factory)) {
|
try (var scope = new CollectAll(factory)) {
|
||||||
|
|
||||||
var latch = new CountDownLatch(1);
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
// start task that does not respond to interrupt
|
// start task that does not respond to interrupt
|
||||||
@ -322,7 +319,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test join with no threads.
|
* Test join with no threads.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinWithNoThreads() throws Exception {
|
void testJoinWithNoThreads() throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
scope.join();
|
scope.join();
|
||||||
}
|
}
|
||||||
@ -331,30 +328,32 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test join with threads running.
|
* Test join with threads running.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinWithThreads(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinWithThreads(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofMillis(50));
|
Thread.sleep(Duration.ofMillis(50));
|
||||||
return "foo";
|
return "foo";
|
||||||
});
|
});
|
||||||
scope.join();
|
scope.join();
|
||||||
assertEquals(future.resultNow(), "foo");
|
assertEquals("foo", future.resultNow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test join is owner confined.
|
* Test join is owner confined.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
// attempt to join on thread in scope
|
// attempt to join on thread in scope
|
||||||
Future<Void> future1 = scope.fork(() -> {
|
Future<Void> future1 = scope.fork(() -> {
|
||||||
scope.join();
|
scope.join();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
|
|
||||||
// random thread cannot join
|
// random thread cannot join
|
||||||
@ -363,7 +362,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope.join();
|
scope.join();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
ex = expectThrows(ExecutionException.class, future2::get);
|
ex = assertThrows(ExecutionException.class, future2::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,11 +373,14 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test join with interrupt status set.
|
* Test join with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptJoin1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInterruptJoin1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofMillis(100));
|
latch.await();
|
||||||
return "foo";
|
return "foo";
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -389,22 +391,28 @@ public class StructuredTaskScopeTest {
|
|||||||
fail("join did not throw");
|
fail("join did not throw");
|
||||||
} catch (InterruptedException expected) {
|
} catch (InterruptedException expected) {
|
||||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||||
|
} finally {
|
||||||
|
// let task continue
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// join should complete
|
// join should complete
|
||||||
scope.join();
|
scope.join();
|
||||||
assertEquals(future.resultNow(), "foo");
|
assertEquals("foo", future.resultNow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test interrupt of thread blocked in join.
|
* Test interrupt of thread blocked in join.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptJoin2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInterruptJoin2(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofSeconds(3));
|
latch.await();
|
||||||
return "foo";
|
return "foo";
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -415,19 +423,23 @@ public class StructuredTaskScopeTest {
|
|||||||
fail("join did not throw");
|
fail("join did not throw");
|
||||||
} catch (InterruptedException expected) {
|
} catch (InterruptedException expected) {
|
||||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||||
|
} finally {
|
||||||
|
// let task continue
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// join should complete
|
// join should complete
|
||||||
scope.join();
|
scope.join();
|
||||||
assertEquals(future.resultNow(), "foo");
|
assertEquals("foo", future.resultNow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test join when scope is already shutdown.
|
* Test join when scope is already shutdown.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinWithShutdown1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinWithShutdown1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofDays(1));
|
Thread.sleep(Duration.ofDays(1));
|
||||||
@ -444,8 +456,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test shutdown when owner is blocked in join.
|
* Test shutdown when owner is blocked in join.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinWithShutdown2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinWithShutdown2(ThreadFactory factory) throws Exception {
|
||||||
class MyScope<T> extends StructuredTaskScope<T> {
|
class MyScope<T> extends StructuredTaskScope<T> {
|
||||||
MyScope(ThreadFactory factory) {
|
MyScope(ThreadFactory factory) {
|
||||||
super(null, factory);
|
super(null, factory);
|
||||||
@ -479,7 +492,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test join after scope is shutdown.
|
* Test join after scope is shutdown.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinAfterShutdown() throws Exception {
|
void testJoinAfterShutdown() throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
scope.shutdown();
|
scope.shutdown();
|
||||||
scope.join();
|
scope.join();
|
||||||
@ -490,7 +503,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test join after scope is closed.
|
* Test join after scope is closed.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testJoinAfterClose() throws Exception {
|
void testJoinAfterClose() throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
scope.join();
|
scope.join();
|
||||||
scope.close();
|
scope.close();
|
||||||
@ -502,8 +515,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test joinUntil, threads finish before deadline expires.
|
* Test joinUntil, threads finish before deadline expires.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinUntil1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinUntil1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
try {
|
try {
|
||||||
@ -514,7 +528,8 @@ public class StructuredTaskScopeTest {
|
|||||||
|
|
||||||
long startMillis = millisTime();
|
long startMillis = millisTime();
|
||||||
scope.joinUntil(Instant.now().plusSeconds(30));
|
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);
|
expectDuration(startMillis, /*min*/1900, /*max*/20_000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,8 +537,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test joinUntil, deadline expires before threads finish.
|
* Test joinUntil, deadline expires before threads finish.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinUntil2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinUntil2(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
try {
|
try {
|
||||||
@ -545,8 +561,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test joinUntil many times.
|
* Test joinUntil many times.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinUntil3(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinUntil3(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
try {
|
try {
|
||||||
@ -573,8 +590,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test joinUntil with a deadline that has already expired.
|
* Test joinUntil with a deadline that has already expired.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testJoinUntil4(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testJoinUntil4(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
try {
|
try {
|
||||||
@ -610,37 +628,46 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test joinUntil with interrupt status set.
|
* Test joinUntil with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptJoinUntil1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInterruptJoinUntil1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofSeconds(2));
|
latch.await();
|
||||||
return "foo";
|
return "foo";
|
||||||
});
|
});
|
||||||
|
|
||||||
// joinUntil should throw
|
// joinUntil should throw
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
try {
|
try {
|
||||||
scope.joinUntil(Instant.now().plusSeconds(10));
|
scope.joinUntil(Instant.now().plusSeconds(30));
|
||||||
fail("joinUntil did not throw");
|
fail("joinUntil did not throw");
|
||||||
} catch (InterruptedException expected) {
|
} catch (InterruptedException expected) {
|
||||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||||
|
} finally {
|
||||||
|
// let task continue
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// join should complete
|
// join should complete
|
||||||
scope.join();
|
scope.join();
|
||||||
assertEquals(future.resultNow(), "foo");
|
assertEquals("foo", future.resultNow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test interrupt of thread blocked in joinUntil.
|
* Test interrupt of thread blocked in joinUntil.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptJoinUntil2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInterruptJoinUntil2(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofSeconds(3));
|
latch.await();
|
||||||
return "foo";
|
return "foo";
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -651,18 +678,22 @@ public class StructuredTaskScopeTest {
|
|||||||
fail("joinUntil did not throw");
|
fail("joinUntil did not throw");
|
||||||
} catch (InterruptedException expected) {
|
} catch (InterruptedException expected) {
|
||||||
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
assertFalse(Thread.interrupted()); // interrupt status should be clear
|
||||||
|
} finally {
|
||||||
|
// let task continue
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// join should complete
|
// join should complete
|
||||||
scope.join();
|
scope.join();
|
||||||
assertEquals(future.resultNow(), "foo");
|
assertEquals("foo", future.resultNow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test shutdown after scope is closed.
|
* Test shutdown after scope is closed.
|
||||||
*/
|
*/
|
||||||
public void testShutdownAfterClose() throws Exception {
|
@Test
|
||||||
|
void testShutdownAfterClose() throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
scope.join();
|
scope.join();
|
||||||
scope.close();
|
scope.close();
|
||||||
@ -673,8 +704,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test shutdown is confined to threads in the scope "tree".
|
* Test shutdown is confined to threads in the scope "tree".
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testShutdownConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testShutdownConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var scope1 = new StructuredTaskScope();
|
try (var scope1 = new StructuredTaskScope();
|
||||||
var scope2 = new StructuredTaskScope()) {
|
var scope2 = new StructuredTaskScope()) {
|
||||||
|
|
||||||
@ -684,7 +716,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope1.shutdown();
|
scope1.shutdown();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future::get);
|
Throwable ex = assertThrows(ExecutionException.class, future::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +725,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope2.shutdown();
|
scope2.shutdown();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
|
|
||||||
// thread in scope2 can shutdown scope1
|
// thread in scope2 can shutdown scope1
|
||||||
@ -702,7 +734,7 @@ public class StructuredTaskScopeTest {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
future2.get();
|
future2.get();
|
||||||
assertTrue(future2.resultNow() == null);
|
assertNull(future2.resultNow());
|
||||||
|
|
||||||
scope2.join();
|
scope2.join();
|
||||||
scope1.join();
|
scope1.join();
|
||||||
@ -712,7 +744,8 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test close without join, no threads forked.
|
* Test close without join, no threads forked.
|
||||||
*/
|
*/
|
||||||
public void testCloseWithoutJoin1() {
|
@Test
|
||||||
|
void testCloseWithoutJoin1() {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -721,8 +754,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test close without join, threads forked.
|
* Test close without join, threads forked.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCloseWithoutJoin2(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testCloseWithoutJoin2(ThreadFactory factory) {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofDays(1));
|
Thread.sleep(Duration.ofDays(1));
|
||||||
@ -736,8 +770,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test close with threads forked after join.
|
* Test close with threads forked after join.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCloseWithoutJoin3(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testCloseWithoutJoin3(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
scope.fork(() -> "foo");
|
scope.fork(() -> "foo");
|
||||||
scope.join();
|
scope.join();
|
||||||
@ -754,15 +789,16 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test close is owner confined.
|
* Test close is owner confined.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCloseConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testCloseConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
// attempt to close on thread in scope
|
// attempt to close on thread in scope
|
||||||
Future<Void> future1 = scope.fork(() -> {
|
Future<Void> future1 = scope.fork(() -> {
|
||||||
scope.close();
|
scope.close();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future1::get);
|
Throwable ex = assertThrows(ExecutionException.class, future1::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
|
|
||||||
// random thread cannot close scope
|
// random thread cannot close scope
|
||||||
@ -771,7 +807,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope.close();
|
scope.close();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
ex = expectThrows(ExecutionException.class, future2::get);
|
ex = assertThrows(ExecutionException.class, future2::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,8 +818,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test close with interrupt status set.
|
* Test close with interrupt status set.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptClose1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInterruptClose1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
var latch = new CountDownLatch(1);
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
@ -818,8 +855,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test interrupting thread waiting in close.
|
* Test interrupting thread waiting in close.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptClose2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInterruptClose2(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
var latch = new CountDownLatch(1);
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
@ -854,7 +892,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* nested scope.
|
* nested scope.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStructureViolation1() throws Exception {
|
void testStructureViolation1() throws Exception {
|
||||||
try (var scope1 = new StructuredTaskScope()) {
|
try (var scope1 = new StructuredTaskScope()) {
|
||||||
try (var scope2 = new StructuredTaskScope()) {
|
try (var scope2 = new StructuredTaskScope()) {
|
||||||
|
|
||||||
@ -881,8 +919,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test Future::get, task completes normally.
|
* Test Future::get, task completes normally.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFuture1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFuture1(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
@ -890,9 +929,9 @@ public class StructuredTaskScopeTest {
|
|||||||
return "foo";
|
return "foo";
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEquals(future.get(), "foo");
|
assertEquals("foo", future.get());
|
||||||
assertTrue(future.state() == Future.State.SUCCESS);
|
assertTrue(future.state() == Future.State.SUCCESS);
|
||||||
assertEquals(future.resultNow(), "foo");
|
assertEquals("foo", future.resultNow());
|
||||||
|
|
||||||
scope.join();
|
scope.join();
|
||||||
}
|
}
|
||||||
@ -901,8 +940,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test Future::get, task completes with exception.
|
* Test Future::get, task completes with exception.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFuture2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFuture2(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
@ -910,7 +950,7 @@ public class StructuredTaskScopeTest {
|
|||||||
throw new FooException();
|
throw new FooException();
|
||||||
});
|
});
|
||||||
|
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future::get);
|
Throwable ex = assertThrows(ExecutionException.class, future::get);
|
||||||
assertTrue(ex.getCause() instanceof FooException);
|
assertTrue(ex.getCause() instanceof FooException);
|
||||||
assertTrue(future.state() == Future.State.FAILED);
|
assertTrue(future.state() == Future.State.FAILED);
|
||||||
assertTrue(future.exceptionNow() instanceof FooException);
|
assertTrue(future.exceptionNow() instanceof FooException);
|
||||||
@ -922,8 +962,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test Future::get, task is cancelled.
|
* Test Future::get, task is cancelled.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFuture3(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFuture3(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
|
||||||
Future<String> future = scope.fork(() -> {
|
Future<String> future = scope.fork(() -> {
|
||||||
@ -948,8 +989,9 @@ public class StructuredTaskScopeTest {
|
|||||||
/**
|
/**
|
||||||
* Test scope shutdown with a thread blocked in Future::get.
|
* Test scope shutdown with a thread blocked in Future::get.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFutureWithShutdown(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFutureWithShutdown(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope(null, factory)) {
|
try (var scope = new StructuredTaskScope(null, factory)) {
|
||||||
|
|
||||||
// long running task
|
// 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 Future::cancel throws if invoked by a thread that is not in the tree.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testFutureCancelConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testFutureCancelConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
Future<String> future1 = scope.fork(() -> {
|
Future<String> future1 = scope.fork(() -> {
|
||||||
Thread.sleep(Duration.ofDays(1));
|
Thread.sleep(Duration.ofDays(1));
|
||||||
@ -999,7 +1042,7 @@ public class StructuredTaskScopeTest {
|
|||||||
future1.cancel(true);
|
future1.cancel(true);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
Throwable ex = expectThrows(ExecutionException.class, future2::get);
|
Throwable ex = assertThrows(ExecutionException.class, future2::get);
|
||||||
assertTrue(ex.getCause() instanceof WrongThreadException);
|
assertTrue(ex.getCause() instanceof WrongThreadException);
|
||||||
} finally {
|
} finally {
|
||||||
future1.cancel(true);
|
future1.cancel(true);
|
||||||
@ -1012,7 +1055,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test StructuredTaskScope::toString includes the scope name.
|
* Test StructuredTaskScope::toString includes the scope name.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testToString() throws Exception {
|
void testToString() throws Exception {
|
||||||
ThreadFactory factory = Thread.ofVirtual().factory();
|
ThreadFactory factory = Thread.ofVirtual().factory();
|
||||||
try (var scope = new StructuredTaskScope("xxx", factory)) {
|
try (var scope = new StructuredTaskScope("xxx", factory)) {
|
||||||
// open
|
// open
|
||||||
@ -1033,7 +1076,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test for NullPointerException.
|
* Test for NullPointerException.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNulls() throws Exception {
|
void testNulls() throws Exception {
|
||||||
assertThrows(NullPointerException.class, () -> new StructuredTaskScope("", null));
|
assertThrows(NullPointerException.class, () -> new StructuredTaskScope("", null));
|
||||||
try (var scope = new StructuredTaskScope()) {
|
try (var scope = new StructuredTaskScope()) {
|
||||||
assertThrows(NullPointerException.class, () -> scope.fork(null));
|
assertThrows(NullPointerException.class, () -> scope.fork(null));
|
||||||
@ -1059,7 +1102,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnSuccess with no completed tasks.
|
* Test ShutdownOnSuccess with no completed tasks.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnSuccess1() throws Exception {
|
void testShutdownOnSuccess1() throws Exception {
|
||||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||||
assertThrows(IllegalStateException.class, () -> scope.result());
|
assertThrows(IllegalStateException.class, () -> scope.result());
|
||||||
assertThrows(IllegalStateException.class, () -> scope.result(e -> null));
|
assertThrows(IllegalStateException.class, () -> scope.result(e -> null));
|
||||||
@ -1070,7 +1113,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnSuccess with tasks that completed normally.
|
* Test ShutdownOnSuccess with tasks that completed normally.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnSuccess2() throws Exception {
|
void testShutdownOnSuccess2() throws Exception {
|
||||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||||
|
|
||||||
// two tasks complete normally
|
// two tasks complete normally
|
||||||
@ -1079,8 +1122,8 @@ public class StructuredTaskScopeTest {
|
|||||||
scope.fork(() -> "bar");
|
scope.fork(() -> "bar");
|
||||||
scope.join();
|
scope.join();
|
||||||
|
|
||||||
assertEquals(scope.result(), "foo");
|
assertEquals("foo", scope.result());
|
||||||
assertEquals(scope.result(e -> null), "foo");
|
assertEquals("foo", scope.result(e -> null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,7 +1131,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnSuccess with tasks that completed normally and abnormally.
|
* Test ShutdownOnSuccess with tasks that completed normally and abnormally.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnSuccess3() throws Exception {
|
void testShutdownOnSuccess3() throws Exception {
|
||||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||||
|
|
||||||
// one task completes normally, the other with an exception
|
// one task completes normally, the other with an exception
|
||||||
@ -1096,8 +1139,8 @@ public class StructuredTaskScopeTest {
|
|||||||
scope.fork(() -> { throw new ArithmeticException(); });
|
scope.fork(() -> { throw new ArithmeticException(); });
|
||||||
scope.join();
|
scope.join();
|
||||||
|
|
||||||
assertEquals(scope.result(), "foo");
|
assertEquals("foo", scope.result());
|
||||||
assertEquals(scope.result(e -> null), "foo");
|
assertEquals("foo", scope.result(e -> null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1105,17 +1148,17 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnSuccess with a task that completed with an exception.
|
* Test ShutdownOnSuccess with a task that completed with an exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnSuccess4() throws Exception {
|
void testShutdownOnSuccess4() throws Exception {
|
||||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||||
|
|
||||||
// tasks completes with exception
|
// tasks completes with exception
|
||||||
scope.fork(() -> { throw new ArithmeticException(); });
|
scope.fork(() -> { throw new ArithmeticException(); });
|
||||||
scope.join();
|
scope.join();
|
||||||
|
|
||||||
Throwable ex = expectThrows(ExecutionException.class, () -> scope.result());
|
Throwable ex = assertThrows(ExecutionException.class, () -> scope.result());
|
||||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
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);
|
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1124,7 +1167,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnSuccess with a cancelled task.
|
* Test ShutdownOnSuccess with a cancelled task.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnSuccess5() throws Exception {
|
void testShutdownOnSuccess5() throws Exception {
|
||||||
try (var scope = new ShutdownOnSuccess<String>()) {
|
try (var scope = new ShutdownOnSuccess<String>()) {
|
||||||
|
|
||||||
// cancelled task
|
// cancelled task
|
||||||
@ -1137,7 +1180,7 @@ public class StructuredTaskScopeTest {
|
|||||||
scope.join();
|
scope.join();
|
||||||
|
|
||||||
assertThrows(CancellationException.class, () -> scope.result());
|
assertThrows(CancellationException.class, () -> scope.result());
|
||||||
Throwable ex = expectThrows(FooException.class,
|
Throwable ex = assertThrows(FooException.class,
|
||||||
() -> scope.result(e -> new FooException(e)));
|
() -> scope.result(e -> new FooException(e)));
|
||||||
assertTrue(ex.getCause() instanceof CancellationException);
|
assertTrue(ex.getCause() instanceof CancellationException);
|
||||||
}
|
}
|
||||||
@ -1147,7 +1190,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnFailure with no completed tasks.
|
* Test ShutdownOnFailure with no completed tasks.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnFailure1() throws Throwable {
|
void testShutdownOnFailure1() throws Throwable {
|
||||||
try (var scope = new ShutdownOnFailure()) {
|
try (var scope = new ShutdownOnFailure()) {
|
||||||
assertTrue(scope.exception().isEmpty());
|
assertTrue(scope.exception().isEmpty());
|
||||||
scope.throwIfFailed();
|
scope.throwIfFailed();
|
||||||
@ -1159,7 +1202,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnFailure with tasks that completed normally.
|
* Test ShutdownOnFailure with tasks that completed normally.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnFailure2() throws Throwable {
|
void testShutdownOnFailure2() throws Throwable {
|
||||||
try (var scope = new ShutdownOnFailure()) {
|
try (var scope = new ShutdownOnFailure()) {
|
||||||
scope.fork(() -> "foo");
|
scope.fork(() -> "foo");
|
||||||
scope.fork(() -> "bar");
|
scope.fork(() -> "bar");
|
||||||
@ -1176,7 +1219,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnFailure with tasks that completed normally and abnormally.
|
* Test ShutdownOnFailure with tasks that completed normally and abnormally.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnFailure3() throws Throwable {
|
void testShutdownOnFailure3() throws Throwable {
|
||||||
try (var scope = new ShutdownOnFailure()) {
|
try (var scope = new ShutdownOnFailure()) {
|
||||||
|
|
||||||
// one task completes normally, the other with an exception
|
// one task completes normally, the other with an exception
|
||||||
@ -1187,10 +1230,10 @@ public class StructuredTaskScopeTest {
|
|||||||
Throwable ex = scope.exception().orElse(null);
|
Throwable ex = scope.exception().orElse(null);
|
||||||
assertTrue(ex instanceof ArithmeticException);
|
assertTrue(ex instanceof ArithmeticException);
|
||||||
|
|
||||||
ex = expectThrows(ExecutionException.class, () -> scope.throwIfFailed());
|
ex = assertThrows(ExecutionException.class, () -> scope.throwIfFailed());
|
||||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||||
|
|
||||||
ex = expectThrows(FooException.class,
|
ex = assertThrows(FooException.class,
|
||||||
() -> scope.throwIfFailed(e -> new FooException(e)));
|
() -> scope.throwIfFailed(e -> new FooException(e)));
|
||||||
assertTrue(ex.getCause() instanceof ArithmeticException);
|
assertTrue(ex.getCause() instanceof ArithmeticException);
|
||||||
}
|
}
|
||||||
@ -1200,7 +1243,7 @@ public class StructuredTaskScopeTest {
|
|||||||
* Test ShutdownOnFailure with a cancelled task.
|
* Test ShutdownOnFailure with a cancelled task.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testShutdownOnFailure4() throws Throwable {
|
void testShutdownOnFailure4() throws Throwable {
|
||||||
try (var scope = new ShutdownOnFailure()) {
|
try (var scope = new ShutdownOnFailure()) {
|
||||||
|
|
||||||
var future = scope.fork(() -> {
|
var future = scope.fork(() -> {
|
||||||
@ -1216,7 +1259,7 @@ public class StructuredTaskScopeTest {
|
|||||||
|
|
||||||
assertThrows(CancellationException.class, () -> scope.throwIfFailed());
|
assertThrows(CancellationException.class, () -> scope.throwIfFailed());
|
||||||
|
|
||||||
ex = expectThrows(FooException.class,
|
ex = assertThrows(FooException.class,
|
||||||
() -> scope.throwIfFailed(e -> new FooException(e)));
|
() -> scope.throwIfFailed(e -> new FooException(e)));
|
||||||
assertTrue(ex.getCause() instanceof CancellationException);
|
assertTrue(ex.getCause() instanceof CancellationException);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,7 +28,7 @@
|
|||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @run testng/othervm StructuredThreadDumpTest
|
* @run junit/othervm StructuredThreadDumpTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.incubator.concurrent.StructuredTaskScope;
|
import jdk.incubator.concurrent.StructuredTaskScope;
|
||||||
@ -43,17 +43,17 @@ import java.util.stream.Stream;
|
|||||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||||
import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat;
|
import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat;
|
||||||
import jdk.test.lib.threaddump.ThreadDump;
|
import jdk.test.lib.threaddump.ThreadDump;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.testng.Assert.*;
|
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
|
* Test that a thread dump with a tree of task scopes contains a thread grouping for
|
||||||
* each task scope.
|
* each task scope.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTree() throws Exception {
|
void testTree() throws Exception {
|
||||||
ThreadFactory factory = Thread.ofVirtual().factory();
|
ThreadFactory factory = Thread.ofVirtual().factory();
|
||||||
try (var scope = new StructuredTaskScope<>("scope", factory)) {
|
try (var scope = new StructuredTaskScope<>("scope", factory)) {
|
||||||
Thread thread1 = fork(scope, "child-scope-A");
|
Thread thread1 = fork(scope, "child-scope-A");
|
||||||
@ -95,7 +95,7 @@ public class StructuredThreadDumpTest {
|
|||||||
* each task scope.
|
* each task scope.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNested() throws Exception {
|
void testNested() throws Exception {
|
||||||
ThreadFactory factory = Thread.ofVirtual().factory();
|
ThreadFactory factory = Thread.ofVirtual().factory();
|
||||||
try (var scope1 = new StructuredTaskScope<>("scope-A", factory)) {
|
try (var scope1 = new StructuredTaskScope<>("scope-A", factory)) {
|
||||||
Thread thread1 = fork(scope1);
|
Thread thread1 = fork(scope1);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* @summary Basic tests for StructuredTaskScope with scoped values
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @run testng WithScopedValue
|
* @run junit WithScopedValue
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.incubator.concurrent.ScopedValue;
|
import jdk.incubator.concurrent.ScopedValue;
|
||||||
@ -35,27 +35,25 @@ import jdk.incubator.concurrent.StructureViolationException;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.testng.annotations.DataProvider;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import static org.testng.Assert.*;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@Test
|
class WithScopedValue {
|
||||||
public class WithScopedValue {
|
|
||||||
|
|
||||||
@DataProvider
|
private static Stream<ThreadFactory> factories() {
|
||||||
public Object[][] factories() {
|
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
|
||||||
return new Object[][] {
|
|
||||||
{ Thread.ofPlatform().factory() },
|
|
||||||
{ Thread.ofVirtual().factory() },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that fork inherits a scoped value into a child thread.
|
* Test that fork inherits a scoped value into a child thread.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testForkInheritsScopedValue1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testForkInheritsScopedValue1(ThreadFactory factory) throws Exception {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
String value = ScopedValue.where(name, "x", () -> {
|
String value = ScopedValue.where(name, "x", () -> {
|
||||||
try (var scope = new StructuredTaskScope<String>(null, factory)) {
|
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 that fork inherits a scoped value into a grandchild thread.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testForkInheritsScopedValue2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testForkInheritsScopedValue2(ThreadFactory factory) throws Exception {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
String value = ScopedValue.where(name, "x", () -> {
|
String value = ScopedValue.where(name, "x", () -> {
|
||||||
try (var scope1 = new StructuredTaskScope<String>(null, factory)) {
|
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 that fork inherits a rebound scoped value into a grandchild thread.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testForkInheritsScopedValue3(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testForkInheritsScopedValue3(ThreadFactory factory) throws Exception {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
String value = ScopedValue.where(name, "x", () -> {
|
String value = ScopedValue.where(name, "x", () -> {
|
||||||
try (var scope1 = new StructuredTaskScope<String>(null, factory)) {
|
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.
|
* 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();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
class Box {
|
class Box {
|
||||||
StructuredTaskScope<Object> scope;
|
StructuredTaskScope<Object> scope;
|
||||||
@ -164,7 +165,8 @@ public class WithScopedValue {
|
|||||||
/**
|
/**
|
||||||
* Test closing a StructuredTaskScope while executing in a dynamic scope.
|
* 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();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
try (var scope = new StructuredTaskScope<String>()) {
|
try (var scope = new StructuredTaskScope<String>()) {
|
||||||
ScopedValue.where(name, "x", () -> {
|
ScopedValue.where(name, "x", () -> {
|
||||||
@ -176,7 +178,8 @@ public class WithScopedValue {
|
|||||||
/**
|
/**
|
||||||
* Test fork when a scoped value is bound after a StructuredTaskScope is created.
|
* 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();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
try (var scope = new StructuredTaskScope<String>()) {
|
try (var scope = new StructuredTaskScope<String>()) {
|
||||||
ScopedValue.where(name, "x", () -> {
|
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.
|
* 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> name1 = ScopedValue.newInstance();
|
||||||
ScopedValue<String> name2 = ScopedValue.newInstance();
|
ScopedValue<String> name2 = ScopedValue.newInstance();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,14 +26,14 @@
|
|||||||
* @summary Basic tests for ThreadFlock
|
* @summary Basic tests for ThreadFlock
|
||||||
* @modules java.base/jdk.internal.misc
|
* @modules java.base/jdk.internal.misc
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng/othervm -DthreadFactory=platform ThreadFlockTest
|
* @run junit/othervm -DthreadFactory=platform ThreadFlockTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test id=virtual
|
* @test id=virtual
|
||||||
* @modules java.base/jdk.internal.misc
|
* @modules java.base/jdk.internal.misc
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run testng/othervm -DthreadFactory=virtual ThreadFlockTest
|
* @run junit/othervm -DthreadFactory=virtual ThreadFlockTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -43,26 +43,23 @@ import java.util.concurrent.*;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import jdk.internal.misc.ThreadFlock;
|
import jdk.internal.misc.ThreadFlock;
|
||||||
|
|
||||||
import org.testng.annotations.AfterClass;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import static org.testng.Assert.*;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class ThreadFlockTest {
|
class ThreadFlockTest {
|
||||||
private ScheduledExecutorService scheduler;
|
private static ScheduledExecutorService scheduler;
|
||||||
private Object[][] threadFactories;
|
private static List<ThreadFactory> threadFactories;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeAll
|
||||||
public void setUp() throws Exception {
|
static void setup() throws Exception {
|
||||||
ThreadFactory factory = (task) -> {
|
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
Thread thread = new Thread(task);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
};
|
|
||||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(factory);
|
|
||||||
|
|
||||||
// thread factories
|
// thread factories
|
||||||
String value = System.getProperty("threadFactory");
|
String value = System.getProperty("threadFactory");
|
||||||
@ -72,35 +69,32 @@ public class ThreadFlockTest {
|
|||||||
if (value == null || value.equals("virtual"))
|
if (value == null || value.equals("virtual"))
|
||||||
list.add(Thread.ofVirtual().factory());
|
list.add(Thread.ofVirtual().factory());
|
||||||
assertTrue(list.size() > 0, "No thread factories for tests");
|
assertTrue(list.size() > 0, "No thread factories for tests");
|
||||||
this.threadFactories = list.stream()
|
threadFactories = list;
|
||||||
.map(f -> new Object[] { f })
|
|
||||||
.toArray(Object[][]::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterAll
|
||||||
public void tearDown() {
|
static void shutdown() {
|
||||||
scheduler.shutdown();
|
scheduler.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataProvider(name = "factories")
|
private static Stream<ThreadFactory> factories() {
|
||||||
public Object[][] factories() {
|
return threadFactories.stream();
|
||||||
return threadFactories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test ThreadFlock::name.
|
* Test ThreadFlock::name.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testName() {
|
void testName() {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
assertEquals(flock.name(), null);
|
assertNull(flock.name());
|
||||||
flock.close();
|
flock.close();
|
||||||
assertEquals(flock.name(), null); // after close
|
assertNull(flock.name()); // after close
|
||||||
}
|
}
|
||||||
try (var flock = ThreadFlock.open("fetcher")) {
|
try (var flock = ThreadFlock.open("fetcher")) {
|
||||||
assertEquals(flock.name(), "fetcher");
|
assertEquals("fetcher", flock.name());
|
||||||
flock.close();
|
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 ThreadFlock::owner.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOwner() {
|
void testOwner() {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
assertTrue(flock.owner() == Thread.currentThread());
|
assertTrue(flock.owner() == Thread.currentThread());
|
||||||
flock.close();
|
flock.close();
|
||||||
@ -120,7 +114,7 @@ public class ThreadFlockTest {
|
|||||||
* Test ThreadFlock::isXXXX methods.
|
* Test ThreadFlock::isXXXX methods.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testState() {
|
void testState() {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
assertFalse(flock.isShutdown());
|
assertFalse(flock.isShutdown());
|
||||||
assertFalse(flock.isClosed());
|
assertFalse(flock.isClosed());
|
||||||
@ -141,8 +135,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test ThreadFlock::threads enumerates all threads.
|
* Test ThreadFlock::threads enumerates all threads.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testThreads(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testThreads(ThreadFactory factory) {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
Runnable awaitLatch = () -> {
|
Runnable awaitLatch = () -> {
|
||||||
@ -166,21 +161,22 @@ public class ThreadFlockTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check thread ThreadFlock::threads enumerates all threads
|
// check thread ThreadFlock::threads enumerates all threads
|
||||||
assertEquals(threads, flock.threads().collect(Collectors.toSet()));
|
assertEquals(flock.threads().collect(Collectors.toSet()), threads);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
latch.countDown(); // release threads
|
latch.countDown(); // release threads
|
||||||
flock.close();
|
flock.close();
|
||||||
}
|
}
|
||||||
assertTrue(flock.threads().count() == 0);
|
assertTrue(flock.threads().count() == 0);
|
||||||
assertTrue(exception.get() == null);
|
assertNull(exception.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test ThreadFlock::containsThread with nested flocks.
|
* Test ThreadFlock::containsThread with nested flocks.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testContainsThread1(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testContainsThread1(ThreadFactory factory) {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
|
|
||||||
@ -222,8 +218,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test ThreadFlock::containsThread with a tree of flocks.
|
* Test ThreadFlock::containsThread with a tree of flocks.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testContainsThread2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testContainsThread2(ThreadFactory factory) throws Exception {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
|
|
||||||
@ -276,8 +273,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test that start causes a thread to execute.
|
* Test that start causes a thread to execute.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStart(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testStart(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
AtomicBoolean executed = new AtomicBoolean();
|
AtomicBoolean executed = new AtomicBoolean();
|
||||||
Thread thread = factory.newThread(() -> executed.set(true));
|
Thread thread = factory.newThread(() -> executed.set(true));
|
||||||
@ -290,44 +288,48 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test that start throws IllegalStateException when shutdown
|
* Test that start throws IllegalStateException when shutdown
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStartAfterShutdown(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testStartAfterShutdown(ThreadFactory factory) {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
flock.shutdown();
|
flock.shutdown();
|
||||||
Thread thread = factory.newThread(() -> { });
|
Thread thread = factory.newThread(() -> { });
|
||||||
expectThrows(IllegalStateException.class, () -> flock.start(thread));
|
assertThrows(IllegalStateException.class, () -> flock.start(thread));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that start throws IllegalStateException when closed
|
* Test that start throws IllegalStateException when closed
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStartAfterClose(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testStartAfterClose(ThreadFactory factory) {
|
||||||
var flock = ThreadFlock.open(null);
|
var flock = ThreadFlock.open(null);
|
||||||
flock.close();;
|
flock.close();;
|
||||||
Thread thread = factory.newThread(() -> { });
|
Thread thread = factory.newThread(() -> { });
|
||||||
expectThrows(IllegalStateException.class, () -> flock.start(thread));
|
assertThrows(IllegalStateException.class, () -> flock.start(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that start throws IllegalThreadStateException when invoked to
|
* Test that start throws IllegalThreadStateException when invoked to
|
||||||
* start a thread that has already started.
|
* start a thread that has already started.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStartAfterStarted(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testStartAfterStarted(ThreadFactory factory) {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
Thread thread = factory.newThread(() -> { });
|
Thread thread = factory.newThread(() -> { });
|
||||||
flock.start(thread);
|
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 start is confined to threads in the flock.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStartConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testStartConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
// thread in flock
|
// thread in flock
|
||||||
testStartConfined(flock, task -> {
|
testStartConfined(flock, task -> {
|
||||||
@ -370,7 +372,7 @@ public class ThreadFlockTest {
|
|||||||
thread.join();
|
thread.join();
|
||||||
Throwable cause = exception.get();
|
Throwable cause = exception.get();
|
||||||
if (flock.containsThread(thread)) {
|
if (flock.containsThread(thread)) {
|
||||||
assertTrue(cause == null);
|
assertNull(cause);
|
||||||
} else {
|
} else {
|
||||||
assertTrue(cause instanceof WrongThreadException);
|
assertTrue(cause instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
@ -380,7 +382,7 @@ public class ThreadFlockTest {
|
|||||||
* Test awaitAll with no threads.
|
* Test awaitAll with no threads.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAwaitAllWithNoThreads() throws Exception {
|
void testAwaitAllWithNoThreads() throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
assertTrue(flock.awaitAll());
|
assertTrue(flock.awaitAll());
|
||||||
assertTrue(flock.awaitAll(Duration.ofSeconds(1)));
|
assertTrue(flock.awaitAll(Duration.ofSeconds(1)));
|
||||||
@ -390,8 +392,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with threads running.
|
* Test awaitAll with threads running.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testAwaitAllWithThreads(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testAwaitAllWithThreads(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
AtomicBoolean done = new AtomicBoolean();
|
AtomicBoolean done = new AtomicBoolean();
|
||||||
Runnable task = () -> {
|
Runnable task = () -> {
|
||||||
@ -410,8 +413,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with timeout, threads finish before timeout expires.
|
* Test awaitAll with timeout, threads finish before timeout expires.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testAwaitAllWithTimeout1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testAwaitAllWithTimeout1(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
Runnable task = () -> {
|
Runnable task = () -> {
|
||||||
try {
|
try {
|
||||||
@ -431,12 +435,15 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with timeout, timeout expires before threads finish.
|
* Test awaitAll with timeout, timeout expires before threads finish.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testAwaitAllWithTimeout2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testAwaitAllWithTimeout2(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Runnable task = () -> {
|
Runnable task = () -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Duration.ofSeconds(30));
|
latch.await();
|
||||||
} catch (InterruptedException e) { }
|
} catch (InterruptedException e) { }
|
||||||
};
|
};
|
||||||
Thread thread = factory.newThread(task);
|
Thread thread = factory.newThread(task);
|
||||||
@ -451,7 +458,7 @@ public class ThreadFlockTest {
|
|||||||
checkDuration(startMillis, 1900, 4000);
|
checkDuration(startMillis, 1900, 4000);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
thread.interrupt();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,12 +466,15 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with timeout many times.
|
* Test awaitAll with timeout many times.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testAwaitAllWithTimeout3(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testAwaitAllWithTimeout3(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Runnable task = () -> {
|
Runnable task = () -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Duration.ofSeconds(30));
|
latch.await();
|
||||||
} catch (InterruptedException e) { }
|
} catch (InterruptedException e) { }
|
||||||
};
|
};
|
||||||
Thread thread = factory.newThread(task);
|
Thread thread = factory.newThread(task);
|
||||||
@ -478,7 +488,7 @@ public class ThreadFlockTest {
|
|||||||
} catch (TimeoutException expected) { }
|
} catch (TimeoutException expected) { }
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
thread.interrupt();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean done = flock.awaitAll();
|
boolean done = flock.awaitAll();
|
||||||
@ -489,12 +499,15 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with a 0 or negative timeout.
|
* Test awaitAll with a 0 or negative timeout.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testAwaitAllWithTimeout4(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testAwaitAllWithTimeout4(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
|
||||||
Runnable task = () -> {
|
Runnable task = () -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Duration.ofSeconds(30));
|
latch.await();
|
||||||
} catch (InterruptedException e) { }
|
} catch (InterruptedException e) { }
|
||||||
};
|
};
|
||||||
Thread thread = factory.newThread(task);
|
Thread thread = factory.newThread(task);
|
||||||
@ -510,7 +523,7 @@ public class ThreadFlockTest {
|
|||||||
fail("awaitAll did not throw");
|
fail("awaitAll did not throw");
|
||||||
} catch (TimeoutException expected) { }
|
} catch (TimeoutException expected) { }
|
||||||
} finally {
|
} finally {
|
||||||
thread.interrupt();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean done = flock.awaitAll();
|
boolean done = flock.awaitAll();
|
||||||
@ -521,8 +534,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with interrupt status set, should interrupt thread.
|
* Test awaitAll with interrupt status set, should interrupt thread.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptAwaitAll1(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testInterruptAwaitAll1(ThreadFactory factory) {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
Runnable awaitLatch = () -> {
|
Runnable awaitLatch = () -> {
|
||||||
@ -568,14 +582,15 @@ public class ThreadFlockTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// thread should not have throw any exception
|
// thread should not have throw any exception
|
||||||
assertTrue(exception.get() == null);
|
assertNull(exception.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test interrupt of awaitAll.
|
* Test interrupt of awaitAll.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptAwaitAll2(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testInterruptAwaitAll2(ThreadFactory factory) {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
Runnable awaitLatch = () -> {
|
Runnable awaitLatch = () -> {
|
||||||
@ -619,14 +634,14 @@ public class ThreadFlockTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// thread should not have throw any exception
|
// thread should not have throw any exception
|
||||||
assertTrue(exception.get() == null);
|
assertNull(exception.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test awaitAll after close.
|
* Test awaitAll after close.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAwaitAfterClose() throws Exception {
|
void testAwaitAfterClose() throws Exception {
|
||||||
var flock = ThreadFlock.open(null);
|
var flock = ThreadFlock.open(null);
|
||||||
flock.close();
|
flock.close();
|
||||||
assertTrue(flock.awaitAll());
|
assertTrue(flock.awaitAll());
|
||||||
@ -636,8 +651,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll is flock confined.
|
* Test awaitAll is flock confined.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testAwaitAllConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testAwaitAllConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
// thread in flock
|
// thread in flock
|
||||||
testAwaitAllConfined(flock, task -> {
|
testAwaitAllConfined(flock, task -> {
|
||||||
@ -676,8 +692,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test awaitAll with the wakeup permit.
|
* Test awaitAll with the wakeup permit.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testWakeupAwaitAll1(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testWakeupAwaitAll1(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
@ -704,8 +721,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Schedule a thread to wakeup the owner waiting in awaitAll.
|
* Schedule a thread to wakeup the owner waiting in awaitAll.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testWakeupAwaitAll2(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testWakeupAwaitAll2(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
@ -737,8 +755,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test wakeup is flock confined.
|
* Test wakeup is flock confined.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testWakeupConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testWakeupConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
// thread in flock
|
// thread in flock
|
||||||
testWakeupConfined(flock, task -> {
|
testWakeupConfined(flock, task -> {
|
||||||
@ -772,7 +791,7 @@ public class ThreadFlockTest {
|
|||||||
thread.join();
|
thread.join();
|
||||||
Throwable cause = exception.get();
|
Throwable cause = exception.get();
|
||||||
if (flock.containsThread(thread)) {
|
if (flock.containsThread(thread)) {
|
||||||
assertTrue(cause == null);
|
assertNull(cause);
|
||||||
} else {
|
} else {
|
||||||
assertTrue(cause instanceof WrongThreadException);
|
assertTrue(cause instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
@ -782,7 +801,7 @@ public class ThreadFlockTest {
|
|||||||
* Test close with no threads running.
|
* Test close with no threads running.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCloseWithNoThreads() {
|
void testCloseWithNoThreads() {
|
||||||
var flock = ThreadFlock.open(null);
|
var flock = ThreadFlock.open(null);
|
||||||
flock.close();
|
flock.close();
|
||||||
assertTrue(flock.isClosed());
|
assertTrue(flock.isClosed());
|
||||||
@ -792,8 +811,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test close with threads running.
|
* Test close with threads running.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCloseWithThreads(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testCloseWithThreads(ThreadFactory factory) {
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
Runnable sleepTask = () -> {
|
Runnable sleepTask = () -> {
|
||||||
try {
|
try {
|
||||||
@ -811,14 +831,14 @@ public class ThreadFlockTest {
|
|||||||
}
|
}
|
||||||
assertTrue(flock.isClosed());
|
assertTrue(flock.isClosed());
|
||||||
assertTrue(flock.threads().count() == 0);
|
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 close after flock is closed.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCloseAfterClose() {
|
void testCloseAfterClose() {
|
||||||
var flock = ThreadFlock.open(null);
|
var flock = ThreadFlock.open(null);
|
||||||
flock.close();
|
flock.close();
|
||||||
assertTrue(flock.isClosed());
|
assertTrue(flock.isClosed());
|
||||||
@ -829,8 +849,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test close is owner confined.
|
* Test close is owner confined.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testCloseConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testCloseConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
// thread in flock
|
// thread in flock
|
||||||
testCloseConfined(flock, task -> {
|
testCloseConfined(flock, task -> {
|
||||||
@ -869,8 +890,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test close with interrupt status set, should not interrupt threads.
|
* Test close with interrupt status set, should not interrupt threads.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptClose1(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testInterruptClose1(ThreadFactory factory) {
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
Runnable sleepTask = () -> {
|
Runnable sleepTask = () -> {
|
||||||
try {
|
try {
|
||||||
@ -886,14 +908,15 @@ public class ThreadFlockTest {
|
|||||||
} finally {
|
} finally {
|
||||||
assertTrue(Thread.interrupted()); // clear interrupt
|
assertTrue(Thread.interrupted()); // clear interrupt
|
||||||
}
|
}
|
||||||
assertTrue(exception.get() == null);
|
assertNull(exception.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test interrupt thread block in close.
|
* Test interrupt thread block in close.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInterruptClose2(ThreadFactory factory) {
|
@MethodSource("factories")
|
||||||
|
void testInterruptClose2(ThreadFactory factory) {
|
||||||
var exception = new AtomicReference<Exception>();
|
var exception = new AtomicReference<Exception>();
|
||||||
Runnable sleepTask = () -> {
|
Runnable sleepTask = () -> {
|
||||||
try {
|
try {
|
||||||
@ -909,14 +932,15 @@ public class ThreadFlockTest {
|
|||||||
} finally {
|
} finally {
|
||||||
assertTrue(Thread.interrupted()); // clear interrupt
|
assertTrue(Thread.interrupted()); // clear interrupt
|
||||||
}
|
}
|
||||||
assertTrue(exception.get() == null);
|
assertNull(exception.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test shutdown is confined to threads in the flock.
|
* Test shutdown is confined to threads in the flock.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testShutdownConfined(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testShutdownConfined(ThreadFactory factory) throws Exception {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
// thread in flock
|
// thread in flock
|
||||||
testShutdownConfined(flock, task -> {
|
testShutdownConfined(flock, task -> {
|
||||||
@ -958,7 +982,7 @@ public class ThreadFlockTest {
|
|||||||
thread.join();
|
thread.join();
|
||||||
Throwable cause = exception.get();
|
Throwable cause = exception.get();
|
||||||
if (flock.containsThread(thread)) {
|
if (flock.containsThread(thread)) {
|
||||||
assertTrue(cause == null);
|
assertNull(cause);
|
||||||
} else {
|
} else {
|
||||||
assertTrue(cause instanceof WrongThreadException);
|
assertTrue(cause instanceof WrongThreadException);
|
||||||
}
|
}
|
||||||
@ -968,7 +992,7 @@ public class ThreadFlockTest {
|
|||||||
* Test that closing an enclosing thread flock closes a nested thread flocks.
|
* Test that closing an enclosing thread flock closes a nested thread flocks.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStructureViolation() {
|
void testStructureViolation() {
|
||||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||||
try (var flock2 = ThreadFlock.open("flock2")) {
|
try (var flock2 = ThreadFlock.open("flock2")) {
|
||||||
try {
|
try {
|
||||||
@ -986,8 +1010,9 @@ public class ThreadFlockTest {
|
|||||||
/**
|
/**
|
||||||
* Test Thread exiting with an open flock. The exiting thread should close the flock.
|
* Test Thread exiting with an open flock. The exiting thread should close the flock.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testThreadExitWithOpenFlock(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testThreadExitWithOpenFlock(ThreadFactory factory) throws Exception {
|
||||||
var flockRef = new AtomicReference<ThreadFlock>();
|
var flockRef = new AtomicReference<ThreadFlock>();
|
||||||
var childRef = new AtomicReference<Thread>();
|
var childRef = new AtomicReference<Thread>();
|
||||||
|
|
||||||
@ -1017,7 +1042,7 @@ public class ThreadFlockTest {
|
|||||||
* Test toString includes the flock name.
|
* Test toString includes the flock name.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testToString() {
|
void testToString() {
|
||||||
try (var flock = ThreadFlock.open("xxxx")) {
|
try (var flock = ThreadFlock.open("xxxx")) {
|
||||||
assertTrue(flock.toString().contains("xxx"));
|
assertTrue(flock.toString().contains("xxx"));
|
||||||
}
|
}
|
||||||
@ -1027,11 +1052,11 @@ public class ThreadFlockTest {
|
|||||||
* Test for NullPointerException.
|
* Test for NullPointerException.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNulls() {
|
void testNulls() {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
expectThrows(NullPointerException.class, () -> flock.start(null));
|
assertThrows(NullPointerException.class, () -> flock.start(null));
|
||||||
expectThrows(NullPointerException.class, () -> flock.awaitAll(null));
|
assertThrows(NullPointerException.class, () -> flock.awaitAll(null));
|
||||||
expectThrows(NullPointerException.class, () -> flock.containsThread(null));
|
assertThrows(NullPointerException.class, () -> flock.containsThread(null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,38 +27,33 @@
|
|||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules java.base/jdk.internal.misc
|
* @modules java.base/jdk.internal.misc
|
||||||
* @modules jdk.incubator.concurrent
|
* @modules jdk.incubator.concurrent
|
||||||
* @run testng WithScopedValue
|
* @run junit WithScopedValue
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.internal.misc.ThreadFlock;
|
import jdk.internal.misc.ThreadFlock;
|
||||||
import jdk.incubator.concurrent.ScopedValue;
|
import jdk.incubator.concurrent.ScopedValue;
|
||||||
import jdk.incubator.concurrent.StructureViolationException;
|
import jdk.incubator.concurrent.StructureViolationException;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.testng.annotations.DataProvider;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testng.annotations.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import static org.testng.Assert.*;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@Test
|
class WithScopedValue {
|
||||||
public class WithScopedValue {
|
|
||||||
|
|
||||||
@DataProvider(name = "factories")
|
private static Stream<ThreadFactory> factories() {
|
||||||
public Object[][] factories() {
|
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
|
||||||
var defaultThreadFactory = Executors.defaultThreadFactory();
|
|
||||||
var virtualThreadFactory = Thread.ofVirtual().factory();
|
|
||||||
return new Object[][]{
|
|
||||||
{ defaultThreadFactory, },
|
|
||||||
{ virtualThreadFactory, },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test inheritance of a scoped value.
|
* Test inheritance of a scoped value.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testInheritsScopedValue(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testInheritsScopedValue(ThreadFactory factory) throws Exception {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
String value = ScopedValue.where(name, "duke", () -> {
|
String value = ScopedValue.where(name, "duke", () -> {
|
||||||
var result = new AtomicReference<String>();
|
var result = new AtomicReference<String>();
|
||||||
@ -71,13 +66,14 @@ public class WithScopedValue {
|
|||||||
}
|
}
|
||||||
return result.get();
|
return result.get();
|
||||||
});
|
});
|
||||||
assertEquals(value, "duke");
|
assertEquals("duke", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test exiting a dynamic scope with open thread flocks.
|
* Test exiting a dynamic scope with open thread flocks.
|
||||||
*/
|
*/
|
||||||
public void testStructureViolation1() {
|
@Test
|
||||||
|
void testStructureViolation1() {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
class Box {
|
class Box {
|
||||||
ThreadFlock flock1;
|
ThreadFlock flock1;
|
||||||
@ -99,7 +95,8 @@ public class WithScopedValue {
|
|||||||
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
||||||
* flocks. This test closes enclosing flock1.
|
* flocks. This test closes enclosing flock1.
|
||||||
*/
|
*/
|
||||||
public void testStructureViolation2() {
|
@Test
|
||||||
|
void testStructureViolation2() {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||||
ScopedValue.where(name, "x1", () -> {
|
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
|
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
||||||
* flocks. This test closes enclosing flock2.
|
* flocks. This test closes enclosing flock2.
|
||||||
*/
|
*/
|
||||||
public void testStructureViolation3() {
|
@Test
|
||||||
|
void testStructureViolation3() {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||||
ScopedValue.where(name, "x1", () -> {
|
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
|
* Test closing a thread flock while in a dynamic scope and with enclosing thread
|
||||||
* flocks. This test closes enclosing flock3.
|
* flocks. This test closes enclosing flock3.
|
||||||
*/
|
*/
|
||||||
public void testStructureViolation4() {
|
@Test
|
||||||
|
void testStructureViolation4() {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
try (var flock1 = ThreadFlock.open("flock1")) {
|
try (var flock1 = ThreadFlock.open("flock1")) {
|
||||||
ScopedValue.where(name, "x1", () -> {
|
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 start when a scoped value is bound after a thread flock is created.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStructureViolation5(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testStructureViolation5(ThreadFactory factory) throws Exception {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
Thread thread = factory.newThread(() -> { });
|
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 start when a scoped value is re-bound after a thread flock is created.
|
||||||
*/
|
*/
|
||||||
@Test(dataProvider = "factories")
|
@ParameterizedTest
|
||||||
public void testStructureViolation6(ThreadFactory factory) throws Exception {
|
@MethodSource("factories")
|
||||||
|
void testStructureViolation6(ThreadFactory factory) throws Exception {
|
||||||
ScopedValue<String> name = ScopedValue.newInstance();
|
ScopedValue<String> name = ScopedValue.newInstance();
|
||||||
ScopedValue.where(name, "duke", () -> {
|
ScopedValue.where(name, "duke", () -> {
|
||||||
try (var flock = ThreadFlock.open(null)) {
|
try (var flock = ThreadFlock.open(null)) {
|
||||||
ScopedValue.where(name, "duchess", () -> {
|
ScopedValue.where(name, "duchess", () -> {
|
||||||
Thread thread = factory.newThread(() -> { });
|
Thread thread = factory.newThread(() -> { });
|
||||||
expectThrows(StructureViolationException.class, () -> flock.start(thread));
|
assertThrows(StructureViolationException.class, () -> flock.start(thread));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user