public async Task OpenWriteAsync_ModifiedDuringWrite()
        {
            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            byte[] data = GetRandomBuffer(Constants.KB);
            using Stream stream = new MemoryStream(data);

            // Act
            Stream openWriteStream = await OpenWriteAsync(client, overwrite : true);

            using (Stream update = new MemoryStream(GetRandomBuffer(Constants.KB)))
            {
                await ModifyAsync(client, update);
            }

            await stream.CopyToAsync(openWriteStream);

            async Task CloseStream()
            {
                await openWriteStream.FlushAsync();

                // dispose necessary for some stream implementations
                openWriteStream.Dispose();
            }

            await TestHelper.AssertExpectedExceptionAsync <RequestFailedException>(
                CloseStream(),
                e => Assert.AreEqual(ConditionNotMetErrorCode, e.ErrorCode));
        }
        public virtual async Task OpenWriteAsync_ProgressReporting()
        {
            const int bufferSize = 256;

            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            byte[] data = GetRandomBuffer(Constants.KB);
            using Stream stream = new MemoryStream(data);

            TestProgress progress = new TestProgress();

            // Act
            using (Stream openWriteStream = await OpenWriteAsync(
                       client,
                       overwrite: true,
                       bufferSize: bufferSize,
                       progressHandler: progress))
            {
                await stream.CopyToAsync(openWriteStream);

                await openWriteStream.FlushAsync();
            }

            // Assert
            Assert.IsTrue(progress.List.Count > 0);
            Assert.AreEqual(Constants.KB, progress.List[progress.List.Count - 1]);

            await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
        }
        public async Task OpenWriteAsync_Overwrite()
        {
            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            byte[] originalData = GetRandomBuffer(Constants.KB);
            using (Stream originalStream = new MemoryStream(originalData))
            {
                await InitializeResourceAsync(client, originalStream);
            }

            byte[] newData = GetRandomBuffer(Constants.KB);
            using Stream newStream = new MemoryStream(newData);

            // Act
            using (Stream openWriteStream = await OpenWriteAsync(
                       client,
                       overwrite: true))
            {
                await newStream.CopyToAsync(openWriteStream);

                await openWriteStream.FlushAsync();
            }

            // Assert
            byte[] dataResult = (await DownloadAsync(client)).ToArray();
            Assert.AreEqual(newData.Length, dataResult.Length);
            TestHelper.AssertSequenceEqual(newData, dataResult);

            await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
        }
        public virtual async Task OpenWriteAsync_CreateEmptyBlob_WithMetadata()
        {
            const int bufferSize = Constants.KB;

            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await InitializeResourceAsync(client);

            Dictionary <string, string> metadata = new Dictionary <string, string>()
            {
                { "testkey", "testvalue" }
            };

            // Act
            using (Stream stream = await OpenWriteAsync(
                       client,
                       overwrite: true,
                       bufferSize: bufferSize,
                       metadata: metadata))
            {
            }

            // Assert
            CollectionAssert.AreEqual(metadata, await GetMetadataAsync(client));

            await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
        }
        public async Task OpenWriteAsync_WithIntermediateFlushes()
        {
            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            // Act
            using (Stream stream = await OpenWriteAsync(client, overwrite: true))
            {
                using (var writer = new StreamWriter(stream, Encoding.ASCII))
                {
                    writer.Write(new string('A', 100));
                    writer.Flush();

                    writer.Write(new string('B', 50));
                    writer.Flush();

                    writer.Write(new string('C', 25));
                    writer.Flush();
                }
            }

            // Assert
            byte[] dataResult = (await DownloadAsync(client)).ToArray();
            Assert.AreEqual(new string('A', 100) + new string('B', 50) + new string('C', 25), Encoding.ASCII.GetString(dataResult));

            await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
        }
        public async Task OpenWriteAsync_AccessConditionsFail()
        {
            foreach (AccessConditionParameters parameters in Conditions.AccessConditionsFail_Data)
            {
                // Arrange
                await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

                TResourceClient client = GetResourceClient(disposingContainer.Container);
                await InitializeResourceAsync(client);

                parameters.NoneMatch = await GetMatchConditionAsync(client, parameters.NoneMatch);

                TRequestConditions accessConditions = BuildRequestConditions(parameters);

                byte[] data = GetRandomBuffer(Constants.KB);
                using Stream stream = new MemoryStream(data);

                await TestHelper.AssertExpectedExceptionAsync <RequestFailedException>(
                    OpenWriteAsync(
                        client,
                        overwrite : true,
                        conditions : accessConditions),
                    e => Assert.AreEqual(ConditionNotMetErrorCode, e.ErrorCode));
            }
        }
