Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 35 additions & 26 deletions App/Tests/CLISocketServerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ struct CLISocketServerTests {
))
#expect(request.count > 32 * 1024 * 1024)
#expect(request.count <= WorkflowSizeLimits.transportFrame)
let response: Data = try await withCheckedThrowingContinuation { continuation in
DispatchQueue.global(qos: .userInitiated).async {
continuation.resume(with: Result { try Self.send(requestData: request, socketPath: socketPath) })
}
let response = try await Self.runBlocking {
try Self.send(requestData: request, socketPath: socketPath)
}
#expect(try JSONDecoder().decode(CommandResponse.self, from: response).command == "workflow")
}
Expand Down Expand Up @@ -173,21 +171,21 @@ struct CLISocketServerTests {
)
)

try await Task.detached {
try await Self.runBlocking {
try Self.sendAndCloseAfterAcceptance(
requestData: requestData,
socketPath: socketPath,
accepted: accepted,
closed: closed
)
}.value
let closedBeforeRouting = await Task.detached {
}
let closedBeforeRouting = try await Self.runBlocking {
peerClosed.wait(timeout: .now() + 10)
}.value
}
#expect(closedBeforeRouting)
let connectionRejected = await Task.detached {
let connectionRejected = try await Self.runBlocking {
rejected.wait(timeout: .now() + 10)
}.value
}

#expect(connectionRejected)
#expect(recordedSignal == nil)
Expand Down Expand Up @@ -334,7 +332,7 @@ struct CLISocketServerTests {
let requestData = try JSONEncoder().encode(
CommandEnvelope(output: .json, command: .agentsHook(input))
)
let sendTask = Task.detached {
try await Self.runBlocking {
try Self.sendAndCloseAfterAcceptance(
requestData: requestData,
socketPath: socketPath,
Expand All @@ -343,14 +341,13 @@ struct CLISocketServerTests {
)
}

try await sendTask.value
let closedBeforeRouting = await Task.detached {
let closedBeforeRouting = try await Self.runBlocking {
peerClosed.wait(timeout: .now() + 10)
}.value
}
#expect(closedBeforeRouting)
let didRoute = await Task.detached {
let didRoute = try await Self.runBlocking {
routeRecorded.wait(timeout: .now() + 10)
}.value
}
#expect(didRoute)
#expect(recordedInput == input)
}
Expand Down Expand Up @@ -381,22 +378,22 @@ struct CLISocketServerTests {
)
let requestData = try JSONEncoder().encode(envelope)

try await Task.detached {
try await Self.runBlocking {
try Self.sendAndCloseAfterAcceptance(
requestData: requestData,
socketPath: socketPath,
accepted: accepted,
closed: closed
)
}.value
}

let closedBeforeRouting = await Task.detached {
let closedBeforeRouting = try await Self.runBlocking {
peerClosed.wait(timeout: .now() + 10)
}.value
}
#expect(closedBeforeRouting)
let cancellationObserved = await Task.detached {
let cancellationObserved = try await Self.runBlocking {
probe.waitForCancellation(timeout: .now() + 10)
}.value
}
#expect(cancellationObserved)
#expect(probe.wasCancelled)
}
Expand All @@ -414,9 +411,9 @@ struct CLISocketServerTests {
)

close(descriptors[1])
let activatedDuringCreation = await Task.detached {
let activatedDuringCreation = try await Self.runBlocking {
observation.wait(timeout: .now() + 10)
}.value
}

#expect(activatedDuringCreation)
monitor.cancel()
Expand All @@ -434,9 +431,9 @@ struct CLISocketServerTests {

close(descriptors[0])
close(descriptors[1])
let disconnected = await Task.detached {
let disconnected = try await Self.runBlocking {
observation.wait(timeout: .now() + 10)
}.value
}

#expect(disconnected)
monitor.cancel()
Expand Down Expand Up @@ -531,6 +528,18 @@ struct CLISocketServerTests {
}
}

/// Runs blocking work on a dispatch queue. `TestStore` installs a process-global hook that runs
/// `Task.detached` on the main thread, where a blocking wait stops the main-actor work it waits for.
nonisolated private static func runBlocking<Value: Sendable>(
_ work: @escaping @Sendable () throws -> Value
) async throws -> Value {
try await withCheckedThrowingContinuation { continuation in
DispatchQueue.global(qos: .userInitiated).async {
continuation.resume(with: Result { try work() })
}
}
}

nonisolated private static func writeAll(_ fileDescriptor: Int32, buffer: UnsafeRawBufferPointer) throws {
var offset = 0
while offset < buffer.count {
Expand Down
Loading