package org.bodytrack.datastore;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* <p>
* <code>FilesystemKeyValueStoreTest</code> tests the {@link FilesystemKeyValueStore} class.
* </p>
*
* @author Chris Bartley (bartley@cmu.edu)
*/
@RunWith(JUnit4.class)
public class FilesystemKeyValueStoreTest {
private static final String EMPTY_KEY = "";
private static final String INVALID_KEY = ".invalid_key";
private static final String VALUE_1_KEY = "feynman.quote";
private static final String VALUE_2_KEY = "feynman.photo";
private static File keystoreRootDirectory;
private static final byte[] VALUE_1 = "What I cannot create, I do not understand.\n".getBytes();
private static final byte[] VALUE_2;
private static final byte[] VALUE_3 = "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled.\n".getBytes();
static {
byte[] value2;
try {
value2 = IOUtils.toByteArray(FilesystemKeyValueStoreTest.class.getResourceAsStream("/images/test_image1.jpg"));
}
catch (IOException e) {
value2 = "Failed to read the image file".getBytes();
System.err.println("IOException while trying to read the file for VALUE_2:" + e);
}
VALUE_2 = value2;
}
@BeforeClass
public static void performSetup() {
// get Java's temp directory
final String tempDirectoryPath = System.getProperty("java.io.tmpdir", null);
Assert.assertNotNull(tempDirectoryPath);
// create the root directory used by all the tests
keystoreRootDirectory = new File(tempDirectoryPath, FilesystemKeyValueStore.class.getCanonicalName() + System.nanoTime());
keystoreRootDirectory.deleteOnExit();
// make sure the directory exists
final boolean mkdirsResult = keystoreRootDirectory.mkdirs();
Assert.assertTrue("Expected to be able to create directory [" + keystoreRootDirectory + "]", mkdirsResult);
}
@Test
public void testConstructor() {
// test creating a FilesystemKeyValueStore with a null diretory
try {
//noinspection ConstantConditions
new FilesystemKeyValueStore(null);
Assert.fail("Creating a FilesystemKeyValueStore with a null root directory should fail with an IllegalArgumentException");
}
catch (final IllegalArgumentException e) {
// nothing to do here because we expect it to fail with an IllegalArgumentException
}
// test creating a FilesystemKeyValueStore with a non-existent diretory.
try {
new FilesystemKeyValueStore(new File("/this/is/a/bogus/directory"));
Assert.fail("Creating a FilesystemKeyValueStore with a non-existent directory should fail with an IllegalArgumentException");
}
catch (final IllegalArgumentException e) {
// nothing to do here because we expect it to fail with an IllegalArgumentException
}
// test creating a FilesystemKeyValueStore with a valid diretory
try {
final FilesystemKeyValueStore store = new FilesystemKeyValueStore(keystoreRootDirectory);
Assert.assertNotNull(store);
}
catch (final Exception e) {
Assert.fail("Creation of the FilesystemKeyValueStore should not have thrown an exception: " + e);
}
}
@SuppressWarnings("ConstantConditions")
@Test
public void testKeyToFile() {
try {
FilesystemKeyValueStore.keyToFile(null, null);
Assert.fail("Calling FilesystemKeyValueStore.keyToFile with null arguments should fail with an IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// nothing to do here because we expect it to fail with an IllegalArgumentException
}
try {
FilesystemKeyValueStore.keyToFile(keystoreRootDirectory, null);
Assert.fail("Calling FilesystemKeyValueStore.keyToFile with null arguments should fail with an IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// nothing to do here because we expect it to fail with an IllegalArgumentException
}
try {
FilesystemKeyValueStore.keyToFile(null, "the.key");
Assert.fail("Calling FilesystemKeyValueStore.keyToFile with null arguments should fail with an IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// nothing to do here because we expect it to fail with an IllegalArgumentException
}
Assert.assertNull(FilesystemKeyValueStore.keyToFile(keystoreRootDirectory, EMPTY_KEY));
Assert.assertNull(FilesystemKeyValueStore.keyToFile(keystoreRootDirectory, INVALID_KEY));
final File valueFile1 = FilesystemKeyValueStore.keyToFile(keystoreRootDirectory, VALUE_1_KEY);
Assert.assertNotNull(valueFile1);
Assert.assertEquals(valueFile1.getAbsolutePath(), new File(keystoreRootDirectory, "feynman/quote.val").getAbsolutePath());
final File valueFile2 = FilesystemKeyValueStore.keyToFile(keystoreRootDirectory, VALUE_2_KEY);
Assert.assertNotNull(valueFile2);
Assert.assertEquals(valueFile2.getAbsolutePath(), new File(keystoreRootDirectory, "feynman/photo.val").getAbsolutePath());
}
@SuppressWarnings("ConstantConditions")
@Test
public void testCRUD() {
final FilesystemKeyValueStore store = new FilesystemKeyValueStore(keystoreRootDirectory);
// test hasKey -- these should all be false since there's nothing in the keystore yet
Assert.assertFalse(store.hasKey(null));
Assert.assertFalse(store.hasKey(EMPTY_KEY));
Assert.assertFalse(store.hasKey(INVALID_KEY));
Assert.assertFalse(store.hasKey(VALUE_1_KEY));
Assert.assertFalse(store.hasKey(VALUE_2_KEY));
// test get -- these should all be null since there's nothing in the keystore yet
Assert.assertNull(store.get(null));
Assert.assertNull(store.get(EMPTY_KEY));
Assert.assertNull(store.get(INVALID_KEY));
Assert.assertNull(store.get(VALUE_1_KEY));
Assert.assertNull(store.get(VALUE_2_KEY));
// test set
try {
Assert.assertFalse(store.set(null, null));
Assert.fail(".set should have failed when given null arguments");
}
catch (IllegalArgumentException e) {
// nothing to do since we expect it to fail with an IllegalArgumentException
}
try {
Assert.assertFalse(store.set(null, new byte[]{}));
Assert.fail(".set should have failed when given null arguments");
}
catch (IllegalArgumentException e) {
// nothing to do since we expect it to fail with an IllegalArgumentException
}
try {
Assert.assertFalse(store.set(null, VALUE_1));
Assert.fail(".set should have failed when given null arguments");
}
catch (IllegalArgumentException e) {
// nothing to do since we expect it to fail with an IllegalArgumentException
}
try {
Assert.assertFalse(store.set(EMPTY_KEY, null));
Assert.fail(".set should have failed when given null arguments");
}
catch (IllegalArgumentException e) {
// nothing to do since we expect it to fail with an IllegalArgumentException
}
Assert.assertFalse(store.set(EMPTY_KEY, new byte[]{}));
Assert.assertFalse(store.set(EMPTY_KEY, VALUE_1));
Assert.assertFalse(store.set(INVALID_KEY, VALUE_1));
Assert.assertTrue(store.set(VALUE_1_KEY, VALUE_1));
Assert.assertTrue(store.set(VALUE_2_KEY, VALUE_2));
// now that we've set some values, test hasKey and get again
Assert.assertFalse(store.hasKey(null));
Assert.assertFalse(store.hasKey(EMPTY_KEY));
Assert.assertFalse(store.hasKey(INVALID_KEY));
Assert.assertTrue(store.hasKey(VALUE_1_KEY));
Assert.assertTrue(store.hasKey(VALUE_2_KEY));
Assert.assertNull(store.get(null));
Assert.assertNull(store.get(EMPTY_KEY));
Assert.assertNull(store.get(INVALID_KEY));
final byte[] value1 = store.get(VALUE_1_KEY);
Assert.assertNotNull(value1);
Assert.assertTrue(Arrays.equals(VALUE_1, value1));
final byte[] value2 = store.get(VALUE_2_KEY);
Assert.assertNotNull(value2);
Assert.assertTrue(Arrays.equals(VALUE_2, value2));
// now test overwrite
Assert.assertTrue(store.set(VALUE_1_KEY, VALUE_3));
Assert.assertTrue(store.hasKey(VALUE_1_KEY));
final byte[] value3 = store.get(VALUE_1_KEY);
Assert.assertNotNull(value3);
Assert.assertTrue(Arrays.equals(VALUE_3, value3));
// now test delete
Assert.assertFalse(store.delete(null));
Assert.assertFalse(store.delete(EMPTY_KEY));
Assert.assertFalse(store.delete(INVALID_KEY));
Assert.assertTrue(store.delete(VALUE_1_KEY));
Assert.assertTrue(store.delete(VALUE_2_KEY));
// finally, test hasKey and get again to make sure they return proper
// values now that the values have been deleted
// test hasKey -- these should all be false since there's nothing in the keystore anymore
Assert.assertFalse(store.hasKey(null));
Assert.assertFalse(store.hasKey(EMPTY_KEY));
Assert.assertFalse(store.hasKey(INVALID_KEY));
Assert.assertFalse(store.hasKey(VALUE_1_KEY));
Assert.assertFalse(store.hasKey(VALUE_2_KEY));
// test get -- these should all be null since there's nothing in the keystore anymore
Assert.assertNull(store.get(null));
Assert.assertNull(store.get(EMPTY_KEY));
Assert.assertNull(store.get(INVALID_KEY));
Assert.assertNull(store.get(VALUE_1_KEY));
Assert.assertNull(store.get(VALUE_2_KEY));
}
}