|
|
@@ -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)
|
|
|
}
|
|
|
}
|