E5EB samples: add default leader options samples by zoercai · Pull Request #428 · googleapis/python-spanner · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions samples/samples/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,26 @@ def instance_id():
return f"test-instance-{uuid.uuid4().hex[:10]}"


@pytest.fixture(scope="module")
def multi_region_instance_id():
"""Unique id for the multi-region instance used in samples."""
return f"multi-instance-{uuid.uuid4().hex[:10]}"


@pytest.fixture(scope="module")
def instance_config(spanner_client):
return "{}/instanceConfigs/{}".format(
spanner_client.project_name, "regional-us-central1"
)


@pytest.fixture(scope="module")
def multi_region_instance_config(spanner_client):
return "{}/instanceConfigs/{}".format(
spanner_client.project_name, "nam3"
)


@pytest.fixture(scope="module")
def sample_instance(
spanner_client, cleanup_old_instances, instance_id, instance_config, sample_name,
Expand Down Expand Up @@ -113,6 +126,42 @@ def sample_instance(
sample_instance.delete()


@pytest.fixture(scope="module")
def multi_region_instance(
spanner_client,
cleanup_old_instances,
multi_region_instance_id,
multi_region_instance_config,
sample_name,
):
multi_region_instance = spanner_client.instance(
multi_region_instance_id,
multi_region_instance_config,
labels={
"cloud_spanner_samples": "true",
"sample_name": sample_name,
"created": str(int(time.time()))
},
)
retry_429 = retry.RetryErrors(exceptions.ResourceExhausted, delay=15)
op = retry_429(multi_region_instance.create)()
op.result(120) # block until completion

# Eventual consistency check
retry_found = retry.RetryResult(bool)
retry_found(multi_region_instance.exists)()

yield multi_region_instance

for database_pb in multi_region_instance.list_databases():
database.Database.from_pb(database_pb, multi_region_instance).drop()

for backup_pb in multi_region_instance.list_backups():
backup.Backup.from_pb(backup_pb, multi_region_instance).delete()

multi_region_instance.delete()


@pytest.fixture(scope="module")
def database_id():
"""Id for the database used in samples.
Expand Down
153 changes: 153 additions & 0 deletions samples/samples/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,53 @@ def create_instance_with_processing_units(instance_id, processing_units):
# [END spanner_create_instance_with_processing_units]


# [START spanner_get_instance_config]
def get_instance_config(instance_config):
"""Gets the leader options for the instance configuration."""
spanner_client = spanner.Client()
config_name = "{}/instanceConfigs/{}".format(spanner_client.project_name, instance_config)
config = spanner_client.instance_admin_api.get_instance_config(name=config_name)
print("Available leader options for instance config {}: {}".format(
instance_config, config.leader_options))


# [END spanner_get_instance_config]


# [START spanner_list_instance_configs]
def list_instance_config():
"""Lists the available instance configurations."""
spanner_client = spanner.Client()
configs = spanner_client.list_instance_configs()
for config in configs:
print(
"Available leader options for instance config {}: {}".format(
config.name, config.leader_options
)
)


# [END spanner_list_instance_configs]


# [START spanner_list_databases]
def list_databases(instance_id):
"""Lists databases and their leader options."""
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)

databases = list(instance.list_databases())
for database in databases:
print(
"Database {} has default leader {}".format(
database.name, database.default_leader
)
)


# [END spanner_list_databases]


# [START spanner_create_database]
def create_database(instance_id, database_id):
"""Creates a database and tables for sample data."""
Expand Down Expand Up @@ -168,6 +215,112 @@ def create_database_with_encryption_key(instance_id, database_id, kms_key_name):
# [END spanner_create_database_with_encryption_key]


# [START spanner_create_database_with_default_leader]
def create_database_with_default_leader(
instance_id, database_id, default_leader
):
"""Creates a database with tables with a default leader."""
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)

database = instance.database(
database_id,
ddl_statements=[
"""CREATE TABLE Singers (
SingerId INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
SingerInfo BYTES(MAX)
) PRIMARY KEY (SingerId)""",
"""CREATE TABLE Albums (
SingerId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
AlbumTitle STRING(MAX)
) PRIMARY KEY (SingerId, AlbumId),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE""",
"ALTER DATABASE {}"
" SET OPTIONS (default_leader = '{}')".format(database_id, default_leader),
],
)
operation = database.create()

print("Waiting for operation to complete...")
operation.result(120)

database.reload()

print(
"Database {} created with default leader {}".format(
database.name, database.default_leader
)
)


# [END spanner_create_database_with_default_leader]


# [START spanner_update_database_with_default_leader]
def update_database_with_default_leader(
instance_id, database_id, default_leader
):
"""Updates a database with tables with a default leader."""
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)

database = instance.database(database_id)

operation = database.update_ddl(["ALTER DATABASE {}"
" SET OPTIONS (default_leader = '{}')".format(database_id, default_leader)])
operation.result(120)

database.reload()

print(
"Database {} updated with default leader {}".format(
database.name, database.default_leader
)
)


# [END spanner_update_database_with_default_leader]


# [START spanner_get_database_ddl]
def get_database_ddl(instance_id, database_id):
"""Gets the database DDL statements."""
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
ddl = spanner_client.database_admin_api.get_database_ddl(database=database.name)
print("Retrieved database DDL for {}".format(database_id))
for statement in ddl.statements:
print(statement)


# [END spanner_get_database_ddl]


# [START spanner_query_information_schema_database_options]
def query_information_schema_database_options(instance_id, database_id):
"""Queries the default leader of a database."""
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
with database.snapshot() as snapshot:
results = snapshot.execute_sql(
"SELECT OPTION_VALUE AS default_leader "
"FROM INFORMATION_SCHEMA.DATABASE_OPTIONS "
"WHERE SCHEMA_NAME = '' AND OPTION_NAME = 'default_leader'"
)
for result in results:
print("Database {} has default leader {}".format(
database_id, result[0]
))


# [END spanner_query_information_schema_database_options]


# [START spanner_insert_data]
def insert_data(instance_id, database_id):
"""Inserts sample data into the given database.
Expand Down
64 changes: 64 additions & 0 deletions samples/samples/snippets_test.py
9744
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ def cmek_database_id():
return f"cmek-db-{uuid.uuid4().hex[:10]}"


@pytest.fixture(scope="module")
def default_leader_database_id():
return f"leader_db_{uuid.uuid4().hex[:10]}"


@pytest.fixture(scope="module")
def database_ddl():
"""Sequence of DDL statements used to set up the database.
Expand All @@ -82,6 +87,12 @@ def database_ddl():
return [CREATE_TABLE_SINGERS, CREATE_TABLE_ALBUMS]


@pytest.fixture(scope="module")
def default_leader():
""" Default leader for multi-region ins 4B92 tances. """
return "us-east4"


def test_create_instance_explicit(spanner_client, create_instance_id):
# Rather than re-use 'sample_isntance', we create a new instance, to
# ensure that the 'create_instance' snippet is tested.
Expand Down Expand Up @@ -119,6 +130,59 @@ def test_create_database_with_encryption_config(capsys, instance_id, cmek_databa
assert kms_key_name in out


def test_get_instance_config(capsys):
instance_config = "nam6"
snippets.get_instance_config(instance_config)
out, _ = capsys.readouterr()
assert instance_config in out


def test_list_instance_config(capsys):
snippets.list_instance_config()
out, _ = capsys.readouterr()
assert "regional-us-central1" in out


def test_list_databases(capsys, instance_id):
snippets.list_databases(instance_id)
out, _ = capsys.readouterr()
assert "has default leader" in out


def test_create_database_with_default_leader(capsys, multi_region_instance, multi_region_instance_id, default_leader_database_id, default_leader):
retry_429 = RetryErrors(exceptions.ResourceExhausted, delay=15)
retry_429(snippets.create_database_with_default_leader)(
multi_region_instance_id, default_leader_database_id, default_leader
)
out, _ = capsys.readouterr()
assert default_leader_database_id in out
assert default_leader in out


def test_update_database_with_default_leader(capsys, multi_region_instance, multi_region_instance_id, default_leader_database_id, default_leader):
retry_429 = RetryErrors(exceptions.ResourceExhausted, delay=15)
retry_429(snippets.update_database_with_default_leader)(
multi_region_instance_id, default_leader_database_id, default_leader
)
out, _ = capsys.readouterr()
assert default_leader_database_id in out
assert default_leader in out


def test_get_database_ddl(capsys, instance_id, sample_database):
snippets.get_database_ddl(instance_id, sample_database.database_id)
out, _ = capsys.readouterr()
assert sample_database.database_id in out


def test_query_information_schema_database_options(capsys, multi_region_instance, multi_region_instance_id, default_leader_database_id, default_leader):
snippets.query_information_schema_database_options(
multi_region_instance_id, default_leader_database_id
)
out, _ = capsys.readouterr()
assert default_leader in out


@pytest.mark.dependency(name="insert_data")
def test_insert_data(capsys, instance_id, sample_database):
snippets.insert_data(instance_id, sample_database.database_id)
Expand Down
0