File: SocketAddressTest.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (480 lines) | stat: -rw-r--r-- 20,884 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import XCTest
@testable import NIO

class SocketAddressTest: XCTestCase {

    func testDescriptionWorks() throws {
        var ipv4SocketAddress = sockaddr_in()
        let res = "10.0.0.1".withCString { p in
            inet_pton(NIOBSDSocket.AddressFamily.inet.rawValue, p, &ipv4SocketAddress.sin_addr)
        }
        XCTAssertEqual(res, 1)
        ipv4SocketAddress.sin_port = (12345 as in_port_t).bigEndian
        let sa = SocketAddress(ipv4SocketAddress, host: "foobar.com")
        XCTAssertEqual("[IPv4]foobar.com/10.0.0.1:12345", sa.description)
    }

    func testDescriptionWorksWithoutIP() throws {
        var ipv4SocketAddress = sockaddr_in()
        ipv4SocketAddress.sin_port = (12345 as in_port_t).bigEndian
        let sa = SocketAddress(ipv4SocketAddress, host: "foobar.com")
        XCTAssertEqual("[IPv4]foobar.com/0.0.0.0:12345", sa.description)
    }
    
    func testDescriptionWorksWithIPOnly() throws {
        let sa = try! SocketAddress(ipAddress: "10.0.0.2", port: 12345)
        XCTAssertEqual("[IPv4]10.0.0.2:12345", sa.description)
    }
    
    func testDescriptionWorksWithByteBufferIPv4IP() throws {
        let IPv4: [UInt8] = [0x7F, 0x00, 0x00, 0x01]
        let ipv4Address: ByteBuffer = ByteBuffer.init(bytes: IPv4)
        let sa = try! SocketAddress(packedIPAddress: ipv4Address, port: 12345)
        XCTAssertEqual("[IPv4]127.0.0.1:12345", sa.description)
    }
    
    func testDescriptionWorksWithByteBufferIPv6IP() throws {
        let IPv6: [UInt8] = [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05]
        let ipv6Address: ByteBuffer = ByteBuffer.init(bytes: IPv6)
        let sa = try! SocketAddress(packedIPAddress: ipv6Address, port: 12345)
        XCTAssertEqual("[IPv6]fe80::5:12345", sa.description)
    }
    
    func testRejectsWrongIPByteBufferLength() {
        let wrongIP: [UInt8] = [0x01, 0x7F, 0x00]
        let ipAddress: ByteBuffer = ByteBuffer.init(bytes: wrongIP)
        XCTAssertThrowsError(try SocketAddress(packedIPAddress: ipAddress, port: 12345)) { error in
            switch error {
            case is SocketAddressError.FailedToParseIPByteBuffer:
                XCTAssertEqual(ipAddress, (error as! SocketAddressError.FailedToParseIPByteBuffer).address)
            default:
                XCTFail("unexpected error: \(error)")
            }
        }
    }
    
    func testIn6AddrDescriptionWorks() throws {
        let sampleString = "::1"
        let sampleIn6Addr: [UInt8] = [ // ::1
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
            0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x54,
            0xc2, 0xb5, 0x58, 0xff, 0x7f, 0x0, 0x0, 0x7,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x1, 0x1, 0x0
        ]

        var address         = sockaddr_in6()
        #if os(Linux) || os(Android) // no sin6_len on Linux/Android
        #else
          address.sin6_len  = UInt8(MemoryLayout<sockaddr_in6>.size)
        #endif
        address.sin6_family = sa_family_t(NIOBSDSocket.AddressFamily.inet6.rawValue)
        address.sin6_addr   = sampleIn6Addr.withUnsafeBytes {
            $0.baseAddress!.bindMemory(to: in6_addr.self, capacity: 1).pointee
        }

        let s = address.addressDescription()
        XCTAssertEqual(s.count, sampleString.count,
                       "Address description has unexpected length 😱")
        XCTAssertEqual(s, sampleString,
                       "Address description is way below our expectations 😱")
    }
	
