예제 #1
0
파일: DropboxTests.cs 프로젝트: DinoV/kudu
        public async Task TestDropboxBasic()
        {
            OAuthInfo oauth = GetOAuthInfo();

            if (oauth == null)
            {
                // only run in private kudu
                return;
            }

            AccountInfo       account = GetAccountInfo(oauth);
            DropboxDeployInfo deploy  = GetDeployInfo("/BasicTest", oauth, account);

            string appName = "DropboxTest";
            await ApplicationManager.RunAsync(appName, async appManager =>
            {
                HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials);
                var result        = await client.PostAsJsonAsync("deploy?scmType=Dropbox", deploy);
                result.EnsureSuccessful();

                await Task.WhenAll(
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/default.html", "Hello Default!"),
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/temp/temp.html", "Hello Temp!"),
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/New Folder/New File.html", "Hello New File!")
                    );
            });
        }
예제 #2
0
        public async Task DiagnosticsDumpTests()
        {
            string appName = "DiagnosticsDumpTests";

            await ApplicationManager.RunAsync(appName, async appManager =>
            {
                string path = String.Format("dump?marker={0}", Guid.NewGuid());
                using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                {
                    using (var zipStream = new MemoryStream())
                    {
                        using (var dump = await client.GetStreamAsync(path))
                        {
                            Assert.NotNull(dump);
                            await dump.CopyToAsync(zipStream);
                        }
                        TestTracer.Trace("zipStream lenth={0}", zipStream.Length);
                        Assert.True(zipStream.Length > 0);

                        zipStream.Position = 0;
                        using (var targetStream = new MemoryStream())
                        {
                            ZipUtils.Unzip(zipStream, targetStream);
                            TestTracer.Trace("targetStream lenth={0}", targetStream.Length);
                            Assert.True(targetStream.Length > 0);
                        }
                    }
                }

                // Ensure trace
                string trace = await appManager.VfsManager.ReadAllTextAsync("LogFiles/Git/trace/trace.xml");
                Assert.Contains(path, trace, StringComparison.OrdinalIgnoreCase);
            });
        }
예제 #3
0
        private void VerifyValues(ApplicationManager appManager, params KeyValuePair <string, string>[] values)
        {
            using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
            {
                HttpResponseMessage response = client.GetAsync("diagnostics/settings").Result.EnsureSuccessful();
                using (var reader = new JsonTextReader(new StreamReader(response.Content.ReadAsStreamAsync().Result)))
                {
                    JObject json = (JObject)JToken.ReadFrom(reader);
                    Assert.Equal(values.Length + 6, json.Count);
                    foreach (KeyValuePair <string, string> value in values)
                    {
                        Assert.Equal(value.Value, json[value.Key].Value <string>());
                    }
                }
            }

            foreach (KeyValuePair <string, string> value in values)
            {
                using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                {
                    if (value.Value != null)
                    {
                        HttpResponseMessage response = client.GetAsync("diagnostics/settings/" + value.Key).Result.EnsureSuccessful();
                        var result = response.Content.ReadAsStringAsync().Result;
                        Assert.Equal(value.Value, result.Trim('\"'));
                    }
                    else
                    {
                        var ex = Assert.Throws <HttpUnsuccessfulRequestException>(() => client.GetAsync("diagnostics/settings/" + value.Key).Result.EnsureSuccessful());
                        Assert.Equal(HttpStatusCode.NotFound, ex.ResponseMessage.StatusCode);
                    }
                }
            }
        }
예제 #4
0
        public void ConstructorTest()
        {
            string repositoryName = "Mvc3Application";
            string appName        = "ConstructorTest";

            using (var repo = Git.CreateLocalRepository(repositoryName))
            {
                ApplicationManager.Run(appName, appManager =>
                {
                    using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                    {
                        HttpResponseMessage response = client.GetAsync("diagnostics/settings").Result.EnsureSuccessful();
                        using (var reader = new JsonTextReader(new StreamReader(response.Content.ReadAsStreamAsync().Result)))
                        {
                            JObject json = (JObject)JToken.ReadFrom(reader);
                            Assert.Equal(6, json.Count);
                        }
                    }

                    using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                    {
                        var ex = Assert.Throws <HttpUnsuccessfulRequestException>(() => client.GetAsync("diagnostics/settings/trace_level").Result.EnsureSuccessful());
                        Assert.Equal(HttpStatusCode.NotFound, ex.ResponseMessage.StatusCode);
                    }
                });
            }
        }
예제 #5
0
        public async Task TestDropboxBasicForBasicScenarioWithOAuthV2()
        {
            if (String.IsNullOrEmpty(OAuth20Token))
            {
                // only run in private kudu
                return;
            }

            object payload = new
            {
                scmType       = "DropboxV2",
                dropbox_token = OAuth20Token,
                dropbox_path  = "/Basictest"
            };

            await ApplicationManager.RunAsync("TestDropboxBasicForBasicScenarioWithOAuthV2", async appManager =>
            {
                HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials);
                var result        = await client.PostAsJsonAsync("deploy?scmType=Dropbox", payload);
                result.EnsureSuccessful();

                await Task.WhenAll(
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/default.html", "Hello Default!"),
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/temp/temp.html", "Hello Temp!"),
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/New Folder/New File.html", "Hello New File!")
                    );
            });
        }
예제 #6
0
        private HttpClient CreateDeploymentHttpClient(string websiteName)
        {
            Repository   repository;
            ICredentials credentials;

            websiteName = GetWebsiteDeploymentHttpConfiguration(websiteName, out repository, out credentials);
            return(HttpClientHelper.CreateClient(repository.RepositoryUri, credentials));
        }
예제 #7
0
        public async Task TestDropboxBasicForBasicScenario(Scenario scenario)
        {
            OAuthInfo oauth = GetOAuthInfo();

            if (oauth == null)
            {
                // only run in private kudu
                return;
            }

            AccountInfo account = GetAccountInfo(oauth);

            Assert.Equal(oauth.Account, account.email);
            var deploy = GetDeployInfo("/BasicTest", oauth, account);

            string appName = "DropboxTest";
            await ApplicationManager.RunAsync(appName, async appManager =>
            {
                if (scenario == Scenario.NoRepository)
                {
                    await appManager.SettingsManager.SetValue(SettingsKeys.NoRepository, "1");
                }
                else if (scenario == Scenario.InPlace)
                {
                    await appManager.SettingsManager.SetValue(SettingsKeys.RepositoryPath, "wwwroot");
                }

                HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials);
                var result        = await client.PostAsJsonAsync("deploy?scmType=Dropbox", deploy);
                result.EnsureSuccessful();

                await Task.WhenAll(
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/default.html", "Hello Default!"),
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/temp/temp.html", "Hello Temp!"),
                    KuduAssert.VerifyUrlAsync(appManager.SiteUrl + "/New Folder/New File.html", "Hello New File!")
                    );

                var repositoryGit = appManager.VfsManager.Exists(@"site\repository\.git");
                var wwwrootGit    = appManager.VfsManager.Exists(@"site\wwwroot\.git");

                if (scenario == Scenario.NoRepository)
                {
                    Assert.False(repositoryGit, @"site\repository\.git should not exist for " + scenario);
                    Assert.False(wwwrootGit, @"site\wwwroot\.git should not exist for " + scenario);
                }
                else if (scenario == Scenario.InPlace)
                {
                    Assert.False(repositoryGit, @"site\repository\.git should not exist for " + scenario);
                    Assert.True(wwwrootGit, @"site\wwwroot\.git should exist for " + scenario);
                }
                else if (scenario == Scenario.Default)
                {
                    Assert.True(repositoryGit, @"site\repository\.git should exist for " + scenario);
                    Assert.False(wwwrootGit, @"site\wwwroot\.git should not exist for " + scenario);
                }
            });
        }
