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