Skip to content

Commit e3a6ed9

Browse files
authored
[Storage] [DataMovement] [Tests] Abstract Pause/Resume E2E tests and implement for Share File & Blobs (#48205)
* Initial commit * initial commit * refactored CreateDestinationStorageResourceItem and reduced abstract methods * removed space * added blobClient check
1 parent 24b77fd commit e3a6ed9

23 files changed

+720
-404
lines changed

sdk/storage/Azure.Storage.DataMovement.Blobs/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "net",
44
"TagPrefix": "net/storage/Azure.Storage.DataMovement.Blobs",
5-
"Tag": "net/storage/Azure.Storage.DataMovement.Blobs_148b875701"
5+
"Tag": "net/storage/Azure.Storage.DataMovement.Blobs_214325a4f9"
66
}

sdk/storage/Azure.Storage.DataMovement.Blobs/tests/Azure.Storage.DataMovement.Blobs.Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<Aliases>DMBlobs</Aliases>
1111
</ProjectReference>
1212
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.DataMovement\src\Azure.Storage.DataMovement.csproj" />
13-
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.Blobs\src\Azure.Storage.Blobs.csproj" >
13+
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.Blobs\src\Azure.Storage.Blobs.csproj">
1414
<Aliases>BaseBlobs</Aliases>
1515
</ProjectReference>
1616
</ItemGroup>
@@ -55,6 +55,7 @@
5555
<Compile Include="$(AzureStorageDataMovementTestSharedSources)TransferDirection.cs" LinkBase="Shared\DataMovement" />
5656
<Compile Include="$(AzureStorageDataMovementTestSharedSources)TransferValidator.Local.cs" LinkBase="Shared\DataMovement" />
5757
<Compile Include="$(AzureStorageDataMovementTestSharedSources)TestProgressHandler.cs" LinkBase="Shared\DataMovement" />
58+
<Compile Include="$(AzureStorageDataMovementTestSharedSources)PauseResumeTransferTestBase.cs" LinkBase="Shared\DataMovement" />
5859
</ItemGroup>
5960
<ItemGroup>
6061
<Content Include="Resources\**">
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
extern alias DMBlobs;
4+
extern alias BaseBlobs;
5+
6+
using System;
7+
using System.Threading.Tasks;
8+
using Azure.Storage.Test.Shared;
9+
using Azure.Storage.DataMovement.Tests;
10+
using DMBlobs::Azure.Storage.DataMovement.Blobs;
11+
using BaseBlobs::Azure.Storage.Blobs;
12+
using BaseBlobs::Azure.Storage.Blobs.Specialized;
13+
using BaseBlobs::Azure.Storage.Blobs.Models;
14+
using System.IO;
15+
using NUnit.Framework;
16+
using Metadata = System.Collections.Generic.IDictionary<string, string>;
17+
18+
namespace Azure.Storage.DataMovement.Blobs.Tests
19+
{
20+
[DataMovementBlobsClientTestFixture]
21+
public class BlobPauseResumeTransferTests : PauseResumeTransferTestBase
22+
<BlobServiceClient,
23+
BlobContainerClient,
24+
BlockBlobClient,
25+
BlobClientOptions,
26+
StorageTestEnvironment>
27+
{
28+
protected readonly BlobClientOptions.ServiceVersion _serviceVersion;
29+
30+
public BlobPauseResumeTransferTests(bool async, BlobClientOptions.ServiceVersion serviceVersion)
31+
: base(async, null /* RecordedTestMode.Record /* to re-record */)
32+
{
33+
_serviceVersion = serviceVersion;
34+
ClientBuilder = ClientBuilderExtensions.GetNewBlobsClientBuilder(Tenants, serviceVersion);
35+
}
36+
37+
protected override async Task<IDisposingContainer<BlobContainerClient>> GetDisposingContainerAsync(
38+
string containerName = default,
39+
BlobServiceClient service = default)
40+
=> await ClientBuilder.GetTestContainerAsync(service, containerName);
41+
42+
protected override StorageResourceProvider GetStorageResourceProvider()
43+
=> new BlobsStorageResourceProvider(TestEnvironment.Credential);
44+
45+
protected override async Task<StorageResource> CreateSourceStorageResourceItemAsync(
46+
long size,
47+
string blobName,
48+
BlobContainerClient container)
49+
{
50+
BlockBlobClient blobClient = container.GetBlockBlobClient(blobName);
51+
// create a new file and copy contents of stream into it, and then close the FileStream
52+
using (Stream originalStream = await CreateLimitedMemoryStream(size))
53+
{
54+
// Upload blob to storage account
55+
originalStream.Position = 0;
56+
await blobClient.UploadAsync(originalStream);
57+
}
58+
return BlobsStorageResourceProvider.FromClient(blobClient);
59+
}
60+
61+
protected override StorageResource CreateDestinationStorageResourceItem(
62+
string blobName,
63+
BlobContainerClient container,
64+
Metadata metadata = default,
65+
string contentLanguage = default)
66+
{
67+
BlockBlobStorageResourceOptions testOptions = new()
68+
{
69+
Metadata = metadata,
70+
ContentLanguage = contentLanguage,
71+
};
72+
BlockBlobClient destinationClient = container.GetBlockBlobClient(blobName);
73+
return BlobsStorageResourceProvider.FromClient(destinationClient, testOptions);
74+
}
75+
76+
protected override async Task AssertDestinationProperties(
77+
string blobName,
78+
Metadata expectedMetadata,
79+
string expectedContentLanguage,
80+
BlobContainerClient container)
81+
{
82+
BlockBlobClient blob = container.GetBlockBlobClient(blobName);
83+
BlobProperties props = (await blob.GetPropertiesAsync()).Value;
84+
Assert.That(props.Metadata, Is.EqualTo(expectedMetadata));
85+
Assert.That(props.ContentLanguage, Is.EqualTo(expectedContentLanguage));
86+
}
87+
88+
protected override async Task<Stream> GetStreamFromContainerAsync(Uri uri, BlobContainerClient container)
89+
{
90+
BlobUriBuilder builder = new BlobUriBuilder(uri);
91+
BlockBlobClient blobClient = container.GetBlockBlobClient(builder.BlobName);
92+
if (!await blobClient.ExistsAsync())
93+
{
94+
throw new FileNotFoundException($"Blob not found: {uri}");
95+
}
96+
97+
MemoryStream stream = new MemoryStream();
98+
await blobClient.DownloadToAsync(stream);
99+
stream.Position = 0;
100+
return stream;
101+
}
102+
103+
protected override async Task<StorageResource> CreateSourceStorageResourceContainerAsync(
104+
long size,
105+
int blobCount,
106+
string directoryPath,
107+
BlobContainerClient container)
108+
{
109+
for (int i = 0; i < blobCount; i++)
110+
{
111+
if (i % 3 == 0)
112+
{
113+
BlockBlobClient blobClient = container.GetBlockBlobClient(string.Join("/", directoryPath, GetNewItemName()));
114+
// create a new file and copy contents of stream into it, and then close the FileStream
115+
using (Stream originalStream = await CreateLimitedMemoryStream(size))
116+
{
117+
// Upload blob to storage account
118+
originalStream.Position = 0;
119+
await blobClient.UploadAsync(originalStream);
120+
}
121+
}
122+
else if (i % 3 == 1)
123+
{
124+
AppendBlobClient blobClient = container.GetAppendBlobClient(string.Join("/", directoryPath, GetNewItemName()));
125+
await blobClient.CreateAsync();
126+
// create a new file and copy contents of stream into it, and then close the FileStream
127+
using (Stream originalStream = await CreateLimitedMemoryStream(size))
128+
{
129+
// Upload blob to storage account
130+
originalStream.Position = 0;
131+
await blobClient.AppendBlockAsync(originalStream);
132+
}
133+
}
134+
else
135+
{
136+
PageBlobClient blobClient = container.GetPageBlobClient(string.Join("/", directoryPath, GetNewItemName()));
137+
await blobClient.CreateAsync(size);
138+
// create a new file and copy contents of stream into it, and then close the FileStream
139+
using (Stream originalStream = await CreateLimitedMemoryStream(size))
140+
{
141+
// Upload blob to storage account
142+
originalStream.Position = 0;
143+
await blobClient.UploadPagesAsync(originalStream, 0);
144+
}
145+
}
146+
}
147+
BlobStorageResourceContainerOptions options = new();
148+
options.BlobPrefix = directoryPath;
149+
return BlobsStorageResourceProvider.FromClient(container, options);
150+
}
151+
152+
protected override StorageResource CreateDestinationStorageResourceContainer(
153+
BlobContainerClient container)
154+
{
155+
BlobStorageResourceContainerOptions options = new()
156+
{
157+
BlobPrefix = GetNewContainerName()
158+
};
159+
return BlobsStorageResourceProvider.FromClient(container, options);
160+
}
161+
}
162+
}

