-
Notifications
You must be signed in to change notification settings - Fork 55
Mock out test interactions with swift.org and github.com #133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 25 commits
a62bc2e
9028007
b4a558e
312e5b6
a9a0fe5
fbb11f8
9a3726f
cc5dbdf
d3932ba
531669b
fb04cb8
e05cbf2
9845e97
13204eb
89d2c9f
07e3e90
43f31de
5ad3682
cec440f
1c8f84b
ca8fd34
4432c6a
6e52597
eb9c300
978e710
aecbabb
34f2bf2
34d9675
f4474c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -62,6 +62,23 @@ class SwiftlyTests: XCTestCase { | |||||
} | ||||||
} | ||||||
|
||||||
override class func tearDown() { | ||||||
#if os(Linux) | ||||||
let deleteTestGPGKeys = Process() | ||||||
deleteTestGPGKeys.executableURL = URL(fileURLWithPath: "/usr/bin/env") | ||||||
deleteTestGPGKeys.arguments = [ | ||||||
"bash", | ||||||
"-c", | ||||||
""" | ||||||
gpg --batch --yes --delete-secret-keys --fingerprint "A2A645E5249D25845C43954E7D210032D2F670B7" >/dev/null 2>&1 | ||||||
gpg --batch --yes --delete-keys --fingerprint "A2A645E5249D25845C43954E7D210032D2F670B7" >/dev/null 2>&1 | ||||||
""", | ||||||
] | ||||||
try? deleteTestGPGKeys.run() | ||||||
deleteTestGPGKeys.waitUntilExit() | ||||||
#endif | ||||||
} | ||||||
|
||||||
// Below are some constants that can be used to write test cases. | ||||||
static let oldStable = ToolchainVersion(major: 5, minor: 6, patch: 0) | ||||||
static let oldStableNewPatch = ToolchainVersion(major: 5, minor: 6, patch: 3) | ||||||
|
@@ -451,30 +468,139 @@ private struct MockHTTPRequestExecutor: HTTPRequestExecutor { | |||||
|
||||||
/// An `HTTPRequestExecutor` which will return a mocked response to any toolchain download requests. | ||||||
/// All other requests are performed using an actual HTTP client. | ||||||
public struct MockToolchainDownloader: HTTPRequestExecutor { | ||||||
public class MockToolchainDownloader: HTTPRequestExecutor { | ||||||
private static let releaseURLRegex: Regex<(Substring, Substring, Substring, Substring?)> = | ||||||
try! Regex("swift-(\\d+)\\.(\\d+)(?:\\.(\\d+))?-RELEASE") | ||||||
private static let snapshotURLRegex: Regex<Substring> = | ||||||
try! Regex("swift(?:-[0-9]+\\.[0-9]+)?-DEVELOPMENT-SNAPSHOT-[0-9]{4}-[0-9]{2}-[0-9]{2}") | ||||||
|
||||||
private let executables: [String] | ||||||
#if os(Linux) | ||||||
private var signatures: [String: URL] | ||||||
#endif | ||||||
public let httpRequestExecutor: HTTPRequestExecutor | ||||||
|
||||||
public init(executables: [String]? = nil, prevExecutor: HTTPRequestExecutor) { | ||||||
self.executables = executables ?? ["swift"] | ||||||
self.httpRequestExecutor = prevExecutor | ||||||
#if os(Linux) | ||||||
self.signatures = [:] | ||||||
#endif | ||||||
} | ||||||
|
||||||
public func execute(_ request: HTTPClientRequest, timeout: TimeAmount) async throws -> HTTPClientResponse { | ||||||
public func execute(_ request: HTTPClientRequest, timeout _: TimeAmount) async throws -> HTTPClientResponse { | ||||||
guard let url = URL(string: request.url) else { | ||||||
throw SwiftlyTestError(message: "invalid request URL: \(request.url)") | ||||||
} | ||||||
|
||||||
if url.host == "download.swift.org" { | ||||||
return try self.makeToolchainDownloadResponse(from: url) | ||||||
} else if url.host == "api.github.com" { | ||||||
if url.path == "/repos/apple/swift/releases" { | ||||||
return try self.makeGitHubReleasesAPIResponse(from: url) | ||||||
} else if url.path == "/repos/apple/swift/tags" { | ||||||
return try self.makeGitHubTagsAPIResponse(from: url) | ||||||
} else { | ||||||
throw SwiftlyTestError(message: "unxpected github API request URL: \(request.url)") | ||||||
} | ||||||
} else { | ||||||
return try await self.httpRequestExecutor.execute(request, timeout: timeout) | ||||||
throw SwiftlyTestError(message: "unmocked URL: \(request.url)") | ||||||
} | ||||||
} | ||||||
|
||||||
private func makeGitHubReleasesAPIResponse(from url: URL) throws -> HTTPClientResponse { | ||||||
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { | ||||||
throw SwiftlyTestError(message: "unexpected github url: \(url)") | ||||||
} | ||||||
|
||||||
guard let queryItems = components.queryItems else { | ||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(PackageResources.swift_releases_page1_json)))) | ||||||
} | ||||||
|
||||||
guard let page = queryItems.first(where: { $0.name == "page" }) else { | ||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(PackageResources.swift_releases_page1_json)))) | ||||||
} | ||||||
|
||||||
if page.value != "1" { | ||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(Array("[]".utf8))))) | ||||||
} | ||||||
|
||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(PackageResources.swift_releases_page1_json)))) | ||||||
} | ||||||
|
||||||
private func makeGitHubTagsAPIResponse(from url: URL) throws -> HTTPClientResponse { | ||||||
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { | ||||||
throw SwiftlyTestError(message: "unexpected github url: \(url)") | ||||||
} | ||||||
|
||||||
guard let queryItems = components.queryItems else { | ||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(PackageResources.swift_tags_page1_json)))) | ||||||
} | ||||||
|
||||||
guard let page = queryItems.first(where: { $0.name == "page" }) else { | ||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(PackageResources.swift_tags_page1_json)))) | ||||||
} | ||||||
|
||||||
let payload = switch page.value { | ||||||
case "1": | ||||||
PackageResources.swift_tags_page1_json | ||||||
case "2": | ||||||
PackageResources.swift_tags_page2_json | ||||||
case "3": | ||||||
PackageResources.swift_tags_page3_json | ||||||
case "4": | ||||||
PackageResources.swift_tags_page4_json | ||||||
case "5": | ||||||
PackageResources.swift_tags_page5_json | ||||||
case "6": | ||||||
PackageResources.swift_tags_page6_json | ||||||
case "7": | ||||||
PackageResources.swift_tags_page7_json | ||||||
case "8": | ||||||
PackageResources.swift_tags_page8_json | ||||||
case "9": | ||||||
PackageResources.swift_tags_page9_json | ||||||
case "10": | ||||||
PackageResources.swift_tags_page10_json | ||||||
case "11": | ||||||
PackageResources.swift_tags_page11_json | ||||||
case "12": | ||||||
PackageResources.swift_tags_page12_json | ||||||
case "13": | ||||||
PackageResources.swift_tags_page13_json | ||||||
case "14": | ||||||
PackageResources.swift_tags_page14_json | ||||||
case "15": | ||||||
PackageResources.swift_tags_page15_json | ||||||
case "16": | ||||||
PackageResources.swift_tags_page16_json | ||||||
case "17": | ||||||
PackageResources.swift_tags_page17_json | ||||||
case "18": | ||||||
PackageResources.swift_tags_page18_json | ||||||
case "19": | ||||||
PackageResources.swift_tags_page19_json | ||||||
case "20": | ||||||
PackageResources.swift_tags_page20_json | ||||||
case "21": | ||||||
PackageResources.swift_tags_page21_json | ||||||
case "22": | ||||||
PackageResources.swift_tags_page22_json | ||||||
case "23": | ||||||
PackageResources.swift_tags_page23_json | ||||||
case "24": | ||||||
PackageResources.swift_tags_page24_json | ||||||
case "25": | ||||||
PackageResources.swift_tags_page25_json | ||||||
case "26": | ||||||
PackageResources.swift_tags_page26_json | ||||||
case "27": | ||||||
PackageResources.swift_tags_page27_json | ||||||
default: | ||||||
Array("[]".utf8) | ||||||
} | ||||||
|
||||||
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(payload)))) | ||||||
|
return HTTPClientResponse(body: .bytes(ByteBuffer(data: Data(payload)))) | |
return HTTPClientResponse(body: .bytes(ByteBuffer(bytes: payload))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've fixed this in the latest commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know about
embedInCode
. Nice!