diff --git a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_iam_policy.php b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_iam_policy.php index aec1dff68e18..0ed6e9ff44c5 100644 --- a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_iam_policy.php +++ b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_iam_policy.php @@ -24,7 +24,8 @@ // [START containeranalysis_v1_generated_ContainerAnalysis_GetIamPolicy_sync] use Google\ApiCore\ApiException; -use Google\Cloud\ContainerAnalysis\V1\ContainerAnalysisClient; +use Google\Cloud\ContainerAnalysis\V1\Client\ContainerAnalysisClient; +use Google\Cloud\Iam\V1\GetIamPolicyRequest; use Google\Cloud\Iam\V1\Policy; /** @@ -45,10 +46,14 @@ function get_iam_policy_sample(string $resource): void // Create a client. $containerAnalysisClient = new ContainerAnalysisClient(); + // Prepare the request message. + $request = (new GetIamPolicyRequest()) + ->setResource($resource); + // Call the API and handle any network failures. try { /** @var Policy $response */ - $response = $containerAnalysisClient->getIamPolicy($resource); + $response = $containerAnalysisClient->getIamPolicy($request); printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString()); } catch (ApiException $ex) { printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage()); diff --git a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_vulnerability_occurrences_summary.php b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_vulnerability_occurrences_summary.php index 28f82da2860c..108b3f7ba991 100644 --- a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_vulnerability_occurrences_summary.php +++ b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/get_vulnerability_occurrences_summary.php @@ -24,7 +24,8 @@ // [START containeranalysis_v1_generated_ContainerAnalysis_GetVulnerabilityOccurrencesSummary_sync] use Google\ApiCore\ApiException; -use Google\Cloud\ContainerAnalysis\V1\ContainerAnalysisClient; +use Google\Cloud\ContainerAnalysis\V1\Client\ContainerAnalysisClient; +use Google\Cloud\ContainerAnalysis\V1\GetVulnerabilityOccurrencesSummaryRequest; use Google\Cloud\ContainerAnalysis\V1\VulnerabilityOccurrencesSummary; /** @@ -39,10 +40,14 @@ function get_vulnerability_occurrences_summary_sample(string $formattedParent): // Create a client. $containerAnalysisClient = new ContainerAnalysisClient(); + // Prepare the request message. + $request = (new GetVulnerabilityOccurrencesSummaryRequest()) + ->setParent($formattedParent); + // Call the API and handle any network failures. try { /** @var VulnerabilityOccurrencesSummary $response */ - $response = $containerAnalysisClient->getVulnerabilityOccurrencesSummary($formattedParent); + $response = $containerAnalysisClient->getVulnerabilityOccurrencesSummary($request); printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString()); } catch (ApiException $ex) { printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage()); diff --git a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/set_iam_policy.php b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/set_iam_policy.php index 506ebab4f456..0b954311219a 100644 --- a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/set_iam_policy.php +++ b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/set_iam_policy.php @@ -24,8 +24,9 @@ // [START containeranalysis_v1_generated_ContainerAnalysis_SetIamPolicy_sync] use Google\ApiCore\ApiException; -use Google\Cloud\ContainerAnalysis\V1\ContainerAnalysisClient; +use Google\Cloud\ContainerAnalysis\V1\Client\ContainerAnalysisClient; use Google\Cloud\Iam\V1\Policy; +use Google\Cloud\Iam\V1\SetIamPolicyRequest; /** * Sets the access control policy on the specified note or occurrence. @@ -45,13 +46,16 @@ function set_iam_policy_sample(string $resource): void // Create a client. $containerAnalysisClient = new ContainerAnalysisClient(); - // Prepare any non-scalar elements to be passed along with the request. + // Prepare the request message. $policy = new Policy(); + $request = (new SetIamPolicyRequest()) + ->setResource($resource) + ->setPolicy($policy); // Call the API and handle any network failures. try { /** @var Policy $response */ - $response = $containerAnalysisClient->setIamPolicy($resource, $policy); + $response = $containerAnalysisClient->setIamPolicy($request); printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString()); } catch (ApiException $ex) { printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage()); diff --git a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/test_iam_permissions.php b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/test_iam_permissions.php index 5da3200a4d4f..897de18d219f 100644 --- a/ContainerAnalysis/samples/V1/ContainerAnalysisClient/test_iam_permissions.php +++ b/ContainerAnalysis/samples/V1/ContainerAnalysisClient/test_iam_permissions.php @@ -24,7 +24,8 @@ // [START containeranalysis_v1_generated_ContainerAnalysis_TestIamPermissions_sync] use Google\ApiCore\ApiException; -use Google\Cloud\ContainerAnalysis\V1\ContainerAnalysisClient; +use Google\Cloud\ContainerAnalysis\V1\Client\ContainerAnalysisClient; +use Google\Cloud\Iam\V1\TestIamPermissionsRequest; use Google\Cloud\Iam\V1\TestIamPermissionsResponse; /** @@ -48,13 +49,16 @@ function test_iam_permissions_sample(string $resource, string $permissionsElemen // Create a client. $containerAnalysisClient = new ContainerAnalysisClient(); - // Prepare any non-scalar elements to be passed along with the request. + // Prepare the request message. $permissions = [$permissionsElement,]; + $request = (new TestIamPermissionsRequest()) + ->setResource($resource) + ->setPermissions($permissions); // Call the API and handle any network failures. try { /** @var TestIamPermissionsResponse $response */ - $response = $containerAnalysisClient->testIamPermissions($resource, $permissions); + $response = $containerAnalysisClient->testIamPermissions($request); printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString()); } catch (ApiException $ex) { printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage()); diff --git a/ContainerAnalysis/src/V1/Client/BaseClient/ContainerAnalysisBaseClient.php b/ContainerAnalysis/src/V1/Client/BaseClient/ContainerAnalysisBaseClient.php new file mode 100644 index 000000000000..c3c16cae0235 --- /dev/null +++ b/ContainerAnalysis/src/V1/Client/BaseClient/ContainerAnalysisBaseClient.php @@ -0,0 +1,344 @@ + self::SERVICE_NAME, + 'apiEndpoint' => self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT, + 'clientConfig' => __DIR__ . '/../../resources/container_analysis_client_config.json', + 'descriptorsConfigPath' => __DIR__ . '/../../resources/container_analysis_descriptor_config.php', + 'gcpApiConfigPath' => __DIR__ . '/../../resources/container_analysis_grpc_config.json', + 'credentialsConfig' => [ + 'defaultScopes' => self::$serviceScopes, + ], + 'transportConfig' => [ + 'rest' => [ + 'restClientConfigPath' => __DIR__ . '/../../resources/container_analysis_rest_client_config.php', + ], + ], + ]; + } + + /** + * Formats a string containing the fully-qualified path to represent a project + * resource. + * + * @param string $project + * + * @return string The formatted project resource. + */ + public static function projectName(string $project): string + { + return self::getPathTemplate('project')->render([ + 'project' => $project, + ]); + } + + /** + * Parses a formatted name string and returns an associative array of the components in the name. + * The following name formats are supported: + * Template: Pattern + * - project: projects/{project} + * + * The optional $template argument can be supplied to specify a particular pattern, + * and must match one of the templates listed above. If no $template argument is + * provided, or if the $template argument does not match one of the templates + * listed, then parseName will check each of the supported templates, and return + * the first match. + * + * @param string $formattedName The formatted name string + * @param string $template Optional name of template to match + * + * @return array An associative array from name component IDs to component values. + * + * @throws ValidationException If $formattedName could not be matched. + */ + public static function parseName(string $formattedName, string $template = null): array + { + return self::parseFormattedName($formattedName, $template); + } + + /** + * Constructor. + * + * @param array $options { + * Optional. Options for configuring the service API wrapper. + * + * @type string $apiEndpoint + * The address of the API remote host. May optionally include the port, formatted + * as ":". Default 'containeranalysis.googleapis.com:443'. + * @type string|array|FetchAuthTokenInterface|CredentialsWrapper $credentials + * The credentials to be used by the client to authorize API calls. This option + * accepts either a path to a credentials file, or a decoded credentials file as a + * PHP array. + * *Advanced usage*: In addition, this option can also accept a pre-constructed + * {@see \Google\Auth\FetchAuthTokenInterface} object or + * {@see \Google\ApiCore\CredentialsWrapper} object. Note that when one of these + * objects are provided, any settings in $credentialsConfig will be ignored. + * @type array $credentialsConfig + * Options used to configure credentials, including auth token caching, for the + * client. For a full list of supporting configuration options, see + * {@see \Google\ApiCore\CredentialsWrapper::build()} . + * @type bool $disableRetries + * Determines whether or not retries defined by the client configuration should be + * disabled. Defaults to `false`. + * @type string|array $clientConfig + * Client method configuration, including retry settings. This option can be either + * a path to a JSON file, or a PHP array containing the decoded JSON data. By + * default this settings points to the default client config file, which is + * provided in the resources folder. + * @type string|TransportInterface $transport + * The transport used for executing network requests. May be either the string + * `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system. + * *Advanced usage*: Additionally, it is possible to pass in an already + * instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note + * that when this object is provided, any settings in $transportConfig, and any + * $apiEndpoint setting, will be ignored. + * @type array $transportConfig + * Configuration options that will be used to construct the transport. Options for + * each supported transport type should be passed in a key for that transport. For + * example: + * $transportConfig = [ + * 'grpc' => [...], + * 'rest' => [...], + * ]; + * See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and + * {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the + * supported options. + * @type callable $clientCertSource + * A callable which returns the client cert as a string. This can be used to + * provide a certificate and private key to the transport layer for mTLS. + * } + * + * @throws ValidationException + */ + public function __construct(array $options = []) + { + $clientOptions = $this->buildClientOptions($options); + $this->setClientOptions($clientOptions); + } + + /** Handles execution of the async variants for each documented method. */ + public function __call($method, $args) + { + if (substr($method, -5) !== 'Async') { + trigger_error('Call to undefined method ' . __CLASS__ . "::$method()", E_USER_ERROR); + } + + array_unshift($args, substr($method, 0, -5)); + return call_user_func_array([$this, 'startAsyncCall'], $args); + } + + /** + * Gets the access control policy for a note or an occurrence resource. + * Requires `containeranalysis.notes.setIamPolicy` or + * `containeranalysis.occurrences.setIamPolicy` permission if the resource is + * a note or occurrence, respectively. + * + * The resource takes the format `projects/[PROJECT_ID]/notes/[NOTE_ID]` for + * notes and `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]` for + * occurrences. + * + * The async variant is {@see self::getIamPolicyAsync()} . + * + * @param GetIamPolicyRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return Policy + * + * @throws ApiException Thrown if the API call fails. + */ + public function getIamPolicy(GetIamPolicyRequest $request, array $callOptions = []): Policy + { + return $this->startApiCall('GetIamPolicy', $request, $callOptions)->wait(); + } + + /** + * Gets a summary of the number and severity of occurrences. + * + * The async variant is {@see self::getVulnerabilityOccurrencesSummaryAsync()} . + * + * @param GetVulnerabilityOccurrencesSummaryRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return VulnerabilityOccurrencesSummary + * + * @throws ApiException Thrown if the API call fails. + */ + public function getVulnerabilityOccurrencesSummary(GetVulnerabilityOccurrencesSummaryRequest $request, array $callOptions = []): VulnerabilityOccurrencesSummary + { + return $this->startApiCall('GetVulnerabilityOccurrencesSummary', $request, $callOptions)->wait(); + } + + /** + * Sets the access control policy on the specified note or occurrence. + * Requires `containeranalysis.notes.setIamPolicy` or + * `containeranalysis.occurrences.setIamPolicy` permission if the resource is + * a note or an occurrence, respectively. + * + * The resource takes the format `projects/[PROJECT_ID]/notes/[NOTE_ID]` for + * notes and `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]` for + * occurrences. + * + * The async variant is {@see self::setIamPolicyAsync()} . + * + * @param SetIamPolicyRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return Policy + * + * @throws ApiException Thrown if the API call fails. + */ + public function setIamPolicy(SetIamPolicyRequest $request, array $callOptions = []): Policy + { + return $this->startApiCall('SetIamPolicy', $request, $callOptions)->wait(); + } + + /** + * Returns the permissions that a caller has on the specified note or + * occurrence. Requires list permission on the project (for example, + * `containeranalysis.notes.list`). + * + * The resource takes the format `projects/[PROJECT_ID]/notes/[NOTE_ID]` for + * notes and `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]` for + * occurrences. + * + * The async variant is {@see self::testIamPermissionsAsync()} . + * + * @param TestIamPermissionsRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return TestIamPermissionsResponse + * + * @throws ApiException Thrown if the API call fails. + */ + public function testIamPermissions(TestIamPermissionsRequest $request, array $callOptions = []): TestIamPermissionsResponse + { + return $this->startApiCall('TestIamPermissions', $request, $callOptions)->wait(); + } +} diff --git a/ContainerAnalysis/src/V1/Client/ContainerAnalysisClient.php b/ContainerAnalysis/src/V1/Client/ContainerAnalysisClient.php new file mode 100644 index 000000000000..a15c4877553d --- /dev/null +++ b/ContainerAnalysis/src/V1/Client/ContainerAnalysisClient.php @@ -0,0 +1,40 @@ +setParent($parent) + ->setFilter($filter); + } + /** * Constructor. * diff --git a/ContainerAnalysis/src/V1/resources/container_analysis_descriptor_config.php b/ContainerAnalysis/src/V1/resources/container_analysis_descriptor_config.php index f4ff205caae3..864aead92eb2 100644 --- a/ContainerAnalysis/src/V1/resources/container_analysis_descriptor_config.php +++ b/ContainerAnalysis/src/V1/resources/container_analysis_descriptor_config.php @@ -2,6 +2,58 @@ return [ 'interfaces' => [ - 'google.devtools.containeranalysis.v1.ContainerAnalysis' => [], + 'google.devtools.containeranalysis.v1.ContainerAnalysis' => [ + 'GetIamPolicy' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\Cloud\Iam\V1\Policy', + 'headerParams' => [ + [ + 'keyName' => 'resource', + 'fieldAccessors' => [ + 'getResource', + ], + ], + ], + ], + 'GetVulnerabilityOccurrencesSummary' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\Cloud\ContainerAnalysis\V1\VulnerabilityOccurrencesSummary', + 'headerParams' => [ + [ + 'keyName' => 'parent', + 'fieldAccessors' => [ + 'getParent', + ], + ], + ], + ], + 'SetIamPolicy' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\Cloud\Iam\V1\Policy', + 'headerParams' => [ + [ + 'keyName' => 'resource', + 'fieldAccessors' => [ + 'getResource', + ], + ], + ], + ], + 'TestIamPermissions' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\Cloud\Iam\V1\TestIamPermissionsResponse', + 'headerParams' => [ + [ + 'keyName' => 'resource', + 'fieldAccessors' => [ + 'getResource', + ], + ], + ], + ], + 'templateMap' => [ + 'project' => 'projects/{project}', + ], + ], ], ]; diff --git a/ContainerAnalysis/tests/Unit/V1/Client/ContainerAnalysisClientTest.php b/ContainerAnalysis/tests/Unit/V1/Client/ContainerAnalysisClientTest.php new file mode 100644 index 000000000000..0fa831dca534 --- /dev/null +++ b/ContainerAnalysis/tests/Unit/V1/Client/ContainerAnalysisClientTest.php @@ -0,0 +1,366 @@ +getMockBuilder(CredentialsWrapper::class)->disableOriginalConstructor()->getMock(); + } + + /** @return ContainerAnalysisClient */ + private function createClient(array $options = []) + { + $options += [ + 'credentials' => $this->createCredentials(), + ]; + return new ContainerAnalysisClient($options); + } + + /** @test */ + public function getIamPolicyTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $version = 351608024; + $etag = '21'; + $expectedResponse = new Policy(); + $expectedResponse->setVersion($version); + $expectedResponse->setEtag($etag); + $transport->addResponse($expectedResponse); + // Mock request + $resource = 'resource-341064690'; + $request = (new GetIamPolicyRequest()) + ->setResource($resource); + $response = $gapicClient->getIamPolicy($request); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.devtools.containeranalysis.v1.ContainerAnalysis/GetIamPolicy', $actualFuncCall); + $actualValue = $actualRequestObject->getResource(); + $this->assertProtobufEquals($resource, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function getIamPolicyExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $resource = 'resource-341064690'; + $request = (new GetIamPolicyRequest()) + ->setResource($resource); + try { + $gapicClient->getIamPolicy($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function getVulnerabilityOccurrencesSummaryTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $expectedResponse = new VulnerabilityOccurrencesSummary(); + $transport->addResponse($expectedResponse); + // Mock request + $formattedParent = $gapicClient->projectName('[PROJECT]'); + $request = (new GetVulnerabilityOccurrencesSummaryRequest()) + ->setParent($formattedParent); + $response = $gapicClient->getVulnerabilityOccurrencesSummary($request); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.devtools.containeranalysis.v1.ContainerAnalysis/GetVulnerabilityOccurrencesSummary', $actualFuncCall); + $actualValue = $actualRequestObject->getParent(); + $this->assertProtobufEquals($formattedParent, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function getVulnerabilityOccurrencesSummaryExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $formattedParent = $gapicClient->projectName('[PROJECT]'); + $request = (new GetVulnerabilityOccurrencesSummaryRequest()) + ->setParent($formattedParent); + try { + $gapicClient->getVulnerabilityOccurrencesSummary($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function setIamPolicyTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $version = 351608024; + $etag = '21'; + $expectedResponse = new Policy(); + $expectedResponse->setVersion($version); + $expectedResponse->setEtag($etag); + $transport->addResponse($expectedResponse); + // Mock request + $resource = 'resource-341064690'; + $policy = new Policy(); + $request = (new SetIamPolicyRequest()) + ->setResource($resource) + ->setPolicy($policy); + $response = $gapicClient->setIamPolicy($request); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.devtools.containeranalysis.v1.ContainerAnalysis/SetIamPolicy', $actualFuncCall); + $actualValue = $actualRequestObject->getResource(); + $this->assertProtobufEquals($resource, $actualValue); + $actualValue = $actualRequestObject->getPolicy(); + $this->assertProtobufEquals($policy, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function setIamPolicyExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $resource = 'resource-341064690'; + $policy = new Policy(); + $request = (new SetIamPolicyRequest()) + ->setResource($resource) + ->setPolicy($policy); + try { + $gapicClient->setIamPolicy($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function testIamPermissionsTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $expectedResponse = new TestIamPermissionsResponse(); + $transport->addResponse($expectedResponse); + // Mock request + $resource = 'resource-341064690'; + $permissions = []; + $request = (new TestIamPermissionsRequest()) + ->setResource($resource) + ->setPermissions($permissions); + $response = $gapicClient->testIamPermissions($request); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.devtools.containeranalysis.v1.ContainerAnalysis/TestIamPermissions', $actualFuncCall); + $actualValue = $actualRequestObject->getResource(); + $this->assertProtobufEquals($resource, $actualValue); + $actualValue = $actualRequestObject->getPermissions(); + $this->assertProtobufEquals($permissions, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function testIamPermissionsExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $resource = 'resource-341064690'; + $permissions = []; + $request = (new TestIamPermissionsRequest()) + ->setResource($resource) + ->setPermissions($permissions); + try { + $gapicClient->testIamPermissions($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function getIamPolicyAsyncTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $version = 351608024; + $etag = '21'; + $expectedResponse = new Policy(); + $expectedResponse->setVersion($version); + $expectedResponse->setEtag($etag); + $transport->addResponse($expectedResponse); + // Mock request + $resource = 'resource-341064690'; + $request = (new GetIamPolicyRequest()) + ->setResource($resource); + $response = $gapicClient->getIamPolicyAsync($request)->wait(); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.devtools.containeranalysis.v1.ContainerAnalysis/GetIamPolicy', $actualFuncCall); + $actualValue = $actualRequestObject->getResource(); + $this->assertProtobufEquals($resource, $actualValue); + $this->assertTrue($transport->isExhausted()); + } +}