From 26fc843b839f68e8ac9255690872af1d96fb2de6 Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Tue, 19 Sep 2023 11:03:17 -0700 Subject: [PATCH 1/8] WIP --- ...Movement.Files.Shares.Samples.Tests.csproj | 5 +++ .../src/AssemblyInfo.cs | 17 ++++++++++ ...e.Storage.DataMovement.Files.Shares.csproj | 9 ++++-- ...rceItem.cs => ShareFileStorageResource.cs} | 32 +++++++++++++++---- .../src/ShareFilesStorageResourceProvider.cs | 4 +-- ...age.DataMovement.Files.Shares.Tests.csproj | 8 ++--- .../tests/MockShareFileStorageResource.cs | 17 ++++++++++ .../tests/ShareFileResourceTests.cs | 15 +++++++++ .../src/Shared/DataMovementConstants.cs | 8 +++++ 9 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/AssemblyInfo.cs rename sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/{ShareFileStorageResourceItem.cs => ShareFileStorageResource.cs} (65%) create mode 100644 sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs create mode 100644 sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/samples/Azure.Storage.DataMovement.Files.Shares.Samples.Tests.csproj b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/samples/Azure.Storage.DataMovement.Files.Shares.Samples.Tests.csproj index e50b5044f2a64..71109c1206366 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/samples/Azure.Storage.DataMovement.Files.Shares.Samples.Tests.csproj +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/samples/Azure.Storage.DataMovement.Files.Shares.Samples.Tests.csproj @@ -32,4 +32,9 @@ + + + + + diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/AssemblyInfo.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/AssemblyInfo.cs new file mode 100644 index 0000000000000..afab16ac79109 --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/AssemblyInfo.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Azure.Storage.DataMovement.Tests, PublicKey=" + + "0024000004800000940000000602000000240000525341310004000001000100d15ddcb2968829" + + "5338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc" + + "012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265" + + "e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593d" + + "aa7b11b4")] +[assembly: InternalsVisibleTo("Azure.Storage.DataMovement.Files.Shares.Tests, PublicKey=" + + "0024000004800000940000000602000000240000525341310004000001000100d15ddcb2968829" + + "5338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc" + + "012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265" + + "e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593d" + + "aa7b11b4")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj index a2e444e50928e..fc7f9772f6afd 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj @@ -1,12 +1,12 @@ - + $(RequiredTargetFrameworks);net6.0 true - Microsoft Azure.Storage.DataMovement.Blobs client library + Microsoft Azure.Storage.DataMovement.Files.Shares client library 12.0.0-beta.1 - FileDataMovementSDK;$(DefineConstants) + ShareDataMovementSDK;$(DefineConstants) Microsoft Azure Storage DataMovement, DataMovement, Microsoft, Azure, StorageScalable, azureofficial This client library enables working with the Microsoft Azure Storage services which include the blob and file services for storing binary and text data, and the queue service for storing messages that may be accessed by a client. @@ -31,6 +31,9 @@ + + + diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceItem.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs similarity index 65% rename from sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceItem.cs rename to sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs index 787bf0c1596d3..a6f5c086d1f2d 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceItem.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs @@ -9,23 +9,25 @@ namespace Azure.Storage.DataMovement.Files.Shares { - internal class ShareFileStorageResourceItem : StorageResourceItem + internal class ShareFileStorageResource : StorageResourceItem { + internal long? _length; internal readonly ShareFileStorageResourceOptions _options; + internal ETag? _etagDownloadLock = default; internal ShareFileClient ShareFileClient { get; } public override Uri Uri => ShareFileClient.Uri; - protected override string ResourceId => throw new NotImplementedException(); + protected override string ResourceId => "ShareFile"; - protected override DataTransferOrder TransferType => throw new NotImplementedException(); + protected override DataTransferOrder TransferType => DataTransferOrder.Sequential; - protected override long MaxChunkSize => throw new NotImplementedException(); + protected override long MaxChunkSize => DataMovementConstants.Share.MaxRange; - protected override long? Length => throw new NotImplementedException(); + protected override long? Length => _length; - public ShareFileStorageResourceItem( + public ShareFileStorageResource( ShareFileClient fileClient, ShareFileStorageResourceOptions options = default) { @@ -33,6 +35,24 @@ public ShareFileStorageResourceItem( _options = options; } + /// + /// Internal Constructor for constructing the resource retrieved by a GetStorageResources. + /// + /// The blob client which will service the storage resource operations. + /// The content length of the blob. + /// Preset etag to lock on for reads. + /// Options for the storage resource. See . + internal ShareFileStorageResource( + ShareFileClient fileClient, + long? length, + ETag? etagLock, + ShareFileStorageResourceOptions options = default) + : this(fileClient, options) + { + _length = length; + _etagDownloadLock = etagLock; + } + protected override Task CompleteTransferAsync(bool overwrite, CancellationToken cancellationToken = default) { throw new NotImplementedException(); diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFilesStorageResourceProvider.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFilesStorageResourceProvider.cs index 48a92f0ae9825..c832b48d3e27c 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFilesStorageResourceProvider.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFilesStorageResourceProvider.cs @@ -304,7 +304,7 @@ public StorageResource FromFile(string fileUri, ShareFileStorageResourceOptions CredentialType.Sas => new ShareFileClient(new Uri(fileUri), _getAzureSasCredential(fileUri, false)), _ => throw BadCredentialTypeException(_credentialType), }; - return new ShareFileStorageResourceItem(client, options); + return new ShareFileStorageResource(client, options); } #endregion @@ -344,7 +344,7 @@ public StorageResource FromClient( ShareFileClient client, ShareFileStorageResourceOptions options = default) { - return new ShareFileStorageResourceItem(client, options); + return new ShareFileStorageResource(client, options); } #endregion diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj index e3712cbcf5468..80857fe5ce16c 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj @@ -1,13 +1,13 @@ - + $(RequiredTargetFrameworks) - Microsoft Azure.Storage.DataMovement.Files.Shareas client library tests - BlobDataMovementSDK;$(DefineConstants) + Microsoft Azure.Storage.DataMovement.Files.Shares client library tests + ShareDataMovementSDK;$(DefineConstants) false - DMBlobs + DMShare diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs new file mode 100644 index 0000000000000..b6fe5f9983012 --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +extern alias DMShare; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DMShare::Azure.Storage.DataMovement.Files.Shares; + +namespace Azure.Storage.DataMovement.Files.Shares.Tests +{ + internal class MockShareFileStorageResource : ShareFileStorageResource + { + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs new file mode 100644 index 0000000000000..434ebb3576f65 --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Azure.Storage.DataMovement.Files.Shares.Tests +{ + public class ShareFileResourceTests + { + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs b/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs index 8ee2f90917d6d..8fe01227a097c 100644 --- a/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs +++ b/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs @@ -7,6 +7,9 @@ namespace Azure.Storage.DataMovement { internal class DataMovementConstants { + public const int KB = 1024; + public const int MB = KB * 1024; + /// /// Constants of the Data Movement library /// @@ -267,5 +270,10 @@ internal static class ErrorCode internal static readonly string[] CannotOverwrite = { "BlobAlreadyExists", "Cannot overwrite file." }; internal static readonly string[] AccessDenied = { "AuthenticationFailed", "AuthorizationFailure", "access denied" }; } + + internal static class Share + { + internal const int MaxRange = 4 * MB; + } } } From c8e92935198f4350539fe251392cd6e77bdfbf34 Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Fri, 22 Sep 2023 16:34:44 -0700 Subject: [PATCH 2/8] Implemented base file storage resource; Testst --- .../src/DataMovementSharesExtensions.cs | 103 +++++ .../src/ShareFileStorageResource.cs | 97 +++- .../src/ShareFileStorageResourceOptions.cs | 100 +++- ...age.DataMovement.Files.Shares.Tests.csproj | 29 +- .../tests/MockShareFileStorageResource.cs | 77 +++ .../tests/ShareFileResourceTests.cs | 437 ++++++++++++++++++ .../StorageResourceWriteToOffsetOptions.cs | 4 +- 7 files changed, 823 insertions(+), 24 deletions(-) create mode 100644 sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementSharesExtensions.cs diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementSharesExtensions.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementSharesExtensions.cs new file mode 100644 index 0000000000000..f3a6d2378f092 --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementSharesExtensions.cs @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Storage.Files.Shares.Models; + +namespace Azure.Storage.DataMovement.Files.Shares +{ + internal static partial class DataMovementSharesExtensions + { + internal static ShareFileUploadOptions ToShareFileUploadOptions( + this ShareFileStorageResourceOptions options) + => new() + { + Conditions = options?.DestinationConditions, + TransferValidation = options?.UploadTransferValidationOptions, + }; + + internal static ShareFileUploadRangeOptions ToShareFileUploadRangeOptions( + this ShareFileStorageResourceOptions options) + => new() + { + Conditions = options?.DestinationConditions, + TransferValidation = options?.UploadTransferValidationOptions, + }; + + internal static ShareFileUploadRangeFromUriOptions ToShareFileUploadRangeFromUriOptions( + this ShareFileStorageResourceOptions options) + => new() + { + Conditions = options?.DestinationConditions, + }; + + internal static StorageResourceProperties ToStorageResourceProperties( + this ShareFileProperties properties) + => new( + lastModified: properties.LastModified, + createdOn: properties?.SmbProperties?.FileCreatedOn ?? default, + metadata: properties?.Metadata, + copyCompletedOn: properties.CopyCompletedOn, + copyStatusDescription: properties?.CopyStatusDescription, + copyId: properties?.CopyId, + copyProgress: properties?.CopyProgress, + copySource: new Uri(properties?.CopySource), + contentLength: properties.ContentLength, + contentType: properties?.ContentType, + eTag: properties.ETag, + contentHash: properties?.ContentHash, + blobSequenceNumber: default, + blobCommittedBlockCount: default, + isServerEncrypted: properties.IsServerEncrypted, + encryptionKeySha256: default, + encryptionScope: default, + versionId: default, + isLatestVersion: default, + expiresOn: default, + lastAccessed: default); + + internal static ShareFileDownloadOptions ToShareFileDownloadOptions( + this ShareFileStorageResourceOptions options, + HttpRange range) + => new() + { + Range = range, + Conditions = options?.SourceConditions, + TransferValidation = options?.DownloadTransferValidationOptions, + }; + + internal static StorageResourceReadStreamResult ToStorageResourceReadStreamResult( + this ShareFileDownloadInfo info) + => new( + content: info?.Content, + contentRange: info?.Details.ContentRange, + acceptRanges: info?.Details.AcceptRanges, + rangeContentHash: info?.Details.FileContentHash, + properties: info?.Details.ToStorageResourceProperties()); + + private static StorageResourceProperties ToStorageResourceProperties( + this ShareFileDownloadDetails details) + => new( + lastModified: details.LastModified, + createdOn: details.SmbProperties.FileCreatedOn ?? default, + metadata: details.Metadata, + copyCompletedOn: details.CopyCompletedOn, + copyStatusDescription: details.CopyStatusDescription, + copyId: details.CopyId, + copyProgress: details.CopyProgress, + copySource: details.CopySource, + contentLength: details.ContentRange.Length, + contentType: default, + eTag: details.ETag, + contentHash: default, + blobSequenceNumber: default, + blobCommittedBlockCount: default, + isServerEncrypted: details.IsServerEncrypted, + encryptionKeySha256: default, + encryptionScope: default, + versionId: default, + isLatestVersion: default, + expiresOn: default, + lastAccessed: default); + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs index a6f5c086d1f2d..dcf712c736fdd 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs @@ -3,9 +3,12 @@ using System; using System.IO; +using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; +using Azure.Core; using Azure.Storage.Files.Shares; +using Azure.Storage.Files.Shares.Models; namespace Azure.Storage.DataMovement.Files.Shares { @@ -53,44 +56,110 @@ internal ShareFileStorageResource( _etagDownloadLock = etagLock; } - protected override Task CompleteTransferAsync(bool overwrite, CancellationToken cancellationToken = default) + protected override Task CompleteTransferAsync( + bool overwrite, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + return Task.CompletedTask; } - protected override Task CopyBlockFromUriAsync(StorageResourceItem sourceResource, HttpRange range, bool overwrite, long completeLength, StorageResourceCopyFromUriOptions options = null, CancellationToken cancellationToken = default) + protected override async Task CopyBlockFromUriAsync( + StorageResourceItem sourceResource, + HttpRange range, + bool overwrite, + long completeLength, + StorageResourceCopyFromUriOptions options = null, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + await ShareFileClient.UploadRangeFromUriAsync( + sourceUri: sourceResource.Uri, + range: range, + sourceRange: range, + options: _options.ToShareFileUploadRangeFromUriOptions(), + cancellationToken: cancellationToken).ConfigureAwait(false); } - protected override Task CopyFromStreamAsync(Stream stream, long streamLength, bool overwrite, long completeLength, StorageResourceWriteToOffsetOptions options = null, CancellationToken cancellationToken = default) + protected override async Task CopyFromStreamAsync( + Stream stream, + long streamLength, + bool overwrite, + long completeLength, + StorageResourceWriteToOffsetOptions options = null, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + + long position = options?.Position != default ? options.Position.Value : 0; + if ((streamLength == completeLength) && position == 0) + { + // Default to Upload + await ShareFileClient.UploadAsync( + stream, + _options.ToShareFileUploadOptions(), + cancellationToken: cancellationToken).ConfigureAwait(false); + return; + } + + // Otherwise upload the Range + await ShareFileClient.UploadRangeAsync( + new HttpRange(position, streamLength), + stream, + _options.ToShareFileUploadRangeOptions(), + cancellationToken).ConfigureAwait(false); } - protected override Task CopyFromUriAsync(StorageResourceItem sourceResource, bool overwrite, long completeLength, StorageResourceCopyFromUriOptions options = null, CancellationToken cancellationToken = default) + protected override async Task CopyFromUriAsync( + StorageResourceItem sourceResource, + bool overwrite, + long completeLength, + StorageResourceCopyFromUriOptions options = null, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + await ShareFileClient.UploadRangeFromUriAsync( + sourceUri: sourceResource.Uri, + range: new HttpRange(0, completeLength), + sourceRange: new HttpRange(0, completeLength), + options: _options.ToShareFileUploadRangeFromUriOptions(), + cancellationToken: cancellationToken).ConfigureAwait(false); } - protected override Task DeleteIfExistsAsync(CancellationToken cancellationToken = default) + protected override async Task DeleteIfExistsAsync(CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + return await ShareFileClient.DeleteIfExistsAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } protected override Task GetCopyAuthorizationHeaderAsync(CancellationToken cancellationToken = default) { + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + // TODO: This needs an update to ShareFileClient to allow getting the Copy Authorization Token throw new NotImplementedException(); } - protected override Task GetPropertiesAsync(CancellationToken token = default) + protected override async Task GetPropertiesAsync(CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + Response response = await ShareFileClient.GetPropertiesAsync( + conditions: _options?.SourceConditions, + cancellationToken: cancellationToken).ConfigureAwait(false); + // TODO: should we be grabbing the ETag here even though we can't apply it to the download. + //GrabEtag(response.GetRawResponse()); + return response.Value.ToStorageResourceProperties(); } - protected override Task ReadStreamAsync(long position = 0, long? length = null, CancellationToken cancellationToken = default) + protected override async Task ReadStreamAsync( + long position = 0, + long? length = null, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + Response response = await ShareFileClient.DownloadAsync( + _options.ToShareFileDownloadOptions(new HttpRange(position, length)), + cancellationToken).ConfigureAwait(false); + return response.Value.ToStorageResourceReadStreamResult(); } } } diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceOptions.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceOptions.cs index 9e9b5dbf5f16a..0ef6cf4ff3f6d 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceOptions.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResourceOptions.cs @@ -1,6 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using Azure.Storage.Files.Shares.Models; +using Metadata = System.Collections.Generic.IDictionary; + namespace Azure.Storage.DataMovement.Files.Shares { /// @@ -9,10 +12,99 @@ namespace Azure.Storage.DataMovement.Files.Shares public class ShareFileStorageResourceOptions { /// - /// Default constructor. + /// Optional SMB properties to set for the directory and/or file resource. + /// + public FileSmbProperties SmbProperties { get; set; } + + /// + /// Optional. The file permission to set on the destination directory and/or file. + /// + /// Applies to copy and upload transfers. + /// TODO: determine whether this is something we want to apply and override + /// the potential default of copying over permissions when we go to do + /// file share to file share copy transfer. + /// + public string FilePermissions { get; set; } + + /// + /// Optional SMB properties to set for the directory and/or file. + /// + public ShareFileHttpHeaders HttpHeaders { get; set; } + + /// + /// Optional. See . + /// Access conditions on the copying of data from this source storage resource share file. + /// + /// Applies to copy and download transfers. + /// + public ShareFileRequestConditions SourceConditions { get; set; } + + /// + /// Optional. See . + /// Access conditions on the copying of data to this share file. + /// + /// Applies to copy and upload transfers. + /// + public ShareFileRequestConditions DestinationConditions { get; set; } + + /// + /// Optional boolean Specifying to set archive attribute on a target file. True + /// means archive attribute will be set on a target file despite attribute + /// overrides or a source file state. + /// + /// Only valid on Service Copy on the destination. + /// + public bool? Archive { get; set; } + + /// + /// Optional. Defines custom metadata to set on the destination resource. + /// + /// Applies to upload and copy transfers. + /// +#pragma warning disable CA2227 // Collection properties should be readonly + public Metadata DirectoryMetadata { get; set; } +#pragma warning restore CA2227 // Collection properties should be readonly + + /// + /// Optional. Defines custom metadata to set on the destination resource. + /// + /// Applies to upload and copy transfers. + /// +#pragma warning disable CA2227 // Collection properties should be readonly + public Metadata FileMetadata { get; set; } +#pragma warning restore CA2227 // Collection properties should be readonly + + /// + /// The protocols to enable for the share. + /// + public ShareProtocols? Protocols { get; set; } + + /// + /// Optional. Options for transfer validation settings on this operation. + /// When transfer validation options are set in the client, setting this parameter + /// acts as an override. + /// This operation does not allow + /// to be set. + /// + /// Applies to upload transfers. + /// + public UploadTransferValidationOptions UploadTransferValidationOptions { get; set; } + + /// + /// Optional. Options for transfer validation settings on this operation. + /// When transfer validation options are set in the client, setting this parameter + /// acts as an override. + /// Set to false if you + /// would like to skip SDK checksum validation and validate the checksum found + /// in the object yourself. + /// Range must be provided explicitly, stating a range withing Azure + /// Storage size limits for requesting a transactional hash. See the + /// + /// REST documentation for range limitation details. + /// + /// Applies to download transfers. /// - public ShareFileStorageResourceOptions() - { - } + public DownloadTransferValidationOptions DownloadTransferValidationOptions + { get; set; } } } diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj index 80857fe5ce16c..28f2b7d3ea14b 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj @@ -14,16 +14,37 @@ + + + + + + + + + + + + + + + + + + + + + PreserveNewest - - - PreserveNewest - + + + PreserveNewest + diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs index b6fe5f9983012..45674f4cde96e 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs @@ -4,14 +4,91 @@ extern alias DMShare; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Azure.Storage.Files.Shares; using DMShare::Azure.Storage.DataMovement.Files.Shares; namespace Azure.Storage.DataMovement.Files.Shares.Tests { internal class MockShareFileStorageResource : ShareFileStorageResource { + public MockShareFileStorageResource( + ShareFileClient fileClient, + ShareFileStorageResourceOptions options = null) : base(fileClient, options) + { + } + + internal MockShareFileStorageResource( + ShareFileClient fileClient, + long? length, + ETag? etagLock, + ShareFileStorageResourceOptions options = null) : base(fileClient, length, etagLock, options) + { + } + + internal Task MockCompleteTransferAsync(bool overwrite, CancellationToken cancellationToken = default) + => CompleteTransferAsync(overwrite, cancellationToken); + + internal Task MockCopyBlockFromUriAsync( + StorageResourceItem sourceResource, + HttpRange range, + bool overwrite, + long completeLength, + StorageResourceCopyFromUriOptions options = null, + CancellationToken cancellationToken = default) + => CopyBlockFromUriAsync( + sourceResource, + range, + overwrite, + completeLength, + options, + cancellationToken); + + internal Task MockCopyFromStreamAsync( + Stream stream, + long streamLength, + bool overwrite, + long completeLength, + StorageResourceWriteToOffsetOptions options = null, + CancellationToken cancellationToken = default) + => CopyFromStreamAsync( + stream, + streamLength, + overwrite, + completeLength, + options, + cancellationToken); + + internal Task MockCopyFromUriAsync( + StorageResourceItem sourceResource, + bool overwrite, + long completeLength, + StorageResourceCopyFromUriOptions options = null, + CancellationToken cancellationToken = default) + => CopyFromUriAsync( + sourceResource, + overwrite, + completeLength, + options, + cancellationToken); + + internal Task MockDeleteIfExistsAsync(CancellationToken cancellationToken = default) + => DeleteIfExistsAsync(cancellationToken); + + internal Task MockGetCopyAuthorizationHeaderAsync(CancellationToken cancellationToken = default) + => MockGetCopyAuthorizationHeaderAsync(cancellationToken); + + internal Task MockGetPropertiesAsync(CancellationToken token = default) + => GetPropertiesAsync(token); + + internal Task MockReadStreamAsync( + long position = 0, + long? length = null, + CancellationToken cancellationToken = default) + => ReadStreamAsync(position, length, cancellationToken); } } diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs index 434ebb3576f65..7f973b9e8ffaf 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs @@ -3,13 +3,450 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Azure.Core.TestFramework; +using Azure.Storage.Files.Shares; +using Azure.Storage.Files.Shares.Models; +using Azure.Storage.Test; +using Azure.Storage.Test.Shared; +using Moq; +using NUnit.Framework; namespace Azure.Storage.DataMovement.Files.Shares.Tests { public class ShareFileResourceTests { + public static byte[] GetRandomBuffer(long size, Random random = null) + { + random ??= new Random(Environment.TickCount); + var buffer = new byte[size]; + random.NextBytes(buffer); + return buffer; + } + + [Test] + public void Ctor_PublicUri() + { + // Arrange + Uri uri = new Uri("https://storageaccount.blob.core.windows.net/"); + ShareFileClient fileClient = new ShareFileClient(uri); + MockShareFileStorageResource storageResource = new(fileClient); + + // Assert + Assert.AreEqual(uri, storageResource.Uri.AbsoluteUri); + } + + [Test] + public async Task ReadStreamAsync() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + int length = 1024; + string contentRange = "bytes 0-1024/1024"; + var data = GetRandomBuffer(length); + using (var stream = new MemoryStream(data)) + { + mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + FilesModelFactory.StorageFileDownloadInfo( + content: stream, + contentLength: length, + contentRange: contentRange), + new MockResponse(201)))); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act + StorageResourceReadStreamResult result = await storageResource.MockReadStreamAsync(); + + // Assert + Assert.NotNull(result); + TestHelper.AssertSequenceEqual(data, result.Content.AsBytes().ToArray()); + } + } + + [Test] + public async Task ReadStreamAsync_Position() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + int position = 5; + int length = 1024; + string contentRange = "bytes 0-1024/1024"; + var data = GetRandomBuffer(length); + using (var stream = new MemoryStream(data)) + { + mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + FilesModelFactory.StorageFileDownloadInfo( + content: stream, + contentLength: length, + contentRange: contentRange), + new MockResponse(201)))); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act + StorageResourceReadStreamResult result = await storageResource.MockReadStreamAsync(); + + // Assert + Assert.NotNull(result); + byte[] dataAt5 = new byte[data.Length - position]; + Array.Copy(data, position, dataAt5, 0, data.Length - position); + TestHelper.AssertSequenceEqual(data, result.Content.AsBytes().ToArray()); + } + } + + [Test] + public async Task ReadStreamAsync_Error() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + + mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act without creating the blob + await TestHelper.AssertExpectedExceptionAsync( + storageResource.MockReadStreamAsync(), + e => + { + Assert.AreEqual("ResourceNotFound", e.ErrorCode); + }); + } + + [Test] + public async Task CopyFromStreamAsync() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + int length = 1024; + string contentRange = "bytes 0-1024/1024"; + var data = GetRandomBuffer(length); + using (var stream = new MemoryStream(data)) + { + using var fileContentStream = new MemoryStream(); + mock.Setup(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback( + async (uploadedstream, options, token) => + { + await uploadedstream.CopyToAsync(fileContentStream).ConfigureAwait(false); + fileContentStream.Position = 0; + }) + .Returns(Task.FromResult(Response.FromValue( + ShareModelFactory.ShareFileUploadInfo( + eTag: new ETag("eTag"), + lastModified: DateTimeOffset.UtcNow, + contentHash: default, + isServerEncrypted: false), + new MockResponse(200)))); + + mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + FilesModelFactory.StorageFileDownloadInfo( + content: fileContentStream, + contentLength: length, + contentRange: contentRange), + new MockResponse(201)))); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act + await storageResource.MockCopyFromStreamAsync( + stream: stream, + streamLength: length, + overwrite: false, + completeLength: length); + + // Assert + ShareFileDownloadInfo result = await mock.Object.DownloadAsync(); + + Assert.NotNull(result); + TestHelper.AssertSequenceEqual(data, result.Content.AsBytes().ToArray()); + } + } + + [Test] + public async Task CopyFromStreamAsync_Position() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + int position = 5; + int length = 1024; + string contentRange = "bytes 0-1029/1029"; + var data = GetRandomBuffer(length); + using (var stream = new MemoryStream(data)) + { + using var fileContentStream = new MemoryStream(); + mock.Setup(b => b.UploadRangeAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback( + async (range, uploadedstream, options, token) => + { + fileContentStream.Position = 5; + await uploadedstream.CopyToAsync(fileContentStream).ConfigureAwait(false); + fileContentStream.Position = 0; + }) + .Returns(Task.FromResult(Response.FromValue( + ShareModelFactory.ShareFileUploadInfo( + eTag: new ETag("eTag"), + lastModified: DateTimeOffset.UtcNow, + contentHash: default, + isServerEncrypted: false), + new MockResponse(200)))); + + mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + FilesModelFactory.StorageFileDownloadInfo( + content: fileContentStream, + contentLength: length + position, + contentRange: contentRange), + new MockResponse(201)))); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act + await storageResource.MockCopyFromStreamAsync( + stream: stream, + streamLength: length, + overwrite: false, + completeLength: length, + options: new StorageResourceWriteToOffsetOptions() { Position = position }); + + // Assert + ShareFileDownloadInfo result = await mock.Object.DownloadAsync(); + Assert.NotNull(result); + + byte[] dataAt5 = new byte[data.Length + position]; + Array.Copy(data, 0, dataAt5, 5, length); + TestHelper.AssertSequenceEqual(dataAt5, result.Content.AsBytes().ToArray()); + } + } + + [Test] + public async Task CopyFromStreamAsync_Error() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + + mock.Setup(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act + int length = 1024; + var data = GetRandomBuffer(length); + using (var stream = new MemoryStream(data)) + { + await TestHelper.AssertExpectedExceptionAsync( + storageResource.MockCopyFromStreamAsync(stream, length, false, length), + e => + { + Assert.AreEqual("ResourceNotFound", e.ErrorCode); + }); + } + } + + [Test] + public async Task CopyFromUriAsync() + { + // Arrange + Mock mockSource = new( + new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), + new ShareClientOptions()); + MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + + Mock mockDestination = new( + new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), + new ShareClientOptions()); + + mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + ShareModelFactory.ShareFileUploadInfo( + eTag: new ETag("eTag"), + lastModified: DateTimeOffset.UtcNow, + contentHash: default, + isServerEncrypted: false), + new MockResponse(200)))); + MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + + int length = 1024; + await destinationResource.MockCopyFromUriAsync(sourceResource, false, length); + } + + [Test] + public async Task CopyFromUriAsync_Error() + { + // Arrange + Mock mockSource = new( + new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), + new ShareClientOptions()); + MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + + Mock mockDestination = new( + new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), + new ShareClientOptions()); + + mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); + MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + + // Act + int length = 1024; + await TestHelper.AssertExpectedExceptionAsync( + destinationResource.MockCopyFromUriAsync(sourceResource, false, length), + e => + { + Assert.AreEqual("ResourceNotFound", e.ErrorCode); + }); + } + + [Test] + public async Task CopyBlockFromUriAsync() + { + // Arrange + Mock mockSource = new( + new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), + new ShareClientOptions()); + MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + + Mock mockDestination = new( + new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), + new ShareClientOptions()); + + mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + ShareModelFactory.ShareFileUploadInfo( + eTag: new ETag("eTag"), + lastModified: DateTimeOffset.UtcNow, + contentHash: default, + isServerEncrypted: false), + new MockResponse(200)))); + MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + + int length = 1024; + await destinationResource.MockCopyFromUriAsync(sourceResource, false, length); + + // Act + await destinationResource.MockCopyBlockFromUriAsync( + sourceResource: sourceResource, + overwrite: false, + range: new HttpRange(0, length), + completeLength: length); + } + + [Test] + public async Task CopyBlockFromUriAsync_Error() + { + // Arrange + Mock mockSource = new( + new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), + new ShareClientOptions()); + MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + + Mock mockDestination = new( + new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), + new ShareClientOptions()); + + mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); + MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + + // Act + int length = 1024; + await TestHelper.AssertExpectedExceptionAsync( + destinationResource.MockCopyBlockFromUriAsync(sourceResource, new HttpRange(0, length), false, length), + e => + { + Assert.AreEqual("ResourceNotFound", e.ErrorCode); + }); + } + + [Test] + public async Task GetPropertiesAsync() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + + long length = 1024; + mock.Setup(b => b.GetPropertiesAsync(It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(Response.FromValue( + FilesModelFactory.StorageFileProperties( + lastModified: DateTime.MinValue, + metadata: default, + contentLength: length, + contentType: default, + eTag: new ETag("etag"), + contentHash: default, + contentEncoding: default, + cacheControl: default, + contentDisposition: default, + contentLanguage: default, + copyCompletedOn: DateTimeOffset.MinValue, + copyStatusDescription: default, + copyId: default, + copyProgress: default, + copySource: "https://storageaccount.file.core.windows.net/container/file2", + copyStatus: CopyStatus.Success, + isServerEncrypted: false, + fileAttributes: default, + fileCreationTime: DateTimeOffset.MinValue, + fileLastWriteTime: DateTimeOffset.MinValue, + fileChangeTime: DateTimeOffset.MinValue, + filePermissionKey: default, + fileId: default, + fileParentId: default), + new MockResponse(200)))); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act + StorageResourceProperties result = await storageResource.MockGetPropertiesAsync(); + + // Assert + Assert.NotNull(result); + } + + [Test] + public async Task GetPropertiesAsync_Error() + { + // Arrange + Mock mock = new( + new Uri("https://storageaccount.file.core.windows.net/container/file"), + new ShareClientOptions()); + + mock.Setup(b => b.GetPropertiesAsync(It.IsAny(), It.IsAny())) + .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); + + MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + + // Act without creating the blob + await TestHelper.AssertExpectedExceptionAsync( + storageResource.MockGetPropertiesAsync(), + e => + { + Assert.AreEqual("ResourceNotFound", e.ErrorCode); + }); + } } } diff --git a/sdk/storage/Azure.Storage.DataMovement/src/StorageResourceWriteToOffsetOptions.cs b/sdk/storage/Azure.Storage.DataMovement/src/StorageResourceWriteToOffsetOptions.cs index 3f4d199bb61c7..b4ecdae36a7bd 100644 --- a/sdk/storage/Azure.Storage.DataMovement/src/StorageResourceWriteToOffsetOptions.cs +++ b/sdk/storage/Azure.Storage.DataMovement/src/StorageResourceWriteToOffsetOptions.cs @@ -17,11 +17,11 @@ public class StorageResourceWriteToOffsetOptions /// /// Applies only to block blobs. /// - public string BlockId { get; internal set; } + public string BlockId { get; set; } /// /// Optional. Specifies the position to write to. Will default to 0 if not specified. /// - public long? Position { get; internal set; } + public long? Position { get; set; } } } From b1d2655de3a2ebe5874027c619dc367945b45cee Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Mon, 25 Sep 2023 10:45:39 -0700 Subject: [PATCH 3/8] Export API --- .../Azure.Storage.DataMovement.Files.Shares.net6.0.cs | 11 +++++++++++ ...torage.DataMovement.Files.Shares.netstandard2.0.cs | 11 +++++++++++ .../api/Azure.Storage.DataMovement.net6.0.cs | 4 ++-- .../api/Azure.Storage.DataMovement.netstandard2.0.cs | 4 ++-- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs index dfa95cd1db82d..1d35114f198b0 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs @@ -23,5 +23,16 @@ public ShareFilesStorageResourceProvider(Azure.Storage.StorageSharedKeyCredentia public partial class ShareFileStorageResourceOptions { public ShareFileStorageResourceOptions() { } + public bool? Archive { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareFileRequestConditions DestinationConditions { get { throw null; } set { } } + public System.Collections.Generic.IDictionary DirectoryMetadata { get { throw null; } set { } } + public Azure.Storage.DownloadTransferValidationOptions DownloadTransferValidationOptions { get { throw null; } set { } } + public System.Collections.Generic.IDictionary FileMetadata { get { throw null; } set { } } + public string FilePermissions { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareFileHttpHeaders HttpHeaders { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareProtocols? Protocols { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.FileSmbProperties SmbProperties { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareFileRequestConditions SourceConditions { get { throw null; } set { } } + public Azure.Storage.UploadTransferValidationOptions UploadTransferValidationOptions { get { throw null; } set { } } } } diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs index dfa95cd1db82d..1d35114f198b0 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs @@ -23,5 +23,16 @@ public ShareFilesStorageResourceProvider(Azure.Storage.StorageSharedKeyCredentia public partial class ShareFileStorageResourceOptions { public ShareFileStorageResourceOptions() { } + public bool? Archive { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareFileRequestConditions DestinationConditions { get { throw null; } set { } } + public System.Collections.Generic.IDictionary DirectoryMetadata { get { throw null; } set { } } + public Azure.Storage.DownloadTransferValidationOptions DownloadTransferValidationOptions { get { throw null; } set { } } + public System.Collections.Generic.IDictionary FileMetadata { get { throw null; } set { } } + public string FilePermissions { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareFileHttpHeaders HttpHeaders { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareProtocols? Protocols { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.FileSmbProperties SmbProperties { get { throw null; } set { } } + public Azure.Storage.Files.Shares.Models.ShareFileRequestConditions SourceConditions { get { throw null; } set { } } + public Azure.Storage.UploadTransferValidationOptions UploadTransferValidationOptions { get { throw null; } set { } } } } diff --git a/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.net6.0.cs b/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.net6.0.cs index febae2eec9d73..ee62763d45fad 100644 --- a/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.net6.0.cs +++ b/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.net6.0.cs @@ -178,8 +178,8 @@ public StorageResourceReadStreamResult(System.IO.Stream content, string contentR public partial class StorageResourceWriteToOffsetOptions { public StorageResourceWriteToOffsetOptions() { } - public string BlockId { get { throw null; } } - public long? Position { get { throw null; } } + public string BlockId { get { throw null; } set { } } + public long? Position { get { throw null; } set { } } } public partial class TransferCheckpointStoreOptions { diff --git a/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.netstandard2.0.cs b/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.netstandard2.0.cs index febae2eec9d73..ee62763d45fad 100644 --- a/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.netstandard2.0.cs +++ b/sdk/storage/Azure.Storage.DataMovement/api/Azure.Storage.DataMovement.netstandard2.0.cs @@ -178,8 +178,8 @@ public StorageResourceReadStreamResult(System.IO.Stream content, string contentR public partial class StorageResourceWriteToOffsetOptions { public StorageResourceWriteToOffsetOptions() { } - public string BlockId { get { throw null; } } - public long? Position { get { throw null; } } + public string BlockId { get { throw null; } set { } } + public long? Position { get { throw null; } set { } } } public partial class TransferCheckpointStoreOptions { From 89a66ac6b2c421efd9def86e199c63234e6c364f Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Mon, 25 Sep 2023 10:50:58 -0700 Subject: [PATCH 4/8] Attempt to fix double dependency files in tests --- .../Azure.Storage.DataMovement.Files.Shares.Tests.csproj | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj index 8b5975f5f8ad1..eeca6c590db6f 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/Azure.Storage.DataMovement.Files.Shares.Tests.csproj @@ -20,11 +20,6 @@ - - - - - From d33b7feb2e275c7782bb2d67f3126231b3bd571d Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Mon, 25 Sep 2023 14:57:05 -0700 Subject: [PATCH 5/8] Addressing PR comments; Added StorageResourceItemInternal --- ...e.Storage.DataMovement.Files.Shares.csproj | 1 + .../src/DataMovementShareConstants.cs | 17 +++++++++ .../src/ShareFileStorageResource.cs | 5 +-- .../tests/ShareFileResourceTests.cs | 37 +++++++++---------- .../src/Shared/DataMovementConstants.cs | 8 ---- .../Shared/StorageResourceItemInternal.cs} | 21 ++--------- 6 files changed, 40 insertions(+), 49 deletions(-) create mode 100644 sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementShareConstants.cs rename sdk/storage/{Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs => Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs} (78%) diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj index fc7f9772f6afd..e7a512025ccbe 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/Azure.Storage.DataMovement.Files.Shares.csproj @@ -33,6 +33,7 @@ + diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementShareConstants.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementShareConstants.cs new file mode 100644 index 0000000000000..a0c773c0901df --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/DataMovementShareConstants.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Azure.Storage.DataMovement.Files.Shares +{ + internal class DataMovementShareConstants + { + public const int KB = 1024; + public const int MB = KB * 1024; + + internal const int MaxRange = 4 * MB; + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs index 9d2a27f16c389..dd06ea2e7bedc 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareFileStorageResource.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using Azure.Core; @@ -12,7 +11,7 @@ namespace Azure.Storage.DataMovement.Files.Shares { - internal class ShareFileStorageResource : StorageResourceItem + internal class ShareFileStorageResource : StorageResourceItemInternal { internal long? _length; internal readonly ShareFileStorageResourceOptions _options; @@ -26,7 +25,7 @@ internal class ShareFileStorageResource : StorageResourceItem protected override DataTransferOrder TransferType => DataTransferOrder.Sequential; - protected override long MaxChunkSize => DataMovementConstants.Share.MaxRange; + protected override long MaxChunkSize => DataMovementShareConstants.MaxRange; protected override long? Length => _length; diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs index 7f973b9e8ffaf..e4a43276c493d 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs @@ -2,17 +2,14 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; using Azure.Core.TestFramework; using Azure.Storage.Files.Shares; using Azure.Storage.Files.Shares.Models; using Azure.Storage.Test; -using Azure.Storage.Test.Shared; using Moq; using NUnit.Framework; @@ -34,7 +31,7 @@ public void Ctor_PublicUri() // Arrange Uri uri = new Uri("https://storageaccount.blob.core.windows.net/"); ShareFileClient fileClient = new ShareFileClient(uri); - MockShareFileStorageResource storageResource = new(fileClient); + ShareFileStorageResource storageResource = new(fileClient); // Assert Assert.AreEqual(uri, storageResource.Uri.AbsoluteUri); @@ -60,7 +57,7 @@ public async Task ReadStreamAsync() contentRange: contentRange), new MockResponse(201)))); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act StorageResourceReadStreamResult result = await storageResource.MockReadStreamAsync(); @@ -92,7 +89,7 @@ public async Task ReadStreamAsync_Position() contentRange: contentRange), new MockResponse(201)))); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act StorageResourceReadStreamResult result = await storageResource.MockReadStreamAsync(); @@ -116,7 +113,7 @@ public async Task ReadStreamAsync_Error() mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act without creating the blob await TestHelper.AssertExpectedExceptionAsync( @@ -163,7 +160,7 @@ public async Task CopyFromStreamAsync() contentRange: contentRange), new MockResponse(201)))); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act await storageResource.MockCopyFromStreamAsync( @@ -218,7 +215,7 @@ public async Task CopyFromStreamAsync_Position() contentRange: contentRange), new MockResponse(201)))); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act await storageResource.MockCopyFromStreamAsync( @@ -249,7 +246,7 @@ public async Task CopyFromStreamAsync_Error() mock.Setup(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act int length = 1024; @@ -272,7 +269,7 @@ public async Task CopyFromUriAsync() Mock mockSource = new( new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), new ShareClientOptions()); - MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), @@ -286,7 +283,7 @@ public async Task CopyFromUriAsync() contentHash: default, isServerEncrypted: false), new MockResponse(200)))); - MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); int length = 1024; await destinationResource.MockCopyFromUriAsync(sourceResource, false, length); @@ -299,7 +296,7 @@ public async Task CopyFromUriAsync_Error() Mock mockSource = new( new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), new ShareClientOptions()); - MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), @@ -307,7 +304,7 @@ public async Task CopyFromUriAsync_Error() mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); - MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); // Act int length = 1024; @@ -326,7 +323,7 @@ public async Task CopyBlockFromUriAsync() Mock mockSource = new( new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), new ShareClientOptions()); - MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), @@ -340,7 +337,7 @@ public async Task CopyBlockFromUriAsync() contentHash: default, isServerEncrypted: false), new MockResponse(200)))); - MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); int length = 1024; await destinationResource.MockCopyFromUriAsync(sourceResource, false, length); @@ -360,7 +357,7 @@ public async Task CopyBlockFromUriAsync_Error() Mock mockSource = new( new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), new ShareClientOptions()); - MockShareFileStorageResource sourceResource = new MockShareFileStorageResource(mockSource.Object); + ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), @@ -368,7 +365,7 @@ public async Task CopyBlockFromUriAsync_Error() mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); - MockShareFileStorageResource destinationResource = new MockShareFileStorageResource(mockDestination.Object); + ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); // Act int length = 1024; @@ -418,7 +415,7 @@ public async Task GetPropertiesAsync() fileParentId: default), new MockResponse(200)))); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act StorageResourceProperties result = await storageResource.MockGetPropertiesAsync(); @@ -438,7 +435,7 @@ public async Task GetPropertiesAsync_Error() mock.Setup(b => b.GetPropertiesAsync(It.IsAny(), It.IsAny())) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); - MockShareFileStorageResource storageResource = new MockShareFileStorageResource(mock.Object); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act without creating the blob await TestHelper.AssertExpectedExceptionAsync( diff --git a/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs b/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs index 8fe01227a097c..8ee2f90917d6d 100644 --- a/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs +++ b/sdk/storage/Azure.Storage.DataMovement/src/Shared/DataMovementConstants.cs @@ -7,9 +7,6 @@ namespace Azure.Storage.DataMovement { internal class DataMovementConstants { - public const int KB = 1024; - public const int MB = KB * 1024; - /// /// Constants of the Data Movement library /// @@ -270,10 +267,5 @@ internal static class ErrorCode internal static readonly string[] CannotOverwrite = { "BlobAlreadyExists", "Cannot overwrite file." }; internal static readonly string[] AccessDenied = { "AuthenticationFailed", "AuthorizationFailure", "access denied" }; } - - internal static class Share - { - internal const int MaxRange = 4 * MB; - } } } diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs b/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs similarity index 78% rename from sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs rename to sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs index ab0e38cfa2dfc..b06faf1831675 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/MockShareFileStorageResource.cs +++ b/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs @@ -4,26 +4,11 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -using Azure.Storage.Files.Shares; -namespace Azure.Storage.DataMovement.Files.Shares.Tests +namespace Azure.Storage.DataMovement { - internal class MockShareFileStorageResource : ShareFileStorageResource + internal abstract class StorageResourceItemInternal : StorageResourceItem { - public MockShareFileStorageResource( - ShareFileClient fileClient, - ShareFileStorageResourceOptions options = null) : base(fileClient, options) - { - } - - internal MockShareFileStorageResource( - ShareFileClient fileClient, - long? length, - ETag? etagLock, - ShareFileStorageResourceOptions options = null) : base(fileClient, length, etagLock, options) - { - } - internal Task MockCompleteTransferAsync(bool overwrite, CancellationToken cancellationToken = default) => CompleteTransferAsync(overwrite, cancellationToken); @@ -74,7 +59,7 @@ internal Task MockDeleteIfExistsAsync(CancellationToken cancellationToken => DeleteIfExistsAsync(cancellationToken); internal Task MockGetCopyAuthorizationHeaderAsync(CancellationToken cancellationToken = default) - => MockGetCopyAuthorizationHeaderAsync(cancellationToken); + => GetCopyAuthorizationHeaderAsync(cancellationToken); internal Task MockGetPropertiesAsync(CancellationToken token = default) => GetPropertiesAsync(token); From adaa91f39f607fa741790b482b913374e9d5ab08 Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Mon, 25 Sep 2023 19:26:29 -0700 Subject: [PATCH 6/8] Rename internal methods --- .../tests/ShareFileResourceTests.cs | 26 +++++++++---------- .../src/Shared/StorageResourceItemInternal.cs | 16 ++++++------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs index e4a43276c493d..10701554f3f19 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs @@ -60,7 +60,7 @@ public async Task ReadStreamAsync() ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act - StorageResourceReadStreamResult result = await storageResource.MockReadStreamAsync(); + StorageResourceReadStreamResult result = await storageResource.ReadStreamInternalAsync(); // Assert Assert.NotNull(result); @@ -92,7 +92,7 @@ public async Task ReadStreamAsync_Position() ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act - StorageResourceReadStreamResult result = await storageResource.MockReadStreamAsync(); + StorageResourceReadStreamResult result = await storageResource.ReadStreamInternalAsync(); // Assert Assert.NotNull(result); @@ -117,7 +117,7 @@ public async Task ReadStreamAsync_Error() // Act without creating the blob await TestHelper.AssertExpectedExceptionAsync( - storageResource.MockReadStreamAsync(), + storageResource.ReadStreamInternalAsync(), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); @@ -163,7 +163,7 @@ public async Task CopyFromStreamAsync() ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act - await storageResource.MockCopyFromStreamAsync( + await storageResource.CopyFromStreamInternalAsync( stream: stream, streamLength: length, overwrite: false, @@ -218,7 +218,7 @@ public async Task CopyFromStreamAsync_Position() ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act - await storageResource.MockCopyFromStreamAsync( + await storageResource.CopyFromStreamInternalAsync( stream: stream, streamLength: length, overwrite: false, @@ -254,7 +254,7 @@ public async Task CopyFromStreamAsync_Error() using (var stream = new MemoryStream(data)) { await TestHelper.AssertExpectedExceptionAsync( - storageResource.MockCopyFromStreamAsync(stream, length, false, length), + storageResource.CopyFromStreamInternalAsync(stream, length, false, length), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); @@ -286,7 +286,7 @@ public async Task CopyFromUriAsync() ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); int length = 1024; - await destinationResource.MockCopyFromUriAsync(sourceResource, false, length); + await destinationResource.CopyFromUriInternalAsync(sourceResource, false, length); } [Test] @@ -309,7 +309,7 @@ public async Task CopyFromUriAsync_Error() // Act int length = 1024; await TestHelper.AssertExpectedExceptionAsync( - destinationResource.MockCopyFromUriAsync(sourceResource, false, length), + destinationResource.CopyFromUriInternalAsync(sourceResource, false, length), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); @@ -340,10 +340,10 @@ public async Task CopyBlockFromUriAsync() ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); int length = 1024; - await destinationResource.MockCopyFromUriAsync(sourceResource, false, length); + await destinationResource.CopyFromUriInternalAsync(sourceResource, false, length); // Act - await destinationResource.MockCopyBlockFromUriAsync( + await destinationResource.CopyBlockFromUriInternalAsync( sourceResource: sourceResource, overwrite: false, range: new HttpRange(0, length), @@ -370,7 +370,7 @@ public async Task CopyBlockFromUriAsync_Error() // Act int length = 1024; await TestHelper.AssertExpectedExceptionAsync( - destinationResource.MockCopyBlockFromUriAsync(sourceResource, new HttpRange(0, length), false, length), + destinationResource.CopyBlockFromUriInternalAsync(sourceResource, new HttpRange(0, length), false, length), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); @@ -418,7 +418,7 @@ public async Task GetPropertiesAsync() ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); // Act - StorageResourceProperties result = await storageResource.MockGetPropertiesAsync(); + StorageResourceProperties result = await storageResource.GetPropertiesInternalAsync(); // Assert Assert.NotNull(result); @@ -439,7 +439,7 @@ public async Task GetPropertiesAsync_Error() // Act without creating the blob await TestHelper.AssertExpectedExceptionAsync( - storageResource.MockGetPropertiesAsync(), + storageResource.GetPropertiesInternalAsync(), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); diff --git a/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs b/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs index b06faf1831675..6f442bb265d57 100644 --- a/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs +++ b/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs @@ -9,10 +9,10 @@ namespace Azure.Storage.DataMovement { internal abstract class StorageResourceItemInternal : StorageResourceItem { - internal Task MockCompleteTransferAsync(bool overwrite, CancellationToken cancellationToken = default) + internal Task CompleteTransferInternalAsync(bool overwrite, CancellationToken cancellationToken = default) => CompleteTransferAsync(overwrite, cancellationToken); - internal Task MockCopyBlockFromUriAsync( + internal Task CopyBlockFromUriInternalAsync( StorageResourceItem sourceResource, HttpRange range, bool overwrite, @@ -27,7 +27,7 @@ internal Task MockCopyBlockFromUriAsync( options, cancellationToken); - internal Task MockCopyFromStreamAsync( + internal Task CopyFromStreamInternalAsync( Stream stream, long streamLength, bool overwrite, @@ -42,7 +42,7 @@ internal Task MockCopyFromStreamAsync( options, cancellationToken); - internal Task MockCopyFromUriAsync( + internal Task CopyFromUriInternalAsync( StorageResourceItem sourceResource, bool overwrite, long completeLength, @@ -55,16 +55,16 @@ internal Task MockCopyFromUriAsync( options, cancellationToken); - internal Task MockDeleteIfExistsAsync(CancellationToken cancellationToken = default) + internal Task DeleteIfExistsInternalAsync(CancellationToken cancellationToken = default) => DeleteIfExistsAsync(cancellationToken); - internal Task MockGetCopyAuthorizationHeaderAsync(CancellationToken cancellationToken = default) + internal Task GetCopyAuthorizationHeaderInternalAsync(CancellationToken cancellationToken = default) => GetCopyAuthorizationHeaderAsync(cancellationToken); - internal Task MockGetPropertiesAsync(CancellationToken token = default) + internal Task GetPropertiesInternalAsync(CancellationToken token = default) => GetPropertiesAsync(token); - internal Task MockReadStreamAsync( + internal Task ReadStreamInternalAsync( long position = 0, long? length = null, CancellationToken cancellationToken = default) From 0e84ef6dd338df390ad16e75f26974ea22bd18a5 Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Tue, 26 Sep 2023 10:28:47 -0700 Subject: [PATCH 7/8] PR Comments for tests --- .../tests/ShareFileResourceTests.cs | 275 +++++++++++------- .../src/Shared/StorageResourceItemInternal.cs | 3 + 2 files changed, 172 insertions(+), 106 deletions(-) diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs index 10701554f3f19..27b925acf10b8 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs @@ -64,8 +64,11 @@ public async Task ReadStreamAsync() // Assert Assert.NotNull(result); - TestHelper.AssertSequenceEqual(data, result.Content.AsBytes().ToArray()); + Assert.That(data, Is.EqualTo(result.Content.AsBytes().ToArray())); } + mock.Verify(b => b.DownloadAsync(It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] @@ -98,8 +101,11 @@ public async Task ReadStreamAsync_Position() Assert.NotNull(result); byte[] dataAt5 = new byte[data.Length - position]; Array.Copy(data, position, dataAt5, 0, data.Length - position); - TestHelper.AssertSequenceEqual(data, result.Content.AsBytes().ToArray()); + Assert.That(data, Is.EqualTo(result.Content.AsBytes().ToArray())); } + mock.Verify(b => b.DownloadAsync(It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] @@ -122,6 +128,9 @@ await TestHelper.AssertExpectedExceptionAsync( { Assert.AreEqual("ResourceNotFound", e.ErrorCode); }); + mock.Verify(b => b.DownloadAsync(It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] @@ -132,49 +141,37 @@ public async Task CopyFromStreamAsync() new Uri("https://storageaccount.file.core.windows.net/container/file"), new ShareClientOptions()); int length = 1024; - string contentRange = "bytes 0-1024/1024"; var data = GetRandomBuffer(length); - using (var stream = new MemoryStream(data)) - { - using var fileContentStream = new MemoryStream(); - mock.Setup(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .Callback( - async (uploadedstream, options, token) => - { - await uploadedstream.CopyToAsync(fileContentStream).ConfigureAwait(false); - fileContentStream.Position = 0; - }) - .Returns(Task.FromResult(Response.FromValue( - ShareModelFactory.ShareFileUploadInfo( - eTag: new ETag("eTag"), - lastModified: DateTimeOffset.UtcNow, - contentHash: default, - isServerEncrypted: false), - new MockResponse(200)))); - - mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + using var stream = new MemoryStream(data); + using var fileContentStream = new MemoryStream(); + mock.Setup(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback( + async (uploadedstream, options, token) => + { + await uploadedstream.CopyToAsync(fileContentStream).ConfigureAwait(false); + fileContentStream.Position = 0; + }) .Returns(Task.FromResult(Response.FromValue( - FilesModelFactory.StorageFileDownloadInfo( - content: fileContentStream, - contentLength: length, - contentRange: contentRange), - new MockResponse(201)))); - - ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); + ShareModelFactory.ShareFileUploadInfo( + eTag: new ETag("eTag"), + lastModified: DateTimeOffset.UtcNow, + contentHash: default, + isServerEncrypted: false), + new MockResponse(200)))); - // Act - await storageResource.CopyFromStreamInternalAsync( - stream: stream, - streamLength: length, - overwrite: false, - completeLength: length); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); - // Assert - ShareFileDownloadInfo result = await mock.Object.DownloadAsync(); + // Act + await storageResource.CopyFromStreamInternalAsync( + stream: stream, + streamLength: length, + overwrite: false, + completeLength: length); - Assert.NotNull(result); - TestHelper.AssertSequenceEqual(data, result.Content.AsBytes().ToArray()); - } + Assert.That(data, Is.EqualTo(fileContentStream.AsBytes().ToArray())); + mock.Verify(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] @@ -186,53 +183,42 @@ public async Task CopyFromStreamAsync_Position() new ShareClientOptions()); int position = 5; int length = 1024; - string contentRange = "bytes 0-1029/1029"; var data = GetRandomBuffer(length); - using (var stream = new MemoryStream(data)) - { - using var fileContentStream = new MemoryStream(); - mock.Setup(b => b.UploadRangeAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback( - async (range, uploadedstream, options, token) => - { - fileContentStream.Position = 5; - await uploadedstream.CopyToAsync(fileContentStream).ConfigureAwait(false); - fileContentStream.Position = 0; - }) - .Returns(Task.FromResult(Response.FromValue( - ShareModelFactory.ShareFileUploadInfo( - eTag: new ETag("eTag"), - lastModified: DateTimeOffset.UtcNow, - contentHash: default, - isServerEncrypted: false), - new MockResponse(200)))); - - mock.Setup(b => b.DownloadAsync(It.IsAny(), It.IsAny())) + using var stream = new MemoryStream(data); + using var fileContentStream = new MemoryStream(); + mock.Setup(b => b.UploadRangeAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback( + async (range, uploadedstream, options, token) => + { + fileContentStream.Position = 5; + await uploadedstream.CopyToAsync(fileContentStream).ConfigureAwait(false); + fileContentStream.Position = 0; + }) .Returns(Task.FromResult(Response.FromValue( - FilesModelFactory.StorageFileDownloadInfo( - content: fileContentStream, - contentLength: length + position, - contentRange: contentRange), - new MockResponse(201)))); - - ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); + ShareModelFactory.ShareFileUploadInfo( + eTag: new ETag("eTag"), + lastModified: DateTimeOffset.UtcNow, + contentHash: default, + isServerEncrypted: false), + new MockResponse(200)))); - // Act - await storageResource.CopyFromStreamInternalAsync( - stream: stream, - streamLength: length, - overwrite: false, - completeLength: length, - options: new StorageResourceWriteToOffsetOptions() { Position = position }); + ShareFileStorageResource storageResource = new ShareFileStorageResource(mock.Object); - // Assert - ShareFileDownloadInfo result = await mock.Object.DownloadAsync(); - Assert.NotNull(result); + // Act + await storageResource.CopyFromStreamInternalAsync( + stream: stream, + streamLength: length, + overwrite: false, + completeLength: length, + options: new StorageResourceWriteToOffsetOptions() { Position = position }); - byte[] dataAt5 = new byte[data.Length + position]; - Array.Copy(data, 0, dataAt5, 5, length); - TestHelper.AssertSequenceEqual(dataAt5, result.Content.AsBytes().ToArray()); - } + // Assert + byte[] dataAt5 = new byte[data.Length + position]; + Array.Copy(data, 0, dataAt5, 5, length); + Assert.That(dataAt5, Is.EqualTo(fileContentStream.AsBytes().ToArray())); + mock.Verify(b => b.UploadRangeAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] @@ -260,22 +246,33 @@ await TestHelper.AssertExpectedExceptionAsync( Assert.AreEqual("ResourceNotFound", e.ErrorCode); }); } + mock.Verify(b => b.UploadAsync(It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] public async Task CopyFromUriAsync() { // Arrange - Mock mockSource = new( - new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), - new ShareClientOptions()); - ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); + Mock sourceResource = new(); + sourceResource.Setup(b => b.Uri) + .Returns(new Uri("https://storageaccount.file.core.windows.net/container/sourcefile")); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); + Uri passedSourceUri = default; + HttpRange passedRange = default; + HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((sourceUri, range, sourceRange, options, token) => + { + passedSourceUri = sourceUri; + passedRange = range; + passedSourceRange = sourceRange; + }) .Returns(Task.FromResult(Response.FromValue( ShareModelFactory.ShareFileUploadInfo( eTag: new ETag("eTag"), @@ -286,50 +283,85 @@ public async Task CopyFromUriAsync() ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); int length = 1024; - await destinationResource.CopyFromUriInternalAsync(sourceResource, false, length); + await destinationResource.CopyFromUriInternalAsync(sourceResource.Object, false, length); + + sourceResource.Verify(b => b.Uri, Times.Once()); + sourceResource.VerifyNoOtherCalls(); + mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); + Assert.AreEqual(new HttpRange(0, length), passedRange); + Assert.AreEqual(new HttpRange(0, length), passedSourceRange); + mockDestination.VerifyNoOtherCalls(); } [Test] public async Task CopyFromUriAsync_Error() { // Arrange - Mock mockSource = new( - new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), - new ShareClientOptions()); - ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); + Mock sourceResource = new(); + sourceResource.Setup(b => b.Uri) + .Returns(new Uri("https://storageaccount.file.core.windows.net/container/sourcefile")); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); + Uri passedSourceUri = default; + HttpRange passedRange = default; + HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((sourceUri, range, sourceRange, options, token) => + { + passedSourceUri = sourceUri; + passedRange = range; + passedSourceRange = sourceRange; + }) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); // Act int length = 1024; await TestHelper.AssertExpectedExceptionAsync( - destinationResource.CopyFromUriInternalAsync(sourceResource, false, length), + destinationResource.CopyFromUriInternalAsync(sourceResource.Object, false, length), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); }); + + sourceResource.Verify(b => b.Uri, Times.Once()); + sourceResource.VerifyNoOtherCalls(); + mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + mockDestination.VerifyNoOtherCalls(); + Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); + Assert.AreEqual(new HttpRange(0, length), passedRange); + Assert.AreEqual(new HttpRange(0, length), passedSourceRange); } [Test] public async Task CopyBlockFromUriAsync() { // Arrange - Mock mockSource = new( - new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), - new ShareClientOptions()); - ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); + int length = 1024; + Mock sourceResource = new(); + sourceResource.Setup(b => b.Uri) + .Returns(new Uri("https://storageaccount.file.core.windows.net/container/sourcefile")); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); + Uri passedSourceUri = default; + HttpRange passedRange = default; + HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((sourceUri, range, sourceRange, options, token) => + { + passedSourceUri = sourceUri; + passedRange = range; + passedSourceRange = sourceRange; + }) .Returns(Task.FromResult(Response.FromValue( ShareModelFactory.ShareFileUploadInfo( eTag: new ETag("eTag"), @@ -339,42 +371,65 @@ public async Task CopyBlockFromUriAsync() new MockResponse(200)))); ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); - int length = 1024; - await destinationResource.CopyFromUriInternalAsync(sourceResource, false, length); - // Act await destinationResource.CopyBlockFromUriInternalAsync( - sourceResource: sourceResource, + sourceResource: sourceResource.Object, overwrite: false, range: new HttpRange(0, length), completeLength: length); + + sourceResource.Verify(b => b.Uri, Times.Once()); + sourceResource.VerifyNoOtherCalls(); + mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + mockDestination.VerifyNoOtherCalls(); + Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); + Assert.AreEqual(new HttpRange(0, length), passedRange); + Assert.AreEqual(new HttpRange(0, length), passedSourceRange); } [Test] public async Task CopyBlockFromUriAsync_Error() { // Arrange - Mock mockSource = new( - new Uri("https://storageaccount.file.core.windows.net/container/sourcefile"), - new ShareClientOptions()); - ShareFileStorageResource sourceResource = new ShareFileStorageResource(mockSource.Object); + Mock sourceResource = new(); + sourceResource.Setup(b => b.Uri) + .Returns(new Uri("https://storageaccount.file.core.windows.net/container/sourcefile")); Mock mockDestination = new( new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); + Uri passedSourceUri = default; + HttpRange passedRange = default; + HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((sourceUri, range, sourceRange, options, token) => + { + passedSourceUri = sourceUri; + passedRange = range; + passedSourceRange = sourceRange; + }) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); // Act int length = 1024; await TestHelper.AssertExpectedExceptionAsync( - destinationResource.CopyBlockFromUriInternalAsync(sourceResource, new HttpRange(0, length), false, length), + destinationResource.CopyBlockFromUriInternalAsync(sourceResource.Object, new HttpRange(0, length), false, length), e => { Assert.AreEqual("ResourceNotFound", e.ErrorCode); }); + + sourceResource.Verify(b => b.Uri, Times.Once()); + sourceResource.VerifyNoOtherCalls(); + mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once()); + mockDestination.VerifyNoOtherCalls(); + Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); + Assert.AreEqual(new HttpRange(0, length), passedRange); + Assert.AreEqual(new HttpRange(0, length), passedSourceRange); } [Test] @@ -386,6 +441,7 @@ public async Task GetPropertiesAsync() new ShareClientOptions()); long length = 1024; + string source = "https://storageaccount.file.core.windows.net/container/file2"; mock.Setup(b => b.GetPropertiesAsync(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(Response.FromValue( FilesModelFactory.StorageFileProperties( @@ -403,7 +459,7 @@ public async Task GetPropertiesAsync() copyStatusDescription: default, copyId: default, copyProgress: default, - copySource: "https://storageaccount.file.core.windows.net/container/file2", + copySource: source, copyStatus: CopyStatus.Success, isServerEncrypted: false, fileAttributes: default, @@ -419,9 +475,13 @@ public async Task GetPropertiesAsync() // Act StorageResourceProperties result = await storageResource.GetPropertiesInternalAsync(); + Mock properties = new Mock(result); // Assert Assert.NotNull(result); + mock.Verify(b => b.GetPropertiesAsync(It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } [Test] @@ -444,6 +504,9 @@ await TestHelper.AssertExpectedExceptionAsync( { Assert.AreEqual("ResourceNotFound", e.ErrorCode); }); + mock.Verify(b => b.GetPropertiesAsync(It.IsAny(), It.IsAny()), + Times.Once()); + mock.VerifyNoOtherCalls(); } } } diff --git a/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs b/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs index 6f442bb265d57..9314bdd4e43a9 100644 --- a/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs +++ b/sdk/storage/Azure.Storage.DataMovement/src/Shared/StorageResourceItemInternal.cs @@ -7,6 +7,9 @@ namespace Azure.Storage.DataMovement { + /// + /// This is used internally for testing purposes. It is shared within the test packages. + /// internal abstract class StorageResourceItemInternal : StorageResourceItem { internal Task CompleteTransferInternalAsync(bool overwrite, CancellationToken cancellationToken = default) From d9400e0bf4b8c70c5565cb6be99fc80972496b4f Mon Sep 17 00:00:00 2001 From: Amanda Nguyen Date: Tue, 26 Sep 2023 11:15:10 -0700 Subject: [PATCH 8/8] CHange out verify parameters with the mock verify method --- .../tests/ShareFileResourceTests.cs | 76 ++++++------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs index 27b925acf10b8..fd2bc19fc5968 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareFileResourceTests.cs @@ -263,16 +263,7 @@ public async Task CopyFromUriAsync() new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); - Uri passedSourceUri = default; - HttpRange passedRange = default; - HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((sourceUri, range, sourceRange, options, token) => - { - passedSourceUri = sourceUri; - passedRange = range; - passedSourceRange = sourceRange; - }) .Returns(Task.FromResult(Response.FromValue( ShareModelFactory.ShareFileUploadInfo( eTag: new ETag("eTag"), @@ -287,11 +278,13 @@ public async Task CopyFromUriAsync() sourceResource.Verify(b => b.Uri, Times.Once()); sourceResource.VerifyNoOtherCalls(); - mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + mockDestination.Verify(b => b.UploadRangeFromUriAsync( + sourceResource.Object.Uri, + new HttpRange(0, length), + new HttpRange(0, length), + It.IsAny(), + It.IsAny()), Times.Once()); - Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); - Assert.AreEqual(new HttpRange(0, length), passedRange); - Assert.AreEqual(new HttpRange(0, length), passedSourceRange); mockDestination.VerifyNoOtherCalls(); } @@ -307,16 +300,7 @@ public async Task CopyFromUriAsync_Error() new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); - Uri passedSourceUri = default; - HttpRange passedRange = default; - HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((sourceUri, range, sourceRange, options, token) => - { - passedSourceUri = sourceUri; - passedRange = range; - passedSourceRange = sourceRange; - }) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); @@ -331,12 +315,14 @@ await TestHelper.AssertExpectedExceptionAsync( sourceResource.Verify(b => b.Uri, Times.Once()); sourceResource.VerifyNoOtherCalls(); - mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + mockDestination.Verify(b => b.UploadRangeFromUriAsync( + sourceResource.Object.Uri, + new HttpRange(0, length), + new HttpRange(0, length), + It.IsAny(), + It.IsAny()), Times.Once()); mockDestination.VerifyNoOtherCalls(); - Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); - Assert.AreEqual(new HttpRange(0, length), passedRange); - Assert.AreEqual(new HttpRange(0, length), passedSourceRange); } [Test] @@ -352,16 +338,7 @@ public async Task CopyBlockFromUriAsync() new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); - Uri passedSourceUri = default; - HttpRange passedRange = default; - HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((sourceUri, range, sourceRange, options, token) => - { - passedSourceUri = sourceUri; - passedRange = range; - passedSourceRange = sourceRange; - }) .Returns(Task.FromResult(Response.FromValue( ShareModelFactory.ShareFileUploadInfo( eTag: new ETag("eTag"), @@ -380,12 +357,14 @@ await destinationResource.CopyBlockFromUriInternalAsync( sourceResource.Verify(b => b.Uri, Times.Once()); sourceResource.VerifyNoOtherCalls(); - mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + mockDestination.Verify(b => b.UploadRangeFromUriAsync( + sourceResource.Object.Uri, + new HttpRange(0, length), + new HttpRange(0, length), + It.IsAny(), + It.IsAny()), Times.Once()); mockDestination.VerifyNoOtherCalls(); - Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); - Assert.AreEqual(new HttpRange(0, length), passedRange); - Assert.AreEqual(new HttpRange(0, length), passedSourceRange); } [Test] @@ -400,16 +379,7 @@ public async Task CopyBlockFromUriAsync_Error() new Uri("https://storageaccount.file.core.windows.net/container/destinationfile"), new ShareClientOptions()); - Uri passedSourceUri = default; - HttpRange passedRange = default; - HttpRange passedSourceRange = default; mockDestination.Setup(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((sourceUri, range, sourceRange, options, token) => - { - passedSourceUri = sourceUri; - passedRange = range; - passedSourceRange = sourceRange; - }) .Throws(new RequestFailedException(status: 404, message: "The specified resource does not exist.", errorCode: "ResourceNotFound", default)); ShareFileStorageResource destinationResource = new ShareFileStorageResource(mockDestination.Object); @@ -424,12 +394,14 @@ await TestHelper.AssertExpectedExceptionAsync( sourceResource.Verify(b => b.Uri, Times.Once()); sourceResource.VerifyNoOtherCalls(); - mockDestination.Verify(b => b.UploadRangeFromUriAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + mockDestination.Verify(b => b.UploadRangeFromUriAsync( + sourceResource.Object.Uri, + new HttpRange(0, length), + new HttpRange(0, length), + It.IsAny(), + It.IsAny()), Times.Once()); mockDestination.VerifyNoOtherCalls(); - Assert.AreEqual(sourceResource.Object.Uri, passedSourceUri); - Assert.AreEqual(new HttpRange(0, length), passedRange); - Assert.AreEqual(new HttpRange(0, length), passedSourceRange); } [Test]