diff --git a/.github/workflows/integration-tests-against-emulator-3.14.yml b/.github/workflows/integration-tests-against-emulator-3.14.yml new file mode 100644 index 0000000000..f2865975f4 --- /dev/null +++ b/.github/workflows/integration-tests-against-emulator-3.14.yml @@ -0,0 +1,35 @@ +on: + push: + branches: + - main + pull_request: +permissions: + contents: read + pull-requests: write +name: Run Django Spanner integration tests against emulator 3.14 +jobs: + system-tests: + runs-on: ubuntu-latest + + services: + emulator: + image: gcr.io/cloud-spanner-emulator/emulator:latest + ports: + - 9010:9010 + - 9020:9020 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + - name: Install nox + run: python -m pip install nox + - name: Run nox + run: nox -s unit-3.14 + env: + SPANNER_EMULATOR_HOST: localhost:9010 + GOOGLE_CLOUD_PROJECT: emulator-test-project + GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE: true diff --git a/.github/workflows/mockserver-tests.yml b/.github/workflows/mockserver-tests.yml index 1cdc634fa1..1322a8d371 100644 --- a/.github/workflows/mockserver-tests.yml +++ b/.github/workflows/mockserver-tests.yml @@ -11,10 +11,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.14" - name: Install nox run: python -m pip install nox - name: Run nox diff --git a/noxfile.py b/noxfile.py index cb438618f7..3d819b4799 100644 --- a/noxfile.py +++ b/noxfile.py @@ -24,10 +24,10 @@ "setup.py", ] -MOCKSERVER_TEST_PYTHON_VERSION = "3.12" +MOCKSERVER_TEST_PYTHON_VERSION = "3.14" DEFAULT_PYTHON_VERSION = "3.8" SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] -UNIT_TEST_PYTHON_VERSIONS = ["3.8", "3.9", "3.10"] +UNIT_TEST_PYTHON_VERSIONS = ["3.8", "3.9", "3.10", "3.14"] CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() diff --git a/tests/mockserver_tests/test_basics.py b/tests/mockserver_tests/test_basics.py index 489ebf3cbf..a965486a48 100644 --- a/tests/mockserver_tests/test_basics.py +++ b/tests/mockserver_tests/test_basics.py @@ -13,6 +13,7 @@ # limitations under the License. from google.cloud.spanner_v1 import ( BatchCreateSessionsRequest, + CreateSessionRequest, ExecuteSqlRequest, CommitRequest, ) @@ -36,9 +37,10 @@ def verify_select1(self, results): self.assertEqual(row[0], 1) self.assertEqual(len(result_list), 1) requests = self.spanner_service.requests - self.assertEqual(len(requests), 2) + self.assertEqual(len(requests), 3) self.assertIsInstance(requests[0], BatchCreateSessionsRequest) - self.assertIsInstance(requests[1], ExecuteSqlRequest) + self.assertIsInstance(requests[1], CreateSessionRequest) + self.assertIsInstance(requests[2], ExecuteSqlRequest) def test_select1(self): add_select1_result() @@ -59,9 +61,10 @@ def test_django_select_singer(self): singers = Singer.objects.all() self.assertEqual(len(singers), 2) requests = self.spanner_service.requests - self.assertEqual(len(requests), 2) + self.assertEqual(len(requests), 3) self.assertIsInstance(requests[0], BatchCreateSessionsRequest) - self.assertIsInstance(requests[1], ExecuteSqlRequest) + self.assertIsInstance(requests[1], CreateSessionRequest) + self.assertIsInstance(requests[2], ExecuteSqlRequest) def test_django_select_singer_using_other_db(self): add_singer_query_result( @@ -70,9 +73,10 @@ def test_django_select_singer_using_other_db(self): singers = Singer.objects.using("secondary").all() self.assertEqual(len(singers), 2) requests = self.spanner_service.requests - self.assertEqual(len(requests), 2) + self.assertEqual(len(requests), 3) self.assertIsInstance(requests[0], BatchCreateSessionsRequest) - self.assertIsInstance(requests[1], ExecuteSqlRequest) + self.assertIsInstance(requests[1], CreateSessionRequest) + self.assertIsInstance(requests[2], ExecuteSqlRequest) def test_insert_singer(self): add_update_count( @@ -84,15 +88,16 @@ def test_insert_singer(self): singer = Singer(first_name="test", last_name="test") singer.save() requests = self.spanner_service.requests - self.assertEqual(len(requests), 3) + self.assertEqual(len(requests), 4) self.assertIsInstance(requests[0], BatchCreateSessionsRequest) - self.assertIsInstance(requests[1], ExecuteSqlRequest) - self.assertIsInstance(requests[2], CommitRequest) + self.assertIsInstance(requests[1], CreateSessionRequest) + self.assertIsInstance(requests[2], ExecuteSqlRequest) + self.assertIsInstance(requests[3], CommitRequest) # The ExecuteSqlRequest should have 3 parameters: # 1. first_name # 2. last_name # 3. client-side auto-generated primary key - self.assertEqual(len(requests[1].params), 3) + self.assertEqual(len(requests[2].params), 3) def test_insert_singer_with_disabled_random_primary_key(self): for db, config in DATABASES.items(): @@ -115,15 +120,16 @@ class LocalSinger(models.Model): singer = LocalSinger(first_name="test", last_name="test") singer.save() requests = self.spanner_service.requests - self.assertEqual(len(requests), 3) + self.assertEqual(len(requests), 4) self.assertIsInstance(requests[0], BatchCreateSessionsRequest) - self.assertIsInstance(requests[1], ExecuteSqlRequest) - self.assertIsInstance(requests[2], CommitRequest) + self.assertIsInstance(requests[1], CreateSessionRequest) + self.assertIsInstance(requests[2], ExecuteSqlRequest) + self.assertIsInstance(requests[3], CommitRequest) # The ExecuteSqlRequest should have 2 parameters: # 1. first_name # 2. last_name # There should be no client-side auto-generated primary key. - self.assertEqual(len(requests[1].params), 2) + self.assertEqual(len(requests[2].params), 2) finally: for db, config in DATABASES.items(): if config["ENGINE"] == "django_spanner":