Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions sdk/storage/azure-storage-blob-stress/scenarios-matrix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,180 @@ matrix:
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadStreamOptions with CRC64 validation
cvdownloadstreamsm:
testScenario: contentvalidationdownloadstream
sync: true
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadStreamOptions with CRC64 validation and async client
cvdownloadstreamasyncsm:
testScenario: contentvalidationdownloadstream
sync: false
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadStreamOptions with CRC64 validation and large payload
cvdownloadstreamlg:
testScenario: contentvalidationdownloadstream
sync: true
sizeBytes: "52428800"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadStreamOptions with CRC64 validation, async client, and large payload
cvdownloadstreamasynclg:
testScenario: contentvalidationdownloadstream
sync: false
sizeBytes: "52428800"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadStreamOptions with AUTO validation
cvdownloadstreamauto:
testScenario: contentvalidationdownloadstream
sync: true
sizeBytes: "10485760"
contentValidationAlgorithm: AUTO
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadContentOptions with CRC64 validation
cvdownloadcontentsm:
testScenario: contentvalidationdownloadcontent
sync: true
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadContentOptions with CRC64 validation and async client
cvdownloadcontentasyncsm:
testScenario: contentvalidationdownloadcontent
sync: false
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadContentOptions with CRC64 validation and large payload
cvdownloadcontentlg:
testScenario: contentvalidationdownloadcontent
sync: true
sizeBytes: "52428800"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadContentOptions with CRC64 validation, async client, and large payload
cvdownloadcontentasynclg:
testScenario: contentvalidationdownloadcontent
sync: false
sizeBytes: "52428800"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadContentOptions with AUTO validation
cvdownloadcontentauto:
testScenario: contentvalidationdownloadcontent
sync: true
sizeBytes: "10485760"
contentValidationAlgorithm: AUTO
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadToFileOptions with CRC64 validation
cvdownloadfilesm:
testScenario: contentvalidationdownloadtofile
sync: true
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadToFileOptions with CRC64 validation and async client
cvdownloadfileasyncsm:
testScenario: contentvalidationdownloadtofile
sync: false
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadToFileOptions with CRC64 validation and multi-block payload
cvdownloadfilemd:
testScenario: contentvalidationdownloadtofile
sync: true
sizeBytes: "16777216"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadToFileOptions with CRC64 validation, async client, and multi-block payload
cvdownloadfileasyncmd:
testScenario: contentvalidationdownloadtofile
sync: false
sizeBytes: "16777216"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobDownloadToFileOptions with AUTO validation
cvdownloadfileauto:
testScenario: contentvalidationdownloadtofile
sync: true
sizeBytes: "10485760"
contentValidationAlgorithm: AUTO
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobInputStreamOptions with CRC64 validation
cvinputstreamsm:
testScenario: contentvalidationopeninputstream
sync: true
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobInputStreamOptions with CRC64 validation and large payload
cvinputstreamlg:
testScenario: contentvalidationopeninputstream
sync: true
sizeBytes: "52428800"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# content validation downloads using BlobSeekableByteChannelReadOptions with CRC64 validation
cvbytechannelreadsm:
testScenario: contentvalidationopenseekablebytechannelread
sync: true
sizeBytes: 1024
downloadFaults: true
durationMin: 25
imageBuildDir: "../../.."

# content validation downloads using BlobSeekableByteChannelReadOptions with CRC64 validation and large payload
cvbytechannelreadlg:
testScenario: contentvalidationopenseekablebytechannelread
sync: true
sizeBytes: "52428800"
downloadFaults: true
durationMin: 60
imageBuildDir: "../../.."

