diff --git a/java-spanner/samples/snippets/pom.xml b/java-spanner/samples/snippets/pom.xml index 4f41d624282d..e7fcde94aa85 100644 --- a/java-spanner/samples/snippets/pom.xml +++ b/java-spanner/samples/snippets/pom.xml @@ -25,6 +25,7 @@ 1.8 UTF-8 0.31.1 + mysample @@ -137,7 +138,7 @@ us-east1 cmek-test-key-ring cmek-test-key - mysample + ${spanner.sample.database} quick-db @@ -166,7 +167,7 @@ us-east1 cmek-test-key-ring cmek-test-key - mysample + ${spanner.sample.database} quick-db diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateFullBackupScheduleSampleIT.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateFullBackupScheduleSampleIT.java index 82b67c4dfe85..4f4a5cfcbb53 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateFullBackupScheduleSampleIT.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateFullBackupScheduleSampleIT.java @@ -20,6 +20,7 @@ import com.google.spanner.admin.database.v1.BackupScheduleName; import java.util.UUID; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,7 +28,12 @@ @RunWith(JUnit4.class) public class CreateFullBackupScheduleSampleIT extends SampleTestBaseV2 { // Default instance and given db should exist for tests to pass. - private static String databaseId = System.getProperty("spanner.sample.database", "mysample"); + private static String databaseId = getSampleDatabase(); + + @Before + public void cleanUpPreExistingBackupSchedules() { + cleanUpStaleBackupSchedules(instanceId, databaseId); + } @Test public void testCreateFullBackupScheduleSample() throws Exception { diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateIncrementalBackupScheduleSampleIT.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateIncrementalBackupScheduleSampleIT.java index ac38150f5203..61af70935f59 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateIncrementalBackupScheduleSampleIT.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/CreateIncrementalBackupScheduleSampleIT.java @@ -20,6 +20,7 @@ import com.google.spanner.admin.database.v1.BackupScheduleName; import java.util.UUID; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,7 +28,12 @@ @RunWith(JUnit4.class) public class CreateIncrementalBackupScheduleSampleIT extends SampleTestBaseV2 { // Default instance and given db should exist for tests to pass. - private static String databaseId = System.getProperty("spanner.sample.database", "mysample"); + private static String databaseId = getSampleDatabase(); + + @Before + public void cleanUpPreExistingBackupSchedules() { + cleanUpStaleBackupSchedules(multiRegionalInstanceId, databaseId); + } @Test public void testCreateIncrementalBackupScheduleSample() throws Exception { diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/DeleteBackupScheduleSampleIT.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/DeleteBackupScheduleSampleIT.java index f379c9bfe47d..8d89754d7c5e 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/DeleteBackupScheduleSampleIT.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/DeleteBackupScheduleSampleIT.java @@ -20,6 +20,7 @@ import com.google.spanner.admin.database.v1.BackupScheduleName; import java.util.UUID; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,7 +28,12 @@ @RunWith(JUnit4.class) public class DeleteBackupScheduleSampleIT extends SampleTestBaseV2 { // Default instance and given db should exist for tests to pass. - private static String databaseId = System.getProperty("spanner.sample.database", "mysample"); + private static String databaseId = getSampleDatabase(); + + @Before + public void cleanUpPreExistingBackupSchedules() { + cleanUpStaleBackupSchedules(instanceId, databaseId); + } @Test public void testDeleteBackupScheduleSample() throws Exception { diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/GetBackupScheduleSampleIT.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/GetBackupScheduleSampleIT.java index 366093cddd5e..a7c523b8bd5a 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/GetBackupScheduleSampleIT.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/GetBackupScheduleSampleIT.java @@ -20,6 +20,7 @@ import com.google.spanner.admin.database.v1.BackupScheduleName; import java.util.UUID; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,7 +28,12 @@ @RunWith(JUnit4.class) public class GetBackupScheduleSampleIT extends SampleTestBaseV2 { // Default instance and given db should exist for tests to pass. - private static String databaseId = System.getProperty("spanner.sample.database", "mysample"); + private static String databaseId = getSampleDatabase(); + + @Before + public void cleanUpPreExistingBackupSchedules() { + cleanUpStaleBackupSchedules(instanceId, databaseId); + } @Test public void testGetBackupScheduleSample() throws Exception { diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/ListBackupSchedulesSampleIT.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/ListBackupSchedulesSampleIT.java index 97feb2d7e9ba..eca11a2ed813 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/ListBackupSchedulesSampleIT.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/ListBackupSchedulesSampleIT.java @@ -20,6 +20,7 @@ import com.google.spanner.admin.database.v1.BackupScheduleName; import java.util.UUID; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,7 +28,12 @@ @RunWith(JUnit4.class) public class ListBackupSchedulesSampleIT extends SampleTestBaseV2 { // Default instance and given db should exist for tests to pass. - private static String databaseId = System.getProperty("spanner.sample.database", "mysample"); + private static String databaseId = getSampleDatabase(); + + @Before + public void cleanUpPreExistingBackupSchedules() { + cleanUpStaleBackupSchedules(instanceId, databaseId); + } @Test public void testListBackupSchedulesSample() throws Exception { diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2.java index 5a43261269d9..5c9bcddcbeb3 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2.java @@ -23,8 +23,10 @@ import com.google.cloud.spanner.admin.database.v1.DatabaseAdminSettings; import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; import com.google.cloud.spanner.admin.instance.v1.InstanceAdminSettings; +import com.google.spanner.admin.database.v1.BackupSchedule; import com.google.spanner.admin.database.v1.DatabaseDialect; import java.io.IOException; +import java.time.Instant; import java.util.concurrent.TimeUnit; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -37,12 +39,45 @@ public class SampleTestBaseV2 { private static final String BASE_INSTANCE_ID = System.getProperty("spanner.sample.instance", "mysample-instance"); - private static final String BASE_DATABASE_ID = - System.getProperty("spanner.sample.database", "sampledb"); + private static final String BASE_DATABASE_ID = getSampleDatabase(); private static final String BASE_BACKUP_ID = "samplebk"; private static final String BASE_INSTANCE_CONFIG_ID = "sampleconfig"; private static final int AWAIT_TERMINATION_SECONDS = 10; + static String resolveSampleDatabase(String sysProp, String envDb, String kokoroJob) { + if (sysProp != null && !sysProp.trim().isEmpty() && !sysProp.equals("mysample")) { + return sysProp.trim(); + } + if (envDb != null && !envDb.trim().isEmpty()) { + return envDb.trim(); + } + if (kokoroJob != null) { + if (kokoroJob.contains("java8-samples")) { + return "mysample_java8"; + } else if (kokoroJob.contains("java11-samples")) { + return "mysample_java11"; + } + } + if (sysProp != null && !sysProp.trim().isEmpty()) { + return sysProp.trim(); + } + return "mysample"; + } + + public static String getSampleDatabase() { + String kokoroJob = System.getenv("KOKORO_JOB_NAME"); + if (kokoroJob == null || kokoroJob.isEmpty()) { + kokoroJob = System.getenv("JOB_NAME"); + } + if (kokoroJob == null || kokoroJob.isEmpty()) { + kokoroJob = System.getenv("JOB_TYPE"); + } + return resolveSampleDatabase( + System.getProperty("spanner.sample.database"), + System.getenv("SPANNER_SAMPLE_DATABASE"), + kokoroJob); + } + protected static String projectId; protected static final String instanceId = System.getProperty("spanner.test.instance"); protected static DatabaseAdminClient databaseAdminClient; @@ -148,6 +183,40 @@ public static void afterClass() throws InterruptedException { instanceAdminClient.awaitTermination(AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); } + protected static void cleanUpStaleBackupSchedules( + final String targetInstanceId, final String targetDatabaseId) { + try { + final long nowSeconds = Instant.now().getEpochSecond(); + final long staleThresholdSeconds = TimeUnit.HOURS.toSeconds(3); + + for (BackupSchedule schedule : + databaseAdminClient + .listBackupSchedules(getDatabaseName(projectId, targetInstanceId, targetDatabaseId)) + .iterateAll()) { + if (schedule.hasUpdateTime()) { + long ageSeconds = nowSeconds - schedule.getUpdateTime().getSeconds(); + if (ageSeconds > staleThresholdSeconds) { + try { + databaseAdminClient.deleteBackupSchedule(schedule.getName()); + } catch (Exception e) { + System.out.println( + "Failed to delete stale backup schedule " + + schedule.getName() + + " due to " + + e.getMessage() + + ", skipping..."); + } + } + } + } + } catch (Exception e) { + System.out.println( + "Failed to list or clean up stale backup schedules due to " + + e.getMessage() + + ", skipping..."); + } + } + static String getDatabaseName(final String projectId, final String instanceId, final String databaseId) { return String.format( diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2Test.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2Test.java new file mode 100644 index 000000000000..5eab66f50f99 --- /dev/null +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/SampleTestBaseV2Test.java @@ -0,0 +1,78 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +package com.example.spanner; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class SampleTestBaseV2Test { + + @Test + public void testDefaultFallbackToMySample() { + assertThat(SampleTestBaseV2.resolveSampleDatabase(null, null, null)).isEqualTo("mysample"); + assertThat(SampleTestBaseV2.resolveSampleDatabase("", "", "")).isEqualTo("mysample"); + } + + @Test + public void testDefaultPropertyReturnsMySample() { + assertThat(SampleTestBaseV2.resolveSampleDatabase("mysample", null, null)).isEqualTo("mysample"); + } + + @Test + public void testKokoroJava8SamplesAutoDetection() { + assertThat( + SampleTestBaseV2.resolveSampleDatabase( + "mysample", null, "cloud-devrel/client-libraries/java/java-spanner/nightly/java8-samples")) + .isEqualTo("mysample_java8"); + } + + @Test + public void testKokoroJava11SamplesAutoDetection() { + assertThat( + SampleTestBaseV2.resolveSampleDatabase( + "mysample", null, "cloud-devrel/client-libraries/java/java-spanner/nightly/java11-samples")) + .isEqualTo("mysample_java11"); + } + + @Test + public void testKokoroSamplesJobFallback() { + assertThat( + SampleTestBaseV2.resolveSampleDatabase( + "mysample", null, "cloud-devrel/client-libraries/java/java-spanner/nightly/samples")) + .isEqualTo("mysample"); + } + + @Test + public void testExplicitSystemPropertyOverrideTakesPrecedence() { + assertThat( + SampleTestBaseV2.resolveSampleDatabase( + "custom-db", null, "cloud-devrel/client-libraries/java/java-spanner/nightly/java8-samples")) + .isEqualTo("custom-db"); + } + + @Test + public void testExplicitEnvVarOverrideTakesPrecedence() { + assertThat( + SampleTestBaseV2.resolveSampleDatabase( + "mysample", "env-custom-db", "cloud-devrel/client-libraries/java/java-spanner/nightly/java8-samples")) + .isEqualTo("env-custom-db"); + } +} diff --git a/java-spanner/samples/snippets/src/test/java/com/example/spanner/UpdateBackupScheduleSampleIT.java b/java-spanner/samples/snippets/src/test/java/com/example/spanner/UpdateBackupScheduleSampleIT.java index eff037459f91..39bae31a2b0b 100644 --- a/java-spanner/samples/snippets/src/test/java/com/example/spanner/UpdateBackupScheduleSampleIT.java +++ b/java-spanner/samples/snippets/src/test/java/com/example/spanner/UpdateBackupScheduleSampleIT.java @@ -20,6 +20,7 @@ import com.google.spanner.admin.database.v1.BackupScheduleName; import java.util.UUID; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,7 +28,12 @@ @RunWith(JUnit4.class) public class UpdateBackupScheduleSampleIT extends SampleTestBaseV2 { // Default instance and given db should exist for tests to pass. - private static String databaseId = System.getProperty("spanner.sample.database", "mysample"); + private static String databaseId = getSampleDatabase(); + + @Before + public void cleanUpPreExistingBackupSchedules() { + cleanUpStaleBackupSchedules(instanceId, databaseId); + } @Test public void testUpdateBackupScheduleSample() throws Exception {