    func testIPAddressWorks() throws {
        let sa = try! SocketAddress(ipAddress: "127.0.0.1", port: 12345)
        XCTAssertEqual("127.0.0.1", sa.ipAddress)
        let sa6 = try! SocketAddress(ipAddress: "::1", port: 12345)
        XCTAssertEqual("::1", sa6.ipAddress)
        let unix = try! SocketAddress(unixDomainSocketPath: "/definitely/a/path")
        XCTAssertEqual(nil, unix.ipAddress)
    }

    func testCanCreateIPv4AddressFromString() throws {
        let sa = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let expectedAddress: [UInt8] = [0x7F, 0x00, 0x00, 0x01]
        if case .v4(let address) = sa {
            var addr = address.address
            let host = address.host
            XCTAssertEqual(host, "")
            XCTAssertEqual(addr.sin_family, sa_family_t(NIOBSDSocket.AddressFamily.inet.rawValue))
            XCTAssertEqual(addr.sin_port, in_port_t(80).bigEndian)
            expectedAddress.withUnsafeBytes { expectedPtr in
                withUnsafeBytes(of: &addr.sin_addr) { actualPtr in
                    let rc = memcmp(actualPtr.baseAddress!, expectedPtr.baseAddress!, MemoryLayout<in_addr>.size)
                    XCTAssertEqual(rc, 0)
                }
            }
        } else {
            XCTFail("Invalid address: \(sa)")
        }
    }

    func testCanCreateIPv6AddressFromString() throws {
        let sa = try SocketAddress(ipAddress: "fe80::5", port: 443)
        let expectedAddress: [UInt8] = [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05]
        if case .v6(let address) = sa {
            var addr = address.address
            let host = address.host
            XCTAssertEqual(host, "")
            XCTAssertEqual(addr.sin6_family, sa_family_t(NIOBSDSocket.AddressFamily.inet6.rawValue))
            XCTAssertEqual(addr.sin6_port, in_port_t(443).bigEndian)
            XCTAssertEqual(addr.sin6_scope_id, 0)
            XCTAssertEqual(addr.sin6_flowinfo, 0)
            expectedAddress.withUnsafeBytes { expectedPtr in
                withUnsafeBytes(of: &addr.sin6_addr) { actualPtr in
                    let rc = memcmp(actualPtr.baseAddress!, expectedPtr.baseAddress!, MemoryLayout<in6_addr>.size)
                    XCTAssertEqual(rc, 0)
                }
            }
        } else {
            XCTFail("Invalid address: \(sa)")
        }
    }

    func testRejectsNonIPStrings() {
        XCTAssertThrowsError(try SocketAddress(ipAddress: "definitelynotanip", port: 800)) { error in
            switch error as? SocketAddressError {
            case .some(.failedToParseIPString("definitelynotanip")):
                () // ok
            default:
                XCTFail("unexpected error: \(error)")
            }
        }
    }

    func testWithMutableAddressCopiesFaithfully() throws {
        let first = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let second = try SocketAddress(ipAddress: "::1", port: 80)
        let third = try SocketAddress(unixDomainSocketPath: "/definitely/a/path")

        guard case .v4(let firstAddress) = first else {
            XCTFail("Unable to extract IPv4 address")
            return
        }
        guard case .v6(let secondAddress) = second else {
            XCTFail("Unable to extract IPv6 address")
            return
        }
        guard case .unixDomainSocket(let thirdAddress) = third else {
            XCTFail("Unable to extract UDS address")
            return
        }

        var firstIPAddress = firstAddress.address
        var secondIPAddress = secondAddress.address
        var thirdIPAddress = thirdAddress.address

        var firstCopy = firstIPAddress.withMutableSockAddr { (addr, size) -> sockaddr_in in
            XCTAssertEqual(size, MemoryLayout<sockaddr_in>.size)
            return addr.withMemoryRebound(to: sockaddr_in.self, capacity: 1) { $0.pointee }
        }
        var secondCopy = secondIPAddress.withMutableSockAddr { (addr, size) -> sockaddr_in6 in
            XCTAssertEqual(size, MemoryLayout<sockaddr_in6>.size)
            return addr.withMemoryRebound(to: sockaddr_in6.self, capacity: 1) { $0.pointee }
        }
        var thirdCopy = thirdIPAddress.withMutableSockAddr { (addr, size) -> sockaddr_un in
            XCTAssertEqual(size, MemoryLayout<sockaddr_un>.size)
            return addr.withMemoryRebound(to: sockaddr_un.self, capacity: 1) { $0.pointee }
        }

        XCTAssertEqual(memcmp(&firstIPAddress, &firstCopy, MemoryLayout<sockaddr_in>.size), 0)
        XCTAssertEqual(memcmp(&secondIPAddress, &secondCopy, MemoryLayout<sockaddr_in6>.size), 0)
        XCTAssertEqual(memcmp(&thirdIPAddress, &thirdCopy, MemoryLayout<sockaddr_un>.size), 0)
    }

