| // 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 |