mirror of
https://github.com/apple/container.git
synced 2026-08-24 02:24:19 -05:00
Simplify correlation of test prefix to test ID. (#2071)
This commit is contained in:
@@ -80,16 +80,47 @@ public final class ContainerFixture: Sendable {
|
||||
public static func with<T>(_ body: (ContainerFixture) async throws -> T) async throws -> T {
|
||||
let testID = String(UUID().uuidString.prefix(8)).lowercased()
|
||||
|
||||
let testName =
|
||||
Test.current.map { $0.name.hasSuffix("()") ? String($0.name.dropLast(2)) : $0.name }
|
||||
?? testID
|
||||
// Test.current is a value describing the running test, not an instance of the suite
|
||||
// type, so `type(of:)` always yields `Test` itself. Derive the suite from the test's
|
||||
// fully-qualified ID instead (e.g. "IntegrationTests.TestCLIStatus/explicitTableFormat()/...")
|
||||
// — the same identifier format used in the swift-testing event-stream JSON.
|
||||
let testIdentifier = Test.current.map { "\($0.id)" }
|
||||
let suiteName = testIdentifier?.split(separator: "/", maxSplits: 1).first.map(String.init) ?? "unknown"
|
||||
|
||||
// Swift Testing doesn't expose a stable per-case identifier or the case's arguments
|
||||
// publicly, only `isParameterized`. Parameterized tests share one `testName` across all
|
||||
// their concurrently-running cases, so fall back to the per-invocation `testID` to keep
|
||||
// each case's log file distinct.
|
||||
let isParameterized = Test.Case.current?.isParameterized ?? false
|
||||
let logFileName = isParameterized ? "\(testName)-\(testID).log" : "\(testName).log"
|
||||
|
||||
// Set up logging before any fixture work (scratch dir creation, etc.) so a "test start"
|
||||
// message is the first thing recorded — bookended by "test end" once `body` returns.
|
||||
var logger = Logger(label: "com.apple.container.test") { label in
|
||||
if let root = ProcessInfo.processInfo.environment["CLITEST_LOG_ROOT"], !root.isEmpty {
|
||||
let path =
|
||||
FilePath(root)
|
||||
.appending("clitests")
|
||||
.appending(suiteName)
|
||||
.appending(logFileName)
|
||||
if let handler = try? FileLogHandler(label: label, category: "clitests", path: path) {
|
||||
return handler
|
||||
}
|
||||
}
|
||||
return StreamLogHandler.standardOutput(label: label)
|
||||
}
|
||||
logger[metadataKey: "testID"] = "\(testID)"
|
||||
logger[metadataKey: "test"] = "\(testIdentifier ?? testName)"
|
||||
logger.info("test start")
|
||||
|
||||
let scratchRoot =
|
||||
ProcessInfo.processInfo.environment["CLITEST_SCRATCH_ROOT"]
|
||||
.map { FilePath($0) }
|
||||
?? FilePath(FileManager.default.temporaryDirectory.path)
|
||||
|
||||
let testName =
|
||||
Test.current.map { $0.name.hasSuffix("()") ? String($0.name.dropLast(2)) : $0.name }
|
||||
?? testID
|
||||
let suiteName = Test.current.map { "\(type(of: $0))" } ?? "unknown"
|
||||
|
||||
// Name the scratch directory so it's immediately identifiable when browsing:
|
||||
// {sanitizedTestName}-{testID}
|
||||
let safeName = testName.replacingOccurrences(
|
||||
@@ -98,21 +129,6 @@ public final class ContainerFixture: Sendable {
|
||||
try FileManager.default.createDirectory(
|
||||
atPath: testDir.string, withIntermediateDirectories: true, attributes: nil)
|
||||
|
||||
var logger = Logger(label: "com.apple.container.test") { label in
|
||||
if let root = ProcessInfo.processInfo.environment["CLITEST_LOG_ROOT"], !root.isEmpty {
|
||||
let path =
|
||||
FilePath(root)
|
||||
.appending("clitests")
|
||||
.appending(suiteName)
|
||||
.appending(testName + ".log")
|
||||
if let handler = try? FileLogHandler(label: label, category: "clitests", path: path) {
|
||||
return handler
|
||||
}
|
||||
}
|
||||
return StreamLogHandler.standardOutput(label: label)
|
||||
}
|
||||
logger[metadataKey: "testID"] = "\(testID)"
|
||||
|
||||
let fixture = ContainerFixture(testID: testID, testDir: testDir, log: logger)
|
||||
|
||||
if ProcessInfo.processInfo.environment["CLITEST_PRESERVE_SCRATCH"] != "true" {
|
||||
@@ -123,10 +139,14 @@ public final class ContainerFixture: Sendable {
|
||||
|
||||
do {
|
||||
let result = try await body(fixture)
|
||||
logger.info("test end", metadata: ["result": "pass"])
|
||||
await fixture.runCleanup()
|
||||
logger.info("test cleaned up")
|
||||
return result
|
||||
} catch {
|
||||
logger.info("test end", metadata: ["result": "fail", "error": "\(error)"])
|
||||
await fixture.runCleanup()
|
||||
logger.info("test cleaned up")
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user