    func testWithMutableAddressAllowsMutationWithoutPersistence() throws {
        let first = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let second = try SocketAddress(ipAddress: "::1", port: 80)
        let third = try SocketAddress(unixDomainSocketPath: "/definitely/a/path")

        guard case .v4(let firstAddress) = first else {
            XCTFail("Unable to extract IPv4 address")
            return
        }
        guard case .v6(let secondAddress) = second else {
            XCTFail("Unable to extract IPv6 address")
            return
        }
        guard case .unixDomainSocket(let thirdAddress) = third else {
            XCTFail("Unable to extract UDS address")
            return
        }

        var firstIPAddress = firstAddress.address
        var secondIPAddress = secondAddress.address
        var thirdIPAddress = thirdAddress.address

        // Copy the original values.
        var firstCopy = firstIPAddress
        var secondCopy = secondIPAddress
        var thirdCopy = thirdIPAddress

        firstIPAddress.withMutableSockAddr { (addr, size) -> Void in
            addr.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                $0.pointee.sin_port = 5
            }
        }
        secondIPAddress.withMutableSockAddr { (addr, size) -> Void in
            XCTAssertEqual(size, MemoryLayout<sockaddr_in6>.size)
            addr.withMemoryRebound(to: sockaddr_in6.self, capacity: 1) {
                $0.pointee.sin6_port = in_port_t(5).bigEndian
            }
        }
        thirdIPAddress.withMutableSockAddr { (addr, size) -> Void in
            XCTAssertEqual(size, MemoryLayout<sockaddr_un>.size)
            addr.withMemoryRebound(to: sockaddr_un.self, capacity: 1) {
                $0.pointee.sun_path.2 = 50
            }
        }

