GRPCTests.swift 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright 2017, 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 XCTest
  17. import Foundation
  18. import Dispatch
  19. @testable import gRPC
  20. class gRPCTests: XCTestCase {
  21. func testConnectivity() {
  22. runTest(useSSL:false)
  23. }
  24. func testConnectivitySecure() {
  25. runTest(useSSL:true)
  26. }
  27. }
  28. extension gRPCTests {
  29. static var allTests : [(String, (gRPCTests) -> () throws -> Void)] {
  30. return [
  31. ("testConnectivity", testConnectivity),
  32. ("testConnectivitySecure", testConnectivitySecure),
  33. ]
  34. }
  35. }
  36. let address = "localhost:8085"
  37. let host = "example.com"
  38. let clientText = "hello, server!"
  39. let serverText = "hello, client!"
  40. let initialClientMetadata =
  41. ["x": "xylophone",
  42. "y": "yu",
  43. "z": "zither"]
  44. let initialServerMetadata =
  45. ["a": "Apple",
  46. "b": "Banana",
  47. "c": "Cherry"]
  48. let trailingServerMetadata =
  49. ["0": "zero",
  50. "1": "one",
  51. "2": "two"]
  52. let steps = 10
  53. let hello = "/hello"
  54. let statusCode = 0
  55. let statusMessage = "OK"
  56. func runTest(useSSL: Bool) {
  57. gRPC.initialize()
  58. let serverRunningSemaphore = DispatchSemaphore(value: 0)
  59. // create the server
  60. var server : gRPC.Server!
  61. if useSSL {
  62. let certificateURL = URL(fileURLWithPath:"Tests/ssl.crt")
  63. let keyURL = URL(fileURLWithPath:"Tests/ssl.key")
  64. guard
  65. let certificate = try? String(contentsOf: certificateURL, encoding: .utf8),
  66. let key = try? String(contentsOf: keyURL, encoding: .utf8)
  67. else {
  68. return
  69. }
  70. server = gRPC.Server(address:address,
  71. key:key,
  72. certs:certificate)
  73. } else {
  74. server = gRPC.Server(address:address)
  75. }
  76. // start the server
  77. DispatchQueue.global().async() {
  78. do {
  79. try runServer(server:server)
  80. } catch (let error) {
  81. XCTFail("server error \(error)")
  82. }
  83. serverRunningSemaphore.signal() // when the server exits, the test is finished
  84. }
  85. // run the client
  86. do {
  87. try runClient(useSSL:useSSL)
  88. } catch (let error) {
  89. XCTFail("client error \(error)")
  90. }
  91. // stop the server
  92. server.stop()
  93. // wait until the server has shut down
  94. _ = serverRunningSemaphore.wait(timeout: DispatchTime.distantFuture)
  95. }
  96. func verify_metadata(_ metadata: Metadata, expected: [String:String]) {
  97. XCTAssertGreaterThanOrEqual(metadata.count(), expected.count)
  98. for i in 0..<metadata.count() {
  99. if expected[metadata.key(i)] != nil {
  100. XCTAssertEqual(metadata.value(i), expected[metadata.key(i)])
  101. }
  102. }
  103. }
  104. func runClient(useSSL: Bool) throws {
  105. let message = clientText.data(using: .utf8)
  106. var channel : gRPC.Channel!
  107. if useSSL {
  108. let certificateURL = URL(fileURLWithPath:"Tests/ssl.crt")
  109. guard
  110. let certificates = try? String(contentsOf: certificateURL, encoding: .utf8)
  111. else {
  112. return
  113. }
  114. let host = "example.com"
  115. channel = gRPC.Channel(address:address, certificates:certificates, host:host)
  116. } else {
  117. channel = gRPC.Channel(address:address)
  118. }
  119. channel.host = host
  120. for i in 0..<steps {
  121. let sem = DispatchSemaphore(value: 0)
  122. let method = hello
  123. let call = channel.makeCall(method)
  124. let metadata = Metadata(initialClientMetadata)
  125. try call.start(.unary, metadata:metadata, message:message) {
  126. (response) in
  127. // verify the basic response from the server
  128. XCTAssertEqual(response.statusCode, statusCode)
  129. XCTAssertEqual(response.statusMessage, statusMessage)
  130. // verify the message from the server
  131. let resultData = response.resultData
  132. let messageString = String(data: resultData!, encoding: .utf8)
  133. XCTAssertEqual(messageString, serverText)
  134. // verify the initial metadata from the server
  135. let initialMetadata = response.initialMetadata!
  136. verify_metadata(initialMetadata, expected: initialServerMetadata)
  137. // verify the trailing metadata from the server
  138. let trailingMetadata = response.trailingMetadata!
  139. verify_metadata(trailingMetadata, expected: trailingServerMetadata)
  140. // report completion
  141. sem.signal()
  142. }
  143. // wait for the call to complete
  144. _ = sem.wait(timeout: DispatchTime.distantFuture)
  145. }
  146. }
  147. func runServer(server: gRPC.Server) throws {
  148. var requestCount = 0
  149. let sem = DispatchSemaphore(value: 0)
  150. server.run() {(requestHandler) in
  151. do {
  152. requestCount += 1
  153. XCTAssertEqual(requestHandler.host, host)
  154. XCTAssertEqual(requestHandler.method, hello)
  155. let initialMetadata = requestHandler.requestMetadata
  156. verify_metadata(initialMetadata, expected: initialClientMetadata)
  157. let initialMetadataToSend = Metadata(initialServerMetadata)
  158. try requestHandler.receiveMessage(initialMetadata:initialMetadataToSend)
  159. {(messageData) in
  160. let messageString = String(data: messageData!, encoding: .utf8)
  161. XCTAssertEqual(messageString, clientText)
  162. }
  163. let replyMessage = serverText
  164. let trailingMetadataToSend = Metadata(trailingServerMetadata)
  165. try requestHandler.sendResponse(message:replyMessage.data(using: .utf8)!,
  166. statusCode:statusCode,
  167. statusMessage:statusMessage,
  168. trailingMetadata:trailingMetadataToSend)
  169. } catch (let error) {
  170. XCTFail("error \(error)")
  171. }
  172. }
  173. server.onCompletion() {
  174. // return from runServer()
  175. sem.signal()
  176. }
  177. // wait for the server to exit
  178. _ = sem.wait(timeout: DispatchTime.distantFuture)
  179. }