Exemple #7
0
        public virtual async Task OpenReadAsync_Modified()
        {
            int size       = Constants.KB;
            int bufferSize = size / 2;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            var             data   = GetRandomBuffer(size);
            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data));

            // Act
            Stream outputStream = await OpenReadAsync(client, bufferSize : bufferSize);

            byte[] outputBytes = new byte[size];
            await outputStream.ReadAsync(outputBytes, 0, size / 2);

            // Modify the blob.
            await ModifyDataAsync(client, new MemoryStream(GetRandomBuffer(size)), ModifyDataMode.Replace);

            // Assert
            await AssertExpectedExceptionOpenReadModifiedAsync(outputStream.ReadAsync(outputBytes, size / 2, size / 2));
        }
Exemple #8
0
        public async Task OpenWriteAsync_AppendExistingBlob()
        {
            await using IDisposingContainer <BlobContainerClient> disposingContainer = await GetDisposingContainerAsync();

            AppendBlobClient blob = GetResourceClient(disposingContainer.Container);
            await blob.CreateAsync();

            byte[] originalData = GetRandomBuffer(Constants.KB);
            using Stream originalStream = new MemoryStream(originalData);

            await blob.AppendBlockAsync(content: originalStream);

            byte[] newData = GetRandomBuffer(Constants.KB);
            using Stream newStream = new MemoryStream(newData);

            // Act
            Stream openWriteStream = await blob.OpenWriteAsync(overwrite : false);

            await newStream.CopyToAsync(openWriteStream);

            await openWriteStream.FlushAsync();

            // Assert
            byte[] expectedData = new byte[2 * Constants.KB];
            Array.Copy(originalData, 0, expectedData, 0, Constants.KB);
            Array.Copy(newData, 0, expectedData, Constants.KB, Constants.KB);

            Response <BlobDownloadInfo> result = await blob.DownloadAsync(new HttpRange(0, 2 * Constants.KB));

            MemoryStream dataResult = new MemoryStream();
            await result.Value.Content.CopyToAsync(dataResult);

            Assert.AreEqual(expectedData.Length, dataResult.Length);
            TestHelper.AssertSequenceEqual(expectedData, dataResult.ToArray());
        }
Exemple #9
0
        public virtual async Task UploadPartitionSuccessfulHashComputation(TransactionalHashAlgorithm algorithm)
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            const int dataLength     = Constants.KB;
            var       data           = GetRandomBuffer(dataLength);
            var       hashingOptions = new UploadTransactionalHashingOptions
            {
                Algorithm = algorithm
            };

            // make pipeline assertion for checking hash was present on upload
            var hashPipelineAssertion = new AssertMessageContentsPolicy(checkRequest: GetRequestHashAssertion(algorithm));
            var clientOptions         = ClientBuilder.GetOptions();

            clientOptions.AddPolicy(hashPipelineAssertion, HttpPipelinePosition.PerCall);

            var client = await GetResourceClientAsync(
                disposingContainer.Container,
                resourceLength : dataLength,
                createResource : true,
                options : clientOptions);

            // Act
            using (var stream = new MemoryStream(data))
            {
                hashPipelineAssertion.CheckRequest = true;
                await UploadPartitionAsync(client, stream, hashingOptions);
            }

            // Assert
            // Assertion was in the pipeline and the service returning success means the hash was correct
        }
