import XCTest @testable import NetworkCityCore /// Fixtures are taken verbatim from real `nettop -L 1 -x -n -J time,bytes_in,bytes_out` /// output captured on macOS 26, so the parser is pinned to reality. final class NettopParserTests: XCTestCase { let sample = """ time,,bytes_in,bytes_out, 23:49:56.574393,launchd.1,0,0, 23:49:56.573243,tcp4 127.0.0.1:8021<->*:*,,, 23:49:56.574395,apsd.571,15671580,11326466, 23:49:56.573044,tcp4 192.168.10.194:57359<->17.57.144.184:5223,15671580,11326466, 23:49:56.574397,trustd.609,10032,18469, 23:49:56.569491,quic4 192.168.10.194:51698<->17.248.242.102:443,5017,9232, 23:49:56.574410,mDNSResponder.647,974941537,77402609, 23:49:56.569906,udp6 *.5353<->*.*,176848739,34857088, 23:49:56.574316,tcp6 fe80::d08d:6eb7:1dcd:6466%utun4.1024<->fe80::9ed2:d4f7:aa69:9e47%utun4.1024,0,0, """ func testParsesProcessAndConnectionRows() { let conns = NettopParser.parseConnections(sample) // 4 connection rows present (launchd listener, apsd, trustd, mDNS, utun6) XCTAssertEqual(conns.count, 5) } func testConnectionInheritsPrecedingProcess() { let conns = NettopParser.parseConnections(sample) let apsd = conns.first { $0.remote.host == "17.57.144.184" } XCTAssertEqual(apsd?.processName, "apsd") XCTAssertEqual(apsd?.pid, 571) XCTAssertEqual(apsd?.proto, .tcp4) XCTAssertEqual(apsd?.remote.port, 5223) XCTAssertEqual(apsd?.bytesIn, 15671580) XCTAssertEqual(apsd?.bytesOut, 11326466) } func testIPv4EndpointParsing() { let ep = NettopParser.parseEndpoint("192.168.10.194:57359", isV6: false) XCTAssertEqual(ep.host, "192.168.10.194") XCTAssertEqual(ep.port, 57359) } func testIPv6EndpointParsingStripsZone() { let ep = NettopParser.parseEndpoint("fe80::d08d:6eb7:1dcd:6466%utun4.1024", isV6: true) XCTAssertEqual(ep.host, "fe80::d08d:6eb7:1dcd:6466") XCTAssertEqual(ep.port, 1024) } func testWildcardEndpointHasNoPort() { XCTAssertNil(NettopParser.parseEndpoint("*:*", isV6: false).port) XCTAssertNil(NettopParser.parseEndpoint("*.*", isV6: true).port) } func testExternalClassification() { let conns = NettopParser.parseConnections(sample) let external = conns.filter(\.isExternal) // Only apsd (17.57.x) and quic (17.248.x) are real off-box destinations. // Loopback listener, mDNS wildcard, and fe80 link-local are excluded. XCTAssertEqual(Set(external.map(\.remote.host)), ["17.57.144.184", "17.248.242.102"]) } func testQuicProtocolRecognised() { let conns = NettopParser.parseConnections(sample) XCTAssertTrue(conns.contains { $0.proto == .quic4 }) } }