Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add firestoreInDatastoreMode for datastore emulator #1698

Merged
merged 48 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
b826220
feat: Add firestoreInDatastoreMode for datastore emulator
cindy-peng Jan 6, 2025
a0f1c50
chore: generate libraries at Mon Jan 6 17:28:37 UTC 2025
cloud-java-bot Jan 6, 2025
274557d
update emulator min version
cindy-peng Jan 6, 2025
911b2dd
update version to 2.2.2
cindy-peng Jan 6, 2025
fda80ff
update version to 2.3.0
cindy-peng Jan 6, 2025
19a9bbc
update version to 2.2.1
cindy-peng Jan 6, 2025
bc1a960
update version to 2.3.1
cindy-peng Jan 6, 2025
079b7bb
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 9, 2025
45377ff
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 13, 2025
406beb6
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 13, 2025
41dccf1
chore: generate libraries at Mon Jan 13 23:32:38 UTC 2025
cloud-java-bot Jan 13, 2025
104fa72
Fix ci testing environment with java 11
cindy-peng Jan 14, 2025
75bdacf
Add Java 11 enviroment to run tests
cindy-peng Jan 14, 2025
d754713
Fix java env formatting
cindy-peng Jan 14, 2025
112699f
set maven env
cindy-peng Jan 14, 2025
5e5c25c
set maven env
cindy-peng Jan 14, 2025
fac0bf1
testing java 11
cindy-peng Jan 15, 2025
b3b7d16
Add sample test env variable
cindy-peng Jan 15, 2025
dfbdab5
Add sample test env variable
cindy-peng Jan 15, 2025
f356c9a
Add sample test env variable
cindy-peng Jan 15, 2025
45399b6
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 16, 2025
029f448
run with java8 but build with 11
cindy-peng Jan 16, 2025
0adba63
Add java 11 as java_home sample build
cindy-peng Jan 16, 2025
fc0f684
Add java_home for presubmit
cindy-peng Jan 17, 2025
2b850fc
Fix SUREFIRE_JVM_OPT for sample build
cindy-peng Jan 17, 2025
7bd94f5
Fix JAVA_HOME for sample build
cindy-peng Jan 17, 2025
2047196
Fix JAVA_HOME for sample build
cindy-peng Jan 17, 2025
b45dc79
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 17, 2025
9384638
Modify Java env for presubmit integration build
cindy-peng Jan 18, 2025
d0f551e
Add setjava to builder script
cindy-peng Jan 20, 2025
cfdef38
Add setjava to builder script
cindy-peng Jan 20, 2025
86772ee
Add setjava to builder script
cindy-peng Jan 20, 2025
32c3a90
Add debugging info to builder script
cindy-peng Jan 20, 2025
2926ebe
Add debugging info to builder script
cindy-peng Jan 20, 2025
ea61f7e
Add debugging info to builder script
cindy-peng Jan 20, 2025
57faf20
Add debugging info to builder script
cindy-peng Jan 20, 2025
c90f911
formatting
cindy-peng Jan 20, 2025
3fb60ba
Add debugging
cindy-peng Jan 20, 2025
165967a
Add debugging
cindy-peng Jan 20, 2025
b51e5d1
Add debugging
cindy-peng Jan 20, 2025
0ee9a9b
Add debugging
cindy-peng Jan 20, 2025
feae654
Add debugging
cindy-peng Jan 20, 2025
9565310
Add debugging
cindy-peng Jan 20, 2025
3e31255
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 21, 2025
f082807
Resolve conflicts
cindy-peng Jan 21, 2025
e964ba1
Change sample build to use java11 container
cindy-peng Jan 23, 2025
e71d759
Merge branch 'main' into cindy/emulatorflag1
cindy-peng Jan 23, 2025
5cbc1ca
chore: generate libraries at Thu Jan 23 23:20:47 UTC 2025
cloud-java-bot Jan 23, 2025
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
1 change: 1 addition & 0 deletions .cloudbuild/samples_build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ steps:
- 'JOB_TYPE=samples'
- 'GOOGLE_CLOUD_PROJECT=cloud-java-ci-sample'
- 'KOKORO_GITHUB_PULL_REQUEST_NUMBER=$_PR_NUMBER'
- 'JAVA=/usr/lib/jvm/java-11-openjdk-amd64/bin/java'
cindy-peng marked this conversation as resolved.
Show resolved Hide resolved
- name: gcr.io/cloud-devrel-public-resources/java8
entrypoint: echo
args: [
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,23 @@ jobs:
env:
JOB_TYPE: test
windows:
# Building using Java 11 and run the tests with Java 8 runtime
runs-on: windows-latest
steps:
- name: Support longpaths
run: git config --system core.longpaths true
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 8
distribution: temurin
- name: "Set jvm system property environment variable for surefire plugin (unit tests)"
run: echo "SUREFIRE_JVM_OPT=-Djvm=${JAVA_HOME}\bin\java" >> $GITHUB_ENV
shell: bash
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 11
- run: java -version
- run: .kokoro/build.bat
env:
Expand Down
12 changes: 12 additions & 0 deletions .kokoro/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ javadoc)
RETURN_CODE=$?
;;
integration)
# Kokoro integration tests use both JDK 11 and JDK 8. Integration
# tests require JDK 11 export as JAVA env variable to run cloud datastore
# emulator (https://cloud.google.com/sdk/docs/release-notes#39300_2022-07-12).
# For Java 8 environment, we will still run the tests using Java 8 with
# SUREFIRE_JVM_OPT for Maven surefire plugin:
# https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#jvm
if [[ -n "${JAVA11_HOME}" && -n "${JAVA8_HOME}" ]]
then
export JAVA=${JAVA11_HOME}/bin/java
export SUREFIRE_JVM_OPT=-Djvm=${JAVA8_HOME}/bin/java
fi

