Description
Description
Note: I filed this bug in Apple's Feedback (FB14192814) when I first discovered it on July 4th. As it's still an issue with the Beta 6, wanted to bring more awareness to it.
For any Swift Testing test where you use #expect
to compare two ClosedRange<Int>
instances, and the actual value deviates from the expected value, the test may hang or crash.
Note: While I will present details below for various values, I didn't yet do any testing with ClosedRange<Int8>
or any other types. So possible that the issue doesn't just affect ClosedRange<Int>
Expected behavior
As with XCTest (which has no issues when using XCTAssertEqual), tests shouldn't hang or crash for trivial comparisons of ranges where an failure will be generated.
Actual behavior
Depending upon the values stored in lowerBound
and/or upperBound
, the tests will have three possible outcomes whenever a failure is expected:
- The test does not hang and reports the failure correctly.
- The test hangs (Xcode Beta 2 I believe had extremely long hangs. Betas 3 through 6 will hang for several seconds on an M2 Ultra Mac Studio. Though a failure will ultimately be generated.
- The test crashes (same behavior in Beta 2 through Beta 6) with EXC_BREAKPOINT (Testing.__checkBinaryOperation)
Steps to reproduce
I'm attaching the sample project also attached to Apple's Feedback. Reproduction instructions:
- Open the ExpectRange project with Xcode 16.0 Beta (I have not tried things with the 16.1 Beta, but expect the same outcome).
- In the file ExpectRangeTests.swift I have set things up such that if Swift Testing is available, it will run those versions of the tests. Opening the project in Xcode 15.x will execute the equivalent XCTest tests which show no issue.
- Run the first test "doesNotHangWithCorrectRanges". This shows that when no failure needs to be generated, Int values that could also be stored in Int8, UInt8, ... Int64 all have no issues.
- Run the next two tests "int8_doesNotHang" and "uint8_doesNotHang". Note that failures should be immediately generated for all lines in the test (where I set just the upperBound to an invalid value, just the lowerBound and both).
- Run any of "int16_hangs" through "uint32_hangs". These will ultimately generate failures, but run significantly slower that when the Int values are small (can fit within Int8/UInt8)
- Run "int64_crashes" to see the crash.
- Run "doesNotHang" which shows the workaround of using
#expect
to verifylowerBound
andupperBound
individually.
Note: Even though the test names mention "int8", "uint16", etc. all closed ranges involved are of type ClosedRange<Int>
. Not to be confused with the actual types of Int8
, UInt16
, etc. It's interesting that for very small values stored in an Int that the tests don't hang, medium to semi-large will hang, and the largest values crash.
swift-testing version/commit hash
No response
Swift & OS version (output of swift --version ; uname -a
)
swift-driver version: 1.115 Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2)
Target: arm64-apple-macosx14.0
Darwin Ariel-Mac-Studio.local 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6020 arm64