Skip to content

Commit 835b9c1

Browse files
In-memory: test in-memory database #194
Ignore tests not compatible with in-memory db. Assert in-memory database creates no files.
1 parent 642ff74 commit 835b9c1

File tree

5 files changed

+100
-27
lines changed

5 files changed

+100
-27
lines changed

tests/objectbox-java-test/build.gradle.kts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,18 @@ dependencies {
7272
testImplementation("app.cash.turbine:turbine:0.5.2")
7373
}
7474

75-
tasks.test {
75+
val testInMemory by tasks.registering(Test::class) {
76+
group = "verification"
77+
description = "Run unit tests with in-memory database"
78+
systemProperty("obx.inMemory", true)
79+
}
80+
81+
// Run in-memory tests as part of regular check run
82+
tasks.check {
83+
dependsOn(testInMemory)
84+
}
85+
86+
tasks.withType<Test> {
7687
if (System.getenv("TEST_WITH_JAVA_X86") == "true") {
7788
// To run tests with 32-bit ObjectBox
7889
// Note: 32-bit JDK is only available on Windows

tests/objectbox-java-test/src/test/java/io/objectbox/AbstractObjectBoxTest.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2023 ObjectBox Ltd. All rights reserved.
2+
* Copyright 2017-2024 ObjectBox Ltd. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,17 +16,9 @@
1616

1717
package io.objectbox;
1818

19-
import io.objectbox.ModelBuilder.EntityBuilder;
20-
import io.objectbox.ModelBuilder.PropertyBuilder;
21-
import io.objectbox.annotation.IndexType;
22-
import io.objectbox.config.DebugFlags;
23-
import io.objectbox.model.PropertyFlags;
24-
import io.objectbox.model.PropertyType;
2519
import org.junit.After;
2620
import org.junit.Before;
2721

28-
import javax.annotation.Nullable;
29-
3022
import java.io.File;
3123
import java.io.IOException;
3224
import java.nio.file.Files;
@@ -37,11 +29,22 @@
3729
import java.util.HashMap;
3830
import java.util.List;
3931
import java.util.Map;
32+
import java.util.Objects;
4033
import java.util.Random;
4134
import java.util.concurrent.CountDownLatch;
4235
import java.util.concurrent.TimeUnit;
4336
import java.util.stream.Stream;
4437

38+
import javax.annotation.Nullable;
39+
40+
import io.objectbox.ModelBuilder.EntityBuilder;
41+
import io.objectbox.ModelBuilder.PropertyBuilder;
42+
import io.objectbox.annotation.IndexType;
43+
import io.objectbox.config.DebugFlags;
44+
import io.objectbox.model.PropertyFlags;
45+
import io.objectbox.model.PropertyType;
46+
47+
4548
import static org.junit.Assert.assertEquals;
4649
import static org.junit.Assert.assertTrue;
4750
import static org.junit.Assert.fail;
@@ -52,6 +55,11 @@ public abstract class AbstractObjectBoxTest {
5255
* Turns on additional log output, including logging of transactions or query parameters.
5356
*/
5457
protected static final boolean DEBUG_LOG = false;
58+
59+
/**
60+
* If instead of files the database should be in memory.
61+
*/
62+
protected static final boolean IN_MEMORY = Objects.equals(System.getProperty("obx.inMemory"), "true");
5563
private static boolean printedVersionsOnce;
5664

5765
protected File boxStoreDir;
@@ -92,6 +100,7 @@ public void setUp() throws IOException {
92100
System.out.println("ObjectBox Java version: " + BoxStore.getVersion());
93101
System.out.println("ObjectBox Core version: " + BoxStore.getVersionNative());
94102
System.out.println("First DB dir: " + boxStoreDir);
103+
System.out.println("IN_MEMORY=" + IN_MEMORY);
95104
System.out.println("java.version=" + System.getProperty("java.version"));
96105
System.out.println("file.encoding=" + System.getProperty("file.encoding"));
97106
System.out.println("sun.jnu.encoding=" + System.getProperty("sun.jnu.encoding"));
@@ -105,11 +114,20 @@ public void setUp() throws IOException {
105114
* This works with Android without needing any context.
106115
*/
107116
protected File prepareTempDir(String prefix) throws IOException {
108-
File tempFile = File.createTempFile(prefix, "");
109-
if (!tempFile.delete()) {
110-
throw new IOException("Could not prep temp dir; file delete failed for " + tempFile.getAbsolutePath());
117+
if (IN_MEMORY) {
118+
// Instead of random temp directory, use random suffix for each test to avoid re-using existing database
119+
// from other tests in case clean-up fails.
120+
// Note: all clean-up code will gracefully fail (e.g. deleting the database files will do nothing as the
121+
// directory does not exist).
122+
String randomPart = Long.toUnsignedString(random.nextLong());
123+
return new File(BoxStore.IN_MEMORY_PREFIX + prefix + randomPart);
124+
} else {
125+
File tempFile = File.createTempFile(prefix, "");
126+
if (!tempFile.delete()) {
127+
throw new IOException("Could not prep temp dir; file delete failed for " + tempFile.getAbsolutePath());
128+
}
129+
return tempFile;
111130
}
112-
return tempFile;
113131
}
114132

115133
protected BoxStore createBoxStore() {

tests/objectbox-java-test/src/test/java/io/objectbox/BoxStoreBuilderTest.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2023 ObjectBox Ltd. All rights reserved.
2+
* Copyright 2017-2024 ObjectBox Ltd. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
1616

1717
package io.objectbox;
1818

19+
import org.junit.Before;
20+
import org.junit.Test;
21+
1922
import java.io.File;
2023
import java.io.IOException;
2124
import java.nio.file.Files;
@@ -28,14 +31,14 @@
2831

2932
import io.objectbox.exception.DbFullException;
3033
import io.objectbox.exception.DbMaxDataSizeExceededException;
31-
import org.junit.Before;
32-
import org.junit.Test;
34+
3335

3436
import static org.junit.Assert.assertEquals;
3537
import static org.junit.Assert.assertSame;
3638
import static org.junit.Assert.assertThrows;
3739
import static org.junit.Assert.assertTrue;
3840
import static org.junit.Assert.fail;
41+
import static org.junit.Assume.assumeFalse;
3942

4043
public class BoxStoreBuilderTest extends AbstractObjectBoxTest {
4144

@@ -186,6 +189,8 @@ public void maxSize_invalidValues_throw() {
186189

187190
@Test
188191
public void maxFileSize() {
192+
assumeFalse(IN_MEMORY); // no max size support for in-memory
193+
189194
builder = createBoxStoreBuilder(null);
190195
builder.maxSizeInKByte(30); // Empty file is around 12 KB, object below adds about 8 KB each.
191196
store = builder.build();

tests/objectbox-java-test/src/test/java/io/objectbox/BoxStoreTest.java

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 ObjectBox Ltd. All rights reserved.
2+
* Copyright 2017-2024 ObjectBox Ltd. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,14 +16,16 @@
1616

1717
package io.objectbox;
1818

19-
import io.objectbox.exception.DbException;
2019
import org.junit.Test;
2120
import org.junit.function.ThrowingRunnable;
2221

2322
import java.io.File;
2423
import java.util.concurrent.Callable;
2524
import java.util.concurrent.RejectedExecutionException;
2625

26+
import io.objectbox.exception.DbException;
27+
28+
2729
import static org.junit.Assert.assertEquals;
2830
import static org.junit.Assert.assertFalse;
2931
import static org.junit.Assert.assertNotNull;
@@ -32,6 +34,8 @@
3234
import static org.junit.Assert.assertThrows;
3335
import static org.junit.Assert.assertTrue;
3436
import static org.junit.Assert.fail;
37+
import static org.junit.Assume.assumeFalse;
38+
import static org.junit.Assume.assumeTrue;
3539

3640
public class BoxStoreTest extends AbstractObjectBoxTest {
3741

@@ -178,12 +182,15 @@ public void testOpenTwoBoxStoreTwoFiles() {
178182

179183
@Test
180184
public void testDeleteAllFiles() {
185+
assumeFalse(IN_MEMORY);
181186
closeStoreForTest();
182187
}
183188

184189
@Test
185190
public void testDeleteAllFiles_staticDir() {
191+
assumeFalse(IN_MEMORY);
186192
closeStoreForTest();
193+
187194
File boxStoreDir2 = new File(boxStoreDir.getAbsolutePath() + "-2");
188195
BoxStoreBuilder builder = new BoxStoreBuilder(createTestModel(null)).directory(boxStoreDir2);
189196
BoxStore store2 = builder.build();
@@ -196,6 +203,8 @@ public void testDeleteAllFiles_staticDir() {
196203

197204
@Test
198205
public void testDeleteAllFiles_baseDirName() {
206+
assumeFalse(IN_MEMORY);
207+
199208
closeStoreForTest();
200209
File basedir = new File("test-base-dir");
201210
String name = "mydb";
@@ -220,6 +229,7 @@ public void testDeleteAllFiles_baseDirName() {
220229

221230
@Test(expected = IllegalStateException.class)
222231
public void testDeleteAllFiles_openStore() {
232+
assumeFalse(IN_MEMORY);
223233
BoxStore.deleteAllFiles(boxStoreDir);
224234
}
225235

@@ -245,9 +255,13 @@ public void removeAllObjects() {
245255
}
246256

247257
private void closeStoreForTest() {
248-
assertTrue(boxStoreDir.exists());
258+
if (!IN_MEMORY) {
259+
assertTrue(boxStoreDir.exists());
260+
}
249261
store.close();
250-
assertTrue(store.deleteAllFiles());
262+
if (!IN_MEMORY) {
263+
assertTrue(store.deleteAllFiles());
264+
}
251265
assertFalse(boxStoreDir.exists());
252266
}
253267

@@ -295,22 +309,36 @@ private Callable<String> createTestCallable(final int[] countHolder) {
295309

296310
@Test
297311
public void testSizeOnDisk() {
312+
assumeFalse(IN_MEMORY);
313+
298314
long size = store.sizeOnDisk();
299315
assertTrue(size >= 8192);
300316
}
301317

318+
@Test
319+
public void testInMemory_createsNoFiles() {
320+
assumeTrue(IN_MEMORY);
321+
322+
assertFalse(boxStoreDir.exists());
323+
assertFalse(new File("memory").exists());
324+
assertFalse(new File("memory:").exists());
325+
String identifierPart = boxStoreDir.getPath().substring("memory:".length());
326+
assertFalse(new File(identifierPart).exists());
327+
}
328+
302329
@Test
303330
public void validate() {
304331
putTestEntities(100);
305332

333+
// Note: not implemented for in-memory, returns 0.
306334
// No limit.
307335
long validated = store.validate(0, true);
308-
assertEquals(14, validated);
336+
assertEquals(IN_MEMORY ? 0 : 14, validated);
309337

310338
// With limit.
311339
validated = store.validate(1, true);
312340
// 2 because the first page doesn't contain any actual data?
313-
assertEquals(2, validated);
341+
assertEquals(IN_MEMORY ? 0 : 2, validated);
314342
}
315343

316344
@Test

tests/objectbox-java-test/src/test/java/io/objectbox/BoxStoreValidationTest.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 ObjectBox Ltd. All rights reserved.
2+
* Copyright 2023-2024 ObjectBox Ltd. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,10 @@
1616

1717
package io.objectbox;
1818

19+
import org.greenrobot.essentials.io.IoUtils;
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
1923
import java.io.File;
2024
import java.io.FileOutputStream;
2125
import java.io.IOException;
@@ -24,15 +28,14 @@
2428
import io.objectbox.config.ValidateOnOpenModePages;
2529
import io.objectbox.exception.FileCorruptException;
2630
import io.objectbox.exception.PagesCorruptException;
27-
import org.greenrobot.essentials.io.IoUtils;
28-
import org.junit.Before;
29-
import org.junit.Test;
31+
3032

3133
import static org.junit.Assert.assertEquals;
3234
import static org.junit.Assert.assertNotNull;
3335
import static org.junit.Assert.assertThrows;
3436
import static org.junit.Assert.assertTrue;
3537
import static org.junit.Assert.fail;
38+
import static org.junit.Assume.assumeFalse;
3639

3740
/**
3841
* Tests validation (and recovery) options on opening a store.
@@ -71,6 +74,8 @@ public void validateOnOpen() {
7174

7275
@Test
7376
public void validateOnOpenCorruptFile() throws IOException {
77+
assumeFalse(IN_MEMORY);
78+
7479
File dir = prepareTempDir("object-store-test-corrupted");
7580
prepareBadDataFile(dir, "corrupt-pageno-in-branch-data.mdb");
7681

@@ -87,6 +92,8 @@ public void validateOnOpenCorruptFile() throws IOException {
8792

8893
@Test
8994
public void usePreviousCommitWithCorruptFile() throws IOException {
95+
assumeFalse(IN_MEMORY);
96+
9097
File dir = prepareTempDir("object-store-test-corrupted");
9198
prepareBadDataFile(dir, "corrupt-pageno-in-branch-data.mdb");
9299
builder = BoxStoreBuilder.createDebugWithoutModel().directory(dir);
@@ -101,6 +108,8 @@ public void usePreviousCommitWithCorruptFile() throws IOException {
101108

102109
@Test
103110
public void usePreviousCommitAfterFileCorruptException() throws IOException {
111+
assumeFalse(IN_MEMORY);
112+
104113
File dir = prepareTempDir("object-store-test-corrupted");
105114
prepareBadDataFile(dir, "corrupt-pageno-in-branch-data.mdb");
106115
builder = BoxStoreBuilder.createDebugWithoutModel().directory(dir);
@@ -137,6 +146,8 @@ public void validateOnOpenKv() {
137146

138147
@Test
139148
public void validateOnOpenKvCorruptFile() throws IOException {
149+
assumeFalse(IN_MEMORY);
150+
140151
File dir = prepareTempDir("obx-store-validate-kv-corrupted");
141152
prepareBadDataFile(dir, "corrupt-keysize0-data.mdb");
142153

0 commit comments

Comments
 (0)