From 0ba2c42d957e2f2bc028d8b416858f8093936722 Mon Sep 17 00:00:00 2001 From: J Logan Date: Wed, 10 Sep 2025 10:22:34 -0700 Subject: [PATCH] Pass DNS integration tests when default domain is set. (#594) - Closes #547. - Reduce DNS test count, make tests more readable. ## Type of Change - [x] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Documentation update ## Motivation and Context Painful to have to unset the default domain on a dev system to pass local integration tests. ## Testing - [x] Tested locally - [x] Added/updated tests - [ ] Added/updated docs --- .../Subcommands/Run/TestCLIRunOptions.swift | 114 +++++++++--------- 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/Tests/CLITests/Subcommands/Run/TestCLIRunOptions.swift b/Tests/CLITests/Subcommands/Run/TestCLIRunOptions.swift index 0bd38ac4..44a5e7bd 100644 --- a/Tests/CLITests/Subcommands/Run/TestCLIRunOptions.swift +++ b/Tests/CLITests/Subcommands/Run/TestCLIRunOptions.swift @@ -367,61 +367,69 @@ class TestCLIRunCommand: CLITest { } } - @Test func testRunCommandDNS() throws { + @Test func testRunCommandDefaultResolvConf() throws { do { let name: String! = Test.current?.name.trimmingCharacters(in: ["(", ")"]) - let dns = "8.8.8.8" - try doLongRun(name: name, args: ["--dns", dns]) + try doLongRun(name: name, args: []) defer { try? doStop(name: name) } - var output = try doExec(name: name, cmd: ["cat", "/etc/resolv.conf"]) - output = output.trimmingCharacters(in: .whitespacesAndNewlines) - let words = output.split(separator: " ") - #expect(words.count == 2, "expected 'nameserver \(dns)', instead got '\(output)'") - #expect(words[1].lowercased() == dns, "expected 'nameserver \(dns)', instead got '\(output)'") + + let output = try doExec(name: name, cmd: ["cat", "/etc/resolv.conf"]) + let actualLines = output.components(separatedBy: .newlines) + .filter { !$0.isEmpty } + .map { $0.components(separatedBy: .whitespaces) } + .map { $0.joined(separator: " ") } + + let inspectOutput = try inspectContainer(name) + let ip = String(inspectOutput.networks[0].address.split(separator: "/")[0]) + let ipv4Address = try IPv4Address(ip) + let expectedNameserver = IPv4Address(fromValue: ipv4Address.prefix(prefixLength: 24).value + 1).description + let defaultDomain = try getDefaultDomain() + let expectedLines: [String] = [ + "nameserver \(expectedNameserver)", + defaultDomain.map { "domain \($0)" }, + ].compactMap { $0 } + + #expect(expectedLines == actualLines) } catch { Issue.record("failed to run container \(error)") return } } - @Test func testRunCommandDNSDomain() throws { + @Test func testRunCommandNonDefaultResolvConf() throws { do { + let expectedDns: String = "8.8.8.8" + let expectedDomain = "example.com" + let expectedSearch = "test.com" + let expectedOption = "debug" let name: String! = Test.current?.name.trimmingCharacters(in: ["(", ")"]) - let dnsDomain = "example.com" - try doLongRun(name: name, args: ["--dns-domain", dnsDomain]) + try doLongRun( + name: name, + args: [ + "--dns", expectedDns, + "--dns-domain", expectedDomain, + "--dns-search", expectedSearch, + "--dns-option", expectedOption, + ]) defer { try? doStop(name: name) } - let output = try doExec(name: name, cmd: ["cat", "/etc/resolv.conf"]) - let lines = output.split(separator: "\n") - #expect(lines.count == 2, "expected two lines of info in /etc/resolv.conf, got \(output)") - let words = lines[1].split(separator: " ") - #expect(words.count == 2, "expected 'domain \(dnsDomain)', instead got '\(lines[1])'") - #expect(words[0].lowercased() == "domain", "expected entry to list domain, instead got '\(words[0])'") - #expect(words[1].lowercased() == dnsDomain, "expected '\(dnsDomain)' search domain, instead got '\(words[1])'") - } catch { - Issue.record("failed to run container \(error)") - return - } - } - @Test func testRunCommandDNSSearch() throws { - do { - let name: String! = Test.current?.name.trimmingCharacters(in: ["(", ")"]) - let dnsSearch = "test.com" - try doLongRun(name: name, args: ["--dns-search", dnsSearch]) - defer { - try? doStop(name: name) - } let output = try doExec(name: name, cmd: ["cat", "/etc/resolv.conf"]) - let lines = output.split(separator: "\n") - #expect(lines.count == 2, "expected two lines of info in /etc/resolv.conf, got \(output)") - let words = lines[1].split(separator: " ") - #expect(words.count == 2, "expected 'search \(dnsSearch)', instead got '\(lines[1])'") - #expect(words[0].lowercased() == "search", "expected entry to list search domains, instead got '\(words[0])'") - #expect(words[1].lowercased() == dnsSearch, "expected '\(dnsSearch)' search domain, instead got '\(words[1])'") + let actualLines = output.components(separatedBy: .newlines) + .filter { !$0.isEmpty } + .map { $0.components(separatedBy: .whitespaces) } + .map { $0.joined(separator: " ") } + + let expectedLines: [String] = [ + "nameserver \(expectedDns)", + "domain \(expectedDomain)", + "search \(expectedSearch)", + "opts \(expectedOption)", + ] + #expect(expectedLines == actualLines) } catch { Issue.record("failed to run container \(error)") return @@ -457,27 +465,6 @@ class TestCLIRunCommand: CLITest { } } - @Test func testRunCommandDNSOption() throws { - do { - let name: String! = Test.current?.name.trimmingCharacters(in: ["(", ")"]) - let dnsOption = "debug" - try doLongRun(name: name, args: ["--dns-option", dnsOption]) - defer { - try? doStop(name: name) - } - let output = try doExec(name: name, cmd: ["cat", "/etc/resolv.conf"]) - let lines = output.split(separator: "\n") - #expect(lines.count == 2, "expected two lines of info in /etc/resolv.conf, got \(output)") - let words = lines[1].split(separator: " ") - #expect(words.count == 2, "expected 'opts \(dnsOption)', instead got '\(lines[1])'") - #expect(words[0].lowercased() == "opts", "expected entry to list dns options, instead got '\(words[0])'") - #expect(words[1].lowercased() == dnsOption, "expected option '\(dnsOption)', instead got '\(words[1])'") - } catch { - Issue.record("failed to run container \(error)") - return - } - } - @Test func testForwardTCP() async throws { let retries = 10 let retryDelaySeconds = Int64(3) @@ -521,4 +508,15 @@ class TestCLIRunCommand: CLITest { return } } + + func getDefaultDomain() throws -> String? { + let (output, err, status) = try run(arguments: ["system", "dns", "default", "inspect"]) + try #require(status == 0, "default DNS domain retrieval returned status \(status): \(err)") + let trimmedOutput = output.trimmingCharacters(in: .whitespacesAndNewlines) + if trimmedOutput == "" { + return nil + } + + return trimmedOutput + } }