예제 #8
0
        public void DeployLargeRepoFromDropbox(string repoPath, string appName, string verificationText, string resourcePath)
        {
            if (!shouldRunLargeRepoTests)
            {
                return;
            }
            using (new LatencyLogger("PushAndDeployApps - " + appName))
            {
                var db = new DropboxTests();
                {
                    DropboxTests.OAuthInfo oauth = db.GetOAuthInfo(appName);

                    if (oauth == null)
                    {
                        // only run in private kudu
                        return;
                    }
                    JObject deploy;
                    DropboxTests.AccountInfo account = db.GetAccountInfo(oauth);
                    using (new LatencyLogger("DropboxGetDeployInfo - " + appName))
                    {
                        deploy = db.GetDeployInfo(repoPath, oauth, account);
                    }

                    ApplicationManager.Run(appName, appManager =>
                    {
                        const int timeoutInMinutes = 100;
                        DateTime stopTime          = DateTime.Now.AddMinutes(timeoutInMinutes);

                        var client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials);

                        using (new LatencyLogger("DropboxDeploy - " + appName))
                        {
                            client.PostAsJsonAsync("deploy?scmType=Dropbox", deploy);
                            List <DeployResult> results;
                            do
                            {
                                Thread.Sleep(5000);
                                if (DateTime.Now > stopTime)
                                {
                                    throw new TimeoutException("Terminating test. Current test took too long.");
                                }
                                results = appManager.DeploymentManager.GetResultsAsync().Result.ToList();
                                TestTracer.Trace(results[0].Progress);
                            } while ((results[0]).Status != DeployStatus.Success && (results[0]).Status != DeployStatus.Failed);
                        }

                        KuduAssert.VerifyUrl(appManager.SiteUrl + resourcePath, verificationText);
                        using (new LatencyLogger("DropboxScmDelete - " + appName))
                        {
                            appManager.RepositoryManager.Delete(deleteWebRoot: false, ignoreErrors: false).Wait();
                        }
                    });
                }
            }
        }
예제 #9
0
 private static async Task WaitForSiteAsync(string serviceUrl, ICredentials credentials)
 {
     using (var client = HttpClientHelper.CreateClient(serviceUrl, credentials))
     {
         using (var response = await client.GetAsync(""))
         {
             response.EnsureSuccessStatusCode();
         }
     }
 }
예제 #10
0
        public IEnumerable <T> SearchFTS <T>(string query, int start = 0, int limit = 0) where T : BaseE3SEntity
        {
            HttpClient client           = HttpClientHelper.CreateClient(UserName, Password);
            var        requestGenerator = new FTSRequestGenerator(_basedAddress);

            Uri request = requestGenerator.GenerateRequestUrl <T>(query, start, limit);

            string resultString = client.GetStringAsync(request).Result;

            return(JsonConvert.DeserializeObject <FTSResponse <T> >(resultString).Items.Select(t => t.Data));
        }
예제 #11
0
        private async Task WaitForSiteAsync(string serviceUrl)
        {
            var credentials = _context.Configuration.BasicAuthCredential.GetCredentials();

            using (var client = HttpClientHelper.CreateClient(serviceUrl, credentials))
            {
                using (var response = await client.GetAsync(serviceUrl))
                {
                    response.EnsureSuccessStatusCode();
                }
            }
        }
예제 #12
0
        public void SetGetDeleteValue()
        {
            var values = new[]
            {
                new KeyValuePair <string, string>(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()),
                new KeyValuePair <string, string>(Guid.NewGuid().ToString(), String.Empty),
                new KeyValuePair <string, string>(Guid.NewGuid().ToString(), null)
            };

            string repositoryName = "Mvc3Application";
            string appName        = "SetGetDeleteValue";

            using (var repo = Git.CreateLocalRepository(repositoryName))
            {
                ApplicationManager.Run(appName, appManager =>
                {
                    // set values
                    using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                    {
                        JObject json = new JObject();
                        foreach (KeyValuePair <string, string> value in values)
                        {
                            json[value.Key] = value.Value;
                        }
                        client.PostAsJsonAsync("diagnostics/settings", json).Result.EnsureSuccessful();
                    }

                    // verify values
                    VerifyValues(appManager, values);

                    // delete value
                    using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                    {
                        KeyValuePair <string, string> deleted = values[1];
                        client.DeleteAsync("diagnostics/settings/" + deleted.Key).Result.EnsureSuccessful();
                        values = values.Where(p => p.Key != deleted.Key).ToArray();
                    }

                    // update value
                    using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                    {
                        KeyValuePair <string, string> updated = values[0] = new KeyValuePair <string, string>(values[0].Key, Guid.NewGuid().ToString());
                        JObject json      = new JObject();
                        json[updated.Key] = updated.Value;
                        client.PostAsJsonAsync("diagnostics/settings", json).Result.EnsureSuccessful();
                    }

                    // verify values
                    VerifyValues(appManager, values);
                });
            }
        }
예제 #13
0
        protected KuduRemoteClientBase(
            string serviceUrl,
            ICredentials credentials   = null,
            HttpMessageHandler handler = null)
        {
            if (serviceUrl == null)
            {
                throw new ArgumentNullException("serviceUrl");
            }

            ServiceUrl  = GeneralUtilities.EnsureTrailingSlash(serviceUrl);
            Credentials = credentials;
            Client      = HttpClientHelper.CreateClient(ServiceUrl, credentials, handler);
        }
예제 #14
0
        private HttpClient CreateWebsitesHttpClient()
        {
            WebRequestHandler requestHandler = new WebRequestHandler();

            requestHandler.ClientCertificates.Add(Subscription.Certificate);
            StringBuilder endpoint = new StringBuilder(General.EnsureTrailingSlash(Subscription.ServiceEndpoint));

            endpoint.Append(subscriptionId);
            endpoint.Append("/services/");
            HttpClient client = HttpClientHelper.CreateClient(endpoint.ToString(), handler: requestHandler);

            client.DefaultRequestHeaders.Add(ServiceManagement.Constants.VersionHeaderName, WebsitesServiceVersion);

            return(client);
        }
예제 #15
0
        public void DiagnosticsSettingsExpectedValuesReturned()
        {
            const string expectedEmptyResponse =
                "{\"AzureDriveEnabled\":false,\"AzureDriveTraceLevel\":\"Error\"," +
                "\"AzureTableEnabled\":false,\"AzureTableTraceLevel\":\"Error\"," +
                "\"AzureBlobEnabled\":false,\"AzureBlobTraceLevel\":\"Error\"}";

            const string settingsContentWithNumbers = "{AzureDriveEnabled: true,AzureDriveTraceLevel: \"4\"}";
            const string settingsContentWithNulls   = "{AzureDriveEnabled: null,AzureDriveTraceLevel: \"4\"}";

            const string settingsContentWithString = "{AzureDriveEnabled: true,AzureDriveTraceLevel: \"Warning\"}";
            const string expectedResponse          =
                "{\"AzureDriveEnabled\":true,\"AzureDriveTraceLevel\":\"Warning\"," +
                "\"AzureTableEnabled\":false,\"AzureTableTraceLevel\":\"Error\"," +
                "\"AzureBlobEnabled\":false,\"AzureBlobTraceLevel\":\"Error\"}";

            const string repositoryName = "Mvc3Application";
            const string appName        = "DiagnosticsSettingsExpectedValuesReturned";

            using (var repo = Git.Clone(repositoryName))
            {
                ApplicationManager.Run(appName, appManager =>
                {
                    // verify values
                    using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                    {
                        // Empty settings.json should return default values
                        string responseContent = DownloadDiagnosticsSettings(client);
                        Assert.Equal(expectedEmptyResponse, responseContent);

                        // Expecting value will be reset
                        appManager.VfsManager.WriteAllText("site/diagnostics/settings.json", settingsContentWithNumbers);
                        responseContent = DownloadDiagnosticsSettings(client);
                        Assert.Equal(expectedEmptyResponse, responseContent);

                        // Invalid json we expect default values
                        appManager.VfsManager.WriteAllText("site/diagnostics/settings.json", settingsContentWithNulls);
                        responseContent = DownloadDiagnosticsSettings(client);
                        Assert.Equal(expectedEmptyResponse, responseContent);

                        // Expecting AzureDriveEnabled to be true
                        appManager.VfsManager.WriteAllText("site/diagnostics/settings.json", settingsContentWithString);
                        responseContent = DownloadDiagnosticsSettings(client);
                        Assert.Equal(expectedResponse, responseContent);
                    }
                });
            }
        }
