GRPCServerRequestRoutingHandlerTests.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. super.tearDown()
  40. }
  41. func testInvalidGRPCContentTypeReturnsUnsupportedMediaType() throws {
  42. let requestHead = HTTPRequestHead(
  43. version: .init(major: 2, minor: 0),
  44. method: .POST,
  45. uri: "/echo.Echo/Get",
  46. headers: ["content-type": "not-grpc"]
  47. )
  48. XCTAssertNoThrow(try self.channel.writeInbound(HTTPServerRequestPart.head(requestHead)))
  49. let firstResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  50. switch firstResponsePart {
  51. case .some(.head(let head)):
  52. XCTAssertEqual(head.status, .unsupportedMediaType)
  53. default:
  54. XCTFail("Unexpected response part: \(String(describing: firstResponsePart))")
  55. }
  56. let secondResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  57. switch secondResponsePart {
  58. case .some(.end(nil)):
  59. ()
  60. default:
  61. XCTFail("Unexpected response part: \(String(describing: secondResponsePart))")
  62. }
  63. }
  64. func testUnimplementedMethodReturnsUnimplementedStatus() throws {
  65. let requestHead = HTTPRequestHead(
  66. version: .init(major: 2, minor: 0),
  67. method: .POST,
  68. uri: "/foo/Bar",
  69. headers: ["content-type": "application/grpc"]
  70. )
  71. XCTAssertNoThrow(try self.channel.writeInbound(HTTPServerRequestPart.head(requestHead)))
  72. let firstResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  73. switch firstResponsePart {
  74. case .some(.head(let head)):
  75. XCTAssertEqual(head.status, .ok)
  76. XCTAssertEqual(head.headers.first(name: "grpc-status"), "\(GRPCStatus.Code.unimplemented.rawValue)")
  77. default:
  78. XCTFail("Unexpected response part: \(String(describing: firstResponsePart))")
  79. }
  80. let secondResponsePart = try self.channel.readOutbound(as: HTTPServerResponsePart.self)
  81. switch secondResponsePart {
  82. case .some(.end(nil)):
  83. ()
  84. default:
  85. XCTFail("Unexpected response part: \(String(describing: secondResponsePart))")
  86. }
  87. }
  88. func testImplementedMethodReconfiguresPipeline() throws {
  89. let requestHead = HTTPRequestHead(
  90. version: .init(major: 2, minor: 0),
  91. method: .POST,
  92. uri: "/echo.Echo/Get",
  93. headers: ["content-type": "application/grpc"]
  94. )
  95. XCTAssertNoThrow(try self.channel.writeInbound(HTTPServerRequestPart.head(requestHead)))
  96. // The router should be removed from the pipeline.
  97. let router = self.channel.pipeline.handler(type: GRPCServerRequestRoutingHandler.self)
  98. XCTAssertThrowsError(try router.wait())
  99. // There should now be a unary call handler.
  100. let unary = self.channel.pipeline.handler(type: UnaryCallHandler<Echo_EchoRequest, Echo_EchoResponse>.self)
  101. XCTAssertNoThrow(try unary.wait())
  102. }
  103. }