Exemple #10
0
        public async Task OpenReadAsync_InvalidParameterTests()
        {
            int size = Constants.KB;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            var             data   = GetRandomBuffer(size);
            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data));

            Stream stream = await OpenReadAsync(client);

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentNullException>(
                stream.ReadAsync(buffer: null, offset: 0, count: 10),
                new ArgumentNullException("buffer", "buffer cannot be null."));

            await TestHelper.AssertExpectedExceptionAsync <ArgumentOutOfRangeException>(
                stream.ReadAsync(buffer: new byte[10], offset: -1, count: 10),
                new ArgumentOutOfRangeException("offset", "offset cannot be less than 0."));

            await TestHelper.AssertExpectedExceptionAsync <ArgumentOutOfRangeException>(
                stream.ReadAsync(buffer: new byte[10], offset: 11, count: 10),
                new ArgumentOutOfRangeException("offset", "offset cannot exceed buffer length."));

            await TestHelper.AssertExpectedExceptionAsync <ArgumentOutOfRangeException>(
                stream.ReadAsync(buffer: new byte[10], offset: 1, count: -1),
                new ArgumentOutOfRangeException("count", "count cannot be less than 0."));
        }
Exemple #11
0
        public async Task OpenReadAsync_SetPosition(long position)
        {
            int size           = Constants.KB;
            int bufferSize     = 128;
            int initalPosition = 450;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            byte[] data         = GetRandomBuffer(size);
            byte[] expectedData = new byte[size - position];
            Array.Copy(data, position, expectedData, 0, size - position);
            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data));

            // Act
            Stream openReadStream = await OpenReadAsync(client, bufferSize : bufferSize);

            int readbytes = initalPosition;

            while (readbytes > 0)
            {
                readbytes -= await openReadStream.ReadAsync(new byte[readbytes], 0, readbytes);
            }

            openReadStream.Position = position;

            using MemoryStream outputStream = new MemoryStream();
            await openReadStream.CopyToAsync(outputStream);

            // Assert
            Assert.AreEqual(expectedData.Length, outputStream.ToArray().Length);
            TestHelper.AssertSequenceEqual(expectedData, outputStream.ToArray());
        }
Exemple #12
0
        public async Task OpenReadAsync_Seek_PositionUnchanged()
        {
            int size = Constants.KB;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            var             data   = GetRandomBuffer(size);
            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data));

            // Act
            Stream outputStream = await OpenReadAsync(client);

            byte[] outputBytes = new byte[size];
            outputStream.Seek(0, SeekOrigin.Begin);

            Assert.AreEqual(0, outputStream.Position);

            await outputStream.ReadAsync(outputBytes, 0, size);

            // Assert
            Assert.AreEqual(data.Length, outputStream.Length);
            TestHelper.AssertSequenceEqual(data, outputBytes);
        }
Exemple #13
0
        public async Task OpenReadAsync_OffsetAndBufferSize()
        {
            int size       = Constants.KB;
            int bufferSize = size / 8;
            int position   = size / 2;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            var             data   = GetRandomBuffer(size);
            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data));

            byte[] expected = new byte[size];
            Array.Copy(data, position, expected, position, size - position);

            // Act
            Stream outputStream = await OpenReadAsync(client, bufferSize : bufferSize, position : position);

            byte[] outputBytes = new byte[size];

            int downloadedBytes = position;

            while (downloadedBytes < size)
            {
                downloadedBytes += await outputStream.ReadAsync(outputBytes, downloadedBytes, size / 4);
            }

            // Assert
            Assert.AreEqual(data.Length, outputStream.Length);
            TestHelper.AssertSequenceEqual(expected, outputBytes);
        }
