/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.azureblob.blobstore.integration;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import org.jclouds.azureblob.blobstore.strategy.MultipartUploadStrategy;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
import org.jclouds.blobstore.options.PutOptions;
import org.testng.SkipException;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static com.google.common.hash.Hashing.md5;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class AzureBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
private InputSupplier<InputStream> oneHundredOneConstitutions;
private byte[] oneHundredOneConstitutionsMD5;
public AzureBlobIntegrationLiveTest() {
provider = "azureblob";
}
@Override
public void testGetIfMatch() throws InterruptedException {
// this currently fails
}
@Override
public void testGetIfModifiedSince() throws InterruptedException {
// this currently fails!
}
public void testCreateBlobWithExpiry() throws InterruptedException {
throw new SkipException("Expires header unsupported: http://msdn.microsoft.com/en-us/library/windowsazure/dd179404.aspx#Subheading3");
}
@Override
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPutObjectStream() throws InterruptedException, IOException, ExecutionException {
super.testPutObjectStream();
}
// according to docs, content disposition is not persisted
// http://msdn.microsoft.com/en-us/library/dd179440.aspx
@Override
protected void checkContentDisposition(Blob blob, String contentDisposition) {
assert blob.getPayload().getContentMetadata().getContentDisposition() == null;
assert blob.getMetadata().getContentMetadata().getContentDisposition() == null;
}
/**
* Essentially copied from the AWS multipart chucked stream test
*/
public void testMultipartChunkedFileStream() throws IOException, InterruptedException {
oneHundredOneConstitutions = getTestDataSupplier();
oneHundredOneConstitutionsMD5 = ByteStreams.hash(oneHundredOneConstitutions, md5()).asBytes();
File file = new File("target/const.txt");
Files.copy(oneHundredOneConstitutions, file);
String containerName = getContainerName();
try {
BlobStore blobStore = view.getBlobStore();
blobStore.createContainerInLocation(null, containerName);
Blob blob = blobStore.blobBuilder("const.txt").payload(file).build();
String expected = blobStore.putBlob(containerName, blob, PutOptions.Builder.multipart());
String etag = blobStore.blobMetadata(containerName, "const.txt").getETag();
assertEquals(etag, expected);
} finally {
returnContainer(containerName);
}
}
public void testMultipartChunkedFileStreamPowerOfTwoSize() throws IOException, InterruptedException {
final long limit = MultipartUploadStrategy.MAX_BLOCK_SIZE;
InputSupplier<InputStream> input = new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
return ByteStreams.limit(ZERO_INPUT_STREAM, limit);
}
};
File file = new File("target/const.txt");
Files.copy(input, file);
String containerName = getContainerName();
try {
BlobStore blobStore = view.getBlobStore();
blobStore.createContainerInLocation(null, containerName);
Blob blob = blobStore.blobBuilder("const.txt").payload(file).build();
String expected = blobStore.putBlob(containerName, blob, PutOptions.Builder.multipart());
String etag = blobStore.blobMetadata(containerName, "const.txt").getETag();
assertEquals(etag, expected);
} finally {
returnContainer(containerName);
}
}
/** An infinite-length zero byte InputStream. */
// Guava feature request:
// https://code.google.com/p/guava-libraries/issues/detail?id=1370
private static final InputStream ZERO_INPUT_STREAM = new InputStream() {
@Override
public int read() {
return 0;
}
@Override
public int read(final byte[] b) {
return read(b, 0, b.length);
}
@Override
public int read(final byte[] b, final int off, final int len) {
if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
}
int length = Math.min(len, b.length - off);
Arrays.fill(b, off, length, (byte) 0);
return length;
}
};
}