sdk/storage/Azure.Storage.DataMovement.Files.Shares/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "net",
44
"TagPrefix": "net/storage/Azure.Storage.DataMovement.Files.Shares",
5-
"Tag": "net/storage/Azure.Storage.DataMovement.Files.Shares_147f0416cd"
5+
"Tag": "net/storage/Azure.Storage.DataMovement.Files.Shares_f8e20fac90"
66
}

sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryStorageResourceContainer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Azure.Storage.DataMovement.Files.Shares
1616
internal class ShareDirectoryStorageResourceContainer : StorageResourceContainerInternal
1717
{
1818
internal ShareFileStorageResourceOptions ResourceOptions { get; set; }
19-
internal PathScanner PathScanner { get; set; } = PathScanner.Singleton.Value;
19+
internal SharesPathScanner PathScanner { get; set; } = SharesPathScanner.Singleton.Value;
2020

2121
internal ShareDirectoryClient ShareDirectoryClient { get; }
2222

sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/PathScanner.cs renamed to sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/SharesPathScanner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
namespace Azure.Storage.DataMovement.Files.Shares
1515
{
16-
internal class PathScanner
16+
internal class SharesPathScanner
1717
{
18-
public static Lazy<PathScanner> Singleton { get; } = new Lazy<PathScanner>(() => new PathScanner());
18+
public static Lazy<SharesPathScanner> Singleton { get; } = new Lazy<SharesPathScanner>(() => new SharesPathScanner());
1919

2020
public virtual async IAsyncEnumerable<StorageResource> ScanAsync(
2121
ShareDirectoryClient sourceDirectory,

sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
<Aliases>DMShare</Aliases>
1111
</ProjectReference>
1212
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.DataMovement\src\Azure.Storage.DataMovement.csproj" />
13-
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.DataMovement.Files.Shares\src\Azure.Storage.DataMovement.Files.Shares.csproj" />
1413
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.Files.Shares\src\Azure.Storage.Files.Shares.csproj">
1514
<Aliases>BaseShares</Aliases>
1615
</ProjectReference>
@@ -35,9 +34,6 @@
3534
</None>
3635
<None Include="$(AzureStorageSharedTestSources)\azurite_cert.pem" CopyToOutputDirectory="PreserveNewest" />
3736
</ItemGroup>
38-
<ItemGroup>
39-
<Compile Include="$(AzureStorageDataMovementSharedSources)TransferStatusInternal.cs" LinkBase="Shared\DataMovement" />
40-
</ItemGroup>
4137
<ItemGroup>
4238
<Compile Include="$(AzureStorageDataMovementTestSharedSources)DataMovementTestConstants.cs" LinkBase="Shared\DataMovement" />
4339
<Compile Include="$(AzureStorageDataMovementTestSharedSources)TestEventsRaised.cs" LinkBase="Shared\DataMovement" />
@@ -51,6 +47,8 @@
5147
<Compile Include="$(AzureStorageDataMovementTestSharedSources)StartTransferDownloadTestBase.cs" LinkBase="Shared\DataMovement" />
5248
<Compile Include="$(AzureStorageDataMovementTestSharedSources)StartTransferDirectoryDownloadTestBase.cs" LinkBase="Shared\DataMovement" />
5349
<Compile Include="$(AzureStorageDataMovementTestSharedSources)TestTransferWithTimeout.cs" LinkBase="Shared\DataMovement" />
50+
<Compile Include="$(AzureStorageDataMovementTestSharedSources)PauseResumeTransferTestBase.cs" LinkBase="Shared\DataMovement" />
51+
<Compile Include="$(AzureStorageDataMovementTestSharedSources)TransferDirection.cs" LinkBase="Shared\DataMovement" />
5452
</ItemGroup>
5553
<ItemGroup>
5654
<Content Include="Resources\**">

sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/PathScannerTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
extern alias BaseShares;
5+
extern alias DMShare;
56

67
using System;
78
using System.Collections.Generic;
@@ -13,6 +14,7 @@
1314
using Moq;
1415
using Moq.Protected;
1516
using NUnit.Framework;
17+
using DMShare::Azure.Storage.DataMovement.Files.Shares;
1618

1719
namespace Azure.Storage.DataMovement.Files.Shares.Tests
1820
{
@@ -59,7 +61,7 @@ public async Task PathScannerFindsAllRecursive(string baseDirName)
5961
List<ShareFileStorageResource> files = new();
6062
List<ShareDirectoryStorageResourceContainer> directories = new();
6163
await foreach (StorageResource storageResource
62-
in new PathScanner().ScanAsync(
64+
in new SharesPathScanner().ScanAsync(
6365
sourceDirectory: sourceDirectory.Object,
6466
destinationShare: destinationShare.Object,
6567
sourceOptions: default,
@@ -132,7 +134,7 @@ public async Task PathScannerFindsAllRecursive_Traits()
132134
List<ShareDirectoryStorageResourceContainer> directories = new();
133135
ShareFileTraits traits = ShareFileTraits.Attributes | ShareFileTraits.PermissionKey;
134136
await foreach (StorageResource storageResource
135-
in new PathScanner().ScanAsync(
137+
in new SharesPathScanner().ScanAsync(
136138
sourceDirectory: mockDirectory.Object,
137139
destinationShare: mockDestinationShare.Object,
138140
sourceOptions: default,

sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/RehydrateShareResourceTests.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33
extern alias BaseShares;
4+
extern alias DMShare;
45

56
using System;
67
using System.Collections.Generic;
@@ -13,6 +14,7 @@
1314
using NUnit.Framework;
1415
using Azure.Core;
1516
using Azure.Identity;
17+
using DMShare::Azure.Storage.DataMovement.Files.Shares;
1618

1719
namespace Azure.Storage.DataMovement.Files.Shares.Tests
1820
{
@@ -28,6 +30,20 @@ private static byte[] GetBytes(StorageResourceCheckpointDetailsInternal checkpoi
2830
return stream.ToArray();
2931
}
3032

33+
private static byte[] GetBytesSource(ShareFileSourceCheckpointDetails checkpointDetails)
34+
{
35+
using MemoryStream stream = new();
36+
checkpointDetails.SerializeInternal(stream);
37+
return stream.ToArray();
38+
}
39+
40+
private static byte[] GetBytesDestination(ShareFileDestinationCheckpointDetails checkpointDetails)
41+
{
42+
using MemoryStream stream = new();
43+
checkpointDetails.SerializeInternal(stream);
44+
return stream.ToArray();
45+
}
46+
3147
private static Mock<TransferProperties> GetProperties(
3248
string transferId,
3349
string sourcePath,
@@ -44,8 +60,8 @@ private static Mock<TransferProperties> GetProperties(
4460
mock.Setup(p => p.DestinationUri).Returns(new Uri(destinationPath));
4561
mock.Setup(p => p.SourceProviderId).Returns(sourceProviderId);
4662
mock.Setup(p => p.DestinationProviderId).Returns(destinationProviderId);
47-
mock.Setup(p => p.SourceCheckpointDetails).Returns(GetBytes(sourceCheckpointDetails));
48-
mock.Setup(p => p.DestinationCheckpointDetails).Returns(GetBytes(destinationCheckpointDetails));
63+
mock.Setup(p => p.SourceCheckpointDetails).Returns(GetBytesSource(sourceCheckpointDetails));
64+
mock.Setup(p => p.DestinationCheckpointDetails).Returns(GetBytesDestination(destinationCheckpointDetails));
4965
mock.Setup(p => p.IsContainer).Returns(isContainer);
5066
return mock;
5167
}

sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareDestinationCheckpointDetailsTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33
extern alias BaseShares;
4+
extern alias DMShare;
45

56
using System;
67
using System.Collections.Generic;
@@ -10,6 +11,7 @@
1011
using Azure.Storage.Test;
1112
using NUnit.Framework;
1213
using Metadata = System.Collections.Generic.IDictionary<string, string>;
14+
using DMShare::Azure.Storage.DataMovement.Files.Shares;
1315

1416
namespace Azure.Storage.DataMovement.Files.Shares.Tests
1517
{

0 commit comments

Comments
 (0)