Exemple #14
0
        public async Task OpenReadAsync_ModifiedAllowBlobModifications()
        {
            int size = Constants.KB;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            byte[] data0        = GetRandomBuffer(size);
            byte[] data1        = GetRandomBuffer(size);
            byte[] expectedData = new byte[2 * size];
            Array.Copy(data0, 0, expectedData, 0, size);
            Array.Copy(data1, 0, expectedData, size, size);

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data0));

            // Act
            Stream outputStream = await OpenReadAsync(client, allowModifications : true);

            byte[] outputBytes = new byte[2 * size];
            await outputStream.ReadAsync(outputBytes, 0, size);

            // Modify the blob.
            await ModifyDataAsync(client, new MemoryStream(data1), ModifyDataMode.Append);

            await outputStream.ReadAsync(outputBytes, size, size);

            // Assert
            TestHelper.AssertSequenceEqual(expectedData, outputBytes);
        }
Exemple #15
0
        public virtual async Task OpenReadAsync_AccessConditionsFail()
        {
            // Arrange
            int size           = Constants.KB;
            int bufferSize     = size / 4;
            var garbageLeaseId = GetGarbageLeaseId();

            foreach (AccessConditionParameters parameters in Conditions.GetAccessConditionsFail_Data(garbageLeaseId))
            {
                await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

                var             data   = GetRandomBuffer(size);
                TResourceClient client = GetResourceClient(disposingContainer.Container);
                await StageDataAsync(client, new MemoryStream(data));

                parameters.NoneMatch = await GetMatchConditionAsync(client, parameters.NoneMatch);

                TRequestConditions conditions = BuildRequestConditions(parameters, lease: true);

                // Act

                await TestHelper.CatchAsync <Exception>(
                    async() =>
                {
                    var _ = await OpenReadAsync(client, bufferSize: bufferSize, conditions: conditions);
                });
            }
        }
        public override async Task OpenWriteAsync_WithIntermediateFlushes()
        {
            // Arrange
            await using IDisposingContainer <BlobContainerClient> disposingContainer = await GetDisposingContainerAsync();

            PageBlobClient client = GetResourceClient(disposingContainer.Container);

            // Act
            using (Stream stream = await OpenWriteAsync(client, overwrite: true, maxDataSize: 2 * Constants.KB, bufferSize: 2 * Constants.KB))
            {
                using (var writer = new StreamWriter(stream, Encoding.ASCII))
                {
                    writer.Write(new string('A', 512));
                    writer.Flush();

                    writer.Write(new string('B', 1024));
                    writer.Flush();

                    writer.Write(new string('C', 512));
                    writer.Flush();
                }
            }

            // Assert
            byte[] dataResult = (await DownloadAsync(client)).ToArray();
            Assert.AreEqual(new string('A', 512) + new string('B', 1024) + new string('C', 512), Encoding.ASCII.GetString(dataResult));

            await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
        }
Exemple #17
0
        public async Task OpenWriteAsync_CreateEmptyBlob_WithTags()
        {
            const int bufferSize = Constants.KB;

            // Arrange
            await using IDisposingContainer <BlobContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TBlobClient client = GetResourceClient(disposingContainer.Container);

            await InitializeResourceAsync(client);

            Dictionary <string, string> tags = new Dictionary <string, string>()
            {
                { "testkey", "testvalue" }
            };

            // Act
            Stream stream = await OpenWriteAsync(
                client,
                overwrite : true,
                bufferSize : bufferSize,
                tags : tags);

            // Assert
            CollectionAssert.AreEqual(tags, await GetTagsAsync(client));
        }
