1<?php 2/* 3 * 4 * Copyright 2018 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 */ 19 20class ChannelTest extends \PHPUnit\Framework\TestCase 21{ 22 private $channel; 23 private $channel1; 24 private $channel2; 25 private $channel3; 26 27 public function setUp(): void 28 { 29 } 30 31 public function tearDown(): void 32 { 33 foreach ([$this->channel, $this->channel1, $this->channel2, $this->channel3] as $channel) 34 if (!empty($channel)) { 35 $channel->close(); 36 } 37 } 38 39 public function testInsecureCredentials() 40 { 41 $this->channel = new Grpc\Channel('localhost:50000', 42 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 43 $this->assertSame('Grpc\Channel', get_class($this->channel)); 44 } 45 46 public function testConstructorCreateSsl() 47 { 48 $channel = new Grpc\Channel('localhost:50033', 49 ['credentials' => \Grpc\ChannelCredentials::createSsl()]); 50 $this->assertNotNull($channel); 51 } 52 53 public function testCreateXdsWithSsl() 54 { 55 $xdsCreds = \Grpc\ChannelCredentials::createXds( 56 \Grpc\ChannelCredentials::createSsl() 57 ); 58 $this->assertNotNull($xdsCreds); 59 } 60 61 public function disabled_testCreateXdsWithInsecure() { 62 $xdsCreds = \Grpc\ChannelCredentials::createXds( 63 \Grpc\ChannelCredentials::createInsecure() 64 ); 65 $this->assertNotNull($xdsCreds); 66 } 67 68 public function testCreateXdsWithNull() { 69 $this->expectException(\InvalidArgumentException::class); 70 $xdsCreds = \Grpc\ChannelCredentials::createXds(null); 71 } 72 73 public function testCreateXdsWithInvalidType() 74 { 75 $expected = $this->logicalOr( 76 // PHP8 77 new \PHPUnit\Framework\Constraint\Exception(\InvalidArgumentException::class), 78 // PHP7 79 new \PHPUnit\Framework\Constraint\Exception(\TypeError::class) 80 ); 81 try { 82 $xdsCreds = \Grpc\ChannelCredentials::createXds("invalid-type"); 83 } catch (\Throwable $exception) { 84 $this->assertThat($exception, $expected); 85 return; 86 } 87 $this->assertThat(null, $expected); 88 } 89 90 public function testGetConnectivityState() 91 { 92 $this->channel = new Grpc\Channel('localhost:50001', 93 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 94 $state = $this->channel->getConnectivityState(); 95 $this->assertEquals(0, $state); 96 } 97 98 public function testGetConnectivityStateWithInt() 99 { 100 $this->channel = new Grpc\Channel('localhost:50002', 101 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 102 $state = $this->channel->getConnectivityState(123); 103 $this->assertEquals(0, $state); 104 } 105 106 public function testGetConnectivityStateWithString() 107 { 108 $this->channel = new Grpc\Channel('localhost:50003', 109 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 110 $state = $this->channel->getConnectivityState('hello'); 111 $this->assertEquals(0, $state); 112 } 113 114 public function testGetConnectivityStateWithBool() 115 { 116 $this->channel = new Grpc\Channel('localhost:50004', 117 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 118 $state = $this->channel->getConnectivityState(true); 119 $this->assertEquals(0, $state); 120 } 121 122 public function testGetTarget() 123 { 124 $this->channel = new Grpc\Channel('localhost:50005', 125 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 126 $target = $this->channel->getTarget(); 127 $this->assertTrue(is_string($target)); 128 } 129 130 public function testWatchConnectivityState() 131 { 132 $this->channel = new Grpc\Channel('localhost:50006', 133 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 134 $now = Grpc\Timeval::now(); 135 $deadline = $now->add(new Grpc\Timeval(100*1000)); // 100ms 136 // we act as if 'CONNECTING'(=1) was the last state 137 // we saw, so the default state of 'IDLE' should be delivered instantly 138 $state = $this->channel->watchConnectivityState(1, $deadline); 139 $this->assertTrue($state); 140 unset($now); 141 unset($deadline); 142 } 143 144 public function testClose() 145 { 146 $this->channel = new Grpc\Channel('localhost:50007', 147 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 148 $this->assertNotNull($this->channel); 149 $this->channel->close(); 150 } 151 152 public function testInvalidConstructorWithNull() 153 { 154 $this->expectException(\InvalidArgumentException::class); 155 $this->channel = new Grpc\Channel(); 156 $this->assertNull($this->channel); 157 } 158 159 public function testInvalidConstructorWith() 160 { 161 $this->expectException(\InvalidArgumentException::class); 162 $this->channel = new Grpc\Channel('localhost:50008', 'invalid'); 163 $this->assertNull($this->channel); 164 } 165 166 public function testInvalidCredentials() 167 { 168 $this->expectException(\InvalidArgumentException::class); 169 $this->channel = new Grpc\Channel('localhost:50009', 170 ['credentials' => new Grpc\Timeval(100)]); 171 } 172 173 public function testInvalidOptionsArray() 174 { 175 $this->expectException(\InvalidArgumentException::class); 176 $this->channel = new Grpc\Channel('localhost:50010', 177 ['abc' => []]); 178 } 179 180 public function testInvalidGetConnectivityStateWithArray() 181 { 182 $this->expectException(\InvalidArgumentException::class); 183 $this->channel = new Grpc\Channel('localhost:50011', 184 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 185 $this->channel->getConnectivityState([]); 186 } 187 188 public function testInvalidWatchConnectivityState() 189 { 190 $this->expectException(\InvalidArgumentException::class); 191 $this->channel = new Grpc\Channel('localhost:50012', 192 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 193 $this->channel->watchConnectivityState([]); 194 } 195 196 public function testInvalidWatchConnectivityState2() 197 { 198 $this->expectException(\InvalidArgumentException::class); 199 $this->channel = new Grpc\Channel('localhost:50013', 200 ['credentials' => Grpc\ChannelCredentials::createInsecure()]); 201 $this->channel->watchConnectivityState(1, 'hi'); 202 } 203 204 205 public function assertConnecting($state) { 206 $this->assertTrue($state == GRPC\CHANNEL_CONNECTING || 207 $state == GRPC\CHANNEL_TRANSIENT_FAILURE); 208 } 209 210 public function waitUntilNotIdle($channel) { 211 for ($i = 0; $i < 10; $i++) { 212 $now = Grpc\Timeval::now(); 213 $deadline = $now->add(new Grpc\Timeval(1000)); 214 if ($channel->watchConnectivityState(GRPC\CHANNEL_IDLE, 215 $deadline)) { 216 return true; 217 } 218 } 219 $this->assertTrue(false); 220 } 221 222 public function testPersistentChannelSameHost() 223 { 224 $this->channel1 = new Grpc\Channel('localhost:50014', [ 225 "grpc_target_persist_bound" => 3, 226 ]); 227 // the underlying grpc channel is the same by default 228 // when connecting to the same host 229 $this->channel2 = new Grpc\Channel('localhost:50014', []); 230 231 // both channels should be IDLE 232 $state = $this->channel1->getConnectivityState(); 233 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 234 $state = $this->channel2->getConnectivityState(); 235 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 236 237 // try to connect on channel1 238 $state = $this->channel1->getConnectivityState(true); 239 $this->waitUntilNotIdle($this->channel1); 240 241 // both channels should now be in the CONNECTING state 242 $state = $this->channel1->getConnectivityState(); 243 $this->assertConnecting($state); 244 $state = $this->channel2->getConnectivityState(); 245 $this->assertConnecting($state); 246 247 $this->channel1->close(); 248 $this->channel2->close(); 249 } 250 251 public function testPersistentChannelDifferentHost() 252 { 253 // two different underlying channels because different hostname 254 $this->channel1 = new Grpc\Channel('localhost:50015', [ 255 "grpc_target_persist_bound" => 3, 256 ]); 257 $this->channel2 = new Grpc\Channel('localhost:50016', []); 258 259 // both channels should be IDLE 260 $state = $this->channel1->getConnectivityState(); 261 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 262 $state = $this->channel2->getConnectivityState(); 263 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 264 265 // try to connect on channel1 266 $state = $this->channel1->getConnectivityState(true); 267 $this->waitUntilNotIdle($this->channel1); 268 269 // channel1 should now be in the CONNECTING state 270 $state = $this->channel1->getConnectivityState(); 271 $this->assertConnecting($state); 272 // channel2 should still be in the IDLE state 273 $state = $this->channel2->getConnectivityState(); 274 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 275 276 $this->channel1->close(); 277 $this->channel2->close(); 278 } 279 280 public function testPersistentChannelSameArgs() 281 { 282 $this->channel1 = new Grpc\Channel('localhost:50017', [ 283 "grpc_target_persist_bound" => 3, 284 "abc" => "def", 285 ]); 286 $this->channel2 = new Grpc\Channel('localhost:50017', ["abc" => "def"]); 287 288 // try to connect on channel1 289 $state = $this->channel1->getConnectivityState(true); 290 $this->waitUntilNotIdle($this->channel1); 291 292 $state = $this->channel1->getConnectivityState(); 293 $this->assertConnecting($state); 294 $state = $this->channel2->getConnectivityState(); 295 $this->assertConnecting($state); 296 297 $this->channel1->close(); 298 $this->channel2->close(); 299 } 300 301 public function testPersistentChannelDifferentArgs() 302 { 303 $this->channel1 = new Grpc\Channel('localhost:50018', [ 304 "grpc_target_persist_bound" => 3, 305 ]); 306 $this->channel2 = new Grpc\Channel('localhost:50018', ["abc" => "def"]); 307 308 // try to connect on channel1 309 $state = $this->channel1->getConnectivityState(true); 310 $this->waitUntilNotIdle($this->channel1); 311 312 $state = $this->channel1->getConnectivityState(); 313 $this->assertConnecting($state); 314 $state = $this->channel2->getConnectivityState(); 315 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 316 317 $this->channel1->close(); 318 $this->channel2->close(); 319 } 320 321 public function persistentChannelSameChannelCredentialsProvider(): array 322 { 323 return [ 324 [ 325 Grpc\ChannelCredentials::createSsl(), 326 Grpc\ChannelCredentials::createSsl(), 327 50301, 328 ], 329 [ 330 Grpc\ChannelCredentials::createSsl( 331 file_get_contents(dirname(__FILE__) . '/../data/ca.pem') 332 ), 333 Grpc\ChannelCredentials::createSsl( 334 file_get_contents(dirname(__FILE__) . '/../data/ca.pem') 335 ), 336 50302, 337 ], 338 [ 339 Grpc\ChannelCredentials::createInSecure(), 340 Grpc\ChannelCredentials::createInSecure(), 341 50303, 342 ], 343 [ 344 \Grpc\ChannelCredentials::createXds( 345 \Grpc\ChannelCredentials::createSsl() 346 ), 347 \Grpc\ChannelCredentials::createXds( 348 \Grpc\ChannelCredentials::createSsl() 349 ), 350 50304, 351 ], 352 [ 353 \Grpc\ChannelCredentials::createXds( 354 \Grpc\ChannelCredentials::createSsl() 355 ), 356 \Grpc\ChannelCredentials::createXds( 357 \Grpc\ChannelCredentials::createSsl() 358 ), 359 50305, 360 ], 361 [ 362 \Grpc\ChannelCredentials::createXds( 363 \Grpc\ChannelCredentials::createSsl( 364 file_get_contents(dirname(__FILE__) . '/../data/ca.pem') 365 ) 366 ), 367 \Grpc\ChannelCredentials::createXds( 368 \Grpc\ChannelCredentials::createSsl( 369 file_get_contents(dirname(__FILE__) . '/../data/ca.pem') 370 ) 371 ), 372 50306, 373 ], 374 /* 375 [ 376 \Grpc\ChannelCredentials::createXds( 377 \Grpc\ChannelCredentials::createInSecure() 378 ), 379 \Grpc\ChannelCredentials::createXds( 380 \Grpc\ChannelCredentials::createInSecure() 381 ), 382 50307, 383 ], 384 */ 385 ]; 386 } 387 388 /** 389 * @dataProvider persistentChannelSameChannelCredentialsProvider 390 */ 391 public function testPersistentChannelSameChannelCredentials( 392 $creds1, 393 $creds2, 394 $port 395 ) { 396 $this->channel1 = new Grpc\Channel( 397 'localhost:' . $port, 398 [ 399 "credentials" => $creds1, 400 "grpc_target_persist_bound" => 3, 401 ] 402 ); 403 $this->channel2 = new Grpc\Channel( 404 'localhost:' . $port, 405 ["credentials" => $creds2] 406 ); 407 408 // try to connect on channel1 409 $state = $this->channel1->getConnectivityState(true); 410 $this->waitUntilNotIdle($this->channel1); 411 412 $state = $this->channel1->getConnectivityState(); 413 $this->assertConnecting($state); 414 $state = $this->channel2->getConnectivityState(); 415 $this->assertConnecting($state); 416 417 $this->channel1->close(); 418 $this->channel2->close(); 419 } 420 421 public function persistentChannelDifferentChannelCredentialsProvider(): array 422 { 423 return [ 424 [ 425 Grpc\ChannelCredentials::createSsl(), 426 Grpc\ChannelCredentials::createSsl( 427 file_get_contents(dirname(__FILE__) . '/../data/ca.pem') 428 ), 429 50351, 430 ], 431 [ 432 Grpc\ChannelCredentials::createSsl(), 433 Grpc\ChannelCredentials::createInsecure(), 434 50352, 435 ], 436 [ 437 \Grpc\ChannelCredentials::createXds( 438 \Grpc\ChannelCredentials::createSsl() 439 ), 440 \Grpc\ChannelCredentials::createXds( 441 \Grpc\ChannelCredentials::createSsl( 442 file_get_contents(dirname(__FILE__) . '/../data/ca.pem') 443 ) 444 ), 445 50353, 446 ], 447 /* 448 [ 449 \Grpc\ChannelCredentials::createXds( 450 \Grpc\ChannelCredentials::createSsl() 451 ), 452 \Grpc\ChannelCredentials::createXds( 453 \Grpc\ChannelCredentials::createInsecure() 454 ), 455 50354, 456 ], 457 [ 458 \Grpc\ChannelCredentials::createInsecure(), 459 \Grpc\ChannelCredentials::createXds( 460 \Grpc\ChannelCredentials::createInsecure() 461 ), 462 50355, 463 ], 464 */ 465 [ 466 \Grpc\ChannelCredentials::createSsl(), 467 \Grpc\ChannelCredentials::createXds( 468 \Grpc\ChannelCredentials::createSsl() 469 ), 470 50356, 471 ], 472 ]; 473 } 474 475 /** 476 * @dataProvider persistentChannelDifferentChannelCredentialsProvider 477 */ 478 public function testPersistentChannelDifferentChannelCredentials( 479 $creds1, 480 $creds2, 481 $port 482 ) { 483 484 $this->channel1 = new Grpc\Channel( 485 'localhost:' . $port, 486 [ 487 "credentials" => $creds1, 488 "grpc_target_persist_bound" => 3, 489 ] 490 ); 491 $this->channel2 = new Grpc\Channel( 492 'localhost:' . $port, 493 ["credentials" => $creds2] 494 ); 495 496 // try to connect on channel1 497 $state = $this->channel1->getConnectivityState(true); 498 $this->waitUntilNotIdle($this->channel1); 499 500 $state = $this->channel1->getConnectivityState(); 501 $this->assertConnecting($state); 502 $state = $this->channel2->getConnectivityState(); 503 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 504 505 $this->channel1->close(); 506 $this->channel2->close(); 507 } 508 509 public function testPersistentChannelSharedChannelClose1() 510 { 511 // same underlying channel 512 $this->channel1 = new Grpc\Channel('localhost:50123', [ 513 "grpc_target_persist_bound" => 3, 514 ]); 515 $this->channel2 = new Grpc\Channel('localhost:50123', []); 516 517 // close channel1 518 $this->channel1->close(); 519 520 // channel2 can still be use. We need to exclude the possible that 521 // in testPersistentChannelSharedChannelClose2, the exception is thrown 522 // by channel1. 523 $state = $this->channel2->getConnectivityState(); 524 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 525 } 526 527 public function testPersistentChannelSharedChannelClose2() 528 { 529 $this->expectException(\RuntimeException::class); 530 // same underlying channel 531 $this->channel1 = new Grpc\Channel('localhost:50223', [ 532 "grpc_target_persist_bound" => 3, 533 ]); 534 $this->channel2 = new Grpc\Channel('localhost:50223', []); 535 536 // close channel1 537 $this->channel1->close(); 538 539 // channel2 can still be use 540 $state = $this->channel2->getConnectivityState(); 541 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 542 543 // channel 1 is closed 544 $state = $this->channel1->getConnectivityState(); 545 } 546 547 public function testPersistentChannelCreateAfterClose() 548 { 549 $this->channel1 = new Grpc\Channel('localhost:50024', [ 550 "grpc_target_persist_bound" => 3, 551 ]); 552 553 $this->channel1->close(); 554 555 $this->channel2 = new Grpc\Channel('localhost:50024', []); 556 $state = $this->channel2->getConnectivityState(); 557 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 558 559 $this->channel2->close(); 560 } 561 562 public function testPersistentChannelSharedMoreThanTwo() 563 { 564 $this->channel1 = new Grpc\Channel('localhost:50025', [ 565 "grpc_target_persist_bound" => 3, 566 ]); 567 $this->channel2 = new Grpc\Channel('localhost:50025', []); 568 $this->channel3 = new Grpc\Channel('localhost:50025', []); 569 570 // try to connect on channel1 571 $state = $this->channel1->getConnectivityState(true); 572 $this->waitUntilNotIdle($this->channel1); 573 574 // all 3 channels should be in CONNECTING state 575 $state = $this->channel1->getConnectivityState(); 576 $this->assertConnecting($state); 577 $state = $this->channel2->getConnectivityState(); 578 $this->assertConnecting($state); 579 $state = $this->channel3->getConnectivityState(); 580 $this->assertConnecting($state); 581 582 $this->channel1->close(); 583 } 584 585 public function callbackFunc($context) 586 { 587 return []; 588 } 589 590 public function callbackFunc2($context) 591 { 592 return ["k1" => "v1"]; 593 } 594 595 public function testPersistentChannelWithCallCredentials() 596 { 597 $creds = Grpc\ChannelCredentials::createSsl(); 598 $callCreds = Grpc\CallCredentials::createFromPlugin( 599 [$this, 'callbackFunc']); 600 $credsWithCallCreds = Grpc\ChannelCredentials::createComposite( 601 $creds, $callCreds); 602 603 // If a ChannelCredentials object is composed with a 604 // CallCredentials object, the underlying grpc channel will 605 // always be created new and NOT persisted. 606 $this->channel1 = new Grpc\Channel('localhost:50026', 607 ["credentials" => 608 $credsWithCallCreds, 609 "grpc_target_persist_bound" => 3, 610 ]); 611 $this->channel2 = new Grpc\Channel('localhost:50026', 612 ["credentials" => 613 $credsWithCallCreds]); 614 615 // try to connect on channel1 616 $state = $this->channel1->getConnectivityState(true); 617 $this->waitUntilNotIdle($this->channel1); 618 619 $state = $this->channel1->getConnectivityState(); 620 $this->assertConnecting($state); 621 $state = $this->channel2->getConnectivityState(); 622 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 623 624 $this->channel1->close(); 625 $this->channel2->close(); 626 } 627 628 public function testPersistentChannelWithDifferentCallCredentials() 629 { 630 $callCreds1 = Grpc\CallCredentials::createFromPlugin( 631 [$this, 'callbackFunc']); 632 $callCreds2 = Grpc\CallCredentials::createFromPlugin( 633 [$this, 'callbackFunc2']); 634 635 $creds1 = Grpc\ChannelCredentials::createSsl(); 636 $creds2 = Grpc\ChannelCredentials::createComposite( 637 $creds1, $callCreds1); 638 $creds3 = Grpc\ChannelCredentials::createComposite( 639 $creds1, $callCreds2); 640 641 // Similar to the test above, anytime a ChannelCredentials 642 // object is composed with a CallCredentials object, the 643 // underlying grpc channel will always be separate and not 644 // persisted 645 $this->channel1 = new Grpc\Channel('localhost:50027', 646 ["credentials" => $creds1, 647 "grpc_target_persist_bound" => 3, 648 ]); 649 $this->channel2 = new Grpc\Channel('localhost:50027', 650 ["credentials" => $creds2]); 651 $this->channel3 = new Grpc\Channel('localhost:50027', 652 ["credentials" => $creds3]); 653 654 // try to connect on channel1 655 $state = $this->channel1->getConnectivityState(true); 656 $this->waitUntilNotIdle($this->channel1); 657 658 $state = $this->channel1->getConnectivityState(); 659 $this->assertConnecting($state); 660 $state = $this->channel2->getConnectivityState(); 661 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 662 $state = $this->channel3->getConnectivityState(); 663 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 664 665 $this->channel1->close(); 666 $this->channel2->close(); 667 $this->channel3->close(); 668 } 669 670 public function testPersistentChannelForceNew() 671 { 672 $this->channel1 = new Grpc\Channel('localhost:50028', [ 673 "grpc_target_persist_bound" => 2, 674 ]); 675 // even though all the channel params are the same, channel2 676 // has a new and different underlying channel 677 $this->channel2 = new Grpc\Channel('localhost:50028', 678 ["force_new" => true]); 679 680 // try to connect on channel1 681 $state = $this->channel1->getConnectivityState(true); 682 $this->waitUntilNotIdle($this->channel1); 683 684 $state = $this->channel1->getConnectivityState(); 685 $this->assertConnecting($state); 686 $state = $this->channel2->getConnectivityState(); 687 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 688 689 $this->channel1->close(); 690 $this->channel2->close(); 691 } 692 693 public function testPersistentChannelForceNewOldChannelIdle1() 694 { 695 696 $this->channel1 = new Grpc\Channel('localhost:50029', [ 697 "grpc_target_persist_bound" => 2, 698 ]); 699 $this->channel2 = new Grpc\Channel('localhost:50029', 700 ["force_new" => true]); 701 // channel3 shares with channel1 702 $this->channel3 = new Grpc\Channel('localhost:50029', []); 703 704 // try to connect on channel2 705 $state = $this->channel2->getConnectivityState(true); 706 $this->waitUntilNotIdle($this->channel2); 707 $state = $this->channel1->getConnectivityState(); 708 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 709 $state = $this->channel2->getConnectivityState(); 710 $this->assertConnecting($state); 711 $state = $this->channel3->getConnectivityState(); 712 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 713 714 $this->channel1->close(); 715 $this->channel2->close(); 716 } 717 718 public function testPersistentChannelForceNewOldChannelIdle2() 719 { 720 721 $this->channel1 = new Grpc\Channel('localhost:50032', [ 722 "grpc_target_persist_bound" => 2, 723 ]); 724 $this->channel2 = new Grpc\Channel('localhost:50032', []); 725 726 // try to connect on channel2 727 $state = $this->channel1->getConnectivityState(true); 728 $this->waitUntilNotIdle($this->channel2); 729 $state = $this->channel1->getConnectivityState(); 730 $this->assertConnecting($state); 731 $state = $this->channel2->getConnectivityState(); 732 $this->assertConnecting($state); 733 734 $this->channel1->close(); 735 $this->channel2->close(); 736 } 737 738 public function testPersistentChannelForceNewOldChannelClose1() 739 { 740 741 $this->channel1 = new Grpc\Channel('localhost:50130', [ 742 "grpc_target_persist_bound" => 2, 743 ]); 744 $this->channel2 = new Grpc\Channel('localhost:50130', 745 ["force_new" => true]); 746 // channel3 shares with channel1 747 $this->channel3 = new Grpc\Channel('localhost:50130', []); 748 749 $this->channel1->close(); 750 751 $state = $this->channel2->getConnectivityState(); 752 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 753 754 // channel3 is still usable. We need to exclude the possibility that in 755 // testPersistentChannelForceNewOldChannelClose2, the exception is thrown 756 // by channel1 and channel2. 757 $state = $this->channel3->getConnectivityState(); 758 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 759 } 760 761 public function testPersistentChannelForceNewOldChannelClose2() 762 { 763 $this->expectException(\RuntimeException::class); 764 $this->channel1 = new Grpc\Channel('localhost:50230', [ 765 "grpc_target_persist_bound" => 2, 766 ]); 767 $this->channel2 = new Grpc\Channel('localhost:50230', 768 ["force_new" => true]); 769 // channel3 shares with channel1 770 $this->channel3 = new Grpc\Channel('localhost:50230', []); 771 772 $this->channel1->close(); 773 774 $state = $this->channel2->getConnectivityState(); 775 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 776 777 // channel3 is still usable 778 $state = $this->channel3->getConnectivityState(); 779 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 780 781 // channel 1 is closed 782 $this->channel1->getConnectivityState(); 783 } 784 785 public function testPersistentChannelForceNewNewChannelClose() 786 { 787 788 $this->channel1 = new Grpc\Channel('localhost:50031', [ 789 "grpc_target_persist_bound" => 2, 790 ]); 791 $this->channel2 = new Grpc\Channel('localhost:50031', 792 ["force_new" => true]); 793 $this->channel3 = new Grpc\Channel('localhost:50031', []); 794 795 $this->channel2->close(); 796 797 $state = $this->channel1->getConnectivityState(); 798 $this->assertEquals(GRPC\CHANNEL_IDLE, $state); 799 800 // can still connect on channel1 801 $state = $this->channel1->getConnectivityState(true); 802 $this->waitUntilNotIdle($this->channel1); 803 804 $state = $this->channel1->getConnectivityState(); 805 $this->assertConnecting($state); 806 807 $this->channel1->close(); 808 } 809} 810