Add micro-benchmark for GuavaDataStore
Bug: b/334980270
Test: ./gradlew :datastore:datastore-benchmark:connectedAndroidTest
Change-Id: I6485f1242d5e389d4d88e11921abf523dadc1332
diff --git a/datastore/datastore-benchmark/build.gradle b/datastore/datastore-benchmark/build.gradle
index 9cfb056..3fdc300 100644
--- a/datastore/datastore-benchmark/build.gradle
+++ b/datastore/datastore-benchmark/build.gradle
@@ -32,6 +32,7 @@
dependencies {
androidTestImplementation(project(":datastore:datastore-core"))
+ androidTestImplementation(project(":datastore:datastore-guava"))
androidTestImplementation(project(":internal-testutils-datastore"))
androidTestImplementation(libs.kotlinStdlib)
androidTestImplementation(projectOrArtifact(":benchmark:benchmark-junit4"))
@@ -40,6 +41,7 @@
androidTestImplementation(libs.testCore)
androidTestImplementation(libs.testRunner)
androidTestImplementation(libs.testRules)
+ androidTestImplementation(libs.truth)
androidTestImplementation(libs.kotlinCoroutinesTest)
}
diff --git a/datastore/datastore-benchmark/src/androidTest/java/androidx/datastore/core/GuavaDataStoreSingleProcessTest.java b/datastore/datastore-benchmark/src/androidTest/java/androidx/datastore/core/GuavaDataStoreSingleProcessTest.java
new file mode 100644
index 0000000..dd8a6bcc
--- /dev/null
+++ b/datastore/datastore-benchmark/src/androidTest/java/androidx/datastore/core/GuavaDataStoreSingleProcessTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * 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 androidx.datastore.core;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.benchmark.BenchmarkState;
+import androidx.benchmark.junit4.BenchmarkRule;
+import androidx.datastore.guava.GuavaDataStore;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+
+public class GuavaDataStoreSingleProcessTest {
+ @Rule
+ public BenchmarkRule benchmarkRule = new BenchmarkRule();
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ private static Byte incrementByte(Byte byteIn) {
+ return ++byteIn;
+ }
+
+ private static Byte sameValueByte(Byte byteIn) {
+ return byteIn;
+ }
+
+ @Test
+ public void testCreate() throws Exception {
+ BenchmarkState state = benchmarkRule.getState();
+ while (state.keepRunning()) {
+ File testFile = tmp.newFile();
+ GuavaDataStore<Byte> store = new GuavaDataStore.Builder<Byte>(
+ new TestingSerializer(),
+ () -> testFile
+ ).build();
+
+ state.pauseTiming();
+ Assert.assertNotNull(store);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void testRead() throws Exception {
+ BenchmarkState state = benchmarkRule.getState();
+ File testFile = tmp.newFile();
+ GuavaDataStore<Byte> store = new GuavaDataStore.Builder<Byte>(
+ new TestingSerializer(),
+ () -> testFile
+ ).build();
+ ListenableFuture<Byte> updateFuture = store.updateDataAsync(
+ GuavaDataStoreSingleProcessTest::incrementByte
+ );
+ assertThat(updateFuture.get()).isEqualTo(1);
+
+ while (state.keepRunning()) {
+ Byte currentData = store.getDataAsync().get();
+
+ state.pauseTiming();
+ assertThat(currentData).isEqualTo(1);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void testUpdate_withoutValueChange() throws Exception {
+ BenchmarkState state = benchmarkRule.getState();
+ File testFile = tmp.newFile();
+ GuavaDataStore<Byte> store = new GuavaDataStore.Builder<Byte>(
+ new TestingSerializer(),
+ () -> testFile
+ ).build();
+ ListenableFuture<Byte> updateFuture = store.updateDataAsync(
+ GuavaDataStoreSingleProcessTest::incrementByte
+ );
+ assertThat(updateFuture.get()).isEqualTo(1);
+
+ while (state.keepRunning()) {
+ Byte updatedData = store.updateDataAsync(
+ GuavaDataStoreSingleProcessTest::sameValueByte).get();
+
+ state.pauseTiming();
+ assertThat(updatedData).isEqualTo(1);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void testUpdate_withValueChange() throws Exception {
+ BenchmarkState state = benchmarkRule.getState();
+ File testFile = tmp.newFile();
+ byte counter = 0;
+ GuavaDataStore<Byte> store = new GuavaDataStore.Builder<Byte>(
+ new TestingSerializer(),
+ () -> testFile
+ ).build();
+ // first update creates the file
+ ListenableFuture<Byte> updateFuture = store.updateDataAsync(
+ GuavaDataStoreSingleProcessTest::incrementByte
+ );
+ counter++;
+ assertThat(updateFuture.get()).isEqualTo(counter);
+
+ while (state.keepRunning()) {
+ Byte updatedData = store.updateDataAsync(
+ GuavaDataStoreSingleProcessTest::incrementByte).get();
+
+ state.pauseTiming();
+ counter++;
+ assertThat(updatedData).isEqualTo(counter);
+ state.resumeTiming();
+ }
+ }
+}