Exemple #18
0
        public virtual async Task UploadPartitionMismatchedHashThrows(TransactionalHashAlgorithm algorithm)
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            const int dataLength     = Constants.KB;
            var       data           = GetRandomBuffer(dataLength);
            var       hashingOptions = new UploadTransactionalHashingOptions
            {
                Algorithm = algorithm
            };

            // Tamper with stream contents in the pipeline to simulate silent failure in the transit layer
            var streamTamperPolicy = new TamperStreamContentsPolicy();
            var clientOptions      = ClientBuilder.GetOptions();

            clientOptions.AddPolicy(streamTamperPolicy, HttpPipelinePosition.PerCall);

            var client = await GetResourceClientAsync(
                disposingContainer.Container,
                resourceLength : dataLength,
                createResource : true,
                options : clientOptions);

            using (var stream = new MemoryStream(data))
            {
                // Act
                streamTamperPolicy.TransformRequestBody = true;
                AsyncTestDelegate operation = async() => await UploadPartitionAsync(client, stream, hashingOptions);

                // Assert
                AssertWriteHashMismatch(operation, algorithm);
            }
        }
        public async Task OpenWriteAsync_CreateEmptyBlob_WithHeaders()
        {
            const int bufferSize = Constants.KB;

            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            HttpHeaderParameters headers = new HttpHeaderParameters
            {
                ContentType     = "application/json",
                ContentLanguage = "en",
            };

            // Act
            using (Stream stream = await OpenWriteAsync(
                       client,
                       overwrite: true,
                       maxDataSize: Constants.KB,
                       bufferSize: bufferSize,
                       httpHeaders: headers))
            {
            }

            // Assert
            Response response = await GetPropertiesAsync(client);

            Assert.IsTrue(response.Headers.TryGetValue("Content-Type", out string downloadedContentType));
            Assert.AreEqual(headers.ContentType, downloadedContentType);
            Assert.IsTrue(response.Headers.TryGetValue("Content-Language", out string downloadedContentLanguage));
            Assert.AreEqual(headers.ContentLanguage, downloadedContentLanguage);

            await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
        }
Exemple #20
0
        public async Task OpenReadAsync_Error()
        {
            // Arrange
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            TResourceClient client = GetResourceClient(disposingContainer.Container);

            // Act
            await TestHelper.AssertExpectedExceptionAsync <RequestFailedException>(
                OpenReadAsync(client),
                e => Assert.AreEqual(OpenReadAsync_Error_Code, e.ErrorCode));
        }
