Skip to content

Commit 1a90ef0

Browse files
Improve debug logging and add tests that it is not evaluated when disabled
1 parent 8464a53 commit 1a90ef0

File tree

7 files changed

+85
-51
lines changed

7 files changed

+85
-51
lines changed

Sources/OpenAPIURLSession/URLSessionTransport.swift

+9-2
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,17 @@ var debugLoggingEnabled: Bool {
230230
get { _debugLoggingEnabled.withLockedValue { $0 } }
231231
set { _debugLoggingEnabled.withLockedValue { $0 = newValue } }
232232
}
233-
func debug(_ items: Any..., separator: String = " ", terminator: String = "\n") {
233+
private let _standardErrorLock = LockStorage.create(value: FileHandle.standardError)
234+
func debug(_ message: @autoclosure () -> String, function: String = #function, file: String = #file, line: UInt = #line)
235+
{
234236
assert(
235237
{
236-
if debugLoggingEnabled { print(items, separator: separator, terminator: terminator) }
238+
if debugLoggingEnabled {
239+
_standardErrorLock.withLockedValue {
240+
let logLine = "[\(function) \(file.split(separator: "/").last!):\(line)] \(message())\n"
241+
$0.write(Data((logLine).utf8))
242+
}
243+
}
237244
return true
238245
}()
239246
)

Tests/OpenAPIURLSessionTests/AsyncBackpressuredStreamTests/AsyncBackpressuredStreamTests.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ final class AsyncBackpressuredStreamTests: XCTestCase {
5151
group.addTask {
5252
while true {
5353
backPressureEventContinuation.yield(())
54-
print("Yielding")
54+
debug("Yielding")
5555
try await source.asyncWrite(contentsOf: [1])
5656
}
5757
}
@@ -64,12 +64,12 @@ final class AsyncBackpressuredStreamTests: XCTestCase {
6464
await backPressureEventIterator.next()
6565
await backPressureEventIterator.next()
6666

67-
print("Waited 4 times")
67+
debug("Waited 4 times")
6868

6969
_ = try await iterator.next()
7070
_ = try await iterator.next()
7171
_ = try await iterator.next()
72-
print("Consumed three")
72+
debug("Consumed three")
7373

7474
await backPressureEventIterator.next()
7575
await backPressureEventIterator.next()
@@ -91,12 +91,12 @@ final class AsyncBackpressuredStreamTests: XCTestCase {
9191
group.addTask {
9292
@Sendable func yield() {
9393
backPressureEventContinuation.yield(())
94-
print("Yielding")
94+
debug("Yielding")
9595
source.write(contentsOf: [1]) { result in
9696
switch result {
9797
case .success: yield()
9898

99-
case .failure: print("Stopping to yield")
99+
case .failure: debug("Stopping to yield")
100100
}
101101
}
102102
}
@@ -112,12 +112,12 @@ final class AsyncBackpressuredStreamTests: XCTestCase {
112112
await backPressureEventIterator.next()
113113
await backPressureEventIterator.next()
114114

115-
print("Waited 4 times")
115+
debug("Waited 4 times")
116116

117117
_ = try await iterator.next()
118118
_ = try await iterator.next()
119119
_ = try await iterator.next()
120-
print("Consumed three")
120+
debug("Consumed three")
121121

122122
await backPressureEventIterator.next()
123123
await backPressureEventIterator.next()

Tests/OpenAPIURLSessionTests/NIOAsyncHTTP1TestServer.swift

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import NIOCore
1515
import NIOPosix
1616
import NIOHTTP1
17+
@testable import OpenAPIURLSession
1718

1819
final class AsyncTestHTTP1Server {
1920

@@ -58,10 +59,10 @@ final class AsyncTestHTTP1Server {
5859
for try await connectionChannel in inbound {
5960
group.addTask {
6061
do {
61-
print("Sevrer handling new connection")
62+
debug("Sevrer handling new connection")
6263
try await connectionHandler(connectionChannel)
63-
print("Server done handling connection")
64-
} catch { print("Server error handling connection: \(error)") }
64+
debug("Server done handling connection")
65+
} catch { debug("Server error handling connection: \(error)") }
6566
}
6667
}
6768
}

Tests/OpenAPIURLSessionTests/URLSessionBidirectionalStreamingTests/HTTPBodyOutputStreamTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import XCTest
1919

2020
// swift-format-ignore: AllPublicDeclarationsHaveDocumentation
2121
class HTTPBodyOutputStreamBridgeTests: XCTestCase {
22-
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = true }
22+
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = false }
2323

2424
func testHTTPBodyOutputStreamInputOutput() async throws {
2525
let chunkSize = 71

Tests/OpenAPIURLSessionTests/URLSessionBidirectionalStreamingTests/MockInputStreamDelegate.swift

+7-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#if canImport(Darwin)
1515

1616
import Foundation
17+
@testable import OpenAPIURLSession
1718

1819
/// Reads one byte at a time from the stream, regardless of how many bytes are available.
1920
///
@@ -39,7 +40,7 @@ final class MockInputStreamDelegate: NSObject, StreamDelegate {
3940
self.inputStream.open()
4041
}
4142

42-
deinit { print("Input stream delegate deinit") }
43+
deinit { debug("Input stream delegate deinit") }
4344

4445
private func readAndResumeContinuation() {
4546
dispatchPrecondition(condition: .onQueue(Self.streamQueue))
@@ -52,15 +53,15 @@ final class MockInputStreamDelegate: NSObject, StreamDelegate {
5253
}
5354
switch buffer.count {
5455
case -1:
55-
print("Input stream delegate error reading from stream: \(inputStream.streamError!)")
56+
debug("Input stream delegate error reading from stream: \(inputStream.streamError!)")
5657
inputStream.close()
5758
continuation.resume(throwing: inputStream.streamError!)
5859
case 0:
59-
print("Input stream delegate reached end of stream; will close stream")
60+
debug("Input stream delegate reached end of stream; will close stream")
6061
self.close()
6162
continuation.resume(returning: nil)
6263
case let numBytesRead where numBytesRead > 0:
63-
print("Input stream delegate read \(numBytesRead) bytes from stream: \(buffer)")
64+
debug("Input stream delegate read \(numBytesRead) bytes from stream: \(buffer)")
6465
continuation.resume(returning: buffer)
6566
default: preconditionFailure()
6667
}
@@ -85,12 +86,12 @@ final class MockInputStreamDelegate: NSObject, StreamDelegate {
8586
func close(withError error: (any Error)? = nil) {
8687
self.inputStream.close()
8788
Self.streamQueue.async { self.state = .closed(error) }
88-
print("Input stream delegate closed stream with error: \(String(describing: error))")
89+
debug("Input stream delegate closed stream with error: \(String(describing: error))")
8990
}
9091

9192
func stream(_ stream: Stream, handle event: Stream.Event) {
9293
dispatchPrecondition(condition: .onQueue(Self.streamQueue))
93-
print("Input stream delegate received event: \(event)")
94+
debug("Input stream delegate received event: \(event)")
9495
switch event {
9596
case .hasBytesAvailable:
9697
switch state {

Tests/OpenAPIURLSessionTests/URLSessionBidirectionalStreamingTests/URLSessionBidirectionalStreamingTests.swift

+12-12
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import XCTest
2323

2424
class URLSessionBidirectionalStreamingTests: XCTestCase {
2525
// swift-format-ignore: AllPublicDeclarationsHaveDocumentation
26-
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = true }
26+
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = false }
2727

2828
func testBidirectionalEcho_PerChunkRatchet_1BChunk_1Chunks_1BUploadBuffer_1BDownloadWatermark() async throws {
2929
try await testBidirectionalEchoPerChunkRatchet(
@@ -329,31 +329,31 @@ class URLSessionBidirectionalStreamingTests: XCTestCase {
329329
)
330330
)
331331
)
332-
print("Server sent response head")
332+
debug("Server sent response head")
333333
for i in 1...numResponseChunks {
334334
try await outbound.write(.body(ByteBuffer(bytes: responseChunk)))
335-
print("Server sent body chunk \(i)/\(numResponseChunks) of \(responseChunk.count)")
335+
debug("Server sent body chunk \(i)/\(numResponseChunks) of \(responseChunk.count)")
336336
}
337337
case .body: preconditionFailure()
338338
case .end:
339339
try await outbound.write(.end(nil))
340-
print("Server sent response end")
340+
debug("Server sent response end")
341341
}
342342
}
343343
}
344344
}
345-
print("Server running on 127.0.0.1:\(serverPort)")
345+
debug("Server running on 127.0.0.1:\(serverPort)")
346346

347347
// Send the request.
348-
print("Client starting request")
348+
debug("Client starting request")
349349
let (response, responseBody) = try await URLSession.shared.bidirectionalStreamingRequest(
350350
for: HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"),
351351
baseURL: URL(string: "http://127.0.0.1:\(serverPort)")!,
352352
requestBody: nil,
353353
requestStreamBufferSize: 16 * 1024 * 1024,
354354
responseStreamWatermarks: responseStreamWatermarks
355355
)
356-
print("Client received response head: \(response)")
356+
debug("Client received response head: \(response)")
357357
XCTAssertEqual(response.status, .ok)
358358

359359
switch verification {
@@ -362,10 +362,10 @@ class URLSessionBidirectionalStreamingTests: XCTestCase {
362362
var unprocessedBytes = ByteBuffer()
363363
var numProcessedChunks = 0
364364
for try await receivedResponseChunk in responseBody! {
365-
print("Client received some response body bytes (numBytes: \(receivedResponseChunk.count))")
365+
debug("Client received some response body bytes (numBytes: \(receivedResponseChunk.count))")
366366
unprocessedBytes.writeBytes(receivedResponseChunk)
367367
while unprocessedBytes.readableBytes >= responseChunk.count {
368-
print("Client reconstructing and verifying chunk \(numProcessedChunks+1)/\(numResponseChunks)")
368+
debug("Client reconstructing and verifying chunk \(numProcessedChunks+1)/\(numResponseChunks)")
369369
XCTAssertEqual(
370370
ArraySlice(unprocessedBytes.readBytes(length: responseChunk.count)!),
371371
responseChunk
@@ -379,14 +379,14 @@ class URLSessionBidirectionalStreamingTests: XCTestCase {
379379
case .count:
380380
var numBytesReceived = 0
381381
for try await receivedResponseChunk in responseBody! {
382-
print("Client received some response body bytes (numBytes: \(receivedResponseChunk.count))")
382+
debug("Client received some response body bytes (numBytes: \(receivedResponseChunk.count))")
383383
numBytesReceived += receivedResponseChunk.count
384384
}
385385
XCTAssertEqual(numBytesReceived, responseChunk.count * numResponseChunks)
386386
case .delay(let delay):
387387
for try await receivedResponseChunk in responseBody! {
388-
print("Client received some response body bytes (numBytes: \(receivedResponseChunk.count))")
389-
print("Client doing fake work for \(delay)s")
388+
debug("Client received some response body bytes (numBytes: \(receivedResponseChunk.count))")
389+
debug("Client doing fake work for \(delay)s")
390390
try await Task.sleep(nanoseconds: UInt64(delay.nanoseconds))
391391
}
392392
}

Tests/OpenAPIURLSessionTests/URLSessionTransportTests.swift

+45-20
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import XCTest
2424

2525
// swift-format-ignore: AllPublicDeclarationsHaveDocumentation
2626
class URLSessionTransportConverterTests: XCTestCase {
27-
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = true }
27+
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = false }
2828

2929
func testRequestConversion() async throws {
3030
let request = HTTPRequest(
@@ -58,7 +58,7 @@ class URLSessionTransportConverterTests: XCTestCase {
5858
class URLSessionTransportBufferedTests: XCTestCase {
5959
var transport: (any ClientTransport)!
6060

61-
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = true }
61+
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = false }
6262

6363
override func setUp() async throws {
6464
transport = URLSessionTransport(configuration: .init(implementation: .buffering))
@@ -91,7 +91,7 @@ class URLSessionTransportBufferedTests: XCTestCase {
9191
class URLSessionTransportStreamingTests: XCTestCase {
9292
var transport: (any ClientTransport)!
9393

94-
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = true }
94+
static override func setUp() { OpenAPIURLSession.debugLoggingEnabled = false }
9595

9696
override func setUpWithError() throws {
9797
try XCTSkipUnless(URLSessionTransport.Configuration.Implementation.platformSupportsStreaming)
@@ -165,43 +165,43 @@ func testHTTPRedirect(
165165
while let requestPart = try await requestPartIterator.next() {
166166
switch requestPart {
167167
case .head(let head):
168-
print("Server received head for \(head.uri)")
168+
debug("Server received head for \(head.uri)")
169169
currentURI = head.uri
170170
case .body(let buffer):
171171
let currentURI = try XCTUnwrap(currentURI)
172-
print("Server received body bytes for \(currentURI) (numBytes: \(buffer.readableBytes))")
172+
debug("Server received body bytes for \(currentURI) (numBytes: \(buffer.readableBytes))")
173173
accumulatedBody.writeImmutableBuffer(buffer)
174174
case .end:
175175
let currentURI = try XCTUnwrap(currentURI)
176-
print("Server received end for \(currentURI)")
176+
debug("Server received end for \(currentURI)")
177177
XCTAssertEqual(accumulatedBody, ByteBuffer(string: requestBodyChunks.joined()))
178178
switch currentURI {
179179
case "/old":
180-
print("Server reseting body buffer")
180+
debug("Server reseting body buffer")
181181
accumulatedBody = ByteBuffer()
182182
try await outbound.write(
183183
.head(
184184
.init(version: .http1_1, status: .temporaryRedirect, headers: ["Location": "/new"])
185185
)
186186
)
187-
print("Server sent head for \(currentURI)")
187+
debug("Server sent head for \(currentURI)")
188188
try await outbound.write(.end(nil))
189-
print("Server sent end for \(currentURI)")
189+
debug("Server sent end for \(currentURI)")
190190
case "/new":
191191
try await outbound.write(.head(.init(version: .http1_1, status: .ok)))
192-
print("Server sent head for \(currentURI)")
192+
debug("Server sent head for \(currentURI)")
193193
try await outbound.write(.end(nil))
194-
print("Server sent end for \(currentURI)")
194+
debug("Server sent end for \(currentURI)")
195195
default: preconditionFailure()
196196
}
197197
}
198198
}
199199
}
200200
}
201-
print("Server running on 127.0.0.1:\(serverPort)")
201+
debug("Server running on 127.0.0.1:\(serverPort)")
202202

203203
// Send the request.
204-
print("Client starting request")
204+
debug("Client starting request")
205205
if expectFailureDueToIterationBehavior {
206206
await XCTAssertThrowsError(
207207
try await transport.send(
@@ -218,7 +218,7 @@ func testHTTPRedirect(
218218
baseURL: URL(string: "http://127.0.0.1:\(serverPort)")!,
219219
operationID: "unused"
220220
)
221-
print("Client received response head: \(response)")
221+
debug("Client received response head: \(response)")
222222
XCTAssertEqual(response.status, .ok)
223223
}
224224

@@ -248,17 +248,17 @@ func testHTTPBasicGet(transport: any ClientTransport) async throws {
248248
}
249249
}
250250
}
251-
print("Server running on 127.0.0.1:\(serverPort)")
251+
debug("Server running on 127.0.0.1:\(serverPort)")
252252

253253
// Send the request.
254-
print("Client starting request")
254+
debug("Client starting request")
255255
let (response, maybeResponseBody) = try await transport.send(
256256
HTTPRequest(method: .get, scheme: nil, authority: nil, path: requestPath),
257257
body: nil,
258258
baseURL: URL(string: "http://127.0.0.1:\(serverPort)")!,
259259
operationID: "unused"
260260
)
261-
print("Client received response head: \(response)")
261+
debug("Client received response head: \(response)")
262262
XCTAssertEqual(response.status, .ok)
263263
let receivedMessage = try await String(collecting: try XCTUnwrap(maybeResponseBody), upTo: .max)
264264
XCTAssertEqual(receivedMessage, responseBodyMessage)
@@ -292,21 +292,46 @@ func testHTTPBasicPost(transport: any ClientTransport) async throws {
292292
}
293293
}
294294
}
295-
print("Server running on 127.0.0.1:\(serverPort)")
295+
debug("Server running on 127.0.0.1:\(serverPort)")
296296

297297
// Send the request.
298-
print("Client starting request")
298+
debug("Client starting request")
299299
let (response, maybeResponseBody) = try await transport.send(
300300
HTTPRequest(method: .post, scheme: nil, authority: nil, path: requestPath),
301301
body: HTTPBody(requestBodyMessage),
302302
baseURL: URL(string: "http://127.0.0.1:\(serverPort)")!,
303303
operationID: "unused"
304304
)
305-
print("Client received response head: \(response)")
305+
debug("Client received response head: \(response)")
306306
XCTAssertEqual(response.status, .ok)
307307
let receivedMessage = try await String(collecting: try XCTUnwrap(maybeResponseBody), upTo: .max)
308308
XCTAssertEqual(receivedMessage, responseBodyMessage)
309309

310310
group.cancelAll()
311311
}
312312
}
313+
314+
class URLSessionTransportDebugLoggingTests: XCTestCase {
315+
func testDebugLoggingEnabled() async throws {
316+
let expectation = expectation(description: "message autoclosure evaluated")
317+
func message() -> String {
318+
expectation.fulfill()
319+
return "message"
320+
}
321+
OpenAPIURLSession.debugLoggingEnabled = true
322+
debug(message())
323+
await fulfillment(of: [expectation], timeout: 0)
324+
}
325+
326+
func testDebugLoggingDisabled() async throws {
327+
let expectation = expectation(description: "message autoclosure evaluated")
328+
expectation.isInverted = true
329+
func message() -> String {
330+
expectation.fulfill()
331+
return "message"
332+
}
333+
OpenAPIURLSession.debugLoggingEnabled = false
334+
debug(message())
335+
await fulfillment(of: [expectation], timeout: 0)
336+
}
337+
}

0 commit comments

Comments
 (0)