Skip to content

Commit 24983b0

Browse files
committed
Tweak tests
1 parent 1be1455 commit 24983b0

9 files changed

Lines changed: 210 additions & 190 deletions

src/test/groovy/org/apache/groovy/runtime/async/AsyncConcurrencyTest.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test
2323
import org.junit.jupiter.api.Timeout
2424
import org.junit.jupiter.api.DisplayName
2525

26+
import java.io.IOException
2627
import java.util.concurrent.CountDownLatch
2728
import java.util.concurrent.CyclicBarrier
2829
import java.util.concurrent.TimeUnit
@@ -503,13 +504,13 @@ class AsyncConcurrencyTest {
503504
void testMoveNextPropagatesExceptionViaSneakyThrow() {
504505
def gen = new AsyncStreamGenerator<Integer>()
505506
Thread.start {
506-
gen.error(new java.io.IOException("disk fail"))
507+
gen.error(new IOException("disk fail"))
507508
}
508509

509510
try {
510511
gen.moveNext().get()
511512
assert false : "Expected IOException"
512-
} catch (java.io.IOException e) {
513+
} catch (IOException e) {
513514
assert e.message == "disk fail"
514515
}
515516
}

src/test/groovy/org/codehaus/groovy/transform/AsyncApiTest.groovy

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.codehaus.groovy.transform
2020

21+
import groovy.concurrent.AsyncScope
2122
import groovy.concurrent.AsyncStream
2223
import groovy.concurrent.AwaitResult
2324
import groovy.concurrent.Awaitable
@@ -29,17 +30,24 @@ import org.apache.groovy.runtime.async.GroovyPromise
2930
import org.junit.jupiter.api.AfterEach
3031
import org.junit.jupiter.api.Test
3132

33+
import java.lang.reflect.InvocationTargetException
3234
import java.util.concurrent.Callable
3335
import java.util.concurrent.CancellationException
3436
import java.util.concurrent.CompletableFuture
3537
import java.util.concurrent.CompletionException
3638
import java.util.concurrent.CompletionStage
39+
import java.util.concurrent.ConcurrentLinkedQueue
3740
import java.util.concurrent.CountDownLatch
41+
import java.util.concurrent.CyclicBarrier
3842
import java.util.concurrent.ExecutionException
43+
import java.util.concurrent.Executor
44+
import java.util.concurrent.Executors
3945
import java.util.concurrent.Flow
46+
import java.util.concurrent.Future
4047
import java.util.concurrent.FutureTask
4148
import java.util.concurrent.SubmissionPublisher
4249
import java.util.concurrent.TimeUnit
50+
import java.util.concurrent.TimeoutException
4351
import java.util.concurrent.atomic.AtomicBoolean
4452
import java.util.concurrent.atomic.AtomicInteger
4553
import java.util.concurrent.atomic.AtomicReference
@@ -150,15 +158,15 @@ class AsyncApiTest {
150158
void testAwaitPlainFutureSuccess() {
151159
def ft = new FutureTask<String>({ 'hello' } as Callable<String>)
152160
ft.run()
153-
assert AsyncSupport.await((java.util.concurrent.Future<String>) ft) == 'hello'
161+
assert AsyncSupport.await((Future<String>) ft) == 'hello'
154162
}
155163

156164
@Test
157165
void testAwaitPlainFutureFailed() {
158166
def ft = new FutureTask<String>({ throw new IOException('future-error') } as Callable<String>)
159167
ft.run()
160168
try {
161-
AsyncSupport.await((java.util.concurrent.Future<String>) ft)
169+
AsyncSupport.await((Future<String>) ft)
162170
assert false
163171
} catch (IOException e) {
164172
assert e.message == 'future-error'
@@ -170,7 +178,7 @@ class AsyncApiTest {
170178
def ft = new FutureTask<String>({ 'never' } as Callable<String>)
171179
ft.cancel(true)
172180
try {
173-
AsyncSupport.await((java.util.concurrent.Future<String>) ft)
181+
AsyncSupport.await((Future<String>) ft)
174182
assert false
175183
} catch (CancellationException ignored) {}
176184
}
@@ -185,7 +193,7 @@ class AsyncApiTest {
185193
// Don't run it — it will block on get(), and we set interrupt
186194
Thread.currentThread().interrupt()
187195
try {
188-
AsyncSupport.await((java.util.concurrent.Future<String>) ft)
196+
AsyncSupport.await((Future<String>) ft)
189197
assert false
190198
} catch (CancellationException e) {
191199
assert e.message.contains('Interrupted')
@@ -199,7 +207,7 @@ class AsyncApiTest {
199207
void testAwaitFutureWithCompletableFuture() {
200208
// Pass CF as Future to hit line 245: instanceof CompletableFuture shortcut
201209
def cf = CompletableFuture.completedFuture('via-cf')
202-
assert AsyncSupport.await((java.util.concurrent.Future<String>) cf) == 'via-cf'
210+
assert AsyncSupport.await((Future<String>) cf) == 'via-cf'
203211
}
204212

205213
@Test
@@ -297,7 +305,7 @@ class AsyncApiTest {
297305
def ft = new FutureTask<String>({ throw new ArithmeticException('div-zero') } as Callable<String>)
298306
ft.run()
299307
try {
300-
AsyncSupport.await((java.util.concurrent.Future<String>) ft)
308+
AsyncSupport.await((Future<String>) ft)
301309
assert false
302310
} catch (ArithmeticException e) {
303311
assert e.message == 'div-zero'
@@ -1042,7 +1050,7 @@ class AsyncApiTest {
10421050
void testCloseInterruptsBlockedProducerThread() {
10431051
def gen = new AsyncStreamGenerator<Integer>()
10441052
def producerExit = new CompletableFuture<String>()
1045-
def producerBlocked = new java.util.concurrent.CountDownLatch(1)
1053+
def producerBlocked = new CountDownLatch(1)
10461054

10471055
def producerThread = Thread.start {
10481056
gen.attachProducer(Thread.currentThread())
@@ -1094,7 +1102,7 @@ class AsyncApiTest {
10941102
void testCloseInterruptsBlockedConsumerThread() {
10951103
def gen = new AsyncStreamGenerator<Integer>()
10961104
def consumerResult = new CompletableFuture<Boolean>()
1097-
def consumerBlocked = new java.util.concurrent.CountDownLatch(1)
1105+
def consumerBlocked = new CountDownLatch(1)
10981106

10991107
// Start a consumer thread that will block in moveNext()
11001108
// because no producer will ever yield anything
@@ -1367,7 +1375,7 @@ class AsyncApiTest {
13671375
def toAwaitable = builtInClass.getDeclaredMethod('toAwaitable', Object)
13681376
toAwaitable.accessible = true
13691377

1370-
def ex = shouldFail(java.lang.reflect.InvocationTargetException) {
1378+
def ex = shouldFail(InvocationTargetException) {
13711379
toAwaitable.invoke(adapter, new Object())
13721380
}
13731381
assert ex.cause instanceof IllegalArgumentException
@@ -1384,7 +1392,7 @@ class AsyncApiTest {
13841392
def toAsyncStream = builtInClass.getDeclaredMethod('toAsyncStream', Object)
13851393
toAsyncStream.accessible = true
13861394

1387-
def ex = shouldFail(java.lang.reflect.InvocationTargetException) {
1395+
def ex = shouldFail(InvocationTargetException) {
13881396
toAsyncStream.invoke(adapter, 123)
13891397
}
13901398
assert ex.cause instanceof IllegalArgumentException
@@ -2040,13 +2048,13 @@ class AsyncApiTest {
20402048
assert false
20412049
} catch (Exception e) {
20422050
// IOException wrapped in ExecutionException, then unwrapped
2043-
assert e instanceof IOException || e instanceof java.util.concurrent.ExecutionException
2051+
assert e instanceof IOException || e instanceof ExecutionException
20442052
}
20452053
}
20462054

20472055
@Test
20482056
void testFutureAdapterInterruptedFutureMapsToCancellation() {
2049-
def interruptedFuture = new java.util.concurrent.Future<String>() {
2057+
def interruptedFuture = new Future<String>() {
20502058
boolean cancel(boolean mayInterruptIfRunning) { false }
20512059
boolean isCancelled() { false }
20522060
boolean isDone() { true }
@@ -2062,7 +2070,7 @@ class AsyncApiTest {
20622070

20632071
@Test
20642072
void testFutureAdapterCancellationExceptionIsPropagated() {
2065-
def cancelledFuture = new java.util.concurrent.Future<String>() {
2073+
def cancelledFuture = new Future<String>() {
20662074
boolean cancel(boolean mayInterruptIfRunning) { false }
20672075
boolean isCancelled() { true }
20682076
boolean isDone() { true }
@@ -2078,7 +2086,7 @@ class AsyncApiTest {
20782086

20792087
@Test
20802088
void testFutureAdapterUnexpectedExceptionIsPropagated() {
2081-
def brokenFuture = new java.util.concurrent.Future<String>() {
2089+
def brokenFuture = new Future<String>() {
20822090
boolean cancel(boolean mayInterruptIfRunning) { false }
20832091
boolean isCancelled() { false }
20842092
boolean isDone() { true }
@@ -2113,7 +2121,7 @@ class AsyncApiTest {
21132121
void testGetSetExecutor() {
21142122
def original = AsyncSupport.getExecutor()
21152123
assert original != null
2116-
def custom = { Runnable r -> r.run() } as java.util.concurrent.Executor
2124+
def custom = { Runnable r -> r.run() } as Executor
21172125
AsyncSupport.setExecutor(custom)
21182126
assert AsyncSupport.getExecutor().is(custom)
21192127
AsyncSupport.setExecutor(null) // reset
@@ -2402,7 +2410,7 @@ class AsyncApiTest {
24022410
def ex = shouldFail(ExecutionException) {
24032411
withTimeout.get()
24042412
}
2405-
assert ex.cause instanceof java.util.concurrent.TimeoutException
2413+
assert ex.cause instanceof TimeoutException
24062414
}
24072415

24082416
@Test
@@ -2413,7 +2421,7 @@ class AsyncApiTest {
24132421
def ex = shouldFail(ExecutionException) {
24142422
withTimeout.get()
24152423
}
2416-
assert ex.cause instanceof java.util.concurrent.TimeoutException
2424+
assert ex.cause instanceof TimeoutException
24172425
}
24182426

24192427
@Test
@@ -2469,7 +2477,7 @@ class AsyncApiTest {
24692477
void testGroovyPromiseGetWithTimeoutExpired() {
24702478
def cf = new CompletableFuture<>()
24712479
def promise = GroovyPromise.of(cf)
2472-
shouldFail(java.util.concurrent.TimeoutException) {
2480+
shouldFail(TimeoutException) {
24732481
promise.get(50, TimeUnit.MILLISECONDS)
24742482
}
24752483
}
@@ -2690,7 +2698,7 @@ class AsyncApiTest {
26902698
def ex = shouldFail(ExecutionException) {
26912699
aw.get()
26922700
}
2693-
assert ex.cause instanceof java.util.concurrent.TimeoutException
2701+
assert ex.cause instanceof TimeoutException
26942702
}
26952703

26962704
@Test
@@ -2716,7 +2724,7 @@ class AsyncApiTest {
27162724
def original = Awaitable.getExecutor()
27172725
assert original != null
27182726
try {
2719-
def custom = java.util.concurrent.Executors.newSingleThreadExecutor()
2727+
def custom = Executors.newSingleThreadExecutor()
27202728
Awaitable.setExecutor(custom)
27212729
assert Awaitable.getExecutor().is(custom)
27222730
custom.shutdown()
@@ -3169,7 +3177,7 @@ class AsyncApiTest {
31693177
void testAbstractAsyncStreamGeneratorBeforeTakeRejectsSecondConsumer() {
31703178
// AsyncStreamGenerator.beforeTake() enforces single-consumer semantics
31713179
def gen = new AsyncStreamGenerator<Integer>()
3172-
def latch = new java.util.concurrent.CountDownLatch(1)
3180+
def latch = new CountDownLatch(1)
31733181
def error = new CompletableFuture<Throwable>()
31743182

31753183
CompletableFuture.runAsync {
@@ -3344,8 +3352,8 @@ class AsyncApiTest {
33443352
void testAdapterCacheConcurrentAccess() {
33453353
// Hammer the cache from multiple threads to verify thread safety
33463354
int threadCount = 32
3347-
def barrier = new java.util.concurrent.CyclicBarrier(threadCount)
3348-
def errors = new java.util.concurrent.ConcurrentLinkedQueue<Throwable>()
3355+
def barrier = new CyclicBarrier(threadCount)
3356+
def errors = new ConcurrentLinkedQueue<Throwable>()
33493357
def threads = (1..threadCount).collect { idx ->
33503358
Thread.start {
33513359
try {
@@ -3442,7 +3450,7 @@ class AsyncApiTest {
34423450

34433451
@Test
34443452
void testAsyncScopeBasicUsage() {
3445-
def result = groovy.concurrent.AsyncScope.withScope { scope ->
3453+
def result = AsyncScope.withScope { scope ->
34463454
def a = scope.async { 10 }
34473455
def b = scope.async { 20 }
34483456
return a.get() + b.get()
@@ -3456,7 +3464,7 @@ class AsyncApiTest {
34563464
def error = null
34573465

34583466
try {
3459-
groovy.concurrent.AsyncScope.withScope { scope ->
3467+
AsyncScope.withScope { scope ->
34603468
// Slow task
34613469
scope.async {
34623470
try {
@@ -3484,7 +3492,7 @@ class AsyncApiTest {
34843492
@Test
34853493
void testAsyncScopeAggregatesSuppressedExceptions() {
34863494
try {
3487-
groovy.concurrent.AsyncScope.withScope { scope ->
3495+
AsyncScope.withScope { scope ->
34883496
scope.async { throw new IllegalArgumentException("err1") }
34893497
scope.async { throw new IllegalStateException("err2") }
34903498
Thread.sleep(200) // Let both fail
@@ -3502,7 +3510,7 @@ class AsyncApiTest {
35023510

35033511
@Test
35043512
void testAsyncScopeRejectsAfterClose() {
3505-
def scope = new groovy.concurrent.AsyncScope()
3513+
def scope = new AsyncScope()
35063514
scope.close()
35073515
shouldFail(IllegalStateException) {
35083516
scope.async { 42 }
@@ -3511,7 +3519,7 @@ class AsyncApiTest {
35113519

35123520
@Test
35133521
void testAsyncScopeChildCount() {
3514-
groovy.concurrent.AsyncScope.withScope { scope ->
3522+
AsyncScope.withScope { scope ->
35153523
assert scope.childCount == 0
35163524
scope.async { 1 }
35173525
scope.async { 2 }
@@ -3524,7 +3532,7 @@ class AsyncApiTest {
35243532
@Test
35253533
void testAsyncScopeHighConcurrency() {
35263534
int taskCount = 10_000
3527-
def result = groovy.concurrent.AsyncScope.withScope { scope ->
3535+
def result = AsyncScope.withScope { scope ->
35283536
def tasks = (1..taskCount).collect { n ->
35293537
scope.async { n }
35303538
}
@@ -3539,7 +3547,7 @@ class AsyncApiTest {
35393547

35403548
@Test
35413549
void testAsyncScopeCloseIsIdempotent() {
3542-
def scope = new groovy.concurrent.AsyncScope()
3550+
def scope = new AsyncScope()
35433551
def task = scope.async { 42 }
35443552
assert task.get() == 42
35453553
scope.close()

src/test/groovy/org/codehaus/groovy/transform/AsyncAwaitSyntaxTest.groovy

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,7 @@ class AsyncAwaitSyntaxTest {
14211421
void testAsyncWithCustomExecutor() {
14221422
assertScript '''
14231423
import java.util.concurrent.Executors
1424+
import groovy.concurrent.Awaitable
14241425
14251426
class Svc {
14261427
static executor = Executors.newFixedThreadPool(2)
@@ -1429,12 +1430,12 @@ class AsyncAwaitSyntaxTest {
14291430
}
14301431
}
14311432
1432-
groovy.concurrent.Awaitable.setExecutor(Svc.executor)
1433+
Awaitable.setExecutor(Svc.executor)
14331434
try {
14341435
def name = new Svc().threadInfo().get()
14351436
assert name.contains("pool")
14361437
} finally {
1437-
groovy.concurrent.Awaitable.setExecutor(null)
1438+
Awaitable.setExecutor(null)
14381439
Svc.executor.shutdown()
14391440
}
14401441
'''
@@ -1643,29 +1644,6 @@ class AsyncAwaitSyntaxTest {
16431644
// 6. Error cases — syntax and semantic rejections
16441645
// =====================================================================
16451646

1646-
@Test
1647-
void testAsyncOnAbstractMethodFails() {
1648-
def err = shouldFail CompilationFailedException, '''
1649-
abstract class Svc {
1650-
@groovy.transform.Async
1651-
abstract def compute()
1652-
}
1653-
'''
1654-
assert err.message.contains('cannot be applied to abstract method')
1655-
}
1656-
1657-
@Test
1658-
void testAsyncOnAwaitableReturnTypeFails() {
1659-
def err = shouldFail CompilationFailedException, '''
1660-
import groovy.concurrent.Awaitable
1661-
class Svc {
1662-
@groovy.transform.Async
1663-
Awaitable<String> compute() { Awaitable.of("x") }
1664-
}
1665-
'''
1666-
assert err.message.contains('already returns an async type')
1667-
}
1668-
16691647
@Test
16701648
void testForAwaitWithTraditionalForSyntaxFails() {
16711649
def err = shouldFail CompilationFailedException, '''
@@ -2471,9 +2449,11 @@ class AsyncAwaitSyntaxTest {
24712449
@Test
24722450
void testYieldReturnOutsideAsyncMethodFails() {
24732451
assertScript '''
2452+
import org.apache.groovy.runtime.async.AsyncSupport
2453+
24742454
// yield return outside async method should fail at runtime
24752455
try {
2476-
org.apache.groovy.runtime.async.AsyncSupport.yieldReturn("oops")
2456+
AsyncSupport.yieldReturn("oops")
24772457
assert false : "expected exception"
24782458
} catch (IllegalStateException e) {
24792459
assert e.message.contains("yield return")

0 commit comments

Comments
 (0)