Home | History | Annotate | Download | only in interop
      1 <?php
      2 /*
      3  *
      4  * Copyright 2015-2016 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 require_once realpath(dirname(__FILE__).'/../../vendor/autoload.php');
     20 
     21 // The following includes are needed when using protobuf 3.1.0
     22 // and will suppress warnings when using protobuf 3.2.0+
     23 @include_once 'src/proto/grpc/testing/test.pb.php';
     24 @include_once 'src/proto/grpc/testing/test_grpc_pb.php';
     25 
     26 use Google\Auth\CredentialsLoader;
     27 use Google\Auth\ApplicationDefaultCredentials;
     28 use GuzzleHttp\ClientInterface;
     29 
     30 /**
     31  * Assertion function that always exits with an error code if the assertion is
     32  * falsy.
     33  *
     34  * @param $value Assertion value. Should be true.
     35  * @param $error_message Message to display if the assertion is false
     36  */
     37 function hardAssert($value, $error_message)
     38 {
     39     if (!$value) {
     40         echo $error_message."\n";
     41         exit(1);
     42     }
     43 }
     44 
     45 function hardAssertIfStatusOk($status)
     46 {
     47     if ($status->code !== Grpc\STATUS_OK) {
     48         echo "Call did not complete successfully. Status object:\n";
     49         var_dump($status);
     50         exit(1);
     51     }
     52 }
     53 
     54 /**
     55  * Run the empty_unary test.
     56  *
     57  * @param $stub Stub object that has service methods
     58  */
     59 function emptyUnary($stub)
     60 {
     61     list($result, $status) =
     62         $stub->EmptyCall(new Grpc\Testing\EmptyMessage())->wait();
     63     hardAssertIfStatusOk($status);
     64     hardAssert($result !== null, 'Call completed with a null response');
     65 }
     66 
     67 /**
     68  * Run the large_unary test.
     69  *
     70  * @param $stub Stub object that has service methods
     71  */
     72 function largeUnary($stub)
     73 {
     74     performLargeUnary($stub);
     75 }
     76 
     77 /**
     78  * Shared code between large unary test and auth test.
     79  *
     80  * @param $stub Stub object that has service methods
     81  * @param $fillUsername boolean whether to fill result with username
     82  * @param $fillOauthScope boolean whether to fill result with oauth scope
     83  */
     84 function performLargeUnary($stub, $fillUsername = false,
     85                            $fillOauthScope = false, $callback = false)
     86 {
     87     $request_len = 271828;
     88     $response_len = 314159;
     89 
     90     $request = new Grpc\Testing\SimpleRequest();
     91     $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
     92     $request->setResponseSize($response_len);
     93     $payload = new Grpc\Testing\Payload();
     94     $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
     95     $payload->setBody(str_repeat("\0", $request_len));
     96     $request->setPayload($payload);
     97     $request->setFillUsername($fillUsername);
     98     $request->setFillOauthScope($fillOauthScope);
     99 
    100     $options = [];
    101     if ($callback) {
    102         $options['call_credentials_callback'] = $callback;
    103     }
    104 
    105     list($result, $status) = $stub->UnaryCall($request, [], $options)->wait();
    106     hardAssertIfStatusOk($status);
    107     hardAssert($result !== null, 'Call returned a null response');
    108     $payload = $result->getPayload();
    109     hardAssert($payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
    110                'Payload had the wrong type');
    111     hardAssert(strlen($payload->getBody()) === $response_len,
    112                'Payload had the wrong length');
    113     hardAssert($payload->getBody() === str_repeat("\0", $response_len),
    114                'Payload had the wrong content');
    115 
    116     return $result;
    117 }
    118 
    119 /**
    120  * Run the service account credentials auth test.
    121  *
    122  * @param $stub Stub object that has service methods
    123  * @param $args array command line args
    124  */
    125 function serviceAccountCreds($stub, $args)
    126 {
    127     if (!array_key_exists('oauth_scope', $args)) {
    128         throw new Exception('Missing oauth scope');
    129     }
    130     $jsonKey = json_decode(
    131         file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
    132         true);
    133     $result = performLargeUnary($stub, $fillUsername = true,
    134                                 $fillOauthScope = true);
    135     hardAssert($result->getUsername() === $jsonKey['client_email'],
    136                'invalid email returned');
    137     hardAssert(strpos($args['oauth_scope'], $result->getOauthScope()) !== false,
    138                'invalid oauth scope returned');
    139 }
    140 
    141 /**
    142  * Run the compute engine credentials auth test.
    143  * Has not been run from gcloud as of 2015-05-05.
    144  *
    145  * @param $stub Stub object that has service methods
    146  * @param $args array command line args
    147  */
    148 function computeEngineCreds($stub, $args)
    149 {
    150     if (!array_key_exists('oauth_scope', $args)) {
    151         throw new Exception('Missing oauth scope');
    152     }
    153     if (!array_key_exists('default_service_account', $args)) {
    154         throw new Exception('Missing default_service_account');
    155     }
    156     $result = performLargeUnary($stub, $fillUsername = true,
    157                                 $fillOauthScope = true);
    158     hardAssert($args['default_service_account'] === $result->getUsername(),
    159                'invalid email returned');
    160 }
    161 
    162 /**
    163  * Run the jwt token credentials auth test.
    164  *
    165  * @param $stub Stub object that has service methods
    166  * @param $args array command line args
    167  */
    168 function jwtTokenCreds($stub, $args)
    169 {
    170     $jsonKey = json_decode(
    171         file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
    172         true);
    173     $result = performLargeUnary($stub, $fillUsername = true,
    174                                 $fillOauthScope = true);
    175     hardAssert($result->getUsername() === $jsonKey['client_email'],
    176                'invalid email returned');
    177 }
    178 
    179 /**
    180  * Run the oauth2_auth_token auth test.
    181  *
    182  * @param $stub Stub object that has service methods
    183  * @param $args array command line args
    184  */
    185 function oauth2AuthToken($stub, $args)
    186 {
    187     $jsonKey = json_decode(
    188         file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
    189         true);
    190     $result = performLargeUnary($stub, $fillUsername = true,
    191                                 $fillOauthScope = true);
    192     hardAssert($result->getUsername() === $jsonKey['client_email'],
    193                'invalid email returned');
    194 }
    195 
    196 function updateAuthMetadataCallback($context)
    197 {
    198     $authUri = $context->service_url;
    199     $methodName = $context->method_name;
    200     $auth_credentials = ApplicationDefaultCredentials::getCredentials();
    201 
    202     $metadata = [];
    203     $result = $auth_credentials->updateMetadata([], $authUri);
    204     foreach ($result as $key => $value) {
    205         $metadata[strtolower($key)] = $value;
    206     }
    207 
    208     return $metadata;
    209 }
    210 
    211 /**
    212  * Run the per_rpc_creds auth test.
    213  *
    214  * @param $stub Stub object that has service methods
    215  * @param $args array command line args
    216  */
    217 function perRpcCreds($stub, $args)
    218 {
    219     $jsonKey = json_decode(
    220         file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
    221         true);
    222 
    223     $result = performLargeUnary($stub, $fillUsername = true,
    224                                 $fillOauthScope = true,
    225                                 'updateAuthMetadataCallback');
    226     hardAssert($result->getUsername() === $jsonKey['client_email'],
    227                'invalid email returned');
    228 }
    229 
    230 /**
    231  * Run the client_streaming test.
    232  *
    233  * @param $stub Stub object that has service methods
    234  */
    235 function clientStreaming($stub)
    236 {
    237     $request_lengths = [27182, 8, 1828, 45904];
    238 
    239     $requests = array_map(
    240         function ($length) {
    241             $request = new Grpc\Testing\StreamingInputCallRequest();
    242             $payload = new Grpc\Testing\Payload();
    243             $payload->setBody(str_repeat("\0", $length));
    244             $request->setPayload($payload);
    245 
    246             return $request;
    247         }, $request_lengths);
    248 
    249     $call = $stub->StreamingInputCall();
    250     foreach ($requests as $request) {
    251         $call->write($request);
    252     }
    253     list($result, $status) = $call->wait();
    254     hardAssertIfStatusOk($status);
    255     hardAssert($result->getAggregatedPayloadSize() === 74922,
    256                'aggregated_payload_size was incorrect');
    257 }
    258 
    259 /**
    260  * Run the server_streaming test.
    261  *
    262  * @param $stub Stub object that has service methods.
    263  */
    264 function serverStreaming($stub)
    265 {
    266     $sizes = [31415, 9, 2653, 58979];
    267 
    268     $request = new Grpc\Testing\StreamingOutputCallRequest();
    269     $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    270     foreach ($sizes as $size) {
    271         $response_parameters = new Grpc\Testing\ResponseParameters();
    272         $response_parameters->setSize($size);
    273         $request->getResponseParameters()[] = $response_parameters;
    274     }
    275 
    276     $call = $stub->StreamingOutputCall($request);
    277     $i = 0;
    278     foreach ($call->responses() as $value) {
    279         hardAssert($i < 4, 'Too many responses');
    280         $payload = $value->getPayload();
    281         hardAssert(
    282             $payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
    283             'Payload '.$i.' had the wrong type');
    284         hardAssert(strlen($payload->getBody()) === $sizes[$i],
    285                    'Response '.$i.' had the wrong length');
    286         $i += 1;
    287     }
    288     hardAssertIfStatusOk($call->getStatus());
    289 }
    290 
    291 /**
    292  * Run the ping_pong test.
    293  *
    294  * @param $stub Stub object that has service methods.
    295  */
    296 function pingPong($stub)
    297 {
    298     $request_lengths = [27182, 8, 1828, 45904];
    299     $response_lengths = [31415, 9, 2653, 58979];
    300 
    301     $call = $stub->FullDuplexCall();
    302     for ($i = 0; $i < 4; ++$i) {
    303         $request = new Grpc\Testing\StreamingOutputCallRequest();
    304         $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    305         $response_parameters = new Grpc\Testing\ResponseParameters();
    306         $response_parameters->setSize($response_lengths[$i]);
    307         $request->getResponseParameters()[] = $response_parameters;
    308         $payload = new Grpc\Testing\Payload();
    309         $payload->setBody(str_repeat("\0", $request_lengths[$i]));
    310         $request->setPayload($payload);
    311 
    312         $call->write($request);
    313         $response = $call->read();
    314 
    315         hardAssert($response !== null, 'Server returned too few responses');
    316         $payload = $response->getPayload();
    317         hardAssert(
    318             $payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
    319             'Payload '.$i.' had the wrong type');
    320         hardAssert(strlen($payload->getBody()) === $response_lengths[$i],
    321                    'Payload '.$i.' had the wrong length');
    322     }
    323     $call->writesDone();
    324     hardAssert($call->read() === null, 'Server returned too many responses');
    325     hardAssertIfStatusOk($call->getStatus());
    326 }
    327 
    328 /**
    329  * Run the empty_stream test.
    330  *
    331  * @param $stub Stub object that has service methods.
    332  */
    333 function emptyStream($stub)
    334 {
    335     $call = $stub->FullDuplexCall();
    336     $call->writesDone();
    337     hardAssert($call->read() === null, 'Server returned too many responses');
    338     hardAssertIfStatusOk($call->getStatus());
    339 }
    340 
    341 /**
    342  * Run the cancel_after_begin test.
    343  *
    344  * @param $stub Stub object that has service methods.
    345  */
    346 function cancelAfterBegin($stub)
    347 {
    348     $call = $stub->StreamingInputCall();
    349     $call->cancel();
    350     list($result, $status) = $call->wait();
    351     hardAssert($status->code === Grpc\STATUS_CANCELLED,
    352                'Call status was not CANCELLED');
    353 }
    354 
    355 /**
    356  * Run the cancel_after_first_response test.
    357  *
    358  * @param $stub Stub object that has service methods.
    359  */
    360 function cancelAfterFirstResponse($stub)
    361 {
    362     $call = $stub->FullDuplexCall();
    363     $request = new Grpc\Testing\StreamingOutputCallRequest();
    364     $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    365     $response_parameters = new Grpc\Testing\ResponseParameters();
    366     $response_parameters->setSize(31415);
    367     $request->getResponseParameters()[] = $response_parameters;
    368     $payload = new Grpc\Testing\Payload();
    369     $payload->setBody(str_repeat("\0", 27182));
    370     $request->setPayload($payload);
    371 
    372     $call->write($request);
    373     $response = $call->read();
    374 
    375     $call->cancel();
    376     hardAssert($call->getStatus()->code === Grpc\STATUS_CANCELLED,
    377                'Call status was not CANCELLED');
    378 }
    379 
    380 function timeoutOnSleepingServer($stub)
    381 {
    382     $call = $stub->FullDuplexCall([], ['timeout' => 1000]);
    383     $request = new Grpc\Testing\StreamingOutputCallRequest();
    384     $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    385     $response_parameters = new Grpc\Testing\ResponseParameters();
    386     $response_parameters->setSize(8);
    387     $request->getResponseParameters()[] = $response_parameters;
    388     $payload = new Grpc\Testing\Payload();
    389     $payload->setBody(str_repeat("\0", 9));
    390     $request->setPayload($payload);
    391 
    392     $call->write($request);
    393     $response = $call->read();
    394 
    395     hardAssert($call->getStatus()->code === Grpc\STATUS_DEADLINE_EXCEEDED,
    396                'Call status was not DEADLINE_EXCEEDED');
    397 }
    398 
    399 function customMetadata($stub)
    400 {
    401     $ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
    402     $ECHO_INITIAL_VALUE = 'test_initial_metadata_value';
    403     $ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
    404     $ECHO_TRAILING_VALUE = 'ababab';
    405     $request_len = 271828;
    406     $response_len = 314159;
    407 
    408     $request = new Grpc\Testing\SimpleRequest();
    409     $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    410     $request->setResponseSize($response_len);
    411     $payload = new Grpc\Testing\Payload();
    412     $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
    413     $payload->setBody(str_repeat("\0", $request_len));
    414     $request->setPayload($payload);
    415 
    416     $metadata = [
    417         $ECHO_INITIAL_KEY => [$ECHO_INITIAL_VALUE],
    418         $ECHO_TRAILING_KEY => [$ECHO_TRAILING_VALUE],
    419     ];
    420     $call = $stub->UnaryCall($request, $metadata);
    421 
    422     $initial_metadata = $call->getMetadata();
    423     hardAssert(array_key_exists($ECHO_INITIAL_KEY, $initial_metadata),
    424                'Initial metadata does not contain expected key');
    425     hardAssert(
    426         $initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
    427         'Incorrect initial metadata value');
    428 
    429     list($result, $status) = $call->wait();
    430     hardAssertIfStatusOk($status);
    431 
    432     $trailing_metadata = $call->getTrailingMetadata();
    433     hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata),
    434                'Trailing metadata does not contain expected key');
    435     hardAssert(
    436         $trailing_metadata[$ECHO_TRAILING_KEY][0] === $ECHO_TRAILING_VALUE,
    437         'Incorrect trailing metadata value');
    438 
    439     $streaming_call = $stub->FullDuplexCall($metadata);
    440 
    441     $streaming_request = new Grpc\Testing\StreamingOutputCallRequest();
    442     $streaming_request->setPayload($payload);
    443     $response_parameters = new Grpc\Testing\ResponseParameters();
    444     $response_parameters->setSize($response_len);
    445     $streaming_request->getResponseParameters()[] = $response_parameters;
    446     $streaming_call->write($streaming_request);
    447     $streaming_call->writesDone();
    448     $result = $streaming_call->read();
    449 
    450     hardAssertIfStatusOk($streaming_call->getStatus());
    451 
    452     $streaming_initial_metadata = $streaming_call->getMetadata();
    453     hardAssert(array_key_exists($ECHO_INITIAL_KEY, $streaming_initial_metadata),
    454                'Initial metadata does not contain expected key');
    455     hardAssert(
    456         $streaming_initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
    457         'Incorrect initial metadata value');
    458 
    459     $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
    460     hardAssert(array_key_exists($ECHO_TRAILING_KEY,
    461                                 $streaming_trailing_metadata),
    462                'Trailing metadata does not contain expected key');
    463     hardAssert($streaming_trailing_metadata[$ECHO_TRAILING_KEY][0] ===
    464                $ECHO_TRAILING_VALUE, 'Incorrect trailing metadata value');
    465 }
    466 
    467 function statusCodeAndMessage($stub)
    468 {
    469     $echo_status = new Grpc\Testing\EchoStatus();
    470     $echo_status->setCode(2);
    471     $echo_status->setMessage('test status message');
    472 
    473     $request = new Grpc\Testing\SimpleRequest();
    474     $request->setResponseStatus($echo_status);
    475 
    476     $call = $stub->UnaryCall($request);
    477     list($result, $status) = $call->wait();
    478 
    479     hardAssert($status->code === 2,
    480                'Received unexpected UnaryCall status code: '.
    481                $status->code);
    482     hardAssert($status->details === 'test status message',
    483                'Received unexpected UnaryCall status details: '.
    484                $status->details);
    485 
    486     $streaming_call = $stub->FullDuplexCall();
    487 
    488     $streaming_request = new Grpc\Testing\StreamingOutputCallRequest();
    489     $streaming_request->setResponseStatus($echo_status);
    490     $streaming_call->write($streaming_request);
    491     $streaming_call->writesDone();
    492     $result = $streaming_call->read();
    493 
    494     $status = $streaming_call->getStatus();
    495     hardAssert($status->code === 2,
    496                'Received unexpected FullDuplexCall status code: '.
    497                $status->code);
    498     hardAssert($status->details === 'test status message',
    499                'Received unexpected FullDuplexCall status details: '.
    500                $status->details);
    501 }
    502 
    503 # NOTE: the stub input to this function is from UnimplementedService
    504 function unimplementedService($stub)
    505 {
    506     $call = $stub->UnimplementedCall(new Grpc\Testing\EmptyMessage());
    507     list($result, $status) = $call->wait();
    508     hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
    509                'Received unexpected status code');
    510 }
    511 
    512 # NOTE: the stub input to this function is from TestService
    513 function unimplementedMethod($stub)
    514 {
    515     $call = $stub->UnimplementedCall(new Grpc\Testing\EmptyMessage());
    516     list($result, $status) = $call->wait();
    517     hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
    518                'Received unexpected status code');
    519 }
    520 
    521 function _makeStub($args)
    522 {
    523     if (!array_key_exists('server_host', $args)) {
    524         throw new Exception('Missing argument: --server_host is required');
    525     }
    526     if (!array_key_exists('server_port', $args)) {
    527         throw new Exception('Missing argument: --server_port is required');
    528     }
    529     if (!array_key_exists('test_case', $args)) {
    530         throw new Exception('Missing argument: --test_case is required');
    531     }
    532 
    533     if ($args['server_port'] === 443) {
    534         $server_address = $args['server_host'];
    535     } else {
    536         $server_address = $args['server_host'].':'.$args['server_port'];
    537     }
    538 
    539     $test_case = $args['test_case'];
    540 
    541     $host_override = 'foo.test.google.fr';
    542     if (array_key_exists('server_host_override', $args)) {
    543         $host_override = $args['server_host_override'];
    544     }
    545 
    546     $use_tls = false;
    547     if (array_key_exists('use_tls', $args) &&
    548         $args['use_tls'] != 'false') {
    549         $use_tls = true;
    550     }
    551 
    552     $use_test_ca = false;
    553     if (array_key_exists('use_test_ca', $args) &&
    554         $args['use_test_ca'] != 'false') {
    555         $use_test_ca = true;
    556     }
    557 
    558     $opts = [];
    559 
    560     if ($use_tls) {
    561         if ($use_test_ca) {
    562             $ssl_credentials = Grpc\ChannelCredentials::createSsl(
    563                 file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
    564         } else {
    565             $ssl_credentials = Grpc\ChannelCredentials::createSsl();
    566         }
    567         $opts['credentials'] = $ssl_credentials;
    568         $opts['grpc.ssl_target_name_override'] = $host_override;
    569     } else {
    570         $opts['credentials'] = Grpc\ChannelCredentials::createInsecure();
    571     }
    572 
    573     if (in_array($test_case, ['service_account_creds',
    574                               'compute_engine_creds', 'jwt_token_creds', ])) {
    575         if ($test_case === 'jwt_token_creds') {
    576             $auth_credentials = ApplicationDefaultCredentials::getCredentials();
    577         } else {
    578             $auth_credentials = ApplicationDefaultCredentials::getCredentials(
    579                 $args['oauth_scope']
    580             );
    581         }
    582         $opts['update_metadata'] = $auth_credentials->getUpdateMetadataFunc();
    583     }
    584 
    585     if ($test_case === 'oauth2_auth_token') {
    586         $auth_credentials = ApplicationDefaultCredentials::getCredentials(
    587             $args['oauth_scope']
    588         );
    589         $token = $auth_credentials->fetchAuthToken();
    590         $update_metadata =
    591             function ($metadata,
    592                       $authUri = null,
    593                       ClientInterface $client = null) use ($token) {
    594                 $metadata_copy = $metadata;
    595                 $metadata_copy[CredentialsLoader::AUTH_METADATA_KEY] =
    596                     [sprintf('%s %s',
    597                              $token['token_type'],
    598                              $token['access_token'])];
    599 
    600                 return $metadata_copy;
    601             };
    602         $opts['update_metadata'] = $update_metadata;
    603     }
    604 
    605     if ($test_case === 'unimplemented_service') {
    606         $stub = new Grpc\Testing\UnimplementedServiceClient($server_address,
    607                                                             $opts);
    608     } else {
    609         $stub = new Grpc\Testing\TestServiceClient($server_address, $opts);
    610     }
    611 
    612     return $stub;
    613 }
    614 
    615 function interop_main($args, $stub = false)
    616 {
    617     if (!$stub) {
    618         $stub = _makeStub($args);
    619     }
    620 
    621     $test_case = $args['test_case'];
    622     echo "Running test case $test_case\n";
    623 
    624     switch ($test_case) {
    625         case 'empty_unary':
    626             emptyUnary($stub);
    627             break;
    628         case 'large_unary':
    629             largeUnary($stub);
    630             break;
    631         case 'client_streaming':
    632             clientStreaming($stub);
    633             break;
    634         case 'server_streaming':
    635             serverStreaming($stub);
    636             break;
    637         case 'ping_pong':
    638             pingPong($stub);
    639             break;
    640         case 'empty_stream':
    641             emptyStream($stub);
    642             break;
    643         case 'cancel_after_begin':
    644             cancelAfterBegin($stub);
    645             break;
    646         case 'cancel_after_first_response':
    647             cancelAfterFirstResponse($stub);
    648             break;
    649         case 'timeout_on_sleeping_server':
    650             timeoutOnSleepingServer($stub);
    651             break;
    652         case 'custom_metadata':
    653             customMetadata($stub);
    654             break;
    655         case 'status_code_and_message':
    656             statusCodeAndMessage($stub);
    657             break;
    658         case 'unimplemented_service':
    659             unimplementedService($stub);
    660             break;
    661         case 'unimplemented_method':
    662             unimplementedMethod($stub);
    663             break;
    664         case 'service_account_creds':
    665             serviceAccountCreds($stub, $args);
    666             break;
    667         case 'compute_engine_creds':
    668             computeEngineCreds($stub, $args);
    669             break;
    670         case 'jwt_token_creds':
    671             jwtTokenCreds($stub, $args);
    672             break;
    673         case 'oauth2_auth_token':
    674             oauth2AuthToken($stub, $args);
    675             break;
    676         case 'per_rpc_creds':
    677             perRpcCreds($stub, $args);
    678             break;
    679         default:
    680             echo "Unsupported test case $test_case\n";
    681             exit(1);
    682     }
    683 
    684     return $stub;
    685 }
    686 
    687 if (isset($_SERVER['PHP_SELF']) &&
    688     preg_match('/interop_client/', $_SERVER['PHP_SELF'])) {
    689     $args = getopt('', ['server_host:', 'server_port:', 'test_case:',
    690                         'use_tls::', 'use_test_ca::',
    691                         'server_host_override:', 'oauth_scope:',
    692                         'default_service_account:', ]);
    693     interop_main($args);
    694 }
    695