예제 #16
0
파일: KuduAssert.cs 프로젝트: zmoon111/kudu
        public static void VerifyUrl(string url, ICredentials cred, params string[] contents)
        {
            HttpClient client = HttpClientHelper.CreateClient(url, cred);

            client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Kudu-Test", "1.0"));
            var response = client.GetAsync(url).Result.EnsureSuccessful();

            if (contents.Length > 0)
            {
                var responseBody = response.Content.ReadAsStringAsync().Result;
                foreach (var content in contents)
                {
                    Assert.Contains(content, responseBody, StringComparison.Ordinal);
                }
            }
        }
예제 #17
0
        public async Task KuduVersionTest()
        {
            string appName = "KuduVersionTest";

            await ApplicationManager.RunAsync(appName, async appManager =>
            {
                // Arrange
                var id     = Git.Id(Directory.GetCurrentDirectory());
                var client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.SettingsManager.Credentials);
                client.DefaultRequestHeaders.Accept.Clear();

                // Act
                string clientId = await client.GetStringAsync("commit.txt");

                // Assert
                Assert.Equal(id, clientId.TrimEnd());
            });
        }
예제 #18
0
        private HttpClient CreateServiceBusHttpClient()
        {
            WebRequestHandler requestHandler = new WebRequestHandler()
            {
                ClientCertificateOptions = ClientCertificateOption.Manual
            };

            requestHandler.ClientCertificates.Add(Subscription.Certificate);
            StringBuilder endpoint = new StringBuilder(General.EnsureTrailingSlash(Subscription.ServiceEndpoint));

            endpoint.Append(subscriptionId);
            endpoint.Append("/services/servicebus/namespaces/");
            HttpClient client = HttpClientHelper.CreateClient(endpoint.ToString(), handler: requestHandler);

            client.DefaultRequestHeaders.Add(ApiConstants.VersionHeaderName, "2012-03-01");

            return(client);
        }
예제 #19
0
        /// <summary>
        ///     Creates and initialise instance of HttpClient
        /// </summary>
        /// <returns></returns>
        private static HttpClient CreateIMediaServicesHttpClient(SubscriptionData subscription)
        {
            var requestHandler = new WebRequestHandler();

            requestHandler.ClientCertificates.Add(subscription.Certificate);
            var endpoint = new StringBuilder(General.EnsureTrailingSlash(subscription.ServiceEndpoint));

            endpoint.Append(subscription.SubscriptionId);

            //Please note that / is nessesary here
            endpoint.Append("/services/mediaservices/");
            HttpClient client = HttpClientHelper.CreateClient(endpoint.ToString(), handler: requestHandler);

            client.DefaultRequestHeaders.Add(Constants.VersionHeaderName, MediaServiceVersion);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            return(client);
        }
예제 #20
0
        public void TestDropboxConcurrent()
        {
            OAuthInfo oauth = GetOAuthInfo();

            if (oauth == null)
            {
                // only run in private kudu
                return;
            }

            AccountInfo       account = GetAccountInfo(oauth);
            DropboxDeployInfo deploy  = GetDeployInfo("/BasicTest", oauth, account);

            string appName = "DropboxTest";

            ApplicationManager.Run(appName, appManager =>
            {
                HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials);
                var tasks         = new Task <HttpResponseMessage>[]
                {
                    client.PostAsJsonAsync("deploy", deploy),
                    client.PostAsJsonAsync("deploy", deploy)
                };

                Task.WaitAll(tasks);

                // both 200 and 202 is success
                tasks[0].Result.EnsureSuccessful();
                tasks[1].Result.EnsureSuccessful();

                var success = (tasks[0].Result.StatusCode == HttpStatusCode.OK) ? tasks[0].Result : tasks[1].Result;
                var failure = !Object.ReferenceEquals(success, tasks[0].Result) ? tasks[0].Result : tasks[1].Result;

                success.EnsureSuccessful();
                Assert.Equal(HttpStatusCode.Accepted, failure.StatusCode);

                var results = appManager.DeploymentManager.GetResultsAsync().Result.ToList();
                Assert.Equal(1, results.Count);
                Assert.Equal(DeployStatus.Success, results[0].Status);
                Assert.Equal("Dropbox", results[0].Deployer);
            });
        }
예제 #21
0
        public IEnumerable SearchFTS(Type type, IList <string> queries, int start = 0, int limit = 0)
        {
            HttpClient client           = HttpClientHelper.CreateClient(UserName, Password);
            var        requestGenerator = new FTSRequestGenerator(_basedAddress);

            Uri request = requestGenerator.GenerateRequestUrl(type, queries, start, limit);

            var resultString = client.GetStringAsync(request).Result;
            var endType      = typeof(FTSResponse <>).MakeGenericType(type);
            var result       = JsonConvert.DeserializeObject(resultString, endType);

            var list = Activator.CreateInstance(typeof(List <>).MakeGenericType(type)) as IList;

            foreach (object item in (IEnumerable)endType.GetProperty("items").GetValue(result))
            {
                list.Add(item.GetType().GetProperty("data").GetValue(item));
            }

            return(list);
        }
예제 #22
0
        public string GetKuduUpTime()
        {
            const string pattern = @"<div class=""col-xs-2"">\s*<strong>Site up time</strong>\s*</div>\s*<div>([^<]*)</div>";

            string content = OperationManager.Attempt <string>(() =>
            {
                using (HttpClient client = HttpClientHelper.CreateClient(this.ServiceUrl, this.DeploymentManager.Credentials))
                {
                    using (HttpResponseMessage response = client.GetAsync(String.Empty).Result.EnsureSuccessStatusCode())
                    {
                        return(response.Content.ReadAsStringAsync().Result);
                    }
                }
            }, 3, 1000);

            MatchCollection matches = Regex.Matches(content, pattern);

            Debug.Assert(matches.Count == 1, "Could not find Up Time section!");
            Debug.Assert(matches[0].Groups.Count == 2, "Could not find Up Time value!");
            return(matches[0].Groups[1].Value);
        }
예제 #23
0
        public void TestDropboxSpecialFolderChars()
        {
            OAuthInfo oauth = GetOAuthInfo();

            if (oauth == null)
            {
                // only run in private kudu
                return;
            }

            AccountInfo       account = GetAccountInfo(oauth);
            DropboxDeployInfo deploy  = GetDeployInfo("/!@#$faiztest$#!@", oauth, account);

            string appName = "SpecialCharsTest";

            ApplicationManager.Run(appName, appManager =>
            {
                HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials);
                client.PostAsJsonAsync("deploy?scmType=Dropbox", deploy).Result.EnsureSuccessful();
            });
        }