Exemple #21
0
        public virtual async Task DownloadHashMismatchThrows(
            [Values(TransactionalHashAlgorithm.MD5, TransactionalHashAlgorithm.StorageCrc64)] TransactionalHashAlgorithm algorithm,
            [Values(true, false)] bool validate)
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            const int dataLength = Constants.KB;
            var       data       = GetRandomBuffer(dataLength);

            var resourceName = GetNewResourceName();
            var client       = await GetResourceClientAsync(
                disposingContainer.Container,
                resourceLength : dataLength,
                createResource : true,
                resourceName : resourceName);

            await SetupDataAsync(client, new MemoryStream(data));

            var hashingOptions = new DownloadTransactionalHashingOptions {
                Algorithm = algorithm, Validate = validate
            };

            // alter response contents in pipeline, forcing a hash mismatch on verification step
            var clientOptions = ClientBuilder.GetOptions();

            clientOptions.AddPolicy(new TamperStreamContentsPolicy()
            {
                TransformResponseBody = true
            }, HttpPipelinePosition.PerCall);
            client = await GetResourceClientAsync(
                disposingContainer.Container,
                createResource : false,
                resourceName : resourceName,
                options : clientOptions);

            // Act
            AsyncTestDelegate operation = async() => await DownloadPartitionAsync(client, Stream.Null, hashingOptions, new HttpRange(length : data.Length));

            // Assert
            if (validate)
            {
                // SDK responsible for finding bad hash. Throw.
                ThrowsOrInconclusiveAsync <InvalidDataException>(operation);
            }
            else
            {
                // bad hash is for caller to find. Don't throw.
                await DoesNotThrowOrInconclusiveAsync(operation);
            }
        }
        public async Task OpenWriteAsync_NewBlobNoSize()
        {
            // Arrange
            await using IDisposingContainer <BlobContainerClient> disposingContainer = await GetDisposingContainerAsync();

            PageBlobClient blob = GetResourceClient(disposingContainer.Container);

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentException>(
                blob.OpenWriteAsync(
                    overwrite: false,
                    position: 0),
                e => Assert.AreEqual("options.Size must be set if the Page Blob is being created for the first time", e.Message));
        }
        public async Task OpenWriteAsync_OverwriteNoSize()
        {
            // Arrange
            await using IDisposingContainer <BlobContainerClient> disposingContainer = await GetDisposingContainerAsync();

            PageBlobClient blob = GetResourceClient(disposingContainer.Container);

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentException>(
                blob.OpenWriteAsync(
                    overwrite: true,
                    position: 0),
                e => Assert.AreEqual("options.Size must be set if overwrite is set to true", e.Message));
        }
        public async Task OpenWriteAsync_AccessConditions()
        {
            foreach (AccessConditionParameters parameters in Conditions.AccessConditions_Data)
            {
                // Arrange
                await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

                TResourceClient client = GetResourceClient(disposingContainer.Container);

                // initialize client with starter data
                using (Stream dest = await OpenWriteAsync(
                           client,
                           overwrite: true,
                           maxDataSize: Constants.KB))
                {
                    await new MemoryStream(GetRandomBuffer(Constants.KB)).CopyToAsync(dest);
                    await dest.FlushAsync();
                }

                var garbageLeaseId = GetGarbageLeaseId();
                parameters.Match = await GetMatchConditionAsync(client, parameters.Match);

                parameters.LeaseId = await SetupLeaseAsync(client, parameters.LeaseId, garbageLeaseId);

                TRequestConditions accessConditions = BuildRequestConditions(parameters);

                byte[] data = GetRandomBuffer(Constants.KB);
                using Stream stream = new MemoryStream(data);

                // Act
                using (Stream openWriteStream = await OpenWriteAsync(
                           client,
                           overwrite: true,
                           maxDataSize: data.Length,
                           conditions: accessConditions))
                {
                    await stream.CopyToAsync(openWriteStream);

                    await openWriteStream.FlushAsync();
                }

                // Assert
                byte[] dataResult = (await DownloadAsync(client)).ToArray();
                Assert.AreEqual(data.Length, dataResult.Length);
                TestHelper.AssertSequenceEqual(data, dataResult);

                await(AdditionalAssertions?.Invoke(client) ?? Task.CompletedTask);
            }
        }
Exemple #25
0
        public virtual async Task OpenReadSuccessfulHashVerification(
            [Values(TransactionalHashAlgorithm.MD5, TransactionalHashAlgorithm.StorageCrc64)] TransactionalHashAlgorithm algorithm,
            [Values(
                 // multiple reads that neatly align
                 Constants.KB,
                 // multiple reads with final having leftover buffer space
                 2 * Constants.KB,
                 // buffer larger than data
                 4 * Constants.KB)] int bufferSize)
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            // bufferSize/datasize MUST be a multiple of 512 for pageblob tests
            const int dataLength = 3 * Constants.KB;
            var       data       = GetRandomBuffer(dataLength);

            var resourceName = GetNewResourceName();
            var client       = await GetResourceClientAsync(
                disposingContainer.Container,
                resourceLength : dataLength,
                createResource : true,
                resourceName : resourceName);

            await SetupDataAsync(client, new MemoryStream(data));

            // make pipeline assertion for checking hash was present on download
            var hashPipelineAssertion = new AssertMessageContentsPolicy(checkResponse: GetResponseHashAssertion(algorithm));
            var clientOptions         = ClientBuilder.GetOptions();

            clientOptions.AddPolicy(hashPipelineAssertion, HttpPipelinePosition.PerCall);

            client = await GetResourceClientAsync(
                disposingContainer.Container,
                createResource : false,
                resourceName : resourceName,
                options : clientOptions);

            var hashingOptions = new DownloadTransactionalHashingOptions {
                Algorithm = algorithm
            };

            // Act
            var readStream = await OpenReadAsync(client, hashingOptions, bufferSize);

            // Assert
            hashPipelineAssertion.CheckResponse = true;
            await DoesNotThrowOrInconclusiveAsync(async() => await readStream.CopyToAsync(Stream.Null));
        }
