Skip to content

Commit abadbdf

Browse files
authored
Adding all download scenarios for BlobClient (#37956)
1 parent 1dd626d commit abadbdf

File tree

9 files changed

+440
-75
lines changed

9 files changed

+440
-75
lines changed
Lines changed: 160 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
matrix:
22
scenarios:
3+
# this test downloads 1024 bytes, small file, no chunking
34
download-small-file-test:
45
testScenario: downloadtofile
56
sync: true
67
sizeBytes: 1024
78
parallel: 100
89
faults: true
9-
durationSeconds: 900
10+
durationSeconds: 1000
1011
imageBuildDir: "../../.."
1112

1213
download-small-file-async-test:
@@ -15,52 +16,173 @@ matrix:
1516
sizeBytes: 1024
1617
parallel: 100
1718
faults: true
18-
durationSeconds: 900
19+
durationSeconds: 1000
1920
imageBuildDir: "../../.."
2021

21-
# download-small-file-no-fi:
22-
# testScenario: downloadtofile
23-
# sync: true
24-
# sizeBytes: 1024
25-
# parallel: 100
26-
# faults: false
27-
# durationSeconds: 900
28-
# imageBuildDir: "../../.."
29-
30-
# # this test downloads 16 * 1024 * 1024 bytes, medium file in several chunks
22+
# this test downloads 16 * 1024 * 1024 bytes, medium file in several chunks
3123
download-med-file-test:
3224
testScenario: downloadtofile
3325
sync: true
34-
sizeBytes: 16777216
26+
sizeBytes: "16777216"
3527
parallel: 100
3628
faults: true
37-
durationSeconds: 900
29+
durationSeconds: 1000
3830
imageBuildDir: "../../.."
3931

40-
# # this test downloads 8 * 1026 * 1024 + 10 bytes, unaligned file in several chunks
32+
# this test downloads 8 * 1026 * 1024 + 10 bytes, unaligned file in several chunks
4133
download-unaligned-file-test:
4234
testScenario: downloadtofile
4335
sync: true
44-
sizeBytes: 8405002
45-
parallel: 100
46-
faults: true
47-
durationSeconds: 900
48-
imageBuildDir: "../../.."
49-
#
50-
# # this test downloads 50 * 1024 * 1024 bytes, large file requiring multiple requests
51-
# download-large-file-test:
52-
# testScenario: downloadtofile
53-
# sync: true
54-
# sizeBytes: 52428800
55-
# parallel: 100
56-
# faults: true
57-
# durationSeconds: 900
58-
# imageBuildDir: "../../.."
59-
#
60-
# # we can add new test cases here - will run in parallel
61-
# download-large-file-test:
62-
# testScenario: downloadtofile
63-
# sync: true
64-
# sizeBytes: 104857600
65-
# parallel: 500
66-
# imageBuildDir: "../../.."
36+
sizeBytes: "8405002"
37+
parallel: 100
38+
faults: true
39+
durationSeconds: 1000
40+
imageBuildDir: "../../.."
41+
42+
# this test downloads 50 * 1024 * 1024 bytes, large file requiring multiple requests
43+
download-large-file-test:
44+
testScenario: downloadtofile
45+
sync: true
46+
sizeBytes: "52428800"
47+
parallel: 100
48+
faults: true
49+
durationSeconds: 1000
50+
imageBuildDir: "../../.."
51+
52+
# this test downloads 1024 bytes, small stream, no chunking
53+
download-small-stream-test:
54+
testScenario: downloadstream
55+
sync: true
56+
sizeBytes: 1024
57+
parallel: 100
58+
faults: true
59+
durationSeconds: 1000
60+
imageBuildDir: "../../.."
61+
62+
download-small-stream-async-test:
63+
testScenario: downloadstream
64+
sync: false
65+
sizeBytes: 1024
66+
parallel: 100
67+
faults: true
68+
durationSeconds: 1000
69+
imageBuildDir: "../../.."
70+
71+
# this test downloads 16 * 1024 * 1024 bytes, medium stream in several chunks
72+
download-med-stream-test:
73+
testScenario: downloadstream
74+
sync: true
75+
sizeBytes: "16777216"
76+
parallel: 100
77+
faults: true
78+
durationSeconds: 1000
79+
imageBuildDir: "../../.."
80+
81+
# this test downloads 50 * 1024 * 1024 bytes, large file requiring multiple requests
82+
download-large-stream-test:
83+
testScenario: downloadstream
84+
sync: true
85+
sizeBytes: "52428800"
86+
parallel: 100
87+
faults: true
88+
durationSeconds: 1000
89+
imageBuildDir: "../../.."
90+
91+
# this test downloads 1024 bytes, small content, no chunking
92+
download-small-content-test:
93+
testScenario: downloadcontent
94+
sync: true
95+
sizeBytes: 1024
96+
parallel: 100
97+
faults: true
98+
durationSeconds: 1000
99+
imageBuildDir: "../../.."
100+
101+
download-small-content-async-test:
102+
testScenario: downloadcontent
103+
sync: false
104+
sizeBytes: 1024
105+
parallel: 100
106+
faults: true
107+
durationSeconds: 1000
108+
imageBuildDir: "../../.."
109+
110+
# this test downloads 16 * 1024 * 1024 bytes, medium content in several chunks
111+
download-med-content-test:
112+
testScenario: downloadcontent
113+
sync: true
114+
sizeBytes: "16777216"
115+
parallel: 100
116+
faults: true
117+
durationSeconds: 1000
118+
imageBuildDir: "../../.."
119+
120+
# this test downloads 50 * 1024 * 1024 bytes, large content requiring multiple requests
121+
download-large-content-test:
122+
testScenario: downloadcontent
123+
sync: true
124+
sizeBytes: "52428800"
125+
parallel: 100
126+
faults: true
127+
durationSeconds: 1000
128+
imageBuildDir: "../../.."
129+
130+
# this test downloads 1024 bytes to open input stream, no chunking
131+
openinputstream-small-test:
132+
testScenario: openinputstream
133+
sync: true
134+
sizeBytes: 1024
135+
parallel: 100
136+
faults: true
137+
durationSeconds: 1000
138+
imageBuildDir: "../../.."
139+
140+
# this test downloads 16 * 1024 * 1024 bytes to open input stream in several chunks
141+
openinputstream-med-test:
142+
testScenario: openinputstream
143+
sync: true
144+
sizeBytes: "16777216"
145+
parallel: 100
146+
faults: true
147+
durationSeconds: 1000
148+
imageBuildDir: "../../.."
149+
150+
# this test downloads 50 * 1024 * 1024 bytes to open input stream requiring multiple requests
151+
openinputstream-large-test:
152+
testScenario: openinputstream
153+
sync: true
154+
sizeBytes: "52428800"
155+
parallel: 100
156+
faults: true
157+
durationSeconds: 1000
158+
imageBuildDir: "../../.."
159+
160+
# this test downloads 1024 bytes to seekablebytechannel, no chunking
161+
seekablebytechannel-small-test:
162+
testScenario: openseekablebytechannelread
163+
sync: true
164+
sizeBytes: 1024
165+
parallel: 100
166+
faults: true
167+
durationSeconds: 1000
168+
imageBuildDir: "../../.."
169+
170+
# this test downloads 16 * 1024 * 1024 bytes to seekablebytechannel in several chunks
171+
seekablebytechannel-med-test:
172+
testScenario: openseekablebytechannelread
173+
sync: true
174+
sizeBytes: "16777216"
175+
parallel: 100
176+
faults: true
177+
durationSeconds: 1000
178+
imageBuildDir: "../../.."
179+
180+
# this test downloads 50 * 1024 * 1024 bytes to seekablebytechannel requiring multiple requests
181+
seekablebytechannel-large-test:
182+
testScenario: openseekablebytechannelread
183+
sync: true
184+
sizeBytes: "52428800"
185+
parallel: 100
186+
faults: true
187+
durationSeconds: 1000
188+
imageBuildDir: "../../.."

sdk/storage/azure-storage-blob-stress/src/main/java/com/azure/storage/blob/stress/App.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ public class App {
99
public static void main(String[] args) {
1010
PerfStressProgram.run(new Class<?>[]{
1111
DownloadToFile.class,
12+
DownloadStream.class,
13+
DownloadContent.class,
14+
OpenInputStream.class,
15+
OpenSeekableByteChannelRead.class
1216
}, args);
1317
}
1418
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.storage.blob.stress;
5+
6+
import com.azure.core.util.Context;
7+
import com.azure.core.util.logging.ClientLogger;
8+
import com.azure.storage.blob.BlobAsyncClient;
9+
import com.azure.storage.blob.BlobClient;
10+
import com.azure.storage.blob.stress.utils.OriginalContent;
11+
import com.azure.storage.blob.stress.utils.TelemetryHelper;
12+
import com.azure.storage.stress.StorageStressOptions;
13+
import reactor.core.publisher.Mono;
14+
15+
public class DownloadContent extends BlobScenarioBase<StorageStressOptions> {
16+
private static final ClientLogger LOGGER = new ClientLogger(DownloadContent.class);
17+
private static final TelemetryHelper TELEMETRY_HELPER = new TelemetryHelper(DownloadContent.class);
18+
private static final OriginalContent ORIGINAL_CONTENT = new OriginalContent();
19+
private final BlobClient syncClient;
20+
private final BlobAsyncClient asyncClient;
21+
private final BlobAsyncClient asyncNoFaultClient;
22+
23+
public DownloadContent(StorageStressOptions options) {
24+
super(options, TELEMETRY_HELPER);
25+
this.asyncNoFaultClient = getAsyncContainerClientNoFault().getBlobAsyncClient(options.getBlobName());
26+
this.syncClient = getSyncContainerClient().getBlobClient(options.getBlobName());
27+
this.asyncClient = getAsyncContainerClient().getBlobAsyncClient(options.getBlobName());
28+
}
29+
30+
@Override
31+
protected boolean runInternal(Context span) {
32+
try {
33+
return ORIGINAL_CONTENT.checkMatch(syncClient.downloadContent(), span).block().booleanValue();
34+
} catch (Exception e) {
35+
LOGGER.error("Failed to download blob", e);
36+
return false;
37+
}
38+
}
39+
40+
@Override
41+
protected Mono<Boolean> runInternalAsync(Context span) {
42+
return asyncClient.downloadContent().flatMap(response -> ORIGINAL_CONTENT.checkMatch(response, span));
43+
}
44+
45+
@Override
46+
public Mono<Void> globalSetupAsync() {
47+
return super.globalSetupAsync()
48+
.then(ORIGINAL_CONTENT.setupBlob(asyncNoFaultClient, options.getSize()));
49+
}
50+
51+
@Override
52+
public Mono<Void> globalCleanupAsync() {
53+
return asyncNoFaultClient.delete()
54+
.then(super.globalCleanupAsync());
55+
}
56+
}
57+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.storage.blob.stress;
5+
6+
import com.azure.core.util.BinaryData;
7+
import com.azure.core.util.Context;
8+
import com.azure.core.util.logging.ClientLogger;
9+
import com.azure.storage.blob.BlobAsyncClient;
10+
import com.azure.storage.blob.BlobClient;
11+
import com.azure.storage.blob.stress.utils.OriginalContent;
12+
import com.azure.storage.blob.stress.utils.TelemetryHelper;
13+
import com.azure.storage.stress.StorageStressOptions;
14+
import reactor.core.publisher.Flux;
15+
import reactor.core.publisher.Mono;
16+
17+
import java.io.ByteArrayOutputStream;
18+
import java.nio.ByteBuffer;
19+
import java.util.Collections;
20+
import java.util.Objects;
21+
22+
public class DownloadStream extends BlobScenarioBase<StorageStressOptions> {
23+
private static final ClientLogger LOGGER = new ClientLogger(DownloadStream.class);
24+
private static final TelemetryHelper TELEMETRY_HELPER = new TelemetryHelper(DownloadStream.class);
25+
private static final OriginalContent ORIGINAL_CONTENT = new OriginalContent();
26+
private final BlobClient syncClient;
27+
private final BlobAsyncClient asyncClient;
28+
private final BlobAsyncClient asyncNoFaultClient;
29+
30+
public DownloadStream(StorageStressOptions options) {
31+
super(options, TELEMETRY_HELPER);
32+
this.asyncNoFaultClient = getAsyncContainerClientNoFault().getBlobAsyncClient(options.getBlobName());
33+
this.syncClient = getSyncContainerClient().getBlobClient(options.getBlobName());
34+
this.asyncClient = getAsyncContainerClient().getBlobAsyncClient(options.getBlobName());
35+
}
36+
37+
@Override
38+
protected boolean runInternal(Context span) {
39+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
40+
try {
41+
syncClient.downloadStreamWithResponse(outputStream, null, null, null, false, null, span);
42+
return ORIGINAL_CONTENT.checkMatch(BinaryData.fromBytes(outputStream.toByteArray()), span).block().booleanValue();
43+
} catch (Exception e) {
44+
LOGGER.error("Failed to download blob", e);
45+
return false;
46+
}
47+
}
48+
49+
@Override
50+
protected Mono<Boolean> runInternalAsync(Context span) {
51+
return asyncClient.downloadStreamWithResponse(null, null, null, false)
52+
.flatMap(response -> ORIGINAL_CONTENT.checkMatch(BinaryData.fromFlux(response.getValue()).block(), span));
53+
}
54+
55+
@Override
56+
public Mono<Void> globalSetupAsync() {
57+
return super.globalSetupAsync()
58+
.then(ORIGINAL_CONTENT.setupBlob(asyncNoFaultClient, options.getSize()));
59+
}
60+
61+
@Override
62+
public Mono<Void> globalCleanupAsync() {
63+
return asyncNoFaultClient.delete()
64+
.then(super.globalCleanupAsync());
65+
}
66+
67+
}

sdk/storage/azure-storage-blob-stress/src/main/java/com/azure/storage/blob/stress/DownloadToFile.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
package com.azure.storage.blob.stress;
55

6+
import com.azure.core.util.BinaryData;
67
import com.azure.core.util.Context;
78
import com.azure.core.util.logging.ClientLogger;
89
import com.azure.storage.blob.BlobAsyncClient;
@@ -44,7 +45,7 @@ protected boolean runInternal(Context span) {
4445

4546
try {
4647
syncClient.downloadToFileWithResponse(blobOptions, Duration.ofSeconds(options.getDuration()), span);
47-
return ORIGINAL_CONTENT.checkMatch(downloadPath, span).block();
48+
return ORIGINAL_CONTENT.checkMatch(BinaryData.fromFile(downloadPath), span).block().booleanValue();
4849
} finally {
4950
deleteFile(downloadPath);
5051
}
@@ -55,8 +56,8 @@ protected Mono<Boolean> runInternalAsync(Context span) {
5556
return Mono.using(
5657
() -> directoryPath.resolve(UUID.randomUUID() + ".txt"),
5758
path -> asyncClient.downloadToFileWithResponse(new BlobDownloadToFileOptions(path.toString()))
58-
.flatMap(ignored -> ORIGINAL_CONTENT.checkMatch(path, span)),
59-
path -> deleteFile(path));
59+
.flatMap(ignored -> ORIGINAL_CONTENT.checkMatch(BinaryData.fromFile(path), span)),
60+
DownloadToFile::deleteFile);
6061
}
6162

6263
private static void deleteFile(Path path) {

0 commit comments

Comments
 (0)