Skip to content

Commit 50f106d

Browse files
feat: Add firestoreInDatastoreMode for datastore emulator (#1698)
* feat: Add firestoreInDatastoreMode for datastore emulator * chore: generate libraries at Mon Jan 6 17:28:37 UTC 2025 * update emulator min version * update version to 2.2.2 * update version to 2.3.0 * update version to 2.2.1 * update version to 2.3.1 * chore: generate libraries at Mon Jan 13 23:32:38 UTC 2025 * Fix ci testing environment with java 11 * Add Java 11 enviroment to run tests * Fix java env formatting * set maven env * set maven env * testing java 11 * Add sample test env variable * Add sample test env variable * Add sample test env variable * run with java8 but build with 11 * Add java 11 as java_home sample build * Add java_home for presubmit * Fix SUREFIRE_JVM_OPT for sample build * Fix JAVA_HOME for sample build * Fix JAVA_HOME for sample build * Modify Java env for presubmit integration build * Add setjava to builder script * Add setjava to builder script * Add setjava to builder script * Add debugging info to builder script * Add debugging info to builder script * Add debugging info to builder script * Add debugging info to builder script * formatting * Add debugging * Add debugging * Add debugging * Add debugging * Add debugging * Add debugging * Resolve conflicts * Change sample build to use java11 container * chore: generate libraries at Thu Jan 23 23:20:47 UTC 2025 --------- Co-authored-by: cloud-java-bot <[email protected]>
1 parent a38a741 commit 50f106d

File tree

7 files changed

+87
-11
lines changed

7 files changed

+87
-11
lines changed

.cloudbuild/samples_build.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
steps:
2-
- name: gcr.io/cloud-devrel-public-resources/java8
2+
- name: gcr.io/cloud-devrel-public-resources/java11
33
entrypoint: ls
44
args: [
55
'-alt',
66
]
7-
- name: gcr.io/cloud-devrel-public-resources/java8
7+
- name: gcr.io/cloud-devrel-public-resources/java11
88
entrypoint: curl
99
args: [
1010
'--header',
1111
'Metadata-Flavor: Google',
1212
'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email'
1313
]
14-
- name: gcr.io/cloud-devrel-public-resources/java8
14+
- name: gcr.io/cloud-devrel-public-resources/java11
1515
entrypoint: pwd
16-
- name: gcr.io/cloud-devrel-public-resources/java8
16+
- name: gcr.io/cloud-devrel-public-resources/java11
1717
entrypoint: bash
1818
args: [
1919
'.kokoro/build.sh'
@@ -22,7 +22,7 @@ steps:
2222
- 'JOB_TYPE=samples'
2323
- 'GOOGLE_CLOUD_PROJECT=cloud-java-ci-sample'
2424
- 'KOKORO_GITHUB_PULL_REQUEST_NUMBER=$_PR_NUMBER'
25-
- name: gcr.io/cloud-devrel-public-resources/java8
25+
- name: gcr.io/cloud-devrel-public-resources/java11
2626
entrypoint: echo
2727
args: [
2828
'Sample job succeeded',

.github/workflows/ci.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,23 @@ jobs:
5959
env:
6060
JOB_TYPE: test
6161
windows:
62+
# Building using Java 11 and run the tests with Java 8 runtime
6263
runs-on: windows-latest
6364
steps:
6465
- name: Support longpaths
6566
run: git config --system core.longpaths true
6667
- uses: actions/checkout@v4
6768
- uses: actions/setup-java@v4
6869
with:
69-
distribution: temurin
7070
java-version: 8
71+
distribution: temurin
72+
- name: "Set jvm system property environment variable for surefire plugin (unit tests)"
73+
run: echo "SUREFIRE_JVM_OPT=-Djvm=${JAVA_HOME}\bin\java" >> $GITHUB_ENV
74+
shell: bash
75+
- uses: actions/setup-java@v4
76+
with:
77+
distribution: temurin
78+
java-version: 11
7179
- run: java -version
7280
- run: .kokoro/build.bat
7381
env:

.kokoro/build.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ javadoc)
6060
RETURN_CODE=$?
6161
;;
6262
integration)
63+
# Kokoro integration tests use both JDK 11 and JDK 8. Integration
64+
# tests require JDK 11 export as JAVA env variable to run cloud datastore
65+
# emulator (https://cloud.google.com/sdk/docs/release-notes#39300_2022-07-12).
66+
# For Java 8 environment, we will still run the tests using Java 8 with
67+
# SUREFIRE_JVM_OPT for Maven surefire plugin:
68+
# https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#jvm
69+
if [[ -n "${JAVA11_HOME}" && -n "${JAVA8_HOME}" ]]
70+
then
71+
export JAVA=${JAVA11_HOME}/bin/java
72+
export SUREFIRE_JVM_OPT=-Djvm=${JAVA8_HOME}/bin/java
73+
fi
74+
6375
mvn -B ${INTEGRATION_TEST_ARGS} \
6476
-ntp \
6577
-Penable-integration-tests \

.kokoro/common.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function retry_with_backoff {
5252
return $exit_code
5353
}
5454

55-
## Helper functionss
55+
## Helper functions
5656
function now() { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n'; }
5757
function msg() { println "$*" >&2; }
5858
function println() { printf '%s\n' "$(now) $*"; }

.kokoro/presubmit/integration.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ env_vars: {
3535
env_vars: {
3636
key: "SECRET_MANAGER_KEYS"
3737
value: "java-it-service-account"
38-
}
38+
}

google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ public class LocalDatastoreHelper extends BaseEmulatorHelper<DatastoreOptions> {
5353
private final double consistency;
5454
private final Path gcdPath;
5555
private boolean storeOnDisk;
56+
private boolean firestoreInDatastoreMode;
5657

5758
// Gcloud emulator settings
5859
private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators datastore start";
5960
private static final String GCLOUD_CMD_PORT_FLAG = "--host-port=";
6061
private static final String VERSION_PREFIX = "cloud-datastore-emulator ";
61-
private static final String MIN_VERSION = "2.0.2";
62+
private static final String MIN_VERSION = "2.3.1";
6263

6364
// Downloadable emulator settings
6465
private static final String BIN_NAME = "cloud-datastore-emulator/cloud_datastore_emulator";
@@ -74,6 +75,8 @@ public class LocalDatastoreHelper extends BaseEmulatorHelper<DatastoreOptions> {
7475
private static final String PROJECT_FLAG = "--project=";
7576
private static final double DEFAULT_CONSISTENCY = 0.9;
7677
private static final String DEFAULT_PROJECT_ID = PROJECT_ID_PREFIX + UUID.randomUUID();
78+
private static final String FIRESTORE_IN_DATASTORE_MODE_FLAG =
79+
"--use-firestore-in-datastore-mode";
7780

7881
private static final Logger LOGGER = Logger.getLogger(LocalDatastoreHelper.class.getName());
7982

@@ -102,6 +105,7 @@ public static class Builder {
102105
private int port;
103106
private Path dataDir;
104107
private boolean storeOnDisk = true;
108+
private boolean firestoreInDatastoreMode = false;
105109
private String projectId;
106110

107111
private Builder() {}
@@ -110,6 +114,7 @@ private Builder(LocalDatastoreHelper helper) {
110114
this.consistency = helper.consistency;
111115
this.dataDir = helper.gcdPath;
112116
this.storeOnDisk = helper.storeOnDisk;
117+
this.firestoreInDatastoreMode = helper.firestoreInDatastoreMode;
113118
}
114119

115120
public Builder setConsistency(double consistency) {
@@ -137,6 +142,11 @@ public Builder setStoreOnDisk(boolean storeOnDisk) {
137142
return this;
138143
}
139144

145+
public Builder setFirestoreInDatastoreMode(boolean firestoreInDatastoreMode) {
146+
this.firestoreInDatastoreMode = firestoreInDatastoreMode;
147+
return this;
148+
}
149+
140150
/** Creates a {@code LocalDatastoreHelper} object. */
141151
public LocalDatastoreHelper build() {
142152
return new LocalDatastoreHelper(this);
@@ -152,14 +162,21 @@ private LocalDatastoreHelper(Builder builder) {
152162
this.consistency = builder.consistency > 0 ? builder.consistency : DEFAULT_CONSISTENCY;
153163
this.gcdPath = builder.dataDir;
154164
this.storeOnDisk = builder.storeOnDisk;
165+
this.firestoreInDatastoreMode = builder.firestoreInDatastoreMode;
155166
String binName = BIN_NAME;
156167
if (isWindows()) {
157168
binName = BIN_NAME.replace("/", "\\");
158169
}
159170
List<String> gcloudCommand = new ArrayList<>(Arrays.asList(GCLOUD_CMD_TEXT.split(" ")));
160171
gcloudCommand.add(GCLOUD_CMD_PORT_FLAG + "localhost:" + getPort());
161-
gcloudCommand.add(CONSISTENCY_FLAG + builder.consistency);
162172
gcloudCommand.add(PROJECT_FLAG + projectId);
173+
if (builder.firestoreInDatastoreMode) {
174+
gcloudCommand.add(FIRESTORE_IN_DATASTORE_MODE_FLAG);
175+
} else {
176+
// At most one of --consistency | --use-firestore-in-datastore-mode can be specified.
177+
// --consistency will be ignored with --use-firestore-in-datastore-mode.
178+
gcloudCommand.add(CONSISTENCY_FLAG + builder.consistency);
179+
}
163180
if (!builder.storeOnDisk) {
164181
gcloudCommand.add("--no-store-on-disk");
165182
}
@@ -170,8 +187,16 @@ private LocalDatastoreHelper(Builder builder) {
170187
new GcloudEmulatorRunner(gcloudCommand, VERSION_PREFIX, MIN_VERSION);
171188
List<String> binCommand = new ArrayList<>(Arrays.asList(binName, "start"));
172189
binCommand.add("--testing");
190+
if (builder.firestoreInDatastoreMode) {
191+
// Downloadable emulator runner takes the flag in a different
192+
// format: --firestore_in_datastore_mode
193+
binCommand.add("--firestore_in_datastore_mode");
194+
} else {
195+
// At most one of --consistency | --firestore_in_datastore_mode can be specified.
196+
// --consistency will be ignored with --firestore_in_datastore_mode.
197+
binCommand.add(CONSISTENCY_FLAG + getConsistency());
198+
}
173199
binCommand.add(BIN_CMD_PORT_FLAG + getPort());
174-
binCommand.add(CONSISTENCY_FLAG + getConsistency());
175200
DownloadableEmulatorRunner downloadRunner =
176201
new DownloadableEmulatorRunner(binCommand, EMULATOR_URL, MD5_CHECKSUM, ACCESS_TOKEN);
177202
this.emulatorRunners = ImmutableList.of(gcloudRunner, downloadRunner);
@@ -235,6 +260,13 @@ public boolean isStoreOnDisk() {
235260
return storeOnDisk;
236261
}
237262

263+
/**
264+
* Returns {@code true} use firestore-in-datastore-mode, otherwise {@code false} use native mode.
265+
*/
266+
public boolean isFirestoreInDatastoreMode() {
267+
return firestoreInDatastoreMode;
268+
}
269+
238270
/**
239271
* Creates a local Datastore helper with the specified settings for project ID and consistency.
240272
*

google-cloud-datastore/src/test/java/com/google/cloud/datastore/testing/ITLocalDatastoreHelperTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ public void testCreateWithBuilder() {
7676
.setConsistency(0.75)
7777
.setPort(8081)
7878
.setStoreOnDisk(false)
79+
.setFirestoreInDatastoreMode(true)
7980
.setDataDir(dataDir)
8081
.build();
8182
assertTrue(Math.abs(0.75 - helper.getConsistency()) < TOLERANCE);
8283
assertTrue(helper.getProjectId().startsWith(PROJECT_ID_PREFIX));
8384
assertFalse(helper.isStoreOnDisk());
85+
assertTrue(helper.isFirestoreInDatastoreMode());
8486
assertEquals(8081, helper.getPort());
8587
assertEquals(dataDir, helper.getGcdPath());
8688
LocalDatastoreHelper incompleteHelper = LocalDatastoreHelper.newBuilder().build();
@@ -103,11 +105,13 @@ public void testCreateWithToBuilder() throws IOException {
103105
.setConsistency(0.75)
104106
.setPort(8081)
105107
.setStoreOnDisk(false)
108+
.setFirestoreInDatastoreMode(true)
106109
.setDataDir(dataDir)
107110
.build();
108111
assertTrue(Math.abs(0.75 - helper.getConsistency()) < TOLERANCE);
109112
assertTrue(helper.getProjectId().startsWith(PROJECT_ID_PREFIX));
110113
assertFalse(helper.isStoreOnDisk());
114+
assertTrue(helper.isFirestoreInDatastoreMode());
111115
assertEquals(8081, helper.getPort());
112116
assertEquals(dataDir, helper.getGcdPath());
113117
LocalDatastoreHelper actualHelper = helper.toBuilder().build();
@@ -119,10 +123,12 @@ public void testCreateWithToBuilder() throws IOException {
119123
.setConsistency(0.85)
120124
.setPort(9091)
121125
.setStoreOnDisk(true)
126+
.setFirestoreInDatastoreMode(false)
122127
.setDataDir(dataDir)
123128
.build();
124129
assertTrue(Math.abs(0.85 - actualHelper.getConsistency()) < TOLERANCE);
125130
assertTrue(actualHelper.isStoreOnDisk());
131+
assertFalse(actualHelper.isFirestoreInDatastoreMode());
126132
assertEquals(9091, actualHelper.getPort());
127133
assertEquals(dataDir, actualHelper.getGcdPath());
128134
LocalDatastoreHelper.deleteRecursively(dataDir);
@@ -206,10 +212,28 @@ public void testStartStopResetWithBuilder()
206212
}
207213
}
208214

215+
@Test
216+
public void testCreateWithFirestoreInDatastoreMode()
217+
throws IOException, InterruptedException, TimeoutException {
218+
LocalDatastoreHelper helper =
219+
LocalDatastoreHelper.newBuilder().setFirestoreInDatastoreMode(true).build();
220+
assertTrue(helper.isFirestoreInDatastoreMode());
221+
helper.start();
222+
Datastore datastore = helper.getOptions().getService();
223+
Key key = datastore.newKeyFactory().setKind("kind").newKey("name");
224+
Entity expected = Entity.newBuilder(key).build();
225+
datastore.put(expected);
226+
assertNotNull(datastore.get(key));
227+
Entity actual = datastore.get(key);
228+
assertEquals(expected, actual);
229+
helper.stop();
230+
}
231+
209232
public void assertLocalDatastoreHelpersEquivelent(
210233
LocalDatastoreHelper expected, LocalDatastoreHelper actual) {
211234
assertEquals(expected.getConsistency(), actual.getConsistency(), 0);
212235
assertEquals(expected.isStoreOnDisk(), actual.isStoreOnDisk());
236+
assertEquals(expected.isFirestoreInDatastoreMode(), actual.isFirestoreInDatastoreMode());
213237
assertEquals(expected.getGcdPath(), actual.getGcdPath());
214238
}
215239
}

0 commit comments

Comments
 (0)