public void testDeleteDirectory() throws IOException {
    TestUtils.createContainerAsDirectory(CONTAINER_NAME);
    TestUtils.createBlobsInContainer(
        CONTAINER_NAME,
        new String[] {
          TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev3" + FS, ".txt"),
          TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev4" + FS, ".jpg")
        });

    // delete directory in different ways
    storageStrategy.deleteDirectory(CONTAINER_NAME, "lev1" + FS + "lev2" + FS + "lev4");
    TestUtils.directoryExists(
        TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2" + FS + "lev4", false);
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2", true);

    storageStrategy.deleteDirectory(CONTAINER_NAME, "lev1" + FS + "lev2" + FS + "lev3" + FS);
    TestUtils.directoryExists(
        TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2" + FS + "lev3", false);
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2", true);

    storageStrategy.deleteDirectory(CONTAINER_NAME, FS + "lev1");
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1", false);
    TestUtils.directoryExists(TARGET_CONTAINER_NAME, true);

    // delete the directory and all the files inside
    TestUtils.createBlobsInContainer(
        CONTAINER_NAME,
        new String[] {
          TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev3" + FS, ".txt"),
          TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev4" + FS, ".jpg")
        });
    storageStrategy.deleteDirectory(CONTAINER_NAME, null);
    TestUtils.directoryExists(TARGET_CONTAINER_NAME, false);
  }
  public void testBlobMetadata_withDefaultMetadata() throws IOException {
    String BLOB_KEY = TestUtils.createRandomBlobKey(null, null);
    // create the blob
    TestUtils.createBlobsInContainer(CONTAINER_NAME, BLOB_KEY);

    BlobMetadata metadata = blobStore.blobMetadata(CONTAINER_NAME, BLOB_KEY);
    assertNotNull(metadata, "Metadata null");

    assertEquals(metadata.getName(), BLOB_KEY, "Wrong blob name");
    assertEquals(metadata.getType(), StorageType.BLOB, "Wrong blob type");
    assertEquals(
        metadata.getContentMetadata().getContentType(),
        "application/unknown",
        "Wrong blob content-type");
    assertEquals(
        base16().lowerCase().encode(metadata.getContentMetadata().getContentMD5()),
        metadata.getETag(),
        "Wrong blob MD5");
    assertEquals(metadata.getLocation(), null, "Wrong blob location");
    assertEquals(metadata.getProviderId(), null, "Wrong blob provider id");
    assertEquals(metadata.getUri(), null, "Wrong blob URI");
    assertNotNull(metadata.getUserMetadata(), "No blob UserMetadata");
    assertEquals(metadata.getUserMetadata().size(), 0, "Wrong blob UserMetadata");
    // metadata.getLastModified()
    File file = new File(TARGET_CONTAINER_NAME, BLOB_KEY);
    assertEquals(
        metadata.getContentMetadata().getContentLength(),
        Long.valueOf(file.length()),
        "Wrong blob size");
  }
  /** Test of getBlob method, of class FilesystemAsyncBlobStore. */
  public void testGetBlob() throws IOException {
    String blobKey = TestUtils.createRandomBlobKey();
    GetOptions options = null;
    Blob resultBlob;

    blobStore.createContainerInLocation(null, CONTAINER_NAME);

    resultBlob = blobStore.getBlob(CONTAINER_NAME, blobKey, options);
    assertNull(resultBlob, "Blob exists");

    // create blob
    TestUtils.createBlobsInContainer(CONTAINER_NAME, blobKey);

    resultBlob = blobStore.getBlob(CONTAINER_NAME, blobKey, options);

    assertNotNull(resultBlob, "Blob exists");
    // checks file content
    InputSupplier<FileInputStream> expectedFile =
        Files.newInputStreamSupplier(new File(TARGET_CONTAINER_NAME, blobKey));
    assertTrue(
        ByteStreams.equal(expectedFile, resultBlob.getPayload()),
        "Blob payload differs from file content");
    // metadata are verified in the test for blobMetadata, so no need to
    // perform a complete test here
    assertNotNull(resultBlob.getMetadata(), "Metadata null");
    MutableBlobMetadata metadata = resultBlob.getMetadata();
    assertEquals(blobKey, metadata.getName(), "Wrong blob metadata");
  }
  /** Test of removeBlob method, with only one blob with a complex path as key */
  @Test
  public void testRemoveBlob_ComplexBlobKey() throws IOException {
    final String BLOB_KEY = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null);
    boolean result;

    // checks that blob doesn't exists
    blobStore.createContainerInLocation(null, CONTAINER_NAME);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY);
    assertFalse(result, "Blob exists");
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false);

    // create the blob
    TestUtils.createBlobsInContainer(CONTAINER_NAME, BLOB_KEY);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY);
    assertTrue(result, "Blob doesn't exist");

    // remove it
    blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY);
    assertFalse(result, "Blob still exists");
    // file removed
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false);
    // also the entire directory structure was removed
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa", false);
  }
  public void testRemoveBlob_TwoSimpleBlobKeys() throws IOException {
    final String BLOB_KEY1 = TestUtils.createRandomBlobKey(null, null);
    final String BLOB_KEY2 = TestUtils.createRandomBlobKey(null, null);
    boolean result;

    // create the container and checks that blob doesn't exists
    blobStore.createContainerInLocation(null, CONTAINER_NAME);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1);
    assertFalse(result, "Blob1 exists");
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertFalse(result, "Blob2 exists");

    // create the blob
    TestUtils.createBlobsInContainer(CONTAINER_NAME, BLOB_KEY1, BLOB_KEY2);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1);
    assertTrue(result, "Blob " + BLOB_KEY1 + " doesn't exist");
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertTrue(result, "Blob " + BLOB_KEY2 + " doesn't exist");

    // remove first blob
    blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY1);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1);
    assertFalse(result, "Blob1 still exists");
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertTrue(result, "Blob2 doesn't exist");
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY1, false);
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, true);
    // remove second blob
    blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY2);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertFalse(result, "Blob2 still exists");
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, false);
  }
  public void testGetBlobKeysInsideContainer() throws IOException {
    Iterable<String> resultList;

    // no container
    resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);
    assertNotNull(resultList, "Result is null");
    assertFalse(resultList.iterator().hasNext(), "Blobs detected");

    // create blobs
    storageStrategy.createContainer(CONTAINER_NAME);
    Set<String> createBlobKeys =
        TestUtils.createBlobsInContainer(
            CONTAINER_NAME,
            new String[] {
              TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"),
              TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"),
              TestUtils.createRandomBlobKey("563" + FS + "g3sx2" + FS + "removeBlob-", ".jpg"),
              TestUtils.createRandomBlobKey("563" + FS + "g3sx2" + FS + "removeBlob-", ".jpg")
            });
    storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);

    List<String> retrievedBlobKeys = new ArrayList<String>();
    resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);
    Iterator<String> containersIterator = resultList.iterator();
    while (containersIterator.hasNext()) {
      retrievedBlobKeys.add(containersIterator.next());
    }
    assertEquals(retrievedBlobKeys.size(), createBlobKeys.size(), "Different blobs number");
    for (String createdBlobKey : createBlobKeys) {
      assertTrue(
          retrievedBlobKeys.contains(createdBlobKey), "Blob " + createdBlobKey + " not found");
    }
  }
  public void testRemoveBlob() throws IOException {
    storageStrategy.createContainer(CONTAINER_NAME);
    Set<String> blobKeys =
        TestUtils.createBlobsInContainer(
            CONTAINER_NAME,
            new String[] {
              TestUtils.createRandomBlobKey("removeBlob-", ".jpg"),
              TestUtils.createRandomBlobKey("removeBlob-", ".jpg"),
              TestUtils.createRandomBlobKey("346" + FS + "g3sx2" + FS + "removeBlob-", ".jpg"),
              TestUtils.createRandomBlobKey("346" + FS + "g3sx2" + FS + "removeBlob-", ".jpg")
            });

    Set<String> remainingBlobKeys = new HashSet<String>();
    for (String key : blobKeys) {
      remainingBlobKeys.add(key);
    }
    for (String blobKeyToRemove : blobKeys) {
      storageStrategy.removeBlob(CONTAINER_NAME, blobKeyToRemove);
      // checks if the blob was removed
      TestUtils.fileExists(blobKeyToRemove, false);
      remainingBlobKeys.remove(blobKeyToRemove);
      // checks if all other blobs still exists
      for (String remainingBlobKey : remainingBlobKeys) {
        TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + remainingBlobKey, true);
      }
    }
  }
  public void testDeleteContainer() throws IOException {
    final String BLOB_KEY1 = "blobName.jpg";
    final String BLOB_KEY2 =
        "aa"
            + FS
            + "bb"
            + FS
            + "cc"
            + FS
            + "dd"
            + FS
            + "ee"
            + FS
            + "ff"
            + FS
            + "23"
            + FS
            + "blobName.jpg";
    boolean result;

    result = storageStrategy.createContainer(CONTAINER_NAME);

    // put data inside the container
    TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] {BLOB_KEY1, BLOB_KEY2});

    storageStrategy.deleteContainer(CONTAINER_NAME);
    assertTrue(result, "Cannot delete container");
    TestUtils.directoryExists(CONTAINER_NAME, false);
  }
  public void testClearContainerAndThenDeleteContainer() throws IOException {
    storageStrategy.createContainer(CONTAINER_NAME);
    Set<String> blobs =
        TestUtils.createBlobsInContainer(
            CONTAINER_NAME,
            new String[] {
              TestUtils.createRandomBlobKey("clean_container-", ".jpg"),
              TestUtils.createRandomBlobKey(
                  "bf" + FS + "sd" + FS + "as" + FS + "clean_container-", ".jpg")
            });
    // test if file exits
    for (String blob : blobs) {
      TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, true);
    }

    // clear the container
    storageStrategy.clearContainer(CONTAINER_NAME);
    // test if container still exits
    TestUtils.directoryExists(TARGET_CONTAINER_NAME, true);
    // test if file was cleared
    for (String blob : blobs) {
      TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, false);
    }

    // delete the container
    storageStrategy.deleteContainer(CONTAINER_NAME);
    // test if container still exits
    TestUtils.directoryExists(TARGET_CONTAINER_NAME, false);
    assertFalse(storageStrategy.containerExists(CONTAINER_NAME), "Container still exists");
  }
  /**
   * Integration test, because clearContainer is not redefined in {@link FilesystemAsyncBlobStore}
   * class
   */
  public void testClearContainer_NoOptions() throws IOException {
    final String CONTAINER_NAME2 = "containerToClear";

    // create containers
    blobStore.createContainerInLocation(null, CONTAINER_NAME);
    blobStore.createContainerInLocation(null, CONTAINER_NAME2);

    // creates blobs in first container
    Set<String> blobNamesCreatedInContainer1 =
        TestUtils.createBlobsInContainer(
            CONTAINER_NAME,
            "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg",
            TestUtils.createRandomBlobKey(),
            "rrr" + File.separator + "sss" + File.separator + "788.jpg",
            "xdc" + File.separator + "wert.kpg");

    // creates blobs in second container
    blobStore.createContainerInLocation(null, CONTAINER_NAME2);
    Set<String> blobNamesCreatedInContainer2 =
        TestUtils.createBlobsInContainer(
            CONTAINER_NAME2,
            "asd"
                + File.separator
                + "bbb"
                + File.separator
                + "ccc"
                + File.separator
                + "ddd"
                + File.separator
                + "1234.jpg",
            TestUtils.createRandomBlobKey(),
            "rrr" + File.separator + "sss" + File.separator + "788.jpg",
            "xdc" + File.separator + "wert.kpg");

    // test blobs in containers
    checkForContainerContent(CONTAINER_NAME, blobNamesCreatedInContainer1);
    checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2);

    // delete blobs in first container
    blobStore.clearContainer(CONTAINER_NAME);
    checkForContainerContent(CONTAINER_NAME, null);
    checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2);
    // delete blobs in second container
    blobStore.clearContainer(CONTAINER_NAME2);
    checkForContainerContent(CONTAINER_NAME2, null);
  }
  public void testDeleteContainer() throws IOException {
    boolean result;
    String CONTAINER_NAME2 = "container-to-delete";
    String TARGET_CONTAINER_NAME2 = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2;
    blobStore.createContainerInLocation(null, CONTAINER_NAME);
    blobStore.createContainerInLocation(null, CONTAINER_NAME2);

    result = blobStore.containerExists(CONTAINER_NAME);
    assertTrue(result, "Container [" + CONTAINER_NAME + "] doesn't exists");
    TestUtils.directoryExists(TARGET_CONTAINER_NAME, true);
    result = blobStore.containerExists(CONTAINER_NAME2);
    assertTrue(result, "Container [" + CONTAINER_NAME2 + "] doesn't exists");
    TestUtils.directoryExists(TARGET_CONTAINER_NAME2, true);

    // create blobs inside container
    TestUtils.createBlobsInContainer(
        CONTAINER_NAME,
        TestUtils.createRandomBlobKey("testutils-", null),
        TestUtils.createRandomBlobKey("testutils-", null),
        TestUtils.createRandomBlobKey("ab123s" + File.separator + "testutils-", null));
    TestUtils.createBlobsInContainer(
        CONTAINER_NAME,
        TestUtils.createRandomBlobKey("testutils-", null),
        TestUtils.createRandomBlobKey("testutils-", null),
        TestUtils.createRandomBlobKey("asda123s" + File.separator + "testutils-", null),
        TestUtils.createRandomBlobKey("123-_3s" + File.separator + "testutils-", null));

    // delete first container
    blobStore.deleteContainer(CONTAINER_NAME);
    result = blobStore.containerExists(CONTAINER_NAME);
    assertFalse(result, "Container [" + CONTAINER_NAME + "] still exists");
    TestUtils.directoryExists(TARGET_CONTAINER_NAME, false);
    result = blobStore.containerExists(CONTAINER_NAME2);
    assertTrue(result, "Container [" + CONTAINER_NAME2 + "] still exists");
    TestUtils.directoryExists(TARGET_CONTAINER_NAME2, true);
    // delete second container
    blobStore.deleteContainer(CONTAINER_NAME2);
    result = blobStore.containerExists(CONTAINER_NAME2);
    assertFalse(result, "Container [" + CONTAINER_NAME2 + "] still exists");
    TestUtils.directoryExists(TARGET_CONTAINER_NAME2, false);
  }
  /** Test of list method, of class FilesystemAsyncBlobStore. */
  public void testList_NoOptionSingleContainer() throws IOException {
    blobStore.createContainerInLocation(null, CONTAINER_NAME);
    // Testing list for an empty container
    checkForContainerContent(CONTAINER_NAME, null);

    // creates blobs in first container
    Set<String> blobsExpected =
        TestUtils.createBlobsInContainer(
            CONTAINER_NAME,
            "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg",
            "4rrr.jpg",
            "rrr" + File.separator + "sss" + File.separator + "788.jpg",
            "xdc" + File.separator + "wert.kpg");

    checkForContainerContent(CONTAINER_NAME, blobsExpected);
  }
  public void testBlobExists() throws IOException {
    String[] sourceBlobKeys =
        new String[] {
          TestUtils.createRandomBlobKey("blobExists-", ".jpg"),
          TestUtils.createRandomBlobKey("blobExists-", ".jpg"),
          TestUtils.createRandomBlobKey("afasd" + FS + "asdma" + FS + "blobExists-", ".jpg")
        };

    for (String blobKey : sourceBlobKeys) {
      assertFalse(
          storageStrategy.blobExists(CONTAINER_NAME, blobKey), "Blob " + blobKey + " exists");
    }
    TestUtils.createBlobsInContainer(CONTAINER_NAME, sourceBlobKeys);
    for (String blobKey : sourceBlobKeys) {
      assertTrue(
          storageStrategy.blobExists(CONTAINER_NAME, blobKey),
          "Blob " + blobKey + " doesn't exist");
    }
  }
  public void testRemoveBlob_SimpleBlobKey() throws IOException {
    final String BLOB_KEY = TestUtils.createRandomBlobKey(null, ".txt");
    boolean result;

    blobStore.createContainerInLocation(null, CONTAINER_NAME);

    // checks that blob doesn't exists
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY);
    assertFalse(result, "Blob exists");

    // create the blob
    TestUtils.createBlobsInContainer(CONTAINER_NAME, BLOB_KEY);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY);
    assertTrue(result, "Blob exists");

    // remove it
    blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY);
    assertFalse(result, "Blob still exists");
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false);
  }
  /**
   * Test of removeBlob method, with two blobs with a complex path as key and when first blob is
   * removed, not all of its key's path is removed, because it is shared with the second blob's key
   */
  @Test
  public void testRemoveBlob_TwoComplexBlobKeys() throws IOException {
    final String BLOB_KEY1 = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null);
    final String BLOB_KEY2 = TestUtils.createRandomBlobKey("aa/bb/ee/ff/", null);
    boolean result;

    blobStore.createContainerInLocation(null, CONTAINER_NAME);

    // checks that blob doesn't exist
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1);
    assertFalse(result, "Blob1 exists");
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertFalse(result, "Blob2 exists");

    // create the blobs
    TestUtils.createBlobsInContainer(CONTAINER_NAME, BLOB_KEY1, BLOB_KEY2);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1);
    assertTrue(result, "Blob " + BLOB_KEY1 + " doesn't exist");
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertTrue(result, "Blob " + BLOB_KEY2 + " doesn't exist");

    // remove first blob
    blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY1);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1);
    assertFalse(result, "Blob still exists");
    // first file deleted, not the second
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY1, false);
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, true);
    // only partial directory structure was removed, because it shares a path
    // with the second blob created
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa/bb/cc/dd", false);
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa/bb", true);
    // remove second blob
    blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY2);
    result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2);
    assertFalse(result, "Blob still exists");
    TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, false);
    // now all the directory structure is empty
    TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa", false);
  }