/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package fedora.server.storage.lowlevel.akubra; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; import org.akubraproject.mem.MemBlobStore; import fedora.common.FaultException; import fedora.server.errors.LowlevelStorageException; import fedora.server.errors.ObjectAlreadyInLowlevelStorageException; import fedora.server.errors.ObjectNotInLowlevelStorageException; import static org.junit.Assert.assertEquals; /** * Unit tests for {@link AkubraLowlevelStorage} * * @author Chris Wilper */ public class AkubraLowlevelStorageTest { private static final String OBJ_KEY = "test:obj"; private static final String OBJ_CONTENT = "obj-content"; private static final String OBJ_CONTENT2 = "obj-content2"; private static final String DS_KEY = OBJ_KEY + "+DS+DS.0"; private static final String DS_CONTENT = "ds-content"; private static final String DS_CONTENT2 = "ds-content2"; private AkubraLowlevelStorage instance; private AkubraLowlevelStorage safeInstance; @Before public void setUp() { this.instance = getInstance(false, false); this.safeInstance = getInstance(true, true); } /** Adding an existing datastream should fail. */ @Test (expected=ObjectAlreadyInLowlevelStorageException.class) public void testAddExistingDatastream() throws LowlevelStorageException { instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); } /** Adding an existing object should fail. */ @Test (expected=ObjectAlreadyInLowlevelStorageException.class) public void testAddExistingObject() throws LowlevelStorageException { instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); } /** Adding a new datastream should succeed. */ @Test public void testAddNonExistingDatastream() throws Exception { instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); } /** Adding a new object should succeed. */ @Test public void testAddNonExistingObject() throws Exception { instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); } /** Datastream audit should not throw an exception. */ @Test public void testAuditDatastream() throws Exception { instance.auditDatastream(); } /** Object audit should not throw an exception. */ @Test public void testAuditObject() throws Exception { instance.auditObject(); } /** Datastream rebuild should not throw an exception. */ @Test public void testRebuildDatastream() throws Exception { instance.rebuildDatastream(); } /** Object rebuild should not throw an exception. */ @Test public void testRebuildObject() throws Exception { instance.rebuildObject(); } /** Removing an existing datastream should succeed. */ @Test public void testRemoveExistingDatastream() throws Exception { instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); instance.removeDatastream(DS_KEY); } /** Removing an existing object should succeed. */ @Test public void testRemoveExistingObject() throws Exception { instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); instance.removeObject(OBJ_KEY); } /** Removing a non-existing datastream should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testRemoveNonExistingDatastream() throws Exception { instance.removeDatastream(DS_KEY); } /** Removing a non-existing object should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testRemoveNonExistingObject() throws Exception { instance.removeObject(OBJ_KEY); } /** Replacing an existing datastream should succeed. */ @Test public void testReplaceExistingDatastream() throws Exception { instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); instance.replaceDatastream(DS_KEY, toStream(DS_CONTENT2)); List<String> list = toList(instance.listDatastreams()); assertEquals(1, list.size()); assertEquals(DS_CONTENT2, toString(instance.retrieveDatastream(DS_KEY))); } /** Replacing an existing datastream "safely" should succeed. */ @Test public void testReplaceExistingDatastreamSafely() throws Exception { safeInstance.addDatastream(DS_KEY, toStream(DS_CONTENT)); safeInstance.replaceDatastream(DS_KEY, toStream(DS_CONTENT2)); List<String> list = toList(safeInstance.listDatastreams()); assertEquals(1, list.size()); assertEquals(DS_CONTENT2, toString(safeInstance.retrieveDatastream(DS_KEY))); } /** Replacing an existing object should succeed. */ @Test public void testReplaceExistingObject() throws Exception { instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); instance.replaceObject(OBJ_KEY, toStream(OBJ_CONTENT2)); List<String> list = toList(instance.listObjects()); assertEquals(1, list.size()); assertEquals(OBJ_CONTENT2, toString(instance.retrieveObject(OBJ_KEY))); } /** Replacing an existing object "safely" should succeed. */ @Test public void testReplaceExistingObjectSafely() throws Exception { safeInstance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); safeInstance.replaceObject(OBJ_KEY, toStream(OBJ_CONTENT2)); List<String> list = toList(safeInstance.listObjects()); assertEquals(1, list.size()); assertEquals(OBJ_CONTENT2, toString(safeInstance.retrieveObject(OBJ_KEY))); } /** Replacing a non-existing datastream should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testReplaceNonExistingDatastream() throws Exception { instance.replaceDatastream(DS_KEY, toStream(DS_CONTENT)); } /** Replacing a non-existing datastream "safely" should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testReplaceNonExistingDatastreamSafely() throws Exception { safeInstance.replaceDatastream(DS_KEY, toStream(DS_CONTENT)); } /** Replacing a non-existing object should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testReplaceNonExistingObject() throws Exception { instance.replaceObject(OBJ_KEY, toStream(OBJ_CONTENT)); } /** Replacing a non-existing object "safely" should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testReplaceNonExistingObjectSafely() throws Exception { safeInstance.replaceObject(OBJ_KEY, toStream(OBJ_CONTENT)); } /** Retrieving an existing datastream should succeed. */ @Test public void testRetrieveExistingDatastream() throws Exception { instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); assertEquals(DS_CONTENT, toString(instance.retrieveDatastream(DS_KEY))); } /** Retrieving an existing object should succeed. */ @Test public void testRetrieveExistingObject() throws Exception { instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); assertEquals(OBJ_CONTENT, toString(instance.retrieveObject(OBJ_KEY))); } /** Retrieving a non-existing datastream should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testRetrieveNonExistingDatastream() throws Exception { instance.retrieveDatastream(DS_KEY); } /** Retrieving a non-existing object should fail. */ @Test (expected=ObjectNotInLowlevelStorageException.class) public void testRetrieveNonExistingObject() throws Exception { instance.retrieveDatastream(OBJ_KEY); } /** * List of datastreams should start at 0, and change to reflect * reflect what's added and removed. */ @Test public void testListDatastreams() throws Exception { List<String> list; list = toList(instance.listDatastreams()); assertEquals(0, list.size()); instance.addDatastream(DS_KEY, toStream(DS_CONTENT)); list = toList(instance.listDatastreams()); assertEquals(1, list.size()); assertEquals(DS_KEY, list.get(0)); instance.removeDatastream(DS_KEY); list = toList(instance.listDatastreams()); assertEquals(0, list.size()); } /** * List of objects should start at 0, and change to reflect * reflect what's added and removed. */ @Test public void testListObjects() throws Exception { List<String> list; list = toList(instance.listObjects()); assertEquals(0, list.size()); instance.addObject(OBJ_KEY, toStream(OBJ_CONTENT)); list = toList(instance.listObjects()); assertEquals(1, list.size()); assertEquals(OBJ_KEY, list.get(0)); instance.removeObject(OBJ_KEY); list = toList(instance.listObjects()); assertEquals(0, list.size()); } private static AkubraLowlevelStorage getInstance( boolean forceSafeObjectOverwrites, boolean forceSafeDatastreamOverwrites) { return new AkubraLowlevelStorage(new MemBlobStore(), new MemBlobStore(), forceSafeObjectOverwrites, forceSafeDatastreamOverwrites); } private static List<String> toList(Iterator<String> iter) { List<String> list = new ArrayList<String>(); while (iter.hasNext()) { list.add(iter.next()); } return list; } private static InputStream toStream(String string) { try { return new ByteArrayInputStream(string.getBytes("UTF-8")); } catch (IOException wontHappen) { throw new FaultException(wontHappen); } } private static String toString(InputStream stream) { try { return new BufferedReader(new InputStreamReader(stream)).readLine(); } catch (IOException wontHappen) { throw new FaultException(wontHappen); } finally { IOUtils.closeQuietly(stream); } } // Supports legacy test runners public static junit.framework.Test suite() { return new junit.framework.JUnit4TestAdapter(AkubraLowlevelStorageTest.class); } }