Skip to content

Commit d1ab457

Browse files
authored
Tests: APIDiff Tests - mark known issues on AL2 (#8927)
Change #8857 added SwiftBUild support for diagnose-api-breaking-changs. However, it appears that some test expectation are failing on Amazon Linux 2. Mark these a known issues until they can be fixed.
1 parent 87e77b8 commit d1ab457

File tree

5 files changed

+206
-13
lines changed

5 files changed

+206
-13
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2025 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
package struct CombinationsWithRepetition<C: Collection> : Sequence {
13+
14+
let base: C
15+
let length: Int
16+
17+
init(of base: C, length: Int) {
18+
self.base = base
19+
self.length = length
20+
}
21+
22+
package struct Iterator : IteratorProtocol {
23+
let base: C
24+
25+
var firstIteration = true
26+
var finished: Bool
27+
var positions: [C.Index]
28+
29+
package init(of base: C, length: Int) {
30+
self.base = base
31+
finished = base.isEmpty
32+
positions = Array(repeating: base.startIndex, count: length)
33+
}
34+
35+
package mutating func next() -> [C.Element]? {
36+
if firstIteration {
37+
firstIteration = false
38+
} else {
39+
// Update indices for next combination.
40+
finished = true
41+
for i in positions.indices.reversed() {
42+
base.formIndex(after: &positions[i])
43+
if positions[i] != base.endIndex {
44+
finished = false
45+
break
46+
} else {
47+
positions[i] = base.startIndex
48+
}
49+
}
50+
51+
}
52+
return finished ? nil : positions.map { base[$0] }
53+
}
54+
}
55+
56+
package func makeIterator() -> Iterator {
57+
return Iterator(of: base, length: length)
58+
}
59+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2025 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
import Foundation
11+
12+
extension ProcessInfo {
13+
public static func isHostAmazonLinux2(_ content: String? = nil) -> Bool {
14+
let contentString: String
15+
if let content {
16+
contentString = content
17+
} else {
18+
let osReleasePath = "/etc/os-release"
19+
do {
20+
contentString = try String(contentsOfFile: osReleasePath, encoding: .utf8)
21+
} catch {
22+
return false
23+
}
24+
}
25+
let lines = contentString.components(separatedBy: .newlines)
26+
for line in lines {
27+
if line.starts(with: "ID=") {
28+
let id = line.replacingOccurrences(of: "ID=", with: "").trimmingCharacters(in: .whitespacesAndNewlines)
29+
if id == "amzn" { // ID for Amazon Linux is "amzn"
30+
return true
31+
}
32+
}
33+
}
34+
return false
35+
}
36+
37+
}

Tests/BasicsTests/Environment/EnvironmentTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ struct EnvironmentTests {
148148
/// Important: This test is inherently race-prone, if it is proven to be
149149
/// flaky, it should run in a singled threaded environment/removed entirely.
150150
@Test(
151-
.disabled(if: isInCiEnvironment || CiEnvironment.runningInSelfHostedPipeline, "This test can disrupt other tests running in parallel."),
151+
.disabled(if: CiEnvironment.runningInSmokeTestPipeline || CiEnvironment.runningInSelfHostedPipeline, "This test can disrupt other tests running in parallel."),
152152
)
153153
func makeCustomPathEnv() async throws {
154154
let customEnvironment: Environment = .current
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
import Foundation
13+
import Basics
14+
import Testing
15+
@testable import struct _InternalTestSupport.CombinationsWithRepetition
16+
17+
fileprivate let d = [
18+
[],
19+
[""],
20+
["line1"],
21+
["line1", "line2"],
22+
["line1", "line2", "line3"],
23+
]
24+
fileprivate let prefixAndSuffixData = CombinationsWithRepetition(of: d, length: 2).map( {data in
25+
// Content(prefix: data.0, suffix: data.1)
26+
Content(prefix: data[0], suffix: data[1])
27+
})
28+
29+
fileprivate struct Content {
30+
let prefix: [String]
31+
let suffix: [String]
32+
33+
init(prefix pre: [String], suffix: [String]) {
34+
self.prefix = pre
35+
self.suffix = suffix
36+
}
37+
38+
func getContent(_ value: String) -> String {
39+
let contentArray: [String] = self.prefix + [value] + self.suffix
40+
let content = contentArray.joined(separator: "\n")
41+
return content
42+
}
43+
}
44+
45+
@Suite
46+
struct ProcessInfoExtensionTests {
47+
48+
@Suite
49+
struct isAmazonLinux2 {
50+
@Test(
51+
arguments: [
52+
(contentUT: "", expected: false),
53+
(contentUT: "ID=", expected: false),
54+
(contentUT: "ID=foo", expected: false),
55+
(contentUT: "ID=amzn", expected: true),
56+
(contentUT: " ID=amzn", expected: false),
57+
], prefixAndSuffixData,
58+
)
59+
fileprivate func isAmazonLinux2ReturnsExpectedValue(
60+
data: (contentUT: String, expected: Bool),
61+
content: Content,
62+
) async throws {
63+
let content = content.getContent(data.contentUT)
64+
65+
let actual = ProcessInfo.isHostAmazonLinux2(content)
66+
67+
#expect(actual == data.expected, "Content is: '\(content)'")
68+
}
69+
70+
@Test(
71+
"isHostAmazonLinux2 returns false when not executed on Linux",
72+
.skipHostOS(.linux),
73+
.tags(Tag.TestSize.medium),
74+
)
75+
func isAmazonLinux2ReturnsFalseWhenNotRunOnLinux() {
76+
let actual = ProcessInfo.isHostAmazonLinux2()
77+
78+
#expect(actual == false)
79+
}
80+
}
81+
}

Tests/CommandsTests/APIDiffTests.swift

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ struct APIDiffTests {
103103
}
104104
}
105105

106-
@Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms)
106+
@Test(
107+
.requiresAPIDigester,
108+
.issue("https://github.com/swiftlang/swift-package-manager/issues/8926", relationship: .defect),
109+
arguments: SupportedBuildSystemOnAllPlatforms,
110+
)
107111
func testMultiTargetAPIDiff(buildSystem: BuildSystemProvider.Kind) async throws {
108112
try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in
109113
let packageRoot = fixturePath.appending("Bar")
@@ -116,11 +120,15 @@ struct APIDiffTests {
116120
string: "public class Qux<T, U> { private let x = 1 }"
117121
)
118122
try await expectThrowsCommandExecutionError(try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem)) { error in
119-
#expect(error.stdout.contains("2 breaking changes detected in Qux"))
120-
#expect(error.stdout.contains("💔 API breakage: class Qux has generic signature change from <T> to <T, U>"))
121-
#expect(error.stdout.contains("💔 API breakage: var Qux.x has been removed"))
122-
#expect(error.stdout.contains("1 breaking change detected in Baz"))
123-
#expect(error.stdout.contains("💔 API breakage: func bar() has been removed"))
123+
withKnownIssue {
124+
#expect(error.stdout.contains("2 breaking changes detected in Qux"))
125+
#expect(error.stdout.contains("💔 API breakage: class Qux has generic signature change from <T> to <T, U>"))
126+
#expect(error.stdout.contains("💔 API breakage: var Qux.x has been removed"))
127+
#expect(error.stdout.contains("1 breaking change detected in Baz"))
128+
#expect(error.stdout.contains("💔 API breakage: func bar() has been removed"))
129+
} when: {
130+
buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2()
131+
}
124132
}
125133
}
126134
}
@@ -156,7 +164,11 @@ struct APIDiffTests {
156164
}
157165
}
158166

