GRPCTests.swift 5.9 KB

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