Skip to content
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

Adopt swift-testing for Timeout tests #2051

Merged
merged 4 commits into from
Sep 11, 2024
Merged
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
249 changes: 64 additions & 185 deletions Tests/GRPCCoreTests/TimeoutTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,193 +13,72 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import XCTest

@testable import GRPCCore

@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
final class TimeoutTests: XCTestCase {
func testDecodeInvalidTimeout_Empty() {
let timeoutHeader = ""
XCTAssertNil(Timeout(decoding: timeoutHeader))
}

func testDecodeInvalidTimeout_NoAmount() {
let timeoutHeader = "H"
XCTAssertNil(Timeout(decoding: timeoutHeader))
}

func testDecodeInvalidTimeout_NoUnit() {
let timeoutHeader = "123"
XCTAssertNil(Timeout(decoding: timeoutHeader))
}

func testDecodeInvalidTimeout_TooLongAmount() {
let timeoutHeader = "100000000S"
XCTAssertNil(Timeout(decoding: timeoutHeader))
}

func testDecodeInvalidTimeout_InvalidUnit() {
let timeoutHeader = "123j"
XCTAssertNil(Timeout(decoding: timeoutHeader))
}

func testDecodeValidTimeout_Hours() throws {
let timeoutHeader = "123H"
let timeout = Timeout(decoding: timeoutHeader)
let unwrappedTimeout = try XCTUnwrap(timeout)
XCTAssertEqual(unwrappedTimeout.duration, Duration.hours(123))
XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
}

func testDecodeValidTimeout_Minutes() throws {
let timeoutHeader = "123M"
let timeout = Timeout(decoding: timeoutHeader)
let unwrappedTimeout = try XCTUnwrap(timeout)
XCTAssertEqual(unwrappedTimeout.duration, Duration.minutes(123))
XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
}

func testDecodeValidTimeout_Seconds() throws {
let timeoutHeader = "123S"
let timeout = Timeout(decoding: timeoutHeader)
let unwrappedTimeout = try XCTUnwrap(timeout)
XCTAssertEqual(unwrappedTimeout.duration, Duration.seconds(123))
XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
}

func testDecodeValidTimeout_Milliseconds() throws {
let timeoutHeader = "123m"
let timeout = Timeout(decoding: timeoutHeader)
let unwrappedTimeout = try XCTUnwrap(timeout)
XCTAssertEqual(unwrappedTimeout.duration, Duration.milliseconds(123))
XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
}

func testDecodeValidTimeout_Microseconds() throws {
let timeoutHeader = "123u"
let timeout = Timeout(decoding: timeoutHeader)
let unwrappedTimeout = try XCTUnwrap(timeout)
XCTAssertEqual(unwrappedTimeout.duration, Duration.microseconds(123))
XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
}

func testDecodeValidTimeout_Nanoseconds() throws {
let timeoutHeader = "123n"
let timeout = Timeout(decoding: timeoutHeader)
let unwrappedTimeout = try XCTUnwrap(timeout)
XCTAssertEqual(unwrappedTimeout.duration, Duration.nanoseconds(123))
XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
}
import Testing

func testEncodeValidTimeout_Hours() {
let duration = Duration.hours(123)
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}

func testEncodeValidTimeout_Minutes() {
let duration = Duration.minutes(43)
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}

func testEncodeValidTimeout_Seconds() {
let duration = Duration.seconds(12345)
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}

func testEncodeValidTimeout_Seconds_TooLong_Minutes() {
let duration = Duration.seconds(111_111_111)
let timeout = Timeout(duration: duration)
// The conversion from seconds to minutes results in a loss of precision.
// 111,111,111 seconds / 60 = 1,851,851.85 minutes -rounding up-> 1,851,852 minutes * 60 = 111,111,120 seconds
let expectedRoundedDuration = Duration.minutes(1_851_852)
XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
XCTAssertEqual(
timeout.duration.components.attoseconds,
expectedRoundedDuration.components.attoseconds
)
}

func testEncodeValidTimeout_Seconds_TooLong_Hours() {
let duration = Duration.seconds(9_999_999_999 as Int64)
let timeout = Timeout(duration: duration)
// The conversion from seconds to hours results in a loss of precision.
// 9,999,999,999 seconds / 60 = 166,666,666.65 minutes -rounding up->
// 166,666,667 minutes / 60 = 2,777,777.78 hours -rounding up->
// 2,777,778 hours * 60 -> 166,666,680 minutes * 60 = 10,000,000,800 seconds
let expectedRoundedDuration = Duration.hours(2_777_778)
XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
XCTAssertEqual(
timeout.duration.components.attoseconds,
expectedRoundedDuration.components.attoseconds
)
}

func testEncodeValidTimeout_Seconds_TooLong_MaxAmount() {
let duration = Duration.seconds(999_999_999_999 as Int64)
let timeout = Timeout(duration: duration)
// The conversion from seconds to hours results in a number that still has
// more than the maximum allowed 8 digits, so we must clamp it.
// Make sure that `Timeout.maxAmount` is the amount used for the resulting timeout.
let expectedRoundedDuration = Duration.hours(Timeout.maxAmount)
XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
XCTAssertEqual(
timeout.duration.components.attoseconds,
expectedRoundedDuration.components.attoseconds
)
}

func testEncodeValidTimeout_SecondsAndMilliseconds() {
let duration = Duration(secondsComponent: 100, attosecondsComponent: Int64(1e+17))
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}

func testEncodeValidTimeout_SecondsAndMicroseconds() {
let duration = Duration(secondsComponent: 1, attosecondsComponent: Int64(1e+14))
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}

func testEncodeValidTimeout_SecondsAndNanoseconds() {
let duration = Duration(secondsComponent: 1, attosecondsComponent: Int64(1e+11))
let timeout = Timeout(duration: duration)
// We can't convert seconds to nanoseconds because that would require at least
// 9 digits, and the maximum allowed is 8: we expect to simply drop the nanoseconds.
let expectedRoundedDuration = Duration.seconds(1)
XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
XCTAssertEqual(
timeout.duration.components.attoseconds,
expectedRoundedDuration.components.attoseconds
)
}

func testEncodeValidTimeout_Milliseconds() {
let duration = Duration.milliseconds(100)
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}

func testEncodeValidTimeout_Microseconds() {
let duration = Duration.microseconds(100)
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
}
@testable import GRPCCore

func testEncodeValidTimeout_Nanoseconds() {
let duration = Duration.nanoseconds(100)
let timeout = Timeout(duration: duration)
XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
struct TimeoutTests {
@Test("Initialize from invalid String value", arguments: ["", "H", "123", "100000000S", "123j"])
func initFromStringWithInvalidValue(_ value: String) throws {
#expect(Timeout(decoding: value) == nil)
}

@Test(
"Initialize from String",
arguments: [
("123H", .hours(123)),
("123M", .minutes(123)),
("123S", .seconds(123)),
("123m", .milliseconds(123)),
("123u", .microseconds(123)),
("123n", .nanoseconds(123)),
] as [(String, Duration)]
)
func initFromString(_ value: String, expected: Duration) throws {
let timeout = try #require(Timeout(decoding: value))
#expect(timeout.duration == expected)
}

@Test(
"Initialize from Duration",
arguments: [
.hours(123),
.minutes(43),
.seconds(12345),
.milliseconds(100),
.microseconds(100),
.nanoseconds(100),
] as [Duration]
)
func initFromDuration(_ value: Duration) {
let timeout = Timeout(duration: value)
#expect(timeout.duration == value)
}

@Test(
"Initialize from Duration with loss of precision",
arguments: [
// 111,111,111 seconds / 60 = 1,851,851.85 minutes -rounding up-> 1,851,852 minutes * 60 = 111,111,120 seconds
(.seconds(111_111_111), .minutes(1_851_852)),

// 9,999,999,999 seconds / 60 = 166,666,666.65 minutes -rounding up->
// 166,666,667 minutes / 60 = 2,777,777.78 hours -rounding up->
// 2,777,778 hours * 60 -> 166,666,680 minutes * 60 = 10,000,000,800 seconds
(.seconds(9_999_999_999 as Int64), .hours(2_777_778)),

// The conversion from seconds to hours results in a number that still has
// more than the maximum allowed 8 digits, so we must clamp it.
// Make sure that `Timeout.maxAmount` is the amount used for the resulting timeout.
(.seconds(999_999_999_999 as Int64), .hours(Timeout.maxAmount)),

// We can't convert seconds to nanoseconds because that would require at least
// 9 digits, and the maximum allowed is 8: we expect to simply drop the nanoseconds.
(Duration(secondsComponent: 1, attosecondsComponent: Int64(1e11)), .seconds(1)),
] as [(Duration, Duration)]
)
func initFromDurationWithLossOfPrecision(original: Duration, rounded: Duration) {
let timeout = Timeout(duration: original)
#expect(timeout.duration == rounded)
}
}
Loading