|
| 1 | +//===----------------------------------------------------------------------===// |
| 2 | +// Copyright © 2025 Apple Inc. and the container project authors. |
| 3 | +// |
| 4 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +// you may not use this file except in compliance with the License. |
| 6 | +// You may obtain a copy of the License at |
| 7 | +// |
| 8 | +// https://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +// |
| 10 | +// Unless required by applicable law or agreed to in writing, software |
| 11 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +// See the License for the specific language governing permissions and |
| 14 | +// limitations under the License. |
| 15 | +//===----------------------------------------------------------------------===// |
| 16 | + |
| 17 | +import Foundation |
| 18 | +import Testing |
| 19 | + |
| 20 | +/// Tests for `container system version` output formats and build type detection. |
| 21 | +final class TestCLIVersion: CLITest { |
| 22 | + struct VersionInfo: Codable { |
| 23 | + let version: String |
| 24 | + let buildType: String |
| 25 | + let commit: String |
| 26 | + let appName: String |
| 27 | + } |
| 28 | + |
| 29 | + struct VersionJSON: Codable { |
| 30 | + let version: String |
| 31 | + let buildType: String |
| 32 | + let commit: String |
| 33 | + let appName: String |
| 34 | + let server: VersionInfo? |
| 35 | + } |
| 36 | + |
| 37 | + private func expectedBuildType() throws -> String { |
| 38 | + let path = try executablePath |
| 39 | + if path.path.contains("/debug/") { |
| 40 | + return "debug" |
| 41 | + } else if path.path.contains("/release/") { |
| 42 | + return "release" |
| 43 | + } |
| 44 | + // Fallback: prefer debug when ambiguous (matches SwiftPM default for tests) |
| 45 | + return "debug" |
| 46 | + } |
| 47 | + |
| 48 | + @Test func defaultDisplaysTable() throws { |
| 49 | + let (data, out, err, status) = try run(arguments: ["system", "version"]) // default is table |
| 50 | + #expect(status == 0, "system version should succeed, stderr: \(err)") |
| 51 | + #expect(!out.isEmpty) |
| 52 | + |
| 53 | + // Validate table structure |
| 54 | + let lines = out.trimmingCharacters(in: .whitespacesAndNewlines) |
| 55 | + .components(separatedBy: .newlines) |
| 56 | + #expect(lines.count >= 2) // header + at least CLI row |
| 57 | + #expect(lines[0].contains("COMPONENT") && lines[0].contains("VERSION") && lines[0].contains("BUILD") && lines[0].contains("COMMIT")) |
| 58 | + #expect(lines[1].hasPrefix("CLI ")) |
| 59 | + |
| 60 | + // Build should reflect the binary we are running (debug/release) |
| 61 | + let expected = try expectedBuildType() |
| 62 | + #expect(lines.joined(separator: "\n").contains(" CLI ")) |
| 63 | + #expect(lines.joined(separator: "\n").contains(" \(expected) ")) |
| 64 | + _ = data // silence unused warning if assertions short-circuit |
| 65 | + } |
| 66 | + |
| 67 | + @Test func jsonFormat() throws { |
| 68 | + let (data, out, err, status) = try run(arguments: ["system", "version", "--format", "json"]) |
| 69 | + #expect(status == 0, "system version --format json should succeed, stderr: \(err)") |
| 70 | + #expect(!out.isEmpty) |
| 71 | + |
| 72 | + let decoded = try JSONDecoder().decode(VersionJSON.self, from: data) |
| 73 | + #expect(decoded.appName == "container CLI") |
| 74 | + #expect(!decoded.version.isEmpty) |
| 75 | + #expect(!decoded.commit.isEmpty) |
| 76 | + |
| 77 | + let expected = try expectedBuildType() |
| 78 | + #expect(decoded.buildType == expected) |
| 79 | + } |
| 80 | + |
| 81 | + @Test func explicitTableFormat() throws { |
| 82 | + let (_, out, err, status) = try run(arguments: ["system", "version", "--format", "table"]) |
| 83 | + #expect(status == 0, "system version --format table should succeed, stderr: \(err)") |
| 84 | + #expect(!out.isEmpty) |
| 85 | + |
| 86 | + let lines = out.trimmingCharacters(in: .whitespacesAndNewlines) |
| 87 | + .components(separatedBy: .newlines) |
| 88 | + #expect(lines.count >= 2) |
| 89 | + #expect(lines[0].contains("COMPONENT") && lines[0].contains("VERSION") && lines[0].contains("BUILD") && lines[0].contains("COMMIT")) |
| 90 | + #expect(lines[1].hasPrefix("CLI ")) |
| 91 | + } |
| 92 | + |
| 93 | + @Test func buildTypeMatchesBinary() throws { |
| 94 | + // Validate build type via JSON to avoid parsing table text loosely |
| 95 | + let (data, _, err, status) = try run(arguments: ["system", "version", "--format", "json"]) |
| 96 | + #expect(status == 0, "version --format json should succeed, stderr: \(err)") |
| 97 | + let decoded = try JSONDecoder().decode(VersionJSON.self, from: data) |
| 98 | + |
| 99 | + let expected = try expectedBuildType() |
| 100 | + #expect(decoded.buildType == expected, "Expected build type \(expected) but got \(decoded.buildType)") |
| 101 | + } |
| 102 | +} |
0 commit comments