diff --git a/Sources/App/Commands/Swift6Trigger.swift b/Sources/App/Commands/Swift6Trigger.swift index a0ae103b8..8ddfcadb4 100644 --- a/Sources/App/Commands/Swift6Trigger.swift +++ b/Sources/App/Commands/Swift6Trigger.swift @@ -181,7 +181,7 @@ extension Swift6TriggerCommand { if force { Current.logger().info("Skipping pending pipeline check") } else { - let pendingJobs = try await Current.getStatusCount(client, .pending).get() + let pendingJobs = try await Current.getStatusCount(client, .pending) guard pendingJobs + triggers.count < Current.gitlabPipelineLimit() else { Current.logger().info("too many pending pipelines (\(pendingJobs))") return diff --git a/Sources/App/Commands/TriggerBuilds.swift b/Sources/App/Commands/TriggerBuilds.swift index c84d75dce..75fb3a640 100644 --- a/Sources/App/Commands/TriggerBuilds.swift +++ b/Sources/App/Commands/TriggerBuilds.swift @@ -191,8 +191,8 @@ func triggerBuilds(on database: Database, } } - async let pendingJobsTask = Current.getStatusCount(client, .pending).get() - async let runningJobsTask = Current.getStatusCount(client, .running).get() + async let pendingJobsTask = Current.getStatusCount(client, .pending) + async let runningJobsTask = Current.getStatusCount(client, .running) let pendingJobs = try await pendingJobsTask let runningJobs = try await runningJobsTask @@ -270,7 +270,7 @@ func triggerBuildsUnchecked(on database: Database, isDocBuild: trigger.docPairs.contains(pair), platform: pair.platform, swiftVersion: pair.swiftVersion, - versionId: trigger.versionId).get() + versionId: trigger.versionId) guard [HTTPStatus.ok, .created].contains(response.status), let jobUrl = response.webUrl else { return } diff --git a/Sources/App/Core/AppEnvironment.swift b/Sources/App/Core/AppEnvironment.swift index 7a0a58c88..f92c0573a 100644 --- a/Sources/App/Core/AppEnvironment.swift +++ b/Sources/App/Core/AppEnvironment.swift @@ -51,8 +51,7 @@ struct AppEnvironment: Sendable { var fetchReadme: @Sendable (_ client: Client, _ owner: String, _ repository: String) async -> Github.Readme? var fetchS3Readme: @Sendable (_ client: Client, _ owner: String, _ repository: String) async throws -> String var fileManager: FileManager - var getStatusCount: @Sendable (_ client: Client, - _ status: Gitlab.Builder.Status) -> EventLoopFuture + var getStatusCount: @Sendable (_ client: Client, _ status: Gitlab.Builder.Status) async throws -> Int var git: Git var githubToken: @Sendable () -> String? var gitlabApiToken: @Sendable () -> String? @@ -87,7 +86,7 @@ struct AppEnvironment: Sendable { _ platform: Build.Platform, _ reference: Reference, _ swiftVersion: SwiftVersion, - _ versionID: Version.Id) -> EventLoopFuture + _ versionID: Version.Id) async throws -> Build.TriggerResponse } @@ -176,12 +175,11 @@ extension AppEnvironment { fetchS3Readme: { client, owner, repo in try await S3Store.fetchReadme(client:client, owner: owner, repository: repo) }, fileManager: .live, getStatusCount: { client, status in - Gitlab.Builder.getStatusCount( - client: client, - status: status, - page: 1, - pageSize: 100, - maxPageCount: 5) + try await Gitlab.Builder.getStatusCount(client: client, + status: status, + page: 1, + pageSize: 100, + maxPageCount: 5) }, git: .live, githubToken: { Environment.get("GITHUB_TOKEN") }, @@ -224,14 +222,14 @@ extension AppEnvironment { storeS3ReadmeImages: { client, images in try await S3Store.storeReadmeImages(client: client, imagesToCache: images) }, timeZone: { .current }, triggerBuild: { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } ) } diff --git a/Sources/App/Core/Gitlab.swift b/Sources/App/Core/Gitlab.swift index 7d0737277..a4a6ef4e8 100644 --- a/Sources/App/Core/Gitlab.swift +++ b/Sources/App/Core/Gitlab.swift @@ -75,17 +75,17 @@ extension Gitlab.Builder { platform: Build.Platform, reference: Reference, swiftVersion: SwiftVersion, - versionID: Version.Id) -> EventLoopFuture { + versionID: Version.Id) async throws -> Build.TriggerResponse { guard let pipelineToken = Current.gitlabPipelineToken(), let builderToken = Current.builderToken() - else { return client.eventLoop.future(error: Gitlab.Error.missingToken) } + else { throw Gitlab.Error.missingToken } guard let awsDocsBucket = Current.awsDocsBucket() else { - return client.eventLoop.future(error: Gitlab.Error.missingConfiguration("AWS_DOCS_BUCKET")) + throw Gitlab.Error.missingConfiguration("AWS_DOCS_BUCKET") } let timeout = Current.buildTimeout() + (isDocBuild ? 5 : 0) let uri: URI = .init(string: "\(projectURL)/trigger/pipeline") - let req = client + let response = try await client .post(uri) { req in let data = PostDTO( token: pipelineToken, @@ -104,19 +104,17 @@ extension Gitlab.Builder { ]) try req.query.encode(data) } - return req.map { response in - do { - let res = Build.TriggerResponse( - status: response.status, - webUrl: try response.content.decode(Response.self).webUrl - ) - Current.logger().info("Triggered build: \(res.webUrl)") - return res - } catch { - let body = response.body?.asString() ?? "nil" - Current.logger().error("Trigger failed: \(cloneURL) @ \(reference), \(platform) / \(swiftVersion), \(versionID), status: \(response.status), body: \(body)") - return .init(status: response.status, webUrl: nil) - } + do { + let res = Build.TriggerResponse( + status: response.status, + webUrl: try response.content.decode(Response.self).webUrl + ) + Current.logger().info("Triggered build: \(res.webUrl)") + return res + } catch { + let body = response.body?.asString() ?? "nil" + Current.logger().error("Trigger failed: \(cloneURL) @ \(reference), \(platform) / \(swiftVersion), \(versionID), status: \(response.status), body: \(body)") + return .init(status: response.status, webUrl: nil) } } @@ -155,45 +153,33 @@ extension Gitlab.Builder { static func fetchPipelines(client: Client, status: Status, page: Int, - pageSize: Int = 20) -> EventLoopFuture<[Pipeline]> { - guard let apiToken = Current.gitlabApiToken() - else { return client.eventLoop.future(error: Gitlab.Error.missingToken) } + pageSize: Int = 20) async throws -> [Pipeline] { + guard let apiToken = Current.gitlabApiToken() else { throw Gitlab.Error.missingToken } let uri: URI = .init(string: "\(projectURL)/pipelines?status=\(status)&page=\(page)&per_page=\(pageSize)") - return client - .get(uri, headers: HTTPHeaders([("Authorization", "Bearer \(apiToken)")])) - .flatMap { response -> EventLoopFuture<[Pipeline]> in - guard response.status == .ok else { - return client.eventLoop.future(error: Gitlab.Error.requestFailed(response.status, uri)) - } - do { - let res = try response.content.decode([Pipeline].self, using: Gitlab.decoder) - return client.eventLoop.future(res) - } catch { - return client.eventLoop.future(error: error) - } - } + let response = try await client.get(uri, headers: HTTPHeaders([("Authorization", "Bearer \(apiToken)")])) + + guard response.status == .ok else { throw Gitlab.Error.requestFailed(response.status, uri) } + + return try response.content.decode([Pipeline].self, using: Gitlab.decoder) } static func getStatusCount(client: Client, status: Status, page: Int = 1, pageSize: Int = 20, - maxPageCount: Int = 5) -> EventLoopFuture { - fetchPipelines(client: client, status: status, page: page, pageSize: pageSize) - .map(\.count) - .flatMap { count -> EventLoopFuture in - if count == pageSize && page < maxPageCount { - return getStatusCount(client: client, - status: status, - page: page + 1, - pageSize: pageSize, - maxPageCount: maxPageCount) - .map { count + $0 } - } else { - return client.eventLoop.future(count) - } - } + maxPageCount: Int = 5) async throws -> Int { + let count = try await fetchPipelines(client: client, status: status, page: page, pageSize: pageSize).count + if count == pageSize && page < maxPageCount { + let statusCount = try await getStatusCount(client: client, + status: status, + page: page + 1, + pageSize: pageSize, + maxPageCount: maxPageCount) + return count + statusCount + } else { + return count + } } } diff --git a/Sources/App/Models/Build.swift b/Sources/App/Models/Build.swift index 2bf9f87cf..afd62464b 100644 --- a/Sources/App/Models/Build.swift +++ b/Sources/App/Models/Build.swift @@ -179,23 +179,21 @@ extension Build { isDocBuild: Bool, platform: Build.Platform, swiftVersion: SwiftVersion, - versionId: Version.Id) -> EventLoopFuture { - let version: EventLoopFuture = Version + versionId: Version.Id) async throws -> TriggerResponse { + let version = try await Version .query(on: database) .filter(\.$id == versionId) .with(\.$package) .first() .unwrap(or: Abort(.notFound)) - return version.flatMap { - return Current.triggerBuild(client, - buildId, - $0.package.url, - isDocBuild, - platform, - $0.reference, - swiftVersion, - versionId) - } + return try await Current.triggerBuild(client, + buildId, + version.package.url, + isDocBuild, + platform, + version.reference, + swiftVersion, + versionId) } } diff --git a/Tests/AppTests/BuildTests.swift b/Tests/AppTests/BuildTests.swift index 5411f6389..0e325c6c4 100644 --- a/Tests/AppTests/BuildTests.swift +++ b/Tests/AppTests/BuildTests.swift @@ -22,11 +22,11 @@ import XCTVapor class BuildTests: AppTestCase { - func test_save() throws { + func test_save() async throws { // setup let pkg = try savePackage(on: app.db, "1") let v = try Version(package: pkg) - try v.save(on: app.db).wait() + try await v.save(on: app.db) let b = try Build(version: v, buildCommand: #"xcrun xcodebuild -scheme "Foo""#, jobUrl: "https://example.com/jobs/1", @@ -36,10 +36,10 @@ class BuildTests: AppTestCase { swiftVersion: .init(5, 2, 0)) // MUT - try b.save(on: app.db).wait() + try await b.save(on: app.db) do { // validate - let b = try XCTUnwrap(Build.find(b.id, on: app.db).wait()) + let b = try await XCTUnwrapAsync(try await Build.find(b.id, on: app.db)) XCTAssertEqual(b.buildCommand, #"xcrun xcodebuild -scheme "Foo""#) XCTAssertEqual(b.jobUrl, "https://example.com/jobs/1") XCTAssertEqual(b.logUrl, "https://example.com/logs/1") @@ -50,93 +50,105 @@ class BuildTests: AppTestCase { } } - func test_delete_cascade() throws { + func test_delete_cascade() async throws { // Ensure deleting a version also deletes the builds // setup let pkg = try savePackage(on: app.db, "1") let v = try Version(package: pkg) - try v.save(on: app.db).wait() + try await v.save(on: app.db) let b = try Build(version: v, platform: .iOS, status: .ok, swiftVersion: .init(5, 2, 0)) - try b.save(on: app.db).wait() - XCTAssertEqual(try Build.query(on: app.db).count().wait(), 1) + try await b.save(on: app.db) + do { + let count = try await Build.query(on: app.db).count() + XCTAssertEqual(count, 1) + } // MUT - try v.delete(on: app.db).wait() + try await v.delete(on: app.db) // validate - XCTAssertEqual(try Build.query(on: app.db).count().wait(), 0) + do { + let count = try await Build.query(on: app.db).count() + XCTAssertEqual(count, 0) + } } - func test_unique_constraint() throws { + func test_unique_constraint() async throws { // Ensure builds are unique over (id, platform, swiftVersion) // setup let pkg = try savePackage(on: app.db, "1") let v1 = try Version(package: pkg) - try v1.save(on: app.db).wait() + try await v1.save(on: app.db) let v2 = try Version(package: pkg) - try v2.save(on: app.db).wait() + try await v2.save(on: app.db) // MUT // initial save - ok - try Build(version: v1, - platform: .linux, - status: .ok, - swiftVersion: .init(5, 2, 0)).save(on: app.db).wait() + try await Build(version: v1, + platform: .linux, + status: .ok, + swiftVersion: .init(5, 2, 0)).save(on: app.db) // different version - ok - try Build(version: v2, - platform: .linux, - status: .ok, - swiftVersion: .init(5, 2, 0)).save(on: app.db).wait() + try await Build(version: v2, + platform: .linux, + status: .ok, + swiftVersion: .init(5, 2, 0)).save(on: app.db) // different platform - ok - try Build(version: v1, - platform: .macosXcodebuild, - status: .ok, - swiftVersion: .init(5, 2, 0)).save(on: app.db).wait() + try await Build(version: v1, + platform: .macosXcodebuild, + status: .ok, + swiftVersion: .init(5, 2, 0)).save(on: app.db) // different swiftVersion - ok - try Build(version: v1, - platform: .linux, - status: .ok, - swiftVersion: .init(4, 0, 0)).save(on: app.db).wait() + try await Build(version: v1, + platform: .linux, + status: .ok, + swiftVersion: .init(4, 0, 0)).save(on: app.db) // (v1, linx, 5.2.0) - not ok - XCTAssertThrowsError( - try Build(version: v1, - platform: .linux, - status: .ok, - swiftVersion: .init(5, 2, 0)).save(on: app.db).wait() - ) { - XCTAssertEqual(($0 as? PSQLError)?.isUniqueViolation, .some(true)) + do { + try await Build(version: v1, + platform: .linux, + status: .ok, + swiftVersion: .init(5, 2, 0)).save(on: app.db) + XCTFail("Expected unique constraint violation") + } catch let error as PSQLError { + XCTAssertEqual(error.isUniqueViolation, true) + } catch { + XCTFail("unexpected error: \(error)") } // validate - XCTAssertEqual(try Build.query(on: app.db).count().wait(), 4) + do { + let count = try await Build.query(on: app.db).count() + XCTAssertEqual(count, 4) + } } - func test_trigger() throws { + func test_trigger() async throws { Current.builderToken = { "builder token" } Current.gitlabPipelineToken = { "pipeline token" } Current.siteURL = { "http://example.com" } // setup let p = try savePackage(on: app.db, "1") let v = try Version(package: p, reference: .branch("main")) - try v.save(on: app.db).wait() + try await v.save(on: app.db) let buildId = UUID() let versionID = try XCTUnwrap(v.id) // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var called = false let client = MockClient { req, res in @@ -165,20 +177,20 @@ class BuildTests: AppTestCase { } // MUT - let res = try Build.trigger(database: app.db, - client: client, - buildId: buildId, - isDocBuild: false, - platform: .macosXcodebuild, - swiftVersion: .init(5, 2, 4), - versionId: versionID).wait() + let res = try await Build.trigger(database: app.db, + client: client, + buildId: buildId, + isDocBuild: false, + platform: .macosXcodebuild, + swiftVersion: .init(5, 2, 4), + versionId: versionID) // validate XCTAssertTrue(called) XCTAssertEqual(res.status, .created) } - func test_trigger_isDocBuild() throws { + func test_trigger_isDocBuild() async throws { // Same test as test_trigger above, except we trigger with isDocBuild: true // and expect a 15m TIMEOUT instead of 10m Current.builderToken = { "builder token" } @@ -187,21 +199,21 @@ class BuildTests: AppTestCase { // setup let p = try savePackage(on: app.db, "1") let v = try Version(package: p, reference: .branch("main")) - try v.save(on: app.db).wait() + try await v.save(on: app.db) let buildId = UUID() let versionID = try XCTUnwrap(v.id) // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var called = false let client = MockClient { req, res in @@ -217,13 +229,13 @@ class BuildTests: AppTestCase { } // MUT - let res = try Build.trigger(database: app.db, - client: client, - buildId: buildId, - isDocBuild: true, - platform: .macosXcodebuild, - swiftVersion: .init(5, 2, 4), - versionId: versionID).wait() + let res = try await Build.trigger(database: app.db, + client: client, + buildId: buildId, + isDocBuild: true, + platform: .macosXcodebuild, + swiftVersion: .init(5, 2, 4), + versionId: versionID) // validate XCTAssertTrue(called) @@ -293,120 +305,119 @@ class BuildTests: AppTestCase { } - func test_delete_by_versionId() throws { + func test_delete_by_versionId() async throws { // setup let pkg = try savePackage(on: app.db, "1") let vid1 = UUID() let v1 = try Version(id: vid1, package: pkg) - try v1.save(on: app.db).wait() + try await v1.save(on: app.db) let vid2 = UUID() let v2 = try Version(id: vid2, package: pkg) - try v2.save(on: app.db).wait() - try Build(version: v1, platform: .iOS, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() - try Build(version: v2, platform: .iOS, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() + try await v2.save(on: app.db) + try await Build(version: v1, platform: .iOS, status: .ok, swiftVersion: .v2) + .save(on: app.db) + try await Build(version: v2, platform: .iOS, status: .ok, swiftVersion: .v2) + .save(on: app.db) // MUT - let count = try Build.delete(on: app.db, versionId: vid2).wait() + let count = try await Build.delete(on: app.db, versionId: vid2).get() // validate XCTAssertEqual(count, 1) - let builds = try Build.query(on: app.db).all().wait() + let builds = try await Build.query(on: app.db).all() XCTAssertEqual(builds.map(\.$version.id), [vid1]) } - func test_delete_by_packageId() throws { + func test_delete_by_packageId() async throws { // setup let pkgId1 = UUID() let pkg1 = Package(id: pkgId1, url: "1") - try pkg1.save(on: app.db).wait() + try await pkg1.save(on: app.db) let pkgId2 = UUID() let pkg2 = Package(id: pkgId2, url: "2") - try pkg2.save(on: app.db).wait() + try await pkg2.save(on: app.db) let v1 = try Version(package: pkg1) - try v1.save(on: app.db).wait() + try await v1.save(on: app.db) let v2 = try Version(package: pkg2) - try v2.save(on: app.db).wait() + try await v2.save(on: app.db) // save different platforms as an easy way to check the correct one has been deleted - try Build(version: v1, platform: .iOS, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() - try Build(version: v2, platform: .linux, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() + try await Build(version: v1, platform: .iOS, status: .ok, swiftVersion: .v2) + .save(on: app.db) + try await Build(version: v2, platform: .linux, status: .ok, swiftVersion: .v2) + .save(on: app.db) // MUT - let count = try Build.delete(on: app.db, packageId: pkgId2).wait() + let count = try await Build.delete(on: app.db, packageId: pkgId2).get() // validate XCTAssertEqual(count, 1) - let builds = try Build.query(on: app.db).all().wait() + let builds = try await Build.query(on: app.db).all() XCTAssertEqual(builds.map(\.platform), [.iOS]) } - func test_delete_by_packageId_versionKind() throws { + func test_delete_by_packageId_versionKind() async throws { // setup let pkgId1 = UUID() let pkg1 = Package(id: pkgId1, url: "1") - try pkg1.save(on: app.db).wait() + try await pkg1.save(on: app.db) let pkgId2 = UUID() let pkg2 = Package(id: pkgId2, url: "2") - try pkg2.save(on: app.db).wait() + try await pkg2.save(on: app.db) let v1 = try Version(package: pkg1) - try v1.save(on: app.db).wait() + try await v1.save(on: app.db) let v2 = try Version(package: pkg2, latest: .defaultBranch) - try v2.save(on: app.db).wait() + try await v2.save(on: app.db) let v3 = try Version(package: pkg2, latest: .release) - try v3.save(on: app.db).wait() + try await v3.save(on: app.db) // save different platforms as an easy way to check the correct one has been deleted - try Build(version: v1, platform: .iOS, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() - try Build(version: v2, platform: .linux, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() - try Build(version: v3, platform: .tvOS, status: .ok, swiftVersion: .v2) - .save(on: app.db).wait() + try await Build(version: v1, platform: .iOS, status: .ok, swiftVersion: .v2) + .save(on: app.db) + try await Build(version: v2, platform: .linux, status: .ok, swiftVersion: .v2) + .save(on: app.db) + try await Build(version: v3, platform: .tvOS, status: .ok, swiftVersion: .v2) + .save(on: app.db) // MUT - let count = try Build.delete(on: app.db, packageId: pkgId2, versionKind: .defaultBranch).wait() + let count = try await Build.delete(on: app.db, packageId: pkgId2, versionKind: .defaultBranch).get() // validate XCTAssertEqual(count, 1) - let builds = try Build.query(on: app.db).all().wait() + let builds = try await Build.query(on: app.db).all() XCTAssertEqual(builds.map(\.platform), [.iOS, .tvOS]) } - func test_pending_to_triggered_migration() throws { + func test_pending_to_triggered_migration() async throws { // setup let p = Package(url: "1") - try p.save(on: app.db).wait() + try await p.save(on: app.db) let v = try Version(package: p, latest: .defaultBranch) - try v.save(on: app.db).wait() + try await v.save(on: app.db) // save a Build with status 'triggered' - try Build(id: .id0, version: v, platform: .iOS, status: .triggered, swiftVersion: .v1).save(on: app.db).wait() + try await Build(id: .id0, version: v, platform: .iOS, status: .triggered, swiftVersion: .v1).save(on: app.db) // MUT - test roll back to previous schema, migrating 'triggered' -> 'pending' - try UpdateBuildPendingToTriggered().revert(on: app.db).wait() + try await UpdateBuildPendingToTriggered().revert(on: app.db) do { // validate struct Row: Codable, Equatable { var status: String } - let result = try (app.db as! SQLDatabase) + let result = try await (app.db as! SQLDatabase) .raw("SELECT status FROM builds") .all(decoding: Row.self) - .wait() XCTAssertEqual(result, [.init(status: "pending")]) } // MUT - test migrating 'pending' -> 'triggered' - try UpdateBuildPendingToTriggered().prepare(on: app.db).wait() + try await UpdateBuildPendingToTriggered().prepare(on: app.db) // validate - let b = try XCTUnwrap(Build.find(.id0, on: app.db).wait()) + let b = try await XCTUnwrapAsync(try await Build.find(.id0, on: app.db)) XCTAssertEqual(b.status, .triggered) } diff --git a/Tests/AppTests/BuildTriggerTests.swift b/Tests/AppTests/BuildTriggerTests.swift index 45c2f57d9..2ba91f386 100644 --- a/Tests/AppTests/BuildTriggerTests.swift +++ b/Tests/AppTests/BuildTriggerTests.swift @@ -335,14 +335,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } let queries = QueueIsolated<[Gitlab.Builder.PostDTO]>([]) let client = MockClient { req, res in @@ -393,14 +393,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } let queries = QueueIsolated<[Gitlab.Builder.PostDTO]>([]) let client = MockClient { req, res in @@ -478,14 +478,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } let queries = QueueIsolated<[Gitlab.Builder.PostDTO]>([]) let client = MockClient { req, res in @@ -544,14 +544,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var triggerCount = 0 let client = MockClient { _, res in @@ -562,7 +562,7 @@ class BuildTriggerTests: AppTestCase { } do { // fist run: we are at capacity and should not be triggering more builds - Current.getStatusCount = { c, _ in c.eventLoop.makeSucceededFuture(300) } + Current.getStatusCount = { _, _ in 300 } let pkgId = UUID() let versionId = UUID() @@ -587,7 +587,7 @@ class BuildTriggerTests: AppTestCase { triggerCount = 0 do { // second run: we are just below capacity and allow more builds to be triggered - Current.getStatusCount = { c, _ in c.eventLoop.makeSucceededFuture(299) } + Current.getStatusCount = { c, _ in 299 } let pkgId = UUID() let versionId = UUID() @@ -610,7 +610,7 @@ class BuildTriggerTests: AppTestCase { } do { // third run: we are at capacity and using the `force` flag - Current.getStatusCount = { c, _ in c.eventLoop.makeSucceededFuture(300) } + Current.getStatusCount = { c, _ in 300 } var triggerCount = 0 let client = MockClient { _, res in @@ -652,14 +652,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } let triggerCount = NIOLockedValueBox(0) let client = MockClient { _, res in @@ -668,7 +668,7 @@ class BuildTriggerTests: AppTestCase { Gitlab.Builder.Response.init(webUrl: "http://web_url") ) } - Current.getStatusCount = { c, _ in c.eventLoop.makeSucceededFuture(299 + triggerCount.withLockedValue { $0 }) } + Current.getStatusCount = { c, _ in 299 + triggerCount.withLockedValue { $0 } } let pkgIds = [UUID(), UUID()] try pkgIds.forEach { id in @@ -727,14 +727,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var triggerCount = 0 let client = MockClient { _, res in @@ -818,14 +818,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var triggerCount = 0 let client = MockClient { _, res in @@ -887,14 +887,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var triggerCount = 0 let client = MockClient { _, res in @@ -958,14 +958,14 @@ class BuildTriggerTests: AppTestCase { // Use live dependency but replace actual client with a mock so we can // assert on the details being sent without actually making a request Current.triggerBuild = { client, buildId, cloneURL, isDocBuild, platform, ref, swiftVersion, versionID in - Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: cloneURL, - isDocBuild: isDocBuild, - platform: platform, - reference: ref, - swiftVersion: swiftVersion, - versionID: versionID) + try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: cloneURL, + isDocBuild: isDocBuild, + platform: platform, + reference: ref, + swiftVersion: swiftVersion, + versionID: versionID) } var triggerCount = 0 let client = MockClient { _, res in diff --git a/Tests/AppTests/GitlabBuilderTests.swift b/Tests/AppTests/GitlabBuilderTests.swift index ed36936dd..8136ed603 100644 --- a/Tests/AppTests/GitlabBuilderTests.swift +++ b/Tests/AppTests/GitlabBuilderTests.swift @@ -51,7 +51,7 @@ class GitlabBuilderTests: AppTestCase { } } - func test_triggerBuild() throws { + func test_triggerBuild() async throws { Current.awsDocsBucket = { "docs-bucket" } Current.builderToken = { "builder token" } Current.gitlabPipelineToken = { "pipeline token" } @@ -85,18 +85,18 @@ class GitlabBuilderTests: AppTestCase { } // MUT - _ = try Gitlab.Builder.triggerBuild(client: client, - buildId: buildId, - cloneURL: "https://github.com/daveverwer/LeftPad.git", - isDocBuild: false, - platform: .macosSpm, - reference: .tag(.init(1, 2, 3)), - swiftVersion: .init(5, 2, 4), - versionID: versionID).wait() + _ = try await Gitlab.Builder.triggerBuild(client: client, + buildId: buildId, + cloneURL: "https://github.com/daveverwer/LeftPad.git", + isDocBuild: false, + platform: .macosSpm, + reference: .tag(.init(1, 2, 3)), + swiftVersion: .init(5, 2, 4), + versionID: versionID) XCTAssertTrue(called) } - func test_issue_588() throws { + func test_issue_588() async throws { Current.awsDocsBucket = { "docs-bucket" } Current.builderToken = { "builder token" } Current.gitlabPipelineToken = { "pipeline token" } @@ -115,18 +115,18 @@ class GitlabBuilderTests: AppTestCase { } // MUT - _ = try Gitlab.Builder.triggerBuild(client: client, - buildId: .id0, - cloneURL: "https://github.com/daveverwer/LeftPad.git", - isDocBuild: false, - platform: .macosSpm, - reference: .tag(.init(1, 2, 3)), - swiftVersion: .v6_0, - versionID: .id1).wait() + _ = try await Gitlab.Builder.triggerBuild(client: client, + buildId: .id0, + cloneURL: "https://github.com/daveverwer/LeftPad.git", + isDocBuild: false, + platform: .macosSpm, + reference: .tag(.init(1, 2, 3)), + swiftVersion: .v6_0, + versionID: .id1) XCTAssertTrue(called) } - func test_getStatusCount() throws { + func test_getStatusCount() async throws { Current.gitlabApiToken = { "api token" } Current.gitlabPipelineToken = { nil } @@ -148,10 +148,10 @@ class GitlabBuilderTests: AppTestCase { page += 1 } - let res = try Gitlab.Builder.getStatusCount(client: client, - status: .pending, - pageSize: 20, - maxPageCount: 3).wait() + let res = try await Gitlab.Builder.getStatusCount(client: client, + status: .pending, + pageSize: 20, + maxPageCount: 3) XCTAssertEqual(res, 30) } @@ -196,7 +196,7 @@ class LiveGitlabBuilderTests: AppTestCase { platform: .macosSpm, reference: .tag(.init(0, 3, 2)), swiftVersion: .v4, - versionID: versionID).get() + versionID: versionID) print("status: \(res.status)") print("buildId: \(buildId)") diff --git a/Tests/AppTests/Mocks/AppEnvironment+mock.swift b/Tests/AppTests/Mocks/AppEnvironment+mock.swift index cf83319e8..6e26ff811 100644 --- a/Tests/AppTests/Mocks/AppEnvironment+mock.swift +++ b/Tests/AppTests/Mocks/AppEnvironment+mock.swift @@ -55,7 +55,7 @@ extension AppEnvironment { fetchReadme: { _, _, _ in .init(html: "readme html", htmlUrl: "readme html url", imagesToCache: []) }, fetchS3Readme: { _, _, _ in "" }, fileManager: .mock, - getStatusCount: { _, _ in eventLoop.future(100) }, + getStatusCount: { _, _ in 100 }, git: .mock, githubToken: { nil }, gitlabApiToken: { nil }, @@ -80,9 +80,7 @@ extension AppEnvironment { storeS3Readme: { _, _, _ in "s3ObjectUrl" }, storeS3ReadmeImages: { _, _ in }, timeZone: { .utc }, - triggerBuild: { _, _, _, _, _, _, _, _ in - eventLoop.future(.init(status: .ok, webUrl: "http://web_url")) - } + triggerBuild: { _, _, _, _, _, _, _, _ in .init(status: .ok, webUrl: "http://web_url") } ) } }