Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions Tests/WebSocketTests/AutobahnTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ import Foundation
import Logging
import NIOConcurrencyHelpers
import NIOPosix
import Testing
import WSClient
import WSCompression
import XCTest

/// The Autobahn|Testsuite provides a fully automated test suite to verify client and server
/// implementations of The WebSocket Protocol for specification conformance and implementation robustness.
/// You can find out more at https://github.com/crossbario/autobahn-testsuite
///
/// Before running these tests run `./scripts/autobahn-server.sh` to running the test server.
final class AutobahnTests: XCTestCase {
@Suite(.disabled(if: ci), .serialized)
struct AutobahnTests {
/// To run all the autobahn compression tests takes a long time. By default we only run a selection.
/// The `AUTOBAHN_ALL_TESTS` environment flag triggers running all of them.
var runAllTests: Bool { ProcessInfo.processInfo.environment["AUTOBAHN_ALL_TESTS"] == "true" }
Expand All @@ -52,17 +53,14 @@ final class AutobahnTests: XCTestCase {
return
}
}
return try result.withLockedValue { try XCTUnwrap($0) }
return try result.withLockedValue { try #require($0) }
}

/// Run a number of autobahn tests
func autobahnTests(
cases: Set<Int>,
extensions: [WebSocketExtensionFactory] = [.perMessageDeflate(maxDecompressedFrameSize: 16_777_216)]
) async throws {
// These are broken in CI currently
try XCTSkipIf(ProcessInfo.processInfo.environment["CI"] != nil)

struct CaseInfo: Decodable {
let id: String
let description: String
Expand Down Expand Up @@ -102,7 +100,7 @@ final class AutobahnTests: XCTestCase {

// get case status
let status = try await getValue("getCaseStatus?case=\(index)&agent=swift-websocket", as: CaseStatus.self)
XCTAssert(status.behavior == "OK" || status.behavior == "INFORMATIONAL" || status.behavior == "NON-STRICT")
#expect(status.behavior == "OK" || status.behavior == "INFORMATIONAL" || status.behavior == "NON-STRICT")
}

try await WebSocketClient.connect(
Expand All @@ -117,35 +115,35 @@ final class AutobahnTests: XCTestCase {
}
}

func test_1_Framing() async throws {
@Test func test_1_Framing() async throws {
try await self.autobahnTests(cases: .init(1..<17))
}

func test_2_PingPongs() async throws {
@Test func test_2_PingPongs() async throws {
try await self.autobahnTests(cases: .init(17..<28))
}

func test_3_ReservedBits() async throws {
@Test func test_3_ReservedBits() async throws {
try await self.autobahnTests(cases: .init(28..<35))
}

func test_4_Opcodes() async throws {
@Test func test_4_Opcodes() async throws {
try await self.autobahnTests(cases: .init(35..<45))
}

func test_5_Fragmentation() async throws {
@Test func test_5_Fragmentation() async throws {
try await self.autobahnTests(cases: .init(45..<65))
}

func test_6_UTF8Handling() async throws {
@Test func test_6_UTF8Handling() async throws {
// UTF8 validation is available on swift 5.10 or earlier
#if compiler(<6)
try XCTSkipIf(true)
#endif
try await self.autobahnTests(cases: .init(65..<210))
}

func test_7_CloseHandling() async throws {
@Test func test_7_CloseHandling() async throws {
// UTF8 validation is available on swift 5.10 or earlier
#if compiler(<6)
try await self.autobahnTests(cases: .init(210..<222))
Expand All @@ -155,27 +153,27 @@ final class AutobahnTests: XCTestCase {
#endif
}

func test_9_Performance() async throws {
@Test func test_9_Performance() async throws {
if !self.runAllTests {
try await self.autobahnTests(cases: .init([247, 260, 270, 281, 291, 296]))
} else {
try await self.autobahnTests(cases: .init(247..<301))
}
}

func test_10_AutoFragmentation() async throws {
@Test func test_10_AutoFragmentation() async throws {
try await self.autobahnTests(cases: .init([301]))
}

func test_12_CompressionDifferentPayloads() async throws {
@Test func test_12_CompressionDifferentPayloads() async throws {
if !self.runAllTests {
try await self.autobahnTests(cases: .init([302, 330, 349, 360, 388]))
} else {
try await self.autobahnTests(cases: .init(302..<391))
}
}

func test_13_CompressionDifferentParameters() async throws {
@Test func test_13_CompressionDifferentParameters() async throws {
if !self.runAllTests {
try await self.autobahnTests(
cases: .init([392]),
Expand Down Expand Up @@ -255,3 +253,5 @@ final class AutobahnTests: XCTestCase {
}
}
}

var ci: Bool { ProcessInfo.processInfo.environment["CI"] != nil }
12 changes: 6 additions & 6 deletions Tests/WebSocketTests/ClientChannelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
//===----------------------------------------------------------------------===//

import Logging
import XCTest
import Testing

@testable import WSClient

final class ClientChannelTests: XCTestCase {
struct ClientChannelTests {

func testInitialRequestHeader() async throws {
@Test func testInitialRequestHeader() async throws {
let ws = try WebSocketClientChannel(handler: { _, _, _ in }, url: "wss://echo.websocket.org:443/ws", configuration: .init())

XCTAssertEqual(ws.urlPath, "/ws")
XCTAssertEqual(ws.hostHeader, "echo.websocket.org:443")
XCTAssertEqual(ws.originHeader, "wss://echo.websocket.org")
#expect(ws.urlPath == "/ws")
#expect(ws.hostHeader == "echo.websocket.org:443")
#expect(ws.originHeader == "wss://echo.websocket.org")
}
}
8 changes: 4 additions & 4 deletions Tests/WebSocketTests/ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import Logging
import NIOCore
import NIOSSL
import NIOWebSocket
import Testing
import WSClient
import XCTest

final class WebSocketClientTests: XCTestCase {
struct WebSocketClientTests {

func testEchoServer() async throws {
@Test func testEchoServer() async throws {
let clientLogger = {
var logger = Logger(label: "client")
logger.logLevel = .trace
Expand All @@ -40,7 +40,7 @@ final class WebSocketClientTests: XCTestCase {
}
}

func testEchoServerWithSNIHostname() async throws {
@Test func testEchoServerWithSNIHostname() async throws {
let clientLogger = {
var logger = Logger(label: "client")
logger.logLevel = .trace
Expand Down
65 changes: 30 additions & 35 deletions Tests/WebSocketTests/WebSocketExtensionNegotiationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,74 @@

import HTTPTypes
import NIOWebSocket
import XCTest
import Testing

@testable import WSCompression
@testable import WSCore

final class WebSocketExtensionNegotiationTests: XCTestCase {
func testExtensionHeaderParsing() {
struct WebSocketExtensionNegotiationTests {
@Test func testExtensionHeaderParsing() {
let headers: HTTPFields = .init([
.init(name: .secWebSocketExtensions, value: "permessage-deflate; client_max_window_bits; server_max_window_bits=10"),
.init(name: .secWebSocketExtensions, value: "permessage-deflate;client_max_window_bits"),
])
let extensions = WebSocketExtensionHTTPParameters.parseHeaders(headers)
XCTAssertEqual(
extensions,
[
#expect(
extensions == [
.init("permessage-deflate", parameters: ["client_max_window_bits": .null, "server_max_window_bits": .value("10")]),
.init("permessage-deflate", parameters: ["client_max_window_bits": .null]),
]
)
}

func testDeflateServerResponse() {
@Test func testDeflateServerResponse() {
let requestHeaders: [WebSocketExtensionHTTPParameters] = [
.init("permessage-deflate", parameters: ["client_max_window_bits": .value("10")])
]
let ext = PerMessageDeflateExtensionBuilder(clientNoContextTakeover: true, serverNoContextTakeover: true)
let serverResponse = ext.serverResponseHeader(to: requestHeaders)
XCTAssertEqual(
serverResponse,
"permessage-deflate;client_max_window_bits=10;client_no_context_takeover;server_no_context_takeover"
#expect(
serverResponse == "permessage-deflate;client_max_window_bits=10;client_no_context_takeover;server_no_context_takeover"
)
}

func testDeflateServerResponseClientMaxWindowBits() {
@Test func testDeflateServerResponseClientMaxWindowBits() {
let requestHeaders: [WebSocketExtensionHTTPParameters] = [
.init("permessage-deflate", parameters: ["client_max_window_bits": .null])
]
let ext1 = PerMessageDeflateExtensionBuilder(serverNoContextTakeover: true)
let serverResponse1 = ext1.serverResponseHeader(to: requestHeaders)
XCTAssertEqual(
serverResponse1,
"permessage-deflate;server_no_context_takeover"
#expect(
serverResponse1 == "permessage-deflate;server_no_context_takeover"
)
let ext2 = PerMessageDeflateExtensionBuilder(clientNoContextTakeover: true, serverMaxWindow: 12)
let serverResponse2 = ext2.serverResponseHeader(to: requestHeaders)
XCTAssertEqual(
serverResponse2,
"permessage-deflate;client_no_context_takeover;server_max_window_bits=12"
#expect(
serverResponse2 == "permessage-deflate;client_no_context_takeover;server_max_window_bits=12"
)
}

func testUnregonisedExtensionServerResponse() throws {
@Test func testUnregonisedExtensionServerResponse() throws {
let serverExtensions: [WebSocketExtensionBuilder] = [PerMessageDeflateExtensionBuilder()]
let (headers, extensions) = try serverExtensions.serverExtensionNegotiation(
requestHeaders: [
.secWebSocketExtensions: "permessage-foo;bar=baz",
.secWebSocketExtensions: "permessage-deflate;client_max_window_bits=10",
]
)
XCTAssertEqual(
headers[.secWebSocketExtensions],
"permessage-deflate;client_max_window_bits=10"
#expect(
headers[.secWebSocketExtensions] == "permessage-deflate;client_max_window_bits=10"
)
XCTAssertEqual(extensions.count, 1)
let firstExtension = try XCTUnwrap(extensions.first)
XCTAssert(firstExtension is PerMessageDeflateExtension)
#expect(extensions.count == 1)
let firstExtension = try #require(extensions.first)
#expect(firstExtension is PerMessageDeflateExtension)

let requestExtensions = try serverExtensions.buildClientExtensions(from: headers)
XCTAssertEqual(requestExtensions.count, 1)
XCTAssert(requestExtensions[0] is PerMessageDeflateExtension)
#expect(requestExtensions.count == 1)
#expect(requestExtensions[0] is PerMessageDeflateExtension)
}

func testNonNegotiableClientExtension() throws {
@Test func testNonNegotiableClientExtension() throws {
struct MyExtension: WebSocketExtension {
var name = "my-extension"

Expand All @@ -106,12 +101,12 @@ final class WebSocketExtensionNegotiationTests: XCTestCase {
}.build()
]
let clientExtensions = try clientExtensionBuilders.buildClientExtensions(from: [:])
XCTAssertEqual(clientExtensions.count, 1)
let myExtension = try XCTUnwrap(clientExtensions.first)
XCTAssert(myExtension is MyExtension)
#expect(clientExtensions.count == 1)
let myExtension = try #require(clientExtensions.first)
#expect(myExtension is MyExtension)
}

func testNonNegotiableServerExtension() throws {
@Test func testNonNegotiableServerExtension() throws {
struct MyExtension: WebSocketExtension {
var name = "my-extension"

Expand All @@ -129,9 +124,9 @@ final class WebSocketExtensionNegotiationTests: XCTestCase {
let (headers, serverExtensions) = try serverExtensionBuilders.serverExtensionNegotiation(
requestHeaders: [:]
)
XCTAssertEqual(headers.count, 0)
XCTAssertEqual(serverExtensions.count, 1)
let myExtension = try XCTUnwrap(serverExtensions.first)
XCTAssert(myExtension is MyExtension)
#expect(headers.count == 0)
#expect(serverExtensions.count == 1)
let myExtension = try #require(serverExtensions.first)
#expect(myExtension is MyExtension)
}
}
Loading