From c32462d787a2f073cf2caa46b3cb5dd10a61400f Mon Sep 17 00:00:00 2001 From: Tommy Schmidt Date: Sat, 6 Jul 2024 17:23:49 +0200 Subject: [PATCH 1/6] feat: graalvm support for mvstore --- .../serialization-config.json | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 nitrite-mvstore-adapter/src/main/resources/META-INF/native-image/org.dizitart/nitrite-mvstore-adapter/serialization-config.json diff --git a/nitrite-mvstore-adapter/src/main/resources/META-INF/native-image/org.dizitart/nitrite-mvstore-adapter/serialization-config.json b/nitrite-mvstore-adapter/src/main/resources/META-INF/native-image/org.dizitart/nitrite-mvstore-adapter/serialization-config.json new file mode 100644 index 00000000..678f855d --- /dev/null +++ b/nitrite-mvstore-adapter/src/main/resources/META-INF/native-image/org.dizitart/nitrite-mvstore-adapter/serialization-config.json @@ -0,0 +1,80 @@ +[ + { + "name": "java.lang.Integer" + }, + { + "name": "java.lang.Long" + }, + { + "name": "java.lang.Number" + }, + { + "name": "java.lang.String" + }, + { + "name": "java.util.ArrayList" + }, + { + "name": "java.util.concurrent.atomic.AtomicBoolean" + }, + { + "name": "java.util.concurrent.ConcurrentHashMap" + }, + { + "name": "java.util.concurrent.ConcurrentHashMap$Segment" + }, + { + "name": "java.util.concurrent.CopyOnWriteArrayList" + }, + { + "name": "java.util.concurrent.locks.AbstractOwnableSynchronizer" + }, + { + "name": "java.util.concurrent.locks.AbstractQueuedSynchronizer" + }, + { + "name": "java.util.concurrent.locks.ReentrantLock" + }, + { + "name": "java.util.concurrent.locks.ReentrantLock$NonfairSync" + }, + { + "name": "java.util.concurrent.locks.ReentrantLock$Sync" + }, + { + "name": "java.util.HashMap" + }, + { + "name": "java.util.HashSet" + }, + { + "name": "java.util.LinkedHashMap" + }, + { + "name": "org.dizitart.no2.collection.NitriteDocument" + }, + { + "name": "org.dizitart.no2.collection.NitriteId" + }, + { + "name": "org.dizitart.no2.common.DBValue" + }, + { + "name": "org.dizitart.no2.common.Fields" + }, + { + "name": "org.dizitart.no2.common.meta.Attributes" + }, + { + "name": "org.dizitart.no2.common.tuples.Pair" + }, + { + "name": "org.dizitart.no2.index.IndexDescriptor" + }, + { + "name": "org.dizitart.no2.index.IndexMeta" + }, + { + "name": "org.dizitart.no2.store.UserCredential" + } +] From daeedcf70e98ad0918761dd8a5c7fe2615c8e6d7 Mon Sep 17 00:00:00 2001 From: Tommy Schmidt Date: Sat, 6 Jul 2024 21:54:26 +0200 Subject: [PATCH 2/6] chore: add module with native tests --- .github/workflows/build.yml | 24 ++- nitrite-native-tests/pom.xml | 148 ++++++++++++++++++ .../nitrite/test/DatabaseTestUtils.java | 41 +++++ .../collection/NitriteCollectionDemoTest.java | 40 +++++ .../repository/NitriteRepositoryDemoTest.java | 65 ++++++++ .../repository/PersonEntityConverter.java | 41 +++++ .../nitrite/test/repository/model/Person.java | 79 ++++++++++ .../nitrite/test/repository/model/Title.java | 6 + .../nitrite-native-tests/reflect-config.json | 6 + .../serialization-config.json | 11 ++ pom.xml | 1 + 11 files changed, 461 insertions(+), 1 deletion(-) create mode 100644 nitrite-native-tests/pom.xml create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/PersonEntityConverter.java create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Person.java create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Title.java create mode 100644 nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/reflect-config.json create mode 100644 nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/serialization-config.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df10d2af..a4d10113 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ['11', '17'] + java: [ '11', '17' ] env: JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1" @@ -94,3 +94,25 @@ jobs: - name: Build with Maven run: mvn -B -ff -ntp clean install --% -Dgpg.skip=true + + verify-native: + name: Verify GraalVM compatibility on ${{ matrix.os }} + strategy: + matrix: + os: [ 'ubuntu-latest', 'windows-latest', 'macos-latest' ] + java: [ '17', '21' ] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - uses: graalvm/setup-graalvm@v1.2.1 + with: + java-version: ${{ matrix.java }} + distribution: 'graalvm-community' + + - name: Install nitrite + run: mvn -B -ff -ntp clean install -Dgpg.skip=true -DskipTests + + - name: Run native tests + working-directory: ./nitrite-native-tests + run: mvn -B -ff -ntp -PnativeTest verify diff --git a/nitrite-native-tests/pom.xml b/nitrite-native-tests/pom.xml new file mode 100644 index 00000000..c157319d --- /dev/null +++ b/nitrite-native-tests/pom.xml @@ -0,0 +1,148 @@ + + + 4.0.0 + + + org.dizitart + nitrite-java + 4.3.1-SNAPSHOT + + + nitrite-native-tests + + Nitrite Native Tests + Test module to ensures GraalVM compatibility of nitrite + + + 17 + 17 + UTF-8 + + 3.25.3 + 5.10.3 + 0.10.2 + + + + + + org.junit + junit-bom + ${junit.version} + pom + import + + + + + + + org.dizitart + nitrite + ${project.version} + + + org.dizitart + nitrite-mvstore-adapter + ${project.version} + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + + + org.apache.maven.plugins + maven-install-plugin + + true + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + + org.apache.maven.plugins + maven-source-plugin + + true + + + + + org.apache.maven.plugins + maven-gpg-plugin + + true + + + + + + + + nativeTest + + + org.junit.platform + junit-platform-launcher + test + + + + + + org.graalvm.buildtools + native-maven-plugin + ${native-build-tools-plugin.version} + true + + ${project.build.outputDirectory} + + + + native-test + + test + + + + + + + + + \ No newline at end of file diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java new file mode 100644 index 00000000..69b326bf --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java @@ -0,0 +1,41 @@ +package org.dizitart.nitrite.test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.logging.Logger; + +import org.dizitart.nitrite.test.repository.PersonEntityConverter; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.mvstore.MVStoreModule; + +public class DatabaseTestUtils { + + private static final Logger logger = Logger.getLogger(DatabaseTestUtils.class.getSimpleName()); + + public static Nitrite setupDatabase() throws IOException { + return setupDatabase(null); + } + + public static Nitrite setupDatabase(final Path template) throws IOException { + + final Path databasePath = Files.createTempFile("v-rising-bot", ".db"); + logger.info("Test Db location: " + databasePath.toAbsolutePath()); + + if (template != null) { + logger.info("Loading template from '" + template.toAbsolutePath() + "'."); + Files.copy(template, databasePath, StandardCopyOption.REPLACE_EXISTING); + } + + final MVStoreModule mvStoreModule = MVStoreModule.withConfig() + .filePath(databasePath.toFile()) + .build(); + + return Nitrite.builder() + .loadModule(mvStoreModule) + .disableRepositoryTypeValidation() + .registerEntityConverter(new PersonEntityConverter()) + .openOrCreate("test", "test"); + } +} diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java new file mode 100644 index 00000000..494aaeb1 --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java @@ -0,0 +1,40 @@ +package org.dizitart.nitrite.test.collection; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.math.BigDecimal; + +import org.dizitart.nitrite.test.DatabaseTestUtils; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.junit.jupiter.api.Test; + +public class NitriteCollectionDemoTest { + + @Test + void readAndWriteOperationsShouldSucceed() throws IOException { + + try (final Nitrite database = DatabaseTestUtils.setupDatabase()) { + + final var testCollection = database.getCollection("test"); + + final Document expectedDocument = Document.createDocument() + .put("test", "test") + // requires additional serialization hints for BigDecimal and BigInteger + // this also applies to other Serializable classes + // see: src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/serialization-config.json + .put("price", new BigDecimal("9.99")); + + final NitriteId id = testCollection.insert(expectedDocument).iterator().next(); + + final Document actualDocument = testCollection.getById(id); + + assertThat(actualDocument).isNotNull(); + assertThat(actualDocument.getId()).isEqualTo(id); + assertThat(actualDocument.get("test", String.class)).isEqualTo("test"); + assertThat(actualDocument.get("price", BigDecimal.class)).isEqualTo("9.99"); + } + } +} diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java new file mode 100644 index 00000000..e02e06d4 --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java @@ -0,0 +1,65 @@ +package org.dizitart.nitrite.test.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.util.Set; +import java.util.UUID; + +import org.dizitart.nitrite.test.DatabaseTestUtils; +import org.dizitart.nitrite.test.repository.model.Person; +import org.dizitart.nitrite.test.repository.model.Title; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.filters.FluentFilter; +import org.junit.jupiter.api.Test; + +public class NitriteRepositoryDemoTest { + + @Test + void readAndWriteOperationsShouldSucceed() throws IOException { + + try (final Nitrite database = DatabaseTestUtils.setupDatabase()) { + + final var personRepository = database.getRepository(Person.class); + + final Person expectedPerson = new Person( + UUID.randomUUID().toString(), + "Testi", + "Tester", + 20, + Set.of(Title.PROF), + false + ); + personRepository.insert(expectedPerson); + + final Person actualPerson = personRepository.getById(expectedPerson.getId()); + + assertThat(actualPerson).isEqualTo(expectedPerson); + } + } + + @Test + void filterByIndexedFieldShouldSucceed() throws IOException { + + try (final Nitrite database = DatabaseTestUtils.setupDatabase()) { + + final var personRepository = database.getRepository(Person.class); + + final Person expectedPerson = new Person( + UUID.randomUUID().toString(), + "Testi", + "Tester", + 20, + Set.of(Title.PROF), + true + ); + personRepository.insert(expectedPerson); + + final Person actualPerson = personRepository.find( + FluentFilter.where("lastName").eq("Tester") + ).firstOrNull(); + + assertThat(actualPerson).isEqualTo(expectedPerson); + } + } +} diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/PersonEntityConverter.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/PersonEntityConverter.java new file mode 100644 index 00000000..52a009cc --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/PersonEntityConverter.java @@ -0,0 +1,41 @@ +package org.dizitart.nitrite.test.repository; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.dizitart.nitrite.test.repository.model.Person; +import org.dizitart.nitrite.test.repository.model.Title; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.EntityConverter; +import org.dizitart.no2.common.mapper.NitriteMapper; + +public class PersonEntityConverter implements EntityConverter { + + @Override + public Class getEntityType() { + return Person.class; + } + + @Override + public Document toDocument(final Person person, final NitriteMapper nitriteMapper) { + return Document.createDocument() + .put("id", person.getId()) + .put("firstName", person.getFirstName()) + .put("lastName", person.getLastName()) + .put("age", person.getAge()) + .put("titles", person.getTitles().stream().map(Enum::name).collect(Collectors.toSet())) + .put("someBoolean", person.isSomeBoolean()); + } + + @Override + public Person fromDocument(final Document document, final NitriteMapper nitriteMapper) { + return new Person( + document.get("id", String.class), + document.get("firstName", String.class), + document.get("lastName", String.class), + (int) document.get("age"), + ((Set) document.get("titles")).stream().map(title -> Title.valueOf((String) title)).collect(Collectors.toSet()), + (boolean) document.get("someBoolean") + ); + } +} diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Person.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Person.java new file mode 100644 index 00000000..422b9011 --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Person.java @@ -0,0 +1,79 @@ +package org.dizitart.nitrite.test.repository.model; + +import java.util.Objects; +import java.util.Set; + +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; +import org.dizitart.no2.repository.annotations.Indices; + +// @Indices requires additional reflection hints for GraalVM +// see: src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/reflect-config.json +@Indices( + @Index(fields = "lastName", type = IndexType.NON_UNIQUE) +) +public class Person { + @Id + private final String id; + private final String firstName; + private final String lastName; + private final int age; + private final Set titles; + + // additional serialization hints are required to serialize boolean fields + // this also applies to other Serializable classes + // see: src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/serialization-config.json + private final boolean someBoolean; + + public Person(final String id, + final String firstName, + final String lastName, + final int age, + final Set<Title> titles, + final boolean someBoolean) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + this.titles = titles; + this.someBoolean = someBoolean; + } + + public String getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public int getAge() { + return age; + } + + public Set<Title> getTitles() { + return titles; + } + + public boolean isSomeBoolean() { + return someBoolean; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Person person = (Person) o; + return age == person.age && someBoolean == person.someBoolean && Objects.equals(id, person.id) && Objects.equals(firstName, person.firstName) && Objects.equals(lastName, person.lastName) && Objects.equals(titles, person.titles); + } + + @Override + public int hashCode() { + return Objects.hash(id, firstName, lastName, age, titles, someBoolean); + } +} diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Title.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Title.java new file mode 100644 index 00000000..e78af8f8 --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/model/Title.java @@ -0,0 +1,6 @@ +package org.dizitart.nitrite.test.repository.model; + +public enum Title { + DR, + PROF +} diff --git a/nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/reflect-config.json b/nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/reflect-config.json new file mode 100644 index 00000000..253efd58 --- /dev/null +++ b/nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/reflect-config.json @@ -0,0 +1,6 @@ +[ + { + "name": "org.dizitart.nitrite.test.repository.model.Person", + "allDeclaredFields": true + } +] diff --git a/nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/serialization-config.json b/nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/serialization-config.json new file mode 100644 index 00000000..344f9fc7 --- /dev/null +++ b/nitrite-native-tests/src/test/resources/META-INF/native-image/org.dizitart/nitrite-native-tests/serialization-config.json @@ -0,0 +1,11 @@ +[ + { + "name": "java.lang.Boolean" + }, + { + "name": "java.math.BigDecimal" + }, + { + "name": "java.math.BigInteger" + } +] diff --git a/pom.xml b/pom.xml index deed1996..34a0ffa6 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ <module>nitrite-bom</module> <module>nitrite-jackson-mapper</module> <module>nitrite-mvstore-adapter</module> + <module>nitrite-native-tests</module> <module>nitrite-rocksdb-adapter</module> <module>nitrite-spatial</module> <module>nitrite-support</module> From b3248f53128ece50d75cdc40c12703fa0e9b2f85 Mon Sep 17 00:00:00 2001 From: Tommy Schmidt <tommy.schmidt@idealo.de> Date: Sat, 6 Jul 2024 21:56:17 +0200 Subject: [PATCH 3/6] chore: add module with native tests --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4d10113..141b8f94 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -96,7 +96,7 @@ jobs: run: mvn -B -ff -ntp clean install --% -Dgpg.skip=true verify-native: - name: Verify GraalVM compatibility on ${{ matrix.os }} + name: Verify GraalVM ${{ matrix.java }} compatibility on ${{ matrix.os }} strategy: matrix: os: [ 'ubuntu-latest', 'windows-latest', 'macos-latest' ] From 0777eb320d2257380622b606ce1b3d9833a20aa1 Mon Sep 17 00:00:00 2001 From: Tommy Schmidt <tommy.schmidt@idealo.de> Date: Sat, 6 Jul 2024 21:58:36 +0200 Subject: [PATCH 4/6] chore: add module with native tests --- nitrite-native-tests/pom.xml | 2 +- .../test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nitrite-native-tests/pom.xml b/nitrite-native-tests/pom.xml index c157319d..902dc3ef 100644 --- a/nitrite-native-tests/pom.xml +++ b/nitrite-native-tests/pom.xml @@ -145,4 +145,4 @@ </build> </profile> </profiles> -</project> \ No newline at end of file +</project> diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java index 69b326bf..28867ff4 100644 --- a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java @@ -20,7 +20,7 @@ public static Nitrite setupDatabase() throws IOException { public static Nitrite setupDatabase(final Path template) throws IOException { - final Path databasePath = Files.createTempFile("v-rising-bot", ".db"); + final Path databasePath = Files.createTempFile("nitrite-native", ".db"); logger.info("Test Db location: " + databasePath.toAbsolutePath()); if (template != null) { From 00c66f383885c55cd62df2f076a3f87dbbebfe47 Mon Sep 17 00:00:00 2001 From: DarkAtra <darkatra@gmail.com> Date: Sun, 7 Jul 2024 19:59:54 +0200 Subject: [PATCH 5/6] chore: add tests for transactions --- .github/workflows/build.yml | 2 +- ...ctionDemoTest.java => CollectionTest.java} | 9 ++- ...itoryDemoTest.java => RepositoryTest.java} | 11 ++- .../test/transaction/TransactionTest.java | 67 +++++++++++++++++++ 4 files changed, 77 insertions(+), 12 deletions(-) rename nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/{NitriteCollectionDemoTest.java => CollectionTest.java} (97%) rename nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/{NitriteRepositoryDemoTest.java => RepositoryTest.java} (97%) create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/transaction/TransactionTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 141b8f94..ea87b2e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -111,7 +111,7 @@ jobs: distribution: 'graalvm-community' - name: Install nitrite - run: mvn -B -ff -ntp clean install -Dgpg.skip=true -DskipTests + run: mvn -B -ff -ntp clean install "-Dgpg.skip=true" -DskipTests - name: Run native tests working-directory: ./nitrite-native-tests diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/CollectionTest.java similarity index 97% rename from nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java rename to nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/CollectionTest.java index 494aaeb1..837157cc 100644 --- a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/NitriteCollectionDemoTest.java +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/collection/CollectionTest.java @@ -1,17 +1,16 @@ package org.dizitart.nitrite.test.collection; import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; -import java.math.BigDecimal; - import org.dizitart.nitrite.test.DatabaseTestUtils; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.junit.jupiter.api.Test; -public class NitriteCollectionDemoTest { +import java.io.IOException; +import java.math.BigDecimal; + +public class CollectionTest { @Test void readAndWriteOperationsShouldSucceed() throws IOException { diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/RepositoryTest.java similarity index 97% rename from nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java rename to nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/RepositoryTest.java index e02e06d4..fc9091cf 100644 --- a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/NitriteRepositoryDemoTest.java +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/repository/RepositoryTest.java @@ -1,11 +1,6 @@ package org.dizitart.nitrite.test.repository; import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; -import java.util.Set; -import java.util.UUID; - import org.dizitart.nitrite.test.DatabaseTestUtils; import org.dizitart.nitrite.test.repository.model.Person; import org.dizitart.nitrite.test.repository.model.Title; @@ -13,7 +8,11 @@ import org.dizitart.no2.filters.FluentFilter; import org.junit.jupiter.api.Test; -public class NitriteRepositoryDemoTest { +import java.io.IOException; +import java.util.Set; +import java.util.UUID; + +public class RepositoryTest { @Test void readAndWriteOperationsShouldSucceed() throws IOException { diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/transaction/TransactionTest.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/transaction/TransactionTest.java new file mode 100644 index 00000000..0482e2fb --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/transaction/TransactionTest.java @@ -0,0 +1,67 @@ +package org.dizitart.nitrite.test.transaction; + +import static org.assertj.core.api.Assertions.assertThat; +import org.dizitart.nitrite.test.DatabaseTestUtils; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.transaction.Session; +import org.dizitart.no2.transaction.Transaction; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +public class TransactionTest { + + @Test + void transactionCommitShouldSucceed() throws IOException { + + try (final Nitrite database = DatabaseTestUtils.setupDatabase()) { + + final var testCollection = database.getCollection("test"); + + try (final Session session = database.createSession(); + final Transaction transaction = session.beginTransaction()) { + + final Document expectedDocument = Document.createDocument() + .put("test", "test"); + + final NitriteId id = transaction.getCollection("test").insert(expectedDocument).iterator().next(); + + assertThat(testCollection.getById(id)).isNull(); + + transaction.commit(); + + final Document actualDocument = testCollection.getById(id); + + assertThat(actualDocument).isNotNull(); + assertThat(actualDocument.getId()).isEqualTo(id); + assertThat(actualDocument.get("test", String.class)).isEqualTo("test"); + } + } + } + + @Test + void transactionRollbackShouldSucceed() throws IOException { + + try (final Nitrite database = DatabaseTestUtils.setupDatabase()) { + + final var testCollection = database.getCollection("test"); + + try (final Session session = database.createSession(); + final Transaction transaction = session.beginTransaction()) { + + final Document expectedDocument = Document.createDocument() + .put("test", "test"); + + final NitriteId id = transaction.getCollection("test").insert(expectedDocument).iterator().next(); + + assertThat(testCollection.getById(id)).isNull(); + + transaction.rollback(); + + assertThat(testCollection.getById(id)).isNull(); + } + } + } +} From d50500bf28169443278629f94d5f6ec299328def Mon Sep 17 00:00:00 2001 From: Tommy Schmidt <tommy.schmidt@idealo.de> Date: Mon, 8 Jul 2024 16:11:36 +0200 Subject: [PATCH 6/6] chore: add test for migrations --- .../nitrite/test/DatabaseTestUtils.java | 11 ++- .../nitrite/test/migration/MigrationTest.java | 79 +++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/migration/MigrationTest.java diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java index 28867ff4..556f9366 100644 --- a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/DatabaseTestUtils.java @@ -14,17 +14,22 @@ public class DatabaseTestUtils { private static final Logger logger = Logger.getLogger(DatabaseTestUtils.class.getSimpleName()); + public static Path getRandomDatabasePath() throws IOException { + final Path databasePath = Files.createTempFile("nitrite-native", ".db"); + logger.finest("Test Db location: " + databasePath.toAbsolutePath()); + return databasePath; + } + public static Nitrite setupDatabase() throws IOException { return setupDatabase(null); } public static Nitrite setupDatabase(final Path template) throws IOException { - final Path databasePath = Files.createTempFile("nitrite-native", ".db"); - logger.info("Test Db location: " + databasePath.toAbsolutePath()); + final Path databasePath = getRandomDatabasePath(); if (template != null) { - logger.info("Loading template from '" + template.toAbsolutePath() + "'."); + logger.finest("Loading template from '" + template.toAbsolutePath() + "'."); Files.copy(template, databasePath, StandardCopyOption.REPLACE_EXISTING); } diff --git a/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/migration/MigrationTest.java b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/migration/MigrationTest.java new file mode 100644 index 00000000..2ef29849 --- /dev/null +++ b/nitrite-native-tests/src/test/java/org/dizitart/nitrite/test/migration/MigrationTest.java @@ -0,0 +1,79 @@ +package org.dizitart.nitrite.test.migration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.dizitart.no2.index.IndexOptions.indexOptions; + +import java.io.IOException; + +import org.dizitart.nitrite.test.DatabaseTestUtils; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.Constants; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.migration.InstructionSet; +import org.dizitart.no2.migration.Migration; +import org.dizitart.no2.mvstore.MVStoreModule; +import org.junit.jupiter.api.Test; + +public class MigrationTest { + + @Test + void schemaMigrationShouldSucceed() throws IOException { + + final MVStoreModule mvStoreModule = MVStoreModule.withConfig() + .filePath(DatabaseTestUtils.getRandomDatabasePath().toAbsolutePath().toFile()) + .build(); + + try (final Nitrite database = Nitrite.builder() + .loadModule(mvStoreModule) + .schemaVersion(1) + .openOrCreate()) { + + final var collection = database.getCollection("test"); + for (int i = 0; i < 10; i++) { + Document document = Document.createDocument(); + document.put("firstName", "first-name"); + document.put("lastName", "last-name"); + document.put("bloodGroup", "blood-group"); + document.put("age", 21); + + collection.insert(document); + } + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + + assertThat(collection.hasIndex("firstName")).isTrue(); + assertThat(collection.hasIndex("lastName")).isTrue(); + assertThat(collection.size()).isEqualTo(10); + assertThat(database.listCollectionNames()).hasSize(1); + assertThat(database.getDatabaseMetaData().getSchemaVersion()).isEqualTo(Constants.INITIAL_SCHEMA_VERSION); + } + + final Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, Constants.INITIAL_SCHEMA_VERSION + 1) { + @Override + public void migrate(InstructionSet instruction) { + instruction.forDatabase() + .addUser("test-user", "test-password"); + + instruction.forCollection("test") + .rename("testCollectionMigrate") + .deleteField("lastName"); + } + }; + + try (final Nitrite database = Nitrite.builder() + .loadModule(mvStoreModule) + .schemaVersion(Constants.INITIAL_SCHEMA_VERSION + 1) + .addMigrations(migration) + .openOrCreate("test-user", "test-password")) { + + final var collection = database.getCollection("testCollectionMigrate"); + assertThat(collection.hasIndex("firstName")).isTrue(); + assertThat(collection.hasIndex("lastName")).isFalse(); + assertThat(collection.size()).isEqualTo(10); + assertThat(database.listCollectionNames()).hasSize(1); + assertThat(database.getDatabaseMetaData().getSchemaVersion()).isEqualTo(2); + } + } +}