Exemple #26
0
        public virtual async Task ParallelDownloadSuccessfulHashVerification(
            [Values(TransactionalHashAlgorithm.MD5, TransactionalHashAlgorithm.StorageCrc64)] TransactionalHashAlgorithm algorithm,
            [Values(512, 2 * Constants.KB)] int chunkSize)
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            const int dataLength = 2 * Constants.KB;
            var       data       = GetRandomBuffer(dataLength);

            var resourceName = GetNewResourceName();
            var client       = await GetResourceClientAsync(
                disposingContainer.Container,
                resourceLength : dataLength,
                createResource : true,
                resourceName : resourceName);

            await SetupDataAsync(client, new MemoryStream(data));

            // make pipeline assertion for checking hash was present on download
            var hashPipelineAssertion = new AssertMessageContentsPolicy(checkResponse: GetResponseHashAssertion(algorithm));
            var clientOptions         = ClientBuilder.GetOptions();

            clientOptions.AddPolicy(hashPipelineAssertion, HttpPipelinePosition.PerCall);

            client = await GetResourceClientAsync(
                disposingContainer.Container,
                createResource : false,
                resourceName : resourceName,
                options : clientOptions);

            var hashingOptions = new DownloadTransactionalHashingOptions {
                Algorithm = algorithm
            };
            StorageTransferOptions transferOptions = new StorageTransferOptions
            {
                InitialTransferSize = chunkSize,
                MaximumTransferSize = chunkSize
            };

            // Act
            hashPipelineAssertion.CheckResponse = true;
            await ParallelDownloadAsync(client, Stream.Null, hashingOptions, transferOptions);

            // Assert
            // Assertion was in the pipeline and the SDK not throwing means the hash was validated
        }
Exemple #27
0
        public virtual async Task UploadPartitionUsePrecalculatedHash(TransactionalHashAlgorithm algorithm)
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            const int dataLength = Constants.KB;
            var       data       = GetRandomBuffer(dataLength);
            // service throws different error for crc only when hash size in incorrect; we don't want to test that
            var hashSizeBytes = algorithm switch
            {
                TransactionalHashAlgorithm.MD5 => 16,
                TransactionalHashAlgorithm.StorageCrc64 => 8,
                _ => throw new ArgumentException("Cannot determine hash size for provided algorithm type")
            };
            // hash needs to be wrong so we detect difference from auto-SDK correct calculation
            var precalculatedHash = GetRandomBuffer(hashSizeBytes);
            var hashingOptions    = new UploadTransactionalHashingOptions
            {
                Algorithm         = algorithm,
                PrecalculatedHash = precalculatedHash
            };

            // make pipeline assertion for checking precalculated hash was present on upload
            var hashPipelineAssertion = new AssertMessageContentsPolicy(checkRequest: GetRequestHashAssertion(algorithm, expectedHash: precalculatedHash));
            var clientOptions         = ClientBuilder.GetOptions();

            clientOptions.AddPolicy(hashPipelineAssertion, HttpPipelinePosition.PerCall);

            var client = await GetResourceClientAsync(
                disposingContainer.Container,
                resourceLength : dataLength,
                createResource : true,
                options : clientOptions);

            hashPipelineAssertion.CheckRequest = true;
            using (var stream = new MemoryStream(data))
            {
                // Act
                AsyncTestDelegate operation = async() => await UploadPartitionAsync(client, stream, hashingOptions);

                // Assert
                AssertWriteHashMismatch(operation, algorithm);
            }
        }
Exemple #28
0
        public async Task OpenReadAsync_Seek_NegativeNewPosition()
        {
            int size = Constants.KB;

            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            var             data   = GetRandomBuffer(size);
            TResourceClient client = GetResourceClient(disposingContainer.Container);

            await StageDataAsync(client, new MemoryStream(data));

            // Act
            Stream outputStream = await OpenReadAsync(client);

            TestHelper.AssertExpectedException <ArgumentException>(
                () => outputStream.Seek(-10, SeekOrigin.Begin),
                new ArgumentException("New offset cannot be less than 0.  Value was -10", "offset"));
        }
        public async Task OpenWriteAsync_Position()
        {
            // Arrange
            await using IDisposingContainer <BlobContainerClient> disposingContainer = await GetDisposingContainerAsync();

            PageBlobClient blob = GetResourceClient(disposingContainer.Container);
            await blob.CreateAsync(Constants.KB);

            byte[] data0 = GetRandomBuffer(512);
            byte[] data1 = GetRandomBuffer(512);
            using Stream dataStream0 = new MemoryStream(data0);
            using Stream dataStream1 = new MemoryStream(data1);
            byte[] expectedData = new byte[Constants.KB];
            Array.Copy(data0, expectedData, 512);
            Array.Copy(data1, 0, expectedData, 512, 512);

            // Act
            Stream openWriteStream = await blob.OpenWriteAsync(
                overwrite : false,
                position : 0);

            Assert.AreEqual(0, openWriteStream.Position);

            await dataStream0.CopyToAsync(openWriteStream);

            Assert.AreEqual(512, openWriteStream.Position);

            await dataStream1.CopyToAsync(openWriteStream);

            Assert.AreEqual(1024, openWriteStream.Position);

            await openWriteStream.FlushAsync();

            Assert.AreEqual(1024, openWriteStream.Position);

            Response <BlobDownloadInfo> result = await blob.DownloadAsync();

            MemoryStream dataResult = new MemoryStream();
            await result.Value.Content.CopyToAsync(dataResult);

            Assert.AreEqual(expectedData.Length, dataResult.Length);
            TestHelper.AssertSequenceEqual(expectedData, dataResult.ToArray());
        }
Exemple #30
0
        public async Task RoundtripWIthDefaults()
        {
            await using IDisposingContainer <TContainerClient> disposingContainer = await GetDisposingContainerAsync();

            // Arrange
            const TransactionalHashAlgorithm expectedAlgorithm = TransactionalHashAlgorithm.StorageCrc64;
            const int dataLength                   = Constants.KB;
            var       data                         = GetRandomBuffer(dataLength);
            var       uploadHashingOptions         = new UploadTransactionalHashingOptions();
            var       downloadHashingOptions       = new DownloadTransactionalHashingOptions();
            var       clientOptions                = ClientBuilder.GetOptions();
            StorageTransferOptions transferOptions = new StorageTransferOptions
            {
                InitialTransferSize = 512,
                MaximumTransferSize = 512
            };

            // make pipeline assertion for checking hash was present on upload AND download
            var hashPipelineAssertion = new AssertMessageContentsPolicy(
                checkRequest: GetRequestHashAssertion(expectedAlgorithm, isHashExpected: ParallelUploadIsHashExpected),
                checkResponse: GetResponseHashAssertion(expectedAlgorithm));

            clientOptions.AddPolicy(hashPipelineAssertion, HttpPipelinePosition.PerCall);

            var client = await GetResourceClientAsync(disposingContainer.Container, resourceLength : dataLength, createResource : true, options : clientOptions);

            // Act
            using (var stream = new MemoryStream(data))
            {
                hashPipelineAssertion.CheckRequest = true;
                await ParallelUploadAsync(client, stream, uploadHashingOptions, transferOptions);

                hashPipelineAssertion.CheckRequest = false;
            }

            hashPipelineAssertion.CheckResponse = true;
            await ParallelDownloadAsync(client, Stream.Null, downloadHashingOptions, transferOptions);

            // Assert
            // Assertion was in the pipeline and the service returning success means the hash was correct
        }