Speed up the tests (#3601)

### Motivation

We want our tests to pass in reasonable time.

### Changes

- Disable test
`ByteBufferCrashTests.setBytesWithoutContigiousStorageMoreThanUInt32maxBytes`
- Do not initialize data in `ByteBufferCrashTests.
takingOwnershipOfPointerThatsToLarge`

### Result

Tests are faster again.
This commit is contained in:
Fabian Fett
2026-05-20 12:12:53 +02:00
committed by GitHub
parent b24872d3aa
commit 57c0a08a33
4 changed files with 42 additions and 34 deletions
+12 -13
View File
@@ -31,7 +31,9 @@ public final class NIOHTTPRequestHeadersValidator: ChannelOutboundHandler, Remov
public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise<Void>?) {
switch NIOHTTPRequestHeadersValidator.unwrapOutboundIn(data) {
case .head(let head):
guard Self.uriOnlyContainsAllowedCharacters(head.uri), head.method.isValidToSend, head.headers.areValidToSend else {
guard Self.uriOnlyContainsAllowedCharacters(head.uri), head.method.isValidToSend,
head.headers.areValidToSend
else {
promise?.fail(HTTPParserError.invalidHeaderToken)
context.fireErrorCaught(HTTPParserError.invalidHeaderToken)
return
@@ -98,10 +100,9 @@ public final class NIOHTTPRequestHeadersValidator: ChannelOutboundHandler, Remov
uri.utf8.allSatisfy { byte in
switch byte {
case
// unreserved
// - ALPHA
UInt8(ascii: "A")...UInt8(ascii: "Z"), UInt8(ascii: "a")...UInt8(ascii: "z"),
case // unreserved
// - ALPHA
UInt8(ascii: "A")...UInt8(ascii: "Z"), UInt8(ascii: "a")...UInt8(ascii: "z"),
// - DIGIT
UInt8(ascii: "0")...UInt8(ascii: "9"),
// - extra characters
@@ -225,7 +226,7 @@ extension HTTPMethod {
.SOURCE:
true
case .RAW(value: let value):
case .RAW(let value):
// The spec in [RFC 9110](https://httpwg.org/specs/rfc9110.html#method.overview) defines the valid
// characters as the following:
//
@@ -241,9 +242,8 @@ extension HTTPMethod {
value.utf8.allSatisfy { byte in
switch byte {
case
// ALPHA
UInt8(ascii: "A")...UInt8(ascii: "Z"), UInt8(ascii: "a")...UInt8(ascii: "z"),
case // ALPHA
UInt8(ascii: "A")...UInt8(ascii: "Z"), UInt8(ascii: "a")...UInt8(ascii: "z"),
// DIGIT
UInt8(ascii: "0")...UInt8(ascii: "9"),
// token
@@ -337,11 +337,10 @@ extension HTTPResponseStatus {
reasonPhrase.utf8.allSatisfy { byte in
switch byte {
case
9, // HTAB
32, // SP
case 9, // HTAB
32, // SP
33...126, // VCHAR
128...255: // obs-text
128...255: // obs-text
return true
default:
return false
+1 -1
View File
@@ -156,6 +156,7 @@ extension ChannelPipeline {
/// - enableOutboundHeaderValidation: Whether the pipeline should confirm that outbound headers are well-formed.
/// Defaults to `true`.
/// - encoderConfiguration: The configuration for the ``HTTPRequestEncoder``.
/// - decoderLimitConfiguration: The limit configuration for the ``HTTPDecoder``.
/// - upgrade: Add a ``NIOHTTPClientUpgradeHandler`` to the pipeline, configured for
/// HTTP upgrade. Should be a tuple of an array of ``NIOHTTPClientUpgradeHandler`` and
/// the upgrade completion handler. See the documentation on ``NIOHTTPClientUpgradeHandler``
@@ -389,7 +390,6 @@ extension ChannelPipeline {
)
}
private func _configureHTTPServerPipeline(
position: ChannelPipeline.Position = .last,
withPipeliningAssistance pipelining: Bool = true,
@@ -12,9 +12,9 @@
//
//===----------------------------------------------------------------------===//
import Foundation
@_spi(CustomByteBufferAllocator) import NIOCore
import Testing
import Foundation
#if compiler(>=6.2)
@Suite struct ByteBufferCrashTests {
@@ -91,7 +91,11 @@ import Foundation
}
}
@Test func setBytesWithoutContigiousStorageMoreThanUInt32maxBytes() async {
@Test(
.disabled(
"This test is taking too long, as it needs to allocate 4GB of memory. It doesn't work on 32bit machines."
)
) func setBytesWithoutContigiousStorageMoreThanUInt32maxBytes() async {
await #expect(processExitsWith: .failure) {
let circularBuffer = CircularBuffer<UInt8>(repeating: 0, count: Int(UInt32.max) + 1)
var bb = ByteBuffer()
@@ -138,12 +142,6 @@ import Foundation
let capacity = Int(UInt32.max) + 1
let ptr = malloc(capacity)!
// Initialize some data in the external memory
let boundPtr = ptr.bindMemory(to: UInt8.self, capacity: capacity)
for i in 0..<capacity {
boundPtr[i] = 1
}
let allocator = ByteBufferCustomAllocatorTest.makeTrackedAllocator()
// this should crash
@@ -613,7 +613,12 @@ import Testing
try channel.pipeline.syncOperations.addHTTPClientHandlers()
let headers = HTTPHeaders([("Host", "example.com")])
let goodRequest = HTTPRequestHead(version: .http1_1, method: .RAW(value: weirdAllowedMethodName), uri: "/", headers: headers)
let goodRequest = HTTPRequestHead(
version: .http1_1,
method: .RAW(value: weirdAllowedMethodName),
uri: "/",
headers: headers
)
let goodRequestBytes = ByteBuffer(
string: "\(weirdAllowedMethodName) / HTTP/1.1\r\nHost: example.com\r\n\r\n"
)
@@ -638,7 +643,12 @@ import Testing
try channel.pipeline.syncOperations.addHTTPClientHandlers()
let headers = HTTPHeaders([("Host", "example.com")])
let badRequest = HTTPRequestHead(version: .http1_1, method: .RAW(value: forbiddenFieldName), uri: "/", headers: headers)
let badRequest = HTTPRequestHead(
version: .http1_1,
method: .RAW(value: forbiddenFieldName),
uri: "/",
headers: headers
)
let error = #expect(
throws: HTTPParserError.self,
@@ -662,9 +672,9 @@ import Testing
// ```
let allowedRanges: [ClosedRange<UInt8>] = [
9...9, // HTAB
32...32, // SP
33...126, // VCHAR
9...9, // HTAB
32...32, // SP
33...126, // VCHAR
128...255, // obs-text
]
@@ -693,7 +703,9 @@ import Testing
switch allowed {
case true:
let goodRequestBytes = ByteBuffer(string: "HTTP/1.1 600 \(testReason)\r\ntransfer-encoding: chunked\r\n\r\n")
let goodRequestBytes = ByteBuffer(
string: "HTTP/1.1 600 \(testReason)\r\ntransfer-encoding: chunked\r\n\r\n"
)
let goodEnd = ByteBuffer(string: "0\r\n\r\n")
#expect(throws: Never.self, "Rejected reason phrase with byte: \(byte)") {
try channel.writeOutbound(HTTPServerResponsePart.head(response))
@@ -829,7 +841,7 @@ import Testing
return String(Unicode.Scalar(byte))
case 0xC0, 0xC1:
return nil // forbidden in UTF-8
return nil // forbidden in UTF-8
case 0xC2...0xDF:
// Lead of 2-byte seq. Smallest scalar with this lead:
@@ -844,7 +856,7 @@ import Testing
let base = UInt32(byte & 0x0F) << 12
let scalar = (byte == 0xE0) ? 0x0800 : base
// Skip surrogates if we land in D800DFFF (byte == 0xED)
if byte == 0xED { return String(Unicode.Scalar(0xD000 - 0x0800 + base)!) } // simple pick
if byte == 0xED { return String(Unicode.Scalar(0xD000 - 0x0800 + base)!) } // simple pick
return Unicode.Scalar(scalar).map { String($0) }
case 0xF0...0xF4:
@@ -856,12 +868,12 @@ import Testing
switch byte {
case 0xF0: scalar = 0x10000
case 0xF4: scalar = 0x100000
default: scalar = UInt32(byte & 0x07) << 18
default: scalar = UInt32(byte & 0x07) << 18
}
return Unicode.Scalar(scalar).map { String($0) }
default: // 0xF5...0xFF
return nil // forbidden in UTF-8
default: // 0xF5...0xFF
return nil // forbidden in UTF-8
}
}
}
@@ -872,4 +884,3 @@ extension EmbeddedChannel {
try self.writeInbound(request)
}
}