public void testWeCanReadAndWriteToDrive() throws IOException {
   drive2 =
       client.createDrive(
           new CreateDriveRequest.Builder().name(prefix + "2").size(1 * 1024 * 1024l).build());
   client.writeDrive(drive2.getUuid(), Payloads.newStringPayload("foo"));
   assertEquals(Strings2.toString(client.readDrive(drive2.getUuid(), 0, 3)), "foo");
 }
  public void testMultipleParts() throws IOException {

    StringBuilder builder = new StringBuilder();
    addData(boundary, "hello", builder);
    addData(boundary, "goodbye", builder);

    builder.append("--").append(boundary).append("--").append("\r\n");
    String expects = builder.toString();

    assertEquals(expects.length(), 352);

    MultipartForm multipartForm = new MultipartForm(boundary, newPart("hello"), newPart("goodbye"));

    assertEquals(Strings2.toString(multipartForm), expects);

    // test repeatable
    assert multipartForm.isRepeatable();
    assertEquals(Strings2.toString(multipartForm), expects);
    assertEquals(multipartForm.getContentMetadata().getContentLength(), Long.valueOf(352));
  }
  public void testRanges() throws IOException {
    blobStore.createContainerInLocation(null, CONTAINER_NAME);
    String input = "abcdefgh";
    Payload payload;
    Blob blob = blobStore.blobBuilder("test").payload(new StringPayload(input)).build();
    blobStore.putBlob(CONTAINER_NAME, blob);

    GetOptions getOptionsRangeStartAt = new GetOptions();
    getOptionsRangeStartAt.startAt(1);
    Blob blobRangeStartAt =
        blobStore.getBlob(CONTAINER_NAME, blob.getMetadata().getName(), getOptionsRangeStartAt);
    payload = blobRangeStartAt.getPayload();
    try {
      assertEquals(input.substring(1), Strings2.toString(payload));
    } finally {
      Closeables.closeQuietly(payload);
    }

    GetOptions getOptionsRangeTail = new GetOptions();
    getOptionsRangeTail.tail(3);
    Blob blobRangeTail =
        blobStore.getBlob(CONTAINER_NAME, blob.getMetadata().getName(), getOptionsRangeTail);
    payload = blobRangeTail.getPayload();
    try {
      assertEquals(input.substring(5), Strings2.toString(payload));
    } finally {
      Closeables.closeQuietly(payload);
    }

    GetOptions getOptionsFragment = new GetOptions();
    getOptionsFragment.range(4, 6);
    Blob blobFragment =
        blobStore.getBlob(CONTAINER_NAME, blob.getMetadata().getName(), getOptionsFragment);
    payload = blobFragment.getPayload();
    try {
      assertEquals(input.substring(4, 7), Strings2.toString(payload));
    } finally {
      Closeables.closeQuietly(payload);
    }
  }
  public void testSinglePart() throws IOException {

    StringBuilder builder = new StringBuilder();
    addData(boundary, "hello", builder);
    builder.append("--").append(boundary).append("--").append("\r\n");
    String expects = builder.toString();
    assertEquals(expects.length(), 199);

    MultipartForm multipartForm = new MultipartForm(boundary, newPart("hello"));

    assertEquals(Strings2.toString(multipartForm), expects);
    assertEquals(multipartForm.getContentMetadata().getContentLength(), Long.valueOf(199));
  }
 static String requestPayloadIfStringOrFormIfNotReturnEmptyString(HttpRequest request) {
   if (request.getPayload() != null
       && ("application/x-www-form-urlencoded"
               .equals(request.getPayload().getContentMetadata().getContentType())
           || request.getPayload() instanceof StringPayload)
       && request.getPayload().getContentMetadata().getContentLength() != null
       && request.getPayload().getContentMetadata().getContentLength() < 1024) {
     try {
       return String.format(
           " [%s] ",
           request.getPayload() instanceof StringPayload
               ? request.getPayload().getRawContent()
               : Strings2.toString(request.getPayload()));
     } catch (IOException e) {
     }
   }
   return "";
 }
 @Test(dependsOnMethods = "testWeCanReadAndWriteToDrive")
 public void testWeCopyADriveContentsViaGzip() throws IOException {
   try {
     drive3 =
         client.createDrive(
             new CreateDriveRequest.Builder().name(prefix + "3").size(1 * 1024 * 1024l).build());
     System.err.println("before image; drive 2" + client.getDriveInfo(drive2.getUuid()));
     System.err.println("before image; drive 3" + client.getDriveInfo(drive3.getUuid()));
     client.imageDrive(drive2.getUuid(), drive3.getUuid());
     assert driveNotClaimed.apply(drive3) : client.getDriveInfo(drive3.getUuid());
     assert driveNotClaimed.apply(drive2) : client.getDriveInfo(drive2.getUuid());
     System.err.println("after image; drive 2" + client.getDriveInfo(drive2.getUuid()));
     System.err.println("after image; drive 3" + client.getDriveInfo(drive3.getUuid()));
     assertEquals(Strings2.toString(client.readDrive(drive3.getUuid(), 0, 3)), "foo");
   } finally {
     client.destroyDrive(drive2.getUuid());
     client.destroyDrive(drive3.getUuid());
   }
 }
  @Test(
      timeOut = 5 * 60 * 1000,
      dependsOnMethods = {"testCreateContainer", "testCreatePublicContainer"})
  public void testObjectOperations() throws Exception {
    String data = "Here is my data";

    // Test PUT with string data, ETag hash, and a piece of metadata
    AzureBlob object = getApi().newBlob();
    object.getProperties().setName("object");
    object.setPayload(data);
    Payloads.calculateMD5(object);
    object.getProperties().getContentMetadata().setContentType("text/plain");
    object.getProperties().getMetadata().put("mykey", "metadata-value");
    byte[] md5 = object.getProperties().getContentMetadata().getContentMD5();
    String newEtag = getApi().putBlob(privateContainer, object);
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(object.getProperties().getContentMetadata().getContentMD5()));

    // Test HEAD of missing object
    assert getApi().getBlobProperties(privateContainer, "non-existent-object") == null;

    // Test HEAD of object
    BlobProperties metadata =
        getApi().getBlobProperties(privateContainer, object.getProperties().getName());
    // TODO assertEquals(metadata.getName(),
    // object.getProperties().getName());
    // we can't check this while hacking around lack of content-md5, as GET of
    // the first byte will
    // show incorrect length 1, the returned size, as opposed to the real
    // length. This is an ok
    // tradeoff, as a container list will contain the correct size of the
    // objects in an
    // inexpensive fashion
    // http://code.google.com/p/jclouds/issues/detail?id=92
    // assertEquals(metadata.getSize(), data.length());
    assertEquals(metadata.getContentMetadata().getContentType(), "text/plain");
    // Azure doesn't return the Content-MD5 on head request..
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(object.getProperties().getContentMetadata().getContentMD5()));
    assertEquals(metadata.getETag(), newEtag);
    assertEquals(metadata.getMetadata().entrySet().size(), 1);
    assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");

    // // Test POST to update object's metadata
    // Multimap<String, String> userMetadata = LinkedHashMultimap.create();
    // userMetadata.put("New-Metadata-1", "value-1");
    // userMetadata.put("New-Metadata-2", "value-2");
    // assertTrue(getApi().setBlobProperties(privateContainer,
    // object.getProperties().getName(),
    // userMetadata));

    // Test GET of missing object
    assert getApi().getBlob(privateContainer, "non-existent-object") == null;

    // Test GET of object (including updated metadata)
    AzureBlob getBlob = getApi().getBlob(privateContainer, object.getProperties().getName());
    assertEquals(Strings2.toString(getBlob.getPayload()), data);
    // TODO assertEquals(getBlob.getName(), object.getProperties().getName());
    assertEquals(
        getBlob.getPayload().getContentMetadata().getContentLength(), Long.valueOf(data.length()));
    assertEquals(getBlob.getProperties().getContentMetadata().getContentType(), "text/plain");
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(getBlob.getProperties().getContentMetadata().getContentMD5()));
    assertEquals(newEtag, getBlob.getProperties().getETag());
    // wait until we can update metadata
    // assertEquals(getBlob.getProperties().getMetadata().entries().size(),
    // 2);
    // assertEquals(
    // Iterables.getLast(getBlob.getProperties().getMetadata().get("New-Metadata-1")),
    // "value-1");
    // assertEquals(
    // Iterables.getLast(getBlob.getProperties().getMetadata().get("New-Metadata-2")),
    // "value-2");
    assertEquals(metadata.getMetadata().entrySet().size(), 1);
    assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");

    // test listing
    ListBlobsResponse response =
        getApi()
            .listBlobs(
                privateContainer,
                ListBlobsOptions.Builder.prefix(
                        object
                            .getProperties()
                            .getName()
                            .substring(0, object.getProperties().getName().length() - 1))
                    .maxResults(1)
                    .includeMetadata());
    assertEquals(response.size(), 1);
    assertEquals(Iterables.getOnlyElement(response).getName(), object.getProperties().getName());
    assertEquals(
        Iterables.getOnlyElement(response).getMetadata(),
        ImmutableMap.of("mykey", "metadata-value"));

    // Test PUT with invalid ETag (as if object's data was corrupted in
    // transit)
    String correctEtag = newEtag;
    String incorrectEtag = "0" + correctEtag.substring(1);
    object.getProperties().setETag(incorrectEtag);
    try {
      getApi().putBlob(privateContainer, object);
    } catch (Throwable e) {
      assertEquals(e.getCause().getClass(), HttpResponseException.class);
      assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 422);
    }

    ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes(Charsets.UTF_8));
    object = getApi().newBlob();
    object.getProperties().setName("chunked-object");
    object.setPayload(bais);
    object.getPayload().getContentMetadata().setContentLength(Long.valueOf(data.getBytes().length));
    newEtag = getApi().putBlob(privateContainer, object);
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(getBlob.getProperties().getContentMetadata().getContentMD5()));

    // Test GET with options
    // Non-matching ETag
    try {
      getApi()
          .getBlob(
              privateContainer,
              object.getProperties().getName(),
              GetOptions.Builder.ifETagDoesntMatch(newEtag));
    } catch (Exception e) {
      HttpResponseException httpEx =
          Throwables2.getFirstThrowableOfType(e, HttpResponseException.class);
      assert (httpEx != null) : "expected http exception, not " + e;
      assertEquals(httpEx.getResponse().getStatusCode(), 304);
    }

    // Matching ETag TODO this shouldn't fail!!!
    try {
      getBlob =
          getApi()
              .getBlob(
                  privateContainer,
                  object.getProperties().getName(),
                  GetOptions.Builder.ifETagMatches(newEtag));
      assertEquals(getBlob.getProperties().getETag(), newEtag);
    } catch (HttpResponseException e) {
      assertEquals(e.getResponse().getStatusCode(), 412);
    }

    // Range
    // doesn't work per
    // http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/479fa63f-51df-4b66-96b5-33ae362747b6
    // getBlob = getApi()
    // .getBlob(privateContainer, object.getProperties().getName(),
    // GetOptions.Builder.startAt(8)).get(120,
    // TimeUnit.SECONDS);
    // assertEquals(Utils.toStringAndClose((InputStream) getBlob.getData()),
    // data.substring(8));

    getApi().deleteBlob(privateContainer, "object");
    getApi().deleteBlob(privateContainer, "chunked-object");
  }
  @Test
  public void testCopyObjectOperations() throws Exception {
    String sourceContainer = getContainerName();
    String sourceObject = "original.txt";
    String sourcePath = "/" + sourceContainer + "/" + sourceObject;
    String badSource = "badsource";
    String destinationContainer = getContainerName();
    String destinationObject = "copy.txt";
    String destinationPath = "/" + destinationContainer + "/" + destinationObject;
    String badDestination = "baddestination";
    String data = "Hello World";
    SwiftObject sourceSwiftObject = newSwiftObject(data, sourceObject);

    getApi().putObject(sourceContainer, sourceSwiftObject);

    // test that not giving a destination name *doesn't* copy source name to the destination
    // container with
    // the source name but copy still returns success :(
    assertTrue(getApi().copyObject(sourceContainer, sourceObject, destinationContainer, ""));
    assertFalse(getApi().objectExists(destinationContainer, sourceObject));

    // test copy works
    assertTrue(
        getApi()
            .copyObject(sourceContainer, sourceObject, destinationContainer, destinationObject));
    assertTrue(getApi().objectExists(destinationContainer, destinationObject));

    SwiftObject destinationSwiftObject =
        getApi().getObject(destinationContainer, destinationObject);
    assertEquals(Strings2.toString(destinationSwiftObject.getPayload()), data);

    // test exception thrown on bad destination container
    try {
      assertFalse(
          getApi().copyObject(sourceContainer, sourceObject, badDestination, destinationObject));
      fail("Expected CopyObjectException");
    } catch (CopyObjectException e) {
      assertEquals(e.getSourcePath(), sourcePath);
      assertEquals(e.getDestinationPath(), "/" + badDestination + "/" + destinationObject);
    }

    // test exception thrown on bad source container
    try {
      assertFalse(
          getApi().copyObject(badSource, sourceObject, destinationContainer, destinationObject));
      fail("Expected CopyObjectException");
    } catch (CopyObjectException e) {
      assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObject);
      assertEquals(e.getDestinationPath(), destinationPath);
    }

    // test exception thrown on bad source name
    try {
      assertFalse(
          getApi().copyObject(sourceContainer, badSource, destinationContainer, destinationObject));
      fail("Expected CopyObjectException");
    } catch (CopyObjectException e) {
      assertEquals(e.getSourcePath(), "/" + sourceContainer + "/" + badSource);
      assertEquals(e.getDestinationPath(), destinationPath);
    }
  }
  @Test
  public void testObjectOperations() throws Exception {
    String containerName = getContainerName();
    try {
      // Test PUT with string data, ETag hash, and a piece of metadata
      String data = "Here is my data";
      String key = "object";
      SwiftObject object = newSwiftObject(data, key);
      byte[] md5 = object.getPayload().getContentMetadata().getContentMD5();
      String newEtag = getApi().putObject(containerName, object);
      assert newEtag != null;

      assertEquals(
          base16().lowerCase().encode(md5),
          base16().lowerCase().encode(object.getPayload().getContentMetadata().getContentMD5()));

      // Test HEAD of missing object
      assert getApi().getObjectInfo(containerName, "non-existent-object") == null;

      // Test HEAD of object
      MutableObjectInfoWithMetadata metadata =
          getApi().getObjectInfo(containerName, object.getInfo().getName());
      assertEquals(metadata.getName(), object.getInfo().getName());

      assertEquals(metadata.getBytes(), Long.valueOf(data.length()));
      assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();

      assertEquals(
          base16().lowerCase().encode(md5), base16().lowerCase().encode(metadata.getHash()));
      assertEquals(metadata.getHash(), base16().lowerCase().decode(newEtag));
      assertEquals(metadata.getMetadata().entrySet().size(), 1);
      assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");

      // // Test POST to update object's metadata
      Map<String, String> userMetadata = Maps.newHashMap();
      userMetadata.put("New-Metadata-1", "value-1");
      userMetadata.put("New-Metadata-2", "value-2");
      assertTrue(getApi().setObjectInfo(containerName, object.getInfo().getName(), userMetadata));

      // Test GET of missing object
      assert getApi().getObject(containerName, "non-existent-object") == null;
      // Test GET of object (including updated metadata)
      SwiftObject getBlob = getApi().getObject(containerName, object.getInfo().getName());
      assertEquals(Strings2.toString(getBlob.getPayload()), data);
      // TODO assertEquals(getBlob.getName(),
      // object.getMetadata().getName());
      assertEquals(getBlob.getInfo().getBytes(), Long.valueOf(data.length()));
      testGetObjectContentType(getBlob);
      assertEquals(
          base16().lowerCase().encode(md5),
          base16().lowerCase().encode(getBlob.getInfo().getHash()));
      assertEquals(base16().lowerCase().decode(newEtag), getBlob.getInfo().getHash());
      assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
      assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
      assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");

      // Test PUT with invalid ETag (as if object's data was corrupted in
      // transit)
      String correctEtag = newEtag;
      String incorrectEtag = "0" + correctEtag.substring(1);
      object.getInfo().setHash(base16().lowerCase().decode(incorrectEtag));
      try {
        getApi().putObject(containerName, object);
      } catch (HttpResponseException e) {
        assertEquals(e.getResponse().getStatusCode(), 422);
      }

      // Test PUT chunked/streamed upload with data of "unknown" length
      ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes(Charsets.UTF_8));
      SwiftObject blob = getApi().newSwiftObject();
      blob.getInfo().setName("chunked-object");
      blob.setPayload(bais);
      newEtag = getApi().putObject(containerName, blob);
      assertEquals(
          base16().lowerCase().encode(md5),
          base16().lowerCase().encode(getBlob.getInfo().getHash()));

      // Test GET with options
      // Non-matching ETag
      try {
        getApi()
            .getObject(
                containerName,
                object.getInfo().getName(),
                GetOptions.Builder.ifETagDoesntMatch(newEtag));
      } catch (HttpResponseException e) {
        assertEquals(e.getResponse().getStatusCode(), 304);
      }

      // Matching ETag
      getBlob =
          getApi()
              .getObject(
                  containerName,
                  object.getInfo().getName(),
                  GetOptions.Builder.ifETagMatches(newEtag));
      assertEquals(getBlob.getInfo().getHash(), base16().lowerCase().decode(newEtag));
      getBlob =
          getApi()
              .getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8));
      assertEquals(Strings2.toString(getBlob.getPayload()), data.substring(8));

    } finally {
      returnContainer(containerName);
    }
  }