GRPCChannelHandlerResponseCapturingTestCase.swift 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import Foundation
  2. import NIO
  3. import NIOHTTP1
  4. @testable import SwiftGRPCNIO
  5. import XCTest
  6. class CollectingChannelHandler<OutboundIn>: ChannelOutboundHandler {
  7. var responses: [OutboundIn] = []
  8. func write(ctx: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise<Void>?) {
  9. responses.append(unwrapOutboundIn(data))
  10. }
  11. }
  12. class CollectingServerErrorDelegate: ServerErrorDelegate {
  13. var errors: [Error] = []
  14. func observe(_ error: Error) {
  15. self.errors.append(error)
  16. }
  17. }
  18. class GRPCChannelHandlerResponseCapturingTestCase: XCTestCase {
  19. static let echoProvider: [String: CallHandlerProvider] = ["echo.Echo": EchoProvider_NIO()]
  20. class var defaultServiceProvider: [String: CallHandlerProvider] {
  21. return echoProvider
  22. }
  23. func configureChannel(withHandlers handlers: [ChannelHandler]) -> EventLoopFuture<EmbeddedChannel> {
  24. let channel = EmbeddedChannel()
  25. return channel.pipeline.addHandlers(handlers, first: true)
  26. .map { _ in channel }
  27. }
  28. var errorCollector: CollectingServerErrorDelegate = CollectingServerErrorDelegate()
  29. /// Waits for `count` responses to be collected and then returns them. The test fails if the number
  30. /// of collected responses does not match the expected.
  31. ///
  32. /// - Parameters:
  33. /// - count: expected number of responses.
  34. /// - servicesByName: service providers keyed by their service name.
  35. /// - callback: a callback called after the channel has been setup, intended to "fill" the channel
  36. /// with messages. The callback is called before this function returns.
  37. /// - Returns: The responses collected from the pipeline.
  38. func waitForGRPCChannelHandlerResponses(
  39. count: Int,
  40. servicesByName: [String: CallHandlerProvider] = defaultServiceProvider,
  41. callback: @escaping (EmbeddedChannel) throws -> Void
  42. ) throws -> [RawGRPCServerResponsePart] {
  43. let collector = CollectingChannelHandler<RawGRPCServerResponsePart>()
  44. try configureChannel(withHandlers: [collector, GRPCChannelHandler(servicesByName: servicesByName, errorDelegate: errorCollector)])
  45. .thenThrowing(callback)
  46. .wait()
  47. XCTAssertEqual(count, collector.responses.count)
  48. return collector.responses
  49. }
  50. }