@@ -433,7 +433,7 @@ final class ServiceGroupTests: XCTestCase {
433
433
]
434
434
)
435
435
436
- await withThrowingTaskGroup ( of: Void . self) { group in
436
+ try await withThrowingTaskGroup ( of: Void . self) { group in
437
437
group. addTask {
438
438
try await serviceGroup. run ( )
439
439
}
@@ -474,6 +474,71 @@ final class ServiceGroupTests: XCTestCase {
474
474
475
475
// Let's exit from the first service
476
476
await service1. resumeRunContinuation ( with: . success( ( ) ) )
477
+
478
+ try await XCTAsyncAssertThrowsError ( await group. next ( ) ) {
479
+ XCTAssertTrue ( $0 is ExampleError )
480
+ }
481
+ }
482
+ }
483
+
484
+ func testRun_whenServiceThrows_andShutdownGracefully_andOtherServiceThrows( ) async throws {
485
+ let service1 = MockService ( description: " Service1 " )
486
+ let service2 = MockService ( description: " Service2 " )
487
+ let service3 = MockService ( description: " Service3 " )
488
+ let serviceGroup = self . makeServiceGroup (
489
+ services: [
490
+ . init( service: service1) ,
491
+ . init( service: service2, failureTerminationBehavior: . gracefullyShutdownGroup) ,
492
+ . init( service: service3) ,
493
+ ]
494
+ )
495
+
496
+ try await withThrowingTaskGroup ( of: Void . self) { group in
497
+ group. addTask {
498
+ try await serviceGroup. run ( )
499
+ }
500
+
501
+ var eventIterator1 = service1. events. makeAsyncIterator ( )
502
+ await XCTAsyncAssertEqual ( await eventIterator1. next ( ) , . run)
503
+
504
+ var eventIterator2 = service2. events. makeAsyncIterator ( )
505
+ await XCTAsyncAssertEqual ( await eventIterator2. next ( ) , . run)
506
+
507
+ var eventIterator3 = service3. events. makeAsyncIterator ( )
508
+ await XCTAsyncAssertEqual ( await eventIterator3. next ( ) , . run)
509
+
510
+ await service2. resumeRunContinuation ( with: . failure( ExampleError ( ) ) )
511
+
512
+ // The last service should receive the shutdown signal first
513
+ await XCTAsyncAssertEqual ( await eventIterator3. next ( ) , . shutdownGracefully)
514
+
515
+ // Waiting to see that all two are still running
516
+ service1. sendPing ( )
517
+ service3. sendPing ( )
518
+ await XCTAsyncAssertEqual ( await eventIterator1. next ( ) , . runPing)
519
+ await XCTAsyncAssertEqual ( await eventIterator3. next ( ) , . runPing)
520
+
521
+ // Let's exit from the last service
522
+ await service3. resumeRunContinuation ( with: . success( ( ) ) )
523
+
524
+ // Waiting to see that the remaining is still running
525
+ service1. sendPing ( )
526
+ await XCTAsyncAssertEqual ( await eventIterator1. next ( ) , . runPing)
527
+
528
+ // The first service should now receive the signal
529
+ await XCTAsyncAssertEqual ( await eventIterator1. next ( ) , . shutdownGracefully)
530
+
531
+ // Waiting to see that the one remaining are still running
532
+ service1. sendPing ( )
533
+ await XCTAsyncAssertEqual ( await eventIterator1. next ( ) , . runPing)
534
+
535
+ // Let's throw from this service as well
536
+ struct OtherError : Error { }
537
+ await service1. resumeRunContinuation ( with: . failure( OtherError ( ) ) )
538
+
539
+ try await XCTAsyncAssertThrowsError ( await group. next ( ) ) {
540
+ XCTAssertTrue ( $0 is ExampleError )
541
+ }
477
542
}
478
543
}
479
544
0 commit comments