Home | History | Annotate | Download | only in unit_tests
      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 /**
     20  * Interface exported by the server.
     21  */
     22 require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php');
     23 require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php');
     24 require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php');
     25 require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php');
     26 require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php');
     27 require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php');
     28 require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php');
     29 
     30 class SimpleRequest
     31 {
     32     private $data;
     33     public function __construct($data)
     34     {
     35         $this->data = $data;
     36     }
     37     public function setData($data)
     38     {
     39         $this->data = $data;
     40     }
     41     public function serializeToString()
     42     {
     43         return $this->data;
     44     }
     45 }
     46 
     47 class InterceptorClient extends Grpc\BaseStub
     48 {
     49 
     50     /**
     51      * @param string $hostname hostname
     52      * @param array $opts channel options
     53      * @param Channel|InterceptorChannel $channel (optional) re-use channel object
     54      */
     55     public function __construct($hostname, $opts, $channel = null)
     56     {
     57         parent::__construct($hostname, $opts, $channel);
     58     }
     59 
     60     /**
     61      * A simple RPC.
     62      * @param SimpleRequest $argument input argument
     63      * @param array $metadata metadata
     64      * @param array $options call options
     65      */
     66     public function UnaryCall(
     67         SimpleRequest $argument,
     68         $metadata = [],
     69         $options = []
     70     ) {
     71         return $this->_simpleRequest(
     72             '/dummy_method',
     73             $argument,
     74             [],
     75             $metadata,
     76             $options
     77         );
     78     }
     79 
     80     /**
     81      * A client-to-server streaming RPC.
     82      * @param array $metadata metadata
     83      * @param array $options call options
     84      */
     85     public function StreamCall(
     86         $metadata = [],
     87         $options = []
     88     ) {
     89         return $this->_clientStreamRequest('/dummy_method', [], $metadata, $options);
     90     }
     91 }
     92 
     93 
     94 class ChangeMetadataInterceptor extends Grpc\Interceptor
     95 {
     96     public function interceptUnaryUnary($method,
     97                                         $argument,
     98                                         $deserialize,
     99                                         array $metadata = [],
    100                                         array $options = [],
    101                                         $continuation)
    102     {
    103         $metadata["foo"] = array('interceptor_from_unary_request');
    104         return $continuation($method, $argument, $deserialize, $metadata, $options);
    105     }
    106     public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation)
    107     {
    108         $metadata["foo"] = array('interceptor_from_stream_request');
    109         return $continuation($method, $deserialize, $metadata, $options);
    110     }
    111 }
    112 
    113 class ChangeMetadataInterceptor2 extends Grpc\Interceptor
    114 {
    115     public function interceptUnaryUnary($method,
    116                                         $argument,
    117                                         $deserialize,
    118                                         array $metadata = [],
    119                                         array $options = [],
    120                                         $continuation)
    121     {
    122         if (array_key_exists('foo', $metadata)) {
    123             $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first');
    124         } else {
    125             $metadata["bar"] = array('interceptor_from_unary_request');
    126         }
    127         return $continuation($method, $argument, $deserialize, $metadata, $options);
    128     }
    129     public function interceptStreamUnary($method,
    130                                          $deserialize,
    131                                          array $metadata = [],
    132                                          array $options = [],
    133                                          $continuation)
    134     {
    135         if (array_key_exists('foo', $metadata)) {
    136             $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first');
    137         } else {
    138             $metadata["bar"] = array('interceptor_from_stream_request');
    139         }
    140         return $continuation($method, $deserialize, $metadata, $options);
    141     }
    142 }
    143 
    144 class ChangeRequestCall
    145 {
    146     private $call;
    147 
    148     public function __construct($call)
    149     {
    150         $this->call = $call;
    151     }
    152     public function getCall()
    153     {
    154         return $this->call;
    155     }
    156 
    157     public function write($request)
    158     {
    159         $request->setData('intercepted_stream_request');
    160         $this->getCall()->write($request);
    161     }
    162 
    163     public function wait()
    164     {
    165         return $this->getCall()->wait();
    166     }
    167 }
    168 
    169 class ChangeRequestInterceptor extends Grpc\Interceptor
    170 {
    171     public function interceptUnaryUnary($method,
    172                                         $argument,
    173                                         $deserialize,
    174                                         array $metadata = [],
    175                                         array $options = [],
    176                                         $continuation)
    177     {
    178         $argument->setData('intercepted_unary_request');
    179         return $continuation($method, $argument, $deserialize, $metadata, $options);
    180     }
    181     public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation)
    182     {
    183         return new ChangeRequestCall(
    184             $continuation($method, $deserialize, $metadata, $options)
    185         );
    186     }
    187 }
    188 
    189 class StopCallInterceptor extends Grpc\Interceptor
    190 {
    191     public function interceptUnaryUnary($method,
    192                                         $argument,
    193                                         array $metadata = [],
    194                                         array $options = [],
    195                                         $continuation)
    196     {
    197         $metadata["foo"] = array('interceptor_from_request_response');
    198     }
    199     public function interceptStreamUnary($method,
    200                                          array $metadata = [],
    201                                          array $options = [],
    202                                          $continuation)
    203     {
    204         $metadata["foo"] = array('interceptor_from_request_response');
    205     }
    206 }
    207 
    208 class InterceptorTest extends PHPUnit_Framework_TestCase
    209 {
    210     public function setUp()
    211     {
    212         $this->server = new Grpc\Server([]);
    213         $this->port = $this->server->addHttp2Port('0.0.0.0:0');
    214         $this->channel = new Grpc\Channel('localhost:'.$this->port, [
    215             'force_new' => true,
    216             'credentials' => Grpc\ChannelCredentials::createInsecure()]);
    217         $this->server->start();
    218     }
    219 
    220     public function tearDown()
    221     {
    222         $this->channel->close();
    223         unset($this->server);
    224     }
    225 
    226 
    227     public function testClientChangeMetadataOneInterceptor()
    228     {
    229         $req_text = 'client_request';
    230         $channel_matadata_interceptor = new ChangeMetadataInterceptor();
    231         $intercept_channel = Grpc\Interceptor::intercept($this->channel, $channel_matadata_interceptor);
    232         $client = new InterceptorClient('localhost:'.$this->port, [
    233             'force_new' => true,
    234             'credentials' => Grpc\ChannelCredentials::createInsecure(),
    235         ], $intercept_channel);
    236         $req = new SimpleRequest($req_text);
    237         $unary_call = $client->UnaryCall($req);
    238         $event = $this->server->requestCall();
    239         $this->assertSame('/dummy_method', $event->method);
    240         $this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
    241 
    242         $stream_call = $client->StreamCall();
    243         $stream_call->write($req);
    244         $event = $this->server->requestCall();
    245         $this->assertSame('/dummy_method', $event->method);
    246         $this->assertSame(['interceptor_from_stream_request'], $event->metadata['foo']);
    247 
    248         unset($unary_call);
    249         unset($stream_call);
    250         unset($server_call);
    251     }
    252 
    253     public function testClientChangeMetadataTwoInterceptor()
    254     {
    255         $req_text = 'client_request';
    256         $channel_matadata_interceptor = new ChangeMetadataInterceptor();
    257         $channel_matadata_intercepto2 = new ChangeMetadataInterceptor2();
    258         // test intercept separately.
    259         $intercept_channel1 = Grpc\Interceptor::intercept($this->channel, $channel_matadata_interceptor);
    260         $intercept_channel2 = Grpc\Interceptor::intercept($intercept_channel1, $channel_matadata_intercepto2);
    261         $client = new InterceptorClient('localhost:'.$this->port, [
    262             'force_new' => true,
    263             'credentials' => Grpc\ChannelCredentials::createInsecure(),
    264         ], $intercept_channel2);
    265 
    266         $req = new SimpleRequest($req_text);
    267         $unary_call = $client->UnaryCall($req);
    268         $event = $this->server->requestCall();
    269         $this->assertSame('/dummy_method', $event->method);
    270         $this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
    271         $this->assertSame(['interceptor_from_unary_request'], $event->metadata['bar']);
    272 
    273         $stream_call = $client->StreamCall();
    274         $stream_call->write($req);
    275         $event = $this->server->requestCall();
    276         $this->assertSame('/dummy_method', $event->method);
    277         $this->assertSame(['interceptor_from_stream_request'], $event->metadata['foo']);
    278         $this->assertSame(['interceptor_from_stream_request'], $event->metadata['bar']);
    279 
    280         unset($unary_call);
    281         unset($stream_call);
    282         unset($server_call);
    283 
    284         // test intercept by array.
    285         $intercept_channel3 = Grpc\Interceptor::intercept($this->channel,
    286             [$channel_matadata_intercepto2, $channel_matadata_interceptor]);
    287         $client = new InterceptorClient('localhost:'.$this->port, [
    288             'force_new' => true,
    289             'credentials' => Grpc\ChannelCredentials::createInsecure(),
    290         ], $intercept_channel3);
    291 
    292         $req = new SimpleRequest($req_text);
    293         $unary_call = $client->UnaryCall($req);
    294         $event = $this->server->requestCall();
    295         $this->assertSame('/dummy_method', $event->method);
    296         $this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
    297         $this->assertSame(['interceptor_from_unary_request'], $event->metadata['bar']);
    298 
    299         $stream_call = $client->StreamCall();
    300         $stream_call->write($req);
    301         $event = $this->server->requestCall();
    302         $this->assertSame('/dummy_method', $event->method);
    303         $this->assertSame(['interceptor_from_stream_request'], $event->metadata['foo']);
    304         $this->assertSame(['interceptor_from_stream_request'], $event->metadata['bar']);
    305 
    306         unset($unary_call);
    307         unset($stream_call);
    308         unset($server_call);
    309     }
    310 
    311     public function testClientChangeRequestInterceptor()
    312     {
    313         $req_text = 'client_request';
    314         $change_request_interceptor = new ChangeRequestInterceptor();
    315         $intercept_channel = Grpc\Interceptor::intercept($this->channel,
    316             $change_request_interceptor);
    317         $client = new InterceptorClient('localhost:'.$this->port, [
    318             'force_new' => true,
    319             'credentials' => Grpc\ChannelCredentials::createInsecure(),
    320         ], $intercept_channel);
    321 
    322         $req = new SimpleRequest($req_text);
    323         $unary_call = $client->UnaryCall($req);
    324 
    325         $event = $this->server->requestCall();
    326         $this->assertSame('/dummy_method', $event->method);
    327         $server_call = $event->call;
    328         $event = $server_call->startBatch([
    329             Grpc\OP_SEND_INITIAL_METADATA => [],
    330             Grpc\OP_SEND_STATUS_FROM_SERVER => [
    331                 'metadata' => [],
    332                 'code' => Grpc\STATUS_OK,
    333                 'details' => '',
    334             ],
    335             Grpc\OP_RECV_MESSAGE => true,
    336             Grpc\OP_RECV_CLOSE_ON_SERVER => true,
    337         ]);
    338         $this->assertSame('intercepted_unary_request', $event->message);
    339 
    340         $stream_call = $client->StreamCall();
    341         $stream_call->write($req);
    342         $event = $this->server->requestCall();
    343         $this->assertSame('/dummy_method', $event->method);
    344         $server_call = $event->call;
    345         $event = $server_call->startBatch([
    346             Grpc\OP_SEND_INITIAL_METADATA => [],
    347             Grpc\OP_SEND_STATUS_FROM_SERVER => [
    348                 'metadata' => [],
    349                 'code' => Grpc\STATUS_OK,
    350                 'details' => '',
    351             ],
    352             Grpc\OP_RECV_MESSAGE => true,
    353             Grpc\OP_RECV_CLOSE_ON_SERVER => true,
    354         ]);
    355         $this->assertSame('intercepted_stream_request', $event->message);
    356 
    357         unset($unary_call);
    358         unset($stream_call);
    359         unset($server_call);
    360     }
    361 
    362     public function testClientChangeStopCallInterceptor()
    363     {
    364         $req_text = 'client_request';
    365         $channel_request_interceptor = new StopCallInterceptor();
    366         $intercept_channel = Grpc\Interceptor::intercept($this->channel,
    367             $channel_request_interceptor);
    368         $client = new InterceptorClient('localhost:'.$this->port, [
    369             'force_new' => true,
    370             'credentials' => Grpc\ChannelCredentials::createInsecure(),
    371         ], $intercept_channel);
    372 
    373         $req = new SimpleRequest($req_text);
    374         $unary_call = $client->UnaryCall($req);
    375         $this->assertNull($unary_call);
    376 
    377 
    378         $stream_call = $client->StreamCall();
    379         $this->assertNull($stream_call);
    380 
    381         unset($unary_call);
    382         unset($stream_call);
    383         unset($server_call);
    384     }
    385 
    386     public function testGetInterceptorChannelConnectivityState()
    387     {
    388         $channel = new Grpc\Channel(
    389             'localhost:0',
    390             [
    391                 'force_new' => true,
    392                 'credentials' => Grpc\ChannelCredentials::createInsecure()
    393             ]
    394         );
    395         $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
    396         $state = $interceptor_channel->getConnectivityState();
    397         $this->assertEquals(0, $state);
    398         $channel->close();
    399     }
    400 
    401     public function testInterceptorChannelWatchConnectivityState()
    402     {
    403         $channel = new Grpc\Channel(
    404             'localhost:0',
    405             [
    406                 'force_new' => true,
    407                 'credentials' => Grpc\ChannelCredentials::createInsecure()
    408             ]
    409         );
    410         $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
    411         $now = Grpc\Timeval::now();
    412         $deadline = $now->add(new Grpc\Timeval(100*1000));
    413         $state = $interceptor_channel->watchConnectivityState(1, $deadline);
    414         $this->assertTrue($state);
    415         unset($time);
    416         unset($deadline);
    417         $channel->close();
    418     }
    419 
    420     public function testInterceptorChannelClose()
    421     {
    422         $channel = new Grpc\Channel(
    423             'localhost:0',
    424             [
    425                 'force_new' => true,
    426                 'credentials' => Grpc\ChannelCredentials::createInsecure()
    427             ]
    428         );
    429         $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
    430         $this->assertNotNull($interceptor_channel);
    431         $channel->close();
    432     }
    433 
    434     public function testInterceptorChannelGetTarget()
    435     {
    436         $channel = new Grpc\Channel(
    437             'localhost:8888',
    438             [
    439                 'force_new' => true,
    440                 'credentials' => Grpc\ChannelCredentials::createInsecure()
    441             ]
    442         );
    443         $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
    444         $target = $interceptor_channel->getTarget();
    445         $this->assertTrue(is_string($target));
    446         $channel->close();
    447     }
    448 }
    449