From 263e8830e879e31c6a248684f42d28f12c680a78 Mon Sep 17 00:00:00 2001 From: Sam Khouri Date: Mon, 14 Jul 2025 09:24:41 -0400 Subject: [PATCH] Tests: Update isAmazonLinux2() logic The ProcessInfo extension to determine if a host is running on Amazon Linux 2 was slightly flawed as it did not take into account the double-quote (") surrounding the values. Update the logic to look at "PRETTY_NAME" since the ID can be used in multiple Amazon Linux OS'es, and use exact logic match. issue: rdar://155612963 --- .../ProcessInfo+hostutils.swift | 12 +- Tests/BasicsTests/ProcessInfoTests.swift | 93 ++++++++++- Tests/CommandsTests/APIDiffTests.swift | 146 +++++++++++------- Tests/CommandsTests/TestCommandTests.swift | 6 +- 4 files changed, 187 insertions(+), 70 deletions(-) diff --git a/Sources/_InternalTestSupport/ProcessInfo+hostutils.swift b/Sources/_InternalTestSupport/ProcessInfo+hostutils.swift index 2fbb61ec736..c09a1c59812 100644 --- a/Sources/_InternalTestSupport/ProcessInfo+hostutils.swift +++ b/Sources/_InternalTestSupport/ProcessInfo+hostutils.swift @@ -22,16 +22,8 @@ extension ProcessInfo { return false } } - let lines = contentString.components(separatedBy: .newlines) - for line in lines { - if line.starts(with: "ID=") { - let id = line.replacingOccurrences(of: "ID=", with: "").trimmingCharacters(in: .whitespacesAndNewlines) - if id == "amzn" { // ID for Amazon Linux is "amzn" - return true - } - } - } - return false + let al2_name = "PRETTY_NAME=\"Amazon Linux 2\"" + return contentString.contains(al2_name) } } \ No newline at end of file diff --git a/Tests/BasicsTests/ProcessInfoTests.swift b/Tests/BasicsTests/ProcessInfoTests.swift index 0b795d483b3..eeab84dec79 100644 --- a/Tests/BasicsTests/ProcessInfoTests.swift +++ b/Tests/BasicsTests/ProcessInfoTests.swift @@ -50,10 +50,95 @@ struct ProcessInfoExtensionTests { @Test( arguments: [ (contentUT: "", expected: false), - (contentUT: "ID=", expected: false), - (contentUT: "ID=foo", expected: false), - (contentUT: "ID=amzn", expected: true), - (contentUT: " ID=amzn", expected: false), + (contentUT: "PRETTY_NAME=", expected: false), + (contentUT: "PRETTY_NAME=foo", expected: false), + (contentUT: "PRETTY_NAME=amzn", expected: false), + (contentUT: "PRETTY_NAME=Amazon Linux 2", expected: false), + (contentUT: "PRETTY_NAME=Amazon Linux 2023.6.20250107", expected: false), + (contentUT: " PRETTY_NAME=amzn", expected: false), + (contentUT: "PRETTY_NAME=\"Amazon Linux 2\"", expected: true), + (contentUT: "PRETTY_NAME=\"Amazon Linux 2 (something else)\"", expected: false), + ( + contentUT: """ + NAME="Amazon Linux" + VERSION="2" + ID="amzn" + ID_LIKE="centos rhel fedora" + VERSION_ID="2" + PRETTY_NAME="Amazon Linux 2" + ANSI_COLOR="0;33" + CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" + HOME_URL="https://amazonlinux.com/" + SUPPORT_END="2026-06-30" + """, + expected: true + ), + ( + contentUT: """ + NAME="Amazon Linux" + VERSION="2" + ID="amzn" + ID_LIKE="centos rhel fedora" + VERSION_ID="2" + PRETTY_NAME="Amazon Linux 2 (something else)" + ANSI_COLOR="0;33" + CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" + HOME_URL="https://amazonlinux.com/" + SUPPORT_END="2026-06-30" + """, + expected: false + ), + ( + contentUT: """ + NAME="Amazon Linux" + VERSION="2" + ID="amzn" + ID_LIKE="centos rhel fedora" + VERSION_ID="2" + PRETTY_NAME=Amazon Linux 2 (something else) + ANSI_COLOR="0;33" + CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" + HOME_URL="https://amazonlinux.com/" + SUPPORT_END="2026-06-30" + """, + expected: false + ), + ( + contentUT: """ + NAME="Amazon Linux" + VERSION="2" + ID="amzn" + ID_LIKE="centos rhel fedora" + VERSION_ID="2" + PRETTY_NAME=Amazon Linux 2 + ANSI_COLOR="0;33" + CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" + HOME_URL="https://amazonlinux.com/" + SUPPORT_END="2026-06-30" + """, + expected: false + ), + ( + contentUT: """ + NAME="Amazon Linux" + VERSION="2023" + ID="amzn" + ID_LIKE="fedora" + VERSION_ID="2023" + PLATFORM_ID="platform:al2023" + PRETTY_NAME="Amazon Linux 2023.6.20250107" + ANSI_COLOR="0;33" + CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2023" + HOME_URL="https://aws.amazon.com/linux/amazon-linux-2023/" + DOCUMENTATION_URL="https://docs.aws.amazon.com/linux/" + SUPPORT_URL="https://aws.amazon.com/premiumsupport/" + BUG_REPORT_URL="https://github.com/amazonlinux/amazon-linux-2023" + VENDOR_NAME="AWS" + VENDOR_URL="https://aws.amazon.com/" + SUPPORT_END="2028-03-15" + """, + expected: false, + ) ], prefixAndSuffixData, ) fileprivate func isAmazonLinux2ReturnsExpectedValue( diff --git a/Tests/CommandsTests/APIDiffTests.swift b/Tests/CommandsTests/APIDiffTests.swift index b2f509740d4..65a086235c9 100644 --- a/Tests/CommandsTests/APIDiffTests.swift +++ b/Tests/CommandsTests/APIDiffTests.swift @@ -133,7 +133,11 @@ struct APIDiffTests { } } - @Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms) + @Test( + .requiresAPIDigester, + .issue("https://github.com/swiftlang/swift-package-manager/issues/8926", relationship: .defect), + arguments: SupportedBuildSystemOnAllPlatforms, + ) func testBreakageAllowlist(buildSystem: BuildSystemProvider.Kind) async throws { try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in let packageRoot = fixturePath.appending("Bar") @@ -154,11 +158,15 @@ struct APIDiffTests { try await execute(["diagnose-api-breaking-changes", "1.2.3", "--breakage-allowlist-path", customAllowlistPath.pathString], packagePath: packageRoot, buildSystem: buildSystem) ) { error in - #expect(error.stdout.contains("1 breaking change detected in Qux")) #expect(!error.stdout.contains("💔 API breakage: class Qux has generic signature change from to ")) - #expect(error.stdout.contains("💔 API breakage: var Qux.x has been removed")) - #expect(error.stdout.contains("1 breaking change detected in Baz")) - #expect(error.stdout.contains("💔 API breakage: func bar() has been removed")) + withKnownIssue { + #expect(error.stdout.contains("1 breaking change detected in Qux")) + #expect(error.stdout.contains("💔 API breakage: var Qux.x has been removed")) + #expect(error.stdout.contains("1 breaking change detected in Baz")) + #expect(error.stdout.contains("💔 API breakage: func bar() has been removed")) + } when: { + buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2() + } } } @@ -205,7 +213,11 @@ struct APIDiffTests { } } - @Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms) + @Test( + .requiresAPIDigester, + .issue("https://github.com/swiftlang/swift-package-manager/issues/8926", relationship: .defect), + arguments: SupportedBuildSystemOnAllPlatforms, + ) func testFilters(buildSystem: BuildSystemProvider.Kind) async throws { try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in let packageRoot = fixturePath.appending("NonAPILibraryTargets") @@ -228,10 +240,18 @@ struct APIDiffTests { try await expectThrowsCommandExecutionError( try await execute(["diagnose-api-breaking-changes", "1.2.3", "--products", "One", "--targets", "Bar"], packagePath: packageRoot, buildSystem: buildSystem) ) { error in - #expect(error.stdout.contains("💔 API breakage")) + withKnownIssue { + #expect(error.stdout.contains("💔 API breakage")) + } when: { + buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2() + } let regex = try Regex("\\d+ breaking change(s?) detected in Foo") - #expect(error.stdout.contains(regex)) - #expect(error.stdout.contains(regex)) + + withKnownIssue { + #expect(error.stdout.contains(regex)) + } when: { + buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2() + } // Baz and Qux are not included in the filter, so any API changes should be ignored. #expect(!error.stdout.contains("Baz")) @@ -242,9 +262,13 @@ struct APIDiffTests { try await expectThrowsCommandExecutionError( try await execute(["diagnose-api-breaking-changes", "1.2.3", "--targets", "Baz"], packagePath: packageRoot, buildSystem: buildSystem) ) { error in - #expect(error.stdout.contains("💔 API breakage")) - let regex = try Regex("\\d+ breaking change(s?) detected in Baz") - #expect(error.stdout.contains(regex)) + try withKnownIssue { + #expect(error.stdout.contains("💔 API breakage")) + let regex = try Regex("\\d+ breaking change(s?) detected in Baz") + #expect(error.stdout.contains(regex)) + } when: { + buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2() + } // Only Baz is included, we should not see any other API changes. #expect(!error.stdout.contains("Foo")) @@ -310,53 +334,69 @@ struct APIDiffTests { } } - @Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms) + @Test( + .requiresAPIDigester, + .issue("https://github.com/swiftlang/swift-package-manager/issues/8926", relationship: .defect), + arguments: SupportedBuildSystemOnAllPlatforms, + ) func testNoBreakingChanges(buildSystem: BuildSystemProvider.Kind) async throws { - try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in - let packageRoot = fixturePath.appending("Bar") - // Introduce an API-compatible change - try localFileSystem.writeFileContents( - packageRoot.appending(components: "Sources", "Baz", "Baz.swift"), - string: "public func bar() -> Int { 100 }" - ) - let (output, _) = try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem) - #expect(output.contains("No breaking changes detected in Baz")) - #expect(output.contains("No breaking changes detected in Qux")) + try await withKnownIssue { + try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in + let packageRoot = fixturePath.appending("Bar") + // Introduce an API-compatible change + try localFileSystem.writeFileContents( + packageRoot.appending(components: "Sources", "Baz", "Baz.swift"), + string: "public func bar() -> Int { 100 }" + ) + let (output, _) = try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem) + #expect(output.contains("No breaking changes detected in Baz")) + #expect(output.contains("No breaking changes detected in Qux")) + } + } when : { + buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2() } } - @Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms) + @Test( + .requiresAPIDigester, + .issue("https://github.com/swiftlang/swift-package-manager/issues/8926", relationship: .defect), + arguments: SupportedBuildSystemOnAllPlatforms, + ) func testAPIDiffAfterAddingNewTarget(buildSystem: BuildSystemProvider.Kind) async throws { - try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in - let packageRoot = fixturePath.appending("Bar") - try localFileSystem.createDirectory(packageRoot.appending(components: "Sources", "Foo")) - try localFileSystem.writeFileContents( - packageRoot.appending(components: "Sources", "Foo", "Foo.swift"), - string: #"public let foo = "All new module!""# - ) - try localFileSystem.writeFileContents(packageRoot.appending("Package.swift"), string: - """ - // swift-tools-version:4.2 - import PackageDescription - - let package = Package( - name: "Bar", - products: [ - .library(name: "Baz", targets: ["Baz"]), - .library(name: "Qux", targets: ["Qux", "Foo"]), - ], - targets: [ - .target(name: "Baz"), - .target(name: "Qux"), - .target(name: "Foo") - ] + try await withKnownIssue(isIntermittent: true) { + try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in + let packageRoot = fixturePath.appending("Bar") + try localFileSystem.createDirectory(packageRoot.appending(components: "Sources", "Foo")) + try localFileSystem.writeFileContents( + packageRoot.appending(components: "Sources", "Foo", "Foo.swift"), + string: #"public let foo = "All new module!""# ) - """ - ) - let (output, _) = try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem) - #expect(output.contains("No breaking changes detected in Baz")) - #expect(output.contains("No breaking changes detected in Qux")) - #expect(output.contains("Skipping Foo because it does not exist in the baseline")) + try localFileSystem.writeFileContents(packageRoot.appending("Package.swift"), string: + """ + // swift-tools-version:4.2 + import PackageDescription + + let package = Package( + name: "Bar", + products: [ + .library(name: "Baz", targets: ["Baz"]), + .library(name: "Qux", targets: ["Qux", "Foo"]), + ], + targets: [ + .target(name: "Baz"), + .target(name: "Qux"), + .target(name: "Foo") + ] + ) + """ + ) + let (output, _) = try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem) + #expect(output.contains("No breaking changes detected in Baz")) + #expect(output.contains("No breaking changes detected in Qux")) + #expect(output.contains("Skipping Foo because it does not exist in the baseline")) + } + } when: { + buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2() } } diff --git a/Tests/CommandsTests/TestCommandTests.swift b/Tests/CommandsTests/TestCommandTests.swift index 27d6afb28af..1b38cc7781c 100644 --- a/Tests/CommandsTests/TestCommandTests.swift +++ b/Tests/CommandsTests/TestCommandTests.swift @@ -180,7 +180,7 @@ struct TestCommandTests { buildSystem: buildSystem, ) } - guard case SwiftPMError.executionFailure(_, _, let stderr) = try #require(error) else { + guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else { Issue.record("Incorrect error was raised.") return } @@ -208,7 +208,7 @@ struct TestCommandTests { throwIfCommandFails: true, ) } - guard case SwiftPMError.executionFailure(_, _, let stderr) = try #require(error) else { + guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else { Issue.record("Incorrect error was raised.") return } @@ -262,7 +262,7 @@ struct TestCommandTests { buildSystem: buildSystem, ) } - guard case SwiftPMError.executionFailure(_, _, let stderr) = try #require(error) else { + guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else { Issue.record("Incorrect error was raised.") return }