/**
* Copyright Microsoft Corporation
*
* Licensed 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 com.microsoft.azure.storage.blob;
import com.microsoft.azure.storage.OperationContext;
import com.microsoft.azure.storage.StorageCredentials;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.TestHelper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import static org.junit.Assert.*;
/**
* Blob Test Base
*/
public class BlobTestHelper extends TestHelper {
public static String generateRandomContainerName() {
String containerName = "container" + UUID.randomUUID().toString();
return containerName.replace("-", "");
}
public static CloudBlobContainer getRandomContainerReference() throws URISyntaxException, StorageException {
String containerName = generateRandomContainerName();
CloudBlobClient bClient = TestHelper.createCloudBlobClient();
CloudBlobContainer container = bClient.getContainerReference(containerName);
return container;
}
public static String generateRandomBlobNameWithPrefix(String prefix) {
if (prefix == null) {
prefix = "";
}
String blobName = prefix + UUID.randomUUID().toString();
return blobName.replace("-", "");
}
public static CloudBlob getBlobReference(BlobType type, CloudBlobContainer container, String name)
throws URISyntaxException, StorageException {
CloudBlob blob = null;
switch (type) {
case APPEND_BLOB:
blob = container.getAppendBlobReference(name);
break;
case BLOCK_BLOB:
blob = container.getBlockBlobReference(name);
break;
case PAGE_BLOB:
blob = container.getPageBlobReference(name);
break;
case UNSPECIFIED:
fail();
}
return blob;
}
public static CloudBlob getBlobReference(BlobType type, StorageCredentials credentials, URI uri)
throws StorageException, URISyntaxException {
CloudBlob blob = null;
switch (type) {
case APPEND_BLOB:
blob = new CloudAppendBlob(credentials.transformUri(uri));
break;
case BLOCK_BLOB:
blob = new CloudBlockBlob(credentials.transformUri(uri));
break;
case PAGE_BLOB:
blob = new CloudPageBlob(credentials.transformUri(uri));
break;
case UNSPECIFIED:
fail();
}
return blob;
}
public static List<String> uploadNewBlobs(CloudBlobContainer container, BlobType type, int count, int length,
OperationContext context) throws StorageException, IOException, URISyntaxException {
CloudBlob blob = null;
List<String> blobs = new ArrayList<String>();
for (int i = 0; i < count; i++) {
switch (type) {
case BLOCK_BLOB:
blob = uploadNewBlob(container, type, "bb", length, context);
blobs.add(blob.getName());
break;
case PAGE_BLOB:
blob = uploadNewBlob(container, type, "pb", length, context);
blobs.add(blob.getName());
break;
case APPEND_BLOB:
blob = uploadNewBlob(container, type, "ab", length, context);
blobs.add(blob.getName());
break;
default:
break;
}
}
return blobs;
}
public static CloudBlob uploadNewBlob(CloudBlobContainer container, BlobType type, String prefix, int length,
OperationContext context) throws StorageException, IOException, URISyntaxException {
if (prefix == null) {
prefix = generateRandomBlobNameWithPrefix("");
}
String name = generateRandomBlobNameWithPrefix(prefix);
CloudBlob blob = null;
switch (type) {
case BLOCK_BLOB:
blob = container.getBlockBlobReference(name);
blob.upload(getRandomDataStream(length), length, null, null, context);
break;
case PAGE_BLOB:
blob = container.getPageBlobReference(name);
if (length == 0) {
((CloudPageBlob) blob).create(length, null, null, context);
} else {
blob.upload(getRandomDataStream(length), length, null, null, context);
}
break;
case APPEND_BLOB:
blob = container.getAppendBlobReference(name);
if (length == 0) {
((CloudAppendBlob) blob).createOrReplace(null, null, context);
} else {
blob.upload(getRandomDataStream(length), length, null, null, context);
}
break;
default:
fail();
}
return blob;
}
protected static void doDownloadTest(CloudBlob blob, int blobSize, int bufferSize, int bufferOffset)
throws StorageException, IOException {
final Random randGenerator = new Random();
final byte[] buffer = new byte[blobSize];
randGenerator.nextBytes(buffer);
byte[] resultBuffer = new byte[bufferSize];
BlobRequestOptions options = new BlobRequestOptions();
if (blob.getClass() == CloudBlockBlob.class) {
options.setUseTransactionalContentMD5(true);
}
blob.upload(new ByteArrayInputStream(buffer), buffer.length);
blob.downloadToByteArray(resultBuffer, bufferOffset, null, options, null);
for (int i = 0; i < blob.getProperties().getLength(); i++) {
assertEquals(buffer[i], resultBuffer[bufferOffset + i]);
}
if (bufferOffset + blobSize < bufferSize) {
for (int k = bufferOffset + blobSize; k < bufferSize; k++) {
assertEquals(0, resultBuffer[k]);
}
}
}
protected static void doDownloadRangeToByteArrayTest(CloudBlob blob, int blobSize, int bufferSize,
int bufferOffset, Long blobOffset, Long length) throws IOException, StorageException {
final Random randGenerator = new Random();
final byte[] buffer = new byte[blobSize];
randGenerator.nextBytes(buffer);
byte[] resultBuffer = new byte[bufferSize];
int downloadLength;
BlobRequestOptions options = new BlobRequestOptions();
blob.upload(new ByteArrayInputStream(buffer), buffer.length);
downloadLength = blob.downloadRangeToByteArray(blobOffset, length, resultBuffer, bufferOffset, null, options,
null);
int downloadSize = Math.min(blobSize - (int) (blobOffset != null ? blobOffset : 0), bufferSize - bufferOffset);
if (length != null && length < downloadSize) {
downloadSize = length.intValue();
}
assertEquals(downloadSize, downloadLength);
for (int i = 0; i < bufferOffset; i++) {
assertEquals(0, resultBuffer[i]);
}
for (int j = 0; j < downloadLength; j++) {
assertEquals(buffer[(int) ((blobOffset != null ? blobOffset : 0) + j)], resultBuffer[bufferOffset
+ j]);
}
for (int k = bufferOffset + downloadLength; k < bufferSize; k++) {
assertEquals(0, resultBuffer[k]);
}
}
protected static void doDownloadRangeToByteArrayNegativeTests(CloudBlob blob) throws StorageException, IOException {
int blobLength = 1024;
int resultBufSize = 1024;
final Random randGenerator = new Random();
final byte[] buffer = new byte[blobLength];
randGenerator.nextBytes(buffer);
byte[] resultBuffer = new byte[resultBufSize];
blob.upload(new ByteArrayInputStream(buffer), buffer.length);
try {
blob.downloadRangeToByteArray(1024, (long) 1, resultBuffer, 0);
fail();
}
catch (StorageException ex) {
assertEquals(416, ex.getHttpStatusCode());
}
try {
blob.downloadToByteArray(resultBuffer, 1024);
fail();
}
catch (IndexOutOfBoundsException ex) {
}
try {
blob.downloadRangeToByteArray(0, (long) 1023, resultBuffer, 2);
fail();
}
catch (IndexOutOfBoundsException ex) {
}
// negative length
try {
blob.downloadRangeToByteArray(0, (long) -10, resultBuffer, 0);
fail();
}
catch (IndexOutOfBoundsException ex) {
}
// negative blob offset
try {
blob.downloadRangeToByteArray(-10, (long) 20, resultBuffer, 0);
fail();
}
catch (IndexOutOfBoundsException ex) {
}
// negative buffer offset
try {
blob.downloadRangeToByteArray(0, (long) 20, resultBuffer, -10);
fail();
}
catch (IndexOutOfBoundsException ex) {
}
}
public static CloudAppendBlob defiddler(CloudAppendBlob blob) throws URISyntaxException, StorageException {
URI oldUri = blob.getUri();
URI newUri = defiddler(oldUri);
if (newUri != oldUri) {
CloudAppendBlob newBlob = new CloudAppendBlob(newUri, blob.getServiceClient().getCredentials());
newBlob.setSnapshotID(blob.snapshotID);
return newBlob;
}
else {
return blob;
}
}
public static CloudBlockBlob defiddler(CloudBlockBlob blob) throws URISyntaxException, StorageException {
URI oldUri = blob.getUri();
URI newUri = defiddler(oldUri);
if (newUri != oldUri) {
CloudBlockBlob newBlob = new CloudBlockBlob(newUri, blob.getServiceClient().getCredentials());
newBlob.setSnapshotID(blob.snapshotID);
return newBlob;
}
else {
return blob;
}
}
public static CloudPageBlob defiddler(CloudPageBlob blob) throws URISyntaxException, StorageException {
URI oldUri = blob.getUri();
URI newUri = defiddler(oldUri);
if (newUri != oldUri) {
CloudPageBlob newBlob = new CloudPageBlob(newUri, blob.getServiceClient().getCredentials());
newBlob.setSnapshotID(blob.snapshotID);
return newBlob;
}
else {
return blob;
}
}
public static void waitForCopy(CloudBlob blob) throws StorageException, InterruptedException {
boolean copyInProgress = true;
while (copyInProgress) {
blob.downloadAttributes();
copyInProgress = (blob.getCopyState().getStatus() == CopyStatus.PENDING)
|| (blob.getCopyState().getStatus() == CopyStatus.ABORTED);
// One second sleep if retry is needed
if (copyInProgress) {
Thread.sleep(1000);
}
}
}
public static byte[] getRandomBuffer(int size) {
byte[] buffer = new byte[size];
Random random = new Random();
random.nextBytes(buffer);
return buffer;
}
public static Map<String, BlockEntry> getBlockEntryList(int count) {
Map<String, BlockEntry> blocks = new HashMap<String, BlockEntry>();
for (int i = 0; i < count; i++) {
final String name = generateRandomBlobNameWithPrefix(null);
blocks.put(name, new BlockEntry(name, BlockSearchMode.LATEST));
}
return blocks;
}
public static void setBlobProperties(CloudBlob blob) {
blob.getProperties().setCacheControl("no-transform");
blob.getProperties().setContentDisposition("attachment");
blob.getProperties().setContentEncoding("gzip");
blob.getProperties().setContentLanguage("tr,en");
blob.getProperties().setContentMD5("MDAwMDAwMDA=");
blob.getProperties().setContentType("text/html");
}
public static void assertAreEqual(CloudBlob blob1, CloudBlob blob2) throws URISyntaxException, StorageException {
if (blob1 == null) {
assertNull(blob2);
}
else {
assertNotNull(blob2);
assertEquals(blob1.getClass(), blob2.getClass());
assertEquals(blob1.getUri(), blob2.getUri());
assertEquals(blob1.getSnapshotID(), blob2.getSnapshotID());
assertEquals(blob1.isSnapshot(), blob2.isSnapshot());
assertEquals(blob1.getSnapshotQualifiedStorageUri(), blob2.getSnapshotQualifiedStorageUri());
assertAreEqual(blob1.getProperties(), blob2.getProperties());
assertAreEqual(blob1.getCopyState(), blob2.getCopyState());
}
}
public static void assertAreEqual(BlobProperties prop1, BlobProperties prop2) {
if (prop1 == null) {
assertNull(prop2);
}
else {
assertNotNull(prop2);
assertEquals(prop1.getBlobType(), prop2.getBlobType());
assertEquals(prop1.getCacheControl(), prop2.getCacheControl());
assertEquals(prop1.getContentDisposition(), prop2.getContentDisposition());
assertEquals(prop1.getContentEncoding(), prop2.getContentEncoding());
assertEquals(prop1.getContentLanguage(), prop2.getContentLanguage());
assertEquals(prop1.getContentMD5(), prop2.getContentMD5());
assertEquals(prop1.getContentType(), prop2.getContentType());
assertEquals(prop1.getEtag(), prop2.getEtag());
assertEquals(prop1.getLastModified(), prop2.getLastModified());
assertEquals(prop1.getLength(), prop2.getLength());
assertEquals(prop1.getPageBlobSequenceNumber(), prop2.getPageBlobSequenceNumber());
}
}
public static void assertAreEqual(CopyState copy1, CopyState copy2) {
if (copy1 == null) {
assertNull(copy2);
}
else {
assertNotNull(copy2);
assertEquals(copy1.getBytesCopied(), copy2.getBytesCopied());
assertEquals(copy1.getCompletionTime(), copy2.getCompletionTime());
assertEquals(copy1.getCopyId(), copy2.getCopyId());
assertEquals(copy1.getSource(), copy2.getSource());
assertEquals(copy1.getStatus(), copy2.getStatus());
assertEquals(copy1.getTotalBytes(), copy2.getTotalBytes());
}
}
}