-
Notifications
You must be signed in to change notification settings - Fork 102
Record issues generated within exit tests. #697
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
Conversation
@swift-ci test |
6 similar comments
@swift-ci test |
@swift-ci test |
@swift-ci test |
@swift-ci test |
@swift-ci test |
@swift-ci test |
4b4ec43
to
32b58ed
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
c783c17
to
ff61fc6
Compare
@swift-ci test |
@swift-ci test Linux |
b291707
to
324f6b8
Compare
@swift-ci test |
6845910
to
c635ea3
Compare
This PR moves the logic that implements JSON Lines support (i.e. the code that strips newlines from JSON generated by Foundation) out of EntryPoint.swift so that it can be used by other callers. This change was originally part of #697. I'm splitting it out into its own PR to make that one (both really) easier to read and understand.
@swift-ci test |
1 similar comment
@swift-ci test |
@swift-ci test |
This PR introduces a "back channel" file handle to exit tests, allowing us to record issues that occur within exit test bodies. For example: ```swift await #expect(exitsWith: .failure) { let context = try #require(possiblyMissingContext) ... } ``` In this example, if the call to `try #require()` finds `nil`, it will record an issue, but that issue today will be lost because there's no mechanism to forward the issue back to the parent process hosting the exit test. This PR fixes that! Issues are converted to JSON using the same schema we use for event handling, then written over a pipe back to the parent process where they are decoded. This decoding is lossy, so there will be further refinement needed here to try to preserve more information about the recorded issues. That said, "it's got good bones" right? On Darwin, Linux, and FreeBSD, the pipe's write end is allowed to survive into the child process (i.e. no `FD_CLOEXEC`). On Windows, the equivalent is to tell `CreateProcessW()` to explicitly inherit a `HANDLE`. The identity of this file descriptor or handle is passed to the child process via environment variable. The child process then parses the file descriptor or handle out of the environment and converts it back to a `FileHandle` that is then connected to an instance of `Configuration` with an event handler set, and off we go. Because we can now report these issues back to the parent process, I've removed the compile-time diagnostic in the `#expect(exitsWith:)` macro implementation that we emit when we see a nested `#expect()` or `#require()` call.
…nction so you can't break things by calling it twice in the same process
…y applies to our own entry point and third parties would need to supply their own configuration/etc. anyway
a03037b
to
ec89f02
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
@swift-ci test |
@swift-ci test |
message.symbol == .details ? Comment(rawValue: message.text) : nil | ||
} | ||
let sourceContext = SourceContext( | ||
backtrace: nil, // `issue._backtrace` will have the wrong address space. |
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.
Can we file an issue to follow up here and eventually propagate and preserve some of the symbolicated address of the backtrace? I know the specific numeric addresses will not be useful, but if the backtrace was symbolicated, it would be great to propagate symbol names. But I assume that will require a bit more effort and isn't in scope here
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.
It's something we can do once we have a proper symbolication mechanism rather than the POC that's in the repo now.
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.
Nice!
#718) Hot on the heels of #697… If an exit test records an issue of kind `.errorCaught()`, we currently treat it the same as any other issue and translate it to a flat `.unconditional` issue in the parent process: ```swift await #expect(exitsWith: .failure) { Issue.record(NoSuchWeaselError()) // unconditional issue recorded } ``` This PR distinguishes the `.errorCaught` issue kind and records an `.errorCaught` issue in the parent process. Fidelity of errors across a process boundary is weak, but we encode a minimal representation of the error that should be good enough for most uses. If you need `withKnownIssue()`, or `#expect(throws:)`, you can call them _inside_ the exit test. ### 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.
This PR introduces a "back channel" file handle to exit tests, allowing us to record issues that occur within exit test bodies. For example:
In this example, if the call to
try #require()
findsnil
, it will record an issue, but that issue today will be lost because there's no mechanism to forward the issue back to the parent process hosting the exit test. This PR fixes that!Issues are converted to JSON using the same schema we use for event handling, then written over a pipe back to the parent process where they are decoded. This decoding is lossy, so there will be further refinement needed here to try to preserve more information about the recorded issues. That said, "it's got good bones" right?
On Darwin, Linux, and FreeBSD, the pipe's write end is allowed to survive into the child process (i.e. no
FD_CLOEXEC
). On Windows, the equivalent is to tellCreateProcessW()
to explicitly inherit aHANDLE
. The identity of this file descriptor or handle is passed to the child process via environment variable. The child process then parses the file descriptor or handle out of the environment and converts it back to aFileHandle
that is then connected to an instance ofConfiguration
with an event handler set, and off we go.Because we can now report these issues back to the parent process, I've removed the compile-time diagnostic in the
#expect(exitsWith:)
macro implementation that we emit when we see a nested#expect()
or#require()
call.Checklist: