public async Task BlobOpenWriteTestAsync() { byte[] buffer = GetRandomBuffer(2 * 1024); CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudPageBlob blob = container.GetPageBlobReference("blob1"); using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) { Stream blobStreamForWrite = blobStream; await blobStreamForWrite.WriteAsync(buffer, 0, 2048); await blobStreamForWrite.FlushAsync(); byte[] testBuffer = new byte[2048]; MemoryStream dstStream = new MemoryStream(testBuffer); await blob.DownloadRangeToStreamAsync(dstStream, null, null); MemoryStream memStream = new MemoryStream(buffer); TestHelper.AssertStreamsAreEqual(memStream, dstStream); } } finally { container.DeleteIfExistsAsync().Wait(); } }
public async Task BlobReadWhenOpenWriteAsync() { byte[] buffer = GetRandomBuffer(2 * 1024); bool thrown = false; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudPageBlob blob = container.GetPageBlobReference("blob1"); MemoryStream memoryStream = new MemoryStream(buffer); using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) { Stream blobStreamForWrite = blobStream; await blobStreamForWrite.WriteAsync(buffer, 0, 2048); byte[] testBuffer = new byte[2048]; try { await blobStreamForWrite.ReadAsync(testBuffer, 0, 2048); } catch (NotSupportedException) { thrown = true; } Assert.IsTrue(thrown); } } finally { container.DeleteIfExistsAsync().Wait(); } }
public async Task BlobOpenReadWriteTestAsync() { byte[] buffer = GetRandomBuffer(2 * 1024); CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudPageBlob blob = container.GetPageBlobReference("blob1"); using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) { Stream blobStreamForWrite = blobStream; await blobStreamForWrite.WriteAsync(buffer, 0, 2048); await blobStreamForWrite.FlushAsync(); } using (Stream dstStream = await blob.OpenReadAsync()) { Stream dstStreamForRead = dstStream; MemoryStream memoryStream = new MemoryStream(buffer); TestHelper.AssertStreamsAreEqual(memoryStream, dstStreamForRead); } } finally { await container.DeleteAsync(); } }
public async Task BlobOpenWriteSeekReadTestAsync() { byte[] buffer = GetRandomBuffer(2 * 1024); CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudPageBlob blob = container.GetPageBlobReference("blob1"); MemoryStream memoryStream = new MemoryStream(buffer); using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) { Stream blobStreamForWrite = blobStream; await blobStreamForWrite.WriteAsync(buffer, 0, 2048); Assert.AreEqual(blobStreamForWrite.Position, 2048); blobStreamForWrite.Seek(1024, 0); memoryStream.Seek(1024, 0); Assert.AreEqual(blobStreamForWrite.Position, 1024); byte[] testBuffer = GetRandomBuffer(1024); await memoryStream.WriteAsync(testBuffer, 0, 1024); await blobStreamForWrite.WriteAsync(testBuffer, 0, 1024); Assert.AreEqual(blobStreamForWrite.Position, memoryStream.Position); await blobStreamForWrite.FlushAsync(); } using (Stream dstStream = await blob.OpenReadAsync()) { Stream dstStreamForRead = dstStream; TestHelper.AssertStreamsAreEqual(memoryStream, dstStreamForRead); } } finally { container.DeleteIfExistsAsync().Wait(); } }
public async Task UseTransactionalCRC64GetTestAsync() { BlobRequestOptions optionsWithNoCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = false } }; BlobRequestOptions optionsWithCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = true } }; byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); Crc64Wrapper hasher = new Crc64Wrapper(); hasher.UpdateHash(buffer, 0, buffer.Length); string crc64 = hasher.ComputeHash(); string lastCheckCRC64 = null; OperationContext opContextWithCRC64Check = new OperationContext(); opContextWithCRC64Check.ResponseReceived += (_, args) => { if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckCRC64 = HttpResponseParsers.GetContentCRC64(args.Response); } }; OperationContext opContextWithCRC64CheckAndInjectedFailure = new OperationContext(); opContextWithCRC64CheckAndInjectedFailure.ResponseReceived += (_, args) => { args.Response.Headers.Remove(Constants.HeaderConstants.ContentCrc64Header); args.Response.Headers.TryAddWithoutValidation(Constants.HeaderConstants.ContentCrc64Header, "dummy"); if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckCRC64 = HttpResponseParsers.GetContentCRC64(args.Response); } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); using (Stream blobStream = await blockBlob.OpenWriteAsync()) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } using (Stream stream = new MemoryStream()) { //lastCheckCRC64 = null; //blockBlob.DownloadToStream(stream, null, optionsWithNoCRC64, opContextWithCRC64Check); //Assert.IsNotNull(lastCheckCRC64); //lastCheckCRC64 = null; //blockBlob.DownloadToStream(stream, null, optionsWithCRC64, opContextWithCRC64Check); //Assert.IsNotNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithCRC64, opContextWithCRC64Check), "Downloading more than 4MB with transactional CRC64 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckCRC64 = null; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckCRC64); } lastCheckCRC64 = "invalid_CRC64"; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckCRC64); } } CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 2)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } using (Stream stream = new MemoryStream()) { lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadToStreamAsync(stream, null, optionsWithCRC64, opContextWithCRC64Check), "Page blob will not have CRC64 set by default; with UseTransactional, download should fail"); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithCRC64, opContextWithCRC64Check), "Downloading more than 4MB with transactional CRC64 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckCRC64 = null; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckCRC64); } lastCheckCRC64 = "invalid_CRC64"; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckCRC64); } } } finally { await container.DeleteIfExistsAsync(); } }
public async Task UseTransactionalCRC64PutTestAsync() { BlobRequestOptions optionsWithNoCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = false } }; BlobRequestOptions optionsWithCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = true } }; byte[] buffer = GetRandomBuffer(1024); Crc64Wrapper hasher = new Crc64Wrapper(); hasher.UpdateHash(buffer, 0, buffer.Length); string crc64 = hasher.ComputeHash(); string lastCheckCRC64 = null; int checkCount = 0; OperationContext opContextWithCRC64Check = new OperationContext(); opContextWithCRC64Check.SendingRequest += (_, args) => { if (HttpRequestParsers.GetContentLength(args.Request) >= buffer.Length) { lastCheckCRC64 = HttpRequestParsers.GetContentCRC64(args.Request); checkCount++; } }; OperationContext opContextWithCRC64CheckAndInjectedFailure = new OperationContext(); opContextWithCRC64CheckAndInjectedFailure.SendingRequest += (_, args) => { args.Response.Headers.Remove(Constants.HeaderConstants.ContentCrc64Header); args.Request.Headers.TryAddWithoutValidation(Constants.HeaderConstants.ContentCrc64Header, "dummy"); if (HttpRequestParsers.GetContentLength(args.Request) >= buffer.Length) { lastCheckCRC64 = HttpRequestParsers.GetContentCRC64(args.Request); checkCount++; } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); List <string> blockIds = GetBlockIdList(3); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckCRC64 = "invalid_CRC64"; await blockBlob.PutBlockAsync(blockIds[0], blockData, null, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[1], blockData, null, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); blockData.Seek(0, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.PutBlockAsync(blockIds[1], blockData, null, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[2], blockData, new Checksum(crc64 : crc64), null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); } Assert.AreEqual(3, checkCount); checkCount = 0; CloudAppendBlob appendBlob = container.GetAppendBlobReference("blob2"); await appendBlob.CreateOrReplaceAsync(); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckCRC64 = "invalid_CRC64"; await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); blockData.Seek(0, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync <StorageException>( () => appendBlob.AppendBlockAsync(blockData, null, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, new Checksum(crc64 : crc64), null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); } Assert.AreEqual(3, checkCount); CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); await pageBlob.CreateAsync(buffer.Length); checkCount = 0; using (Stream pageData = new MemoryStream(buffer)) { lastCheckCRC64 = "invalid_CRC64"; await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); pageData.Seek(0, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, new Checksum(crc64 : crc64), null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); } Assert.AreEqual(3, checkCount); lastCheckCRC64 = null; blockBlob = container.GetBlockBlobReference("blob4"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNotNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); lastCheckCRC64 = "invalid_CRC64"; blockBlob = container.GetBlockBlobReference("blob5"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); lastCheckCRC64 = null; pageBlob = container.GetPageBlobReference("blob6"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 3, null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNotNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); lastCheckCRC64 = "invalid_CRC64"; pageBlob = container.GetPageBlobReference("blob7"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 3, null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); } finally { await container.DeleteIfExistsAsync(); } }
public async Task UseTransactionalMD5GetTestAsync() { BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() { UseTransactionalMD5 = false, }; BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() { UseTransactionalMD5 = true, }; byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); MD5 hasher = MD5.Create(); string md5 = Convert.ToBase64String(hasher.ComputeHash(buffer)); string lastCheckMD5 = null; int checkCount = 0; OperationContext opContextWithMD5Check = new OperationContext(); opContextWithMD5Check.ResponseReceived += (_, args) => { if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckMD5 = HttpResponseParsers.GetContentMD5(args.Response); checkCount++; } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); using (Stream blobStream = await blockBlob.OpenWriteAsync()) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } checkCount = 0; using (Stream stream = new MemoryStream()) { lastCheckMD5 = null; await blockBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNotNull(lastCheckMD5); lastCheckMD5 = null; await blockBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, opContextWithMD5Check); Assert.IsNotNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; await blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check), "Downloading more than 4MB with transactional MD5 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckMD5 = null; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckMD5); } lastCheckMD5 = "invalid_md5"; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckMD5); } } Assert.AreEqual(9, checkCount); CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 2)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } checkCount = 0; using (Stream stream = new MemoryStream()) { lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, opContextWithMD5Check), "Page blob will not have MD5 set by default; with UseTransactional, download should fail"); lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check), "Downloading more than 4MB with transactional MD5 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckMD5 = null; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckMD5); } lastCheckMD5 = "invalid_md5"; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckMD5); } } Assert.AreEqual(9, checkCount); } finally { await container.DeleteIfExistsAsync(); } }
public async Task UseTransactionalMD5PutTestAsync() { BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() { UseTransactionalMD5 = false, }; BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() { UseTransactionalMD5 = true, }; byte[] buffer = GetRandomBuffer(1024); MD5 hasher = MD5.Create(); string md5 = Convert.ToBase64String(hasher.ComputeHash(buffer)); string lastCheckMD5 = null; int checkCount = 0; OperationContext opContextWithMD5Check = new OperationContext(); opContextWithMD5Check.SendingRequest += (_, args) => { if (HttpRequestParsers.GetContentLength(args.Request) >= buffer.Length) { lastCheckMD5 = HttpRequestParsers.GetContentMD5(args.Request); checkCount++; } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); List <string> blockIds = GetBlockIdList(3); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckMD5 = "invalid_md5"; await blockBlob.PutBlockAsync(blockIds[0], blockData, null, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[1], blockData, null, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[2], blockData, md5, null, optionsWithNoMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); } Assert.AreEqual(3, checkCount); checkCount = 0; CloudAppendBlob appendBlob = container.GetAppendBlobReference("blob2"); await appendBlob.CreateOrReplaceAsync(); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckMD5 = "invalid_md5"; await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, md5, null, optionsWithNoMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); } Assert.AreEqual(3, checkCount); CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); await pageBlob.CreateAsync(buffer.Length); checkCount = 0; using (Stream pageData = new MemoryStream(buffer)) { lastCheckMD5 = "invalid_md5"; await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, md5, null, optionsWithNoMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); } Assert.AreEqual(3, checkCount); lastCheckMD5 = null; blockBlob = container.GetBlockBlobReference("blob4"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(null, optionsWithMD5, opContextWithMD5Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNotNull(lastCheckMD5); Assert.AreEqual(1, checkCount); lastCheckMD5 = "invalid_md5"; blockBlob = container.GetBlockBlobReference("blob5"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(null, optionsWithNoMD5, opContextWithMD5Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNull(lastCheckMD5); Assert.AreEqual(1, checkCount); lastCheckMD5 = null; pageBlob = container.GetPageBlobReference("blob6"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 3, null, optionsWithMD5, opContextWithMD5Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNotNull(lastCheckMD5); Assert.AreEqual(1, checkCount); lastCheckMD5 = "invalid_md5"; pageBlob = container.GetPageBlobReference("blob7"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 3, null, optionsWithNoMD5, opContextWithMD5Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNull(lastCheckMD5); Assert.AreEqual(1, checkCount); } finally { await container.DeleteIfExistsAsync(); } }
public async Task CloudBlobClientMaximumExecutionTimeoutShouldNotBeHonoredForStreamsAsync() { CloudBlobClient blobClient = GenerateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); byte[] buffer = BlobTestBase.GetRandomBuffer(1024 * 1024); try { await container.CreateAsync(); blobClient.DefaultRequestOptions.MaximumExecutionTime = TimeSpan.FromSeconds(30); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); blockBlob.StreamWriteSizeInBytes = 1024 * 1024; blockBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; pageBlob.StreamWriteSizeInBytes = 1024 * 1024; pageBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; using (CloudBlobStream bos = await blockBlob.OpenWriteAsync()) { DateTime start = DateTime.Now; for (int i = 0; i < 7; i++) { await bos.WriteAsync(buffer, 0, buffer.Length); } // Sleep to ensure we are over the Max execution time when we do the last write int msRemaining = (int)(blobClient.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } await bos.WriteAsync(buffer, 0, buffer.Length); await bos.CommitAsync(); } using (Stream bis = (await blockBlob.OpenReadAsync())) { DateTime start = DateTime.Now; int total = 0; while (total < 7 * 1024 * 1024) { total += await bis.ReadAsync(buffer, 0, buffer.Length); } // Sleep to ensure we are over the Max execution time when we do the last read int msRemaining = (int)(blobClient.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } while (true) { int count = await bis.ReadAsync(buffer, 0, buffer.Length); total += count; if (count == 0) { break; } } } using (CloudBlobStream bos = await pageBlob.OpenWriteAsync(8 * 1024 * 1024)) { DateTime start = DateTime.Now; for (int i = 0; i < 7; i++) { await bos.WriteAsync(buffer, 0, buffer.Length); } // Sleep to ensure we are over the Max execution time when we do the last write int msRemaining = (int)(blobClient.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } await bos.WriteAsync(buffer, 0, buffer.Length); await bos.CommitAsync(); } using (Stream bis = (await pageBlob.OpenReadAsync())) { DateTime start = DateTime.Now; int total = 0; while (total < 7 * 1024 * 1024) { total += await bis.ReadAsync(buffer, 0, buffer.Length); } // Sleep to ensure we are over the Max execution time when we do the last read int msRemaining = (int)(blobClient.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } while (true) { int count = await bis.ReadAsync(buffer, 0, buffer.Length); total += count; if (count == 0) { break; } } } } finally { blobClient.DefaultRequestOptions.MaximumExecutionTime = null; container.DeleteIfExistsAsync().Wait(); } }