| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- * Copyright 2023, gRPC Authors All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- import GRPCCore
- import Testing
- @Suite("RPCError Tests")
- struct RPCErrorTests {
- @Test("Custom String Convertible")
- func testCustomStringConvertible() {
- #expect(String(describing: RPCError(code: .dataLoss, message: "")) == #"dataLoss: """#)
- #expect(
- String(describing: RPCError(code: .unknown, message: "message")) == #"unknown: "message""#
- )
- #expect(
- String(describing: RPCError(code: .aborted, message: "message")) == #"aborted: "message""#
- )
- struct TestError: Error {}
- #expect(
- String(describing: RPCError(code: .aborted, message: "message", cause: TestError()))
- == #"aborted: "message" (cause: "TestError()")"#
- )
- }
- @Test("Error from Status")
- func testErrorFromStatus() throws {
- var status = Status(code: .ok, message: "")
- // ok isn't an error
- #expect(RPCError(status: status) == nil)
- status.code = .invalidArgument
- var error = try #require(RPCError(status: status))
- #expect(error.code == .invalidArgument)
- #expect(error.message == "")
- #expect(error.metadata == [:])
- status.code = .cancelled
- status.message = "an error message"
- error = try #require(RPCError(status: status))
- #expect(error.code == .cancelled)
- #expect(error.message == "an error message")
- #expect(error.metadata == [:])
- }
- @Test(
- "Error Code from Status Code",
- arguments: [
- (Status.Code.ok, nil),
- (Status.Code.cancelled, RPCError.Code.cancelled),
- (Status.Code.unknown, RPCError.Code.unknown),
- (Status.Code.invalidArgument, RPCError.Code.invalidArgument),
- (Status.Code.deadlineExceeded, RPCError.Code.deadlineExceeded),
- (Status.Code.notFound, RPCError.Code.notFound),
- (Status.Code.alreadyExists, RPCError.Code.alreadyExists),
- (Status.Code.permissionDenied, RPCError.Code.permissionDenied),
- (Status.Code.resourceExhausted, RPCError.Code.resourceExhausted),
- (Status.Code.failedPrecondition, RPCError.Code.failedPrecondition),
- (Status.Code.aborted, RPCError.Code.aborted),
- (Status.Code.outOfRange, RPCError.Code.outOfRange),
- (Status.Code.unimplemented, RPCError.Code.unimplemented),
- (Status.Code.internalError, RPCError.Code.internalError),
- (Status.Code.unavailable, RPCError.Code.unavailable),
- (Status.Code.dataLoss, RPCError.Code.dataLoss),
- (Status.Code.unauthenticated, RPCError.Code.unauthenticated),
- ]
- )
- func testErrorCodeFromStatusCode(statusCode: Status.Code, rpcErrorCode: RPCError.Code?) throws {
- #expect(RPCError.Code(statusCode) == rpcErrorCode)
- }
- @Test("Equatable Conformance")
- func testEquatableConformance() {
- #expect(
- RPCError(code: .cancelled, message: "")
- == RPCError(code: .cancelled, message: "")
- )
- #expect(
- RPCError(code: .cancelled, message: "message")
- == RPCError(code: .cancelled, message: "message")
- )
- #expect(
- RPCError(code: .cancelled, message: "message", metadata: ["foo": "bar"])
- == RPCError(code: .cancelled, message: "message", metadata: ["foo": "bar"])
- )
- #expect(
- RPCError(code: .cancelled, message: "")
- != RPCError(code: .cancelled, message: "message")
- )
- #expect(
- RPCError(code: .cancelled, message: "message")
- != RPCError(code: .unknown, message: "message")
- )
- #expect(
- RPCError(code: .cancelled, message: "message", metadata: ["foo": "bar"])
- != RPCError(code: .cancelled, message: "message", metadata: ["foo": "baz"])
- )
- }
- @Test(
- "Status Code Raw Values",
- arguments: [
- (RPCError.Code.cancelled, 1),
- (.unknown, 2),
- (.invalidArgument, 3),
- (.deadlineExceeded, 4),
- (.notFound, 5),
- (.alreadyExists, 6),
- (.permissionDenied, 7),
- (.resourceExhausted, 8),
- (.failedPrecondition, 9),
- (.aborted, 10),
- (.outOfRange, 11),
- (.unimplemented, 12),
- (.internalError, 13),
- (.unavailable, 14),
- (.dataLoss, 15),
- (.unauthenticated, 16),
- ]
- )
- func testStatusCodeRawValues(statusCode: RPCError.Code, rawValue: Int) {
- #expect(statusCode.rawValue == rawValue, "\(statusCode) had unexpected raw value")
- }
- @Test("Flatten causes with same status code")
- func testFlattenCausesWithSameStatusCode() {
- let error1 = RPCError(code: .unknown, message: "Error 1.")
- let error2 = RPCError(code: .unknown, message: "Error 2.", cause: error1)
- let error3 = RPCError(code: .dataLoss, message: "Error 3.", cause: error2)
- let error4 = RPCError(code: .aborted, message: "Error 4.", cause: error3)
- let error5 = RPCError(
- code: .aborted,
- message: "Error 5.",
- cause: error4
- )
- let unknownMerged = RPCError(code: .unknown, message: "Error 2. Error 1.")
- let dataLossMerged = RPCError(code: .dataLoss, message: "Error 3.", cause: unknownMerged)
- let abortedMerged = RPCError(
- code: .aborted,
- message: "Error 5. Error 4.",
- cause: dataLossMerged
- )
- #expect(error5 == abortedMerged)
- }
- @Test("Causes of errors with different status codes aren't flattened")
- func testDifferentStatusCodeAreNotFlattened() throws {
- let error1 = RPCError(code: .unknown, message: "Error 1.")
- let error2 = RPCError(code: .dataLoss, message: "Error 2.", cause: error1)
- let error3 = RPCError(code: .alreadyExists, message: "Error 3.", cause: error2)
- let error4 = RPCError(code: .aborted, message: "Error 4.", cause: error3)
- let error5 = RPCError(
- code: .deadlineExceeded,
- message: "Error 5.",
- cause: error4
- )
- #expect(error5.code == .deadlineExceeded)
- #expect(error5.message == "Error 5.")
- let wrappedError4 = try #require(error5.cause as? RPCError)
- #expect(wrappedError4.code == .aborted)
- #expect(wrappedError4.message == "Error 4.")
- let wrappedError3 = try #require(wrappedError4.cause as? RPCError)
- #expect(wrappedError3.code == .alreadyExists)
- #expect(wrappedError3.message == "Error 3.")
- let wrappedError2 = try #require(wrappedError3.cause as? RPCError)
- #expect(wrappedError2.code == .dataLoss)
- #expect(wrappedError2.message == "Error 2.")
- let wrappedError1 = try #require(wrappedError2.cause as? RPCError)
- #expect(wrappedError1.code == .unknown)
- #expect(wrappedError1.message == "Error 1.")
- #expect(wrappedError1.cause == nil)
- }
- }
|