Skip to content

Commit fc6556a

Browse files
authored
Include severity and isFailure for Issues in the published JSON event stream (#1279)
### Motivation: - Proposed and accepted in ST-0013 [^1], so we can move ahead and include this in the event stream. - This will _not_ be available in event stream version 0 as this is considered a breaking change [^2] ### Modifications: - Promote existing _severity/_isFailure fields -> severity/isFailure without the underscores This effectively makes them part of the official JSON ABI. The underscored names will no longer be accessible, but they were always experimental so this is not considered a blocker. - Only emit severity/isFailure when using event stream version >= 6.3 This removes access to the underscored names from earlier versions, but again, these were experimental. - Remove hidden `__CommandLineArguments_v0` argument `isWarningIssueRecordedEventEnabled` This was only for internal testing use, but is obsolete because we test issue severity by specifying event stream version >= 6.3. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated. [^1]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0013-issue-severity-warning.md [^2]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0013-issue-severity-warning.md#integration-with-supporting-tools Fixes rdar://158621033
1 parent cff2b11 commit fc6556a

File tree

5 files changed

+92
-46
lines changed

5 files changed

+92
-46
lines changed

Sources/Testing/ABI/Encoded/ABI.EncodedIssue.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,21 @@ extension ABI {
2626

2727
/// The severity of this issue.
2828
///
29-
/// - Warning: Severity is not yet part of the JSON schema.
30-
var _severity: Severity
31-
29+
/// Prior to 6.3, this is nil.
30+
///
31+
/// @Metadata {
32+
/// @Available(Swift, introduced: 6.3)
33+
/// }
34+
var severity: Severity?
35+
3236
/// If the issue is a failing issue.
3337
///
34-
/// - Warning: Non-failing issues are not yet part of the JSON schema.
35-
var _isFailure: Bool
38+
/// Prior to 6.3, this is nil.
39+
///
40+
/// @Metadata {
41+
/// @Available(Swift, introduced: 6.3)
42+
/// }
43+
var isFailure: Bool?
3644

3745
/// Whether or not this issue is known to occur.
3846
var isKnown: Bool
@@ -51,13 +59,20 @@ extension ABI {
5159
var _error: EncodedError<V>?
5260

5361
init(encoding issue: borrowing Issue, in eventContext: borrowing Event.Context) {
54-
_severity = switch issue.severity {
55-
case .warning: .warning
56-
case .error: .error
57-
}
58-
_isFailure = issue.isFailure
62+
// >= v0
5963
isKnown = issue.isKnown
6064
sourceLocation = issue.sourceLocation
65+
66+
// >= v6.3
67+
if V.versionNumber >= ABI.v6_3.versionNumber {
68+
severity = switch issue.severity {
69+
case .warning: .warning
70+
case .error: .error
71+
}
72+
isFailure = issue.isFailure
73+
}
74+
75+
// Experimental
6176
if let backtrace = issue.sourceContext.backtrace {
6277
_backtrace = EncodedBacktrace(encoding: backtrace, in: eventContext)
6378
}

Sources/Testing/ABI/EntryPoints/EntryPoint.swift

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
5959
// Use experimental AdvancedConsoleOutputRecorder
6060
var advancedOptions = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>.Options()
6161
advancedOptions.base = .for(.stderr)
62-
62+
6363
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(options: advancedOptions) { string in
6464
try? FileHandle.stderr.write(string)
6565
}
66-
66+
6767
configuration.eventHandler = { [oldEventHandler = configuration.eventHandler] event, context in
6868
eventRecorder.record(event, in: context)
6969
oldEventHandler(event, context)
@@ -328,13 +328,6 @@ public struct __CommandLineArguments_v0: Sendable {
328328

329329
/// The value of the `--attachments-path` argument.
330330
public var attachmentsPath: String?
331-
332-
/// Whether or not the experimental warning issue severity feature should be
333-
/// enabled.
334-
///
335-
/// This property is intended for use in testing the testing library itself.
336-
/// It is not parsed as a command-line argument.
337-
var isWarningIssueRecordedEventEnabled: Bool?
338331
}
339332

340333
extension __CommandLineArguments_v0: Codable {
@@ -635,19 +628,15 @@ public func configurationForEntryPoint(from args: __CommandLineArguments_v0) thr
635628
#endif
636629

637630
// Warning issues (experimental).
638-
if args.isWarningIssueRecordedEventEnabled == true {
639-
configuration.eventHandlingOptions.isWarningIssueRecordedEventEnabled = true
640-
} else {
641-
switch args.eventStreamVersionNumber {
642-
case .some(..<ABI.v6_3.versionNumber):
643-
// If the event stream version was explicitly specified to a value < 6.3,
644-
// disable the warning issue event to maintain legacy behavior.
645-
configuration.eventHandlingOptions.isWarningIssueRecordedEventEnabled = false
646-
default:
647-
// Otherwise the requested event stream version is ≥ 6.3, so don't change
648-
// the warning issue event setting.
649-
break
650-
}
631+
switch args.eventStreamVersionNumber {
632+
case .some(..<ABI.v6_3.versionNumber):
633+
// If the event stream version was explicitly specified to a value < 6.3,
634+
// disable the warning issue event to maintain legacy behavior.
635+
configuration.eventHandlingOptions.isWarningIssueRecordedEventEnabled = false
636+
default:
637+
// Otherwise the requested event stream version is ≥ 6.3, so don't change
638+
// the warning issue event setting.
639+
break
651640
}
652641

653642
return configuration

Sources/Testing/ExitTests/ExitTest.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,10 +1046,11 @@ extension ExitTest {
10461046
// TODO: improve fidelity of issue kind reporting (especially those without associated values)
10471047
.unconditional
10481048
}
1049-
let severity: Issue.Severity = switch issue._severity {
1049+
let severity: Issue.Severity = switch issue.severity {
10501050
case .warning:
10511051
.warning
1052-
case .error:
1052+
case .error, nil:
1053+
// Prior to 6.3, all Issues are errors
10531054
.error
10541055
}
10551056
let sourceContext = SourceContext(

Tests/TestingTests/EntryPointTests.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ struct EntryPointTests {
3030
}
3131
}
3232

33-
@Test("Entry point with WarningIssues feature enabled exits with success if all issues have severity < .error")
34-
func warningIssues() async throws {
33+
@Test("Entry point using event stream version 0 exits with success if all issues have severity < .error")
34+
func warningIssuesDisabled() async throws {
3535
var arguments = __CommandLineArguments_v0()
3636
arguments.filter = ["_recordWarningIssue"]
3737
arguments.includeHiddenTests = true
38+
// WarningIssues is available >= 6.3
3839
arguments.eventStreamSchemaVersion = "0"
3940
arguments.verbosity = .min
4041

@@ -50,13 +51,13 @@ struct EntryPointTests {
5051
#expect(exitCode == EXIT_SUCCESS)
5152
}
5253

53-
@Test("Entry point with WarningIssues feature enabled propagates warning issues and exits with success if all issues have severity < .error")
54+
55+
@Test("Entry point using event stream version 6.3 propagates warning issues and exits with success if all issues have severity < .error")
5456
func warningIssuesEnabled() async throws {
5557
var arguments = __CommandLineArguments_v0()
5658
arguments.filter = ["_recordWarningIssue"]
5759
arguments.includeHiddenTests = true
58-
arguments.eventStreamSchemaVersion = "0"
59-
arguments.isWarningIssueRecordedEventEnabled = true
60+
arguments.eventStreamSchemaVersion = "6.3"
6061
arguments.verbosity = .min
6162

6263
let exitCode = await confirmation("Warning issue recorded", expectedCount: 1) { issueRecorded in

Tests/TestingTests/SwiftPMTests.swift

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ private func configurationForEntryPoint(withArguments args: [String]) throws ->
2020
return try configurationForEntryPoint(from: args)
2121
}
2222

23+
/// Reads event stream output from the provided file matching event stream
24+
/// version `V`.
25+
private func decodedEventStreamRecords<V: ABI.Version>(fromPath filePath: String) throws -> [ABI.Record<V>] {
26+
try FileHandle(forReadingAtPath: filePath).readToEnd()
27+
.split(whereSeparator: \.isASCIINewline)
28+
.map { line in
29+
try line.withUnsafeBytes { line in
30+
return try JSON.decode(ABI.Record<V>.self, from: line)
31+
}
32+
}
33+
}
34+
2335
@Suite("Swift Package Manager Integration Tests")
2436
struct SwiftPMTests {
2537
@Test("Command line arguments are available")
@@ -286,6 +298,40 @@ struct SwiftPMTests {
286298
#expect(versionTypeInfo == nil)
287299
}
288300

301+
@Test("Severity and isFailure fields included in version 6.3")
302+
func validateEventStreamContents() async throws {
303+
let tempDirPath = try temporaryDirectory()
304+
let temporaryFilePath = appendPathComponent("\(UInt64.random(in: 0 ..< .max))", to: tempDirPath)
305+
defer {
306+
_ = remove(temporaryFilePath)
307+
}
308+
309+
do {
310+
let test = Test {
311+
Issue.record("Test warning", severity: .warning)
312+
}
313+
314+
let configuration = try configurationForEntryPoint(withArguments:
315+
["PATH", "--event-stream-output-path", temporaryFilePath, "--experimental-event-stream-version", "6.3"]
316+
)
317+
318+
await test.run(configuration: configuration)
319+
}
320+
321+
let issueEventRecords = try decodedEventStreamRecords(fromPath: temporaryFilePath)
322+
.compactMap { (record: ABI.Record<ABI.v6_3>) in
323+
if case let .event(event) = record.kind, event.kind == .issueRecorded {
324+
return event
325+
}
326+
return nil
327+
}
328+
329+
let issue = try #require(issueEventRecords.first?.issue)
330+
#expect(issueEventRecords.count == 1)
331+
#expect(issue.isFailure == false)
332+
#expect(issue.severity == .warning)
333+
}
334+
289335
@Test("--event-stream-output-path argument (writes to a stream and can be read back)",
290336
arguments: [
291337
("--event-stream-output-path", "--event-stream-version", ABI.v0.versionNumber),
@@ -320,13 +366,7 @@ struct SwiftPMTests {
320366
configuration.handleEvent(Event(.runEnded, testID: nil, testCaseID: nil), in: eventContext)
321367
}
322368

323-
let decodedRecords = try FileHandle(forReadingAtPath: temporaryFilePath).readToEnd()
324-
.split(whereSeparator: \.isASCIINewline)
325-
.map { line in
326-
try line.withUnsafeBytes { line in
327-
try JSON.decode(ABI.Record<V>.self, from: line)
328-
}
329-
}
369+
let decodedRecords: [ABI.Record<V>] = try decodedEventStreamRecords(fromPath: temporaryFilePath)
330370

331371
let testRecords = decodedRecords.compactMap { record in
332372
if case let .test(test) = record.kind {

0 commit comments

Comments
 (0)