interop_client.php 27 KB

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