• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?php
2/*
3 *
4 * Copyright 2015 gRPC authors.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19class EndToEndTest extends \PHPUnit\Framework\TestCase
20{
21    public function setUp(): void
22    {
23        $this->server = new Grpc\Server([]);
24        $this->port = $this->server->addHttp2Port('0.0.0.0:0');
25        $this->channel = new Grpc\Channel('localhost:'.$this->port, [
26            "force_new" => true,
27        ]);
28        $this->server->start();
29    }
30
31    public function tearDown(): void
32    {
33        $this->channel->close();
34        unset($this->server);
35    }
36
37    public function testSimpleRequestBody()
38    {
39        $deadline = Grpc\Timeval::infFuture();
40        $status_text = 'xyz';
41        $call = new Grpc\Call($this->channel,
42                              'dummy_method',
43                              $deadline);
44
45        $event = $call->startBatch([
46            Grpc\OP_SEND_INITIAL_METADATA => [],
47            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
48        ]);
49
50        $this->assertTrue($event->send_metadata);
51        $this->assertTrue($event->send_close);
52
53        $event = $this->server->requestCall();
54        $this->assertSame('dummy_method', $event->method);
55        $server_call = $event->call;
56
57        $event = $server_call->startBatch([
58            Grpc\OP_SEND_INITIAL_METADATA => [],
59            Grpc\OP_SEND_STATUS_FROM_SERVER => [
60                'metadata' => [],
61                'code' => Grpc\STATUS_OK,
62                'details' => $status_text,
63            ],
64            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
65        ]);
66
67        $this->assertTrue($event->send_metadata);
68        $this->assertTrue($event->send_status);
69        $this->assertFalse($event->cancelled);
70
71        $event = $call->startBatch([
72            Grpc\OP_RECV_INITIAL_METADATA => true,
73            Grpc\OP_RECV_STATUS_ON_CLIENT => true,
74        ]);
75
76        $status = $event->status;
77        $this->assertSame([], $status->metadata);
78        $this->assertSame(Grpc\STATUS_OK, $status->code);
79        $this->assertSame($status_text, $status->details);
80
81        unset($call);
82        unset($server_call);
83    }
84
85    public function testMessageWriteFlags()
86    {
87        $deadline = Grpc\Timeval::infFuture();
88        $req_text = 'message_write_flags_test';
89        $status_text = 'xyz';
90        $call = new Grpc\Call($this->channel,
91                              'dummy_method',
92                              $deadline);
93
94        $event = $call->startBatch([
95            Grpc\OP_SEND_INITIAL_METADATA => [],
96            Grpc\OP_SEND_MESSAGE => ['message' => $req_text,
97                                     'flags' => Grpc\WRITE_NO_COMPRESS, ],
98            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
99        ]);
100
101        $this->assertTrue($event->send_metadata);
102        $this->assertTrue($event->send_close);
103
104        $event = $this->server->requestCall();
105        $this->assertSame('dummy_method', $event->method);
106        $server_call = $event->call;
107
108        $event = $server_call->startBatch([
109            Grpc\OP_SEND_INITIAL_METADATA => [],
110            Grpc\OP_SEND_STATUS_FROM_SERVER => [
111                'metadata' => [],
112                'code' => Grpc\STATUS_OK,
113                'details' => $status_text,
114            ],
115        ]);
116
117        $event = $call->startBatch([
118            Grpc\OP_RECV_INITIAL_METADATA => true,
119            Grpc\OP_RECV_STATUS_ON_CLIENT => true,
120        ]);
121
122        $status = $event->status;
123        $this->assertSame([], $status->metadata);
124        $this->assertSame(Grpc\STATUS_OK, $status->code);
125        $this->assertSame($status_text, $status->details);
126
127        unset($call);
128        unset($server_call);
129    }
130
131    public function testClientServerFullRequestResponse()
132    {
133        $deadline = Grpc\Timeval::infFuture();
134        $req_text = 'client_server_full_request_response';
135        $reply_text = 'reply:client_server_full_request_response';
136        $status_text = 'status:client_server_full_response_text';
137
138        $call = new Grpc\Call($this->channel,
139                              'dummy_method',
140                              $deadline);
141
142        $event = $call->startBatch([
143            Grpc\OP_SEND_INITIAL_METADATA => [],
144            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
145            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
146        ]);
147
148        $this->assertTrue($event->send_metadata);
149        $this->assertTrue($event->send_close);
150        $this->assertTrue($event->send_message);
151
152        $event = $this->server->requestCall();
153        $this->assertSame('dummy_method', $event->method);
154        $server_call = $event->call;
155
156        $event = $server_call->startBatch([
157            Grpc\OP_SEND_INITIAL_METADATA => [],
158            Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
159            Grpc\OP_SEND_STATUS_FROM_SERVER => [
160                'metadata' => [],
161                'code' => Grpc\STATUS_OK,
162                'details' => $status_text,
163            ],
164            Grpc\OP_RECV_MESSAGE => true,
165            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
166        ]);
167
168        $this->assertTrue($event->send_metadata);
169        $this->assertTrue($event->send_status);
170        $this->assertTrue($event->send_message);
171        $this->assertFalse($event->cancelled);
172        $this->assertSame($req_text, $event->message);
173
174        $event = $call->startBatch([
175            Grpc\OP_RECV_INITIAL_METADATA => true,
176            Grpc\OP_RECV_MESSAGE => true,
177            Grpc\OP_RECV_STATUS_ON_CLIENT => true,
178        ]);
179
180        $this->assertSame([], $event->metadata);
181        $this->assertSame($reply_text, $event->message);
182        $status = $event->status;
183        $this->assertSame([], $status->metadata);
184        $this->assertSame(Grpc\STATUS_OK, $status->code);
185        $this->assertSame($status_text, $status->details);
186
187        unset($call);
188        unset($server_call);
189    }
190
191    public function testInvalidClientMessageArray()
192    {
193        $this->expectException(\InvalidArgumentException::class);
194        $deadline = Grpc\Timeval::infFuture();
195        $req_text = 'client_server_full_request_response';
196        $reply_text = 'reply:client_server_full_request_response';
197        $status_text = 'status:client_server_full_response_text';
198
199        $call = new Grpc\Call($this->channel,
200                              'dummy_method',
201                              $deadline);
202
203        $event = $call->startBatch([
204            Grpc\OP_SEND_INITIAL_METADATA => [],
205            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
206            Grpc\OP_SEND_MESSAGE => 'invalid',
207        ]);
208    }
209
210    public function testInvalidClientMessageString()
211    {
212        $this->expectException(\InvalidArgumentException::class);
213        $deadline = Grpc\Timeval::infFuture();
214        $req_text = 'client_server_full_request_response';
215        $reply_text = 'reply:client_server_full_request_response';
216        $status_text = 'status:client_server_full_response_text';
217
218        $call = new Grpc\Call($this->channel,
219                              'dummy_method',
220                              $deadline);
221
222        $event = $call->startBatch([
223            Grpc\OP_SEND_INITIAL_METADATA => [],
224            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
225            Grpc\OP_SEND_MESSAGE => ['message' => 0],
226        ]);
227    }
228
229    public function testInvalidClientMessageFlags()
230    {
231        $this->expectException(\InvalidArgumentException::class);
232        $deadline = Grpc\Timeval::infFuture();
233        $req_text = 'client_server_full_request_response';
234        $reply_text = 'reply:client_server_full_request_response';
235        $status_text = 'status:client_server_full_response_text';
236
237        $call = new Grpc\Call($this->channel,
238                              'dummy_method',
239                              $deadline);
240
241        $event = $call->startBatch([
242            Grpc\OP_SEND_INITIAL_METADATA => [],
243            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
244            Grpc\OP_SEND_MESSAGE => ['message' => 'abc',
245                                     'flags' => 'invalid',
246                                     ],
247        ]);
248    }
249
250    public function testInvalidServerStatusMetadata()
251    {
252        $this->expectException(\InvalidArgumentException::class);
253        $deadline = Grpc\Timeval::infFuture();
254        $req_text = 'client_server_full_request_response';
255        $reply_text = 'reply:client_server_full_request_response';
256        $status_text = 'status:client_server_full_response_text';
257
258        $call = new Grpc\Call($this->channel,
259                              'dummy_method',
260                              $deadline);
261
262        $event = $call->startBatch([
263            Grpc\OP_SEND_INITIAL_METADATA => [],
264            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
265            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
266        ]);
267
268        $this->assertTrue($event->send_metadata);
269        $this->assertTrue($event->send_close);
270        $this->assertTrue($event->send_message);
271
272        $event = $this->server->requestCall();
273        $this->assertSame('dummy_method', $event->method);
274        $server_call = $event->call;
275
276        $event = $server_call->startBatch([
277            Grpc\OP_SEND_INITIAL_METADATA => [],
278            Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
279            Grpc\OP_SEND_STATUS_FROM_SERVER => [
280                'metadata' => 'invalid',
281                'code' => Grpc\STATUS_OK,
282                'details' => $status_text,
283            ],
284            Grpc\OP_RECV_MESSAGE => true,
285            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
286        ]);
287    }
288
289    public function testInvalidServerStatusCode()
290    {
291        $this->expectException(\InvalidArgumentException::class);
292        $deadline = Grpc\Timeval::infFuture();
293        $req_text = 'client_server_full_request_response';
294        $reply_text = 'reply:client_server_full_request_response';
295        $status_text = 'status:client_server_full_response_text';
296
297        $call = new Grpc\Call($this->channel,
298                              'dummy_method',
299                              $deadline);
300
301        $event = $call->startBatch([
302            Grpc\OP_SEND_INITIAL_METADATA => [],
303            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
304            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
305        ]);
306
307        $this->assertTrue($event->send_metadata);
308        $this->assertTrue($event->send_close);
309        $this->assertTrue($event->send_message);
310
311        $event = $this->server->requestCall();
312        $this->assertSame('dummy_method', $event->method);
313        $server_call = $event->call;
314
315        $event = $server_call->startBatch([
316            Grpc\OP_SEND_INITIAL_METADATA => [],
317            Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
318            Grpc\OP_SEND_STATUS_FROM_SERVER => [
319                'metadata' => [],
320                'code' => 'invalid',
321                'details' => $status_text,
322            ],
323            Grpc\OP_RECV_MESSAGE => true,
324            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
325        ]);
326    }
327
328    public function testMissingServerStatusCode()
329    {
330        $this->expectException(\InvalidArgumentException::class);
331        $deadline = Grpc\Timeval::infFuture();
332        $req_text = 'client_server_full_request_response';
333        $reply_text = 'reply:client_server_full_request_response';
334        $status_text = 'status:client_server_full_response_text';
335
336        $call = new Grpc\Call($this->channel,
337                              'dummy_method',
338                              $deadline);
339
340        $event = $call->startBatch([
341            Grpc\OP_SEND_INITIAL_METADATA => [],
342            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
343            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
344        ]);
345
346        $this->assertTrue($event->send_metadata);
347        $this->assertTrue($event->send_close);
348        $this->assertTrue($event->send_message);
349
350        $event = $this->server->requestCall();
351        $this->assertSame('dummy_method', $event->method);
352        $server_call = $event->call;
353
354        $event = $server_call->startBatch([
355            Grpc\OP_SEND_INITIAL_METADATA => [],
356            Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
357            Grpc\OP_SEND_STATUS_FROM_SERVER => [
358                'metadata' => [],
359                'details' => $status_text,
360            ],
361            Grpc\OP_RECV_MESSAGE => true,
362            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
363        ]);
364    }
365
366    public function testInvalidServerStatusDetails()
367    {
368        $this->expectException(\InvalidArgumentException::class);
369        $deadline = Grpc\Timeval::infFuture();
370        $req_text = 'client_server_full_request_response';
371        $reply_text = 'reply:client_server_full_request_response';
372        $status_text = 'status:client_server_full_response_text';
373
374        $call = new Grpc\Call($this->channel,
375                              'dummy_method',
376                              $deadline);
377
378        $event = $call->startBatch([
379            Grpc\OP_SEND_INITIAL_METADATA => [],
380            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
381            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
382        ]);
383
384        $this->assertTrue($event->send_metadata);
385        $this->assertTrue($event->send_close);
386        $this->assertTrue($event->send_message);
387
388        $event = $this->server->requestCall();
389        $this->assertSame('dummy_method', $event->method);
390        $server_call = $event->call;
391
392        $event = $server_call->startBatch([
393            Grpc\OP_SEND_INITIAL_METADATA => [],
394            Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
395            Grpc\OP_SEND_STATUS_FROM_SERVER => [
396                'metadata' => [],
397                'code' => Grpc\STATUS_OK,
398                'details' => 0,
399            ],
400            Grpc\OP_RECV_MESSAGE => true,
401            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
402        ]);
403    }
404
405    public function testMissingServerStatusDetails()
406    {
407        $this->expectException(\InvalidArgumentException::class);
408        $deadline = Grpc\Timeval::infFuture();
409        $req_text = 'client_server_full_request_response';
410        $reply_text = 'reply:client_server_full_request_response';
411        $status_text = 'status:client_server_full_response_text';
412
413        $call = new Grpc\Call($this->channel,
414                              'dummy_method',
415                              $deadline);
416
417        $event = $call->startBatch([
418            Grpc\OP_SEND_INITIAL_METADATA => [],
419            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
420            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
421        ]);
422
423        $this->assertTrue($event->send_metadata);
424        $this->assertTrue($event->send_close);
425        $this->assertTrue($event->send_message);
426
427        $event = $this->server->requestCall();
428        $this->assertSame('dummy_method', $event->method);
429        $server_call = $event->call;
430
431        $event = $server_call->startBatch([
432            Grpc\OP_SEND_INITIAL_METADATA => [],
433            Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
434            Grpc\OP_SEND_STATUS_FROM_SERVER => [
435                'metadata' => [],
436                'code' => Grpc\STATUS_OK,
437            ],
438            Grpc\OP_RECV_MESSAGE => true,
439            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
440        ]);
441    }
442
443    public function testInvalidStartBatchKey()
444    {
445        $this->expectException(\InvalidArgumentException::class);
446        $deadline = Grpc\Timeval::infFuture();
447        $req_text = 'client_server_full_request_response';
448        $reply_text = 'reply:client_server_full_request_response';
449        $status_text = 'status:client_server_full_response_text';
450
451        $call = new Grpc\Call($this->channel,
452                              'dummy_method',
453                              $deadline);
454
455        $event = $call->startBatch([
456            9999999 => [],
457        ]);
458    }
459
460    public function testInvalidStartBatch()
461    {
462        $this->expectException(\LogicException::class);
463        $deadline = Grpc\Timeval::infFuture();
464        $req_text = 'client_server_full_request_response';
465        $reply_text = 'reply:client_server_full_request_response';
466        $status_text = 'status:client_server_full_response_text';
467
468        $call = new Grpc\Call($this->channel,
469                              'dummy_method',
470                              $deadline);
471
472        $event = $call->startBatch([
473            Grpc\OP_SEND_INITIAL_METADATA => [],
474            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
475            Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
476            Grpc\OP_SEND_STATUS_FROM_SERVER => [
477                'metadata' => [],
478                'code' => Grpc\STATUS_OK,
479                'details' => 'abc',
480            ],
481        ]);
482    }
483
484    public function testGetTarget()
485    {
486        $this->assertTrue(is_string($this->channel->getTarget()));
487    }
488
489    public function testGetConnectivityState()
490    {
491        $this->assertTrue($this->channel->getConnectivityState() ==
492                          Grpc\CHANNEL_IDLE);
493    }
494
495    public function testWatchConnectivityStateFailed()
496    {
497        $idle_state = $this->channel->getConnectivityState();
498        $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
499
500        $now = Grpc\Timeval::now();
501        $delta = new Grpc\Timeval(50000); // should timeout
502        $deadline = $now->add($delta);
503
504        $this->assertFalse($this->channel->watchConnectivityState(
505        $idle_state, $deadline));
506    }
507
508    public function testWatchConnectivityStateSuccess()
509    {
510        $idle_state = $this->channel->getConnectivityState(true);
511        $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
512
513        $now = Grpc\Timeval::now();
514        $delta = new Grpc\Timeval(3000000); // should finish well before
515        $deadline = $now->add($delta);
516
517        $this->assertTrue($this->channel->watchConnectivityState(
518        $idle_state, $deadline));
519
520        $new_state = $this->channel->getConnectivityState();
521        $this->assertTrue($idle_state != $new_state);
522    }
523
524    public function testWatchConnectivityStateDoNothing()
525    {
526        $idle_state = $this->channel->getConnectivityState();
527        $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
528
529        $now = Grpc\Timeval::now();
530        $delta = new Grpc\Timeval(50000);
531        $deadline = $now->add($delta);
532
533        $this->assertFalse($this->channel->watchConnectivityState(
534        $idle_state, $deadline));
535
536        $new_state = $this->channel->getConnectivityState();
537        $this->assertTrue($new_state == Grpc\CHANNEL_IDLE);
538    }
539
540    public function testGetConnectivityStateInvalidParam()
541    {
542        $this->expectException(\InvalidArgumentException::class);
543        $this->assertTrue($this->channel->getConnectivityState(
544            new Grpc\Timeval()));
545    }
546
547    public function testWatchConnectivityStateInvalidParam()
548    {
549        $this->expectException(\InvalidArgumentException::class);
550        $this->assertTrue($this->channel->watchConnectivityState(
551            0, 1000));
552    }
553
554    public function testChannelConstructorInvalidParam()
555    {
556        $this->expectException(\InvalidArgumentException::class);
557        $this->channel = new Grpc\Channel('localhost:'.$this->port, null);
558    }
559
560    public function testClose()
561    {
562        $this->assertNull($this->channel->close());
563    }
564}
565