• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
19require_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
26use Google\Auth\CredentialsLoader;
27use Google\Auth\ApplicationDefaultCredentials;
28use 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 */
37function hardAssert($value, $error_message)
38{
39    if (!$value) {
40        echo $error_message."\n";
41        exit(1);
42    }
43}
44
45function 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 */
59function 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 */
72function 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 */
84function 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 client_compressed_unary test.
121 *
122 * @param $stub Stub object that has service methods
123 */
124function clientCompressedUnary($stub)
125{
126    $request_len = 271828;
127    $response_len = 314159;
128    $falseBoolValue = new Grpc\Testing\BoolValue(['value' => false]);
129    $trueBoolValue = new Grpc\Testing\BoolValue(['value' => true]);
130    // 1. Probing for compression-checks support
131    $payload = new Grpc\Testing\Payload([
132        'body' => str_repeat("\0", $request_len),
133    ]);
134    $request = new Grpc\Testing\SimpleRequest([
135        'payload' => $payload,
136        'response_size' => $response_len,
137        'expect_compressed' => $trueBoolValue, // lie
138    ]);
139    list($result, $status) = $stub->UnaryCall($request, [], [])->wait();
140    hardAssert(
141        $status->code === GRPC\STATUS_INVALID_ARGUMENT,
142        'Received unexpected UnaryCall status code: ' .
143            $status->code
144    );
145    // 2. with/without compressed message
146    foreach ([true, false] as $compression) {
147        $request->setExpectCompressed($compression ? $trueBoolValue : $falseBoolValue);
148        $metadata = $compression ? [
149            'grpc-internal-encoding-request' => ['gzip'],
150        ] : [];
151        list($result, $status) = $stub->UnaryCall($request, $metadata, [])->wait();
152        hardAssertIfStatusOk($status);
153        hardAssert($result !== null, 'Call returned a null response');
154        $payload = $result->getPayload();
155        hardAssert(
156            strlen($payload->getBody()) === $response_len,
157            'Payload had the wrong length'
158        );
159        hardAssert(
160            $payload->getBody() === str_repeat("\0", $response_len),
161            'Payload had the wrong content'
162        );
163    }
164}
165
166/**
167 * Run the service account credentials auth test.
168 *
169 * @param $stub Stub object that has service methods
170 * @param $args array command line args
171 */
172function serviceAccountCreds($stub, $args)
173{
174    if (!array_key_exists('oauth_scope', $args)) {
175        throw new Exception('Missing oauth scope');
176    }
177    $jsonKey = json_decode(
178        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
179        true);
180    $result = performLargeUnary($stub, $fillUsername = true,
181                                $fillOauthScope = true);
182    hardAssert($result->getUsername() === $jsonKey['client_email'],
183               'invalid email returned');
184    hardAssert(strpos($args['oauth_scope'], $result->getOauthScope()) !== false,
185               'invalid oauth scope returned');
186}
187
188/**
189 * Run the compute engine credentials auth test.
190 * Has not been run from gcloud as of 2015-05-05.
191 *
192 * @param $stub Stub object that has service methods
193 * @param $args array command line args
194 */
195function computeEngineCreds($stub, $args)
196{
197    if (!array_key_exists('oauth_scope', $args)) {
198        throw new Exception('Missing oauth scope');
199    }
200    if (!array_key_exists('default_service_account', $args)) {
201        throw new Exception('Missing default_service_account');
202    }
203    $result = performLargeUnary($stub, $fillUsername = true,
204                                $fillOauthScope = true);
205    hardAssert($args['default_service_account'] === $result->getUsername(),
206               'invalid email returned');
207}
208
209/**
210 * Run the jwt token credentials auth test.
211 *
212 * @param $stub Stub object that has service methods
213 * @param $args array command line args
214 */
215function jwtTokenCreds($stub, $args)
216{
217    $jsonKey = json_decode(
218        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
219        true);
220    $result = performLargeUnary($stub, $fillUsername = true,
221                                $fillOauthScope = true);
222    hardAssert($result->getUsername() === $jsonKey['client_email'],
223               'invalid email returned');
224}
225
226/**
227 * Run the oauth2_auth_token auth test.
228 *
229 * @param $stub Stub object that has service methods
230 * @param $args array command line args
231 */
232function oauth2AuthToken($stub, $args)
233{
234    $jsonKey = json_decode(
235        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
236        true);
237    $result = performLargeUnary($stub, $fillUsername = true,
238                                $fillOauthScope = true);
239    hardAssert($result->getUsername() === $jsonKey['client_email'],
240               'invalid email returned');
241}
242
243function updateAuthMetadataCallback($context)
244{
245    $authUri = $context->service_url;
246    $methodName = $context->method_name;
247    $auth_credentials = ApplicationDefaultCredentials::getCredentials();
248
249    $metadata = [];
250    $result = $auth_credentials->updateMetadata([], $authUri);
251    foreach ($result as $key => $value) {
252        $metadata[strtolower($key)] = $value;
253    }
254
255    return $metadata;
256}
257
258/**
259 * Run the per_rpc_creds auth test.
260 *
261 * @param $stub Stub object that has service methods
262 * @param $args array command line args
263 */
264function perRpcCreds($stub, $args)
265{
266    $jsonKey = json_decode(
267        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
268        true);
269
270    $result = performLargeUnary($stub, $fillUsername = true,
271                                $fillOauthScope = true,
272                                'updateAuthMetadataCallback');
273    hardAssert($result->getUsername() === $jsonKey['client_email'],
274               'invalid email returned');
275}
276
277/**
278 * Run the client_streaming test.
279 *
280 * @param $stub Stub object that has service methods
281 */
282function clientStreaming($stub)
283{
284    $request_lengths = [27182, 8, 1828, 45904];
285
286    $requests = array_map(
287        function ($length) {
288            $request = new Grpc\Testing\StreamingInputCallRequest();
289            $payload = new Grpc\Testing\Payload();
290            $payload->setBody(str_repeat("\0", $length));
291            $request->setPayload($payload);
292
293            return $request;
294        }, $request_lengths);
295
296    $call = $stub->StreamingInputCall();
297    foreach ($requests as $request) {
298        $call->write($request);
299    }
300    list($result, $status) = $call->wait();
301    hardAssertIfStatusOk($status);
302    hardAssert($result->getAggregatedPayloadSize() === 74922,
303               'aggregated_payload_size was incorrect');
304}
305
306/**
307 * Run the client_compressed_streaming test.
308 *
309 * @param $stub Stub object that has service methods
310 */
311function clientCompressedStreaming($stub)
312{
313    $request_len = 27182;
314    $request2_len = 45904;
315    $response_len = 73086;
316    $falseBoolValue = new Grpc\Testing\BoolValue(['value' => false]);
317    $trueBoolValue = new Grpc\Testing\BoolValue(['value' => true]);
318
319    // 1. Probing for compression-checks support
320
321    $payload = new Grpc\Testing\Payload([
322        'body' => str_repeat("\0", $request_len),
323    ]);
324    $request = new Grpc\Testing\StreamingInputCallRequest([
325        'payload' => $payload,
326        'expect_compressed' => $trueBoolValue, // lie
327    ]);
328
329    $call = $stub->StreamingInputCall();
330    $call->write($request);
331    list($result, $status) = $call->wait();
332    hardAssert(
333        $status->code === GRPC\STATUS_INVALID_ARGUMENT,
334        'Received unexpected StreamingInputCall status code: ' .
335            $status->code
336    );
337
338    // 2. write compressed message
339
340    $call = $stub->StreamingInputCall([
341        'grpc-internal-encoding-request' => ['gzip'],
342    ]);
343    $request->setExpectCompressed($trueBoolValue);
344    $call->write($request);
345
346    // 3. write uncompressed message
347
348    $payload2 = new Grpc\Testing\Payload([
349        'body' => str_repeat("\0", $request2_len),
350    ]);
351    $request->setPayload($payload2);
352    $request->setExpectCompressed($falseBoolValue);
353    $call->write($request, [
354        'flags' => 0x02 // GRPC_WRITE_NO_COMPRESS
355    ]);
356
357    // 4. verify response
358
359    list($result, $status) = $call->wait();
360
361    hardAssertIfStatusOk($status);
362    hardAssert(
363        $result->getAggregatedPayloadSize() === $response_len,
364        'aggregated_payload_size was incorrect'
365    );
366}
367
368/**
369 * Run the server_streaming test.
370 *
371 * @param $stub Stub object that has service methods.
372 */
373function serverStreaming($stub)
374{
375    $sizes = [31415, 9, 2653, 58979];
376
377    $request = new Grpc\Testing\StreamingOutputCallRequest();
378    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
379    foreach ($sizes as $size) {
380        $response_parameters = new Grpc\Testing\ResponseParameters();
381        $response_parameters->setSize($size);
382        $request->getResponseParameters()[] = $response_parameters;
383    }
384
385    $call = $stub->StreamingOutputCall($request);
386    $i = 0;
387    foreach ($call->responses() as $value) {
388        hardAssert($i < 4, 'Too many responses');
389        $payload = $value->getPayload();
390        hardAssert(
391            $payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
392            'Payload '.$i.' had the wrong type');
393        hardAssert(strlen($payload->getBody()) === $sizes[$i],
394                   'Response '.$i.' had the wrong length');
395        $i += 1;
396    }
397    hardAssertIfStatusOk($call->getStatus());
398}
399
400/**
401 * Run the ping_pong test.
402 *
403 * @param $stub Stub object that has service methods.
404 */
405function pingPong($stub)
406{
407    $request_lengths = [27182, 8, 1828, 45904];
408    $response_lengths = [31415, 9, 2653, 58979];
409
410    $call = $stub->FullDuplexCall();
411    for ($i = 0; $i < 4; ++$i) {
412        $request = new Grpc\Testing\StreamingOutputCallRequest();
413        $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
414        $response_parameters = new Grpc\Testing\ResponseParameters();
415        $response_parameters->setSize($response_lengths[$i]);
416        $request->getResponseParameters()[] = $response_parameters;
417        $payload = new Grpc\Testing\Payload();
418        $payload->setBody(str_repeat("\0", $request_lengths[$i]));
419        $request->setPayload($payload);
420
421        $call->write($request);
422        $response = $call->read();
423
424        hardAssert($response !== null, 'Server returned too few responses');
425        $payload = $response->getPayload();
426        hardAssert(
427            $payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
428            'Payload '.$i.' had the wrong type');
429        hardAssert(strlen($payload->getBody()) === $response_lengths[$i],
430                   'Payload '.$i.' had the wrong length');
431    }
432    $call->writesDone();
433    hardAssert($call->read() === null, 'Server returned too many responses');
434    hardAssertIfStatusOk($call->getStatus());
435}
436
437/**
438 * Run the empty_stream test.
439 *
440 * @param $stub Stub object that has service methods.
441 */
442function emptyStream($stub)
443{
444    $call = $stub->FullDuplexCall();
445    $call->writesDone();
446    hardAssert($call->read() === null, 'Server returned too many responses');
447    hardAssertIfStatusOk($call->getStatus());
448}
449
450/**
451 * Run the cancel_after_begin test.
452 *
453 * @param $stub Stub object that has service methods.
454 */
455function cancelAfterBegin($stub)
456{
457    $call = $stub->StreamingInputCall();
458    $call->cancel();
459    list($result, $status) = $call->wait();
460    hardAssert($status->code === Grpc\STATUS_CANCELLED,
461               'Call status was not CANCELLED');
462}
463
464/**
465 * Run the cancel_after_first_response test.
466 *
467 * @param $stub Stub object that has service methods.
468 */
469function cancelAfterFirstResponse($stub)
470{
471    $call = $stub->FullDuplexCall();
472    $request = new Grpc\Testing\StreamingOutputCallRequest();
473    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
474    $response_parameters = new Grpc\Testing\ResponseParameters();
475    $response_parameters->setSize(31415);
476    $request->getResponseParameters()[] = $response_parameters;
477    $payload = new Grpc\Testing\Payload();
478    $payload->setBody(str_repeat("\0", 27182));
479    $request->setPayload($payload);
480
481    $call->write($request);
482    $response = $call->read();
483
484    $call->cancel();
485    hardAssert($call->getStatus()->code === Grpc\STATUS_CANCELLED,
486               'Call status was not CANCELLED');
487}
488
489function timeoutOnSleepingServer($stub)
490{
491    $call = $stub->FullDuplexCall([], ['timeout' => 1000]);
492    $request = new Grpc\Testing\StreamingOutputCallRequest();
493    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
494    $response_parameters = new Grpc\Testing\ResponseParameters();
495    $response_parameters->setSize(8);
496    $request->getResponseParameters()[] = $response_parameters;
497    $payload = new Grpc\Testing\Payload();
498    $payload->setBody(str_repeat("\0", 9));
499    $request->setPayload($payload);
500
501    $call->write($request);
502    $response = $call->read();
503
504    hardAssert($call->getStatus()->code === Grpc\STATUS_DEADLINE_EXCEEDED,
505               'Call status was not DEADLINE_EXCEEDED');
506}
507
508function customMetadata($stub)
509{
510    $ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
511    $ECHO_INITIAL_VALUE = 'test_initial_metadata_value';
512    $ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
513    $ECHO_TRAILING_VALUE = 'ababab';
514    $request_len = 271828;
515    $response_len = 314159;
516
517    $request = new Grpc\Testing\SimpleRequest();
518    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
519    $request->setResponseSize($response_len);
520    $payload = new Grpc\Testing\Payload();
521    $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
522    $payload->setBody(str_repeat("\0", $request_len));
523    $request->setPayload($payload);
524
525    $metadata = [
526        $ECHO_INITIAL_KEY => [$ECHO_INITIAL_VALUE],
527        $ECHO_TRAILING_KEY => [$ECHO_TRAILING_VALUE],
528    ];
529    $call = $stub->UnaryCall($request, $metadata);
530
531    $initial_metadata = $call->getMetadata();
532    hardAssert(array_key_exists($ECHO_INITIAL_KEY, $initial_metadata),
533               'Initial metadata does not contain expected key');
534    hardAssert(
535        $initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
536        'Incorrect initial metadata value');
537
538    list($result, $status) = $call->wait();
539    hardAssertIfStatusOk($status);
540
541    $trailing_metadata = $call->getTrailingMetadata();
542    hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata),
543               'Trailing metadata does not contain expected key');
544    hardAssert(
545        $trailing_metadata[$ECHO_TRAILING_KEY][0] === $ECHO_TRAILING_VALUE,
546        'Incorrect trailing metadata value');
547
548    $streaming_call = $stub->FullDuplexCall($metadata);
549
550    $streaming_request = new Grpc\Testing\StreamingOutputCallRequest();
551    $streaming_request->setPayload($payload);
552    $response_parameters = new Grpc\Testing\ResponseParameters();
553    $response_parameters->setSize($response_len);
554    $streaming_request->getResponseParameters()[] = $response_parameters;
555    $streaming_call->write($streaming_request);
556    $streaming_call->writesDone();
557    $result = $streaming_call->read();
558
559    hardAssertIfStatusOk($streaming_call->getStatus());
560
561    $streaming_initial_metadata = $streaming_call->getMetadata();
562    hardAssert(array_key_exists($ECHO_INITIAL_KEY, $streaming_initial_metadata),
563               'Initial metadata does not contain expected key');
564    hardAssert(
565        $streaming_initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
566        'Incorrect initial metadata value');
567
568    $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
569    hardAssert(array_key_exists($ECHO_TRAILING_KEY,
570                                $streaming_trailing_metadata),
571               'Trailing metadata does not contain expected key');
572    hardAssert($streaming_trailing_metadata[$ECHO_TRAILING_KEY][0] ===
573               $ECHO_TRAILING_VALUE, 'Incorrect trailing metadata value');
574}
575
576function statusCodeAndMessage($stub)
577{
578    $echo_status = new Grpc\Testing\EchoStatus();
579    $echo_status->setCode(2);
580    $echo_status->setMessage('test status message');
581
582    $request = new Grpc\Testing\SimpleRequest();
583    $request->setResponseStatus($echo_status);
584
585    $call = $stub->UnaryCall($request);
586    list($result, $status) = $call->wait();
587
588    hardAssert($status->code === 2,
589               'Received unexpected UnaryCall status code: '.
590               $status->code);
591    hardAssert($status->details === 'test status message',
592               'Received unexpected UnaryCall status details: '.
593               $status->details);
594
595    $streaming_call = $stub->FullDuplexCall();
596
597    $streaming_request = new Grpc\Testing\StreamingOutputCallRequest();
598    $streaming_request->setResponseStatus($echo_status);
599    $streaming_call->write($streaming_request);
600    $streaming_call->writesDone();
601    $result = $streaming_call->read();
602
603    $status = $streaming_call->getStatus();
604    hardAssert($status->code === 2,
605               'Received unexpected FullDuplexCall status code: '.
606               $status->code);
607    hardAssert($status->details === 'test status message',
608               'Received unexpected FullDuplexCall status details: '.
609               $status->details);
610}
611
612function specialStatusMessage($stub)
613{
614    $test_code = Grpc\STATUS_UNKNOWN;
615    $test_msg = "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP ��\t\n";
616
617    $echo_status = new Grpc\Testing\EchoStatus();
618    $echo_status->setCode($test_code);
619    $echo_status->setMessage($test_msg);
620
621    $request = new Grpc\Testing\SimpleRequest();
622    $request->setResponseStatus($echo_status);
623
624    $call = $stub->UnaryCall($request);
625    list($result, $status) = $call->wait();
626
627    hardAssert(
628        $status->code === $test_code,
629        'Received unexpected UnaryCall status code: ' . $status->code
630    );
631    hardAssert(
632        $status->details === $test_msg,
633        'Received unexpected UnaryCall status details: ' . $status->details
634    );
635}
636
637# NOTE: the stub input to this function is from UnimplementedService
638function unimplementedService($stub)
639{
640    $call = $stub->UnimplementedCall(new Grpc\Testing\EmptyMessage());
641    list($result, $status) = $call->wait();
642    hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
643               'Received unexpected status code');
644}
645
646# NOTE: the stub input to this function is from TestService
647function unimplementedMethod($stub)
648{
649    $call = $stub->UnimplementedCall(new Grpc\Testing\EmptyMessage());
650    list($result, $status) = $call->wait();
651    hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
652               'Received unexpected status code');
653}
654
655function _makeStub($args)
656{
657    if (!array_key_exists('server_host', $args)) {
658        throw new Exception('Missing argument: --server_host is required');
659    }
660    if (!array_key_exists('server_port', $args)) {
661        throw new Exception('Missing argument: --server_port is required');
662    }
663    if (!array_key_exists('test_case', $args)) {
664        throw new Exception('Missing argument: --test_case is required');
665    }
666
667    $server_address = $args['server_host'].':'.$args['server_port'];
668    $test_case = $args['test_case'];
669
670    $host_override = '';
671    if (array_key_exists('server_host_override', $args)) {
672        $host_override = $args['server_host_override'];
673    }
674
675    $use_tls = false;
676    if (array_key_exists('use_tls', $args) &&
677        $args['use_tls'] != 'false') {
678        $use_tls = true;
679    }
680
681    $use_test_ca = false;
682    if (array_key_exists('use_test_ca', $args) &&
683        $args['use_test_ca'] != 'false') {
684        $use_test_ca = true;
685    }
686
687    $opts = [];
688
689    if ($use_tls) {
690        if ($use_test_ca) {
691            $ssl_credentials = Grpc\ChannelCredentials::createSsl(
692                file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
693        } else {
694            $ssl_credentials = Grpc\ChannelCredentials::createSsl();
695        }
696        $opts['credentials'] = $ssl_credentials;
697        if (!empty($host_override)) {
698            $opts['grpc.ssl_target_name_override'] = $host_override;
699        }
700    } else {
701        $opts['credentials'] = Grpc\ChannelCredentials::createInsecure();
702    }
703
704    if (in_array($test_case, ['service_account_creds',
705                              'compute_engine_creds', 'jwt_token_creds', ])) {
706        if ($test_case === 'jwt_token_creds') {
707            $auth_credentials = ApplicationDefaultCredentials::getCredentials();
708        } else {
709            $auth_credentials = ApplicationDefaultCredentials::getCredentials(
710                $args['oauth_scope']
711            );
712        }
713        $opts['update_metadata'] = $auth_credentials->getUpdateMetadataFunc();
714    }
715
716    if ($test_case === 'oauth2_auth_token') {
717        $auth_credentials = ApplicationDefaultCredentials::getCredentials(
718            $args['oauth_scope']
719        );
720        $token = $auth_credentials->fetchAuthToken();
721        $update_metadata =
722            function ($metadata,
723                      $authUri = null,
724                      ClientInterface $client = null) use ($token) {
725                $metadata_copy = $metadata;
726                $metadata_copy[CredentialsLoader::AUTH_METADATA_KEY] =
727                    [sprintf('%s %s',
728                             $token['token_type'],
729                             $token['access_token'])];
730
731                return $metadata_copy;
732            };
733        $opts['update_metadata'] = $update_metadata;
734    }
735
736    if ($test_case === 'unimplemented_service') {
737        $stub = new Grpc\Testing\UnimplementedServiceClient($server_address,
738                                                            $opts);
739    } else {
740        $stub = new Grpc\Testing\TestServiceClient($server_address, $opts);
741    }
742
743    return $stub;
744}
745
746function interop_main($args, $stub = false)
747{
748    if (!$stub) {
749        $stub = _makeStub($args);
750    }
751
752    $test_case = $args['test_case'];
753    echo "Running test case $test_case\n";
754
755    switch ($test_case) {
756        case 'empty_unary':
757            emptyUnary($stub);
758            break;
759        case 'large_unary':
760            largeUnary($stub);
761            break;
762        case 'client_streaming':
763            clientStreaming($stub);
764            break;
765        case 'server_streaming':
766            serverStreaming($stub);
767            break;
768        case 'ping_pong':
769            pingPong($stub);
770            break;
771        case 'empty_stream':
772            emptyStream($stub);
773            break;
774        case 'cancel_after_begin':
775            cancelAfterBegin($stub);
776            break;
777        case 'cancel_after_first_response':
778            cancelAfterFirstResponse($stub);
779            break;
780        case 'timeout_on_sleeping_server':
781            timeoutOnSleepingServer($stub);
782            break;
783        case 'custom_metadata':
784            customMetadata($stub);
785            break;
786        case 'status_code_and_message':
787            statusCodeAndMessage($stub);
788            break;
789        case 'special_status_message':
790            specialStatusMessage($stub);
791        case 'unimplemented_service':
792            unimplementedService($stub);
793            break;
794        case 'unimplemented_method':
795            unimplementedMethod($stub);
796            break;
797        case 'service_account_creds':
798            serviceAccountCreds($stub, $args);
799            break;
800        case 'compute_engine_creds':
801            computeEngineCreds($stub, $args);
802            break;
803        case 'jwt_token_creds':
804            jwtTokenCreds($stub, $args);
805            break;
806        case 'oauth2_auth_token':
807            oauth2AuthToken($stub, $args);
808            break;
809        case 'per_rpc_creds':
810            perRpcCreds($stub, $args);
811            break;
812        case 'client_compressed_unary':
813            clientCompressedUnary($stub);
814            break;
815        case 'client_compressed_streaming':
816            clientCompressedStreaming($stub);
817            break;
818        default:
819            echo "Unsupported test case $test_case\n";
820            exit(1);
821    }
822
823    return $stub;
824}
825
826if (isset($_SERVER['PHP_SELF']) &&
827    preg_match('/interop_client/', $_SERVER['PHP_SELF'])) {
828    $args = getopt('', ['server_host:', 'server_port:', 'test_case:',
829                        'use_tls::', 'use_test_ca::',
830                        'server_host_override:', 'oauth_scope:',
831                        'default_service_account:', ]);
832    interop_main($args);
833}
834