Skip to content

Use structured concurrency in PackageLoadingTests #7359

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

Merged
merged 2 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,6 @@ let package = Package(
dependencies: ["PackageLoading", "SPMTestSupport"],
exclude: ["Inputs", "pkgconfigInputs"]
),
.testTarget(
name: "PackageLoadingPerformanceTests",
dependencies: ["PackageLoading", "SPMTestSupport"]
),
.testTarget(
name: "PackageModelTests",
dependencies: ["PackageModel", "SPMTestSupport"]
Expand Down
33 changes: 33 additions & 0 deletions Sources/PackageLoading/ManifestLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,39 @@ extension ManifestLoaderProtocol {
completion(.failure(error))
}
}
}

public func load(
packagePath: AbsolutePath,
packageIdentity: PackageIdentity,
packageKind: PackageReference.Kind,
packageLocation: String,
packageVersion: (version: Version?, revision: String?)?,
currentToolsVersion: ToolsVersion,
identityResolver: IdentityResolver,
dependencyMapper: DependencyMapper,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope,
delegateQueue: DispatchQueue,
callbackQueue: DispatchQueue
) async throws -> Manifest {
try await withCheckedThrowingContinuation {
self.load(
packagePath: packagePath,
packageIdentity: packageIdentity,
packageKind: packageKind,
packageLocation: packageLocation,
packageVersion: packageVersion,
currentToolsVersion: currentToolsVersion,
identityResolver: identityResolver,
dependencyMapper: dependencyMapper,
fileSystem: fileSystem,
observabilityScope: observabilityScope,
delegateQueue: delegateQueue,
callbackQueue: callbackQueue,
completion: $0.resume(with:)
)
}
}
}

Expand Down
91 changes: 55 additions & 36 deletions Sources/SPMTestSupport/MockManifestLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import PackageGraph

import func XCTest.XCTFail

import enum TSCBasic.ProcessEnv
import struct TSCUtility.Version

public enum MockManifestLoaderError: Swift.Error {
Expand Down Expand Up @@ -88,7 +89,7 @@ extension ManifestLoader {
dependencyMapper: DependencyMapper? = .none,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope
) throws -> Manifest{
) async throws -> Manifest{
let packageIdentity: PackageIdentity
let packageLocation: String
switch packageKind {
Expand All @@ -109,27 +110,23 @@ extension ManifestLoader {
// FIXME: placeholder
packageLocation = identity.description
}
return try temp_await {
self.load(
manifestPath: manifestPath,
manifestToolsVersion: manifestToolsVersion,
packageIdentity: packageIdentity,
packageKind: packageKind,
packageLocation: packageLocation,
packageVersion: nil,
identityResolver: identityResolver,
dependencyMapper: dependencyMapper ?? DefaultDependencyMapper(identityResolver: identityResolver),
fileSystem: fileSystem,
observabilityScope: observabilityScope,
delegateQueue: .sharedConcurrent,
callbackQueue: .sharedConcurrent,
completion: $0
)
}
return try await self.load(
manifestPath: manifestPath,
manifestToolsVersion: manifestToolsVersion,
packageIdentity: packageIdentity,
packageKind: packageKind,
packageLocation: packageLocation,
packageVersion: nil,
identityResolver: identityResolver,
dependencyMapper: dependencyMapper ?? DefaultDependencyMapper(identityResolver: identityResolver),
fileSystem: fileSystem,
observabilityScope: observabilityScope,
delegateQueue: .sharedConcurrent,
callbackQueue: .sharedConcurrent
)
}
}


extension ManifestLoader {
public func load(
packagePath: AbsolutePath,
Expand All @@ -139,7 +136,7 @@ extension ManifestLoader {
dependencyMapper: DependencyMapper? = .none,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope
) throws -> Manifest{
) async throws -> Manifest{
let packageIdentity: PackageIdentity
let packageLocation: String
switch packageKind {
Expand All @@ -160,22 +157,44 @@ extension ManifestLoader {
// FIXME: placeholder
packageLocation = identity.description
}
return try temp_await {
self.load(
packagePath: packagePath,
packageIdentity: packageIdentity,
packageKind: packageKind,
packageLocation: packageLocation,
packageVersion: nil,
currentToolsVersion: currentToolsVersion,
identityResolver: identityResolver,
dependencyMapper: dependencyMapper ?? DefaultDependencyMapper(identityResolver: identityResolver),
fileSystem: fileSystem,
observabilityScope: observabilityScope,
delegateQueue: .sharedConcurrent,
callbackQueue: .sharedConcurrent,
completion: $0
)
return try await self.load(
packagePath: packagePath,
packageIdentity: packageIdentity,
packageKind: packageKind,
packageLocation: packageLocation,
packageVersion: nil,
currentToolsVersion: currentToolsVersion,
identityResolver: identityResolver,
dependencyMapper: dependencyMapper ?? DefaultDependencyMapper(identityResolver: identityResolver),
fileSystem: fileSystem,
observabilityScope: observabilityScope,
delegateQueue: .sharedConcurrent,
callbackQueue: .sharedConcurrent
)
}
}

/// Temporary override environment variables
///
/// WARNING! This method is not thread-safe. POSIX environments are shared
/// between threads. This means that when this method is called simultaneously
/// from different threads, the environment will neither be setup nor restored
/// correctly.
public func withCustomEnv(_ env: [String: String], body: () async throws -> Void) async throws {
let state = env.map { ($0, $1) }
let restore = {
for (key, value) in state {
try ProcessEnv.setVar(key, value: value)
}
}
do {
for (key, value) in env {
try ProcessEnv.setVar(key, value: value)
}
try await body()
} catch {
try? restore()
throw error
}
try restore()
}
29 changes: 29 additions & 0 deletions Sources/SPMTestSupport/XCTAssertHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,35 @@ public func XCTAssertThrowsCommandExecutionError<T>(
}
}

public func XCTAssertAsyncEqual<T: Equatable>(
_ expression1: @autoclosure () async throws -> T,
_ expression2: @autoclosure () async throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #file,
line: UInt = #line
) async rethrows {
let value1 = try await expression1()
let value2 = try await expression2()

XCTAssertEqual(value1, value2, message(), file: file, line: line)
}

struct XCAsyncTestErrorWhileUnwrappingOptional: Error {}

public func XCTAsyncUnwrap<T>(
_ expression: @autoclosure () async throws -> T?,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) async throws -> T {
guard let result = try await expression() else {
throw XCAsyncTestErrorWhileUnwrappingOptional()
}

return result
}


public struct CommandExecutionError: Error {
public let result: ProcessResult
public let stdout: String
Expand Down
92 changes: 0 additions & 92 deletions Tests/PackageLoadingPerformanceTests/ManifestLoadingTests.swift

This file was deleted.

Loading