diff --git a/noxfile.py b/noxfile.py index 265933acd7..42151a22f9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -238,7 +238,8 @@ def install_systemtest_dependencies(session, *constraints): @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) -def system(session): +@nox.parametrize("database_dialect", ["GOOGLE_STANDARD_SQL", "POSTGRESQL"]) +def system(session, database_dialect): """Run the system test suite.""" constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" @@ -256,6 +257,9 @@ def system(session): session.skip( "Credentials or emulator host must be set via environment variable" ) + # If POSTGRESQL tests and Emulator, skip the tests + if os.environ.get("SPANNER_EMULATOR_HOST") and database_dialect == "POSTGRESQL": + session.skip("Postgresql is not supported by Emulator yet.") # Install pyopenssl for mTLS testing. if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": @@ -277,6 +281,10 @@ def system(session): f"--junitxml=system_{session.python}_sponge_log.xml", system_test_path, *session.posargs, + env={ + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, ) if system_test_folder_exists: session.run( @@ -285,6 +293,10 @@ def system(session): f"--junitxml=system_{session.python}_sponge_log.xml", system_test_folder_path, *session.posargs, + env={ + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, ) diff --git a/tests/system/_helpers.py b/tests/system/_helpers.py index 51a6d773c4..fba1f1a5a5 100644 --- a/tests/system/_helpers.py +++ b/tests/system/_helpers.py @@ -117,7 +117,7 @@ def scrub_instance_ignore_not_found(to_scrub): def cleanup_old_instances(spanner_client): - cutoff = int(time.time()) - 2 * 60 * 60 # two hour ago + cutoff = int(time.time()) - 3 * 60 * 60 # three hour ago instance_filter = "labels.python-spanner-systests:true" for instance_pb in spanner_client.list_instances(filter_=instance_filter): diff --git a/tests/system/conftest.py b/tests/system/conftest.py index b7004fa274..3d6706b582 100644 --- a/tests/system/conftest.py +++ b/tests/system/conftest.py @@ -57,6 +57,14 @@ def not_postgres(database_dialect): ) +@pytest.fixture(scope="session") +def not_google_standard_sql(database_dialect): + if database_dialect == DatabaseDialect.GOOGLE_STANDARD_SQL: + pytest.skip( + f"{_helpers.DATABASE_DIALECT_ENVVAR} set to GOOGLE_STANDARD_SQL in environment." + ) + + @pytest.fixture(scope="session") def database_dialect(): return ( @@ -169,14 +177,27 @@ def shared_instance( def shared_database(shared_instance, database_operation_timeout, database_dialect): database_name = _helpers.unique_id("test_database") pool = spanner_v1.BurstyPool(labels={"testcase": "database_api"}) - database = shared_instance.database( - database_name, - ddl_statements=_helpers.DDL_STATEMENTS, - pool=pool, - database_dialect=database_dialect, - ) - operation = database.create() - operation.result(database_operation_timeout) # raises on failure / timeout. + if database_dialect == DatabaseDialect.POSTGRESQL: + database = shared_instance.database( + database_name, + pool=pool, + database_dialect=database_dialect, + ) + operation = database.create() + operation.result(database_operation_timeout) # raises on failure / timeout. + + operation = database.update_ddl(ddl_statements=_helpers.DDL_STATEMENTS) + operation.result(database_operation_timeout) # raises on failure / timeout. + + else: + database = shared_instance.database( + database_name, + ddl_statements=_helpers.DDL_STATEMENTS, + pool=pool, + database_dialect=database_dialect, + ) + operation = database.create() + operation.result(database_operation_timeout) # raises on failure / timeout. yield database diff --git a/tests/system/test_backup_api.py b/tests/system/test_backup_api.py index bfcd635e8d..dc80653786 100644 --- a/tests/system/test_backup_api.py +++ b/tests/system/test_backup_api.py @@ -14,6 +14,7 @@ import datetime import time +from google.cloud.spanner_admin_database_v1.types.common import DatabaseDialect import pytest @@ -96,14 +97,27 @@ def database_version_time(shared_database): def second_database(shared_instance, database_operation_timeout, database_dialect): database_name = _helpers.unique_id("test_database2") pool = spanner_v1.BurstyPool(labels={"testcase": "database_api"}) - database = shared_instance.database( - database_name, - ddl_statements=_helpers.DDL_STATEMENTS, - pool=pool, - database_dialect=database_dialect, - ) - operation = database.create() - operation.result(database_operation_timeout) # raises on failure / timeout. + if database_dialect == DatabaseDialect.POSTGRESQL: + database = shared_instance.database( + database_name, + pool=pool, + database_dialect=database_dialect, + ) + operation = database.create() + operation.result(database_operation_timeout) # raises on failure / timeout. + + operation = database.update_ddl(ddl_statements=_helpers.DDL_STATEMENTS) + operation.result(database_operation_timeout) # raises on failure / timeout. + + else: + database = shared_instance.database( + database_name, + ddl_statements=_helpers.DDL_STATEMENTS, + pool=pool, + database_dialect=database_dialect, + ) + operation = database.create() + operation.result(database_operation_timeout) # raises on failure / timeout. yield database diff --git a/tests/system/test_database_api.py b/tests/system/test_database_api.py index 1d21a77498..e9e6c69287 100644 --- a/tests/system/test_database_api.py +++ b/tests/system/test_database_api.py @@ -129,6 +129,7 @@ def test_create_database_pitr_success( def test_create_database_with_default_leader_success( not_emulator, # Default leader setting not supported by the emulator + not_postgres, multiregion_instance, databases_to_delete, ): @@ -270,6 +271,7 @@ def test_update_ddl_w_pitr_success( def test_update_ddl_w_default_leader_success( not_emulator, + not_postgres, multiregion_instance, databases_to_delete, ): diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index f211577abd..13c3e246ed 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -200,13 +200,29 @@ def sessions_database(shared_instance, database_operation_timeout, database_dialect): database_name = _helpers.unique_id("test_sessions", separator="_") pool = spanner_v1.BurstyPool(labels={"testcase": "session_api"}) - sessions_database = shared_instance.database( - database_name, - ddl_statements=_helpers.DDL_STATEMENTS, - pool=pool, - ) - operation = sessions_database.create() - operation.result(database_operation_timeout) # raises on failure / timeout. + + if database_dialect == DatabaseDialect.POSTGRESQL: + sessions_database = shared_instance.database( + database_name, + pool=pool, + database_dialect=database_dialect, + ) + + operation = sessions_database.create() + operation.result(database_operation_timeout) + + operation = sessions_database.update_ddl(ddl_statements=_helpers.DDL_STATEMENTS) + operation.result(database_operation_timeout) + + else: + sessions_database = shared_instance.database( + database_name, + ddl_statements=_helpers.DDL_STATEMENTS, + pool=pool, + ) + + operation = sessions_database.create() + operation.result(database_operation_timeout) _helpers.retry_has_all_dll(sessions_database.reload)() # Some tests expect there to be a session present in the pool. @@ -1322,16 +1338,32 @@ def test_read_w_index( # Create an alternate dataase w/ index. extra_ddl = ["CREATE INDEX contacts_by_last_name ON contacts(last_name)"] pool = spanner_v1.BurstyPool(labels={"testcase": "read_w_index"}) - temp_db = shared_instance.database( - _helpers.unique_id("test_read", separator="_"), - ddl_statements=_helpers.DDL_STATEMENTS + extra_ddl, - pool=pool, - database_dialect=database_dialect, - ) - operation = temp_db.create() - databases_to_delete.append(temp_db) - operation.result(database_operation_timeout) # raises on failure / timeout. + if database_dialect == DatabaseDialect.POSTGRESQL: + temp_db = shared_instance.database( + _helpers.unique_id("test_read", separator="_"), + pool=pool, + database_dialect=database_dialect, + ) + operation = temp_db.create() + operation.result(database_operation_timeout) + + operation = temp_db.update_ddl( + ddl_statements=_helpers.DDL_STATEMENTS + extra_ddl, + ) + operation.result(database_operation_timeout) + + else: + temp_db = shared_instance.database( + _helpers.unique_id("test_read", separator="_"), + ddl_statements=_helpers.DDL_STATEMENTS + extra_ddl, + pool=pool, + database_dialect=database_dialect, + ) + operation = temp_db.create() + operation.result(database_operation_timeout) # raises on failure / timeout. + + databases_to_delete.append(temp_db) committed = _set_up_table(temp_db, row_count) with temp_db.snapshot(read_timestamp=committed) as snapshot: @@ -2040,7 +2072,7 @@ def test_execute_sql_w_date_bindings(sessions_database, not_postgres, database_d def test_execute_sql_w_numeric_bindings( - not_emulator, not_postgres, sessions_database, database_dialect + not_emulator, sessions_database, database_dialect ): if database_dialect == DatabaseDialect.POSTGRESQL: _bind_test_helper( @@ -2060,7 +2092,9 @@ def test_execute_sql_w_numeric_bindings( ) -def test_execute_sql_w_json_bindings(not_emulator, sessions_database, database_dialect): +def test_execute_sql_w_json_bindings( + not_emulator, not_postgres, sessions_database, database_dialect +): _bind_test_helper( sessions_database, database_dialect,