Skip to content

Commit

Permalink
check error through pattern matching
Browse files Browse the repository at this point in the history
because `HTTPRequestStateMachine.Action` Equatable conformance ignores the error completly
  • Loading branch information
dnadoba committed Nov 24, 2021
1 parent e097940 commit 3a6a256
Showing 1 changed file with 69 additions and 18 deletions.
87 changes: 69 additions & 18 deletions Tests/AsyncHTTPClientTests/HTTPRequestStateMachineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,10 @@ class HTTPRequestStateMachineTests: XCTestCase {

let part1 = IOData.byteBuffer(ByteBuffer(bytes: 4...7))
XCTAssertEqual(state.requestStreamPartReceived(part1), .sendBodyPart(part1))
XCTAssertEqual(state.requestStreamFinished(), .failRequest(HTTPClientError.bodyLengthMismatch, .close))
guard case .failRequest(let error, .close) = state.requestStreamFinished() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .bodyLengthMismatch)
XCTAssertEqual(state.channelInactive(), .wait)
}

Expand All @@ -227,7 +230,10 @@ class HTTPRequestStateMachineTests: XCTestCase {

let part1 = IOData.byteBuffer(ByteBuffer(bytes: 4...7))
XCTAssertEqual(state.requestStreamPartReceived(part1), .sendBodyPart(part1))
XCTAssertEqual(state.requestStreamFinished(), .failRequest(HTTPClientError.bodyLengthMismatch, .close))
guard case .failRequest(let error, .close) = state.requestStreamFinished() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .bodyLengthMismatch)
XCTAssertEqual(state.channelRead(.end(nil)), .wait)
}

Expand All @@ -252,7 +258,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
let requestHead = HTTPRequestHead(version: .http1_1, method: .GET, uri: "/")
let metadata = RequestFramingMetadata(connectionClose: false, body: .fixedSize(0))
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .wait)
XCTAssertEqual(state.channelInactive(), .failRequest(HTTPClientError.remoteConnectionClosed, .none))
guard case .failRequest(let error, .none) = state.channelInactive() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .remoteConnectionClosed)
}

func testResponseReadingWithBackpressure() {
Expand Down Expand Up @@ -342,15 +351,21 @@ class HTTPRequestStateMachineTests: XCTestCase {

func testCancellingARequestInStateInitializedKeepsTheConnectionAlive() {
var state = HTTPRequestStateMachine(isChannelWritable: false)
XCTAssertEqual(state.requestCancelled(), .failRequest(HTTPClientError.cancelled, .none))
guard case .failRequest(let error, .none) = state.requestCancelled() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .cancelled)
}

func testCancellingARequestBeforeBeingSendKeepsTheConnectionAlive() {
var state = HTTPRequestStateMachine(isChannelWritable: false)
let requestHead = HTTPRequestHead(version: .http1_1, method: .GET, uri: "/")
let metadata = RequestFramingMetadata(connectionClose: false, body: .fixedSize(0))
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .wait)
XCTAssertEqual(state.requestCancelled(), .failRequest(HTTPClientError.cancelled, .none))
guard case .failRequest(let error, .none) = state.requestCancelled() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .cancelled)
}

func testConnectionBecomesWritableBeforeFirstRequest() {
Expand All @@ -376,15 +391,21 @@ class HTTPRequestStateMachineTests: XCTestCase {
let requestHead = HTTPRequestHead(version: .http1_1, method: .GET, uri: "/")
let metadata = RequestFramingMetadata(connectionClose: false, body: .fixedSize(0))
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .sendRequestHead(requestHead, startBody: false))
XCTAssertEqual(state.requestCancelled(), .failRequest(HTTPClientError.cancelled, .close))
guard case .failRequest(let error, .close) = state.requestCancelled() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .cancelled)
}

func testRemoteSuddenlyClosesTheConnection() {
var state = HTTPRequestStateMachine(isChannelWritable: true)
let requestHead = HTTPRequestHead(version: .http1_1, method: .GET, uri: "/", headers: .init([("content-length", "4")]))
let metadata = RequestFramingMetadata(connectionClose: false, body: .fixedSize(4))
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .sendRequestHead(requestHead, startBody: true))
XCTAssertEqual(state.requestCancelled(), .failRequest(HTTPClientError.remoteConnectionClosed, .close))
guard case .failRequest(let error, .close) = state.requestCancelled() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .cancelled)
XCTAssertEqual(state.requestStreamPartReceived(.byteBuffer(.init(bytes: 1...3))), .wait)
}

Expand All @@ -398,7 +419,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
XCTAssertEqual(state.channelRead(.head(responseHead)), .forwardResponseHead(responseHead, pauseRequestBodyStream: false))
let part0 = ByteBuffer(bytes: 0...3)
XCTAssertEqual(state.channelRead(.body(part0)), .wait)
XCTAssertEqual(state.idleReadTimeoutTriggered(), .failRequest(HTTPClientError.readTimeout, .close))
guard case .failRequest(let error, .close) = state.idleReadTimeoutTriggered() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .readTimeout)
XCTAssertEqual(state.channelRead(.body(ByteBuffer(bytes: 4...7))), .wait)
XCTAssertEqual(state.channelRead(.body(ByteBuffer(bytes: 8...11))), .wait)
XCTAssertEqual(state.demandMoreResponseBodyParts(), .wait)
Expand Down Expand Up @@ -451,7 +475,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
let metadata = RequestFramingMetadata(connectionClose: false, body: .fixedSize(0))
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .sendRequestHead(requestHead, startBody: false))

