mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
909 lines
27 KiB
Swift
909 lines
27 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// REQUIRES: executable_test
|
|
|
|
// REQUIRES: objc_interop
|
|
// UNSUPPORTED: OS=watchos
|
|
|
|
|
|
import Network
|
|
import Foundation
|
|
import StdlibUnittest
|
|
|
|
|
|
defer { runAllTests() }
|
|
|
|
var NetworkAPI = TestSuite("NetworkAPI")
|
|
|
|
#if !os(watchOS)
|
|
|
|
if #available(macOS 10.14, iOS 12.0, tvOS 12.0, *) {
|
|
NetworkAPI.test("constants") {
|
|
expectNotNil(NWConnection.ContentContext.defaultMessage)
|
|
expectNotNil(NWConnection.ContentContext.finalMessage)
|
|
expectNotNil(NWConnection.ContentContext.defaultStream)
|
|
expectNotNil(NWParameters.tcp)
|
|
expectNotNil(NWParameters.tls)
|
|
expectNotNil(NWParameters.udp)
|
|
expectNotNil(NWParameters.dtls)
|
|
expectNotNil(IPv4Address.any)
|
|
expectNotNil(IPv4Address.broadcast)
|
|
expectNotNil(IPv4Address.loopback)
|
|
expectNotNil(IPv4Address.allHostsGroup)
|
|
expectNotNil(IPv4Address.allRoutersGroup)
|
|
expectNotNil(IPv4Address.allReportsGroup)
|
|
expectNotNil(IPv4Address.mdnsGroup)
|
|
expectNotNil(IPv6Address.any)
|
|
expectNotNil(IPv6Address.loopback)
|
|
expectNotNil(IPv6Address.nodeLocalNodes)
|
|
expectNotNil(IPv6Address.linkLocalNodes)
|
|
expectNotNil(IPv6Address.linkLocalRouters)
|
|
expectNotNil(NWEndpoint.Port.any)
|
|
expectNotNil(NWEndpoint.Port.ssh)
|
|
expectNotNil(NWEndpoint.Port.smtp)
|
|
expectNotNil(NWEndpoint.Port.http)
|
|
expectNotNil(NWEndpoint.Port.pop)
|
|
expectNotNil(NWEndpoint.Port.imap)
|
|
expectNotNil(NWEndpoint.Port.https)
|
|
expectNotNil(NWEndpoint.Port.imaps)
|
|
expectNotNil(NWEndpoint.Port.socks)
|
|
}
|
|
|
|
NetworkAPI.test("NWEndpoint") {
|
|
let hostEndpoint = NWEndpoint.hostPort(host: "www.apple.com", port: .http)
|
|
expectNotNil(hostEndpoint)
|
|
expectNil(hostEndpoint.interface)
|
|
|
|
let bonjourEndpoint = NWEndpoint.service(name: "myprinter", type: "_ipp._tcp", domain: "local", interface: nil)
|
|
expectNotNil(bonjourEndpoint)
|
|
expectNil(bonjourEndpoint.interface)
|
|
|
|
let unixEndpoint = NWEndpoint.unix(path: "/foo/bar")
|
|
expectNotNil(unixEndpoint)
|
|
expectNil(unixEndpoint.interface)
|
|
}
|
|
|
|
NetworkAPI.test("NWEndpoint.Host") {
|
|
var host = NWEndpoint.Host("www.apple.com")
|
|
expectNotNil(host)
|
|
expectNil(host.interface)
|
|
|
|
host = NWEndpoint.Host("127.0.0.1")
|
|
expectNotNil(host)
|
|
expectNil(host.interface)
|
|
|
|
host = NWEndpoint.Host("::1")
|
|
expectNotNil(host)
|
|
expectNil(host.interface)
|
|
|
|
host = NWEndpoint.Host("::1%lo0")
|
|
expectNotNil(host)
|
|
expectNotNil(host.interface)
|
|
if let interface = host.interface {
|
|
expectEqual(interface.name, "lo0")
|
|
expectEqual(interface.type, .loopback)
|
|
}
|
|
|
|
var ipv4Address = IPv4Address("127.0.0.1")
|
|
expectNotNil(ipv4Address)
|
|
expectNotNil(ipv4Address!.rawValue)
|
|
expectEqual(ipv4Address!.rawValue.count, 4)
|
|
expectNil(ipv4Address!.interface)
|
|
expectTrue(ipv4Address!.isLoopback)
|
|
|
|
let otherIPv4Address = IPv4Address("127.0.0.1")
|
|
expectEqual(ipv4Address, otherIPv4Address)
|
|
|
|
ipv4Address = IPv4Address("169.254.1.0")
|
|
expectNotNil(ipv4Address)
|
|
expectTrue(ipv4Address!.isLinkLocal)
|
|
|
|
ipv4Address = IPv4Address("224.0.0.1")
|
|
expectNotNil(ipv4Address)
|
|
expectTrue(ipv4Address!.isMulticast)
|
|
|
|
var ipv6Address = IPv6Address("::0")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isAny)
|
|
expectNotNil(ipv6Address!.rawValue)
|
|
expectEqual(ipv6Address!.rawValue.count, 16)
|
|
expectNil(ipv6Address!.interface)
|
|
|
|
ipv6Address = IPv6Address("::1")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isLoopback)
|
|
expectNil(ipv6Address!.interface)
|
|
|
|
ipv6Address = IPv6Address("::1%lo0")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isLoopback)
|
|
expectNotNil(ipv6Address!.interface)
|
|
if let interface = ipv6Address!.interface {
|
|
expectEqual(interface.name, "lo0")
|
|
expectEqual(interface.type, .loopback)
|
|
}
|
|
|
|
ipv6Address = IPv6Address("::1.2.3.4")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isIPv4Compatabile)
|
|
|
|
ipv6Address = IPv6Address("::ffff:1.2.3.4")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isIPv4Mapped)
|
|
|
|
ipv4Address = ipv6Address!.asIPv4
|
|
expectNotNil(ipv4Address)
|
|
|
|
ipv6Address = IPv6Address("2002::1")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.is6to4)
|
|
|
|
ipv6Address = IPv6Address("fe80::1")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isLinkLocal)
|
|
|
|
ipv6Address = IPv6Address("ff02::1")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isMulticast)
|
|
|
|
expectEqual(ipv6Address!.multicastScope, .linkLocal)
|
|
|
|
// Try a bad multicast scope
|
|
ipv6Address = IPv6Address("ff03::1")
|
|
expectNotNil(ipv6Address)
|
|
expectTrue(ipv6Address!.isMulticast)
|
|
expectTrue(ipv6Address!.multicastScope != .linkLocal)
|
|
}
|
|
|
|
NetworkAPI.test("NWEndpoint.Port") {
|
|
let port: NWEndpoint.Port = 1234
|
|
expectNotNil(port)
|
|
expectEqual(port.rawValue, 1234)
|
|
|
|
expectEqual(NWEndpoint.Port.https, 443)
|
|
expectEqual(NWEndpoint.Port("https")!.rawValue, 443)
|
|
}
|
|
|
|
NetworkAPI.test("NWParameters") {
|
|
var parameters = NWParameters.tcp
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.internetProtocol is NWProtocolIP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 0)
|
|
|
|
parameters = parameters.copy()
|
|
expectTrue(parameters.defaultProtocolStack.internetProtocol is NWProtocolIP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 0)
|
|
|
|
parameters = NWParameters.udp
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolUDP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 0)
|
|
|
|
parameters = NWParameters.tls
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 1)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols[0] is NWProtocolTLS.Options)
|
|
|
|
parameters.defaultProtocolStack.transportProtocol = NWProtocolUDP.Options()
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolUDP.Options)
|
|
|
|
parameters = NWParameters.tls
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
|
|
parameters = NWParameters.dtls
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolUDP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 1)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols[0] is NWProtocolTLS.Options)
|
|
|
|
parameters = NWParameters(tls:nil, tcp:NWProtocolTCP.Options())
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 0)
|
|
|
|
parameters = NWParameters(dtls:nil, udp:NWProtocolUDP.Options())
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolUDP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 0)
|
|
|
|
parameters = NWParameters(tls:NWProtocolTLS.Options(), tcp:NWProtocolTCP.Options())
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 1)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols[0] is NWProtocolTLS.Options)
|
|
|
|
parameters = NWParameters(dtls:NWProtocolTLS.Options(), udp:NWProtocolUDP.Options())
|
|
expectNotNil(parameters)
|
|
expectTrue(parameters.defaultProtocolStack.transportProtocol is NWProtocolUDP.Options)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 1)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols[0] is NWProtocolTLS.Options)
|
|
|
|
parameters = NWParameters()
|
|
expectNotNil(parameters)
|
|
expectNotNil(parameters.defaultProtocolStack)
|
|
expectTrue(parameters.defaultProtocolStack.applicationProtocols.count == 0)
|
|
expectNil(parameters.defaultProtocolStack.transportProtocol)
|
|
|
|
parameters.defaultProtocolStack.transportProtocol = NWProtocolTCP.Options()
|
|
|
|
expectNil(parameters.requiredInterface)
|
|
|
|
expectEqual(parameters.requiredInterfaceType, NWInterface.InterfaceType.other)
|
|
parameters.requiredInterfaceType = .wifi
|
|
expectEqual(parameters.requiredInterfaceType, NWInterface.InterfaceType.wifi)
|
|
|
|
expectTrue(parameters.prohibitedInterfaces == nil ||
|
|
parameters.prohibitedInterfaces!.count == 0)
|
|
|
|
expectTrue(parameters.prohibitedInterfaceTypes == nil ||
|
|
parameters.prohibitedInterfaceTypes!.count == 0)
|
|
parameters.prohibitedInterfaceTypes = [ .cellular ]
|
|
expectTrue(parameters.prohibitedInterfaceTypes!.count == 1)
|
|
expectEqual(parameters.prohibitedInterfaceTypes![0], .cellular)
|
|
|
|
expectEqual(parameters.prohibitExpensivePaths, false)
|
|
parameters.prohibitExpensivePaths = true;
|
|
expectEqual(parameters.prohibitExpensivePaths, true)
|
|
|
|
expectEqual(parameters.preferNoProxies, false)
|
|
parameters.preferNoProxies = true;
|
|
expectEqual(parameters.preferNoProxies, true)
|
|
|
|
expectNil(parameters.requiredLocalEndpoint)
|
|
parameters.requiredLocalEndpoint = NWEndpoint.hostPort(host: "127.0.0.1", port: 1234)
|
|
expectNotNil(parameters.requiredLocalEndpoint)
|
|
|
|
expectEqual(parameters.allowLocalEndpointReuse, false)
|
|
parameters.allowLocalEndpointReuse = true;
|
|
expectEqual(parameters.allowLocalEndpointReuse, true)
|
|
|
|
expectEqual(parameters.acceptLocalOnly, false)
|
|
parameters.acceptLocalOnly = true;
|
|
expectEqual(parameters.acceptLocalOnly, true)
|
|
|
|
expectEqual(parameters.serviceClass, NWParameters.ServiceClass.bestEffort)
|
|
parameters.serviceClass = .background;
|
|
expectEqual(parameters.serviceClass, NWParameters.ServiceClass.background)
|
|
|
|
expectEqual(parameters.multipathServiceType, NWParameters.MultipathServiceType.disabled)
|
|
parameters.multipathServiceType = .handover;
|
|
expectEqual(parameters.multipathServiceType, NWParameters.MultipathServiceType.handover)
|
|
|
|
expectEqual(parameters.expiredDNSBehavior, NWParameters.ExpiredDNSBehavior.systemDefault)
|
|
parameters.expiredDNSBehavior = .allow;
|
|
expectEqual(parameters.expiredDNSBehavior, NWParameters.ExpiredDNSBehavior.allow)
|
|
|
|
expectEqual(parameters.allowFastOpen, false)
|
|
parameters.allowFastOpen = true;
|
|
expectEqual(parameters.allowFastOpen, true)
|
|
|
|
expectEqual(parameters.includePeerToPeer, false)
|
|
parameters.includePeerToPeer = true;
|
|
expectEqual(parameters.includePeerToPeer, true)
|
|
}
|
|
|
|
NetworkAPI.test("NWProtocolTCP") {
|
|
expectNotNil(NWProtocolTCP.definition)
|
|
expectEqual(NWProtocolTCP.definition.name, "tcp")
|
|
|
|
let options = NWProtocolTCP.Options()
|
|
expectNotNil(options)
|
|
|
|
expectEqual(options.noDelay, false)
|
|
options.noDelay = true;
|
|
expectEqual(options.noDelay, true)
|
|
|
|
expectEqual(options.noPush, false)
|
|
options.noPush = true;
|
|
expectEqual(options.noDelay, true)
|
|
|
|
expectEqual(options.noOptions, false)
|
|
options.noOptions = true;
|
|
expectEqual(options.noOptions, true)
|
|
|
|
expectEqual(options.enableKeepalive, false)
|
|
options.enableKeepalive = true;
|
|
expectEqual(options.enableKeepalive, true)
|
|
|
|
expectEqual(options.keepaliveCount, 0)
|
|
options.keepaliveCount = 5;
|
|
expectEqual(options.keepaliveCount, 5)
|
|
|
|
expectEqual(options.keepaliveIdle, 0)
|
|
options.keepaliveIdle = 5;
|
|
expectEqual(options.keepaliveIdle, 5)
|
|
|
|
expectEqual(options.keepaliveInterval, 0)
|
|
options.keepaliveInterval = 5;
|
|
expectEqual(options.keepaliveInterval, 5)
|
|
|
|
expectEqual(options.maximumSegmentSize, 0)
|
|
options.maximumSegmentSize = 500;
|
|
expectEqual(options.maximumSegmentSize, 500)
|
|
|
|
expectEqual(options.connectionTimeout, 0)
|
|
options.connectionTimeout = 60;
|
|
expectEqual(options.connectionTimeout, 60)
|
|
|
|
expectEqual(options.persistTimeout, 0)
|
|
options.persistTimeout = 60;
|
|
expectEqual(options.persistTimeout, 60)
|
|
|
|
expectEqual(options.connectionDropTime, 0)
|
|
options.connectionDropTime = 60;
|
|
expectEqual(options.connectionDropTime, 60)
|
|
|
|
expectEqual(options.retransmitFinDrop, false)
|
|
options.retransmitFinDrop = true;
|
|
expectEqual(options.retransmitFinDrop, true)
|
|
|
|
expectEqual(options.disableAckStretching, false)
|
|
options.disableAckStretching = true;
|
|
expectEqual(options.disableAckStretching, true)
|
|
|
|
expectEqual(options.enableFastOpen, false)
|
|
options.enableFastOpen = true;
|
|
expectEqual(options.enableFastOpen, true)
|
|
|
|
expectEqual(options.disableECN, false)
|
|
options.disableECN = true;
|
|
expectEqual(options.disableECN, true)
|
|
}
|
|
|
|
NetworkAPI.test("NWProtocolUDP") {
|
|
expectNotNil(NWProtocolUDP.definition)
|
|
expectEqual(NWProtocolUDP.definition.name, "udp")
|
|
|
|
let options = NWProtocolUDP.Options()
|
|
expectNotNil(options)
|
|
|
|
expectEqual(options.preferNoChecksum, false)
|
|
options.preferNoChecksum = true;
|
|
expectEqual(options.preferNoChecksum, true)
|
|
}
|
|
|
|
NetworkAPI.test("NWProtocolIP") {
|
|
expectNotNil(NWProtocolIP.definition)
|
|
expectEqual(NWProtocolIP.definition.name, "ip")
|
|
|
|
let parameters = NWParameters()
|
|
let options = parameters.defaultProtocolStack.internetProtocol
|
|
expectNotNil(options)
|
|
|
|
expectTrue(options is NWProtocolIP.Options)
|
|
|
|
let ipOptions = options as! NWProtocolIP.Options
|
|
|
|
expectEqual(ipOptions.version, .any)
|
|
ipOptions.version = .v6;
|
|
expectEqual(ipOptions.version, .v6)
|
|
|
|
expectEqual(ipOptions.hopLimit, 0)
|
|
ipOptions.hopLimit = 5;
|
|
expectEqual(ipOptions.hopLimit, 5)
|
|
|
|
expectEqual(ipOptions.useMinimumMTU, false)
|
|
ipOptions.useMinimumMTU = true;
|
|
expectEqual(ipOptions.useMinimumMTU, true)
|
|
|
|
expectEqual(ipOptions.disableFragmentation, false)
|
|
ipOptions.disableFragmentation = true;
|
|
expectEqual(ipOptions.disableFragmentation, true)
|
|
|
|
let metadata = NWProtocolIP.Metadata()
|
|
expectNotNil(metadata)
|
|
|
|
expectEqual(metadata.ecn, .nonECT)
|
|
metadata.ecn = .ect0;
|
|
expectEqual(metadata.ecn, .ect0)
|
|
|
|
expectEqual(metadata.serviceClass, .bestEffort)
|
|
metadata.serviceClass = .background;
|
|
expectEqual(metadata.serviceClass, .background)
|
|
|
|
expectEqual(metadata.receiveTime, 0)
|
|
}
|
|
|
|
NetworkAPI.test("NWProtocolTLS") {
|
|
expectNotNil(NWProtocolTLS.definition)
|
|
expectEqual(NWProtocolTLS.definition.name, "tls")
|
|
|
|
let options = NWProtocolTLS.Options()
|
|
expectNotNil(options)
|
|
expectNotNil(options.securityProtocolOptions)
|
|
}
|
|
|
|
NetworkAPI.test("NWPath")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let testQueue = DispatchQueue(label: "testQueue")
|
|
let group = DispatchGroup()
|
|
|
|
let monitor = NWPathMonitor()
|
|
expectNotNil(monitor)
|
|
|
|
monitor.pathUpdateHandler = { (newPath) in
|
|
expectNotNil(newPath)
|
|
group.leave()
|
|
}
|
|
|
|
group.enter();
|
|
monitor.start(queue: testQueue)
|
|
|
|
let path = monitor.currentPath
|
|
expectNotNil(path)
|
|
|
|
let result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
expectEqual(monitor.queue, testQueue)
|
|
|
|
expectNil(path.localEndpoint)
|
|
expectNil(path.remoteEndpoint)
|
|
|
|
for interface in path.availableInterfaces {
|
|
expectNotNil(interface.name)
|
|
expectTrue(interface.index != 0)
|
|
}
|
|
|
|
monitor.cancel()
|
|
|
|
let wifiMonitor = NWPathMonitor(requiredInterfaceType: .wifi)
|
|
expectNotNil(wifiMonitor)
|
|
|
|
wifiMonitor.start(queue: testQueue)
|
|
|
|
let wifiPath = wifiMonitor.currentPath
|
|
expectNotNil(wifiPath)
|
|
|
|
if wifiPath.status == .satisfied {
|
|
expectTrue(wifiPath.usesInterfaceType(.wifi))
|
|
expectTrue(wifiPath.supportsIPv4 || wifiPath.supportsIPv6 || wifiPath.supportsDNS)
|
|
expectTrue(wifiPath.availableInterfaces.count > 0)
|
|
var someInterfaceWiFi = false
|
|
for interface in wifiPath.availableInterfaces {
|
|
if (interface.type == .wifi) {
|
|
someInterfaceWiFi = true
|
|
break
|
|
}
|
|
}
|
|
expectTrue(someInterfaceWiFi)
|
|
}
|
|
|
|
wifiMonitor.cancel()
|
|
|
|
let loopbackMonitor = NWPathMonitor(requiredInterfaceType: .loopback)
|
|
expectNotNil(loopbackMonitor)
|
|
|
|
loopbackMonitor.start(queue: testQueue)
|
|
|
|
let loopbackPath = loopbackMonitor.currentPath
|
|
expectNotNil(loopbackPath)
|
|
|
|
expectTrue(!loopbackPath.isExpensive)
|
|
|
|
loopbackMonitor.cancel()
|
|
}
|
|
|
|
NetworkAPI.test("NWListener failure")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let parameters: NWParameters = .tcp
|
|
parameters.requiredLocalEndpoint = NWEndpoint.hostPort(host: "127.0.0.1", port: 1234)
|
|
|
|
var listener: NWListener? = nil
|
|
do {
|
|
listener = try NWListener(using: parameters, on: 2345)
|
|
} catch {
|
|
print("Received listener error: \(error).")
|
|
}
|
|
expectNil(listener)
|
|
}
|
|
|
|
NetworkAPI.test("NWListener")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let testQueue = DispatchQueue(label: "testQueue")
|
|
let group = DispatchGroup()
|
|
let advertiseGroup = DispatchGroup()
|
|
|
|
let listener = try! NWListener(using: .tcp, on: 1234)
|
|
expectNotNil(listener)
|
|
|
|
listener.service = NWListener.Service(type: "_ipp._tcp")
|
|
|
|
listener.stateUpdateHandler = { (newState) in
|
|
switch(newState) {
|
|
case .ready:
|
|
group.leave()
|
|
case .failed(let error):
|
|
expectNotNil(error)
|
|
listener.cancel()
|
|
case .cancelled:
|
|
group.leave()
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
listener.newConnectionHandler = { (newConn) in
|
|
expectNotNil(newConn)
|
|
newConn.forceCancel()
|
|
}
|
|
|
|
listener.serviceRegistrationUpdateHandler = { (serviceChange) in
|
|
switch(serviceChange) {
|
|
case .add(let endpoint):
|
|
expectNotNil(endpoint)
|
|
case .remove(let endpoint):
|
|
expectNotNil(endpoint)
|
|
}
|
|
advertiseGroup.leave()
|
|
}
|
|
|
|
group.enter()
|
|
advertiseGroup.enter()
|
|
listener.start(queue: testQueue)
|
|
|
|
// Wait for ready
|
|
var result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
// Wait for advertise
|
|
result = advertiseGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
expectEqual(listener.queue, testQueue)
|
|
expectTrue(listener.parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectEqual(listener.port, 1234)
|
|
|
|
group.enter()
|
|
listener.cancel()
|
|
|
|
// Wait for cancelled
|
|
result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
}
|
|
|
|
NetworkAPI.test("NWConnection creation") {
|
|
var connection = NWConnection(host: "localhost", port: 2345, using:.tcp)
|
|
expectNotNil(connection)
|
|
|
|
connection = NWConnection(to: .hostPort(host: "localhost", port: 2345), using:.tcp)
|
|
expectNotNil(connection)
|
|
|
|
connection = NWConnection(to: .service(name: "myprinter", type: "_ipp._tcp", domain: "local", interface: nil), using:.tcp)
|
|
expectNotNil(connection)
|
|
|
|
connection = NWConnection(to: .unix(path: "/foo/bar"), using:.tcp)
|
|
expectNotNil(connection)
|
|
}
|
|
|
|
NetworkAPI.test("NWConnection Waiting Reset")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let testQueue = DispatchQueue(label: "testQueue")
|
|
let group = DispatchGroup()
|
|
|
|
let connection = NWConnection(host: "localhost", port: 3456, using:.tls)
|
|
expectNotNil(connection)
|
|
|
|
connection.stateUpdateHandler = { (newState) in
|
|
switch(newState) {
|
|
case .waiting(let error):
|
|
expectNotNil(error)
|
|
switch(error) {
|
|
case .posix(let code):
|
|
expectEqual(code, .ECONNREFUSED)
|
|
default:
|
|
break
|
|
}
|
|
group.leave()
|
|
case .failed(let error):
|
|
expectNotNil(error)
|
|
connection.cancel()
|
|
case .cancelled:
|
|
group.leave()
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
group.enter()
|
|
connection.start(queue: testQueue)
|
|
|
|
// Wait for waiting
|
|
var result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
connection.restart()
|
|
|
|
group.enter()
|
|
connection.cancel()
|
|
|
|
// Wait for cancelled
|
|
result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
}
|
|
|
|
NetworkAPI.test("NWConnection Waiting DNS")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let testQueue = DispatchQueue(label: "testQueue")
|
|
let group = DispatchGroup()
|
|
|
|
let connection = NWConnection(host: "foobar.fake.apple.com", port: .https, using:.tls)
|
|
expectNotNil(connection)
|
|
|
|
connection.stateUpdateHandler = { (newState) in
|
|
switch(newState) {
|
|
case .waiting(let error):
|
|
expectNotNil(error)
|
|
switch(error) {
|
|
case .dns(let code):
|
|
expectEqual(code, DNSServiceErrorType(kDNSServiceErr_NoSuchRecord))
|
|
default:
|
|
break
|
|
}
|
|
group.leave()
|
|
case .failed(let error):
|
|
expectNotNil(error)
|
|
connection.cancel()
|
|
case .cancelled:
|
|
group.leave()
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
group.enter()
|
|
connection.start(queue: testQueue)
|
|
|
|
// Wait for waiting
|
|
var result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
group.enter()
|
|
connection.cancel()
|
|
|
|
// Wait for cancelled
|
|
result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
}
|
|
|
|
NetworkAPI.test("NWConnection TCP")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let testQueue = DispatchQueue(label: "testQueue")
|
|
let group = DispatchGroup()
|
|
let viableGroup = DispatchGroup()
|
|
let pathGroup = DispatchGroup()
|
|
let sendGroup = DispatchGroup()
|
|
let receiveGroup = DispatchGroup()
|
|
|
|
let listener = try! NWListener(using: .tcp, on: 2345)
|
|
expectNotNil(listener)
|
|
|
|
var inboundConnection: NWConnection? = nil
|
|
listener.newConnectionHandler = { (newConn) in
|
|
expectNotNil(newConn)
|
|
inboundConnection = newConn
|
|
newConn.receive(minimumIncompleteLength: 5, maximumLength: 5) { (receivedContent, context, isComplete, receivedError) in
|
|
expectTrue(!isComplete)
|
|
expectNil(receivedError)
|
|
expectNotNil(receivedContent)
|
|
expectNotNil(context)
|
|
receiveGroup.leave()
|
|
}
|
|
newConn.start(queue: testQueue)
|
|
}
|
|
listener.start(queue: testQueue)
|
|
|
|
// Make sure connecting by address works
|
|
let ipv4Address = IPv4Address("127.0.0.1")
|
|
let connection = NWConnection(to: NWEndpoint.hostPort(host: .ipv4(ipv4Address!), port: 2345), using:.tcp)
|
|
expectNotNil(connection)
|
|
|
|
connection.stateUpdateHandler = { (newState) in
|
|
switch(newState) {
|
|
case .ready:
|
|
group.leave()
|
|
case .failed(let error):
|
|
expectNotNil(error)
|
|
connection.cancel()
|
|
case .cancelled:
|
|
group.leave()
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
connection.pathUpdateHandler = { (newPath) in
|
|
expectNotNil(newPath)
|
|
pathGroup.leave()
|
|
}
|
|
|
|
connection.viabilityUpdateHandler = { (isViable) in
|
|
expectTrue(isViable)
|
|
viableGroup.leave()
|
|
}
|
|
|
|
connection.betterPathUpdateHandler = { (betterPathAvailable) in
|
|
expectTrue(!betterPathAvailable)
|
|
}
|
|
|
|
group.enter()
|
|
viableGroup.enter()
|
|
pathGroup.enter()
|
|
receiveGroup.enter()
|
|
connection.start(queue: testQueue)
|
|
|
|
// Wait for ready
|
|
var result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
let path = connection.currentPath
|
|
expectNotNil(path)
|
|
if let path = path {
|
|
expectTrue(path.usesInterfaceType(.loopback))
|
|
expectNotNil(path.localEndpoint)
|
|
expectNotNil(path.remoteEndpoint)
|
|
}
|
|
|
|
let metadata = connection.metadata(definition: NWProtocolTCP.definition)
|
|
expectNotNil(metadata)
|
|
expectTrue(metadata is NWProtocolTCP.Metadata)
|
|
|
|
let tcpMetadata = metadata as! NWProtocolTCP.Metadata
|
|
expectEqual(tcpMetadata.availableReceiveBuffer, 0)
|
|
expectEqual(tcpMetadata.availableSendBuffer, 0)
|
|
|
|
// Wait for viable
|
|
result = viableGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
// Wait for path
|
|
result = pathGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
expectEqual(connection.queue, testQueue)
|
|
expectTrue(connection.parameters.defaultProtocolStack.transportProtocol is NWProtocolTCP.Options)
|
|
expectNotNil(connection.endpoint)
|
|
|
|
sendGroup.enter()
|
|
|
|
let sendContent: Data = "hello".data(using: .utf8)!
|
|
connection.send(content: sendContent, isComplete: false, completion: .contentProcessed({ (sendError) in
|
|
expectNil(sendError)
|
|
sendGroup.leave()
|
|
}))
|
|
|
|
// Wait for send
|
|
result = sendGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
// Wait for receive
|
|
result = receiveGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
// Send complete
|
|
connection.send(content: sendContent, contentContext: .finalMessage, isComplete: true, completion: .idempotent)
|
|
|
|
group.enter()
|
|
connection.cancel()
|
|
|
|
// Wait for cancelled
|
|
result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
if let inboundConnection = inboundConnection {
|
|
inboundConnection.forceCancel()
|
|
}
|
|
listener.cancel()
|
|
}
|
|
|
|
NetworkAPI.test("NWConnection UDP")
|
|
.skip(.iOSSimulatorAny("Path not fully supported on simulator"))
|
|
.skip(.tvOSSimulatorAny("Path not fully supported on simulator"))
|
|
.code {
|
|
let testQueue = DispatchQueue(label: "testQueue")
|
|
let group = DispatchGroup()
|
|
let cancelGroup = DispatchGroup()
|
|
let receiveGroup = DispatchGroup()
|
|
|
|
var inboundConnection: NWConnection? = nil
|
|
let listener = try! NWListener(using: .udp, on: 4567)
|
|
expectNotNil(listener)
|
|
|
|
listener.newConnectionHandler = { (newConn) in
|
|
expectNotNil(newConn)
|
|
inboundConnection = newConn
|
|
newConn.receiveMessage() { (receivedContent, context, isComplete, receivedError) in
|
|
expectTrue(isComplete)
|
|
expectNil(receivedError)
|
|
expectNotNil(receivedContent)
|
|
expectNotNil(context)
|
|
receiveGroup.leave()
|
|
}
|
|
newConn.start(queue: testQueue)
|
|
}
|
|
listener.start(queue: testQueue)
|
|
|
|
let connection = NWConnection(host: "localhost", port: 4567, using:.udp)
|
|
expectNotNil(connection)
|
|
|
|
connection.stateUpdateHandler = { (newState) in
|
|
switch(newState) {
|
|
case .ready:
|
|
group.leave()
|
|
case .failed(let error):
|
|
expectNotNil(error)
|
|
connection.cancel()
|
|
case .cancelled:
|
|
cancelGroup.leave()
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
group.enter()
|
|
receiveGroup.enter()
|
|
connection.start(queue: testQueue)
|
|
|
|
// Wait for ready
|
|
var result = group.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
expectEqual(connection.queue, testQueue)
|
|
expectTrue(connection.parameters.defaultProtocolStack.transportProtocol is NWProtocolUDP.Options)
|
|
expectNotNil(connection.endpoint)
|
|
|
|
let ipMetadata = NWProtocolIP.Metadata()
|
|
ipMetadata.ecn = .ect0
|
|
let sendContext = NWConnection.ContentContext(identifier: "sendHello", expiration: 5000, priority: 1.0, isFinal: false, antecedent: nil, metadata: [ipMetadata])
|
|
|
|
expectNotNil(sendContext)
|
|
expectNotNil(sendContext.protocolMetadata)
|
|
expectNil(sendContext.antecedent)
|
|
expectEqual(sendContext.expirationMilliseconds, 5000)
|
|
expectEqual(sendContext.relativePriority, 1.0)
|
|
expectEqual(sendContext.isFinal, false)
|
|
expectEqual(sendContext.identifier, "sendHello")
|
|
|
|
let sendContent: Data = "hello".data(using: .utf8)!
|
|
|
|
connection.batch {
|
|
connection.send(content: sendContent, contentContext: sendContext, completion: .idempotent)
|
|
}
|
|
|
|
// Wait for receive
|
|
result = receiveGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
cancelGroup.enter()
|
|
|
|
connection.cancelCurrentEndpoint()
|
|
connection.cancel()
|
|
|
|
// Wait for cancelled
|
|
result = cancelGroup.wait(timeout: DispatchTime.now() + .seconds(10))
|
|
expectTrue(result == .success)
|
|
|
|
if let inboundConnection = inboundConnection {
|
|
inboundConnection.forceCancel()
|
|
}
|
|
listener.cancel()
|
|
}
|
|
}
|
|
|
|
#endif
|