public Task CreateShareAsync(CloudFileShare share, FileRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) { return share.CreateAsync(options, operationContext, cancellationToken); }
public async Task CloudFileWriteRangeAsync() { byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); #if NETCORE MD5 md5 = MD5.Create(); string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); #else CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); hasher.Append(buffer.AsBuffer()); string contentMD5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); #endif CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file1"); await file.CreateAsync(4 * 1024 * 1024); using (MemoryStream memoryStream = new MemoryStream()) { await TestHelper.ExpectedExceptionAsync <ArgumentOutOfRangeException>( async() => await file.WriteRangeAsync(memoryStream, 0, null), "Zero-length WriteRange should fail"); } using (MemoryStream resultingData = new MemoryStream()) { using (MemoryStream memoryStream = new MemoryStream(buffer)) { OperationContext opContext = new OperationContext(); await TestHelper.ExpectedExceptionAsync( async() => await file.WriteRangeAsync(memoryStream, 512, null, null, null, opContext), opContext, "Writing out-of-range ranges should fail", HttpStatusCode.RequestedRangeNotSatisfiable, "InvalidRange"); memoryStream.Seek(0, SeekOrigin.Begin); await file.WriteRangeAsync(memoryStream, 0, contentMD5); resultingData.Write(buffer, 0, buffer.Length); int offset = buffer.Length - 1024; memoryStream.Seek(offset, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync( async() => await file.WriteRangeAsync(memoryStream, 0, contentMD5, null, null, opContext), opContext, "Invalid MD5 should fail with mismatch", HttpStatusCode.BadRequest, "Md5Mismatch"); memoryStream.Seek(offset, SeekOrigin.Begin); await file.WriteRangeAsync(memoryStream, 0, null); resultingData.Seek(0, SeekOrigin.Begin); resultingData.Write(buffer, offset, buffer.Length - offset); offset = buffer.Length - 2048; memoryStream.Seek(offset, SeekOrigin.Begin); await file.WriteRangeAsync(memoryStream, 1024, null); resultingData.Seek(1024, SeekOrigin.Begin); resultingData.Write(buffer, offset, buffer.Length - offset); } using (MemoryStream fileData = new MemoryStream()) { await file.DownloadToStreamAsync(fileData); Assert.AreEqual(resultingData.Length, fileData.Length); Assert.IsTrue(fileData.ToArray().SequenceEqual(resultingData.ToArray())); } } } finally { share.DeleteIfExistsAsync().Wait(); } }
public async Task CloudFileClientMaximumExecutionTimeoutShouldNotBeHonoredForStreamsAsync() { CloudFileClient fileClient = GenerateCloudFileClient(); CloudFileShare share = fileClient.GetShareReference(Guid.NewGuid().ToString("N")); CloudFileDirectory rootDirectory = share.GetRootDirectoryReference(); byte[] buffer = FileTestBase.GetRandomBuffer(1024 * 1024); try { await share.CreateAsync(); fileClient.DefaultRequestOptions.MaximumExecutionTime = TimeSpan.FromSeconds(30); CloudFile file = rootDirectory.GetFileReference("file"); file.StreamMinimumReadSizeInBytes = 1024 * 1024; using (var fileStream = await file.OpenWriteAsync(8 * 1024 * 1024)) { Stream fos = fileStream; DateTime start = DateTime.Now; for (int i = 0; i < 7; i++) { await fos.WriteAsync(buffer, 0, buffer.Length); } // Sleep to ensure we are over the Max execution time when we do the last write int msRemaining = (int)(fileClient.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } await fos.WriteAsync(buffer, 0, buffer.Length); await fileStream.CommitAsync(); } using (var fileStream = await file.OpenReadAsync()) { Stream fis = fileStream; DateTime start = DateTime.Now; int total = 0; while (total < 7 * 1024 * 1024) { total += await fis.ReadAsync(buffer, 0, buffer.Length); } // Sleep to ensure we are over the Max execution time when we do the last read int msRemaining = (int)(fileClient.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } while (true) { int count = await fis.ReadAsync(buffer, 0, buffer.Length); total += count; if (count == 0) { break; } } } } finally { fileClient.DefaultRequestOptions.MaximumExecutionTime = null; share.DeleteIfExistsAsync().Wait(); } }
public async Task FileWriteStreamFlushTestAsync() { byte[] buffer = GetRandomBuffer(512); CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file1"); file.StreamWriteSizeInBytes = 1024; using (MemoryStream wholeFile = new MemoryStream()) { FileRequestOptions options = new FileRequestOptions() { StoreFileContentMD5 = true }; OperationContext opContext = new OperationContext(); using (var fileStream = await file.OpenWriteAsync(4 * 512, null, options, opContext)) { for (int i = 0; i < 3; i++) { await fileStream.WriteAsync(buffer, 0, buffer.Length); await wholeFile.WriteAsync(buffer, 0, buffer.Length); } #if NETCORE // todo: Make some other better logic for this test to be reliable. System.Threading.Thread.Sleep(500); #endif Task.Delay(500).GetAwaiter().GetResult(); Assert.AreEqual(2, opContext.RequestResults.Count); await fileStream.FlushAsync(); Assert.AreEqual(3, opContext.RequestResults.Count); await fileStream.FlushAsync(); Assert.AreEqual(3, opContext.RequestResults.Count); await fileStream.WriteAsync(buffer, 0, buffer.Length); await wholeFile.WriteAsync(buffer, 0, buffer.Length); Assert.AreEqual(3, opContext.RequestResults.Count); await fileStream.CommitAsync(); Assert.AreEqual(5, opContext.RequestResults.Count); } Assert.AreEqual(5, opContext.RequestResults.Count); using (MemoryOutputStream downloadedFile = new MemoryOutputStream()) { await file.DownloadToStreamAsync(downloadedFile); TestHelper.AssertStreamsAreEqual(wholeFile, downloadedFile.UnderlyingStream); } } } finally { share.DeleteIfExistsAsync().Wait(); } }
public async Task CloudFileListRangesAsync() { byte[] buffer = GetRandomBuffer(1024); CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file1"); await file.CreateAsync(4 * 1024); using (MemoryStream memoryStream = new MemoryStream(buffer)) { await file.WriteRangeAsync(memoryStream, 512, null); } using (MemoryStream memoryStream = new MemoryStream(buffer)) { await file.WriteRangeAsync(memoryStream, 3 * 1024, null); } await file.ClearRangeAsync(1024, 1024); await file.ClearRangeAsync(0, 512); IEnumerable <FileRange> fileRanges = await file.ListRangesAsync(); List <string> expectedFileRanges = new List <string>() { new FileRange(512, 1023).ToString(), new FileRange(3 * 1024, 4 * 1024 - 1).ToString(), }; foreach (FileRange fileRange in fileRanges) { Assert.IsTrue(expectedFileRanges.Remove(fileRange.ToString())); } Assert.AreEqual(0, expectedFileRanges.Count); fileRanges = await file.ListRangesAsync(1024, 1024, null, null, null); Assert.AreEqual(0, fileRanges.Count()); fileRanges = await file.ListRangesAsync(512, 3 * 1024, null, null, null); expectedFileRanges = new List <string>() { new FileRange(512, 1023).ToString(), new FileRange(3 * 1024, 7 * 512 - 1).ToString(), }; foreach (FileRange fileRange in fileRanges) { Assert.IsTrue(expectedFileRanges.Remove(fileRange.ToString())); } Assert.AreEqual(0, expectedFileRanges.Count); OperationContext opContext = new OperationContext(); await TestHelper.ExpectedExceptionAsync( async() => await file.ListRangesAsync(1024, null, null, null, opContext), opContext, "List Ranges with an offset but no count should fail", HttpStatusCode.Unused); Assert.IsInstanceOfType(opContext.LastResult.Exception.InnerException, typeof(ArgumentNullException)); } finally { share.DeleteIfExistsAsync().Wait(); } }
public async Task FileDisableContentMD5ValidationTestAsync() { byte[] buffer = new byte[1024]; Random random = new Random(); random.NextBytes(buffer); FileRequestOptions optionsWithNoMD5 = new FileRequestOptions() { DisableContentMD5Validation = true, StoreFileContentMD5 = true, }; FileRequestOptions optionsWithMD5 = new FileRequestOptions() { DisableContentMD5Validation = false, StoreFileContentMD5 = true, }; CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file2"); using (Stream stream = new MemoryStream(buffer)) { await file.UploadFromStreamAsync(stream, null, optionsWithMD5, null); } using (Stream stream = new MemoryStream()) { await file.DownloadToStreamAsync(stream, null, optionsWithMD5, null); await file.DownloadToStreamAsync(stream, null, optionsWithNoMD5, null); using (var fileStream = await file.OpenReadAsync(null, optionsWithMD5, null)) { Stream fileStreamForRead = fileStream; int read; do { read = await fileStreamForRead.ReadAsync(buffer, 0, buffer.Length); }while (read > 0); } using (var fileStream = await file.OpenReadAsync(null, optionsWithNoMD5, null)) { Stream fileStreamForRead = fileStream; int read; do { read = await fileStreamForRead.ReadAsync(buffer, 0, buffer.Length); }while (read > 0); } file.Properties.ContentMD5 = "MDAwMDAwMDA="; await file.SetPropertiesAsync(); OperationContext opContext = new OperationContext(); await TestHelper.ExpectedExceptionAsync( async() => await file.DownloadToStreamAsync(stream, null, optionsWithMD5, opContext), opContext, "Downloading a file with invalid MD5 should fail", HttpStatusCode.OK); await file.DownloadToStreamAsync(stream, null, optionsWithNoMD5, null); using (var fileStream = await file.OpenReadAsync(null, optionsWithMD5, null)) { Stream fileStreamForRead = fileStream; TestHelper.ExpectedException <IOException>( () => { int read; do { read = fileStreamForRead.Read(buffer, 0, buffer.Length); }while (read > 0); }, "Downloading a file with invalid MD5 should fail"); } using (var fileStream = await file.OpenReadAsync(null, optionsWithNoMD5, null)) { Stream fileStreamForRead = fileStream; int read; do { read = await fileStreamForRead.ReadAsync(buffer, 0, buffer.Length); }while (read > 0); } } } finally { share.DeleteIfExistsAsync().Wait(); } }
public async Task FileWriteStreamBasicTestAsync() { byte[] buffer = GetRandomBuffer(6 * 512); #if NETCORE MD5 hasher = MD5.Create(); #else CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); #endif CloudFileShare share = GetRandomShareReference(); share.ServiceClient.DefaultRequestOptions.ParallelOperationThreadCount = 2; try { await share.CreateAsync(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file1"); file.StreamWriteSizeInBytes = 8 * 512; using (MemoryStream wholeFile = new MemoryStream()) { FileRequestOptions options = new FileRequestOptions() { StoreFileContentMD5 = true, }; using (var writeStream = await file.OpenWriteAsync(buffer.Length * 3, null, options, null)) { Stream fileStream = writeStream; for (int i = 0; i < 3; i++) { await fileStream.WriteAsync(buffer, 0, buffer.Length); await wholeFile.WriteAsync(buffer, 0, buffer.Length); Assert.AreEqual(wholeFile.Position, fileStream.Position); #if !NETCORE hasher.Append(buffer.AsBuffer()); #endif } await fileStream.FlushAsync(); } #if NETCORE string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeFile.ToArray())); #else string md5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); #endif await file.FetchAttributesAsync(); Assert.AreEqual(md5, file.Properties.ContentMD5); using (MemoryOutputStream downloadedFile = new MemoryOutputStream()) { await file.DownloadToStreamAsync(downloadedFile); TestHelper.AssertStreamsAreEqual(wholeFile, downloadedFile.UnderlyingStream); } await TestHelper.ExpectedExceptionAsync <ArgumentException>( async() => await file.OpenWriteAsync(null, null, options, null), "OpenWrite with StoreFileContentMD5 on an existing file should fail"); using (var writeStream = await file.OpenWriteAsync(null)) { Stream fileStream = writeStream; fileStream.Seek(buffer.Length / 2, SeekOrigin.Begin); wholeFile.Seek(buffer.Length / 2, SeekOrigin.Begin); for (int i = 0; i < 2; i++) { fileStream.Write(buffer, 0, buffer.Length); wholeFile.Write(buffer, 0, buffer.Length); Assert.AreEqual(wholeFile.Position, fileStream.Position); } await fileStream.FlushAsync(); } await file.FetchAttributesAsync(); Assert.AreEqual(md5, file.Properties.ContentMD5); using (MemoryOutputStream downloadedFile = new MemoryOutputStream()) { options.DisableContentMD5Validation = true; await file.DownloadToStreamAsync(downloadedFile, null, options, null); TestHelper.AssertStreamsAreEqual(wholeFile, downloadedFile.UnderlyingStream); } } } finally { share.DeleteAsync().Wait(); } }
public async Task CloudFileSetPropertiesAsync() { CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file1"); await file.CreateAsync(1024); string eTag = file.Properties.ETag; DateTimeOffset lastModified = file.Properties.LastModified.Value; await Task.Delay(1000); file.Properties.CacheControl = "no-transform"; file.Properties.ContentEncoding = "gzip"; file.Properties.ContentLanguage = "tr,en"; file.Properties.ContentMD5 = "MDAwMDAwMDA="; file.Properties.ContentType = "text/html"; await file.SetPropertiesAsync(); Assert.IsTrue(file.Properties.LastModified > lastModified); Assert.AreNotEqual(eTag, file.Properties.ETag); CloudFile file2 = share.GetRootDirectoryReference().GetFileReference("file1"); await file2.FetchAttributesAsync(); Assert.AreEqual("no-transform", file2.Properties.CacheControl); Assert.AreEqual("gzip", file2.Properties.ContentEncoding); Assert.AreEqual("tr,en", file2.Properties.ContentLanguage); Assert.AreEqual("MDAwMDAwMDA=", file2.Properties.ContentMD5); Assert.AreEqual("text/html", file2.Properties.ContentType); CloudFile file3 = share.GetRootDirectoryReference().GetFileReference("file1"); using (MemoryStream stream = new MemoryStream()) { FileRequestOptions options = new FileRequestOptions() { DisableContentMD5Validation = true, }; await file3.DownloadToStreamAsync(stream, null, options, null); } AssertAreEqual(file2.Properties, file3.Properties); CloudFileDirectory rootDirectory = share.GetRootDirectoryReference(); IEnumerable <IListFileItem> results = await ListFilesAndDirectoriesAsync(rootDirectory, null, null, null, null); CloudFile file4 = (CloudFile)results.First(); Assert.AreEqual(file2.Properties.Length, file4.Properties.Length); CloudFile file5 = share.GetRootDirectoryReference().GetFileReference("file1"); Assert.IsNull(file5.Properties.ContentMD5); byte[] target = new byte[4]; await file5.DownloadRangeToByteArrayAsync(target, 0, 0, 4); Assert.AreEqual("MDAwMDAwMDA=", file5.Properties.ContentMD5); } finally { share.DeleteIfExistsAsync().Wait(); } }
public async Task CloudFileInvalidApisInShareSnapshotAsync() { CloudFileClient client = GenerateCloudFileClient(); string name = GetRandomShareName(); CloudFileShare share = client.GetShareReference(name); await share.CreateAsync(); CloudFileShare snapshot = share.SnapshotAsync().Result; CloudFile file = snapshot.GetRootDirectoryReference().GetDirectoryReference("dir1").GetFileReference("file"); try { await file.CreateAsync(1024); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } try { await file.DeleteAsync(); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } try { await file.SetMetadataAsync(); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } try { await file.AbortCopyAsync(null); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } try { await file.ClearRangeAsync(0, 1024); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } try { await file.StartCopyAsync(file); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } try { await file.UploadFromByteArrayAsync(new byte[1024], 0, 1024); Assert.Fail("API should fail in a snapshot"); } catch (InvalidOperationException e) { Assert.AreEqual(SR.CannotModifyShareSnapshot, e.Message); } await snapshot.DeleteAsync(); await share.DeleteAsync(); }
public async Task CloudFileSASSharedProtocolsQueryParamAsync() { CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); CloudFile file; SharedAccessFilePolicy policy = new SharedAccessFilePolicy() { Permissions = SharedAccessFilePermissions.Read, SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), }; CloudFile fileWithKey = share.GetRootDirectoryReference().GetFileReference("filefile"); byte[] data = new byte[] { 0x1, 0x2, 0x3, 0x4 }; byte[] target = new byte[4]; await fileWithKey.UploadFromByteArrayAsync(data, 0, 4); foreach (SharedAccessProtocol?protocol in new SharedAccessProtocol?[] { null, SharedAccessProtocol.HttpsOrHttp, SharedAccessProtocol.HttpsOnly }) { string fileToken = fileWithKey.GetSharedAccessSignature(policy, null, null, protocol, null); StorageCredentials fileSAS = new StorageCredentials(fileToken); Uri fileSASUri = new Uri(fileWithKey.Uri + fileSAS.SASToken); StorageUri fileSASStorageUri = new StorageUri(new Uri(fileWithKey.StorageUri.PrimaryUri + fileSAS.SASToken), new Uri(fileWithKey.StorageUri.SecondaryUri + fileSAS.SASToken)); int securePort = 443; int httpPort = (fileSASUri.Port == securePort) ? 80 : fileSASUri.Port; if (!string.IsNullOrEmpty(TestBase.TargetTenantConfig.FileSecurePortOverride)) { securePort = Int32.Parse(TestBase.TargetTenantConfig.FileSecurePortOverride); } var schemesAndPorts = new[] { new { scheme = "HTTP", port = httpPort }, new { scheme = "HTTPS", port = securePort } }; foreach (var item in schemesAndPorts) { fileSASUri = TransformSchemeAndPort(fileSASUri, item.scheme, item.port); fileSASStorageUri = new StorageUri(TransformSchemeAndPort(fileSASStorageUri.PrimaryUri, item.scheme, item.port), TransformSchemeAndPort(fileSASStorageUri.SecondaryUri, item.scheme, item.port)); if (protocol.HasValue && protocol == SharedAccessProtocol.HttpsOnly && string.CompareOrdinal(item.scheme, "HTTP") == 0) { file = new CloudFile(fileSASUri); OperationContext context = new OperationContext(); await TestHelper.ExpectedExceptionAsync( async() => await file.FetchAttributesAsync(null /* accessCondition */, null /* options */, context), context, "Access a file using SAS with a shared protocols that does not match", HttpStatusCode.Unused, ""); file = new CloudFile(fileSASStorageUri, null); context = new OperationContext(); await TestHelper.ExpectedExceptionAsync( async() => await file.FetchAttributesAsync(null /* accessCondition */, null /* options */, context), context, "Access a file using SAS with a shared protocols that does not match", HttpStatusCode.Unused, ""); } else { file = new CloudFile(fileSASUri); await file.DownloadRangeToByteArrayAsync(target, 0, 0, 4, null, null, null); for (int i = 0; i < 4; i++) { Assert.AreEqual(data[i], target[i]); } file = new CloudFile(fileSASStorageUri, null); await file.DownloadRangeToByteArrayAsync(target, 0, 0, 4, null, null, null); for (int i = 0; i < 4; i++) { Assert.AreEqual(data[i], target[i]); } } } } } finally { share.DeleteIfExistsAsync().Wait(); } }
public async Task CloudFileListSharesWithSnapshotAsync() { CloudFileShare share = GetRandomShareReference(); await share.CreateAsync(); share.Metadata["key1"] = "value1"; await share.SetMetadataAsync(); CloudFileShare snapshot = await share.SnapshotAsync(); share.Metadata["key2"] = "value2"; await share.SetMetadataAsync(); CloudFileClient client = GenerateCloudFileClient(); List <CloudFileShare> listedShares = new List <CloudFileShare>(); FileContinuationToken token = null; do { ShareResultSegment resultSegment = await client.ListSharesSegmentedAsync(share.Name, ShareListingDetails.All, null, token, null, null); token = resultSegment.ContinuationToken; foreach (CloudFileShare listResultShare in resultSegment.Results) { listedShares.Add(listResultShare); } }while (token != null); int count = 0; bool originalFound = false; bool snapshotFound = false; foreach (CloudFileShare listShareItem in listedShares) { if (listShareItem.Name.Equals(share.Name) && !listShareItem.IsSnapshot && !originalFound) { count++; originalFound = true; Assert.AreEqual(2, listShareItem.Metadata.Count); Assert.AreEqual("value2", listShareItem.Metadata["key2"]); Assert.AreEqual("value1", listShareItem.Metadata["key1"]); Assert.AreEqual(share.StorageUri, listShareItem.StorageUri); } else if (listShareItem.Name.Equals(share.Name) && listShareItem.IsSnapshot && !snapshotFound) { count++; snapshotFound = true; Assert.AreEqual(1, listShareItem.Metadata.Count); Assert.AreEqual("value1", listShareItem.Metadata["key1"]); Assert.AreEqual(snapshot.StorageUri, listShareItem.StorageUri); } } Assert.AreEqual(2, count); await snapshot.DeleteAsync(); await share.DeleteAsync(); }
private static async Task CloudFileCopyAsync(bool sourceIsSas, bool destinationIsSas) { CloudFileShare share = GetRandomShareReference(); try { await share.CreateAsync(); // Create Source on server CloudFile source = share.GetRootDirectoryReference().GetFileReference("source"); string data = "String data"; await UploadTextAsync(source, data, Encoding.UTF8); source.Metadata["Test"] = "value"; await source.SetMetadataAsync(); // Create Destination on server CloudFile destination = share.GetRootDirectoryReference().GetFileReference("destination"); await destination.CreateAsync(1); CloudFile copySource = source; CloudFile copyDestination = destination; if (sourceIsSas) { // Source SAS must have read permissions SharedAccessFilePermissions permissions = SharedAccessFilePermissions.Read; SharedAccessFilePolicy policy = new SharedAccessFilePolicy() { SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), Permissions = permissions, }; string sasToken = source.GetSharedAccessSignature(policy); // Get source StorageCredentials credentials = new StorageCredentials(sasToken); copySource = new CloudFile(credentials.TransformUri(source.Uri)); } if (destinationIsSas) { Assert.IsTrue(sourceIsSas); // Destination SAS must have write permissions SharedAccessFilePermissions permissions = SharedAccessFilePermissions.Write; SharedAccessFilePolicy policy = new SharedAccessFilePolicy() { SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), Permissions = permissions, }; string sasToken = destination.GetSharedAccessSignature(policy); // Get destination StorageCredentials credentials = new StorageCredentials(sasToken); copyDestination = new CloudFile(credentials.TransformUri(destination.Uri)); } // Start copy and wait for completion string copyId = await copyDestination.StartCopyAsync(TestHelper.Defiddler(copySource)); await WaitForCopyAsync(destination); // Check original file references for equality Assert.AreEqual(CopyStatus.Success, destination.CopyState.Status); Assert.AreEqual(source.Uri.AbsolutePath, destination.CopyState.Source.AbsolutePath); Assert.AreEqual(data.Length, destination.CopyState.TotalBytes); Assert.AreEqual(data.Length, destination.CopyState.BytesCopied); Assert.AreEqual(copyId, destination.CopyState.CopyId); Assert.IsTrue(destination.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); if (!destinationIsSas) { // Abort Copy is not supported for SAS destination OperationContext context = new OperationContext(); await TestHelper.ExpectedExceptionAsync( async() => await copyDestination.AbortCopyAsync(copyId, null, null, context), context, "Aborting a copy operation after completion should fail", HttpStatusCode.Conflict, "NoPendingCopyOperation"); } await source.FetchAttributesAsync(); Assert.IsNotNull(destination.Properties.ETag); Assert.AreNotEqual(source.Properties.ETag, destination.Properties.ETag); Assert.IsTrue(destination.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); string copyData = await DownloadTextAsync(destination, Encoding.UTF8); Assert.AreEqual(data, copyData, "Data inside copy of file not equal."); await destination.FetchAttributesAsync(); FileProperties prop1 = destination.Properties; FileProperties prop2 = source.Properties; Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); Assert.AreEqual(prop1.ContentType, prop2.ContentType); Assert.AreEqual("value", destination.Metadata["Test"], false, "Copied metadata not same"); await destination.DeleteAsync(); await source.DeleteAsync(); } finally { share.DeleteIfExistsAsync().Wait(); } }