| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9c529f3 commit 7f1b120
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -144,6 +144,7 @@ def __init__( | |||
| 144 | 144 | self._version_retention_period = None | |
| 145 | 145 | self._earliest_version_time = None | |
| 146 | 146 | self._encryption_info = None | |
| 147 | + self._default_leader = None | ||
| 147 | 148 | self.log_commit_stats = False | |
| 148 | 149 | self._logger = logger | |
| 149 | 150 | self._encryption_config = encryption_config | |
@@ -279,6 +280,15 @@ def encryption_info(self): | |||
| 279 | 280 | """ | |
| 280 | 281 | return self._encryption_info | |
| 281 | 282 | ||
| 283 | + @property | ||
| 284 | + def default_leader(self): | ||
| 285 | + """The read-write region which contains the database's leader replicas. | ||
| 286 | + | ||
| 287 | + :rtype: str | ||
| 288 | + :returns: a string representing the read-write region | ||
| 289 | + """ | ||
| 290 | + return self._default_leader | ||
| 291 | + | ||
| 282 | 292 | @property | |
| 283 | 293 | def ddl_statements(self): | |
| 284 | 294 | """DDL Statements used to define database schema. | |
@@ -414,6 +424,7 @@ def reload(self): | |||
| 414 | 424 | self._earliest_version_time = response.earliest_version_time | |
| 415 | 425 | self._encryption_config = response.encryption_config | |
| 416 | 426 | self._encryption_info = response.encryption_info | |
| 427 | + self._default_leader = response.default_leader | ||
| 417 | 428 | ||
| 418 | 429 | def update_ddl(self, ddl_statements, operation_id=""): | |
| 419 | 430 | """Update DDL for this database. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -68,6 +68,7 @@ | |||
| 68 | 68 | INSTANCE_ID = os.environ.get( | |
| 69 | 69 | "GOOGLE_CLOUD_TESTS_SPANNER_INSTANCE", "google-cloud-python-systest" | |
| 70 | 70 | ) | |
| 71 | + MULTI_REGION_INSTANCE_ID = "multi-region" + unique_resource_id("-") | ||
| 71 | 72 | EXISTING_INSTANCES = [] | |
| 72 | 73 | COUNTERS_TABLE = "counters" | |
| 73 | 74 | COUNTERS_COLUMNS = ("name", "value") | |
@@ -353,9 +354,25 @@ def setUpClass(cls): | |||
| 353 | 354 | SPANNER_OPERATION_TIMEOUT_IN_SECONDS | |
| 354 | 355 | ) # raises on failure / timeout. | |
| 355 | 356 | ||
| 357 | + # Create a multi-region instance | ||
| 358 | + multi_region_config = "nam3" | ||
| 359 | + config_name = "{}/instanceConfigs/{}".format( | ||
| 360 | + Config.CLIENT.project_name, multi_region_config | ||
| 361 | + ) | ||
| 362 | + create_time = str(int(time.time())) | ||
| 363 | + labels = {"python-spanner-systests": "true", "created": create_time} | ||
| 364 | + cls._instance = Config.CLIENT.instance( | ||
| 365 | + instance_id=MULTI_REGION_INSTANCE_ID, | ||
| 366 | + configuration_name=config_name, | ||
| 367 | + labels=labels, | ||
| 368 | + ) | ||
| 369 | + operation = cls._instance.create() | ||
| 370 | + operation.result(SPANNER_OPERATION_TIMEOUT_IN_SECONDS) | ||
| 371 | + | ||
| 356 | 372 | @classmethod | |
| 357 | 373 | def tearDownClass(cls): | |
| 358 | 374 | cls._db.drop() | |
| 375 | + cls._instance.delete() | ||
| 359 | 376 | ||
| 360 | 377 | def setUp(self): | |
| 361 | 378 | self.to_delete = [] | |
@@ -443,6 +460,42 @@ def test_create_database_pitr_success(self): | |||
| 443 | 460 | for result in results: | |
| 444 | 461 | self.assertEqual(result[0], retention_period) | |
| 445 | 462 | ||
| 463 | + @unittest.skipIf( | ||
| 464 | + USE_EMULATOR, "Default leader setting is not supported by the emulator" | ||
| 465 | + ) | ||
| 466 | + def test_create_database_with_default_leader_success(self): | ||
| 467 | + pool = BurstyPool(labels={"testcase": "create_database_default_leader"}) | ||
| 468 | + | ||
| 469 | + temp_db_id = "temp_db" + unique_resource_id("_") | ||
| 470 | + default_leader = "us-east4" | ||
| 471 | + ddl_statements = [ | ||
| 472 | + "ALTER DATABASE {}" | ||
| 473 | + " SET OPTIONS (default_leader = '{}')".format(temp_db_id, default_leader) | ||
| 474 | + ] | ||
| 475 | + temp_db = self._instance.database( | ||
| 476 | + temp_db_id, pool=pool, ddl_statements=ddl_statements | ||
| 477 | + ) | ||
| 478 | + operation = temp_db.create() | ||
| 479 | + self.to_delete.append(temp_db) | ||
| 480 | + | ||
| 481 | + # We want to make sure the operation completes. | ||
| 482 | + operation.result(30) # raises on failure / timeout. | ||
| 483 | + | ||
| 484 | + database_ids = [database.name for database in self._instance.list_databases()] | ||
| 485 | + self.assertIn(temp_db.name, database_ids) | ||
| 486 | + | ||
| 487 | + temp_db.reload() | ||
| 488 | + self.assertEqual(temp_db.default_leader, default_leader) | ||
| 489 | + | ||
| 490 | + with temp_db.snapshot() as snapshot: | ||
| 491 | + results = snapshot.execute_sql( | ||
| 492 | + "SELECT OPTION_VALUE AS default_leader " | ||
| 493 | + "FROM INFORMATION_SCHEMA.DATABASE_OPTIONS " | ||
| 494 | + "WHERE SCHEMA_NAME = '' AND OPTION_NAME = 'default_leader'" | ||
| 495 | + ) | ||
| 496 | + for result in results: | ||
| 497 | + self.assertEqual(result[0], default_leader) | ||
| 498 | + | ||
| 446 | 499 | def test_table_not_found(self): | |
| 447 | 500 | temp_db_id = "temp_db" + unique_resource_id("_") | |
| 448 | 501 | ||
@@ -551,6 +604,36 @@ def test_update_database_ddl_pitr_success(self): | |||
| 551 | 604 | self.assertEqual(temp_db.version_retention_period, retention_period) | |
| 552 | 605 | self.assertEqual(len(temp_db.ddl_statements), len(ddl_statements)) | |
| 553 | 606 | ||
| 607 | + @unittest.skipIf( | ||
| 608 | + USE_EMULATOR, "Default leader update is not supported by the emulator" | ||
| 609 | + ) | ||
| 610 | + def test_update_database_ddl_default_leader_success(self): | ||
| 611 | + pool = BurstyPool(labels={"testcase": "update_database_ddl_default_leader"}) | ||
| 612 | + | ||
| 613 | + temp_db_id = "temp_db" + unique_resource_id("_") | ||
| 614 | + default_leader = "us-east4" | ||
| 615 | + temp_db = self._instance.database(temp_db_id, pool=pool) | ||
| 616 | + create_op = temp_db.create() | ||
| 617 | + self.to_delete.append(temp_db) | ||
| 618 | + | ||
| 619 | + # We want to make sure the operation completes. | ||
| 620 | + create_op.result(240) # raises on failure / timeout. | ||
| 621 | + | ||
| 622 | + self.assertIsNone(temp_db.default_leader) | ||
| 623 | + | ||
| 624 | + ddl_statements = DDL_STATEMENTS + [ | ||
| 625 | + "ALTER DATABASE {}" | ||
| 626 | + " SET OPTIONS (default_leader = '{}')".format(temp_db_id, default_leader) | ||
| 627 | + ] | ||
| 628 | + operation = temp_db.update_ddl(ddl_statements) | ||
| 629 | + | ||
| 630 | + # We want to make sure the operation completes. | ||
| 631 | + operation.result(240) # raises on failure / timeout. | ||
| 632 | + | ||
| 633 | + temp_db.reload() | ||
| 634 | + self.assertEqual(temp_db.default_leader, default_leader) | ||
| 635 | + self.assertEqual(len(temp_db.ddl_statements), len(ddl_statements)) | ||
| 636 | + | ||
| 554 | 637 | def test_db_batch_insert_then_db_snapshot_read(self): | |
| 555 | 638 | retry = RetryInstanceState(_has_all_ddl) | |
| 556 | 639 | retry(self._db.reload)() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -40,6 +40,7 @@ class TestClient(unittest.TestCase): | |||
| 40 | 40 | PROCESSING_UNITS = 5000 | |
| 41 | 41 | LABELS = {"test": "true"} | |
| 42 | 42 | TIMEOUT_SECONDS = 80 | |
| 43 | + LEADER_OPTIONS = ["leader1", "leader2"] | ||
| 43 | 44 | ||
| 44 | 45 | def _get_target_class(self): | |
| 45 | 46 | from google.cloud import spanner | |
@@ -457,7 +458,9 @@ def test_list_instance_configs(self): | |||
| 457 | 458 | instance_config_pbs = ListInstanceConfigsResponse( | |
| 458 | 459 | instance_configs=[ | |
| 459 | 460 | InstanceConfigPB( | |
| 460 | - name=self.CONFIGURATION_NAME, display_name=self.DISPLAY_NAME | ||
| 461 | + name=self.CONFIGURATION_NAME, | ||
| 462 | + display_name=self.DISPLAY_NAME, | ||
| 463 | + leader_options=self.LEADER_OPTIONS, | ||
| 461 | 464 | ) | |
| 462 | 465 | ] | |
| 463 | 466 | ) | |
@@ -473,6 +476,7 @@ def test_list_instance_configs(self): | |||
| 473 | 476 | self.assertIsInstance(instance_config, InstanceConfigPB) | |
| 474 | 477 | self.assertEqual(instance_config.name, self.CONFIGURATION_NAME) | |
| 475 | 478 | self.assertEqual(instance_config.display_name, self.DISPLAY_NAME) | |
| 479 | + self.assertEqual(instance_config.leader_options, self.LEADER_OPTIONS) | ||
| 476 | 480 | ||
| 477 | 481 | expected_metadata = ( | |
| 478 | 482 | ("google-cloud-resource-prefix", client.project_name), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -333,6 +333,13 @@ def test_encryption_info(self): | |||
| 333 | 333 | ] | |
| 334 | 334 | self.assertEqual(database.encryption_info, encryption_info) | |
| 335 | 335 | ||
| 336 | + def test_default_leader(self): | ||
| 337 | + instance = _Instance(self.INSTANCE_NAME) | ||
| 338 | + pool = _Pool() | ||
| 339 | + database = self._make_one(self.DATABASE_ID, instance, pool=pool) | ||
| 340 | + default_leader = database._default_leader = "us-east4" | ||
| 341 | + self.assertEqual(database.default_leader, default_leader) | ||
| 342 | + | ||
| 336 | 343 | def test_spanner_api_property_w_scopeless_creds(self): | |
| 337 | 344 | ||
| 338 | 345 | client = _Client() | |
@@ -715,6 +722,7 @@ def test_reload_success(self): | |||
| 715 | 722 | kms_key_version="kms_key_version", | |
| 716 | 723 | ) | |
| 717 | 724 | ] | |
| 725 | + default_leader = "us-east4" | ||
| 718 | 726 | api = client.database_admin_api = self._make_database_admin_api() | |
| 719 | 727 | api.get_database_ddl.return_value = ddl_pb | |
| 720 | 728 | db_pb = Database( | |
@@ -725,6 +733,7 @@ def test_reload_success(self): | |||
| 725 | 733 | earliest_version_time=_datetime_to_pb_timestamp(timestamp), | |
| 726 | 734 | encryption_config=encryption_config, | |
| 727 | 735 | encryption_info=encryption_info, | |
| 736 | + default_leader=default_leader, | ||
| 728 | 737 | ) | |
| 729 | 738 | api.get_database.return_value = db_pb | |
| 730 | 739 | instance = _Instance(self.INSTANCE_NAME, client=client) | |
@@ -740,6 +749,7 @@ def test_reload_success(self): | |||
| 740 | 749 | self.assertEqual(database._ddl_statements, tuple(DDL_STATEMENTS)) | |
| 741 | 750 | self.assertEqual(database._encryption_config, encryption_config) | |
| 742 | 751 | self.assertEqual(database._encryption_info, encryption_info) | |
| 752 | + self.assertEqual(database._default_leader, default_leader) | ||
| 743 | 753 | ||
| 744 | 754 | api.get_database_ddl.assert_called_once_with( | |
| 745 | 755 | database=self.DATABASE_NAME, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments