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
6 changes: 3 additions & 3 deletions .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:

services:
emulator-0:
image: gcr.io/cloud-spanner-emulator/emulator:latest
image: gcr.io/cloud-spanner-emulator/emulator
ports:
- 9010:9010

Expand All @@ -98,7 +98,7 @@ jobs:

services:
emulator-0:
image: gcr.io/cloud-spanner-emulator/emulator:latest
image: gcr.io/cloud-spanner-emulator/emulator
ports:
- 9010:9010

Expand All @@ -123,7 +123,7 @@ jobs:

services:
emulator-0:
image: gcr.io/cloud-spanner-emulator/emulator:latest
image: gcr.io/cloud-spanner-emulator/emulator
ports:
- 9010:9010

Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ docs/_build
docs.metadata

# Virtual environment
.venv/
env/
coverage.xml
sponge_log.xml
Expand All @@ -59,4 +60,5 @@ system_tests/local_test_setup
pylintrc
pylintrc.test

test.cfg
test.cfg
database
46 changes: 22 additions & 24 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ build==1.2.2.post1 \
# via
# -r requirements.in
# pip-tools
cachetools==6.1.0 \
--hash=sha256:1c7bb3cf9193deaf3508b7c5f2a79986c13ea38965c5adcff1f84519cf39163e \
--hash=sha256:b4c4f404392848db3ce7aac34950d17be4d864da4b8b66911008e430bc544587
cachetools==5.5.2 \
--hash=sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4 \
--hash=sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a
# via google-auth
certifi==2025.6.15 \
--hash=sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057 \
Expand Down Expand Up @@ -144,9 +144,9 @@ google-cloud-core==2.4.3 \
--hash=sha256:1fab62d7102844b278fe6dead3af32408b1df3eb06f5c7e8634cbd40edc4da53 \
--hash=sha256:5130f9f4c14b4fafdff75c79448f9495cfade0d8775facf1b09c3bf67e027f6e
# via google-cloud-spanner
google-cloud-spanner==3.55.0 \
--hash=sha256:bec170c6619f667cc657e977f87391d76975559be70b155d90a2902613662b3c \
--hash=sha256:fc9f717b612924f5e9bfae9514aa0d5cd30e6b40e8d472d030f84b16de2c18fe
google-cloud-spanner==3.57.0 \
--hash=sha256:5b10b40bc646091f1b4cbb2e7e2e82ec66bcce52c7105f86b65070d34d6df86f \
--hash=sha256:73f52f58617449fcff7073274a7f7a798f4f7b2788eda26de3b7f98ad857ab99
# via -r requirements.in
googleapis-common-protos[grpc]==1.70.0 \
--hash=sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257 \
Expand Down Expand Up @@ -372,9 +372,9 @@ opentelemetry-sdk==1.34.1 \
--hash=sha256:308effad4059562f1d92163c61c8141df649da24ce361827812c40abb2a1e96e \
--hash=sha256:8091db0d763fcd6098d4781bbc80ff0971f94e260739aa6afe6fd379cdf3aa4d
# via -r requirements.in
opentelemetry-semantic-conventions==0.54b1 \
--hash=sha256:29dab644a7e435b58d3a3918b58c333c92686236b30f7891d5e51f02933ca60d \
--hash=sha256:d1cecedae15d19bdaafca1e56b29a66aa286f50b5d08f036a145c7f3e9ef9cee
opentelemetry-semantic-conventions==0.55b1 \
--hash=sha256:5da81dfdf7d52e3d37f8fe88d5e771e191de924cfff5f550ab0b8f7b2409baed \
--hash=sha256:ef95b1f009159c28d7a7849f5cbc71c4c34c845bb514d66adfdf1b3fff3598b3
# via opentelemetry-sdk
packaging==25.0 \
--hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \
Expand All @@ -396,18 +396,16 @@ proto-plus==1.26.1 \
# via
# google-api-core
# google-cloud-spanner
protobuf==5.29.5 \
--hash=sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079 \
--hash=sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc \
--hash=sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353 \
--hash=sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61 \
--hash=sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5 \
--hash=sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736 \
--hash=sha256:7318608d56b6402d2ea7704ff1e1e4597bee46d760e7e4dd42a3d45e24b87f2e \
--hash=sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84 \
--hash=sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671 \
--hash=sha256:ef91363ad4faba7b25d844ef1ada59ff1604184c0bcd8b39b8a6bef15e1af238 \
--hash=sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015
protobuf==6.32.0 \
--hash=sha256:15eba1b86f193a407607112ceb9ea0ba9569aed24f93333fe9a497cf2fda37d3 \
--hash=sha256:501fe6372fd1c8ea2a30b4d9be8f87955a64d6be9c88a973996cef5ef6f0abf1 \
--hash=sha256:75a2aab2bd1aeb1f5dc7c5f33bcb11d82ea8c055c9becbb41c26a8c43fd7092c \
--hash=sha256:7db8ed09024f115ac877a1427557b838705359f047b2ff2f2b2364892d19dacb \
--hash=sha256:84f9e3c1ff6fb0308dbacb0950d8aa90694b0d0ee68e75719cb044b7078fe741 \
--hash=sha256:a81439049127067fc49ec1d36e25c6ee1d1a2b7be930675f919258d03c04e7d2 \
--hash=sha256:a8bdbb2f009cfc22a36d031f22a625a38b615b5e19e558a7b756b3279723e68e \
--hash=sha256:ba377e5b67b908c8f3072a57b63e2c6a4cbd18aea4ed98d2584350dbf46f2783 \
--hash=sha256:d52691e5bee6c860fff9a1c86ad26a13afbeb4b168cd4445c922b7e2cf85aaf0
# via
# google-api-core
# google-cloud-spanner
Expand Down Expand Up @@ -547,7 +545,9 @@ typing-extensions==4.14.0 \
--hash=sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af
# via
# alembic
# opentelemetry-api
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# sqlalchemy
urllib3==2.5.0 \
--hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
Expand Down Expand Up @@ -637,9 +637,7 @@ wrapt==1.17.2 \
--hash=sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119 \
--hash=sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b \
--hash=sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58
# via
# deprecated
# opentelemetry-instrumentation
# via opentelemetry-instrumentation
zipp==3.23.0 \
--hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \
--hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166
Expand Down
2 changes: 1 addition & 1 deletion samples/sample_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def start_emulator() -> (DockerContainer, str):
).with_exposed_ports(9010)
emulator.start()
wait_for_logs(emulator, "gRPC server listening at 0.0.0.0:9010")
port = emulator.get_exposed_port(9010)
port = str(emulator.get_exposed_port(9010))
_create_instance_and_database(port)
return emulator, port