XCTAssertEqual(state.errorHappened(HTTPParserError.invalidChunkSize), .failRequest(HTTPParserError.invalidChunkSize, .close))
guard case .failRequest(let error, .close) = state.errorHappened(HTTPParserError.invalidChunkSize) else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPParserError, .invalidChunkSize)
XCTAssertEqual(state.requestCancelled(), .wait, "A cancellation that happens to late is ignored")
}

Expand Down Expand Up @@ -505,7 +532,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
XCTAssertEqual(state.read(), .read)
XCTAssertEqual(state.channelReadComplete(), .wait)
XCTAssertEqual(state.channelRead(.body(body)), .wait)
XCTAssertEqual(state.channelRead(.end(nil)), .failRequest(HTTPClientError.remoteConnectionClosed, .close))
guard case .failRequest(let error, .close) = state.channelRead(.end(nil)) else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .remoteConnectionClosed)
XCTAssertEqual(state.channelInactive(), .wait)
}

Expand All @@ -520,7 +550,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
XCTAssertEqual(state.channelRead(.head(responseHead)), .forwardResponseHead(responseHead, pauseRequestBodyStream: false))
XCTAssertEqual(state.demandMoreResponseBodyParts(), .wait)
XCTAssertEqual(state.channelRead(.body(body)), .wait)
XCTAssertEqual(state.errorHappened(NIOSSLError.uncleanShutdown), .failRequest(NIOSSLError.uncleanShutdown, .close))
guard case .failRequest(let error, .close) = state.errorHappened(NIOSSLError.uncleanShutdown) else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? NIOSSLError, .uncleanShutdown)
XCTAssertEqual(state.channelRead(.end(nil)), .wait)
XCTAssertEqual(state.channelInactive(), .wait)
}
Expand All @@ -532,7 +565,11 @@ class HTTPRequestStateMachineTests: XCTestCase {
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .sendRequestHead(requestHead, startBody: false))

XCTAssertEqual(state.errorHappened(NIOSSLError.uncleanShutdown), .wait)
XCTAssertEqual(state.channelInactive(), .failRequest(HTTPClientError.remoteConnectionClosed, .none))

guard case .failRequest(let error, .none) = state.channelInactive() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .remoteConnectionClosed)
}

func testArbitraryErrorShouldBeTreatedAsARequestFailureWhileInWaitingForHeadState() {
Expand All @@ -541,8 +578,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
let requestHead = HTTPRequestHead(version: .http1_1, method: .GET, uri: "/")
let metadata = RequestFramingMetadata(connectionClose: false, body: .fixedSize(0))
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .sendRequestHead(requestHead, startBody: false))

XCTAssertEqual(state.errorHappened(ArbitraryError()), .failRequest(ArbitraryError(), .close))
guard case .failRequest(let error, .close) = state.errorHappened(ArbitraryError()) else {
return XCTFail("unexpected action")
}
XCTAssertTrue(error is ArbitraryError)
XCTAssertEqual(state.channelInactive(), .wait)
}

Expand All @@ -560,7 +599,10 @@ class HTTPRequestStateMachineTests: XCTestCase {
XCTAssertEqual(state.channelRead(.body(body)), .wait)
XCTAssertEqual(state.channelReadComplete(), .forwardResponseBodyParts([body]))
XCTAssertEqual(state.errorHappened(NIOSSLError.uncleanShutdown), .wait)
XCTAssertEqual(state.errorHappened(HTTPParserError.invalidEOFState), .failRequest(HTTPParserError.invalidEOFState, .close))
guard case .failRequest(let error, .close) = state.errorHappened(HTTPParserError.invalidEOFState) else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPParserError, .invalidEOFState)
XCTAssertEqual(state.channelInactive(), .wait)
}

Expand All @@ -582,7 +624,10 @@ class HTTPRequestStateMachineTests: XCTestCase {

XCTAssertEqual(state.channelRead(.body(ByteBuffer(string: " baz lightyear"))), .wait)
XCTAssertEqual(state.channelReadComplete(), .wait)
XCTAssertEqual(state.channelInactive(), .failRequest(HTTPClientError.remoteConnectionClosed, .none))
guard case .failRequest(let error, .none) = state.channelInactive() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .remoteConnectionClosed)
}

func testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForRead() {
Expand All @@ -603,7 +648,10 @@ class HTTPRequestStateMachineTests: XCTestCase {

XCTAssertEqual(state.channelRead(.body(ByteBuffer(string: " baz lightyear"))), .wait)
XCTAssertEqual(state.channelReadComplete(), .wait)
XCTAssertEqual(state.channelInactive(), .failRequest(HTTPClientError.remoteConnectionClosed, .none))
guard case .failRequest(let error, .none) = state.channelInactive() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .remoteConnectionClosed)
}

func testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemand() {
Expand All @@ -623,7 +671,10 @@ class HTTPRequestStateMachineTests: XCTestCase {

XCTAssertEqual(state.channelRead(.body(ByteBuffer(string: " baz lightyear"))), .wait)
XCTAssertEqual(state.channelReadComplete(), .wait)
XCTAssertEqual(state.channelInactive(), .failRequest(HTTPClientError.remoteConnectionClosed, .none))
guard case .failRequest(let error, .none) = state.channelInactive() else {
return XCTFail("unexpected action")
}
XCTAssertEqual(error as? HTTPClientError, .remoteConnectionClosed)
}

func testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemandMultipleTimes() {
Expand Down

0 comments on commit 3a6a256

Please sign in to comment.