From 8e4f11a341eb21160fd52647b7187da7c53e1bb8 Mon Sep 17 00:00:00 2001 From: Simba Zhang Date: Tue, 3 Nov 2026 13:30:32 -0800 Subject: [PATCH] test: use Task.sleep(nanoseconds:) so the suite runs in Release on Swift 6.2 On Swift 6.2.4 (Xcode 26.3) in a Release build, any Task.sleep(for:) call in the SwiftLMTests bundle aborts the XCTest process with "freed pointer was not the last allocation" (swift_task_dealloc, called from the specialized Task<>.sleep(for:tolerance:clock:)). It needs neither cancellation nor any SwiftLM code: a test containing only `try? await Task.sleep(for: .milliseconds(10))` crashes, while the nanoseconds overload does not. Swift 6.4 is not affected. Switch the test sleeps to Task.sleep(nanoseconds:) with the same durations. ClientDisconnectTests (7) and the whole SwiftLMTests bundle (464) pass in Release on Swift 6.2.4. Co-Authored-By: Claude Sonnet 5.5 --- tests/SwiftLMTests/ClientDisconnectTests.swift | 8 ++++---- tests/SwiftLMTests/DFlashStreamBridgeTests.swift | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/SwiftLMTests/ClientDisconnectTests.swift b/tests/SwiftLMTests/ClientDisconnectTests.swift index 9612b19e..fd281182 100644 --- a/tests/SwiftLMTests/ClientDisconnectTests.swift +++ b/tests/SwiftLMTests/ClientDisconnectTests.swift @@ -90,7 +90,7 @@ final class ClientDisconnectTests: XCTestCase { while !Task.isCancelled { if case .terminated = continuation.yield(.chunk("x", tokenId: token)) { return } token += 1 - try? await Task.sleep(for: .milliseconds(2)) + try? await Task.sleep(nanoseconds: 2_000_000) } } return (stream, producer) @@ -119,7 +119,7 @@ final class ClientDisconnectTests: XCTestCase { } } // Let it consume a few chunks, then the client goes away. - try await Task.sleep(for: .milliseconds(40)) + try await Task.sleep(nanoseconds: 40_000_000) channel.pipeline.fireUserInboundEventTriggered(ChannelEvent.inputClosed) _ = try await response.value @@ -129,7 +129,7 @@ final class ClientDisconnectTests: XCTestCase { let released = Task { await semaphore.wait(); return true } let reacquired = await withTaskGroup(of: Bool.self) { group -> Bool in group.addTask { await released.value } - group.addTask { try? await Task.sleep(for: .seconds(2)); return false } + group.addTask { try? await Task.sleep(nanoseconds: 2_000_000_000); return false } let first = await group.next() ?? false group.cancelAll() return first @@ -174,7 +174,7 @@ final class ClientDisconnectTests: XCTestCase { func testDeferredCancellationCancelsATaskAttachedAfterTheRequest() async { let cancellation = DeferredCancellation() cancellation.cancel() - let task = Task { try await Task.sleep(for: .seconds(10)) } + let task = Task { try await Task.sleep(nanoseconds: 10_000_000_000) } cancellation.attach(task) if case .success = await task.result { XCTFail("the task should have been cancelled") } } diff --git a/tests/SwiftLMTests/DFlashStreamBridgeTests.swift b/tests/SwiftLMTests/DFlashStreamBridgeTests.swift index 2f6daf0e..55a3279f 100644 --- a/tests/SwiftLMTests/DFlashStreamBridgeTests.swift +++ b/tests/SwiftLMTests/DFlashStreamBridgeTests.swift @@ -47,7 +47,7 @@ final class DFlashStreamBridgeTests: XCTestCase { while !Task.isCancelled { counter += 1 continuation.yield(.token(tokenID: counter, generatedTokens: counter, acceptanceRatio: 0, cyclesCompleted: counter)) - try? await Task.sleep(for: .milliseconds(5)) + try? await Task.sleep(nanoseconds: 5_000_000) } continuation.finish() }