mirror of
https://github.com/apple/swift-nio.git
synced 2026-05-20 20:30:36 +00:00
This is a followup to #2867 Some of the literals used in the test cases were too big to fit in an Int32 This is fine on 64-bit systems, because the literals are considered as `Int`, which is Int64 on those systems However, on 32-bit systems, those literals are considered as Int64 Change: Add `as Int64` where needed, to tell the compiler we want these literals to be treated as Int64, which should allow these tests to run on 32 bit systems too
139 lines
6.4 KiB
Swift
139 lines
6.4 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2024 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
|
|
|
|
@testable import NIOCore
|
|
|
|
final class ByteBufferQUICBinaryEncodingStrategyTests: XCTestCase {
|
|
// MARK: - writeEncodedInteger tests
|
|
|
|
func testWriteOneByteQUICVariableLengthInteger() {
|
|
// One byte, ie less than 63, just write out as-is
|
|
for number in 0..<63 {
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(number, to: &buffer)
|
|
XCTAssertEqual(bytesWritten, 1)
|
|
// The number is written exactly as is
|
|
XCTAssertEqual(buffer.readInteger(as: UInt8.self), UInt8(number))
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
}
|
|
|
|
func testWriteBigUInt8() {
|
|
// This test case specifically tests the scenario where 2 bytes are needed, but the number being written is UInt8.
|
|
// A naive implementation of the quic variable length integer encoder might check whether the number is in
|
|
// the range of 64..<16383, to determine that it should be written with 2 bytes.
|
|
// However, constructing such a range on a UInt8 would actually construct 64..<0, because 16383 can't be represented as UInt8.
|
|
// So this test makes sure we didn't make that mistake
|
|
let number: UInt8 = .max
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(number, to: &buffer)
|
|
XCTAssertEqual(bytesWritten, 2)
|
|
XCTAssertEqual(buffer.readInteger(as: UInt16.self), 0b01000000_11111111)
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
|
|
func testWriteTwoByteQUICVariableLengthInteger() {
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(0b00111011_10111101, to: &buffer)
|
|
XCTAssertEqual(bytesWritten, 2)
|
|
// We need to mask the first 2 bits with 01 to indicate this is a 2 byte integer
|
|
// Final result 0b01111011_10111101
|
|
XCTAssertEqual(buffer.readInteger(as: UInt16.self), 0b01111011_10111101)
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
|
|
func testWriteFourByteQUICVariableLengthInteger() {
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(0b00011101_01111111_00111110_01111101 as Int64, to: &buffer)
|
|
XCTAssertEqual(bytesWritten, 4)
|
|
// 2 bit mask is 10 for 4 bytes so this becomes 0b10011101_01111111_00111110_01111101
|
|
XCTAssertEqual(buffer.readInteger(as: UInt32.self), 0b10011101_01111111_00111110_01111101)
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
|
|
func testWriteEightByteQUICVariableLengthInteger() {
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(
|
|
0b00000010_00011001_01111100_01011110_11111111_00010100_11101000_10001100 as Int64,
|
|
to: &buffer
|
|
)
|
|
XCTAssertEqual(bytesWritten, 8)
|
|
// 2 bit mask is 11 for 8 bytes so this becomes 0b11000010_00011001_01111100_01011110_11111111_00010100_11101000_10001100
|
|
XCTAssertEqual(
|
|
buffer.readInteger(as: UInt64.self),
|
|
0b11000010_00011001_01111100_01011110_11111111_00010100_11101000_10001100
|
|
)
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
|
|
// MARK: - writeEncodedIntegerWithReservedCapacity tests
|
|
|
|
func testWriteOneByteQUICVariableLengthIntegerWithTwoBytesReserved() {
|
|
// We only need one byte but the encoder will use 2 because we reserved 2
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(0b00000001, reservedCapacity: 2, to: &buffer)
|
|
XCTAssertEqual(bytesWritten, 2)
|
|
XCTAssertEqual(buffer.readInteger(as: UInt16.self), UInt16(0b01000000_00000001))
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
|
|
func testRoundtripWithReservedCapacity() {
|
|
// This test makes sure that a number encoded with more space than necessary can still be decoded as normal
|
|
for reservedCapacity in [0, 1, 2, 4, 8] {
|
|
let testNumbers: [Int64] = [0, 63, 15293, 494_878_333, 151_288_809_941_952_652]
|
|
for testNumber in testNumbers {
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let bytesWritten = strategy.writeInteger(
|
|
testNumber,
|
|
reservedCapacity: reservedCapacity,
|
|
to: &buffer
|
|
)
|
|
let minRequiredBytes = ByteBuffer.QUICBinaryEncodingStrategy.bytesNeededForInteger(testNumber)
|
|
// If the reserved capacity is higher than the min required, use the reserved number
|
|
let expectedUsedBytes = max(minRequiredBytes, reservedCapacity)
|
|
XCTAssertEqual(bytesWritten, expectedUsedBytes)
|
|
XCTAssertEqual(strategy.readInteger(as: UInt64.self, from: &buffer), UInt64(testNumber))
|
|
XCTAssertEqual(buffer.readableBytes, 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - readEncodedInteger tests
|
|
|
|
func testReadEmptyQUICVariableLengthInteger() {
|
|
var buffer = ByteBuffer()
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
XCTAssertNil(strategy.readInteger(as: Int.self, from: &buffer))
|
|
}
|
|
|
|
func testWriteReadQUICVariableLengthInteger() {
|
|
let strategy = ByteBuffer.QUICBinaryEncodingStrategy.quic
|
|
let testNumbers: [Int64] = [37, 15293, 494_878_333, 151_288_809_941_952_652]
|
|
for integer in testNumbers {
|
|
var buffer = ByteBuffer()
|
|
_ = strategy.writeInteger(integer, to: &buffer)
|
|
XCTAssertEqual(strategy.readInteger(as: Int64.self, from: &buffer), integer)
|
|
}
|
|
}
|
|
}
|