mvn -B ${INTEGRATION_TEST_ARGS} \
-ntp \
-Penable-integration-tests \
Expand Down
2 changes: 1 addition & 1 deletion .kokoro/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function retry_with_backoff {
return $exit_code
}

## Helper functionss
## Helper functions
function now() { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n'; }
function msg() { println "$*" >&2; }
function println() { printf '%s\n' "$(now) $*"; }
Expand Down
2 changes: 1 addition & 1 deletion .kokoro/presubmit/integration.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ env_vars: {
env_vars: {
key: "SECRET_MANAGER_KEYS"
value: "java-it-service-account"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ public class LocalDatastoreHelper extends BaseEmulatorHelper<DatastoreOptions> {
private final double consistency;
private final Path gcdPath;
private boolean storeOnDisk;
private boolean firestoreInDatastoreMode;

// Gcloud emulator settings
private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators datastore start";
private static final String GCLOUD_CMD_PORT_FLAG = "--host-port=";
private static final String VERSION_PREFIX = "cloud-datastore-emulator ";
private static final String MIN_VERSION = "2.0.2";
private static final String MIN_VERSION = "2.3.1";

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

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

Expand Down Expand Up @@ -102,6 +105,7 @@ public static class Builder {
private int port;
private Path dataDir;
private boolean storeOnDisk = true;
private boolean firestoreInDatastoreMode = false;
private String projectId;

private Builder() {}
Expand All @@ -110,6 +114,7 @@ private Builder(LocalDatastoreHelper helper) {
this.consistency = helper.consistency;
this.dataDir = helper.gcdPath;
this.storeOnDisk = helper.storeOnDisk;
this.firestoreInDatastoreMode = helper.firestoreInDatastoreMode;
}

public Builder setConsistency(double consistency) {
Expand Down Expand Up @@ -137,6 +142,11 @@ public Builder setStoreOnDisk(boolean storeOnDisk) {
return this;
}

public Builder setFirestoreInDatastoreMode(boolean firestoreInDatastoreMode) {
this.firestoreInDatastoreMode = firestoreInDatastoreMode;
return this;
}

/** Creates a {@code LocalDatastoreHelper} object. */
public LocalDatastoreHelper build() {
return new LocalDatastoreHelper(this);
Expand All @@ -152,14 +162,21 @@ private LocalDatastoreHelper(Builder builder) {
this.consistency = builder.consistency > 0 ? builder.consistency : DEFAULT_CONSISTENCY;
this.gcdPath = builder.dataDir;
this.storeOnDisk = builder.storeOnDisk;
this.firestoreInDatastoreMode = builder.firestoreInDatastoreMode;
String binName = BIN_NAME;
if (isWindows()) {
binName = BIN_NAME.replace("/", "\\");
}
List<String> gcloudCommand = new ArrayList<>(Arrays.asList(GCLOUD_CMD_TEXT.split(" ")));
gcloudCommand.add(GCLOUD_CMD_PORT_FLAG + "localhost:" + getPort());
gcloudCommand.add(CONSISTENCY_FLAG + builder.consistency);
gcloudCommand.add(PROJECT_FLAG + projectId);
if (builder.firestoreInDatastoreMode) {
gcloudCommand.add(FIRESTORE_IN_DATASTORE_MODE_FLAG);
} else {
// At most one of --consistency | --use-firestore-in-datastore-mode can be specified.
// --consistency will be ignored with --use-firestore-in-datastore-mode.
gcloudCommand.add(CONSISTENCY_FLAG + builder.consistency);
}
if (!builder.storeOnDisk) {
gcloudCommand.add("--no-store-on-disk");
}
Expand All @@ -170,8 +187,16 @@ private LocalDatastoreHelper(Builder builder) {
new GcloudEmulatorRunner(gcloudCommand, VERSION_PREFIX, MIN_VERSION);
List<String> binCommand = new ArrayList<>(Arrays.asList(binName, "start"));
binCommand.add("--testing");
if (builder.firestoreInDatastoreMode) {
// Downloadable emulator runner takes the flag in a different
// format: --firestore_in_datastore_mode
binCommand.add("--firestore_in_datastore_mode");
} else {
// At most one of --consistency | --firestore_in_datastore_mode can be specified.
// --consistency will be ignored with --firestore_in_datastore_mode.
binCommand.add(CONSISTENCY_FLAG + getConsistency());
}
binCommand.add(BIN_CMD_PORT_FLAG + getPort());
binCommand.add(CONSISTENCY_FLAG + getConsistency());
DownloadableEmulatorRunner downloadRunner =
new DownloadableEmulatorRunner(binCommand, EMULATOR_URL, MD5_CHECKSUM, ACCESS_TOKEN);
this.emulatorRunners = ImmutableList.of(gcloudRunner, downloadRunner);
Expand Down Expand Up @@ -235,6 +260,13 @@ public boolean isStoreOnDisk() {
return storeOnDisk;
}

/**
* Returns {@code true} use firestore-in-datastore-mode, otherwise {@code false} use native mode.
*/
public boolean isFirestoreInDatastoreMode() {
return firestoreInDatastoreMode;
}

/**
* Creates a local Datastore helper with the specified settings for project ID and consistency.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ public void testCreateWithBuilder() {
.setConsistency(0.75)
.setPort(8081)
.setStoreOnDisk(false)
.setFirestoreInDatastoreMode(true)
.setDataDir(dataDir)
.build();
assertTrue(Math.abs(0.75 - helper.getConsistency()) < TOLERANCE);
assertTrue(helper.getProjectId().startsWith(PROJECT_ID_PREFIX));
assertFalse(helper.isStoreOnDisk());
assertTrue(helper.isFirestoreInDatastoreMode());
assertEquals(8081, helper.getPort());
assertEquals(dataDir, helper.getGcdPath());
LocalDatastoreHelper incompleteHelper = LocalDatastoreHelper.newBuilder().build();
Expand All @@ -103,11 +105,13 @@ public void testCreateWithToBuilder() throws IOException {
.setConsistency(0.75)
.setPort(8081)
.setStoreOnDisk(false)
.setFirestoreInDatastoreMode(true)
.setDataDir(dataDir)
.build();
assertTrue(Math.abs(0.75 - helper.getConsistency()) < TOLERANCE);
assertTrue(helper.getProjectId().startsWith(PROJECT_ID_PREFIX));
assertFalse(helper.isStoreOnDisk());
assertTrue(helper.isFirestoreInDatastoreMode());
assertEquals(8081, helper.getPort());
assertEquals(dataDir, helper.getGcdPath());
LocalDatastoreHelper actualHelper = helper.toBuilder().build();
Expand All @@ -119,10 +123,12 @@ public void testCreateWithToBuilder() throws IOException {
.setConsistency(0.85)
.setPort(9091)
.setStoreOnDisk(true)
.setFirestoreInDatastoreMode(false)
.setDataDir(dataDir)
.build();
assertTrue(Math.abs(0.85 - actualHelper.getConsistency()) < TOLERANCE);
assertTrue(actualHelper.isStoreOnDisk());
assertFalse(actualHelper.isFirestoreInDatastoreMode());
assertEquals(9091, actualHelper.getPort());
assertEquals(dataDir, actualHelper.getGcdPath());
LocalDatastoreHelper.deleteRecursively(dataDir);
Expand Down Expand Up @@ -206,10 +212,28 @@ public void testStartStopResetWithBuilder()
}
}

@Test
public void testCreateWithFirestoreInDatastoreMode()
throws IOException, InterruptedException, TimeoutException {
LocalDatastoreHelper helper =
LocalDatastoreHelper.newBuilder().setFirestoreInDatastoreMode(true).build();
assertTrue(helper.isFirestoreInDatastoreMode());
helper.start();
Datastore datastore = helper.getOptions().getService();
Key key = datastore.newKeyFactory().setKind("kind").newKey("name");
Entity expected = Entity.newBuilder(key).build();
datastore.put(expected);
assertNotNull(datastore.get(key));
Entity actual = datastore.get(key);
assertEquals(expected, actual);
helper.stop();
}

public void assertLocalDatastoreHelpersEquivelent(
LocalDatastoreHelper expected, LocalDatastoreHelper actual) {
assertEquals(expected.getConsistency(), actual.getConsistency(), 0);
assertEquals(expected.isStoreOnDisk(), actual.isStoreOnDisk());
assertEquals(expected.isFirestoreInDatastoreMode(), actual.isFirestoreInDatastoreMode());
assertEquals(expected.getGcdPath(), actual.getGcdPath());
}
}
Loading