content: package dk.alexandra.fresco.framework.sce.resources.storage;
  
  import static org.junit.Assert.assertTrue;
  import static org.junit.Assert.fail;
  
  import dk.alexandra.fresco.framework.sce.resources.storage.exceptions.NoMoreElementsException;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.Serializable;
  import java.nio.file.Files;
  import java.nio.file.Paths;
  import java.util.HashMap;
  import org.hamcrest.core.Is;
  import org.junit.AfterClass;
  import org.junit.Assert;
  import org.junit.Test;
  
  public class TestFilebasedStreamStorage {
  
    StreamedStorage storage = new FilebasedStreamedStorageImpl(new InMemoryStorage());
  
    /**
     * Removes any remaining files generated by the tests in this class.
     */
    @AfterClass
    public static void removeDanglingFile() {
      try {
        Files.delete(Paths.get("test-obj"));
        Files.delete(Paths.get("foo"));
        Files.delete(Paths.get("bar"));
      } catch (IOException e) {
        // Nevermind - file is likely not present then.
      }
    }
  
  
  
    @Test
    public void testPutAndGetObject() {
      String myObj = "This is a test";
      storage.putObject("test-obj", "test-key", myObj);
      String s = storage.getObject("test-obj", "test-key");
      storage.shutdown();
      Assert.assertThat(s, Is.is(myObj));
    }
  
  
    @Test
    public void testPutAndGetNext() throws NoMoreElementsException {
      String myObj = "This is a test";
      boolean success = storage.putNext("test-obj", myObj);
      Assert.assertTrue(success);
      String s = storage.getNext("test-obj");
      storage.shutdown();
      Assert.assertThat(s, Is.is(myObj));
    }
  
    @Test(expected = NoMoreElementsException.class)
    public void testEmptyFile() throws NoMoreElementsException {
      try {
        (new FileOutputStream("foo")).close();
      } catch (IOException e) {
        e.printStackTrace();
      }
      storage.getNext("foo");
      fail("Should not be reachable");
    }
  
    @Test(expected = RuntimeException.class)
    public void testWriteAfterClose() throws NoMoreElementsException {
      String myObj1 = "Test1";
      String myObj2 = "Test2";
      boolean success1 = storage.putNext("bar", myObj1);
      Assert.assertTrue(success1);
      storage.shutdown();
      storage.putNext("bar", myObj2);
      fail("Should not be reachable.");
    }
  
  
    private static byte[] hexStringToByteArray(String s) {
      int len = s.length();
      byte[] data = new byte[len / 2];
      for (int i = 0; i < len; i += 2) {
        data[i / 2] =
            (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
      }
      return data;
    }
  
    @Test(expected = RuntimeException.class)
    public void testClassNotFound() throws NoMoreElementsException {
      try {
        // A representation of a class we no longer know
        String stringRep = "aced000573720038646b2e616c6578616e6472"
            + "612e66726573636f2e6672616d65776f726b" + "2e7363652e7265736f7572"
            + "6365732e73746f726167652e4861636b" + "1e61559c1df507160200007870";
        FileOutputStream fos = new FileOutputStream("foo");
        fos.write(hexStringToByteArray(stringRep));
        fos.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
      storage.getNext("foo");
      fail("Should not be reachable");
    }
  
    @Test(expected = NoMoreElementsException.class)
    public void testGetNonExisting2() throws NoMoreElementsException {
      storage.getNext("test-obj-2");
      Assert.fail();
    }
  
    @Test(expected = NoMoreElementsException.class)
    public void testGetNonExisting() throws NoMoreElementsException {
      storage.getNext("test-obj-2");
      Assert.fail();
    }
  
    @Test(expected = RuntimeException.class)
    public void testPutBadName() throws NoMoreElementsException {
      storage.putNext("\0", "data");
      Assert.fail();
    }
  
    @Test
    public void testNoIoExceptionOnClose() {
      HashMap<String, ObjectInputStream> inputs = new HashMap<>();
      HashMap<String, ObjectOutputStream> outputs = new HashMap<>();
      try {
        FileOutputStream fos = new FileOutputStream("foo");
        ObjectOutputStream oos = new ObjectOutputStream(fos) {
          @Override
          public void close() throws IOException {
            throw new IOException("Mock Exception");
          }
        };
        outputs.put("bad-store", oos);
        FileInputStream fis = new FileInputStream("foo");
        ObjectInputStream ois = new ObjectInputStream(fis) {
  
          @Override
          public void close() throws IOException {
            throw new IOException("Mock Exception");
          }
        };
        inputs.put("bad-store", ois);
      } catch (IOException e) {
        fail("Should not be reachable.");
      }
      FilebasedStreamedStorageImpl badStore =
          new FilebasedStreamedStorageImpl(new InMemoryStorage(), inputs, outputs);
      badStore.shutdown();
      assertTrue("Should be reachable. Shutdown should handle the exceptions for us.", true);
    }
  
    @Test(expected = NoMoreElementsException.class)
    public void testMultipleReadWrites() throws NoMoreElementsException {
      String myObj = "This is a test";
      boolean success = storage.putNext("test-obj", myObj);
      Assert.assertTrue(success);
      success = storage.putNext("test-obj", "This-is-second-test");
      Assert.assertTrue(success);
      Serializable s = storage.getNext("test-obj");
      Assert.assertThat(s, Is.is(myObj));
      s = storage.getNext("test-obj");
      Assert.assertThat(s, Is.is("This-is-second-test"));
      storage.getNext("test-obj");
  
      Assert.fail();
    }
  
  
  
  }
  