Expand Down
16 changes: 10 additions & 6 deletions test/mockserver_tests/mock_server_test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging

from google.cloud.spanner_dbapi.parsed_statement import AutocommitDmlMode
from sqlalchemy import Engine, create_engine
Expand All @@ -22,7 +23,6 @@
from google.cloud.spanner_v1 import (
Client,
ResultSet,
PingingPool,
TypeCode,
)
from google.cloud.spanner_v1.database import Database
Expand Down Expand Up @@ -131,9 +131,12 @@ class MockServerTestBase(fixtures.TestBase):
spanner_service: SpannerServicer = None
database_admin_service: DatabaseAdminServicer = None
port: int = None
logger: logging.Logger = None

@classmethod
def setup_class(cls):
MockServerTestBase.logger = logging.getLogger("level warning")
MockServerTestBase.logger.setLevel(logging.WARN)
(
MockServerTestBase.server,
MockServerTestBase.spanner_service,
Expand All @@ -151,6 +154,7 @@ def setup_method(self):
self._client = None
self._instance = None
self._database = None
_ = self.database

def teardown_method(self):
MockServerTestBase.spanner_service.clear_requests()
Expand All @@ -159,7 +163,7 @@ def teardown_method(self):
def create_engine(self) -> Engine:
return create_engine(
"spanner:///projects/p/instances/i/databases/d",
connect_args={"client": self.client, "pool": PingingPool(size=10)},
connect_args={"client": self.client, "logger": MockServerTestBase.logger},
)

@property
Expand All @@ -177,13 +181,13 @@ def client(self) -> Client:
@property
def instance(self) -> Instance:
if self._instance is None:
self._instance = self.client.instance("test-instance")
self._instance = self.client.instance("i")
return self._instance

@property
def database(self) -> Database:
logger = logging.getLogger("level warning")
logger.setLevel(logging.WARN)
if self._database is None:
self._database = self.instance.database(
"test-database", pool=PingingPool(size=10)
)
self._database = self.instance.database("d", logger=logger)
return self._database
31 changes: 7 additions & 24 deletions test/mockserver_tests/test_auto_increment.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy.testing import eq_, is_instance_of
from google.cloud.spanner_v1 import (
FixedSizePool,
ResultSet,
BatchCreateSessionsRequest,
CreateSessionRequest,
ExecuteSqlRequest,
CommitRequest,
BeginTransactionRequest,
Expand All @@ -45,10 +43,7 @@ def test_create_table(self):
""",
ResultSet(),
)
engine = create_engine(
"spanner:///projects/p/instances/i/databases/d",
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
)
engine = self.create_engine()
Base.metadata.create_all(engine)
requests = self.database_admin_service.requests
eq_(1, len(requests))
Expand All @@ -74,10 +69,7 @@ def test_create_auto_increment_table(self):
""",
ResultSet(),
)
engine = create_engine(
"spanner:///projects/p/instances/i/databases/d",
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
)
engine = self.create_engine()
engine.dialect.use_auto_increment = True
Base.metadata.create_all(engine)
requests = self.database_admin_service.requests
Expand All @@ -103,10 +95,7 @@ def test_create_table_with_specific_sequence_kind(self):
""",
ResultSet(),
)
engine = create_engine(
"spanner:///projects/p/instances/i/databases/d",
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
)
engine = self.create_engine()
engine.dialect.default_sequence_kind = "non_existing_kind"
Base.metadata.create_all(engine)
requests = self.database_admin_service.requests
Expand All @@ -126,10 +115,7 @@ def test_insert_row(self):
from test.mockserver_tests.auto_increment_model import Singer

self.add_insert_result("INSERT INTO singers (name) VALUES (@a0) THEN RETURN id")
engine = create_engine(
"spanner:///projects/p/instances/i/databases/d",
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
)
engine = self.create_engine()

with Session(engine) as session:
singer = Singer(name="Test")
Expand All @@ -141,7 +127,7 @@ def test_insert_row(self):
# Verify the requests that we got.
requests = self.spanner_service.requests
eq_(4, len(requests))
is_instance_of(requests[0], BatchCreateSessionsRequest)
is_instance_of(requests[0], CreateSessionRequest)
is_instance_of(requests[1], BeginTransactionRequest)
is_instance_of(requests[2], ExecuteSqlRequest)
is_instance_of(requests[3], CommitRequest)
Expand All @@ -152,10 +138,7 @@ def test_insert_row_with_pk_value(self):
# SQLAlchemy should not use a THEN RETURN clause when a value for the
# primary key has been set on the model.
add_update_count("INSERT INTO singers (id, name) VALUES (@a0, @a1)", 1)
engine = create_engine(
"spanner:///projects/p/instances/i/databases/d",
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
)
engine = self.create_engine()

with Session(engine) as session:
# Manually specify a value for the primary key.
Expand Down
Loading