예제 #24
0
        public async Task DiagnosticsDumpTests()
        {
            string appName = "DiagnosticsDumpTests";

            await ApplicationManager.RunAsync(appName, async appManager =>
            {
                string path = String.Format("dump?marker={0}", Guid.NewGuid());
                using (HttpClient client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                {
                    using (var zipStream = new MemoryStream())
                    {
                        using (var dump = await client.GetStreamAsync(path))
                        {
                            Assert.NotNull(dump);
                            await dump.CopyToAsync(zipStream);
                        }
                        TestTracer.Trace("zipStream lenth={0}", zipStream.Length);
                        Assert.True(zipStream.Length > 0);

                        zipStream.Position = 0;
                        using (var targetStream = new MemoryStream())
                        {
                            ZipUtils.Unzip(zipStream, targetStream);
                            TestTracer.Trace("targetStream lenth={0}", targetStream.Length);
                            Assert.True(targetStream.Length > 0);
                        }
                    }
                }

                // Ensure trace
                string trace = await appManager.VfsManager.ReadAllTextAsync("LogFiles/kudu/trace/");
                Assert.Contains("_GET_dump_200_", trace, StringComparison.OrdinalIgnoreCase);
                Assert.Contains("s.xml", trace, StringComparison.OrdinalIgnoreCase);
                Assert.Contains("_GET_api-vfs-LogFiles-kudu-trace_pending.xml", trace, StringComparison.OrdinalIgnoreCase);

                // Test runtime object by checking for one Node version
                RuntimeInfo runtimeInfo = await appManager.RuntimeManager.GetRuntimeInfo();
                Assert.True(runtimeInfo.NodeVersions.Any(dict => dict["version"] == "0.8.2"));
            });
        }
예제 #25
0
        private async Task AssertUrlContentAsync(ApplicationManager appManager, Uri requestUrl, string expectedContent)
        {
            if (expectedContent == null)
            {
                Assert.Null(requestUrl);
                return;
            }

            string address = requestUrl.ToString();

            using (var httpClient = HttpClientHelper.CreateClient(address, appManager.JobsManager.Credentials))
            {
                using (var response = await httpClient.GetAsync(String.Empty))
                {
                    var content = await response.Content.ReadAsStringAsync();

                    TestTracer.Trace("Request to: {0}\nStatus code: {1}\nContent: {2}", address, response.StatusCode, content);

                    Assert.True(content.IndexOf(expectedContent, StringComparison.OrdinalIgnoreCase) >= 0, "Expected content: " + expectedContent);
                }
            }
        }
예제 #26
0
        public async Task Error404UnknownRouteTests()
        {
            string appName = "Error404UnknownRouteTests";

            await ApplicationManager.RunAsync(appName, async appManager =>
            {
                using (var client = HttpClientHelper.CreateClient(appManager.ServiceUrl, appManager.DeploymentManager.Credentials))
                {
                    var path = "/api/badroute";
                    using (var response = await client.GetAsync(path))
                    {
                        Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

                        var content = await response.Content.ReadAsStringAsync();

                        // assert
                        Assert.True(content.Contains("No route registered for"));
                        Assert.True(content.Contains(path));
                    }
                }
            });
        }
예제 #27
0
        public virtual async Task RunIntegrationTest()
        {
            string dir        = Guid.NewGuid().ToString("N");
            string dirAddress = BaseAddress + _segmentDelimiter + dir;
            string dirAddressWithTerminatingSlash = dirAddress + _segmentDelimiter;

            // The %2520 is there to test that we can accept those characters. Here, %2520 is the URL encoded form,
            // and the actual file name has %20 (and not a space character!)
            string file        = Guid.NewGuid().ToString("N") + "%2520" + ".txt";
            string fileAddress = dirAddressWithTerminatingSlash + file;
            string fileAddressWithTerminatingSlash = fileAddress + _segmentDelimiter;

            string query = "?foo=bar";
            string baseAddressWithQuery = BaseAddress + _segmentDelimiter + query;
            string dirAddressWithQuery  = dirAddressWithTerminatingSlash + query;
            string fileAddressWithQuery = fileAddress + query;

            string deploymentFileAddress       = null;
            string customDeploymentFileAddress = null;

            if (DeploymentClient != null)
            {
                deploymentFileAddress       = string.Format("{0}{1}site{1}wwwroot{1}{2}{1}{3}", DeploymentBaseAddress, _segmentDelimiter, dir, file);
                customDeploymentFileAddress = string.Format("{0}{1}site{1}wwwroot{1}test{1}{2}{1}{3}", DeploymentBaseAddress, _segmentDelimiter, dir, file);
            }

            TestTracer.Trace("Starting RunIntegrationTest");
            TestTracer.Trace("Dir - {0}", dirAddress);
            TestTracer.Trace("File - {0}", fileAddress);
            TestTracer.Trace("DeploymentFileAddress - {0}", deploymentFileAddress);

            HttpResponseMessage response;

            // Check not found file responses
            TestTracer.Trace("==== Check not found file responses");
            response = await HttpGetAsync(dirAddress);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            response = await HttpGetAsync(dirAddressWithTerminatingSlash);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            response = await HttpGetAsync(fileAddress);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            response = await HttpGetAsync(fileAddressWithTerminatingSlash);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            // Check create file results in 201 response with etag
            TestTracer.Trace("==== Check create file results in 201 response with etag");
            response = await HttpPutAsync(fileAddress, CreateUploadContent(_fileContent0));
            await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent0);

            Assert.Equal(HttpStatusCode.Created, response.StatusCode);
            EntityTagHeaderValue originalEtag = response.Headers.ETag;

            Assert.NotNull(originalEtag);

            DateTimeOffset?lastModified = response.Content.Headers.LastModified;

            if (!_isScmEditorTest)
            {
                Assert.NotNull(lastModified);
            }

            // Check query string
            TestTracer.Trace("==== Check handle query string");
            response = await HttpGetAsync(baseAddressWithQuery);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            response = await HttpGetAsync(dirAddressWithQuery);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            response = await HttpGetAsync(fileAddressWithQuery);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            // Check that we get a 200 (OK) on created file with the correct etag
            TestTracer.Trace("==== Check that we get a 200 (OK) on created file with the correct etag");
            response = await HttpGetAsync(fileAddress);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal(originalEtag, response.Headers.ETag);
            Assert.Equal(lastModified, response.Content.Headers.LastModified);
            Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);

            // Check that we get a 200 (OK) on created file using HEAD with the correct etag
            TestTracer.Trace("==== Check that we get a 200 (OK) on created file using HEAD with the correct etag");
            using (HttpRequestMessage headReq = new HttpRequestMessage())
            {
                headReq.Method     = HttpMethod.Head;
                headReq.RequestUri = new Uri(fileAddress);
                response           = await Client.SendAsync(headReq);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
                Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);
            }

            // Check that we get a 304 (Not Modified) response if matching If-None-Match
            TestTracer.Trace("==== Check that we get a 304 (Not Modified) response if matching If-None-Match");
            using (HttpRequestMessage ifNoneMatchReq = new HttpRequestMessage())
            {
                ifNoneMatchReq.RequestUri = new Uri(fileAddress);
                ifNoneMatchReq.Headers.IfNoneMatch.Add(originalEtag);
                response = await HttpSendAsync(ifNoneMatchReq);

                Assert.Equal(HttpStatusCode.NotModified, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
            }

            // Check that we get a 200 (OK) response if not matching If-None-Match
            TestTracer.Trace("==== Check that we get a 200 (OK) response if not matching If-None-Match");
            using (HttpRequestMessage ifNoneMatchReqBadEtag = new HttpRequestMessage())
            {
                ifNoneMatchReqBadEtag.RequestUri = new Uri(fileAddress);
                ifNoneMatchReqBadEtag.Headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"NotMatching\""));
                response = await HttpSendAsync(ifNoneMatchReqBadEtag);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
            }

            // Check that If-Range request with range returns 206 (Partial Content)
            TestTracer.Trace("==== Check that If-Range request with range returns 206 (Partial Content)");
            using (HttpRequestMessage ifRangeReq = new HttpRequestMessage())
            {
                ifRangeReq.RequestUri      = new Uri(fileAddress);
                ifRangeReq.Headers.IfRange = new RangeConditionHeaderValue(originalEtag);
                ifRangeReq.Headers.Range   = new RangeHeaderValue(0, 0)
                {
                    Unit = "bytes"
                };
                response = await HttpSendAsync(ifRangeReq);

                Assert.Equal(HttpStatusCode.PartialContent, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
                Assert.Equal(1, response.Content.Headers.ContentLength);
                Assert.Equal(new ContentRangeHeaderValue(0, 0, _fileContent0.Length), response.Content.Headers.ContentRange);
            }

            // Check that If-Range request with no range returns 200 (OK)
            TestTracer.Trace("==== Check that If-Range request with no range returns 200 (OK)");
            using (HttpRequestMessage ifRangeReqNoRange = new HttpRequestMessage())
            {
                ifRangeReqNoRange.RequestUri      = new Uri(fileAddress);
                ifRangeReqNoRange.Headers.IfRange = new RangeConditionHeaderValue(originalEtag);
                response = await HttpSendAsync(ifRangeReqNoRange);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
            }

            // Check that If-Range request with bad range returns 416 (Requested Range Not Satisfiable)
            // including a Content-Range header
            TestTracer.Trace("==== Check that If-Range request with bad range returns 416 (Requested Range Not Satisfiable)");
            using (HttpRequestMessage ifRangeReqBadRange = new HttpRequestMessage())
            {
                ifRangeReqBadRange.RequestUri      = new Uri(fileAddress);
                ifRangeReqBadRange.Headers.IfRange = new RangeConditionHeaderValue(originalEtag);
                ifRangeReqBadRange.Headers.Range   = new RangeHeaderValue(100, 100)
                {
                    Unit = "bytes"
                };
                response = await HttpSendAsync(ifRangeReqBadRange);

                Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, response.StatusCode);
                Assert.Equal(_fileContentRange, response.Content.Headers.ContentRange);
            }

            // Check that we get a root directory view
            TestTracer.Trace("==== Check that we get a root directory view");
            response = await HttpGetAsync(BaseAddress);

            Assert.Equal(_dirMediaType, response.Content.Headers.ContentType);

            // Check that we get a directory view from folder
            TestTracer.Trace("==== Check that we get a directory view from folder");
            response = await HttpGetAsync(dirAddress);

            Assert.Equal(_dirMediaType, response.Content.Headers.ContentType);

            // Check various redirects between files and folders
            HttpClientHandler redirectHandler = HttpClientHelper.CreateClientHandler(BaseAddress, KuduClient.Credentials);

            redirectHandler.AllowAutoRedirect = false;
            using (HttpClient redirectClient = HttpClientHelper.CreateClient(BaseAddress, KuduClient.Credentials, redirectHandler))
            {
                // Ensure that requests to root without slash is redirected to one with slash
                TestTracer.Trace("==== Ensure that requests to root without slash is redirected to one with slash");
                response = await HttpGetAsync(BaseAddress, redirectClient);

                Assert.Equal(HttpStatusCode.TemporaryRedirect, response.StatusCode);
                Assert.Equal(BaseAddress + _segmentDelimiter, response.Headers.Location.AbsoluteUri);

                // Ensure that requests to directory without slash is redirected to one with slash
                TestTracer.Trace("==== Ensure that requests to directory without slash is redirected to one with slash");
                response = await HttpGetAsync(dirAddress, redirectClient);

                Assert.Equal(HttpStatusCode.TemporaryRedirect, response.StatusCode);
                Assert.Equal(dirAddressWithTerminatingSlash, response.Headers.Location.AbsoluteUri);

                // Ensure that requests to file with slash is redirected to one without slash
                TestTracer.Trace("==== Ensure that requests to file with slash is redirected to one without slash");
                response = await HttpGetAsync(fileAddressWithTerminatingSlash, redirectClient);

                Assert.Equal(HttpStatusCode.TemporaryRedirect, response.StatusCode);
                Assert.Equal(fileAddress, response.Headers.Location.AbsoluteUri);
            }

            // Check that 2nd create attempt fails
            TestTracer.Trace("==== Check that 2nd create attempt fails");
            response = await HttpPutAsync(fileAddress, CreateUploadContent(_fileContent0));

            Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
            Assert.Equal(originalEtag, response.Headers.ETag);

            // Check that we can't update a directory
            TestTracer.Trace("==== Check that we can't update a directory");
            response = await HttpPutAsync(dirAddress, CreateUploadContent(_fileContent0));

            Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);

            // Check that we can't delete a non-empty directory
            TestTracer.Trace("==== Check that we can't delete a non-empty directory");
            response = await HttpDeleteAsync(dirAddress);

            Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);

            EntityTagHeaderValue updatedEtag;

            if (_testConflictingUpdates)
            {
                // Update file with first edit based on original etag
                TestTracer.Trace("==== Update file with first edit based on original etag");
                using (HttpRequestMessage update1 = new HttpRequestMessage())
                {
                    update1.Method     = HttpMethod.Put;
                    update1.RequestUri = new Uri(fileAddress);
                    update1.Headers.IfMatch.Add(originalEtag);
                    update1.Content = CreateUploadContent(_fileContent1);

                    response = await HttpSendAsync(update1);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent1);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Update file with second edit based on original etag (non-conflicting merge)
                TestTracer.Trace("==== Update file with second edit based on original etag (non-conflicting merge)");
                using (HttpRequestMessage update2 = new HttpRequestMessage())
                {
                    update2.Method     = HttpMethod.Put;
                    update2.RequestUri = new Uri(fileAddress);
                    update2.Headers.IfMatch.Add(originalEtag);
                    update2.Content = CreateUploadContent(_fileContent2);

                    response = await HttpSendAsync(update2);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(updatedEtag, response.Headers.ETag);
                    Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);
                    updatedEtag = response.Headers.ETag;
                }

                // Update file with third edit based on original etag (non-conflicting merge)
                TestTracer.Trace("==== Update file with third edit based on original etag (non-conflicting merge)");
                using (HttpRequestMessage update3 = new HttpRequestMessage())
                {
                    update3.Method     = HttpMethod.Put;
                    update3.RequestUri = new Uri(fileAddress);
                    update3.Headers.IfMatch.Add(originalEtag);
                    update3.Content = CreateUploadContent(_fileContent3);

                    response = await HttpSendAsync(update3);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                    Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);
                    updatedEtag = response.Headers.ETag;
                }

                // Update file with forth edit based on original etag (conflicting)
                TestTracer.Trace("==== Update file with forth edit based on original etag (conflicting)");
                using (HttpRequestMessage update4 = new HttpRequestMessage())
                {
                    update4.Method     = HttpMethod.Put;
                    update4.RequestUri = new Uri(fileAddress);
                    update4.Headers.IfMatch.Add(originalEtag);
                    update4.Content = CreateUploadContent(_fileContent4);

                    response = await HttpSendAsync(update4);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
                    Assert.Equal(_conflictMediaType, response.Content.Headers.ContentType);
                    Assert.Null(response.Headers.ETag);
                    string content = await response.Content.ReadAsStringAsync();

                    Assert.True(Regex.IsMatch(content, _conflict));
                }

                // Update file with fifth edit based on invalid etag
                TestTracer.Trace("==== Update file with fifth edit based on invalid etag");
                using (HttpRequestMessage update5 = new HttpRequestMessage())
                {
                    update5.Method     = HttpMethod.Put;
                    update5.RequestUri = new Uri(fileAddress);
                    update5.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));
                    update5.Content = CreateUploadContent(_fileContent1);

                    response = await HttpSendAsync(update5);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that update with wildcard etag succeeds
                TestTracer.Trace("==== Check that update with wildcard etag succeeds");
                using (HttpRequestMessage update6 = new HttpRequestMessage())
                {
                    update6.Method     = HttpMethod.Put;
                    update6.RequestUri = new Uri(fileAddress);
                    update6.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    update6.Content = CreateUploadContent(_fileContent1);

                    response = await HttpSendAsync(update6);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent1);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                TestTracer.Trace("==== Check that concurrent updates work");
                List <Task <HttpResponseMessage> > concurrentUpdates = new List <Task <HttpResponseMessage> >();
                for (int cnt = 0; cnt < 16; cnt++)
                {
                    HttpRequestMessage concurrentRequest = new HttpRequestMessage()
                    {
                        Method     = HttpMethod.Put,
                        RequestUri = new Uri(fileAddress + "?nodeploy"),
                        Content    = CreateUploadContent(_fileContent2)
                    };

                    concurrentRequest.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    concurrentUpdates.Add(HttpSendAsync(concurrentRequest));
                }
                await Task.WhenAll(concurrentUpdates);

                IEnumerable <HttpResponseMessage> concurrentResponses = concurrentUpdates.Select(update => update.Result);
                foreach (HttpResponseMessage concurrentResponse in concurrentResponses)
                {
                    // NoContent is the expected success case.
                    // PreConditionFailed can happen due to race condition between LibGit2Sharp cleanup and lock acquisition and release.
                    // In PreConditionFailed case, nothing is written and the repo isn't updated or corrupted.
                    // This is an edge case for a legacy feature
                    Assert.True(
                        concurrentResponse.StatusCode == HttpStatusCode.NoContent ||
                        concurrentResponse.StatusCode == HttpStatusCode.PreconditionFailed,
                        $"Status code expected to be either {HttpStatusCode.NoContent} or {HttpStatusCode.PreconditionFailed} but got {concurrentResponse.StatusCode}");
                }

                TestTracer.Trace("==== Check that 'nodeploy' doesn't deploy and that the old content remains.");
                using (HttpRequestMessage request = new HttpRequestMessage())
                {
                    request.Method     = HttpMethod.Put;
                    request.RequestUri = new Uri(fileAddress + "?nodeploy");
                    request.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    request.Content = CreateUploadContent(_fileContent2);

                    response = await HttpSendAsync(request);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent1);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                TestTracer.Trace("==== Check passing custom commit message.");
                using (HttpRequestMessage request = new HttpRequestMessage())
                {
                    request.Method     = HttpMethod.Put;
                    request.RequestUri = new Uri(fileAddress + "?message=helloworld");
                    request.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    request.Content = CreateUploadContent(_fileContent3);

                    response = await HttpSendAsync(request);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                TestTracer.Trace("==== Check that custom deployment script works");
                using (HttpRequestMessage update7 = new HttpRequestMessage())
                {
                    // Upload custom deployment scripts
                    TestTracer.Trace("==== Upload custom deployment scripts");
                    updatedEtag = await UploadCustomDeploymentScripts();

                    // Upload content and validate that it gets deployed
                    TestTracer.Trace("==== Upload content and validate that it gets deployed");
                    update7.Method     = HttpMethod.Put;
                    update7.RequestUri = new Uri(fileAddress);
                    update7.Headers.IfMatch.Add(updatedEtag);
                    update7.Content = CreateUploadContent(_fileContent2);

                    response = await HttpSendAsync(update7);
                    await VerifyDeploymentAsync(customDeploymentFileAddress, HttpStatusCode.OK, _fileContent2);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;

                    // Remove custom deployment scripts
                    TestTracer.Trace("==== Remove custom deployment scripts");
                    updatedEtag = await RemoveCustomDeploymentScripts();
                }

                // Check that delete with invalid etag fails
                TestTracer.Trace("==== Check that delete with invalid etag fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent2);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that delete with conflict fails
                TestTracer.Trace("==== Check that delete with conflict fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(originalEtag);

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.OK, _fileContent2);

                    Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
                }

                // Check that delete with valid etag succeeds
                TestTracer.Trace("==== Check that delete with valid etag succeeds");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.NotFound, null);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                }

                // Check that 2nd delete attempt fails
                TestTracer.Trace("==== Check that 2nd delete attempt fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeploymentAsync(deploymentFileAddress, HttpStatusCode.NotFound, null);

                    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
                }
            }
            else
            {
                // Check that update with correct etag generates 204 Response with new etag
                TestTracer.Trace("==== Check that update with correct etag generates 204 Response with new etag");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(originalEtag);
                    updateRequest.Content = CreateUploadContent(_fileContent1);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Check that 2nd create attempt fails
                TestTracer.Trace("==== Check that 2nd create attempt fails");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(originalEtag);
                    updateRequest.Content = CreateUploadContent(_fileContent2);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that update with invalid etag fails
                TestTracer.Trace("==== Check that update with invalid etag fails");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));
                    updateRequest.Content = CreateUploadContent(_fileContent1);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that update with wildcard etag succeeds
                TestTracer.Trace("==== Check that update with wildcard etag succeeds");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    updateRequest.Content = CreateUploadContent(_fileContent1);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Check that delete with invalid etag fails
                TestTracer.Trace("==== Check that delete with invalid etag fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));
                    response = await HttpSendAsync(deleteRequest);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that delete with valid etag succeeds
                TestTracer.Trace("==== Check that delete with valid etag succeeds");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);
                    response = await HttpSendAsync(deleteRequest);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                }

                // Check that 2nd delete attempt fails
                TestTracer.Trace("==== Check that 2nd delete attempt fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);
                    response = await HttpSendAsync(deleteRequest);

                    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
                }

                // Check that we can delete an empty directory
                TestTracer.Trace("==== Check that we can delete an empty directory");
                response = await HttpDeleteAsync(dirAddress);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            }
        }
