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() 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() 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 /** 192 * @expectedException InvalidArgumentException 193 */ 194 public function testInvalidClientMessageArray() 195 { 196 $deadline = Grpc\Timeval::infFuture(); 197 $req_text = 'client_server_full_request_response'; 198 $reply_text = 'reply:client_server_full_request_response'; 199 $status_text = 'status:client_server_full_response_text'; 200 201 $call = new Grpc\Call($this->channel, 202 'dummy_method', 203 $deadline); 204 205 $event = $call->startBatch([ 206 Grpc\OP_SEND_INITIAL_METADATA => [], 207 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 208 Grpc\OP_SEND_MESSAGE => 'invalid', 209 ]); 210 } 211 212 /** 213 * @expectedException InvalidArgumentException 214 */ 215 public function testInvalidClientMessageString() 216 { 217 $deadline = Grpc\Timeval::infFuture(); 218 $req_text = 'client_server_full_request_response'; 219 $reply_text = 'reply:client_server_full_request_response'; 220 $status_text = 'status:client_server_full_response_text'; 221 222 $call = new Grpc\Call($this->channel, 223 'dummy_method', 224 $deadline); 225 226 $event = $call->startBatch([ 227 Grpc\OP_SEND_INITIAL_METADATA => [], 228 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 229 Grpc\OP_SEND_MESSAGE => ['message' => 0], 230 ]); 231 } 232 233 /** 234 * @expectedException InvalidArgumentException 235 */ 236 public function testInvalidClientMessageFlags() 237 { 238 $deadline = Grpc\Timeval::infFuture(); 239 $req_text = 'client_server_full_request_response'; 240 $reply_text = 'reply:client_server_full_request_response'; 241 $status_text = 'status:client_server_full_response_text'; 242 243 $call = new Grpc\Call($this->channel, 244 'dummy_method', 245 $deadline); 246 247 $event = $call->startBatch([ 248 Grpc\OP_SEND_INITIAL_METADATA => [], 249 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 250 Grpc\OP_SEND_MESSAGE => ['message' => 'abc', 251 'flags' => 'invalid', 252 ], 253 ]); 254 } 255 256 /** 257 * @expectedException InvalidArgumentException 258 */ 259 public function testInvalidServerStatusMetadata() 260 { 261 $deadline = Grpc\Timeval::infFuture(); 262 $req_text = 'client_server_full_request_response'; 263 $reply_text = 'reply:client_server_full_request_response'; 264 $status_text = 'status:client_server_full_response_text'; 265 266 $call = new Grpc\Call($this->channel, 267 'dummy_method', 268 $deadline); 269 270 $event = $call->startBatch([ 271 Grpc\OP_SEND_INITIAL_METADATA => [], 272 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 273 Grpc\OP_SEND_MESSAGE => ['message' => $req_text], 274 ]); 275 276 $this->assertTrue($event->send_metadata); 277 $this->assertTrue($event->send_close); 278 $this->assertTrue($event->send_message); 279 280 $event = $this->server->requestCall(); 281 $this->assertSame('dummy_method', $event->method); 282 $server_call = $event->call; 283 284 $event = $server_call->startBatch([ 285 Grpc\OP_SEND_INITIAL_METADATA => [], 286 Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], 287 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 288 'metadata' => 'invalid', 289 'code' => Grpc\STATUS_OK, 290 'details' => $status_text, 291 ], 292 Grpc\OP_RECV_MESSAGE => true, 293 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 294 ]); 295 } 296 297 /** 298 * @expectedException InvalidArgumentException 299 */ 300 public function testInvalidServerStatusCode() 301 { 302 $deadline = Grpc\Timeval::infFuture(); 303 $req_text = 'client_server_full_request_response'; 304 $reply_text = 'reply:client_server_full_request_response'; 305 $status_text = 'status:client_server_full_response_text'; 306 307 $call = new Grpc\Call($this->channel, 308 'dummy_method', 309 $deadline); 310 311 $event = $call->startBatch([ 312 Grpc\OP_SEND_INITIAL_METADATA => [], 313 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 314 Grpc\OP_SEND_MESSAGE => ['message' => $req_text], 315 ]); 316 317 $this->assertTrue($event->send_metadata); 318 $this->assertTrue($event->send_close); 319 $this->assertTrue($event->send_message); 320 321 $event = $this->server->requestCall(); 322 $this->assertSame('dummy_method', $event->method); 323 $server_call = $event->call; 324 325 $event = $server_call->startBatch([ 326 Grpc\OP_SEND_INITIAL_METADATA => [], 327 Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], 328 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 329 'metadata' => [], 330 'code' => 'invalid', 331 'details' => $status_text, 332 ], 333 Grpc\OP_RECV_MESSAGE => true, 334 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 335 ]); 336 } 337 338 /** 339 * @expectedException InvalidArgumentException 340 */ 341 public function testMissingServerStatusCode() 342 { 343 $deadline = Grpc\Timeval::infFuture(); 344 $req_text = 'client_server_full_request_response'; 345 $reply_text = 'reply:client_server_full_request_response'; 346 $status_text = 'status:client_server_full_response_text'; 347 348 $call = new Grpc\Call($this->channel, 349 'dummy_method', 350 $deadline); 351 352 $event = $call->startBatch([ 353 Grpc\OP_SEND_INITIAL_METADATA => [], 354 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 355 Grpc\OP_SEND_MESSAGE => ['message' => $req_text], 356 ]); 357 358 $this->assertTrue($event->send_metadata); 359 $this->assertTrue($event->send_close); 360 $this->assertTrue($event->send_message); 361 362 $event = $this->server->requestCall(); 363 $this->assertSame('dummy_method', $event->method); 364 $server_call = $event->call; 365 366 $event = $server_call->startBatch([ 367 Grpc\OP_SEND_INITIAL_METADATA => [], 368 Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], 369 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 370 'metadata' => [], 371 'details' => $status_text, 372 ], 373 Grpc\OP_RECV_MESSAGE => true, 374 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 375 ]); 376 } 377 378 /** 379 * @expectedException InvalidArgumentException 380 */ 381 public function testInvalidServerStatusDetails() 382 { 383 $deadline = Grpc\Timeval::infFuture(); 384 $req_text = 'client_server_full_request_response'; 385 $reply_text = 'reply:client_server_full_request_response'; 386 $status_text = 'status:client_server_full_response_text'; 387 388 $call = new Grpc\Call($this->channel, 389 'dummy_method', 390 $deadline); 391 392 $event = $call->startBatch([ 393 Grpc\OP_SEND_INITIAL_METADATA => [], 394 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 395 Grpc\OP_SEND_MESSAGE => ['message' => $req_text], 396 ]); 397 398 $this->assertTrue($event->send_metadata); 399 $this->assertTrue($event->send_close); 400 $this->assertTrue($event->send_message); 401 402 $event = $this->server->requestCall(); 403 $this->assertSame('dummy_method', $event->method); 404 $server_call = $event->call; 405 406 $event = $server_call->startBatch([ 407 Grpc\OP_SEND_INITIAL_METADATA => [], 408 Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], 409 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 410 'metadata' => [], 411 'code' => Grpc\STATUS_OK, 412 'details' => 0, 413 ], 414 Grpc\OP_RECV_MESSAGE => true, 415 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 416 ]); 417 } 418 419 /** 420 * @expectedException InvalidArgumentException 421 */ 422 public function testMissingServerStatusDetails() 423 { 424 $deadline = Grpc\Timeval::infFuture(); 425 $req_text = 'client_server_full_request_response'; 426 $reply_text = 'reply:client_server_full_request_response'; 427 $status_text = 'status:client_server_full_response_text'; 428 429 $call = new Grpc\Call($this->channel, 430 'dummy_method', 431 $deadline); 432 433 $event = $call->startBatch([ 434 Grpc\OP_SEND_INITIAL_METADATA => [], 435 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 436 Grpc\OP_SEND_MESSAGE => ['message' => $req_text], 437 ]); 438 439 $this->assertTrue($event->send_metadata); 440 $this->assertTrue($event->send_close); 441 $this->assertTrue($event->send_message); 442 443 $event = $this->server->requestCall(); 444 $this->assertSame('dummy_method', $event->method); 445 $server_call = $event->call; 446 447 $event = $server_call->startBatch([ 448 Grpc\OP_SEND_INITIAL_METADATA => [], 449 Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], 450 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 451 'metadata' => [], 452 'code' => Grpc\STATUS_OK, 453 ], 454 Grpc\OP_RECV_MESSAGE => true, 455 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 456 ]); 457 } 458 459 /** 460 * @expectedException InvalidArgumentException 461 */ 462 public function testInvalidStartBatchKey() 463 { 464 $deadline = Grpc\Timeval::infFuture(); 465 $req_text = 'client_server_full_request_response'; 466 $reply_text = 'reply:client_server_full_request_response'; 467 $status_text = 'status:client_server_full_response_text'; 468 469 $call = new Grpc\Call($this->channel, 470 'dummy_method', 471 $deadline); 472 473 $event = $call->startBatch([ 474 9999999 => [], 475 ]); 476 } 477 478 /** 479 * @expectedException LogicException 480 */ 481 public function testInvalidStartBatch() 482 { 483 $deadline = Grpc\Timeval::infFuture(); 484 $req_text = 'client_server_full_request_response'; 485 $reply_text = 'reply:client_server_full_request_response'; 486 $status_text = 'status:client_server_full_response_text'; 487 488 $call = new Grpc\Call($this->channel, 489 'dummy_method', 490 $deadline); 491 492 $event = $call->startBatch([ 493 Grpc\OP_SEND_INITIAL_METADATA => [], 494 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 495 Grpc\OP_SEND_MESSAGE => ['message' => $req_text], 496 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 497 'metadata' => [], 498 'code' => Grpc\STATUS_OK, 499 'details' => 'abc', 500 ], 501 ]); 502 } 503 504 public function testGetTarget() 505 { 506 $this->assertTrue(is_string($this->channel->getTarget())); 507 } 508 509 public function testGetConnectivityState() 510 { 511 $this->assertTrue($this->channel->getConnectivityState() == 512 Grpc\CHANNEL_IDLE); 513 } 514 515 public function testWatchConnectivityStateFailed() 516 { 517 $idle_state = $this->channel->getConnectivityState(); 518 $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE); 519 520 $now = Grpc\Timeval::now(); 521 $delta = new Grpc\Timeval(50000); // should timeout 522 $deadline = $now->add($delta); 523 524 $this->assertFalse($this->channel->watchConnectivityState( 525 $idle_state, $deadline)); 526 } 527 528 public function testWatchConnectivityStateSuccess() 529 { 530 $idle_state = $this->channel->getConnectivityState(true); 531 $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE); 532 533 $now = Grpc\Timeval::now(); 534 $delta = new Grpc\Timeval(3000000); // should finish well before 535 $deadline = $now->add($delta); 536 537 $this->assertTrue($this->channel->watchConnectivityState( 538 $idle_state, $deadline)); 539 540 $new_state = $this->channel->getConnectivityState(); 541 $this->assertTrue($idle_state != $new_state); 542 } 543 544 public function testWatchConnectivityStateDoNothing() 545 { 546 $idle_state = $this->channel->getConnectivityState(); 547 $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE); 548 549 $now = Grpc\Timeval::now(); 550 $delta = new Grpc\Timeval(50000); 551 $deadline = $now->add($delta); 552 553 $this->assertFalse($this->channel->watchConnectivityState( 554 $idle_state, $deadline)); 555 556 $new_state = $this->channel->getConnectivityState(); 557 $this->assertTrue($new_state == Grpc\CHANNEL_IDLE); 558 } 559 560 /** 561 * @expectedException InvalidArgumentException 562 */ 563 public function testGetConnectivityStateInvalidParam() 564 { 565 $this->assertTrue($this->channel->getConnectivityState( 566 new Grpc\Timeval())); 567 } 568 569 /** 570 * @expectedException InvalidArgumentException 571 */ 572 public function testWatchConnectivityStateInvalidParam() 573 { 574 $this->assertTrue($this->channel->watchConnectivityState( 575 0, 1000)); 576 } 577 578 /** 579 * @expectedException InvalidArgumentException 580 */ 581 public function testChannelConstructorInvalidParam() 582 { 583 $this->channel = new Grpc\Channel('localhost:'.$this->port, null); 584 } 585 586 public function testClose() 587 { 588 $this->assertNull($this->channel->close()); 589 } 590} 591