1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "google/cloud/spanner/internal/database_admin_metadata.h"
16 #include "google/cloud/spanner/testing/mock_database_admin_stub.h"
17 #include "google/cloud/internal/api_client_header.h"
18 #include "google/cloud/testing_util/assert_ok.h"
19 #include "google/cloud/testing_util/validate_metadata.h"
20 #include <gmock/gmock.h>
21 
22 namespace google {
23 namespace cloud {
24 namespace spanner {
25 inline namespace SPANNER_CLIENT_NS {
26 namespace internal {
27 namespace {
28 
29 using ::google::cloud::testing_util::IsContextMDValid;
30 using ::testing::_;
31 namespace gcsa = ::google::spanner::admin::database::v1;
32 
33 class DatabaseAdminMetadataTest : public ::testing::Test {
34  protected:
SetUp()35   void SetUp() override {
36     mock_ = std::make_shared<spanner_testing::MockDatabaseAdminStub>();
37     DatabaseAdminMetadata stub(mock_);
38     expected_api_client_header_ = google::cloud::internal::ApiClientHeader();
39   }
40 
TearDown()41   void TearDown() override {}
42 
TransientError()43   static Status TransientError() {
44     return Status(StatusCode::kUnavailable, "try-again");
45   }
46 
47   std::shared_ptr<spanner_testing::MockDatabaseAdminStub> mock_;
48   std::string expected_api_client_header_;
49 };
50 
TEST_F(DatabaseAdminMetadataTest,CreateDatabase)51 TEST_F(DatabaseAdminMetadataTest, CreateDatabase) {
52   EXPECT_CALL(*mock_, CreateDatabase(_, _))
53       .WillOnce([this](grpc::ClientContext& context,
54                        gcsa::CreateDatabaseRequest const&) {
55         EXPECT_STATUS_OK(
56             IsContextMDValid(context,
57                              "google.spanner.admin.database.v1.DatabaseAdmin."
58                              "CreateDatabase",
59                              expected_api_client_header_));
60         return TransientError();
61       });
62 
63   DatabaseAdminMetadata stub(mock_);
64   grpc::ClientContext context;
65   gcsa::CreateDatabaseRequest request;
66   request.set_parent(
67       "projects/test-project-id/"
68       "instances/test-instance-id");
69   auto status = stub.CreateDatabase(context, request);
70   EXPECT_EQ(TransientError(), status.status());
71 }
72 
TEST_F(DatabaseAdminMetadataTest,UpdateDatabase)73 TEST_F(DatabaseAdminMetadataTest, UpdateDatabase) {
74   EXPECT_CALL(*mock_, UpdateDatabase(_, _))
75       .WillOnce([this](grpc::ClientContext& context,
76                        gcsa::UpdateDatabaseDdlRequest const&) {
77         EXPECT_STATUS_OK(
78             IsContextMDValid(context,
79                              "google.spanner.admin.database.v1.DatabaseAdmin."
80                              "UpdateDatabaseDdl",
81                              expected_api_client_header_));
82         return TransientError();
83       });
84 
85   DatabaseAdminMetadata stub(mock_);
86   grpc::ClientContext context;
87   gcsa::UpdateDatabaseDdlRequest request;
88   request.set_database(
89       "projects/test-project-id/"
90       "instances/test-instance-id/"
91       "databases/test-database");
92   auto status = stub.UpdateDatabase(context, request);
93   EXPECT_EQ(TransientError(), status.status());
94 }
95 
TEST_F(DatabaseAdminMetadataTest,DropDatabase)96 TEST_F(DatabaseAdminMetadataTest, DropDatabase) {
97   EXPECT_CALL(*mock_, DropDatabase(_, _))
98       .WillOnce([this](grpc::ClientContext& context,
99                        gcsa::DropDatabaseRequest const&) {
100         EXPECT_STATUS_OK(
101             IsContextMDValid(context,
102                              "google.spanner.admin.database.v1.DatabaseAdmin."
103                              "DropDatabase",
104                              expected_api_client_header_));
105         return TransientError();
106       });
107 
108   DatabaseAdminMetadata stub(mock_);
109   grpc::ClientContext context;
110   gcsa::DropDatabaseRequest request;
111   request.set_database(
112       "projects/test-project-id/"
113       "instances/test-instance-id/"
114       "databases/test-database");
115   auto status = stub.DropDatabase(context, request);
116   EXPECT_EQ(TransientError(), status);
117 }
118 
TEST_F(DatabaseAdminMetadataTest,ListDatabases)119 TEST_F(DatabaseAdminMetadataTest, ListDatabases) {
120   EXPECT_CALL(*mock_, ListDatabases(_, _))
121       .WillOnce([this](grpc::ClientContext& context,
122                        gcsa::ListDatabasesRequest const&) {
123         EXPECT_STATUS_OK(
124             IsContextMDValid(context,
125                              "google.spanner.admin.database.v1.DatabaseAdmin."
126                              "ListDatabases",
127                              expected_api_client_header_));
128         return TransientError();
129       });
130 
131   DatabaseAdminMetadata stub(mock_);
132   grpc::ClientContext context;
133   gcsa::ListDatabasesRequest request;
134   request.set_parent(
135       "projects/test-project-id/"
136       "instances/test-instance-id");
137   auto response = stub.ListDatabases(context, request);
138   EXPECT_EQ(TransientError(), response.status());
139 }
140 
TEST_F(DatabaseAdminMetadataTest,RestoreDatabase)141 TEST_F(DatabaseAdminMetadataTest, RestoreDatabase) {
142   EXPECT_CALL(*mock_, RestoreDatabase(_, _))
143       .WillOnce([this](grpc::ClientContext& context,
144                        gcsa::RestoreDatabaseRequest const&) {
145         EXPECT_STATUS_OK(
146             IsContextMDValid(context,
147                              "google.spanner.admin.database.v1.DatabaseAdmin."
148                              "RestoreDatabase",
149                              expected_api_client_header_));
150         return TransientError();
151       });
152 
153   DatabaseAdminMetadata stub(mock_);
154   grpc::ClientContext context;
155   gcsa::RestoreDatabaseRequest request;
156   request.set_parent(
157       "projects/test-project-id/"
158       "instances/test-instance-id");
159   auto status = stub.RestoreDatabase(context, request);
160   EXPECT_EQ(TransientError(), status.status());
161 }
162 
TEST_F(DatabaseAdminMetadataTest,GetIamPolicy)163 TEST_F(DatabaseAdminMetadataTest, GetIamPolicy) {
164   EXPECT_CALL(*mock_, GetIamPolicy(_, _))
165       .WillOnce([this](grpc::ClientContext& context,
166                        google::iam::v1::GetIamPolicyRequest const&) {
167         EXPECT_STATUS_OK(
168             IsContextMDValid(context,
169                              "google.spanner.admin.database.v1.DatabaseAdmin."
170                              "GetIamPolicy",
171                              expected_api_client_header_));
172         return TransientError();
173       });
174 
175   DatabaseAdminMetadata stub(mock_);
176   grpc::ClientContext context;
177   google::iam::v1::GetIamPolicyRequest request;
178   request.set_resource(
179       "projects/test-project-id/"
180       "instances/test-instance-id/"
181       "databases/test-database");
182   auto response = stub.GetIamPolicy(context, request);
183   EXPECT_EQ(TransientError(), response.status());
184 }
185 
TEST_F(DatabaseAdminMetadataTest,SetIamPolicy)186 TEST_F(DatabaseAdminMetadataTest, SetIamPolicy) {
187   EXPECT_CALL(*mock_, SetIamPolicy(_, _))
188       .WillOnce([this](grpc::ClientContext& context,
189                        google::iam::v1::SetIamPolicyRequest const&) {
190         EXPECT_STATUS_OK(
191             IsContextMDValid(context,
192                              "google.spanner.admin.database.v1.DatabaseAdmin."
193                              "SetIamPolicy",
194                              expected_api_client_header_));
195         return TransientError();
196       });
197 
198   DatabaseAdminMetadata stub(mock_);
199   grpc::ClientContext context;
200   google::iam::v1::SetIamPolicyRequest request;
201   request.set_resource(
202       "projects/test-project-id/"
203       "instances/test-instance-id/"
204       "databases/test-database");
205   google::iam::v1::Policy policy;
206   auto& binding = *policy.add_bindings();
207   binding.set_role("roles/spanner.databaseReader");
208   *binding.add_members() = "user:foobar@example.com";
209   *request.mutable_policy() = std::move(policy);
210 
211   auto response = stub.SetIamPolicy(context, request);
212   EXPECT_EQ(TransientError(), response.status());
213 }
214 
TEST_F(DatabaseAdminMetadataTest,TestIamPermissions)215 TEST_F(DatabaseAdminMetadataTest, TestIamPermissions) {
216   EXPECT_CALL(*mock_, TestIamPermissions(_, _))
217       .WillOnce([this](grpc::ClientContext& context,
218                        google::iam::v1::TestIamPermissionsRequest const&) {
219         EXPECT_STATUS_OK(
220             IsContextMDValid(context,
221                              "google.spanner.admin.database.v1.DatabaseAdmin."
222                              "TestIamPermissions",
223                              expected_api_client_header_));
224         return TransientError();
225       });
226 
227   DatabaseAdminMetadata stub(mock_);
228   grpc::ClientContext context;
229   google::iam::v1::TestIamPermissionsRequest request;
230   request.set_resource(
231       "projects/test-project-id/"
232       "instances/test-instance-id/"
233       "databases/test-database");
234   auto response = stub.TestIamPermissions(context, request);
235   EXPECT_EQ(TransientError(), response.status());
236 }
237 
TEST_F(DatabaseAdminMetadataTest,CreateBackup)238 TEST_F(DatabaseAdminMetadataTest, CreateBackup) {
239   EXPECT_CALL(*mock_, CreateBackup(_, _))
240       .WillOnce([this](grpc::ClientContext& context,
241                        gcsa::CreateBackupRequest const&) {
242         EXPECT_STATUS_OK(
243             IsContextMDValid(context,
244                              "google.spanner.admin.database.v1.DatabaseAdmin."
245                              "CreateBackup",
246                              expected_api_client_header_));
247         return TransientError();
248       });
249 
250   DatabaseAdminMetadata stub(mock_);
251   grpc::ClientContext context;
252   gcsa::CreateBackupRequest request;
253   request.set_parent(
254       "projects/test-project-id/"
255       "instances/test-instance-id");
256   auto status = stub.CreateBackup(context, request);
257   EXPECT_EQ(TransientError(), status.status());
258 }
259 
TEST_F(DatabaseAdminMetadataTest,GetBackup)260 TEST_F(DatabaseAdminMetadataTest, GetBackup) {
261   EXPECT_CALL(*mock_, GetBackup(_, _))
262       .WillOnce(
263           [this](grpc::ClientContext& context, gcsa::GetBackupRequest const&) {
264             EXPECT_STATUS_OK(IsContextMDValid(
265                 context,
266                 "google.spanner.admin.database.v1.DatabaseAdmin."
267                 "GetBackup",
268                 expected_api_client_header_));
269             return TransientError();
270           });
271 
272   DatabaseAdminMetadata stub(mock_);
273   grpc::ClientContext context;
274   gcsa::GetBackupRequest request;
275   request.set_name(
276       "projects/test-project-id/"
277       "instances/test-instance-id/"
278       "backups/test-backup-id");
279   auto status = stub.GetBackup(context, request);
280   EXPECT_EQ(TransientError(), status.status());
281 }
282 
TEST_F(DatabaseAdminMetadataTest,DeleteBackup)283 TEST_F(DatabaseAdminMetadataTest, DeleteBackup) {
284   EXPECT_CALL(*mock_, DeleteBackup(_, _))
285       .WillOnce([this](grpc::ClientContext& context,
286                        gcsa::DeleteBackupRequest const&) {
287         EXPECT_STATUS_OK(
288             IsContextMDValid(context,
289                              "google.spanner.admin.database.v1.DatabaseAdmin."
290                              "DeleteBackup",
291                              expected_api_client_header_));
292         return TransientError();
293       });
294 
295   DatabaseAdminMetadata stub(mock_);
296   grpc::ClientContext context;
297   gcsa::DeleteBackupRequest request;
298   request.set_name(
299       "projects/test-project-id/"
300       "instances/test-instance-id/"
301       "backups/test-backup");
302   auto status = stub.DeleteBackup(context, request);
303   EXPECT_EQ(TransientError(), status);
304 }
305 
TEST_F(DatabaseAdminMetadataTest,ListBackups)306 TEST_F(DatabaseAdminMetadataTest, ListBackups) {
307   EXPECT_CALL(*mock_, ListBackups(_, _))
308       .WillOnce([this](grpc::ClientContext& context,
309                        gcsa::ListBackupsRequest const&) {
310         EXPECT_STATUS_OK(
311             IsContextMDValid(context,
312                              "google.spanner.admin.database.v1.DatabaseAdmin."
313                              "ListBackups",
314                              expected_api_client_header_));
315         return TransientError();
316       });
317 
318   DatabaseAdminMetadata stub(mock_);
319   grpc::ClientContext context;
320   gcsa::ListBackupsRequest request;
321   request.set_parent(
322       "projects/test-project-id/"
323       "instances/test-instance-id");
324   auto response = stub.ListBackups(context, request);
325   EXPECT_EQ(TransientError(), response.status());
326 }
327 
TEST_F(DatabaseAdminMetadataTest,UpdateBackup)328 TEST_F(DatabaseAdminMetadataTest, UpdateBackup) {
329   EXPECT_CALL(*mock_, UpdateBackup(_, _))
330       .WillOnce([this](grpc::ClientContext& context,
331                        gcsa::UpdateBackupRequest const&) {
332         EXPECT_STATUS_OK(
333             IsContextMDValid(context,
334                              "google.spanner.admin.database.v1.DatabaseAdmin."
335                              "UpdateBackup",
336                              expected_api_client_header_));
337         return TransientError();
338       });
339 
340   DatabaseAdminMetadata stub(mock_);
341   grpc::ClientContext context;
342   gcsa::UpdateBackupRequest request;
343   request.mutable_backup()->set_name(
344       "projects/test-project-id/"
345       "instances/test-instance-id/"
346       "backups/test-backup-id");
347   auto status = stub.UpdateBackup(context, request);
348   EXPECT_EQ(TransientError(), status.status());
349 }
350 
TEST_F(DatabaseAdminMetadataTest,ListBackupOperations)351 TEST_F(DatabaseAdminMetadataTest, ListBackupOperations) {
352   EXPECT_CALL(*mock_, ListBackupOperations(_, _))
353       .WillOnce([this](grpc::ClientContext& context,
354                        gcsa::ListBackupOperationsRequest const&) {
355         EXPECT_STATUS_OK(
356             IsContextMDValid(context,
357                              "google.spanner.admin.database.v1.DatabaseAdmin."
358                              "ListBackupOperations",
359                              expected_api_client_header_));
360         return TransientError();
361       });
362 
363   DatabaseAdminMetadata stub(mock_);
364   grpc::ClientContext context;
365   gcsa::ListBackupOperationsRequest request;
366   request.set_parent(
367       "projects/test-project-id/"
368       "instances/test-instance-id");
369   auto response = stub.ListBackupOperations(context, request);
370   EXPECT_EQ(TransientError(), response.status());
371 }
372 
TEST_F(DatabaseAdminMetadataTest,ListDatabaseOperations)373 TEST_F(DatabaseAdminMetadataTest, ListDatabaseOperations) {
374   EXPECT_CALL(*mock_, ListDatabaseOperations(_, _))
375       .WillOnce([this](grpc::ClientContext& context,
376                        gcsa::ListDatabaseOperationsRequest const&) {
377         EXPECT_STATUS_OK(
378             IsContextMDValid(context,
379                              "google.spanner.admin.database.v1.DatabaseAdmin."
380                              "ListDatabaseOperations",
381                              expected_api_client_header_));
382         return TransientError();
383       });
384 
385   DatabaseAdminMetadata stub(mock_);
386   grpc::ClientContext context;
387   gcsa::ListDatabaseOperationsRequest request;
388   request.set_parent(
389       "projects/test-project-id/"
390       "instances/test-instance-id");
391   auto response = stub.ListDatabaseOperations(context, request);
392   EXPECT_EQ(TransientError(), response.status());
393 }
394 
TEST_F(DatabaseAdminMetadataTest,GetOperation)395 TEST_F(DatabaseAdminMetadataTest, GetOperation) {
396   EXPECT_CALL(*mock_, GetOperation(_, _))
397       .WillOnce([this](grpc::ClientContext& context,
398                        google::longrunning::GetOperationRequest const&) {
399         EXPECT_STATUS_OK(IsContextMDValid(
400             context, "google.longrunning.Operations.GetOperation",
401             expected_api_client_header_));
402         return TransientError();
403       });
404 
405   DatabaseAdminMetadata stub(mock_);
406   grpc::ClientContext context;
407   google::longrunning::GetOperationRequest request;
408   request.set_name("operations/fake-operation-name");
409   auto status = stub.GetOperation(context, request);
410   EXPECT_EQ(TransientError(), status.status());
411 }
412 
TEST_F(DatabaseAdminMetadataTest,CancelOperation)413 TEST_F(DatabaseAdminMetadataTest, CancelOperation) {
414   EXPECT_CALL(*mock_, CancelOperation(_, _))
415       .WillOnce([this](grpc::ClientContext& context,
416                        google::longrunning::CancelOperationRequest const&) {
417         EXPECT_STATUS_OK(IsContextMDValid(
418             context, "google.longrunning.Operations.CancelOperation",
419             expected_api_client_header_));
420         return TransientError();
421       });
422 
423   DatabaseAdminMetadata stub(mock_);
424   grpc::ClientContext context;
425   google::longrunning::CancelOperationRequest request;
426   request.set_name("operations/fake-operation-name");
427   auto status = stub.CancelOperation(context, request);
428   EXPECT_EQ(TransientError(), status);
429 }
430 
431 }  // namespace
432 }  // namespace internal
433 }  // namespace SPANNER_CLIENT_NS
434 }  // namespace spanner
435 }  // namespace cloud
436 }  // namespace google
437