159-
@Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms)
167+
@Test(
168+
.requiresAPIDigester,
169+
.issue("https://github.com/swiftlang/swift-package-manager/issues/8926", relationship: .defect),
170+
arguments: SupportedBuildSystemOnAllPlatforms,
171+
)
160172
func testCheckVendedModulesOnly(buildSystem: BuildSystemProvider.Kind) async throws {
161173
try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in
162174
let packageRoot = fixturePath.appending("NonAPILibraryTargets")
@@ -177,11 +189,15 @@ struct APIDiffTests {
177189
string: "public class Qux<T, U> { private let x = 1 }"
178190
)
179191
try await expectThrowsCommandExecutionError(try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem)) { error in
180-
#expect(error.stdout.contains("💔 API breakage"))
181-
let regex = try Regex("\\d+ breaking change(s?) detected in Foo")
182-
#expect(error.stdout.contains(regex))
183-
#expect(error.stdout.contains(regex))
184-
#expect(error.stdout.contains(regex))
192+
try withKnownIssue {
193+
#expect(error.stdout.contains("💔 API breakage"))
194+
let regex = try Regex("\\d+ breaking change(s?) detected in Foo")
195+
#expect(error.stdout.contains(regex))
196+
#expect(error.stdout.contains(regex))
197+
#expect(error.stdout.contains(regex))
198+
} when: {
199+
buildSystem == .swiftbuild && ProcessInfo.isHostAmazonLinux2()
200+
}
185201

186202
// Qux is not part of a library product, so any API changes should be ignored
187203
#expect(!error.stdout.contains("Qux"))

0 commit comments

Comments
 (0)