Skip to content

Commit 476da31

Browse files
[Storage] Improve Storage test utilities and refactor navigation methods (#2525)
1 parent 71917a2 commit 476da31

File tree

7 files changed

+74
-137
lines changed

7 files changed

+74
-137
lines changed

sdk/storage/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "rust",
4-
"Tag": "rust/azure_storage_blob_99380d9553",
4+
"Tag": "rust/azure_storage_blob_e3372225c3",
55
"TagPrefix": "rust/azure_storage_blob"
66
}

sdk/storage/azure_storage_blob/src/clients/blob_client.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use std::sync::Arc;
2828

2929
/// A client to interact with a specific Azure storage blob, although that blob may not yet exist.
3030
pub struct BlobClient {
31-
endpoint: Url,
32-
client: GeneratedBlobClient,
31+
pub(super) endpoint: Url,
32+
pub(super) client: GeneratedBlobClient,
3333
}
3434

3535
impl BlobClient {

sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ use std::sync::Arc;
2020

2121
/// A client to interact with a specified Azure storage container.
2222
pub struct BlobContainerClient {
23-
endpoint: Url,
24-
container_name: String,
25-
credential: Arc<dyn TokenCredential>,
26-
client: GeneratedBlobContainerClient,
23+
pub(super) endpoint: Url,
24+
pub(super) client: GeneratedBlobContainerClient,
2725
}
2826

2927
impl BlobContainerClient {
@@ -67,8 +65,6 @@ impl BlobContainerClient {
6765

6866
Ok(Self {
6967
endpoint: endpoint.parse()?,
70-
container_name,
71-
credential,
7268
client,
7369
})
7470
}
@@ -79,18 +75,11 @@ impl BlobContainerClient {
7975
///
8076
/// * `blob_name` - The name of the blob.
8177
/// * `options` - Optional configuration for the client.
82-
pub fn blob_client(
83-
&self,
84-
blob_name: String,
85-
options: Option<BlobClientOptions>,
86-
) -> Result<BlobClient> {
87-
BlobClient::new(
88-
self.endpoint().as_str(),
89-
self.container_name().to_string(),
90-
blob_name,
91-
self.credential.clone(),
92-
options,
93-
)
78+
pub fn blob_client(&self, blob_name: String) -> BlobClient {
79+
BlobClient {
80+
endpoint: self.client.endpoint.clone(),
81+
client: self.client.get_blob_client(blob_name),
82+
}
9483
}
9584

9685
/// Gets the endpoint of the Storage account this client is connected to.
@@ -100,7 +89,7 @@ impl BlobContainerClient {
10089

10190
/// Gets the container name of the Storage account this client is connected to.
10291
pub fn container_name(&self) -> &str {
103-
&self.container_name
92+
&self.client.container_name
10493
}
10594

10695
/// Creates a new container under the specified account. If the container with the same name already exists, the operation fails.

sdk/storage/azure_storage_blob/src/clients/blob_service_client.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ use std::sync::Arc;
1818

1919
/// A client to interact with an Azure storage account.
2020
pub struct BlobServiceClient {
21-
endpoint: Url,
22-
credential: Arc<dyn TokenCredential>,
23-
client: GeneratedBlobServiceClient,
21+
pub(super) endpoint: Url,
22+
pub(super) client: GeneratedBlobServiceClient,
2423
}
2524

2625
impl BlobServiceClient {
@@ -57,7 +56,6 @@ impl BlobServiceClient {
5756

5857
Ok(Self {
5958
endpoint: endpoint.parse()?,
60-
credential,
6159
client,
6260
})
6361
}
@@ -68,17 +66,11 @@ impl BlobServiceClient {
6866
///
6967
/// * `container_name` - The name of the container.
7068
/// * `options` - Optional configuration for the client.
71-
pub fn blob_container_client(
72-
&self,
73-
container_name: String,
74-
options: Option<BlobContainerClientOptions>,
75-
) -> Result<BlobContainerClient> {
76-
BlobContainerClient::new(
77-
self.endpoint().as_str(),
78-
container_name,
79-
self.credential.clone(),
80-
options,
81-
)
69+
pub fn blob_container_client(&self, container_name: String) -> BlobContainerClient {
70+
BlobContainerClient {
71+
endpoint: self.client.endpoint.clone(),
72+
client: self.client.get_blob_container_client(container_name),
73+
}
8274
}
8375

8476
/// Gets the endpoint of the Storage account this client is connected to.

sdk/storage/azure_storage_blob/tests/blob_client.rs

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,15 @@ use azure_storage_blob::{
1313
},
1414
BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlockBlobClientUploadOptions,
1515
};
16-
use azure_storage_blob_test::{create_test_blob, get_blob_client, get_container_client};
16+
use azure_storage_blob_test::{create_test_blob, get_blob_name, get_container_client};
1717
use std::{collections::HashMap, error::Error};
1818

1919
#[recorded::test]
2020
async fn test_get_blob_properties(ctx: TestContext) -> Result<(), Box<dyn Error>> {
2121
// Recording Setup
2222
let recording = ctx.recording();
23-
let container_client = get_container_client(recording)?;
24-
let blob_client = get_blob_client(
25-
Some(container_client.container_name().to_string()),
26-
recording,
27-
)?;
23+
let container_client = get_container_client(recording, false).await?;
24+
let blob_client = container_client.blob_client(get_blob_name(recording));
2825

2926
// Invalid Container Scenario
3027
let response = blob_client.get_properties(None).await;
@@ -58,12 +55,8 @@ async fn test_get_blob_properties(ctx: TestContext) -> Result<(), Box<dyn Error>
5855
async fn test_set_blob_properties(ctx: TestContext) -> Result<(), Box<dyn Error>> {
5956
// Recording Setup
6057
let recording = ctx.recording();
61-
let container_client = get_container_client(recording)?;
62-
let blob_client = get_blob_client(
63-
Some(container_client.container_name().to_string()),
64-
recording,
65-
)?;
66-
container_client.create_container(None).await?;
58+
let container_client = get_container_client(recording, true).await?;
59+
let blob_client = container_client.blob_client(get_blob_name(recording));
6760
create_test_blob(&blob_client).await?;
6861

6962
// Set Content Settings
@@ -91,14 +84,9 @@ async fn test_set_blob_properties(ctx: TestContext) -> Result<(), Box<dyn Error>
9184
#[recorded::test]
9285
async fn test_upload_blob(ctx: TestContext) -> Result<(), Box<dyn Error>> {
9386
// Recording Setup
94-
9587
let recording = ctx.recording();
96-
let container_client = get_container_client(recording)?;
97-
let blob_client = get_blob_client(
98-
Some(container_client.container_name().to_string()),
99-
recording,
100-
)?;
101-
container_client.create_container(None).await?;
88+
let container_client = get_container_client(recording, true).await?;
89+
let blob_client = container_client.blob_client(get_blob_name(recording));
10290

10391
let data = b"hello rusty world";
10492

@@ -164,14 +152,9 @@ async fn test_upload_blob(ctx: TestContext) -> Result<(), Box<dyn Error>> {
164152
#[recorded::test]
165153
async fn test_delete_blob(ctx: TestContext) -> Result<(), Box<dyn Error>> {
166154
// Recording Setup
167-
168155
let recording = ctx.recording();
169-
let container_client = get_container_client(recording)?;
170-
let blob_client = get_blob_client(
171-
Some(container_client.container_name().to_string()),
172-
recording,
173-
)?;
174-
container_client.create_container(None).await?;
156+
let container_client = get_container_client(recording, true).await?;
157+
let blob_client = container_client.blob_client(get_blob_name(recording));
175158
create_test_blob(&blob_client).await?;
176159

177160
// Existence Check
@@ -193,14 +176,18 @@ async fn test_delete_blob(ctx: TestContext) -> Result<(), Box<dyn Error>> {
193176
async fn test_download_blob(ctx: TestContext) -> Result<(), Box<dyn Error>> {
194177
// Recording Setup
195178
let recording = ctx.recording();
196-
let container_client = get_container_client(recording)?;
197-
let blob_client = get_blob_client(
198-
Some(container_client.container_name().to_string()),
199-
recording,
200-
)?;
201-
container_client.create_container(None).await?;
202-
create_test_blob(&blob_client).await?;
179+
let container_client = get_container_client(recording, true).await?;
180+
let blob_client = container_client.blob_client(get_blob_name(recording));
181+
let data = b"hello rusty world";
203182

183+
blob_client
184+
.upload(
185+
RequestContent::from(data.to_vec()),
186+
false,
187+
u64::try_from(data.len())?,
188+
None,
189+
)
190+
.await?;
204191
let response = blob_client.download(None).await?;
205192

206193
// Assert
@@ -222,12 +209,8 @@ async fn test_set_blob_metadata(ctx: TestContext) -> Result<(), Box<dyn Error>>
222209
// Recording Setup
223210

224211
let recording = ctx.recording();
225-
let container_client = get_container_client(recording)?;
226-
let blob_client = get_blob_client(
227-
Some(container_client.container_name().to_string()),
228-
recording,
229-
)?;
230-
container_client.create_container(None).await?;
212+
let container_client = get_container_client(recording, true).await?;
213+
let blob_client = container_client.blob_client(get_blob_name(recording));
231214
let data = b"hello rusty world";
232215

233216
// Upload Blob With Metadata
@@ -276,12 +259,8 @@ async fn test_set_blob_metadata(ctx: TestContext) -> Result<(), Box<dyn Error>>
276259
async fn test_put_block_list(ctx: TestContext) -> Result<(), Box<dyn Error>> {
277260
// Recording Setup
278261
let recording = ctx.recording();
279-
let container_client = get_container_client(recording)?;
280-
let blob_client = get_blob_client(
281-
Some(container_client.container_name().to_string()),
282-
recording,
283-
)?;
284-
container_client.create_container(None).await?;
262+
let container_client = get_container_client(recording, true).await?;
263+
let blob_client = container_client.blob_client(get_blob_name(recording));
285264

286265
let block_1 = b"AAA";
287266
let block_2 = b"BBB";
@@ -349,12 +328,8 @@ async fn test_put_block_list(ctx: TestContext) -> Result<(), Box<dyn Error>> {
349328
async fn test_get_block_list(ctx: TestContext) -> Result<(), Box<dyn Error>> {
350329
// Recording Setup
351330
let recording = ctx.recording();
352-
let container_client = get_container_client(recording)?;
353-
let blob_client = get_blob_client(
354-
Some(container_client.container_name().to_string()),
355-
recording,
356-
)?;
357-
container_client.create_container(None).await?;
331+
let container_client = get_container_client(recording, true).await?;
332+
let blob_client = container_client.blob_client(get_blob_name(recording));
358333

359334
let block_1 = b"AAA";
360335
let block_2 = b"BBB";
@@ -432,12 +407,8 @@ async fn test_get_block_list(ctx: TestContext) -> Result<(), Box<dyn Error>> {
432407
async fn test_set_access_tier(ctx: TestContext) -> Result<(), Box<dyn Error>> {
433408
// Recording Setup
434409
let recording = ctx.recording();
435-
let container_client = get_container_client(recording)?;
436-
let blob_client = get_blob_client(
437-
Some(container_client.container_name().to_string()),
438-
recording,
439-
)?;
440-
container_client.create_container(None).await?;
410+
let container_client = get_container_client(recording, true).await?;
411+
let blob_client = container_client.blob_client(get_blob_name(recording));
441412
create_test_blob(&blob_client).await?;
442413

443414
let original_response = blob_client.get_properties(None).await?;

sdk/storage/azure_storage_blob/tests/blob_container_client.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{collections::HashMap, error::Error};
1414
async fn test_create_container(ctx: TestContext) -> Result<(), Box<dyn Error>> {
1515
// Recording Setup
1616
let recording = ctx.recording();
17-
let container_client = get_container_client(recording)?;
17+
let container_client = get_container_client(recording, false).await?;
1818

1919
container_client.create_container(None).await?;
2020

@@ -26,7 +26,7 @@ async fn test_create_container(ctx: TestContext) -> Result<(), Box<dyn Error>> {
2626
async fn test_get_container_properties(ctx: TestContext) -> Result<(), Box<dyn Error>> {
2727
// Recording Setup
2828
let recording = ctx.recording();
29-
let container_client = get_container_client(recording)?;
29+
let container_client = get_container_client(recording, false).await?;
3030

3131
// Container Doesn't Exists Scenario
3232
let response = container_client.get_properties(None).await;
@@ -54,8 +54,7 @@ async fn test_get_container_properties(ctx: TestContext) -> Result<(), Box<dyn E
5454
async fn test_set_container_metadata(ctx: TestContext) -> Result<(), Box<dyn Error>> {
5555
// Recording Setup
5656
let recording = ctx.recording();
57-
let container_client = get_container_client(recording)?;
58-
container_client.create_container(None).await?;
57+
let container_client = get_container_client(recording, true).await?;
5958

6059
// Set Metadata With Values
6160
let update_metadata = HashMap::from([("hello".to_string(), "world".to_string())]);

sdk/storage/azure_storage_blob_test/src/lib.rs

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use azure_core::{
77
};
88
use azure_core_test::Recording;
99
use azure_storage_blob::{
10-
models::BlockBlobClientUploadResult, BlobClient, BlobClientOptions, BlobContainerClient,
10+
models::BlockBlobClientUploadResult, BlobClient, BlobContainerClient,
1111
BlobContainerClientOptions, BlobServiceClient, BlobServiceClientOptions,
1212
};
1313

@@ -27,6 +27,18 @@ fn recorded_test_setup(recording: &Recording) -> (ClientOptions, String) {
2727
(client_options, endpoint)
2828
}
2929

30+
pub fn get_blob_name(recording: &Recording) -> String {
31+
recording
32+
.random_string::<12>(Some("blob"))
33+
.to_ascii_lowercase()
34+
}
35+
36+
pub fn get_container_name(recording: &Recording) -> String {
37+
recording
38+
.random_string::<17>(Some("container"))
39+
.to_ascii_lowercase()
40+
}
41+
3042
/// Returns an instance of a BlobServiceClient.
3143
///
3244
/// # Arguments
@@ -50,53 +62,27 @@ pub fn get_blob_service_client(recording: &Recording) -> Result<BlobServiceClien
5062
/// # Arguments
5163
///
5264
/// * `recording` - A reference to a Recording instance.
53-
pub fn get_container_client(recording: &Recording) -> Result<BlobContainerClient> {
54-
let container_name = recording
55-
.random_string::<17>(Some("container"))
56-
.to_ascii_lowercase();
65+
/// * `create` - An optional flag to determine whether the container should also be created.
66+
pub async fn get_container_client(
67+
recording: &Recording,
68+
create: bool,
69+
) -> Result<BlobContainerClient> {
70+
let container_name = get_container_name(recording);
5771
let (options, endpoint) = recorded_test_setup(recording);
5872
let container_client_options = BlobContainerClientOptions {
5973
client_options: options.clone(),
6074
..Default::default()
6175
};
62-
BlobContainerClient::new(
76+
let container_client = BlobContainerClient::new(
6377
&endpoint,
6478
container_name,
6579
recording.credential(),
6680
Some(container_client_options),
67-
)
68-
}
69-
70-
/// Returns an instance of a BlobClient.
71-
///
72-
/// # Arguments
73-
///
74-
/// * `container_name` - The name of the container containing this blob.
75-
/// * `recording` - A reference to a Recording instance.
76-
pub fn get_blob_client(
77-
container_name: Option<String>,
78-
recording: &Recording,
79-
) -> Result<BlobClient> {
80-
let container_name = container_name.unwrap_or(
81-
recording
82-
.random_string::<17>(Some("container"))
83-
.to_ascii_lowercase(),
84-
);
85-
let blob_name = recording
86-
.random_string::<12>(Some("blob"))
87-
.to_ascii_lowercase();
88-
let (options, endpoint) = recorded_test_setup(recording);
89-
let blob_client_options = BlobClientOptions {
90-
client_options: options.clone(),
91-
..Default::default()
92-
};
93-
BlobClient::new(
94-
&endpoint,
95-
container_name,
96-
blob_name,
97-
recording.credential(),
98-
Some(blob_client_options),
99-
)
81+
)?;
82+
if create {
83+
container_client.create_container(None).await?;
84+
}
85+
Ok(container_client)
10086
}
10187

10288
/// Creates a test blob with no options, containing the data "b'hello rusty world'" with content length 17.

0 commit comments

Comments
 (0)