GRPCTests.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import XCTest
  2. import Foundation
  3. import Dispatch
  4. @testable import gRPC
  5. func Log(_ message : String) {
  6. FileHandle.standardError.write((message + "\n").data(using:.utf8)!)
  7. }
  8. class gRPCTests: XCTestCase {
  9. var count : Int = 0
  10. func testBasicSanity() {
  11. gRPC.initialize()
  12. let done = NSCondition()
  13. self.count = 2
  14. DispatchQueue.global().async() {
  15. server()
  16. Log("server finished")
  17. done.lock()
  18. self.count = self.count - 1
  19. done.signal()
  20. done.unlock()
  21. }
  22. DispatchQueue.global().async() {
  23. client()
  24. Log("client finished")
  25. done.lock()
  26. self.count = self.count - 1
  27. done.signal()
  28. done.unlock()
  29. }
  30. var running = true
  31. while (running) {
  32. Log("waiting")
  33. done.lock()
  34. done.wait()
  35. if (self.count == 0) {
  36. running = false
  37. }
  38. Log("count \(self.count)")
  39. done.unlock()
  40. }
  41. }
  42. }
  43. extension gRPCTests {
  44. static var allTests : [(String, (gRPCTests) -> () throws -> Void)] {
  45. return [
  46. ("testBasicSanity", testBasicSanity),
  47. ]
  48. }
  49. }
  50. let address = "localhost:8999"
  51. let host = "foo.test.google.fr"
  52. let clientText = "hello, server!"
  53. let serverText = "hello, client!"
  54. let initialClientMetadata =
  55. ["x": "xylophone",
  56. "y": "yu",
  57. "z": "zither"]
  58. let initialServerMetadata =
  59. ["a": "Apple",
  60. "b": "Banana",
  61. "c": "Cherry"]
  62. let trailingServerMetadata =
  63. ["0": "zero",
  64. "1": "one",
  65. "2": "two"]
  66. let steps = 30
  67. let hello = "/hello"
  68. let goodbye = "/goodbye"
  69. let statusCode = 0
  70. let statusMessage = "OK"
  71. func verify_metadata(_ metadata: Metadata, expected: [String:String]) {
  72. XCTAssertGreaterThanOrEqual(metadata.count(), expected.count)
  73. for i in 0..<metadata.count() {
  74. if expected[metadata.key(i)] != nil {
  75. XCTAssertEqual(metadata.value(i), expected[metadata.key(i)])
  76. }
  77. }
  78. }
  79. func client() {
  80. let message = clientText.data(using: .utf8)
  81. let c = gRPC.Channel(address:address)
  82. c.host = host
  83. let done = NSCondition()
  84. var running = true
  85. for i in 0..<steps {
  86. var call : Call
  87. do {
  88. let method = (i < steps-1) ? hello : goodbye
  89. call = c.makeCall(method)
  90. let metadata = Metadata(initialClientMetadata)
  91. try call.start(.unary, metadata:metadata, message:message) {
  92. (response) in
  93. // verify the basic response from the server
  94. XCTAssertEqual(response.statusCode, statusCode)
  95. XCTAssertEqual(response.statusMessage, statusMessage)
  96. // verify the message from the server
  97. let resultData = response.resultData
  98. let messageString = String(data: resultData!, encoding: .utf8)
  99. XCTAssertEqual(messageString, serverText)
  100. // verify the initial metadata from the server
  101. let initialMetadata = response.initialMetadata!
  102. verify_metadata(initialMetadata, expected: initialServerMetadata)
  103. // verify the trailing metadata from the server
  104. let trailingMetadata = response.trailingMetadata!
  105. verify_metadata(trailingMetadata, expected: trailingServerMetadata)
  106. done.lock()
  107. running = false
  108. done.signal()
  109. done.unlock()
  110. }
  111. } catch (let error) {
  112. XCTFail("error \(error)")
  113. }
  114. // wait for the call to complete
  115. var finished = false
  116. while (!finished) {
  117. done.lock()
  118. done.wait()
  119. if (!running) {
  120. finished = true
  121. }
  122. done.unlock()
  123. }
  124. Log("finished client call \(i)")
  125. }
  126. Log("client done")
  127. }
  128. func server() {
  129. let server = gRPC.Server(address:address)
  130. var requestCount = 0
  131. let done = NSCondition()
  132. var running = true
  133. server.run() {(requestHandler) in
  134. do {
  135. requestCount += 1
  136. XCTAssertEqual(requestHandler.host, host)
  137. if (requestCount < steps) {
  138. XCTAssertEqual(requestHandler.method, hello)
  139. } else {
  140. XCTAssertEqual(requestHandler.method, goodbye)
  141. }
  142. let initialMetadata = requestHandler.requestMetadata
  143. verify_metadata(initialMetadata, expected: initialClientMetadata)
  144. let initialMetadataToSend = Metadata(initialServerMetadata)
  145. try requestHandler.receiveMessage(initialMetadata:initialMetadataToSend)
  146. {(messageData) in
  147. let messageString = String(data: messageData!, encoding: .utf8)
  148. XCTAssertEqual(messageString, clientText)
  149. }
  150. if requestHandler.method == goodbye {
  151. server.stop()
  152. }
  153. let replyMessage = serverText
  154. let trailingMetadataToSend = Metadata(trailingServerMetadata)
  155. try requestHandler.sendResponse(message:replyMessage.data(using: .utf8)!,
  156. statusCode:statusCode,
  157. statusMessage:statusMessage,
  158. trailingMetadata:trailingMetadataToSend)
  159. } catch (let error) {
  160. XCTFail("error \(error)")
  161. }
  162. }
  163. server.onCompletion() {
  164. // exit the server thread
  165. Log("signaling completion")
  166. done.lock()
  167. running = false
  168. done.signal()
  169. done.unlock()
  170. }
  171. // wait for the server to exit
  172. var finished = false
  173. while !finished {
  174. done.lock()
  175. done.wait()
  176. if (!running) {
  177. finished = true
  178. }
  179. done.unlock()
  180. }
  181. Log("server done")
  182. }