@@ -44,13 +44,13 @@ let initialClientMetadata =
44
44
" x " : " xylophone " ,
45
45
" y " : " yu " ,
46
46
" z " : " zither "
47
- ]
47
+ ]
48
48
let initialServerMetadata =
49
49
[
50
50
" a " : " Apple " ,
51
51
" b " : " Banana " ,
52
52
" c " : " Cherry "
53
- ]
53
+ ]
54
54
let trailingServerMetadata =
55
55
[
56
56
// We have more than ten entries here to ensure that even large metadata entries work
@@ -68,11 +68,18 @@ let trailingServerMetadata =
68
68
" 10 " : " ten " ,
69
69
" 11 " : " eleven " ,
70
70
" 12 " : " twelve "
71
- ]
71
+ ]
72
72
let steps = 10
73
- let hello = " /hello "
74
- let statusCode = StatusCode . ok
75
- let statusMessage = " OK "
73
+ let hello = " /hello.unary "
74
+ let helloServerStream = " /hello.server-stream "
75
+ let helloBiDiStream = " /hello.bidi-stream "
76
+
77
+ // Return code/message for unary test
78
+ let oddStatusCode = StatusCode . ok
79
+ let oddStatusMessage = " OK "
80
+
81
+ let evenStatusCode = StatusCode . notFound
82
+ let eventStatusMessage = " Not Found "
76
83
77
84
func runTest( useSSL: Bool ) {
78
85
gRPC. initialize ( )
@@ -87,9 +94,9 @@ func runTest(useSSL: Bool) {
87
94
guard
88
95
let certificate = try ? String ( contentsOf: certificateURL, encoding: . utf8) ,
89
96
let key = try ? String ( contentsOf: keyURL, encoding: . utf8)
90
- else {
91
- // FIXME: We don't want tests to silently pass just because the certificates can't be loaded.
92
- return
97
+ else {
98
+ // FIXME: We don't want tests to silently pass just because the certificates can't be loaded.
99
+ return
93
100
}
94
101
server = Server ( address: address,
95
102
key: key,
@@ -135,15 +142,14 @@ func verify_metadata(_ metadata: Metadata, expected: [String: String], file: Sta
135
142
}
136
143
137
144
func runClient( useSSL: Bool ) throws {
138
- let message = clientText. data ( using: . utf8)
139
145
let channel : Channel
140
146
141
147
if useSSL {
142
148
let certificateURL = URL ( fileURLWithPath: " Tests/ssl.crt " )
143
149
guard
144
150
let certificates = try ? String ( contentsOf: certificateURL, encoding: . utf8)
145
- else {
146
- return
151
+ else {
152
+ return
147
153
}
148
154
let host = " example.com "
149
155
channel = Channel ( address: address, certificates: certificates, host: host)
@@ -152,26 +158,40 @@ func runClient(useSSL: Bool) throws {
152
158
}
153
159
154
160
channel. host = host
155
- for _ in 0 ..< steps {
161
+ try callUnary ( channel: channel)
162
+ try callServerStream ( channel: channel)
163
+ try callBiDiStream ( channel: channel)
164
+ }
165
+
166
+ func callUnary( channel: Channel ) throws {
167
+ let message = clientText. data ( using: . utf8)
168
+
169
+ for i in 0 ..< steps {
156
170
let sem = DispatchSemaphore ( value: 0 )
157
171
let method = hello
158
172
let call = channel. makeCall ( method)
159
173
let metadata = Metadata ( initialClientMetadata)
160
174
try call. start ( . unary, metadata: metadata, message: message) {
161
175
response in
162
176
// verify the basic response from the server
163
- XCTAssertEqual ( response. statusCode, statusCode)
164
- XCTAssertEqual ( response. statusMessage, statusMessage)
177
+ XCTAssertEqual ( response. statusCode, ( i % 2 == 0 ) ? evenStatusCode : oddStatusCode)
178
+ XCTAssertEqual ( response. statusMessage, ( i % 2 == 0 ) ? eventStatusMessage : oddStatusMessage)
179
+
165
180
// verify the message from the server
166
- let resultData = response. resultData!
167
- let messageString = String ( data: resultData, encoding: . utf8)
168
- XCTAssertEqual ( messageString, serverText)
181
+ if ( i % 2 ) == 0 {
182
+ let resultData = response. resultData!
183
+ let messageString = String ( data: resultData, encoding: . utf8)
184
+ XCTAssertEqual ( messageString, serverText)
185
+ }
186
+
169
187
// verify the initial metadata from the server
170
188
let initialMetadata = response. initialMetadata!
171
189
verify_metadata ( initialMetadata, expected: initialServerMetadata)
190
+
172
191
// verify the trailing metadata from the server
173
192
let trailingMetadata = response. trailingMetadata!
174
193
verify_metadata ( trailingMetadata, expected: trailingServerMetadata)
194
+
175
195
// report completion
176
196
sem. signal ( )
177
197
}
@@ -180,27 +200,111 @@ func runClient(useSSL: Bool) throws {
180
200
}
181
201
}
182
202
203
+ func callServerStream( channel: Channel ) throws {
204
+ let message = clientText. data ( using: . utf8)
205
+ let metadata = Metadata ( initialClientMetadata)
206
+
207
+ let sem = DispatchSemaphore ( value: 0 )
208
+ let method = helloServerStream
209
+ let call = channel. makeCall ( method)
210
+ try call. start ( . serverStreaming, metadata: metadata, message: message) {
211
+ response in
212
+
213
+ XCTAssertEqual ( response. statusCode, StatusCode . outOfRange)
214
+ XCTAssertEqual ( response. statusMessage, " Out of range " )
215
+
216
+ // verify the trailing metadata from the server
217
+ let trailingMetadata = response. trailingMetadata!
218
+ verify_metadata ( trailingMetadata, expected: trailingServerMetadata)
219
+
220
+ sem. signal ( ) // signal call is finished
221
+ }
222
+
223
+ for _ in 0 ..< steps {
224
+ let messageSem = DispatchSemaphore ( value: 0 )
225
+ try call. receiveMessage ( completion: { ( data) in
226
+ if let data = data {
227
+ let messageString = String ( data: data, encoding: . utf8)
228
+ XCTAssertEqual ( messageString, serverText)
229
+ }
230
+ messageSem. signal ( )
231
+ } )
232
+
233
+ _ = messageSem. wait ( )
234
+ }
235
+
236
+ _ = sem. wait ( )
237
+ }
238
+
239
+ let clientPing = " ping "
240
+ let serverPong = " pong "
241
+
242
+ func callBiDiStream( channel: Channel ) throws {
243
+ let message = clientPing. data ( using: . utf8)
244
+ let metadata = Metadata ( initialClientMetadata)
245
+
246
+ let sem = DispatchSemaphore ( value: 0 )
247
+ let method = helloBiDiStream
248
+ let call = channel. makeCall ( method)
249
+ try call. start ( . bidiStreaming, metadata: metadata, message: message) {
250
+ response in
251
+
252
+ XCTAssertEqual ( response. statusCode, StatusCode . resourceExhausted)
253
+ XCTAssertEqual ( response. statusMessage, " Resource Exhausted " )
254
+
255
+ // verify the trailing metadata from the server
256
+ let trailingMetadata = response. trailingMetadata!
257
+ verify_metadata ( trailingMetadata, expected: trailingServerMetadata)
258
+
259
+ sem. signal ( ) // signal call is finished
260
+ }
261
+
262
+ // Send pings
263
+ for _ in 0 ..< steps {
264
+ let pingSem = DispatchSemaphore ( value: 0 )
265
+ let message = clientPing. data ( using: . utf8)
266
+ try call. sendMessage ( data: message!) { ( err) in
267
+ XCTAssertNil ( err)
268
+ pingSem. signal ( )
269
+ }
270
+ _ = pingSem. wait ( )
271
+ }
272
+
273
+ // Receive pongs
274
+ for _ in 0 ..< steps {
275
+ let pongSem = DispatchSemaphore ( value: 0 )
276
+ try call. receiveMessage ( completion: { ( data) in
277
+ if let data = data {
278
+ let messageString = String ( data: data, encoding: . utf8)
279
+ XCTAssertEqual ( messageString, serverPong)
280
+ }
281
+ pongSem. signal ( )
282
+ } )
283
+ _ = pongSem. wait ( )
284
+ }
285
+
286
+ _ = sem. wait ( )
287
+ }
288
+
183
289
func runServer( server: Server ) throws {
184
290
var requestCount = 0
185
291
let sem = DispatchSemaphore ( value: 0 )
186
292
server. run { requestHandler in
187
293
do {
188
- requestCount += 1
189
- XCTAssertEqual ( requestHandler. host, host)
190
- XCTAssertEqual ( requestHandler. method, hello)
191
- let initialMetadata = requestHandler. requestMetadata
192
- verify_metadata ( initialMetadata, expected: initialClientMetadata)
193
- let initialMetadataToSend = Metadata ( initialServerMetadata)
194
- try requestHandler. receiveMessage ( initialMetadata: initialMetadataToSend) { messageData in
195
- let messageString = String ( data: messageData!, encoding: . utf8)
196
- XCTAssertEqual ( messageString, clientText)
294
+ if let method = requestHandler. method {
295
+ switch method {
296
+ case hello:
297
+ try handleUnary ( requestHandler: requestHandler, requestCount: requestCount)
298
+ case helloServerStream:
299
+ try handleServerStream ( requestHandler: requestHandler)
300
+ case helloBiDiStream:
301
+ try handleBiDiStream ( requestHandler: requestHandler)
302
+ default :
303
+ XCTFail ( " Invalid method \( method) " )
304
+ }
197
305
}
198
- let replyMessage = serverText
199
- let trailingMetadataToSend = Metadata ( trailingServerMetadata)
200
- try requestHandler. sendResponse ( message: replyMessage. data ( using: . utf8) !,
201
- statusCode: statusCode,
202
- statusMessage: statusMessage,
203
- trailingMetadata: trailingMetadataToSend)
306
+
307
+ requestCount += 1
204
308
} catch ( let error) {
205
309
XCTFail ( " error \( error) " )
206
310
}
@@ -212,3 +316,97 @@ func runServer(server: Server) throws {
212
316
// wait for the server to exit
213
317
_ = sem. wait ( )
214
318
}
319
+
320
+ func handleUnary( requestHandler: Handler , requestCount: Int ) throws {
321
+ XCTAssertEqual ( requestHandler. host, host)
322
+ XCTAssertEqual ( requestHandler. method, hello)
323
+ let initialMetadata = requestHandler. requestMetadata
324
+ verify_metadata ( initialMetadata, expected: initialClientMetadata)
325
+ let initialMetadataToSend = Metadata ( initialServerMetadata)
326
+ try requestHandler. receiveMessage ( initialMetadata: initialMetadataToSend) { messageData in
327
+ let messageString = String ( data: messageData!, encoding: . utf8)
328
+ XCTAssertEqual ( messageString, clientText)
329
+ }
330
+
331
+ if ( requestCount % 2 ) == 0 {
332
+ let replyMessage = serverText
333
+ let trailingMetadataToSend = Metadata ( trailingServerMetadata)
334
+ try requestHandler. sendResponse ( message: replyMessage. data ( using: . utf8) !,
335
+ statusCode: evenStatusCode,
336
+ statusMessage: eventStatusMessage,
337
+ trailingMetadata: trailingMetadataToSend)
338
+ } else {
339
+ let trailingMetadataToSend = Metadata ( trailingServerMetadata)
340
+ try requestHandler. sendResponse ( statusCode: oddStatusCode,
341
+ statusMessage: oddStatusMessage,
342
+ trailingMetadata: trailingMetadataToSend)
343
+ }
344
+ }
345
+
346
+ func handleServerStream( requestHandler: Handler ) throws {
347
+ XCTAssertEqual ( requestHandler. host, host)
348
+ XCTAssertEqual ( requestHandler. method, helloServerStream)
349
+ let initialMetadata = requestHandler. requestMetadata
350
+ verify_metadata ( initialMetadata, expected: initialClientMetadata)
351
+
352
+ let initialMetadataToSend = Metadata ( initialServerMetadata)
353
+ try requestHandler. receiveMessage ( initialMetadata: initialMetadataToSend) { messageData in
354
+ let messageString = String ( data: messageData!, encoding: . utf8)
355
+ XCTAssertEqual ( messageString, clientText)
356
+ }
357
+
358
+ let replyMessage = serverText
359
+ for _ in 0 ..< steps {
360
+ let sendSem = DispatchSemaphore ( value: 0 )
361
+ try requestHandler. sendResponse ( message: replyMessage. data ( using: . utf8) !, completion: { ( error) in
362
+ XCTAssertNil ( error)
363
+ sendSem. signal ( )
364
+ } )
365
+ _ = sendSem. wait ( )
366
+ }
367
+
368
+ let trailingMetadataToSend = Metadata ( trailingServerMetadata)
369
+ try requestHandler. sendStatus ( statusCode: StatusCode . outOfRange,
370
+ statusMessage: " Out of range " ,
371
+ trailingMetadata: trailingMetadataToSend)
372
+ }
373
+
374
+ func handleBiDiStream( requestHandler: Handler ) throws {
375
+ XCTAssertEqual ( requestHandler. host, host)
376
+ XCTAssertEqual ( requestHandler. method, helloBiDiStream)
377
+ let initialMetadata = requestHandler. requestMetadata
378
+ verify_metadata ( initialMetadata, expected: initialClientMetadata)
379
+
380
+ let initialMetadataToSend = Metadata ( initialServerMetadata)
381
+ try requestHandler. receiveMessage ( initialMetadata: initialMetadataToSend) { messageData in
382
+ let messageString = String ( data: messageData!, encoding: . utf8)
383
+ XCTAssertEqual ( messageString, clientPing)
384
+ }
385
+
386
+ // Receive remaining pings
387
+ for _ in 0 ..< steps- 1 {
388
+ let receiveSem = DispatchSemaphore ( value: 0 )
389
+ try requestHandler. receiveMessage ( completion: { ( data) in
390
+ let messageString = String ( data: data!, encoding: . utf8)
391
+ XCTAssertEqual ( messageString, clientPing)
392
+ receiveSem. signal ( )
393
+ } )
394
+ _ = receiveSem. wait ( )
395
+ }
396
+
397
+ // Send back pongs
398
+ let replyMessage = serverPong. data ( using: . utf8) !
399
+ for _ in 0 ..< steps {
400
+ let sendSem = DispatchSemaphore ( value: 0 )
401
+ try requestHandler. sendResponse ( message: replyMessage, completion: { ( error) in
402
+ XCTAssertNil ( error)
403
+ sendSem. signal ( )
404
+ } )
405
+ _ = sendSem. wait ( )
406
+ }
407
+
408
+ let trailingMetadataToSend = Metadata ( trailingServerMetadata)
409
+ try requestHandler. sendStatus ( statusCode: StatusCode . resourceExhausted,
410
+ statusMessage: " Resource Exhausted " ,
411
+ trailingMetadata: trailingMetadataToSend)
412
+ }
0 commit comments