caio.co/de/cerberus

SDB: Add some basic tests

Id
2419e7c3c80848a74b9930a576d1e5d12e1b647a
Author
Caio
Commit time
2019-05-21T09:36:53+02:00

Modified src/main/java/co/caio/cerberus/db/SimpleRecipeMetadataDatabase.java

@@ -9,7 +9,6
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Files;
-import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
@@ -24,16 +23,22
private final LongIntHashMap idToOffset;
private final ByteBuffer rawData;

+ public int size() {
+ return idToOffset.size();
+ }
+
public SimpleRecipeMetadataDatabase(Path baseDir) {

if (!baseDir.toFile().isDirectory()) {
- throw new InvalidPathException(baseDir.toString(), "Not a directory");
+ throw new RecipeMetadataDbException("Not a directory: " + baseDir);
}

try (var raf = new RandomAccessFile(baseDir.resolve(FILE_OFFSETS).toFile(), "r")) {

int size = raf.readInt();
- assert size > 0;
+ if (size < 0) {
+ throw new RecipeMetadataDbException("Invalid offsets file length");
+ }

idToOffset = new LongIntHashMap(size);

@@ -113,7 +118,10
}

try {
- this.offsetsFile.writeInt(0);
+ // First bytes are for the number of items in the database
+ // we set to -1 here and, during close(), configure the
+ // correct value
+ this.offsetsFile.writeInt(-1);
} catch (IOException wrapped) {
throw new RecipeMetadataDbException(wrapped);
}
@@ -136,10 +144,11

public void close() {
try {
- dataChannel.close();
-
+ // Write the number of recipes to the beginning of the offsets file
offsetsFile.seek(0);
offsetsFile.writeInt(numRecipes);
+
+ dataChannel.close();
offsetsFile.close();
} catch (IOException wrapped) {
throw new RecipeMetadataDbException(wrapped);

Modified src/test/java/co/caio/cerberus/db/SimpleRecipeMetadataDatabaseTest.java

@@ -1,24 +1,29
package co.caio.cerberus.db;

import static org.junit.jupiter.api.Assertions.*;

import co.caio.cerberus.Util;
+import co.caio.cerberus.db.RecipeMetadataDatabase.RecipeMetadataDbException;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;

class SimpleRecipeMetadataDatabaseTest {

@Test
- void create() throws IOException {
- var dbPath = Files.createTempDirectory("sdb");
+ void canSaveAndReadSamples() throws IOException {
+ var numSamples = 10;
+ var dbPath = Files.createTempDirectory("sdb-");

var writer = new SimpleRecipeMetadataDatabase.Writer(dbPath);

var samples =
Util.getSampleRecipes()
.map(RecipeMetadata::fromRecipe)
+ .limit(numSamples)
.peek(writer::addRecipe)
.collect(Collectors.toList());

@@ -32,5 +37,43
assertTrue(dbRecipe.isPresent());
assertEquals(r.getRecipeId(), dbRecipe.get().getRecipeId());
});
+
+ assertEquals(numSamples, db.size());
+ }
+
+ @Test
+ void canCreateEmptyDb() throws IOException {
+ var dbPath = Files.createTempDirectory("sdb-empty-");
+ new SimpleRecipeMetadataDatabase.Writer(dbPath).close();
+ assertDoesNotThrow(() -> new SimpleRecipeMetadataDatabase(dbPath));
+ assertEquals(0, new SimpleRecipeMetadataDatabase(dbPath).size());
+ }
+
+ @Test
+ void cannotOpenInvalidDir() {
+ assertThrows(
+ RecipeMetadataDbException.class,
+ () -> new SimpleRecipeMetadataDatabase(Path.of("/does/not/exist")));
+ }
+
+ @Test
+ void cannotWriteToExistingDb() throws IOException {
+ var dbPath = Files.createTempDirectory("sdb-empty-");
+
+ // First open+close should work
+ assertDoesNotThrow(() -> new SimpleRecipeMetadataDatabase.Writer(dbPath).close());
+ // Trying to open a write when a database exists should fail
+ assertThrows(
+ RecipeMetadataDbException.class, () -> new SimpleRecipeMetadataDatabase.Writer(dbPath));
+ }
+
+ @Test
+ void saveAllIsNotAllowed() throws IOException {
+ var dbPath = Files.createTempDirectory("sdb-empty-");
+ new SimpleRecipeMetadataDatabase.Writer(dbPath).close();
+ var db = new SimpleRecipeMetadataDatabase(dbPath);
+ assertThrows(
+ RecipeMetadataDbException.class,
+ () -> db.saveAll(List.of(RecipeMetadata.fromRecipe(Util.getBasicRecipe()))));
}
}