public void Execute_BlockListWithContent_ContentSetProperly()
        {
            var expectedContainer = "test-container";
            var expectedBlob = "test-blob";
            var expectedUri = String.Format("{0}/{1}/{2}?comp=blocklist", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)201, "Created", "", false, new Dictionary<string, string>(){
                                                {"ETag", "\"123\""},
                                                {"Date", DateTime.UtcNow.ToString() },
                                                {"Last-Modified", DateTime.UtcNow.ToString() },
                                                {"Content-MD5", "123-MD5" }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var id1 = Base64Converter.ConvertToBase64("id1");
            var id2 = Base64Converter.ConvertToBase64("id2");
            var id3 = Base64Converter.ConvertToBase64("id3");
            var expectedData = string.Format(
@"<?xml version=""1.0"" encoding=""utf-8""?><BlockList><Committed>{0}</Committed><Uncommitted>{1}</Uncommitted><Latest>{2}</Latest></BlockList>",
id1, id2, id3);
            var givenData = new BlockListBlockIdList
            {
                new BlockListBlockId { Id = id1, ListType = PutBlockListListType.Committed},
                new BlockListBlockId { Id = id2, ListType = PutBlockListListType.Uncommitted},
                new BlockListBlockId { Id = id3, ListType = PutBlockListListType.Latest}
            };

            var request = new PutBlockListRequest(_settings, expectedContainer, expectedBlob, givenData);

            request.Execute();

            Assert.AreEqual(expectedData, Encoding.UTF8.GetString(givenData.AsXMLByteArray()));
        }
        public void Execute_BlockListWithAllHeaders_AllHeadersSetProperly()
        {
            var expectedContainer = "test-container";
            var expectedBlob = "test-blob";
            var expectedUri = String.Format("{0}/{1}/{2}?comp=blocklist", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)201, "Created", "", false, new Dictionary<string, string>(){
                                                {"ETag", "\"123\""},
                                                {"Date", DateTime.UtcNow.ToString() },
                                                {"Last-Modified", DateTime.UtcNow.ToString() },
                                                {"Content-MD5", "123-MD5" }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var expectedData = new BlockListBlockIdList();
            var expectedContentMD5 = expectedData.AsXmlByteArrayWithMd5Hash().MD5Hash;

            var request = new PutBlockListRequest(_settings, expectedContainer, expectedBlob, expectedData,
                "cache/control", "content/type", "content/encoding", "content/language", "blobContent/md5");

            request.Execute();

            Assert.AreEqual(expectedContentMD5, expectedRawRequest.Headers["Content-MD5"]);
            Assert.AreEqual("cache/control", expectedRawRequest.Headers["x-ms-blob-cache-control"]);
            Assert.AreEqual("content/type", expectedRawRequest.Headers["x-ms-blob-content-type"]);
            Assert.AreEqual("content/encoding", expectedRawRequest.Headers["x-ms-blob-content-encoding"]);
            Assert.AreEqual("content/language", expectedRawRequest.Headers["x-ms-blob-content-language"]);
            Assert.AreEqual("blobContent/md5", expectedRawRequest.Headers["x-ms-blob-content-md5"]);
        }
        public void Execute_PageBlobWithAllHeaders_AllHeadersSetProperly()
        {
            var expectedContainer = "test-container";
            var expectedBlob = "test-blob";
            var expectedUri = String.Format("{0}/{1}/{2}", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)201, "Created", "", false, new Dictionary<string, string>(){
                                                {"ETag", "\"123\""},
                                                {"Date", DateTime.UtcNow.ToString() },
                                                {"Last-Modified", DateTime.UtcNow.ToString() },
                                                {"Content-MD5", "123-MD5" }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new PutBlobRequest(_settings, expectedContainer, expectedBlob, 12345,
                                            "content/type", "content/encoding", "content/language",
                                            "content/md5", "cache/control", null, 321);

            var response = request.Execute();

            Assert.AreEqual(0, expectedRawRequest.ContentLength);
            Assert.AreEqual("12345", expectedRawRequest.Headers["x-ms-blob-content-length"]);
            Assert.AreEqual("content/type", expectedRawRequest.ContentType);
            Assert.AreEqual("content/encoding", expectedRawRequest.Headers["Content-Encoding"]);
            Assert.AreEqual("content/language", expectedRawRequest.Headers["Content-Language"]);
            Assert.AreEqual("content/md5", expectedRawRequest.Headers["Content-MD5"]);
            Assert.AreEqual("cache/control", expectedRawRequest.Headers["Cache-Control"]);
            Assert.AreEqual("321", expectedRawRequest.Headers["x-ms-blob-sequence-number"]);
        }
        public async Task Execute_PutBlockAsync_ResponseParsesHeadersCorrectly()
        {
            var expectedContainer = "test-container";
            var expectedBlob = "test-blob";
            var expectedBlock = Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes("test-block-id"));
            var urlEncodedExpectedBlock = WebUtility.UrlEncode(expectedBlock);
            var expectedDate = DateTime.UtcNow;
            var expectedMD5 = "test-MD5";
            var expectedData = new byte[] { };

            var expectedUri = String.Format("{0}/{1}/{2}?comp=block&blockid={3}", _settings.BlobEndpoint, expectedContainer, expectedBlob, urlEncodedExpectedBlock);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)201, "Created", "", false, new Dictionary<string, string>(){
                                                {"Content-MD5", expectedMD5},
                                                {"Date", expectedDate.ToString() }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);

            var request = new PutBlockRequest(_settings, expectedContainer, expectedBlob, expectedBlock, expectedData);

            var response = await request.ExecuteAsync();

            Assert.AreEqual(response.HttpStatus, HttpStatusCode.Created);
            Assert.AreEqual(response.Payload.ContentMD5, expectedMD5);
            Assert.IsTrue(Math.Abs(expectedDate.Subtract(response.Payload.Date).TotalMinutes) < 1);
        }
        public void Execute_CopyBlob_ResponseParsesHeadersCorrectly()
        {
            const string expectedContainer = "test-container";
            const string expectedBlob = "test-blob";
            const string copySource = "http://foo.foo.foo/testContainer/testBlob";
            var expectedUri = String.Format("{0}/{1}/{2}", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedDate = DateTime.UtcNow.AddDays(-2345);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)201, "Success", "", false, new Dictionary<string, string>(){
                                                {"ETag", "\"123\""},
                                                {"Date", expectedDate.ToString() },
                                                {"Last-Modified", expectedDate.ToString() },
                                                {"x-ms-copy-id", "123-copy-id" },
                                                {"x-ms-copy-status", "success" }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new CopyBlobRequest(_settings, expectedContainer, expectedBlob, copySource);

            var response = request.Execute();

            Assert.AreEqual("123", response.Payload.ETag);
            Assert.IsTrue(Math.Abs(expectedDate.Subtract(response.Payload.Date).TotalMinutes) < 1);
            Assert.IsTrue(Math.Abs(expectedDate.Subtract(response.Payload.LastModified).TotalMinutes) < 1);
            Assert.AreEqual("123-copy-id", response.Payload.CopyId);
            Assert.AreEqual(CopyStatus.Success, response.Payload.CopyStatus);
        }
 public void AddRequest(TestableWebRequest request)
 {
     lock (_preparedRequests)
     {
         if (_preparedRequests.ContainsKey(request.RequestUri.AbsoluteUri))
             _preparedRequests.Remove(request.RequestUri.AbsoluteUri);
         _preparedRequests.Add(request.RequestUri.AbsoluteUri, request);
     }
 }
Пример #7
0
 public void AddRequest(TestableWebRequest request)
 {
     lock (_preparedRequests)
     {
         if (_preparedRequests.ContainsKey(request.RequestUri.AbsoluteUri))
         {
             _preparedRequests.Remove(request.RequestUri.AbsoluteUri);
         }
         _preparedRequests.Add(request.RequestUri.AbsoluteUri, request);
     }
 }
        public void Execute_SuccessfulOperation_MarksResponseAsSuccessfull()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri));
            expectedRawRequest.EnqueueResponse(HttpStatusCode.OK, "Success", "Response content", false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            var response = request.Execute();

            Assert.AreEqual(HttpStatusCode.OK, response.HttpStatus);
        }
        public void Execute_TimeoutException_AttemptsToRetry()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                        .EnqueueResponse(new TimeoutException("message"))
                                        .EnqueueResponse(HttpStatusCode.OK, "Success", "Even More Success", false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            var response = request.Execute();

            Assert.AreEqual(2, response.NumberOfAttempts);
        }
        public void Execute_ReceivesStatusError_AttemptsToRetry(string errorCode, int httpStatus, string errorMessage)
        {
            var expectedUri = "test://queue.abc/whatever/";
            var azureErrorMessage = String.Format("<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>{0}</Code><Message>{1}</Message></Error>", errorCode, errorMessage);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                        .EnqueueResponse((HttpStatusCode)httpStatus, errorCode, azureErrorMessage, true)
                                        .EnqueueResponse(HttpStatusCode.OK, "Success", "Response content", false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            var response = request.Execute();

            Assert.AreEqual(2, response.NumberOfAttempts);
        }
        public void Execute_ExpectingEmptyPayload_ConsumesResponseStream()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri));
            var expectedRawResponse = new HttpResponseSettings(HttpStatusCode.OK, "Success", "Response content", false);
            expectedRawRequest.EnqueueResponse(expectedRawResponse);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            var response = request.Execute();

            // expect the response stream to be closed now
            long x;
            Assert.Throws<ObjectDisposedException>(() => x = expectedRawResponse.ResponseStream.Position);
        }
        public async Task Execute_DeleteBlobAsync_ResponseParsesHeadersCorrectly()
        {
            var expectedContainer = "test-container";
            var expectedBlob = "test-blob";
            var expectedUri = String.Format("{0}/{1}/{2}", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)202, "Accepted", "", false, new Dictionary<string, string>(){
                                                {"Date", DateTime.UtcNow.ToString() }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var expectedDate = DateTime.UtcNow;
            var request = new DeleteBlobRequest(_settings, expectedContainer, expectedBlob);

            var response = await request.ExecuteAsync();

            Assert.AreEqual(response.HttpStatus, HttpStatusCode.Accepted);
            Assert.IsTrue(Math.Abs(expectedDate.Subtract(response.Payload.Date).TotalMinutes) < 1);
        }
        public void Execute_CopyBlobWithAllHeaders_AllHeadersSetProperly()
        {
            const string expectedContainer = "test-container";
            const string expectedBlob = "test-blob";
            const string copySource = "http://foo.foo.foo/testContainer/testBlob";
            var expectedUri = String.Format("{0}/{1}/{2}", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)202, "Accepted", "", false, new Dictionary<string,string>(){
                                                {"ETag", "\"123\""},
                                                {"Date", DateTime.UtcNow.ToString() },
                                                {"Last-Modified", DateTime.UtcNow.ToString() },
                                                {"x-ms-copy-id", "123-copy-id" },
                                                {"x-ms-copy-status", "success" }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new CopyBlobRequest(_settings, expectedContainer, expectedBlob, copySource);
            
            request.Execute();

            Assert.AreEqual(copySource, expectedRawRequest.Headers["x-ms-copy-source"]);
        }
 public void Execute_CommonApiException_MapsToProperAzureException(string exceptionName, string errorCode, int httpStatus, string errorMessage)
 {
     //arrange
     string expectedExceptionName = exceptionName + "AzureException";
     var expectedUri = "test://common-api-errors.abc/whatever/";
     var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri));
     expectedRawRequest.EnqueueResponse((HttpStatusCode)httpStatus, errorCode, ErrorContentFor(errorCode, errorMessage), true);
     TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
     var request = new RequestWithErrorPayload(new SettingsFake(), expectedUri, "GET", StorageServiceType.QueueService);
     request.RetryPolicy = new RetryPolicy<ExceptionRetryStrategy>(0);
     try
     {
         //act
         var response = request.Execute();
     }
     catch (AzureException ae)
     {
         //assert
         Assert.AreEqual(expectedExceptionName, ae.GetType().Name);
     }
 }
        public void Execute_ReceiveTransientExceptionThenNonTransient_ThrowsNonTransient()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                .EnqueueResponse(new WebException("Azure hung up after the initial request", new SocketException(1), WebExceptionStatus.ReceiveFailure, null))
                .EnqueueResponse(HttpStatusCode.Conflict, "QueueAlreadyExists", queueAlreadyExistsExceptionText, true);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            request.Execute();

            // expected non transient exception
        }
        public void Execute_ConnectFailureException_AttemptsToRetry()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                        .EnqueueResponse(new WebException("Could not connect because Azure crashed", new SocketException(1), WebExceptionStatus.ConnectFailure, null))
                                        .EnqueueResponse(HttpStatusCode.OK, "Success", "Even More Success", false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            var response = request.Execute();

            Assert.AreEqual(2, response.NumberOfAttempts);
        }
        public void Execute_FailsUntilRetryCountExceeded_ThenGivesUp()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new TimeoutException("message 1"))
                                            .EnqueueResponse(new TimeoutException("message 2"))
                                            .EnqueueResponse(new TimeoutException("message 3"))
                                            .EnqueueResponse(HttpStatusCode.OK, "Success", "Should give up before it gets this one", false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");
            request.RetryPolicy = new RetryPolicy<ExceptionRetryStrategy>(2, TimeSpan.FromMilliseconds(1));

            var response = request.Execute();

            // expecting an exception
        }
        public void Execute_FailsUntilRetryCountExceeded_ThrowsExceptionWithProperRetryStack()
        {
            var expectedUri = "test://queue.abc/whatever/";
            const string message = "message";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                .EnqueueResponse(new TimeoutException(message + "1"))
                .EnqueueResponse(new TimeoutException(message + "2"))
                .EnqueueResponse(new TimeoutException(message + "3"));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");
            request.RetryPolicy = new RetryPolicy<ExceptionRetryStrategy>(2, TimeSpan.FromMilliseconds(1));
            try
            {

                // Act
                request.Execute();

                //Assert, starting with catching the specific exception type
            }
            catch (RetriedException exc)
            {
                Assert.AreEqual(3, exc.Count);
                Assert.AreEqual(exc.Count, exc.ExceptionRetryStack.Count);
                var currentExceptionIndex = 3;
                foreach (var exception in exc.ExceptionRetryStack)
                {
                    Assert.IsInstanceOf<GeneralExceptionDuringAzureOperationException>(exception);
                    Assert.IsInstanceOf<TimeoutException>(exception.InnerException);
                    Assert.AreEqual(exception.InnerException.Message, message + currentExceptionIndex);
                    currentExceptionIndex--; // stack is LIFO
                }
            }
        }
        public void Execute_ReceiveTransientExceptionThenNonTransient_ThrowsExceptionWithProperRetryStack()
        {
            var expectedUri = "test://queue.abc/whatever/";
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                .EnqueueResponse(new WebException("Azure hung up after the initial request", new SocketException(1), WebExceptionStatus.ReceiveFailure, null))
                .EnqueueResponse(HttpStatusCode.Conflict, "QueueAlreadyExists", queueAlreadyExistsExceptionText, true);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var request = new RequestWithEmptyPayload(new SettingsFake(), expectedUri, "GET");

            try
            {
                request.Execute();
            }
            catch (QueueAlreadyExistsAzureException exc)
            {

                Assert.AreEqual(2, exc.RetryCount);
                Assert.AreEqual(exc.RetryCount, exc.ExceptionRetryStack.Count);
                Assert.IsInstanceOf<QueueAlreadyExistsAzureException>(exc.ExceptionRetryStack.First());
                Assert.IsInstanceOf<UnidentifiedAzureException>(exc.ExceptionRetryStack.Last());
                Assert.IsInstanceOf<WebException>(exc.ExceptionRetryStack.Last().InnerException);
            }
        }
        public void Execute_BlockBlob_ResponseParsesHeadersCorrectly()
        {
            var expectedContainer = "test-container";
            var expectedBlob = "test-blob";
            var expectedUri = String.Format("{0}/{1}/{2}", _settings.BlobEndpoint, expectedContainer, expectedBlob);
            var expectedDate = DateTime.UtcNow.AddDays(-2345);
            var expectedRawRequest = new TestableWebRequest(new Uri(expectedUri))
                                            .EnqueueResponse(new HttpResponseSettings((HttpStatusCode)201, "Success", "", false, new Dictionary<string, string>(){
                                                {"ETag", "\"123\""},
                                                {"Date", expectedDate.ToString() },
                                                {"Last-Modified", expectedDate.ToString() },
                                                {"Content-MD5", "123-MD5" }
                                            }));
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRawRequest);
            var expectedData = UTF8Encoding.UTF8.GetBytes("test-data");
            var request = new PutBlobRequest(_settings, expectedContainer, expectedBlob, expectedData);

            var response = request.Execute();

            Assert.AreEqual("123", response.Payload.ETag);
            Assert.IsTrue(Math.Abs(expectedDate.Subtract(response.Payload.Date).TotalMinutes) < 1);
            Assert.IsTrue(Math.Abs(expectedDate.Subtract(response.Payload.LastModified).TotalMinutes) < 1);
            Assert.AreEqual("123-MD5", response.Payload.ContentMD5);
        }