prepare tests for throwing readIn/Outbound (#861)

Motivation:

readInbound/Outbound will soon throw errors if the type isn't right.

Modifications:

prepare tests for throwing readIn/Outbound

Result:

@ianpartridge's PR should pretty much merge after this.
This commit is contained in:
Johannes Weiss 2019-03-04 09:40:59 +00:00 committed by Cory Benfield
parent 49659664c2
commit a1981eb0fd
16 changed files with 328 additions and 288 deletions

View File

@ -328,11 +328,11 @@ public class EmbeddedChannel: Channel {
// Embedded channels never have parents.
public let parent: Channel? = nil
public func readOutbound<T>(as type: T.Type = T.self) -> T? {
public func readOutbound<T>(as type: T.Type = T.self) throws -> T? {
return readFromBuffer(buffer: &channelcore.outboundBuffer)
}
public func readInbound<T>(as type: T.Type = T.self) -> T? {
public func readInbound<T>(as type: T.Type = T.self) throws -> T? {
return readFromBuffer(buffer: &channelcore.inboundBuffer)
}

View File

@ -133,7 +133,7 @@ class HTTPDecoderLengthTest: XCTestCase {
// Prime the decoder with a GET and consume it.
XCTAssertTrue(try channel.writeOutbound(HTTPClientRequestPart.head(HTTPRequestHead(version: version, method: .GET, uri: "/"))))
XCTAssertNotNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNotNil(try channel.readOutbound(as: ByteBuffer.self)))
// We now want to send a HTTP/1.1 response. This response has no content-length, no transfer-encoding,
// is not a response to a HEAD request, is not a 2XX response to CONNECT, and is not 1XX, 204, or 304.
@ -198,7 +198,7 @@ class HTTPDecoderLengthTest: XCTestCase {
XCTAssertTrue(try channel.writeOutbound(HTTPClientRequestPart.head(HTTPRequestHead(version: .init(major: 1, minor: 1),
method: requestMethod,
uri: "/"))))
XCTAssertNotNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNotNil(try channel.readOutbound(as: ByteBuffer.self)))
// We now want to send a HTTP/1.1 response. This response may contain some length framing fields that RFC 7230 says MUST
// be ignored.
@ -337,7 +337,7 @@ class HTTPDecoderLengthTest: XCTestCase {
XCTAssertTrue(try channel.writeOutbound(HTTPClientRequestPart.head(HTTPRequestHead(version: .init(major: 1, minor: 1),
method: .GET,
uri: "/"))))
XCTAssertNotNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNotNil(try channel.readOutbound(as: ByteBuffer.self)))
// Send a 200 with the appropriate Transfer Encoding header. We should see the request,
// but no body or end.

View File

@ -382,7 +382,7 @@ class HTTPDecoderTest: XCTestCase {
buffer.writeStaticString("\r\nGET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
try channel.writeInbound(buffer)
let message: HTTPServerRequestPart? = self.channel.readInbound()
let message: HTTPServerRequestPart? = try self.channel.readInbound()
guard case .some(.head(let head)) = message else {
XCTFail("Invalid message: \(String(describing: message))")
return
@ -393,7 +393,7 @@ class HTTPDecoderTest: XCTestCase {
XCTAssertEqual(head.version, .init(major: 1, minor: 1))
XCTAssertEqual(head.headers, HTTPHeaders([("Host", "example.com")]))
let secondMessage: HTTPServerRequestPart? = self.channel.readInbound()
let secondMessage: HTTPServerRequestPart? = try self.channel.readInbound()
guard case .some(.end(.none)) = secondMessage else {
XCTFail("Invalid second message: \(String(describing: secondMessage))")
return
@ -411,7 +411,7 @@ class HTTPDecoderTest: XCTestCase {
buffer.writeStaticString("SOURCE / HTTP/1.1\r\nHost: example.com\r\n\r\n")
try channel.writeInbound(buffer)
let message: HTTPServerRequestPart? = self.channel.readInbound()
let message: HTTPServerRequestPart? = try self.channel.readInbound()
guard case .some(.head(let head)) = message else {
XCTFail("Invalid message: \(String(describing: message))")
return
@ -422,7 +422,7 @@ class HTTPDecoderTest: XCTestCase {
XCTAssertEqual(head.version, .init(major: 1, minor: 1))
XCTAssertEqual(head.headers, HTTPHeaders([("Host", "example.com")]))
let secondMessage: HTTPServerRequestPart? = self.channel.readInbound()
let secondMessage: HTTPServerRequestPart? = try self.channel.readInbound()
guard case .some(.end(.none)) = secondMessage else {
XCTFail("Invalid second message: \(String(describing: secondMessage))")
return
@ -442,7 +442,7 @@ class HTTPDecoderTest: XCTestCase {
buffer.writeStaticString("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
try channel.writeInbound(buffer)
let message: HTTPServerRequestPart? = self.channel.readInbound()
let message: HTTPServerRequestPart? = try self.channel.readInbound()
guard case .some(.head(let head)) = message else {
XCTFail("Invalid message: \(String(describing: message))")
return
@ -453,7 +453,7 @@ class HTTPDecoderTest: XCTestCase {
XCTAssertEqual(head.version, .init(major: 1, minor: 1))
XCTAssertEqual(head.headers, HTTPHeaders([("Host", "example.com")]))
let secondMessage: HTTPServerRequestPart? = self.channel.readInbound()
let secondMessage: HTTPServerRequestPart? = try self.channel.readInbound()
guard case .some(.end(.none)) = secondMessage else {
XCTFail("Invalid second message: \(String(describing: secondMessage))")
return

View File

@ -33,7 +33,7 @@ class HTTPRequestEncoderTests: XCTestCase {
var request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: method, uri: "/uri")
request.headers = headers
try channel.writeOutbound(HTTPClientRequestPart.head(request))
if let buffer = channel.readOutbound(as: ByteBuffer.self) {
if let buffer = try channel.readOutbound(as: ByteBuffer.self) {
return buffer
} else {
fatalError("Could not read ByteBuffer from channel")
@ -83,7 +83,7 @@ class HTTPRequestEncoderTests: XCTestCase {
// This request contains neither Transfer-Encoding: chunked or Content-Length.
let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:0), method: .GET, uri: "/uri")
XCTAssertNoThrow(try channel.writeOutbound(HTTPClientRequestPart.head(request)))
let writtenData = channel.readOutbound(as: ByteBuffer.self)!
let writtenData = try channel.readOutbound(as: ByteBuffer.self)!
let writtenResponse = writtenData.getString(at: writtenData.readerIndex, length: writtenData.readableBytes)!
XCTAssertEqual(writtenResponse, "GET /uri HTTP/1.0\r\n\r\n")
}
@ -129,10 +129,14 @@ class HTTPRequestEncoderTests: XCTestCase {
}
private func assertOutboundContainsOnly(_ channel: EmbeddedChannel, _ expected: String) {
if let buffer = channel.readOutbound(as: ByteBuffer.self) {
buffer.assertContainsOnly(expected)
} else {
fatalError("Could not read ByteBuffer from channel")
do {
if let buffer = try channel.readOutbound(as: ByteBuffer.self) {
buffer.assertContainsOnly(expected)
} else {
fatalError("Could not read ByteBuffer from channel")
}
} catch {
XCTFail("unexpected error: \(error)")
}
}
}

View File

@ -199,7 +199,7 @@ class HTTPResponseCompressorTest: XCTestCase {
clientChannel.write(NIOAny(HTTPClientRequestPart.head(requestHead)), promise: nil)
clientChannel.write(NIOAny(HTTPClientRequestPart.end(nil)), promise: nil)
while let b = channel.readOutbound(as: ByteBuffer.self) {
while let b = try channel.readOutbound(as: ByteBuffer.self) {
try clientChannel.writeInbound(b)
}
@ -207,7 +207,7 @@ class HTTPResponseCompressorTest: XCTestCase {
// the last, which is the end.
var head: HTTPResponseHead? = nil
var dataChunks = [ByteBuffer]()
loop: while let responsePart: HTTPClientResponsePart = clientChannel.readInbound() {
loop: while let responsePart: HTTPClientResponsePart = try clientChannel.readInbound() {
switch responsePart {
case .head(let h):
precondition(head == nil)

View File

@ -33,10 +33,17 @@ class HTTPResponseEncoderTests: XCTestCase {
var switchingResponse = HTTPResponseHead(version: HTTPVersion(major: 1, minor:1), status: status)
switchingResponse.headers = headers
XCTAssertNoThrow(try channel.writeOutbound(HTTPServerResponsePart.head(switchingResponse)))
if let buffer = channel.readOutbound(as: ByteBuffer.self) {
return buffer
} else {
fatalError("Could not read ByteBuffer from channel")
do {
if let buffer = try channel.readOutbound(as: ByteBuffer.self) {
return buffer
} else {
fatalError("Could not read ByteBuffer from channel")
}
} catch {
XCTFail("unexpected error: \(error)")
var buf = channel.allocator.buffer(capacity: 16)
buf.writeString("unexpected error: \(error)")
return buf
}
}
@ -103,7 +110,7 @@ class HTTPResponseEncoderTests: XCTestCase {
// This response contains neither Transfer-Encoding: chunked or Content-Length.
let response = HTTPResponseHead(version: HTTPVersion(major: 1, minor:0), status: .ok)
XCTAssertNoThrow(try channel.writeOutbound(HTTPServerResponsePart.head(response)))
guard let b = channel.readOutbound(as: ByteBuffer.self) else {
guard let b = try channel.readOutbound(as: ByteBuffer.self) else {
XCTFail("Could not read byte buffer")
return
}

View File

@ -34,12 +34,12 @@ class HTTPServerProtocolErrorHandlerTest: XCTestCase {
XCTAssertNoThrow(try channel.closeFuture.wait())
// We expect exactly one ByteBuffer in the output.
guard var written = channel.readOutbound(as: ByteBuffer.self) else {
guard var written = try channel.readOutbound(as: ByteBuffer.self) else {
XCTFail("No writes")
return
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
// Check the response.
assertResponseIs(response: written.readString(length: written.readableBytes)!,
@ -76,7 +76,7 @@ class HTTPServerProtocolErrorHandlerTest: XCTestCase {
XCTAssertNoThrow(try channel.writeAndFlush(res).wait())
// now we have started a response but it's not complete yet, let's inject a parser error
channel.pipeline.fireErrorCaught(HTTPParserError.invalidEOFState)
var allOutbound = channel.readAllOutboundBuffers()
var allOutbound = try channel.readAllOutboundBuffers()
let allOutboundString = allOutbound.readString(length: allOutbound.readableBytes)
// there should be no HTTP/1.1 400 or anything in here
XCTAssertEqual("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n", allOutboundString)
@ -127,12 +127,12 @@ class HTTPServerProtocolErrorHandlerTest: XCTestCase {
XCTAssertNoThrow(try channel.closeFuture.wait())
// We expect exactly one ByteBuffer in the output.
guard var written = channel.readOutbound(as: ByteBuffer.self) else {
guard var written = try channel.readOutbound(as: ByteBuffer.self) else {
XCTFail("No writes")
return
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
// Check the response.
assertResponseIs(response: written.readString(length: written.readableBytes)!,

View File

@ -62,17 +62,17 @@ extension ChannelPipeline {
}
extension EmbeddedChannel {
func readAllOutboundBuffers() -> ByteBuffer {
func readAllOutboundBuffers() throws -> ByteBuffer {
var buffer = self.allocator.buffer(capacity: 100)
while var writtenData = self.readOutbound(as: ByteBuffer.self) {
while var writtenData = try self.readOutbound(as: ByteBuffer.self) {
buffer.writeBuffer(&writtenData)
}
return buffer
}
func readAllOutboundString() -> String {
var buffer = self.readAllOutboundBuffers()
func readAllOutboundString() throws -> String {
var buffer = try self.readAllOutboundBuffers()
return buffer.readString(length: buffer.readableBytes)!
}
}
@ -396,7 +396,7 @@ class HTTPUpgradeTestCase: XCTestCase {
// The handler removed itself from the pipeline and passed the unexpected
// data on.
try channel.pipeline.assertDoesNotContainUpgrader()
let receivedData: HTTPServerRequestPart = channel.readInbound()!
let receivedData: HTTPServerRequestPart = try channel.readInbound()!
XCTAssertEqual(data, receivedData)
}
@ -820,15 +820,16 @@ class HTTPUpgradeTestCase: XCTestCase {
// Upgrade has been requested but not proceeded.
XCTAssertTrue(upgradeRequested)
XCTAssertNoThrow(try channel.pipeline.assertContainsUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(try XCTAssertNil(channel.readOutbound(as: ByteBuffer.self)))
// Ok, now we can upgrade. Upgrader should be out of the pipeline, and we should have seen the 101 response.
delayedPromise.succeed(())
XCTAssertNoThrow(try channel.pipeline.assertDoesNotContainUpgrader())
let response = channel.readAllOutboundString()
assertResponseIs(response: response,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["X-Upgrade-Complete: true", "upgrade: myproto", "connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try channel.readAllOutboundString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["X-Upgrade-Complete: true",
"upgrade: myproto",
"connection: upgrade"]))
}
func testChainsDelayedUpgradesAppropriately() throws {
@ -873,14 +874,14 @@ class HTTPUpgradeTestCase: XCTestCase {
// Upgrade has been requested but not proceeded for the failing protocol.
XCTAssertEqual(upgradingProtocol, "failingProtocol")
XCTAssertNoThrow(try channel.pipeline.assertContainsUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound(as: ByteBuffer.self)))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
// Ok, now we'll fail the promise. This will catch an error, but the upgrade won't happen: instead, the second handler will be fired.
failingProtocolPromise.fail(No.no)
XCTAssertEqual(upgradingProtocol, "myproto")
XCTAssertNoThrow(try channel.pipeline.assertContainsUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound(as: ByteBuffer.self)))
do {
try channel.throwIfErrorCaught()
XCTFail("Did not throw")
@ -893,8 +894,7 @@ class HTTPUpgradeTestCase: XCTestCase {
// Ok, now we can upgrade. Upgrader should be out of the pipeline, and we should have seen the 101 response.
myprotoPromise.succeed(())
XCTAssertNoThrow(try channel.pipeline.assertDoesNotContainUpgrader())
let response = channel.readAllOutboundString()
assertResponseIs(response: response,
assertResponseIs(response: try channel.readAllOutboundString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["X-Upgrade-Complete: true", "upgrade: myproto", "connection: upgrade"])
}
@ -934,13 +934,13 @@ class HTTPUpgradeTestCase: XCTestCase {
// Upgrade has been requested but not proceeded.
XCTAssertTrue(upgradeRequested)
XCTAssertNoThrow(try channel.pipeline.assertContainsUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound(as: ByteBuffer.self)))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
// Ok, now we fail the upgrade. This fires an error, and then delivers the original request.
delayedPromise.fail(No.no)
XCTAssertNoThrow(try channel.pipeline.assertDoesNotContainUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound(as: ByteBuffer.self)))
do {
try channel.throwIfErrorCaught()
@ -951,7 +951,7 @@ class HTTPUpgradeTestCase: XCTestCase {
XCTFail("Unexpected error: \(error)")
}
switch channel.readInbound(as: HTTPServerRequestPart.self) {
switch try channel.readInbound(as: HTTPServerRequestPart.self) {
case .some(.head):
// ok
break
@ -959,7 +959,7 @@ class HTTPUpgradeTestCase: XCTestCase {
XCTFail("Expected .head, got \(String(describing: t))")
}
switch channel.readInbound(as: HTTPServerRequestPart.self) {
switch try channel.readInbound(as: HTTPServerRequestPart.self) {
case .some(.end):
// ok
break
@ -967,7 +967,7 @@ class HTTPUpgradeTestCase: XCTestCase {
XCTFail("Expected .head, got \(String(describing: t))")
}
XCTAssertNil(channel.readInbound(as: HTTPServerRequestPart.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound(as: HTTPServerRequestPart.self)))
}
func testDelayedUpgradeResponseDeliversFullRequestAndPendingBits() throws {
@ -1007,7 +1007,7 @@ class HTTPUpgradeTestCase: XCTestCase {
// Upgrade has been requested but not proceeded.
XCTAssertTrue(upgradeRequested)
XCTAssertNoThrow(try channel.pipeline.assertContainsUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound(as: ByteBuffer.self)))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
// We now need to inject an extra buffered request. To do this we grab the context for the HTTPRequestDecoder and inject some reads.
@ -1020,7 +1020,7 @@ class HTTPUpgradeTestCase: XCTestCase {
// Ok, now we fail the upgrade. This fires an error, and then delivers the original request and the buffered one.
delayedPromise.fail(No.no)
XCTAssertNoThrow(try channel.pipeline.assertDoesNotContainUpgrader())
XCTAssertNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound(as: ByteBuffer.self)))
do {
try channel.throwIfErrorCaught()
@ -1031,14 +1031,14 @@ class HTTPUpgradeTestCase: XCTestCase {
XCTFail("Unexpected error: \(error)")
}
switch channel.readInbound(as: HTTPServerRequestPart.self) {
switch try channel.readInbound(as: HTTPServerRequestPart.self) {
case .some(.head(let h)):
XCTAssertEqual(h.method, .OPTIONS)
case let t:
XCTFail("Expected .head, got \(String(describing: t))")
}
switch channel.readInbound(as: HTTPServerRequestPart.self) {
switch try channel.readInbound(as: HTTPServerRequestPart.self) {
case .some(.end):
// ok
break
@ -1047,14 +1047,14 @@ class HTTPUpgradeTestCase: XCTestCase {
}
switch channel.readInbound(as: HTTPServerRequestPart.self) {
switch try channel.readInbound(as: HTTPServerRequestPart.self) {
case .some(.head(let h)):
XCTAssertEqual(h.method, .GET)
case let t:
XCTFail("Expected .head, got \(String(describing: t))")
}
switch channel.readInbound(as: HTTPServerRequestPart.self) {
switch try channel.readInbound(as: HTTPServerRequestPart.self) {
case .some(.end):
// ok
break
@ -1062,7 +1062,7 @@ class HTTPUpgradeTestCase: XCTestCase {
XCTFail("Expected .head, got \(String(describing: t))")
}
XCTAssertNil(channel.readInbound(as: HTTPServerRequestPart.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound(as: HTTPServerRequestPart.self)))
}
func testRemovesAllHTTPRelatedHandlersAfterUpgrade() throws {

View File

@ -109,7 +109,7 @@ class ApplicationProtocolNegotiationHandlerTests: XCTestCase {
// The data we write should not be buffered.
try channel.writeInbound("hello")
XCTAssertEqual(channel.readInbound()!, "hello")
XCTAssertNoThrow(XCTAssertEqual(try channel.readInbound()!, "hello"))
XCTAssertFalse(try channel.finish())
}
@ -132,15 +132,15 @@ class ApplicationProtocolNegotiationHandlerTests: XCTestCase {
try channel.writeInbound("writes")
try channel.writeInbound("are")
try channel.writeInbound("buffered")
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
// Complete the pipeline swap.
continuePromise.succeed(())
// Now everything should have been unbuffered.
XCTAssertEqual(channel.readInbound()!, "writes")
XCTAssertEqual(channel.readInbound()!, "are")
XCTAssertEqual(channel.readInbound()!, "buffered")
XCTAssertNoThrow(XCTAssertEqual(try channel.readInbound()!, "writes"))
XCTAssertNoThrow(XCTAssertEqual(try channel.readInbound()!, "are"))
XCTAssertNoThrow(XCTAssertEqual(try channel.readInbound()!, "buffered"))
XCTAssertFalse(try channel.finish())
}
@ -196,7 +196,7 @@ class ApplicationProtocolNegotiationHandlerTests: XCTestCase {
// Now satisfy the future, which forces data unbuffering. This should fire readComplete.
continuePromise.succeed(())
XCTAssertEqual(channel.readInbound()!, "a write")
XCTAssertNoThrow(XCTAssertEqual(try channel.readInbound()!, "a write"))
XCTAssertEqual(readCompleteHandler.readCompleteCount, 2)

View File

@ -281,14 +281,14 @@ class SNIHandlerTest: XCTestCase {
try channel.writeInbound(writeableData)
loop.run()
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
try channel.pipeline.assertContains(handler: handler)
}
// The callback should now have fired, but the handler should still not have
// sent on any data and should still be in the pipeline.
XCTAssertTrue(called)
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
try channel.pipeline.assertContains(handler: handler)
// Now we're going to complete the promise and run the loop. This should cause the complete
@ -296,7 +296,7 @@ class SNIHandlerTest: XCTestCase {
continuePromise.succeed(())
loop.run()
let writtenBuffer: ByteBuffer = channel.readInbound() ?? channel.allocator.buffer(capacity: 0)
let writtenBuffer: ByteBuffer = try channel.readInbound() ?? channel.allocator.buffer(capacity: 0)
let writtenData = writtenBuffer.getData(at: writtenBuffer.readerIndex, length: writtenBuffer.readableBytes)
let expectedData = Data(base64Encoded: clientHello, options: .ignoreUnknownCharacters)!
XCTAssertEqual(writtenData, expectedData)
@ -330,7 +330,7 @@ class SNIHandlerTest: XCTestCase {
// The callback should have fired, but the handler should not have
// sent on any data and should still be in the pipeline.
XCTAssertTrue(called)
XCTAssertNil(channel.readInbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound(as: ByteBuffer.self)))
try channel.pipeline.assertContains(handler: handler)
// Now we're going to complete the promise and run the loop. This should cause the complete
@ -338,7 +338,7 @@ class SNIHandlerTest: XCTestCase {
continuePromise.succeed(())
loop.run()
let writtenBuffer: ByteBuffer? = channel.readInbound()
let writtenBuffer: ByteBuffer? = try channel.readInbound()
if let writtenBuffer = writtenBuffer {
let writtenData = writtenBuffer.getData(at: writtenBuffer.readerIndex, length: writtenBuffer.readableBytes)
let expectedData = Data(base64Encoded: clientHello, options: .ignoreUnknownCharacters)!
@ -369,7 +369,7 @@ class SNIHandlerTest: XCTestCase {
// The callback should not have fired, the handler should still be in the pipeline,
// and no data should have been written.
XCTAssertNil(channel.readInbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound(as: ByteBuffer.self)))
try channel.pipeline.assertContains(handler: handler)
XCTAssertNoThrow(try channel.finish())

View File

@ -44,18 +44,26 @@ private final class IndexWritingHandler: ChannelDuplexHandler {
private extension EmbeddedChannel {
func assertReadIndexOrder(_ order: [UInt8]) {
XCTAssertTrue(try self.writeInbound(self.allocator.buffer(capacity: 32)))
var outBuffer: ByteBuffer = self.readInbound()!
XCTAssertEqual(outBuffer.readBytes(length: outBuffer.readableBytes)!, order)
do {
var outBuffer: ByteBuffer = try self.readInbound()!
XCTAssertEqual(outBuffer.readBytes(length: outBuffer.readableBytes)!, order)
} catch {
XCTFail("unexpected error: \(error)")
}
}
func assertWriteIndexOrder(_ order: [UInt8]) {
XCTAssertTrue(try self.writeOutbound(self.allocator.buffer(capacity: 32)))
guard var outBuffer2 = self.readOutbound(as: ByteBuffer.self) else {
XCTFail("Could not read byte buffer")
return
do {
guard var outBuffer2 = try self.readOutbound(as: ByteBuffer.self) else {
XCTFail("Could not read byte buffer")
return
}
XCTAssertEqual(outBuffer2.readBytes(length: outBuffer2.readableBytes)!, order)
} catch {
XCTFail("unexpected error: \(error)")
}
XCTAssertEqual(outBuffer2.readBytes(length: outBuffer2.readableBytes)!, order)
}
}
@ -112,12 +120,12 @@ class ChannelPipelineTest: XCTestCase {
}).wait()
XCTAssertNoThrow(try channel.writeAndFlush(NIOAny("msg")).wait() as Void)
if let data = channel.readOutbound(as: ByteBuffer.self) {
if let data = try channel.readOutbound(as: ByteBuffer.self) {
XCTAssertEqual(buf, data)
} else {
XCTFail("couldn't read from channel")
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertFalse(try channel.finish())
}
@ -188,14 +196,14 @@ class ChannelPipelineTest: XCTestCase {
channel.pipeline.removeHandler(h)
}.wait()
XCTAssertEqual(Optional<Int>.some(1), channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(Optional<Int>.some(1), try channel.readInbound()))
XCTAssertFalse(try channel.finish())
}
func testEmptyPipelineWorks() throws {
let channel = EmbeddedChannel()
XCTAssertTrue(try assertNoThrowWithValue(channel.writeInbound(2)))
XCTAssertEqual(Optional<Int>.some(2), channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(Optional<Int>.some(2), try channel.readInbound()))
XCTAssertFalse(try channel.finish())
}
@ -297,10 +305,10 @@ class ChannelPipelineTest: XCTestCase {
try channel.writeInbound([])
loop.run()
XCTAssertEqual([2, 6], channel.readInbound()!)
XCTAssertNoThrow(XCTAssertEqual([2, 6], try channel.readInbound()!))
/* the first thing, we should receive is `[-2]` as it shouldn't hit any `MarkingOutboundHandler`s (`4`) */
var outbound = channel.readOutbound(as: ByteBuffer.self)
var outbound = try channel.readOutbound(as: ByteBuffer.self)
if var buf = outbound {
XCTAssertEqual("[-2]", buf.readString(length: buf.readableBytes))
} else {
@ -308,7 +316,7 @@ class ChannelPipelineTest: XCTestCase {
}
/* the next thing we should receive is `[-2, 4]` as the first `WriteOnReadHandler` (receiving `[2]`) is behind the `MarkingOutboundHandler` (`4`) */
outbound = channel.readOutbound()
outbound = try channel.readOutbound()
if var buf = outbound {
XCTAssertEqual("[-2, 4]", buf.readString(length: buf.readableBytes))
} else {
@ -316,15 +324,15 @@ class ChannelPipelineTest: XCTestCase {
}
/* and finally, we're waiting for `[-2, -6, 4]` as the second `WriteOnReadHandler`s (receiving `[2, 4]`) is behind the `MarkingOutboundHandler` (`4`) */
outbound = channel.readOutbound()
outbound = try channel.readOutbound()
if var buf = outbound {
XCTAssertEqual("[-2, -6, 4]", buf.readString(length: buf.readableBytes))
} else {
XCTFail("wrong contents: \(outbound.debugDescription)")
}
XCTAssertNil(channel.readInbound())
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertFalse(try channel.finish())
}
@ -708,12 +716,12 @@ class ChannelPipelineTest: XCTestCase {
context.fireErrorCaught(DummyError())
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
channel.pipeline.removeHandler(context: context, promise: removalPromise)
XCTAssertNoThrow(try removalPromise.futureResult.wait())
guard case .some(.byteBuffer(let receivedBuffer)) = channel.readOutbound(as: IOData.self) else {
guard case .some(.byteBuffer(let receivedBuffer)) = try channel.readOutbound(as: IOData.self) else {
XCTFail("No buffer")
return
}
@ -748,13 +756,13 @@ class ChannelPipelineTest: XCTestCase {
var buffer = channel.allocator.buffer(capacity: 1024)
buffer.writeStaticString("Hello, world!")
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
channel.pipeline.removeHandler(context: context).whenSuccess {
context.writeAndFlush(NIOAny(buffer), promise: nil)
context.fireErrorCaught(DummyError())
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
}
@ -785,11 +793,11 @@ class ChannelPipelineTest: XCTestCase {
XCTFail("unexpected error: \($0)")
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
channel.pipeline.removeHandler(name: "TestHandler", promise: removalPromise)
XCTAssertEqual(channel.readOutbound(), buffer)
XCTAssertNoThrow(XCTAssertEqual(try channel.readOutbound(), buffer))
do {
try channel.throwIfErrorCaught()
@ -820,13 +828,13 @@ class ChannelPipelineTest: XCTestCase {
var buffer = channel.allocator.buffer(capacity: 1024)
buffer.writeStaticString("Hello, world!")
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
channel.pipeline.removeHandler(name: "TestHandler").whenSuccess {
context.writeAndFlush(NIOAny(buffer), promise: nil)
context.fireErrorCaught(DummyError())
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
}
@ -856,11 +864,11 @@ class ChannelPipelineTest: XCTestCase {
context.fireErrorCaught(DummyError())
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
channel.pipeline.removeHandler(handler, promise: removalPromise)
XCTAssertEqual(channel.readOutbound(), buffer)
XCTAssertNoThrow(XCTAssertEqual(try channel.readOutbound(), buffer))
do {
try channel.throwIfErrorCaught()
@ -892,13 +900,13 @@ class ChannelPipelineTest: XCTestCase {
var buffer = channel.allocator.buffer(capacity: 1024)
buffer.writeStaticString("Hello, world!")
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
channel.pipeline.removeHandler(handler).whenSuccess {
context.writeAndFlush(NIOAny(buffer), promise: nil)
context.fireErrorCaught(DummyError())
}
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(try channel.throwIfErrorCaught())
}

View File

@ -134,7 +134,7 @@ public class ByteToMessageDecoderTest: XCTestCase {
buffer.moveWriterIndex(to: writerIndex - 1)
channel.pipeline.fireChannelRead(NIOAny(buffer))
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
channel.pipeline.fireChannelRead(NIOAny(buffer.getSlice(at: writerIndex - 1, length: 1)!))
@ -145,10 +145,10 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTAssertNoThrow(try channel.finish())
XCTAssertEqual(Int32(1), channel.readInbound())
XCTAssertEqual(Int32(2), channel.readInbound())
XCTAssertEqual(Int32(3), channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(Int32(1), try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual(Int32(2), try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual(Int32(3), try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
}
func testDecoderPropagatesChannelInactive() throws {
@ -163,7 +163,7 @@ public class ByteToMessageDecoderTest: XCTestCase {
var buffer = channel.allocator.buffer(capacity: 32)
buffer.writeInteger(Int32(1))
channel.pipeline.fireChannelRead(NIOAny(buffer))
XCTAssertEqual(Int32(1), channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(Int32(1), try channel.readInbound()))
XCTAssertFalse(inactivePromiser.channelInactivePromise.futureResult.isFulfilled)
@ -310,11 +310,16 @@ public class ByteToMessageDecoderTest: XCTestCase {
inputBuffer.clear()
func readOneInboundString() -> String {
switch channel.readInbound(as: ByteBuffer.self) {
case .some(let buffer):
return String(decoding: buffer.readableBytesView, as: Unicode.UTF8.self)
case .none:
XCTFail("expected ByteBuffer found nothing")
do {
switch try channel.readInbound(as: ByteBuffer.self) {
case .some(let buffer):
return String(decoding: buffer.readableBytesView, as: Unicode.UTF8.self)
case .none:
XCTFail("expected ByteBuffer found nothing")
return "no, error from \(#line)"
}
} catch {
XCTFail("unexpected error: \(error)")
return "no, error from \(#line)"
}
}
@ -325,7 +330,7 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTAssertEqual("3", readOneInboundString())
XCTAssertEqual("4", readOneInboundString())
XCTAssertEqual("5", readOneInboundString())
XCTAssertNil(channel.readInbound(as: IOData.self))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound(as: IOData.self)))
XCTAssertTrue(testDecoder.hasReentranced)
}
@ -372,10 +377,16 @@ public class ByteToMessageDecoderTest: XCTestCase {
channel.embeddedEventLoop.run()
XCTAssertFalse(channel.isActive)
XCTAssertEqual("1", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("23", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("4567890", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual("1", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("23", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("4567890", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertEqual(1, decoder.decodeLastCalls)
}
@ -396,12 +407,22 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTAssertNoThrow(try channel.close().wait())
XCTAssertFalse(channel.isActive)
XCTAssertEqual("12", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("34", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("56", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("78", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("90", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual("12", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("34", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("56", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("78", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("90", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("x", String(decoding: try lastPromise.futureResult.wait().readableBytesView,
as: Unicode.UTF8.self)))
@ -432,12 +453,22 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTFail("unexpected error: \(error)")
}
XCTAssertEqual("12", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("34", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("56", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("78", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertEqual("90", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self) })
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual("12", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("34", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("56", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("78", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertEqual("90", try channel.readInbound(as: ByteBuffer.self).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
channel.embeddedEventLoop.run()
XCTAssertNoThrow(XCTAssertEqual("x", String(decoding: try lastPromise.futureResult.wait().readableBytesView,
@ -482,17 +513,17 @@ public class ByteToMessageDecoderTest: XCTestCase {
buffer.writeStaticString("4567890qwer")
XCTAssertNoThrow(try channel.writeInbound(buffer))
XCTAssertEqual(1, channel.readInbound())
XCTAssertEqual(2, channel.readInbound())
XCTAssertEqual(3, channel.readInbound())
XCTAssertEqual(4, channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(1, try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual(2, try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual(3, try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual(4, try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(try channel.close().wait())
XCTAssertFalse(channel.isActive)
XCTAssertEqual(-4, channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(-4, try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
}
func testReentrantChannelReadWhileWholeBufferIsBeingProcessed() {
@ -524,12 +555,12 @@ public class ByteToMessageDecoderTest: XCTestCase {
buffer.writeStaticString("0123456789abcdef")
XCTAssertNoThrow(try channel.writeInbound(buffer))
XCTAssertEqual("0123456789abcdef", channel.readInbound())
XCTAssertEqual("01234567", channel.readInbound())
XCTAssertEqual("0123", channel.readInbound())
XCTAssertEqual("01", channel.readInbound())
XCTAssertEqual("0", channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual("0123456789abcdef", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("01234567", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("0123", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("01", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("0", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
}
func testReentrantChannelCloseInChannelRead() {
@ -559,9 +590,9 @@ public class ByteToMessageDecoderTest: XCTestCase {
buffer.writeStaticString("0123456789abcdefQWER")
XCTAssertNoThrow(try channel.writeInbound(buffer))
XCTAssertEqual("0123456789abcdef", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)})
XCTAssertEqual("QWER", channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)})
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual("0123456789abcdef", try channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)}))
XCTAssertNoThrow(XCTAssertEqual("QWER", try channel.readInbound(as: ByteBuffer.self).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)}))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
}
func testHandlerRemoveInChannelRead() {
@ -591,10 +622,14 @@ public class ByteToMessageDecoderTest: XCTestCase {
buffer.writeStaticString("0123456789abcdefQWER")
XCTAssertNoThrow(try channel.writeInbound(buffer))
XCTAssertEqual("0123456789abcdef", (channel.readInbound() as ByteBuffer?).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)})
XCTAssertEqual("0123456789abcdef", (try channel.readInbound() as ByteBuffer?).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
})
channel.embeddedEventLoop.run()
XCTAssertEqual("QWER", (channel.readInbound() as ByteBuffer?).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)})
XCTAssertNil(channel.readInbound())
XCTAssertEqual("QWER", (try channel.readInbound() as ByteBuffer?).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
})
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
}
func testChannelCloseInChannelRead() {
@ -631,9 +666,11 @@ public class ByteToMessageDecoderTest: XCTestCase {
buffer.writeStaticString("0123456789abcdefQWER")
XCTAssertNoThrow(try channel.writeInbound(buffer))
XCTAssertEqual("0123456789abcdef", (channel.readInbound() as ByteBuffer?).map { String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)})
XCTAssertNoThrow(XCTAssertEqual("0123456789abcdef", (try channel.readInbound() as ByteBuffer?).map {
String(decoding: $0.readableBytesView, as: Unicode.UTF8.self)
}))
channel.embeddedEventLoop.run()
XCTAssertNil(channel.readInbound()) // no leftovers are forwarded
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound())) // no leftovers are forwarded
}
func testDecodeLoopGetsInterruptedWhenRemovalIsTriggered() {
@ -680,8 +717,11 @@ public class ByteToMessageDecoderTest: XCTestCase {
channel.embeddedEventLoop.run()
XCTAssertEqual(1, handler.decoder?.callsToDecode)
XCTAssertEqual(2, handler.decoder?.callsToDecodeLast)
["0", "1234#1", "5678#2"].forEach {
XCTAssertEqual($0, channel.readInbound())
["0", "1234#1", "5678#2"].forEach { expected in
func workaroundSR9815() {
XCTAssertNoThrow(XCTAssertEqual(expected, try channel.readInbound()))
}
workaroundSR9815()
}
}
@ -709,11 +749,11 @@ public class ByteToMessageDecoderTest: XCTestCase {
let channel = EmbeddedChannel(handler: ByteToMessageHandler(decoder))
XCTAssertNoThrow(try channel.connect(to: SocketAddress(ipAddress: "1.2.3.4", port: 5678)).wait())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(try channel.close().wait())
XCTAssertNotNil(channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNotNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertEqual(1, decoder.decodeLastCalls)
}
@ -742,17 +782,17 @@ public class ByteToMessageDecoderTest: XCTestCase {
let channel = EmbeddedChannel(handler: ByteToMessageHandler(decoder))
XCTAssertNoThrow(try channel.connect(to: SocketAddress(ipAddress: "1.2.3.4", port: 5678)).wait())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
channel.pipeline.fireUserInboundEventTriggered(ChannelEvent.inputClosed)
XCTAssertNotNil(channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNotNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertEqual(1, decoder.decodeLastCalls)
XCTAssertNoThrow(XCTAssertFalse(try channel.finish()))
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertEqual(1, decoder.decodeLastCalls)
}
@ -884,12 +924,12 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTAssertNoThrow(try channel.writeOutbound(2))
XCTAssertNoThrow(try channel.writeOutbound(3))
XCTAssertEqual([1, 2, 3], decoder.allObservedWrites)
XCTAssertEqual("a", channel.readInbound())
XCTAssertEqual("b", channel.readInbound())
XCTAssertEqual("c", channel.readInbound())
XCTAssertEqual(1, channel.readOutbound())
XCTAssertEqual(2, channel.readOutbound())
XCTAssertEqual(3, channel.readOutbound())
XCTAssertNoThrow(XCTAssertEqual("a", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("b", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("c", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual(1, try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual(2, try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual(3, try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertFalse(try channel.finish()))
}
@ -957,25 +997,25 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTAssertNoThrow(try channel.writeOutbound("after"))
XCTAssertEqual(["before", "O: 1: a", "O: 2: b", "O: 3: X", "O: 4: x", "O: 5: y", "O: 6: z", "after"],
decoder.allObservedWrites)
XCTAssertEqual("I: 1: a", channel.readInbound())
XCTAssertEqual("I: 2: b", channel.readInbound())
XCTAssertEqual("I: 3: X", channel.readInbound())
XCTAssertEqual("I: 4: x", channel.readInbound())
XCTAssertEqual("I: 5: y", channel.readInbound())
XCTAssertEqual("I: 6: z", channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertEqual("before @ 0", channel.readOutbound())
XCTAssertNoThrow(XCTAssertEqual("I: 1: a", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("I: 2: b", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("I: 3: X", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("I: 4: x", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("I: 5: y", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("I: 6: z", try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertEqual("before @ 0", try channel.readOutbound()))
// in the next line, it's important that it ends in '@ 1' because that means the outbound write was forwarded
// when the Decoder was after decode run 1, ie. before it ever saw the 'b'. It's important we forward writes
// as soon as possible for correctness but also to keep as few queued writes as possible.
XCTAssertEqual("O: 1: a @ 1", channel.readOutbound())
XCTAssertEqual("O: 2: b @ 2", channel.readOutbound())
XCTAssertEqual("O: 3: X @ 3", channel.readOutbound())
XCTAssertEqual("O: 4: x @ 4", channel.readOutbound())
XCTAssertEqual("O: 5: y @ 5", channel.readOutbound())
XCTAssertEqual("O: 6: z @ 6", channel.readOutbound())
XCTAssertEqual("after @ 6", channel.readOutbound())
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertEqual("O: 1: a @ 1", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual("O: 2: b @ 2", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual("O: 3: X @ 3", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual("O: 4: x @ 4", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual("O: 5: y @ 5", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual("O: 6: z @ 6", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertEqual("after @ 6", try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertFalse(try channel.finish()))
}
@ -1007,7 +1047,7 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTAssertThrowsError(try channel.writeInbound(buffer)) { error in
XCTAssert(error is Decoder.DecodeError)
}
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertThrowsError(try channel.writeInbound(buffer)) { error in
if case .some(ByteToMessageDecoderError.dataReceivedInErrorState(let error, let receivedBuffer)) =
@ -1018,7 +1058,7 @@ public class ByteToMessageDecoderTest: XCTestCase {
XCTFail("wrong error: \(error)")
}
}
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertFalse(try channel.finish()))
}
@ -1051,12 +1091,12 @@ public class ByteToMessageDecoderTest: XCTestCase {
var buffer = channel.allocator.buffer(capacity: 1)
buffer.writeString("x")
XCTAssertNoThrow(try channel.writeInbound(buffer))
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertThrowsError(try channel.finish()) { error in
XCTAssert(error is Decoder.DecodeError)
}
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(try channel.writeInbound(buffer)) // this will go through because the decoder is already 'done'
}
@ -1151,7 +1191,7 @@ public class MessageToByteEncoderTest: XCTestCase {
_ = try channel.writeAndFlush(NIOAny(Int32(5))).wait()
if var buffer = channel.readOutbound(as: ByteBuffer.self) {
if var buffer = try channel.readOutbound(as: ByteBuffer.self) {
XCTAssertEqual(Int32(5), buffer.readInteger())
XCTAssertEqual(0, buffer.readableBytes)
} else {

View File

@ -23,9 +23,9 @@ class EmbeddedChannelTest: XCTestCase {
XCTAssertTrue(try channel.writeOutbound(buf))
XCTAssertTrue(try channel.finish())
XCTAssertEqual(buf, channel.readOutbound())
XCTAssertNil(channel.readOutbound())
XCTAssertNil(channel.readInbound())
XCTAssertNoThrow(XCTAssertEqual(buf, try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
}
func testWriteInboundByteBuffer() throws {
@ -35,9 +35,9 @@ class EmbeddedChannelTest: XCTestCase {
XCTAssertTrue(try channel.writeInbound(buf))
XCTAssertTrue(try channel.finish())
XCTAssertEqual(buf, channel.readInbound())
XCTAssertNil(channel.readInbound())
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertEqual(buf, try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound()))
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
}
func testWriteInboundByteBufferReThrow() throws {
@ -184,10 +184,10 @@ class EmbeddedChannelTest: XCTestCase {
var buf = ByteBufferAllocator().buffer(capacity: 1)
buf.writeBytes([1])
let writeFuture = channel.write(buf)
XCTAssertNil(channel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try channel.readOutbound()))
XCTAssertFalse(writeFuture.isFulfilled)
channel.flush()
XCTAssertNotNil(channel.readOutbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNotNil(try channel.readOutbound(as: ByteBuffer.self)))
XCTAssertTrue(writeFuture.isFulfilled)
XCTAssertNoThrow(try XCTAssertFalse(channel.finish()))
}

View File

@ -18,9 +18,9 @@ import NIOHTTP1
@testable import NIOWebSocket
extension EmbeddedChannel {
func readAllInboundBuffers() -> ByteBuffer {
func readAllInboundBuffers() throws -> ByteBuffer {
var buffer = self.allocator.buffer(capacity: 100)
while var writtenData: ByteBuffer = self.readInbound() {
while var writtenData: ByteBuffer = try self.readInbound() {
buffer.writeBuffer(&writtenData)
}
@ -57,11 +57,11 @@ private func interactInMemory(_ first: EmbeddedChannel, _ second: EmbeddedChanne
repeat {
operated = false
if let data = first.readOutbound(as: ByteBuffer.self) {
if let data = try first.readOutbound(as: ByteBuffer.self) {
operated = true
try second.writeInbound(data)
}
if let data = second.readOutbound(as: ByteBuffer.self) {
if let data = try second.readOutbound(as: ByteBuffer.self) {
operated = true
try first.writeInbound(data)
}
@ -139,10 +139,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
}
func testUpgradeWithProtocolName() throws {
@ -159,10 +158,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
}
func testCanRejectUpgrade() throws {
@ -194,7 +192,7 @@ class EndToEndTests: XCTestCase {
}
// Nothing gets written.
XCTAssertEqual(server.readAllOutboundBuffers().allAsString(), "")
XCTAssertNoThrow(XCTAssertEqual(try server.readAllOutboundBuffers().allAsString(), ""))
}
func testCanDelayAcceptingUpgrade() throws {
@ -227,7 +225,7 @@ class EndToEndTests: XCTestCase {
XCTAssertNotNil(acceptPromise)
// No upgrade should have occurred yet.
XCTAssertNil(client.readInbound(as: ByteBuffer.self))
XCTAssertNoThrow(XCTAssertNil(try client.readInbound(as: ByteBuffer.self)))
XCTAssertFalse(upgradeComplete)
// Satisfy the promise. This will cause the upgrade to complete.
@ -235,10 +233,9 @@ class EndToEndTests: XCTestCase {
XCTAssertTrue(upgradeComplete)
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
}
func testRequiresVersion13() throws {
@ -266,7 +263,7 @@ class EndToEndTests: XCTestCase {
}
// Nothing gets written.
XCTAssertEqual(server.readAllOutboundBuffers().allAsString(), "")
XCTAssertNoThrow(XCTAssertEqual(try server.readAllOutboundBuffers().allAsString(), ""))
}
func testRequiresVersionHeader() throws {
@ -294,7 +291,7 @@ class EndToEndTests: XCTestCase {
}
// Nothing gets written.
XCTAssertEqual(server.readAllOutboundBuffers().allAsString(), "")
XCTAssertNoThrow(XCTAssertEqual(try server.readAllOutboundBuffers().allAsString(), ""))
}
func testRequiresKeyHeader() throws {
@ -322,7 +319,7 @@ class EndToEndTests: XCTestCase {
}
// Nothing gets written.
XCTAssertEqual(server.readAllOutboundBuffers().allAsString(), "")
XCTAssertNoThrow(XCTAssertEqual(try server.readAllOutboundBuffers().allAsString(), ""))
}
func testUpgradeMayAddCustomHeaders() throws {
@ -343,10 +340,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade", "TestHeader: TestValue"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade", "TestHeader: TestValue"]))
}
func testMayRegisterMultipleWebSocketEndpoints() throws {
@ -374,10 +370,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade", "Target: third"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade", "Target: third"]))
}
func testSendAFewFrames() throws {
@ -398,10 +393,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
// Put a frame encoder in the client pipeline.
XCTAssertNoThrow(try client.pipeline.addHandler(WebSocketFrameEncoder()).wait())
@ -436,10 +430,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
let decoder = ((try server.pipeline.context(handlerType: ByteToMessageHandler<WebSocketFrameDecoder>.self).wait()).handler as! ByteToMessageHandler<WebSocketFrameDecoder>).decoder
XCTAssertEqual(16, decoder?.maxFrameSize)
@ -463,10 +456,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
// Send a fake frame header that claims this is a ping frame with 126 bytes of data.
var data = client.allocator.buffer(capacity: 12)
@ -486,8 +478,7 @@ class EndToEndTests: XCTestCase {
XCTAssertEqual(recorder.errors.first as? NIOWebSocketError, .some(.multiByteControlFrameLength))
// The client should have received a close frame, if we'd continued interacting.
let errorFrame = server.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual(try server.readAllOutboundBytes(), [0x88, 0x02, 0x03, 0xEA]))
}
func testNoAutomaticErrorHandling() throws {
@ -509,10 +500,9 @@ class EndToEndTests: XCTestCase {
XCTAssertNoThrow(try client.writeString(upgradeRequest).wait())
XCTAssertNoThrow(try interactInMemory(client, server))
let receivedResponse = client.readAllInboundBuffers().allAsString()
assertResponseIs(response: receivedResponse,
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"])
XCTAssertNoThrow(assertResponseIs(response: try client.readAllInboundBuffers().allAsString(),
expectedResponseLine: "HTTP/1.1 101 Switching Protocols",
expectedResponseHeaders: ["Upgrade: websocket", "Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=", "Connection: upgrade"]))
// Send a fake frame header that claims this is a ping frame with 126 bytes of data.
var data = client.allocator.buffer(capacity: 12)
@ -532,7 +522,6 @@ class EndToEndTests: XCTestCase {
XCTAssertEqual(recorder.errors.first as? NIOWebSocketError, .some(.multiByteControlFrameLength))
// The client should not have received a close frame, if we'd continued interacting.
let errorFrame = server.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [])
XCTAssertNoThrow(XCTAssertEqual([], try server.readAllOutboundBytes()))
}
}

View File

@ -79,17 +79,23 @@ public class WebSocketFrameDecoderTest: XCTestCase {
private func frameForFrame(_ frame: WebSocketFrame) -> WebSocketFrame? {
self.encoderChannel.writeAndFlush(frame, promise: nil)
while let d = self.encoderChannel.readOutbound(as: ByteBuffer.self) {
XCTAssertNoThrow(try self.decoderChannel.writeInbound(d))
}
guard let producedFrame: WebSocketFrame = self.decoderChannel.readInbound() else {
XCTFail("Did not produce a frame")
do {
while let d = try self.encoderChannel.readOutbound(as: ByteBuffer.self) {
XCTAssertNoThrow(try self.decoderChannel.writeInbound(d))
}
guard let producedFrame: WebSocketFrame = try self.decoderChannel.readInbound() else {
XCTFail("Did not produce a frame")
return nil
}
// Should only have gotten one frame!
XCTAssertNoThrow(XCTAssertNil(try self.decoderChannel.readInbound(as: WebSocketFrame.self)))
return producedFrame
} catch {
XCTFail("unexpected error: \(error)")
return nil
}
// Should only have gotten one frame!
XCTAssertNil(self.decoderChannel.readInbound(as: WebSocketFrame.self))
return producedFrame
}
private func assertFrameRoundTrips(frame: WebSocketFrame) {
@ -249,8 +255,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xF1])
XCTAssertNoThrow(XCTAssertEqual([0x88, 0x02, 0x03, 0xF1], try self.decoderChannel.readAllOutboundBytes()))
}
public func testDecoderRejectsFragmentedControlFrames() throws {
@ -269,8 +274,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual([0x88, 0x02, 0x03, 0xEA], try self.decoderChannel.readAllOutboundBytes()))
}
public func testDecoderRejectsMultibyteControlFrameLengths() throws {
@ -289,8 +293,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual([0x88, 0x02, 0x03, 0xEA], try self.decoderChannel.readAllOutboundBytes()))
}
func testIgnoresFurtherDataAfterRejectedFrame() throws {
@ -311,8 +314,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual([0x88, 0x02, 0x03, 0xEA], try self.decoderChannel.readAllOutboundBytes()))
// Now write another broken frame, this time an overlong frame.
// No error should occur here.
@ -321,7 +323,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
XCTAssertNoThrow(try self.decoderChannel.writeInbound(self.buffer))
// No extra data should have been sent.
XCTAssertNil(self.decoderChannel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try self.decoderChannel.readOutbound()))
// Allow the channel to close.
swallower.allowClose()
@ -342,17 +344,17 @@ public class WebSocketFrameDecoderTest: XCTestCase {
// a double-parse edge case.
self.encoderChannel.write(frame, promise: nil)
var frameBuffer = self.decoderChannel.allocator.buffer(capacity: 10)
while var d = self.encoderChannel.readOutbound(as: ByteBuffer.self) {
while var d = try self.encoderChannel.readOutbound(as: ByteBuffer.self) {
frameBuffer.writeBuffer(&d)
}
XCTAssertNoThrow(try self.decoderChannel.writeInbound(frameBuffer))
// No data should have been sent or received.
XCTAssertNil(self.decoderChannel.readOutbound())
XCTAssertNil(self.decoderChannel.readInbound(as: WebSocketFrame.self))
XCTAssertNoThrow(XCTAssertNil(try self.decoderChannel.readOutbound()))
XCTAssertNoThrow(XCTAssertNil(try self.decoderChannel.readInbound(as: WebSocketFrame.self)))
}
public func testDecoderRejectsOverlongFramesWithNoAutomaticErrorHandling() throws {
public func testDecoderRejectsOverlongFramesWithNoAutomaticErrorHandling() {
// We need to insert a decoder that doesn't do error handling. We still insert
// an encoder because we want to fail gracefully if a frame is written.
self.swapDecoder(for: ByteToMessageHandler(WebSocketFrameDecoder(automaticErrorHandling: false)))
@ -372,8 +374,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// No error frame should be written.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [])
XCTAssertNoThrow(XCTAssertEqual([], try self.decoderChannel.readAllOutboundBytes()))
}
public func testDecoderRejectsFragmentedControlFramesWithNoAutomaticErrorHandling() throws {
@ -395,8 +396,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// No error frame should be written.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [])
XCTAssertNoThrow(XCTAssertEqual([], try self.decoderChannel.readAllOutboundBytes()))
}
public func testDecoderRejectsMultibyteControlFrameLengthsWithNoAutomaticErrorHandling() throws {
@ -418,11 +418,10 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// No error frame should be written.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [])
XCTAssertNoThrow(XCTAssertEqual([], try self.decoderChannel.readAllOutboundBytes()))
}
func testIgnoresFurtherDataAfterRejectedFrameWithNoAutomaticErrorHandling() throws {
func testIgnoresFurtherDataAfterRejectedFrameWithNoAutomaticErrorHandling() {
// We need to insert a decoder that doesn't do error handling. We still insert
// an encoder because we want to fail gracefully if a frame is written.
self.swapDecoder(for: ByteToMessageHandler(WebSocketFrameDecoder(automaticErrorHandling: false)))
@ -441,8 +440,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// No error frame should be written.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [])
XCTAssertNoThrow(XCTAssertEqual([], try self.decoderChannel.readAllOutboundBytes()))
// Now write another broken frame, this time an overlong frame.
// No error should occur here.
@ -451,7 +449,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
XCTAssertNoThrow(try self.decoderChannel.writeInbound(self.buffer))
// No extra data should have been sent.
XCTAssertNil(self.decoderChannel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try self.decoderChannel.readOutbound()))
}
public func testDecoderRejectsOverlongFramesWithSeparateErrorHandling() throws {
@ -475,8 +473,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xF1])
XCTAssertNoThrow(XCTAssertEqual([0x88, 0x02, 0x03, 0xF1], try self.decoderChannel.readAllOutboundBytes()))
}
public func testDecoderRejectsFragmentedControlFramesWithSeparateErrorHandling() throws {
@ -499,8 +496,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual([0x88, 0x02, 0x03, 0xEA], try self.decoderChannel.readAllOutboundBytes()))
}
public func testDecoderRejectsMultibyteControlFrameLengthsWithSeparateErrorHandling() throws {
@ -523,11 +519,10 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual(try self.decoderChannel.readAllOutboundBytes(), [0x88, 0x02, 0x03, 0xEA]))
}
func testIgnoresFurtherDataAfterRejectedFrameWithSeparateErrorHandling() throws {
func testIgnoresFurtherDataAfterRejectedFrameWithSeparateErrorHandling() {
let swallower = CloseSwallower()
// We need to insert a decoder that doesn't do error handling, and then a separate error
// handler.
@ -549,8 +544,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
}
// We expect that an error frame will have been written out.
let errorFrame = self.decoderChannel.readAllOutboundBytes()
XCTAssertEqual(errorFrame, [0x88, 0x02, 0x03, 0xEA])
XCTAssertNoThrow(XCTAssertEqual(try self.decoderChannel.readAllOutboundBytes(), [0x88, 0x02, 0x03, 0xEA]))
// Now write another broken frame, this time an overlong frame.
// No error should occur here.
@ -559,7 +553,7 @@ public class WebSocketFrameDecoderTest: XCTestCase {
XCTAssertNoThrow(try self.decoderChannel.writeInbound(self.buffer))
// No extra data should have been sent.
XCTAssertNil(self.decoderChannel.readOutbound())
XCTAssertNoThrow(XCTAssertNil(try self.decoderChannel.readOutbound()))
// Allow the channel to close.
swallower.allowClose()

View File

@ -17,17 +17,17 @@ import NIO
import NIOWebSocket
extension EmbeddedChannel {
func readAllOutboundBuffers() -> ByteBuffer {
func readAllOutboundBuffers() throws -> ByteBuffer {
var buffer = self.allocator.buffer(capacity: 100)
while var writtenData = self.readOutbound(as: ByteBuffer.self) {
while var writtenData = try self.readOutbound(as: ByteBuffer.self) {
buffer.writeBuffer(&writtenData)
}
return buffer
}
func readAllOutboundBytes() -> [UInt8] {
var buffer = self.readAllOutboundBuffers()
func readAllOutboundBytes() throws -> [UInt8] {
var buffer = try self.readAllOutboundBuffers()
return buffer.readBytes(length: buffer.readableBytes)!
}
}
@ -50,8 +50,7 @@ public class WebSocketFrameEncoderTest: XCTestCase {
private func assertFrameEncodes(frame: WebSocketFrame, expectedBytes: [UInt8]) {
self.channel.writeAndFlush(frame, promise: nil)
let writtenBytes = self.channel.readAllOutboundBytes()
XCTAssertEqual(writtenBytes, expectedBytes)
XCTAssertNoThrow(XCTAssertEqual(expectedBytes, try self.channel.readAllOutboundBytes()))
}
func testBasicFrameEncoding() throws {
@ -77,9 +76,8 @@ public class WebSocketFrameEncoderTest: XCTestCase {
let frame = WebSocketFrame(fin: true, opcode: .binary, data: self.buffer)
self.channel.writeAndFlush(frame, promise: nil)
let writtenBytes = self.channel.readAllOutboundBytes()
let expectedBytes: [UInt8] = [0x82, 0x7F, 0, 0, 0, 0, 0, 1, 0, 0]
XCTAssertEqual(writtenBytes[..<10], expectedBytes[...])
XCTAssertNoThrow(XCTAssertEqual(expectedBytes[...], try self.channel.readAllOutboundBytes()[..<10]))
}
func testEncodesEachReservedBitProperly() throws {