2424use Google \Cloud \TestUtils \TestTrait ;
2525use PHPUnitRetry \RetryTrait ;
2626use PHPUnit \Framework \TestCase ;
27+ use Google \Auth \ApplicationDefaultCredentials ;
28+ use GuzzleHttp \Client ;
29+ use GuzzleHttp \HandlerStack ;
2730
2831/**
2932 * @retryAttempts 3
@@ -95,6 +98,12 @@ class spannerTest extends TestCase
9598 /** @var InstanceConfiguration $customInstanceConfig */
9699 protected static $ customInstanceConfig ;
97100
101+ /** @var string $databaseRole */
102+ protected static $ databaseRole ;
103+
104+ /** @var string serviceAccountEmail */
105+ protected static $ serviceAccountEmail = null ;
106+
98107 public static function setUpBeforeClass (): void
99108 {
100109 self ::checkProjectEnvVars ();
@@ -126,6 +135,7 @@ public static function setUpBeforeClass(): void
126135 self ::$ baseConfigId = 'nam7 ' ;
127136 self ::$ customInstanceConfigId = 'custom- ' . time () . rand ();
128137 self ::$ customInstanceConfig = $ spanner ->instanceConfiguration (self ::$ customInstanceConfigId );
138+ self ::$ databaseRole = 'new_parent ' ;
129139 }
130140
131141 public function testCreateInstance ()
@@ -932,10 +942,50 @@ public function testDmlReturningDelete()
932942 public function testAddDropDatabaseRole ()
933943 {
934944 $ output = $ this ->runFunctionSnippet ('add_drop_database_role ' );
935- $ this ->assertStringContainsString ('Waiting for create role and grant operation to complete... ' . PHP_EOL , $ output );
936- $ this ->assertStringContainsString ('Created roles new_parent and new_child and granted privileges ' . PHP_EOL , $ output );
937- $ this ->assertStringContainsString ('Waiting for revoke role and drop role operation to complete... ' . PHP_EOL , $ output );
938- $ this ->assertStringContainsString ('Revoked privileges and dropped roles new_child and new_parent ' . PHP_EOL , $ output );
945+ $ this ->assertStringContainsString ('Waiting for create role and grant operation to complete... ' . PHP_EOL , $ output );
946+ $ this ->assertStringContainsString ('Created roles new_parent and new_child and granted privileges ' . PHP_EOL , $ output );
947+ $ this ->assertStringContainsString ('Waiting for revoke role and drop role operation to complete... ' . PHP_EOL , $ output );
948+ $ this ->assertStringContainsString ('Revoked privileges and dropped role new_child ' . PHP_EOL , $ output );
949+ }
950+
951+ /**
952+ * @depends testAddDropDatabaseRole
953+ */
954+ public function testListDatabaseRoles ()
955+ {
956+ $ output = $ this ->runFunctionSnippet ('list_database_roles ' , [
957+ self ::$ projectId ,
958+ self ::$ instanceId ,
959+ self ::$ databaseId
960+ ]);
961+ $ this ->assertStringContainsString (sprintf ('databaseRoles/%s ' , self ::$ databaseRole ), $ output );
962+ }
963+
964+ /**
965+ * @depends testAddDropDatabaseRole
966+ * @depends testInsertDataWithDml
967+ */
968+ public function testReadDataWithDatabaseRole ()
969+ {
970+ $ output = $ this ->runFunctionSnippet ('read_data_with_database_role ' );
971+ $ this ->assertStringContainsString ('SingerId: 10, Firstname: Virginia, LastName: Watson ' , $ output );
972+ }
973+
974+ /**
975+ * depends testAddDropDatabaseRole
976+ */
977+ public function testEnableFineGrainedAccess ()
978+ {
979+ self ::$ serviceAccountEmail = $ this ->createServiceAccount (str_shuffle ('testSvcAcnt ' ));
980+ $ output = $ this ->runFunctionSnippet ('enable_fine_grained_access ' , [
981+ self ::$ projectId ,
982+ self ::$ instanceId ,
983+ self ::$ databaseId ,
984+ sprintf ('serviceAccount:%s ' , self ::$ serviceAccountEmail ),
985+ self ::$ databaseRole ,
986+ 'DatabaseRoleBindingTitle '
987+ ]);
988+ $ this ->assertStringContainsString ('Enabled fine-grained access in IAM ' , $ output );
939989 }
940990
941991 /**
@@ -1029,6 +1079,49 @@ private function runFunctionSnippet($sampleName, $params = [])
10291079 );
10301080 }
10311081
1082+ private function createServiceAccount ($ serviceAccountId )
1083+ {
1084+ $ client = self ::getIamHttpClient ();
1085+ // make the request
1086+ $ response = $ client ->post ('/v1/projects/ ' . self ::$ projectId . '/serviceAccounts ' , [
1087+ 'json ' => [
1088+ 'accountId ' => $ serviceAccountId ,
1089+ 'serviceAccount ' => [
1090+ 'displayName ' => 'Test Service Account ' ,
1091+ 'description ' => 'This account should be deleted automatically after the unit tests complete. '
1092+ ]
1093+ ]
1094+ ]);
1095+
1096+ return json_decode ($ response ->getBody ())->email ;
1097+ }
1098+
1099+ public static function deleteServiceAccount ($ serviceAccountEmail )
1100+ {
1101+ $ client = self ::getIamHttpClient ();
1102+ // make the request
1103+ $ client ->delete ('/v1/projects/ ' . self ::$ projectId . '/serviceAccounts/ ' . $ serviceAccountEmail );
1104+ }
1105+
1106+ private static function getIamHttpClient ()
1107+ {
1108+ // TODO: When this method is exposed in googleapis/google-cloud-php, remove the use of the following
1109+ $ scopes = ['https://www.googleapis.com/auth/cloud-platform ' ];
1110+
1111+ // create middleware
1112+ $ middleware = ApplicationDefaultCredentials::getMiddleware ($ scopes );
1113+ $ stack = HandlerStack::create ();
1114+ $ stack ->push ($ middleware );
1115+
1116+ // create the HTTP client
1117+ $ client = new Client ([
1118+ 'handler ' => $ stack ,
1119+ 'base_uri ' => 'https://iam.googleapis.com ' ,
1120+ 'auth ' => 'google_auth ' // authorize all requests
1121+ ]);
1122+ return $ client ;
1123+ }
1124+
10321125 public static function tearDownAfterClass (): void
10331126 {
10341127 if (self ::$ instance ->exists ()) {// Clean up database
@@ -1042,5 +1135,8 @@ public static function tearDownAfterClass(): void
10421135 if (self ::$ customInstanceConfig ->exists ()) {
10431136 self ::$ customInstanceConfig ->delete ();
10441137 }
1138+ if (!is_null (self ::$ serviceAccountEmail )) {
1139+ self ::deleteServiceAccount (self ::$ serviceAccountEmail );
1140+ }
10451141 }
10461142}
0 commit comments