예제 #28
0
        public async Task RunIntegrationTest()
        {
            string dir        = Guid.NewGuid().ToString("N");
            string dirAddress = BaseAddress + _segmentDelimiter + dir;
            string dirAddressWithTerminatingSlash = dirAddress + _segmentDelimiter;

            string file        = Guid.NewGuid().ToString("N") + ".txt";
            string fileAddress = dirAddressWithTerminatingSlash + file;
            string fileAddressWithTerminatingSlash = fileAddress + _segmentDelimiter;

            string deploymentFileAddress       = null;
            string customDeploymentFileAddress = null;

            if (DeploymentClient != null)
            {
                deploymentFileAddress       = string.Format("{0}{1}site{1}wwwroot{1}{2}{1}{3}", DeploymentBaseAddress, _segmentDelimiter, dir, file);
                customDeploymentFileAddress = string.Format("{0}{1}site{1}wwwroot{1}test{1}{2}{1}{3}", DeploymentBaseAddress, _segmentDelimiter, dir, file);
            }

            TestTracer.Trace("Starting RunIntegrationTest");
            TestTracer.Trace("Dir - {0}", dirAddress);
            TestTracer.Trace("File - {0}", fileAddress);
            TestTracer.Trace("DeploymentFileAddress - {0}", deploymentFileAddress);

            HttpResponseMessage response;

            // Check not found file responses
            TestTracer.Trace("==== Check not found file responses");
            response = await HttpGetAsync(dirAddress);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            response = await HttpGetAsync(dirAddressWithTerminatingSlash);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            response = await HttpGetAsync(fileAddress);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            response = await HttpGetAsync(fileAddressWithTerminatingSlash);

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

            // Check create file results in 201 response with etag
            TestTracer.Trace("==== Check create file results in 201 response with etag");
            response = await HttpPutAsync(fileAddress, CreateUploadContent(_fileContent0));
            await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent0);

            Assert.Equal(HttpStatusCode.Created, response.StatusCode);
            EntityTagHeaderValue originalEtag = response.Headers.ETag;

            Assert.NotNull(originalEtag);

            // Check that we get a 200 (OK) on created file with the correct etag
            TestTracer.Trace("==== Check that we get a 200 (OK) on created file with the correct etag");
            response = await HttpGetAsync(fileAddress);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal(originalEtag, response.Headers.ETag);
            Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);

            // Check that we get a 200 (OK) on created file using HEAD with the correct etag
            TestTracer.Trace("==== Check that we get a 200 (OK) on created file using HEAD with the correct etag");
            using (HttpRequestMessage headReq = new HttpRequestMessage())
            {
                headReq.Method     = HttpMethod.Head;
                headReq.RequestUri = new Uri(fileAddress);
                response           = await Client.SendAsync(headReq);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
                Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);
            }

            // Check that we get a 304 (Not Modified) response if matching If-None-Match
            TestTracer.Trace("==== Check that we get a 304 (Not Modified) response if matching If-None-Match");
            using (HttpRequestMessage ifNoneMatchReq = new HttpRequestMessage())
            {
                ifNoneMatchReq.RequestUri = new Uri(fileAddress);
                ifNoneMatchReq.Headers.IfNoneMatch.Add(originalEtag);
                response = await HttpSendAsync(ifNoneMatchReq);

                Assert.Equal(HttpStatusCode.NotModified, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
            }

            // Check that we get a 200 (OK) response if not matching If-None-Match
            TestTracer.Trace("==== Check that we get a 200 (OK) response if not matching If-None-Match");
            using (HttpRequestMessage ifNoneMatchReqBadEtag = new HttpRequestMessage())
            {
                ifNoneMatchReqBadEtag.RequestUri = new Uri(fileAddress);
                ifNoneMatchReqBadEtag.Headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"NotMatching\""));
                response = await HttpSendAsync(ifNoneMatchReqBadEtag);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
            }

            // Check that If-Range request with range returns 206 (Partial Content)
            TestTracer.Trace("==== Check that If-Range request with range returns 206 (Partial Content)");
            using (HttpRequestMessage ifRangeReq = new HttpRequestMessage())
            {
                ifRangeReq.RequestUri      = new Uri(fileAddress);
                ifRangeReq.Headers.IfRange = new RangeConditionHeaderValue(originalEtag);
                ifRangeReq.Headers.Range   = new RangeHeaderValue(0, 0)
                {
                    Unit = "bytes"
                };
                response = await HttpSendAsync(ifRangeReq);

                Assert.Equal(HttpStatusCode.PartialContent, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
                Assert.Equal(1, response.Content.Headers.ContentLength);
                Assert.Equal(new ContentRangeHeaderValue(0, 0, _fileContent0.Length), response.Content.Headers.ContentRange);
            }

            // Check that If-Range request with no range returns 200 (OK)
            TestTracer.Trace("==== Check that If-Range request with no range returns 200 (OK)");
            using (HttpRequestMessage ifRangeReqNoRange = new HttpRequestMessage())
            {
                ifRangeReqNoRange.RequestUri      = new Uri(fileAddress);
                ifRangeReqNoRange.Headers.IfRange = new RangeConditionHeaderValue(originalEtag);
                response = await HttpSendAsync(ifRangeReqNoRange);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal(originalEtag, response.Headers.ETag);
            }

            // Check that If-Range request with bad range returns 416 (Requested Range Not Satisfiable)
            // including a Content-Range header
            TestTracer.Trace("==== Check that If-Range request with bad range returns 416 (Requested Range Not Satisfiable)");
            using (HttpRequestMessage ifRangeReqBadRange = new HttpRequestMessage())
            {
                ifRangeReqBadRange.RequestUri      = new Uri(fileAddress);
                ifRangeReqBadRange.Headers.IfRange = new RangeConditionHeaderValue(originalEtag);
                ifRangeReqBadRange.Headers.Range   = new RangeHeaderValue(100, 100)
                {
                    Unit = "bytes"
                };
                response = await HttpSendAsync(ifRangeReqBadRange);

                Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, response.StatusCode);
                Assert.Equal(_fileContentRange, response.Content.Headers.ContentRange);
            }

            // Check that we get a root directory view
            TestTracer.Trace("==== Check that we get a root directory view");
            response = await HttpGetAsync(BaseAddress);

            Assert.Equal(_dirMediaType, response.Content.Headers.ContentType);

            // Check that we get a directory view from folder
            TestTracer.Trace("==== Check that we get a directory view from folder");
            response = await HttpGetAsync(dirAddress);

            Assert.Equal(_dirMediaType, response.Content.Headers.ContentType);

            // Check various redirects between files and folders
            HttpClientHandler redirectHandler = HttpClientHelper.CreateClientHandler(BaseAddress, KuduClient.Credentials);

            redirectHandler.AllowAutoRedirect = false;
            using (HttpClient redirectClient = HttpClientHelper.CreateClient(BaseAddress, KuduClient.Credentials, redirectHandler))
            {
                // Ensure that requests to root without slash is redirected to one with slash
                TestTracer.Trace("==== Ensure that requests to root without slash is redirected to one with slash");
                response = await HttpGetAsync(BaseAddress, redirectClient);

                Assert.Equal(HttpStatusCode.TemporaryRedirect, response.StatusCode);
                Assert.Equal(BaseAddress + _segmentDelimiter, response.Headers.Location.AbsoluteUri);

                // Ensure that requests to directory without slash is redirected to one with slash
                TestTracer.Trace("==== Ensure that requests to directory without slash is redirected to one with slash");
                response = await HttpGetAsync(dirAddress, redirectClient);

                Assert.Equal(HttpStatusCode.TemporaryRedirect, response.StatusCode);
                Assert.Equal(dirAddressWithTerminatingSlash, response.Headers.Location.AbsoluteUri);

                // Ensure that requests to file with slash is redirected to one without slash
                TestTracer.Trace("==== Ensure that requests to file with slash is redirected to one without slash");
                response = await HttpGetAsync(fileAddressWithTerminatingSlash, redirectClient);

                Assert.Equal(HttpStatusCode.TemporaryRedirect, response.StatusCode);
                Assert.Equal(fileAddress, response.Headers.Location.AbsoluteUri);
            }

            // Check that 2nd create attempt fails
            TestTracer.Trace("==== Check that 2nd create attempt fails");
            response = await HttpPutAsync(fileAddress, CreateUploadContent(_fileContent0));

            Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
            Assert.Equal(originalEtag, response.Headers.ETag);

            // Check that we can't update a directory
            TestTracer.Trace("==== Check that we can't update a directory");
            response = await HttpPutAsync(dirAddress, CreateUploadContent(_fileContent0));

            Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);

            // Check that we can't delete a non-empty directory
            TestTracer.Trace("==== Check that we can't delete a non-empty directory");
            response = await HttpDeleteAsync(dirAddress);

            Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);

            EntityTagHeaderValue updatedEtag;

            if (_testConflictingUpdates)
            {
                // Update file with first edit based on original etag
                TestTracer.Trace("==== Update file with first edit based on original etag");
                using (HttpRequestMessage update1 = new HttpRequestMessage())
                {
                    update1.Method     = HttpMethod.Put;
                    update1.RequestUri = new Uri(fileAddress);
                    update1.Headers.IfMatch.Add(originalEtag);
                    update1.Content = CreateUploadContent(_fileContent1);

                    response = await HttpSendAsync(update1);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent1);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Update file with second edit based on original etag (non-conflicting merge)
                TestTracer.Trace("==== Update file with second edit based on original etag (non-conflicting merge)");
                using (HttpRequestMessage update2 = new HttpRequestMessage())
                {
                    update2.Method     = HttpMethod.Put;
                    update2.RequestUri = new Uri(fileAddress);
                    update2.Headers.IfMatch.Add(originalEtag);
                    update2.Content = CreateUploadContent(_fileContent2);

                    response = await HttpSendAsync(update2);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(updatedEtag, response.Headers.ETag);
                    Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);
                    updatedEtag = response.Headers.ETag;
                }

                // Update file with third edit based on original etag (non-conflicting merge)
                TestTracer.Trace("==== Update file with third edit based on original etag (non-conflicting merge)");
                using (HttpRequestMessage update3 = new HttpRequestMessage())
                {
                    update3.Method     = HttpMethod.Put;
                    update3.RequestUri = new Uri(fileAddress);
                    update3.Headers.IfMatch.Add(originalEtag);
                    update3.Content = CreateUploadContent(_fileContent3);

                    response = await HttpSendAsync(update3);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                    Assert.Equal(_fileMediaType, response.Content.Headers.ContentType);
                    updatedEtag = response.Headers.ETag;
                }

                // Update file with forth edit based on original etag (conflicting)
                TestTracer.Trace("==== Update file with forth edit based on original etag (conflicting)");
                using (HttpRequestMessage update4 = new HttpRequestMessage())
                {
                    update4.Method     = HttpMethod.Put;
                    update4.RequestUri = new Uri(fileAddress);
                    update4.Headers.IfMatch.Add(originalEtag);
                    update4.Content = CreateUploadContent(_fileContent4);

                    response = await HttpSendAsync(update4);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
                    Assert.Equal(_conflictMediaType, response.Content.Headers.ContentType);
                    Assert.Null(response.Headers.ETag);
                    string content = await response.Content.ReadAsStringAsync();

                    Assert.True(content.StartsWith(_conflict));
                }

                // The previous conflict results in a git cleanup which at times takes time. During this interval the server responds with ServerUnavailable.
                // To work aroudn this, we'll simply add a bit of sleep timing.
                Thread.Sleep(TimeSpan.FromSeconds(3));

                // Update file with fifth edit based on invalid etag
                TestTracer.Trace("==== Update file with fifth edit based on invalid etag");
                using (HttpRequestMessage update5 = new HttpRequestMessage())
                {
                    update5.Method     = HttpMethod.Put;
                    update5.RequestUri = new Uri(fileAddress);
                    update5.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));
                    update5.Content = CreateUploadContent(_fileContent1);

                    response = await HttpSendAsync(update5);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent3);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that update with wildcard etag succeeds
                TestTracer.Trace("==== Check that update with wildcard etag succeeds");
                using (HttpRequestMessage update6 = new HttpRequestMessage())
                {
                    update6.Method     = HttpMethod.Put;
                    update6.RequestUri = new Uri(fileAddress);
                    update6.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    update6.Content = CreateUploadContent(_fileContent1);

                    response = await HttpSendAsync(update6);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent1);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Check that custom deployment script works
                using (HttpRequestMessage update7 = new HttpRequestMessage())
                {
                    // Upload custom deployment scripts
                    TestTracer.Trace("==== Upload custom deployment scripts");
                    updatedEtag = await UploadCustomDeploymentScripts();

                    // Upload content and validate that it gets deployed
                    TestTracer.Trace("==== Upload content and validate that it gets deployed");
                    update7.Method     = HttpMethod.Put;
                    update7.RequestUri = new Uri(fileAddress);
                    update7.Headers.IfMatch.Add(updatedEtag);
                    update7.Content = CreateUploadContent(_fileContent2);

                    response = await HttpSendAsync(update7);
                    await VerifyDeployment(customDeploymentFileAddress, HttpStatusCode.OK, _fileContent2);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;

                    // Remove custom deployment scripts
                    TestTracer.Trace("==== Remove custom deployment scripts");
                    updatedEtag = await RemoveCustomDeploymentScripts();
                }

                // Check that delete with invalid etag fails
                TestTracer.Trace("==== Check that delete with invalid etag fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent2);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that delete with conflict fails
                TestTracer.Trace("==== Check that delete with conflict fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(originalEtag);

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.OK, _fileContent2);

                    Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
                }

                // Check that delete with valid etag succeeds
                TestTracer.Trace("==== Check that delete with valid etag succeeds");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.NotFound, null);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                }

                // Check that 2nd delete attempt fails
                TestTracer.Trace("==== Check that 2nd delete attempt fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);

                    response = await HttpSendAsync(deleteRequest);
                    await VerifyDeployment(deploymentFileAddress, HttpStatusCode.NotFound, null);

                    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
                }
            }
            else
            {
                // Check that update with correct etag generates 204 Response with new etag
                TestTracer.Trace("==== Check that update with correct etag generates 204 Response with new etag");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(originalEtag);
                    updateRequest.Content = CreateUploadContent(_fileContent1);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Check that 2nd create attempt fails
                TestTracer.Trace("==== Check that 2nd create attempt fails");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(originalEtag);
                    updateRequest.Content = CreateUploadContent(_fileContent2);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that update with invalid etag fails
                TestTracer.Trace("==== Check that update with invalid etag fails");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));
                    updateRequest.Content = CreateUploadContent(_fileContent1);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that update with wildcard etag succeeds
                TestTracer.Trace("==== Check that update with wildcard etag succeeds");
                using (HttpRequestMessage updateRequest = new HttpRequestMessage())
                {
                    updateRequest.Method     = HttpMethod.Put;
                    updateRequest.RequestUri = new Uri(fileAddress);
                    updateRequest.Headers.IfMatch.Add(EntityTagHeaderValue.Any);
                    updateRequest.Content = CreateUploadContent(_fileContent1);
                    response = await HttpSendAsync(updateRequest);

                    Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
                    Assert.NotNull(response.Headers.ETag);
                    Assert.NotEqual(originalEtag, response.Headers.ETag);
                    updatedEtag = response.Headers.ETag;
                }

                // Check that delete with invalid etag fails
                TestTracer.Trace("==== Check that delete with invalid etag fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(new EntityTagHeaderValue("\"invalidetag\""));
                    response = await HttpSendAsync(deleteRequest);

                    Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
                    Assert.Equal(updatedEtag, response.Headers.ETag);
                }

                // Check that delete with valid etag succeeds
                TestTracer.Trace("==== Check that delete with valid etag succeeds");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);
                    response = await HttpSendAsync(deleteRequest);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                }

                // Check that 2nd delete attempt fails
                TestTracer.Trace("==== Check that 2nd delete attempt fails");
                using (HttpRequestMessage deleteRequest = new HttpRequestMessage())
                {
                    deleteRequest.Method     = HttpMethod.Delete;
                    deleteRequest.RequestUri = new Uri(fileAddress);
                    deleteRequest.Headers.IfMatch.Add(updatedEtag);
                    response = await HttpSendAsync(deleteRequest);

                    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
                }

                // Check that we can delete an empty directory
                TestTracer.Trace("==== Check that we can delete an empty directory");
                response = await HttpDeleteAsync(dirAddress);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            }
        }
예제 #29
0
 /// <summary>
 /// 发送请求
 /// </summary>
 /// <param name="request">请求的参数</param>
 /// <param name="completionOption"></param>
 /// <param name="token"></param>
 /// <param name="sourceName"></param>
 /// <returns>自定义的Response结果</returns>
 public static Task <HttpResponseMessage> RestSend(this OssHttpRequest request,
                                                   HttpCompletionOption completionOption,
                                                   CancellationToken token, string sourceName = null)
 {
     return(HttpClientHelper.CreateClient(sourceName).RestSend(request, completionOption, token));
 }
예제 #30
0
 /// <summary>
 ///     Creates and initialise instance of HttpClient
 /// </summary>
 /// <returns></returns>
 public HttpClient CreateIMediaServicesHttpClient()
 {
     return(HttpClientHelper.CreateClient("http://test/services/mediaservices/", handler: this));
 }