# this test uploads 1KB (1024 bytes) to append blob, no chunking
appendblocksmall:
testScenario: appendblock
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
set -ex;
dotnet dev-certs https --export-path /mnt/outputs/dev-cert.pfx;
dotnet dev-certs https --export-path /mnt/outputs/dev-cert.crt --format PEM --no-password;
/root/.dotnet/tools/http-fault-injector;
12 changes: 11 additions & 1 deletion sdk/storage/azure-storage-blob-stress/scripts/stress-run.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
#!/bin/sh
set -ex;
set -exa;
keytool -import -alias test -file /mnt/outputs/dev-cert.pfx -keystore ${JAVA_HOME}/lib/security/cacerts -noprompt -keypass changeit -storepass changeit;
attempts=0;
while [ ! -s /mnt/outputs/dev-cert.crt ]; do
attempts=$((attempts + 1));
if [ "$attempts" -gt 60 ]; then
echo "Timed out waiting for fault injector certificate" >&2;
exit 1;
fi;
sleep 1;
done;
keytool -delete -alias HttpFaultInject -keystore "${JAVA_HOME}/lib/security/cacerts" -storepass changeit >/dev/null 2>&1 || true;
keytool -importcert -trustcacerts -alias HttpFaultInject -file /mnt/outputs/dev-cert.crt -keystore "${JAVA_HOME}/lib/security/cacerts" -noprompt -storepass changeit;
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public static void main(String[] args) {
BlockBlobOutputStream.class,
BlockBlobUpload.class,
CommitBlockList.class,
ContentValidationDownloadContent.class,
ContentValidationDownloadStream.class,
ContentValidationDownloadToFile.class,
ContentValidationOpenInputStream.class,
ContentValidationOpenSeekableByteChannelRead.class,
DownloadToFile.class,
DownloadStream.class,
DownloadContent.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob.stress;

import com.azure.storage.common.ContentValidationAlgorithm;
import com.azure.storage.stress.StorageStressOptions;
import com.beust.jcommander.Parameter;

/**
* Options for stress scenarios that enable transactional response content validation on downloads
* (CRC64 / structured message). See {@link com.azure.storage.blob.BlobContentValidationDownloadTests}.
*/
public class ContentValidationDecoderStressOptions extends StorageStressOptions {
/**
* Response content validation behavior for download APIs. Use CRC64 or AUTO to exercise content validation.
* NONE disables response validation.
*/
@Parameter(names = { "--contentValidationAlgorithm" },
description = "CRC64 (default), AUTO, or NONE")
private ContentValidationAlgorithm contentValidationAlgorithm = ContentValidationAlgorithm.CRC64;

public ContentValidationAlgorithm getContentValidationAlgorithm() {
return contentValidationAlgorithm;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob.stress;

import com.azure.core.http.HttpHeaderName;
import com.azure.core.util.BinaryData;
import com.azure.core.util.Context;
import com.azure.storage.blob.BlobAsyncClient;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.options.BlobDownloadContentOptions;
import com.azure.storage.blob.options.BlobDownloadStreamOptions;
import com.azure.storage.blob.stress.utils.OriginalContent;
import reactor.core.publisher.Mono;

/**
* Download content with
* {@link BlobDownloadContentOptions#setContentValidationAlgorithm} enabled.
* Verifies the correctness of the download response content via CRC.
*/
public class ContentValidationDownloadContent extends BlobScenarioBase<ContentValidationDecoderStressOptions> {
private final OriginalContent originalContent = new OriginalContent();
private final BlobClient syncClient;
private final BlobAsyncClient asyncClient;
private final BlobAsyncClient asyncNoFaultClient;

public ContentValidationDownloadContent(ContentValidationDecoderStressOptions options) {
super(options);
String blobName = generateBlobName();
this.asyncNoFaultClient = getAsyncContainerClientNoFault().getBlobAsyncClient(blobName);
this.syncClient = getSyncContainerClient().getBlobClient(blobName);
this.asyncClient = getAsyncContainerClient().getBlobAsyncClient(blobName);
}

@Override
protected void runInternal(Context span) {
originalContent.checkMatch(
syncClient.downloadContentWithResponse(
new BlobDownloadContentOptions()
.setContentValidationAlgorithm(options.getContentValidationAlgorithm()),
null, span).getValue(),
span).block();
}

@Override
protected Mono<Void> runInternalAsync(Context span) {
// TODO return downloadContent once it stops buffering.
return asyncClient.downloadStreamWithResponse(
new BlobDownloadStreamOptions()
.setContentValidationAlgorithm(options.getContentValidationAlgorithm()))
.flatMap(response -> {
long contentLength = Long.valueOf(response.getHeaders().getValue(HttpHeaderName.CONTENT_LENGTH));
return BinaryData.fromFlux(response.getValue(), contentLength, false);
})
.flatMap(bd -> originalContent.checkMatch(bd, span));
}

@Override
public Mono<Void> setupAsync() {
return super.setupAsync()
.then(originalContent.setupBlob(asyncNoFaultClient, options.getSize()));
}

@Override
public Mono<Void> cleanupAsync() {
return asyncNoFaultClient.deleteIfExists()
.then(super.cleanupAsync());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob.stress;

import com.azure.core.util.Context;
import com.azure.storage.blob.BlobAsyncClient;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.options.BlobDownloadStreamOptions;
import com.azure.storage.blob.stress.utils.OriginalContent;
import com.azure.storage.stress.CrcOutputStream;
import reactor.core.publisher.Mono;

import java.io.IOException;

/**
* Streaming blob download with
* {@link BlobDownloadStreamOptions#setContentValidationAlgorithm} enabled.
* Verifies the correctness of the download response content via CRC.
*/
public class ContentValidationDownloadStream extends BlobScenarioBase<ContentValidationDecoderStressOptions> {
private final OriginalContent originalContent = new OriginalContent();
private final BlobClient syncClient;
private final BlobAsyncClient asyncClient;
private final BlobAsyncClient asyncNoFaultClient;

public ContentValidationDownloadStream(ContentValidationDecoderStressOptions options) {
super(options);
String blobName = generateBlobName();
this.asyncNoFaultClient = getAsyncContainerClientNoFault().getBlobAsyncClient(blobName);
this.syncClient = getSyncContainerClient().getBlobClient(blobName);
this.asyncClient = getAsyncContainerClient().getBlobAsyncClient(blobName);
}

@Override
protected void runInternal(Context span) throws IOException {
try (CrcOutputStream outputStream = new CrcOutputStream()) {
syncClient.downloadStreamWithResponse(outputStream,
new BlobDownloadStreamOptions()
.setContentValidationAlgorithm(options.getContentValidationAlgorithm()),
null, span);
outputStream.close();
originalContent.checkMatch(outputStream.getContentInfo(), span).block();
}
}

@Override
protected Mono<Void> runInternalAsync(Context span) {
return asyncClient.downloadStreamWithResponse(
new BlobDownloadStreamOptions()
.setContentValidationAlgorithm(options.getContentValidationAlgorithm()))
.flatMap(response -> originalContent.checkMatch(response.getValue(), span));
}

@Override
public Mono<Void> setupAsync() {
return super.setupAsync()
.then(originalContent.setupBlob(asyncNoFaultClient, options.getSize()));
}

@Override
public Mono<Void> cleanupAsync() {
return asyncNoFaultClient.deleteIfExists()
.then(super.cleanupAsync());
}
}
Loading
Loading