blob: 7730ed6049c778c9a5f7852b39dca727698d778e [file] [log] [blame]
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
#if os(Windows)
import WinSDK
#endif
class TestPortDelegateWithBlock: NSObject, PortDelegate {
let block: (PortMessage) -> Void
init(block: @escaping (PortMessage) -> Void) {
self.block = block
}
func handle(_ message: PortMessage) {
block(message)
}
}
class TestSocketPort : XCTestCase {
func tcpOrUdpPort(of socketPort: SocketPort) -> Int? {
let data = socketPort.address
#if canImport(Darwin) || os(FreeBSD)
let familyOffset = 1
#else
let familyOffset = 0
#endif
if data[data.startIndex + familyOffset] == AF_INET {
return data.withUnsafeBytes { (buffer) in
var sin = sockaddr_in()
withUnsafeMutableBytes(of: &sin) {
$0.copyMemory(from: buffer)
}
return Int(sin.sin_port.bigEndian)
}
} else if data[data.startIndex + familyOffset] == AF_INET6 {
return data.withUnsafeBytes { (buffer) in
var sin = sockaddr_in6()
withUnsafeMutableBytes(of: &sin) {
$0.copyMemory(from: buffer)
}
return Int(sin.sin6_port.bigEndian)
}
} else {
return nil
}
}
func testRemoteSocketPortsAreUniqued() {
let a = SocketPort(remoteWithTCPPort: 10000, host: "localhost")
let b = SocketPort(remoteWithTCPPort: 10000, host: "localhost")
XCTAssertEqual(a, b)
}
func testInitPicksATCPPort() throws {
let local = try XCTUnwrap(SocketPort(tcpPort: 0))
defer { local.invalidate() }
let port = try XCTUnwrap(tcpOrUdpPort(of: local))
XCTAssertNotEqual(port, 0)
XCTAssert(port >= 1024)
}
func testSendingOneMessageRemoteToLocal() throws {
let local = try XCTUnwrap(SocketPort(tcpPort: 0))
defer { local.invalidate() }
let tcpPort = try UInt16(XCTUnwrap(tcpOrUdpPort(of: local)))
let remote = try XCTUnwrap(SocketPort(remoteWithTCPPort: tcpPort, host: "localhost"))
defer { remote.invalidate() }
let data = Data("I cannot weave".utf8)
let received = expectation(description: "Message received")
let delegate = TestPortDelegateWithBlock { message in
XCTAssertEqual(message.components as? [AnyHashable], [data as NSData])
received.fulfill()
}
withExtendedLifetime(delegate) {
local.setDelegate(delegate)
local.schedule(in: .main, forMode: .default)
remote.schedule(in: .main, forMode: .default)
defer {
local.setDelegate(nil)
local.remove(from: .main, forMode: .default)
remote.remove(from: .main, forMode: .default)
}
let sent = remote.sendBeforeDate(Date(timeIntervalSinceNow: 5), components: NSMutableArray(array: [data]), from: nil, reserved: 0)
XCTAssertTrue(sent)
waitForExpectations(timeout: 5.5)
}
}
static var allTests: [(String, (TestSocketPort) -> () throws -> Void)] {
return [
("testRemoteSocketPortsAreUniqued", testRemoteSocketPortsAreUniqued),
("testInitPicksATCPPort", testInitPicksATCPPort),
("testSendingOneMessageRemoteToLocal", testSendingOneMessageRemoteToLocal),
]
}
}