        XCTAssertEqual(memcmp(&firstIPAddress, &firstCopy, MemoryLayout<sockaddr_in>.size), 0)
        XCTAssertEqual(memcmp(&secondIPAddress, &secondCopy, MemoryLayout<sockaddr_in6>.size), 0)
        XCTAssertEqual(memcmp(&thirdIPAddress, &thirdCopy, MemoryLayout<sockaddr_un>.size), 0)
    }

    func testConvertingStorage() throws {
        let first = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let second = try SocketAddress(ipAddress: "::1", port: 80)
        let third = try SocketAddress(unixDomainSocketPath: "/definitely/a/path")

        guard case .v4(let firstAddress) = first else {
            XCTFail("Unable to extract IPv4 address")
            return
        }
        guard case .v6(let secondAddress) = second else {
            XCTFail("Unable to extract IPv6 address")
            return
        }
        guard case .unixDomainSocket(let thirdAddress) = third else {
            XCTFail("Unable to extract UDS address")
            return
        }

        var storage = sockaddr_storage()
        var firstIPAddress = firstAddress.address
        var secondIPAddress = secondAddress.address
        var thirdIPAddress = thirdAddress.address

        var firstCopy: sockaddr_in = withUnsafeBytes(of: &firstIPAddress) { outer in
            _ = withUnsafeMutableBytes(of: &storage) { temp in
                memcpy(temp.baseAddress!, outer.baseAddress!, MemoryLayout<sockaddr_in>.size)
            }
            return storage.convert()
        }
        var secondCopy: sockaddr_in6 = withUnsafeBytes(of: &secondIPAddress) { outer in
            _ = withUnsafeMutableBytes(of: &storage) { temp in
                memcpy(temp.baseAddress!, outer.baseAddress!, MemoryLayout<sockaddr_in6>.size)
            }
            return storage.convert()
        }
        var thirdCopy: sockaddr_un = withUnsafeBytes(of: &thirdIPAddress) { outer in
            _ = withUnsafeMutableBytes(of: &storage) { temp in
                memcpy(temp.baseAddress!, outer.baseAddress!, MemoryLayout<sockaddr_un>.size)
            }
            return storage.convert()
        }

        XCTAssertEqual(memcmp(&firstIPAddress, &firstCopy, MemoryLayout<sockaddr_in>.size), 0)
        XCTAssertEqual(memcmp(&secondIPAddress, &secondCopy, MemoryLayout<sockaddr_in6>.size), 0)
        XCTAssertEqual(memcmp(&thirdIPAddress, &thirdCopy, MemoryLayout<sockaddr_un>.size), 0)
    }

    func testComparingSockaddrs() throws {
        let first = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let second = try SocketAddress(ipAddress: "::1", port: 80)
        let third = try SocketAddress(unixDomainSocketPath: "/definitely/a/path")

        guard case .v4(let firstAddress) = first else {
            XCTFail("Unable to extract IPv4 address")
            return
        }
        guard case .v6(let secondAddress) = second else {
            XCTFail("Unable to extract IPv6 address")
            return
        }
        guard case .unixDomainSocket(let thirdAddress) = third else {
            XCTFail("Unable to extract UDS address")
            return
        }

        var firstIPAddress = firstAddress.address
        var secondIPAddress = secondAddress.address
        var thirdIPAddress = thirdAddress.address

        first.withSockAddr { outerAddr, outerSize in
            firstIPAddress.withSockAddr { innerAddr, innerSize in
                XCTAssertEqual(outerSize, innerSize)
                XCTAssertEqual(memcmp(innerAddr, outerAddr, min(outerSize, innerSize)), 0)
                XCTAssertNotEqual(outerAddr, innerAddr)
            }
        }
        second.withSockAddr { outerAddr, outerSize in
            secondIPAddress.withSockAddr { innerAddr, innerSize in
                XCTAssertEqual(outerSize, innerSize)
                XCTAssertEqual(memcmp(innerAddr, outerAddr, min(outerSize, innerSize)), 0)
                XCTAssertNotEqual(outerAddr, innerAddr)
            }
        }
        third.withSockAddr { outerAddr, outerSize in
            thirdIPAddress.withSockAddr { innerAddr, innerSize in
                XCTAssertEqual(outerSize, innerSize)
                XCTAssertEqual(memcmp(innerAddr, outerAddr, min(outerSize, innerSize)), 0)
                XCTAssertNotEqual(outerAddr, innerAddr)
            }
        }
    }

    func testEqualSocketAddresses() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "00:00::1", port: 80)
        let third = try SocketAddress(ipAddress: "127.0.0.1", port: 443)
        let fourth = try SocketAddress(ipAddress: "127.0.0.1", port: 443)
        let fifth = try SocketAddress(unixDomainSocketPath: "/var/tmp")
        let sixth = try SocketAddress(unixDomainSocketPath: "/var/tmp")

        XCTAssertEqual(first, second)
        XCTAssertEqual(third, fourth)
        XCTAssertEqual(fifth, sixth)
    }

    func testUnequalAddressesOnPort() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "::1", port: 443)
        let third = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let fourth = try SocketAddress(ipAddress: "127.0.0.1", port: 443)

        XCTAssertNotEqual(first, second)
        XCTAssertNotEqual(third, fourth)
    }

    func testUnequalOnAddress() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "::2", port: 80)
        let third = try SocketAddress(ipAddress: "127.0.0.1", port: 443)
        let fourth = try SocketAddress(ipAddress: "127.0.0.2", port: 443)
        let fifth = try SocketAddress(unixDomainSocketPath: "/var/tmp")
        let sixth = try SocketAddress(unixDomainSocketPath: "/var/tmq")

        XCTAssertNotEqual(first, second)
        XCTAssertNotEqual(third, fourth)
        XCTAssertNotEqual(fifth, sixth)
    }

    func testHashEqualSocketAddresses() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "00:00::1", port: 80)
        let third = try SocketAddress(ipAddress: "127.0.0.1", port: 443)
        let fourth = try SocketAddress(ipAddress: "127.0.0.1", port: 443)
        let fifth = try SocketAddress(unixDomainSocketPath: "/var/tmp")
        let sixth = try SocketAddress(unixDomainSocketPath: "/var/tmp")

        let set: Set<SocketAddress> = [first, second, third, fourth, fifth, sixth]
        XCTAssertEqual(set.count, 3)
        XCTAssertEqual(set, [first, third, fifth])
        XCTAssertEqual(set, [second, fourth, sixth])
    }

    func testHashUnequalAddressesOnPort() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "::1", port: 443)
        let third = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let fourth = try SocketAddress(ipAddress: "127.0.0.1", port: 443)

        let set: Set<SocketAddress> = [first, second, third, fourth]
        XCTAssertEqual(set.count, 4)
    }

    func testHashUnequalOnAddress() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "::2", port: 80)
        let third = try SocketAddress(ipAddress: "127.0.0.1", port: 443)
        let fourth = try SocketAddress(ipAddress: "127.0.0.2", port: 443)
        let fifth = try SocketAddress(unixDomainSocketPath: "/var/tmp")
        let sixth = try SocketAddress(unixDomainSocketPath: "/var/tmq")

        let set: Set<SocketAddress> = [first, second, third, fourth, fifth, sixth]
        XCTAssertEqual(set.count, 6)
    }

    func testUnequalAcrossFamilies() throws {
        let first = try SocketAddress(ipAddress: "::1", port: 80)
        let second = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        let third = try SocketAddress(unixDomainSocketPath: "/var/tmp")

        XCTAssertNotEqual(first, second)
        XCTAssertNotEqual(second, third)
        // By the transitive property first != third, but let's protect against me being an idiot
        XCTAssertNotEqual(third, first)
    }

    func testUnixSocketAddressIgnoresTrailingJunk() throws {
        var addr = sockaddr_un()
        addr.sun_family = sa_family_t(NIOBSDSocket.AddressFamily.unix.rawValue)
        let pathBytes: [UInt8] = "/var/tmp".utf8 + [0]

        pathBytes.withUnsafeBufferPointer { srcPtr in
            withUnsafeMutablePointer(to: &addr.sun_path) { dstPtr in
                dstPtr.withMemoryRebound(to: UInt8.self, capacity: srcPtr.count) { dstPtr in
                    dstPtr.assign(from: srcPtr.baseAddress!, count: srcPtr.count)
                }
            }
        }

        let first = SocketAddress(addr)

        // Now poke a random byte at the end. This should be ignored, as that's uninitialized memory.
        addr.sun_path.100 = 60
        let second = SocketAddress(addr)

        XCTAssertEqual(first, second)
        XCTAssertEqual(first.hashValue, second.hashValue)
    }

    func testPortAccessor() throws {
        XCTAssertEqual(try SocketAddress(ipAddress: "127.0.0.1", port: 80).port, 80)
        XCTAssertEqual(try SocketAddress(ipAddress: "::1", port: 80).port, 80)
        XCTAssertEqual(try SocketAddress(unixDomainSocketPath: "/definitely/a/path").port, nil)
    }

    func testCanMutateSockaddrStorage() throws {
        var storage = sockaddr_storage()
        XCTAssertEqual(storage.ss_family, 0)
        storage.withMutableSockAddr { (addr, _) in
            addr.pointee.sa_family = sa_family_t(NIOBSDSocket.AddressFamily.unix.rawValue)
        }
        XCTAssertEqual(storage.ss_family, sa_family_t(NIOBSDSocket.AddressFamily.unix.rawValue))
    }

    func testPortIsMutable() throws {
        var ipV4 = try SocketAddress(ipAddress: "127.0.0.1", port: 80)
        var ipV6 = try SocketAddress(ipAddress: "::1", port: 80)
        var unix = try SocketAddress(unixDomainSocketPath: "/definitely/a/path")

        ipV4.port = 81
        ipV6.port = 81

        XCTAssertEqual(ipV4.port, 81)
        XCTAssertEqual(ipV6.port, 81)

        ipV4.port = nil
        ipV6.port = nil
        unix.port = nil

        XCTAssertEqual(ipV4.port, 0)
        XCTAssertEqual(ipV6.port, 0)
        XCTAssertNil(unix.port)
    }
}