mirror of
https://github.com/apple/swift-nio-extras.git
synced 2025-05-16 09:52:28 +08:00
Motivation: Use B2MDVerifier for the B2MDs in NIOExtras. Already found one bug, separetely fixed in #51. Modifications: Write a basic validation test for all B2MDs. Result: Better test coverage.
138 lines
5.5 KiB
Swift
138 lines
5.5 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import XCTest
|
|
import NIO
|
|
import NIOExtras
|
|
import NIOTestUtils
|
|
|
|
class FixedLengthFrameDecoderTest: XCTestCase {
|
|
public func testDecodeIfFewerBytesAreSent() throws {
|
|
let channel = EmbeddedChannel()
|
|
|
|
let frameLength = 8
|
|
try channel.pipeline.addHandler(ByteToMessageHandler(FixedLengthFrameDecoder(frameLength: frameLength))).wait()
|
|
|
|
var buffer = channel.allocator.buffer(capacity: frameLength)
|
|
buffer.writeString("xxxx")
|
|
XCTAssertTrue(try channel.writeInbound(buffer).isEmpty)
|
|
XCTAssertTrue(try channel.writeInbound(buffer).isFull)
|
|
|
|
XCTAssertEqual("xxxxxxxx", try (channel.readInbound(as: ByteBuffer.self)?.readableBytesView).map {
|
|
String(decoding: $0, as: Unicode.UTF8.self)
|
|
})
|
|
XCTAssertTrue(try channel.finish().isClean)
|
|
}
|
|
|
|
public func testDecodeIfMoreBytesAreSent() throws {
|
|
let channel = EmbeddedChannel()
|
|
|
|
let frameLength = 8
|
|
try channel.pipeline.addHandler(ByteToMessageHandler(FixedLengthFrameDecoder(frameLength: frameLength))).wait()
|
|
|
|
var buffer = channel.allocator.buffer(capacity: 19)
|
|
buffer.writeString("xxxxxxxxaaaaaaaabbb")
|
|
XCTAssertTrue(try channel.writeInbound(buffer).isFull)
|
|
|
|
XCTAssertEqual("xxxxxxxx", try (channel.readInbound(as: ByteBuffer.self)?.readableBytesView).map {
|
|
String(decoding: $0, as: Unicode.UTF8.self)
|
|
})
|
|
|
|
XCTAssertEqual("aaaaaaaa", try (channel.readInbound(as: ByteBuffer.self)?.readableBytesView).map {
|
|
String(decoding: $0, as: Unicode.UTF8.self)
|
|
})
|
|
|
|
XCTAssertNoThrow(XCTAssertNil(try channel.readInbound(as: ByteBuffer.self)))
|
|
XCTAssertThrowsError(try channel.finish()) { error in
|
|
if let error = error as? NIOExtrasErrors.LeftOverBytesError {
|
|
XCTAssertEqual(3, error.leftOverBytes.readableBytes)
|
|
} else {
|
|
XCTFail("unexpected error: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
public func testRemoveHandlerWhenBufferIsNotEmpty() throws {
|
|
let channel = EmbeddedChannel()
|
|
|
|
let frameLength = 8
|
|
let handler = ByteToMessageHandler(FixedLengthFrameDecoder(frameLength: frameLength))
|
|
try channel.pipeline.addHandler(handler).wait()
|
|
|
|
var buffer = channel.allocator.buffer(capacity: 15)
|
|
buffer.writeString("xxxxxxxxxxxxxxx")
|
|
XCTAssertTrue(try channel.writeInbound(buffer).isFull)
|
|
|
|
XCTAssertEqual("xxxxxxxx", try (channel.readInbound(as: ByteBuffer.self)?.readableBytesView).map {
|
|
String(decoding: $0, as: Unicode.UTF8.self)
|
|
})
|
|
|
|
let removeFuture = channel.pipeline.removeHandler(handler)
|
|
(channel.eventLoop as! EmbeddedEventLoop).run()
|
|
XCTAssertNoThrow(try removeFuture.wait())
|
|
XCTAssertThrowsError(try channel.throwIfErrorCaught()) { error in
|
|
guard let error = error as? NIOExtrasErrors.LeftOverBytesError else {
|
|
XCTFail()
|
|
return
|
|
}
|
|
|
|
var expectedBuffer = channel.allocator.buffer(capacity: 7)
|
|
expectedBuffer.writeString("xxxxxxx")
|
|
XCTAssertEqual(error.leftOverBytes, expectedBuffer)
|
|
}
|
|
XCTAssertTrue(try channel.finish().isClean)
|
|
}
|
|
|
|
public func testRemoveHandlerWhenBufferIsEmpty() throws {
|
|
let channel = EmbeddedChannel()
|
|
|
|
let frameLength = 8
|
|
let handler = ByteToMessageHandler(FixedLengthFrameDecoder(frameLength: frameLength))
|
|
try channel.pipeline.addHandler(handler).wait()
|
|
|
|
var buffer = channel.allocator.buffer(capacity: 6)
|
|
buffer.writeString("xxxxxxxx")
|
|
XCTAssertTrue(try channel.writeInbound(buffer).isFull)
|
|
|
|
XCTAssertEqual("xxxxxxxx", try (channel.readInbound(as: ByteBuffer.self)?.readableBytesView).map {
|
|
String(decoding: $0, as: Unicode.UTF8.self)
|
|
})
|
|
|
|
let removeFuture = channel.pipeline.removeHandler(handler)
|
|
(channel.eventLoop as! EmbeddedEventLoop).run()
|
|
XCTAssertNoThrow(try removeFuture.wait())
|
|
XCTAssertNoThrow(try channel.throwIfErrorCaught())
|
|
XCTAssertTrue(try channel.finish().isClean)
|
|
}
|
|
|
|
func testBasicValidation() {
|
|
for length in 1 ... 20 {
|
|
let inputs = [
|
|
String(decoding: Array(repeating: UInt8(ascii: "a"), count: length), as: Unicode.UTF8.self),
|
|
String(decoding: Array(repeating: UInt8(ascii: "b"), count: length), as: Unicode.UTF8.self),
|
|
String(decoding: Array(repeating: UInt8(ascii: "c"), count: length), as: Unicode.UTF8.self),
|
|
]
|
|
func byteBuffer(_ string: String) -> ByteBuffer {
|
|
var buffer = ByteBufferAllocator().buffer(capacity: string.utf8.count)
|
|
buffer.writeString(string)
|
|
return buffer
|
|
}
|
|
let inputOutputPairs: [(String, [ByteBuffer])] = inputs.map { ($0, [byteBuffer($0)]) }
|
|
XCTAssertNoThrow(try ByteToMessageDecoderVerifier.verifyDecoder(stringInputOutputPairs: inputOutputPairs) {
|
|
FixedLengthFrameDecoder(frameLength: length)
|
|
})
|
|
}
|
|
}
|
|
}
|