GRPCServerRequestRoutingHandlerTests.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright 2019, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Foundation
  17. import XCTest
  18. import NIO
  19. import NIOHTTP1
  20. import GRPC
  21. import EchoModel
  22. import EchoImplementation
  23. import Logging
  24. class GRPCServerRequestRoutingHandlerTests: GRPCTestCase {
  25. var channel: EmbeddedChannel!
  26. override func setUp() {
  27. super.setUp()
  28. let provider = EchoProvider()
  29. let handler = GRPCServerRequestRoutingHandler(
  30. servicesByName: [provider.serviceName: provider],
  31. encoding: .disabled,
  32. errorDelegate: nil,
  33. logger: self.logger
  34. )
  35. self.channel = EmbeddedChannel(handler: handler)
  36. }
  37. override func tearDown() {
  38. XCTAssertNoThrow(try self.channel.finish())
  39. }
  40. func testInvalidGRPCContentTypeReturnsUnsupportedMediaType() throws {
  41. let requestHead = HTTPRequestHead(
  42. version: .init(major: 2, minor: 0),
  43. method: .POST,
  44. uri: "/echo.Echo/Get",
  45. headers: ["content-type": "not-grpc"]
  46. )
  47. XCTAssertNoThrow(try self.channel.writeInbound(HTTPServerRequestPart.head(requestHead)))
  48. let firstResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  49. switch firstResponsePart {
  50. case .some(.head(let head)):
  51. XCTAssertEqual(head.status, .unsupportedMediaType)
  52. default:
  53. XCTFail("Unexpected response part: \(String(describing: firstResponsePart))")
  54. }
  55. let secondResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  56. switch secondResponsePart {
  57. case .some(.end(nil)):
  58. ()
  59. default:
  60. XCTFail("Unexpected response part: \(String(describing: secondResponsePart))")
  61. }
  62. }
  63. func testUnimplementedMethodReturnsUnimplementedStatus() throws {
  64. let requestHead = HTTPRequestHead(
  65. version: .init(major: 2, minor: 0),
  66. method: .POST,
  67. uri: "/foo/Bar",
  68. headers: ["content-type": "application/grpc"]
  69. )
  70. XCTAssertNoThrow(try self.channel.writeInbound(HTTPServerRequestPart.head(requestHead)))
  71. let firstResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  72. switch firstResponsePart {
  73. case .some(.head(let head)):
  74. XCTAssertEqual(head.status, .ok)
  75. XCTAssertEqual(head.headers.first(name: "grpc-status"), "\(GRPCStatus.Code.unimplemented.rawValue)")
  76. default:
  77. XCTFail("Unexpected response part: \(String(describing: firstResponsePart))")
  78. }
  79. let secondResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  80. switch secondResponsePart {
  81. case .some(.end(nil)):
  82. ()
  83. default:
  84. XCTFail("Unexpected response part: \(String(describing: secondResponsePart))")
  85. }
  86. }
  87. func testImplementedMethodReconfiguresPipeline() throws {
  88. let requestHead = HTTPRequestHead(
  89. version: .init(major: 2, minor: 0),
  90. method: .POST,
  91. uri: "/echo.Echo/Get",
  92. headers: ["content-type": "application/grpc"]
  93. )
  94. XCTAssertNoThrow(try self.channel.writeInbound(HTTPServerRequestPart.head(requestHead)))
  95. // The router should be removed from the pipeline.
  96. let router = self.channel.pipeline.handler(type: GRPCServerRequestRoutingHandler.self)
  97. XCTAssertThrowsError(try router.wait())
  98. // There should now be a unary call handler.
  99. let unary = self.channel.pipeline.handler(type: UnaryCallHandler<Echo_EchoRequest, Echo_EchoResponse>.self)
  100. XCTAssertNoThrow(try unary.wait())
  101. }
  102. }