[InlineData(null, "sitereplicator", "filecounter", "filecountermvc")] // default site extension endpoint (v2) // [InlineData("https://api.nuget.org/v3/index.json", "bootstrap", "knockoutjs", "angularjs")] // v3 endpoint public async Task SiteExtensionParallelInstallationTest(string feedEndpoint, string testPackageId1, string testPackageId2, string testPackageId3) { const string appName = "SiteExtensionParallelInstallationTest"; string[] packageIds = { testPackageId1, testPackageId2, testPackageId3 }; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; await CleanSiteExtensions(manager); List <Task <HttpResponseMessage> > tasks = new List <Task <HttpResponseMessage> >(); List <Task <HttpResponseMessage> > pollingTasks = new List <Task <HttpResponseMessage> >(); UpdateHeaderIfGoingToBeArmRequest(manager.Client, true); TestTracer.Trace("Start parallel install multiple extensions ..."); foreach (var packageId in packageIds) { tasks.Add(Task.Run <HttpResponseMessage>(async() => { TestTracer.Trace("Install package '{0}' fresh from '{1}' async", packageId, feedEndpoint); HttpResponseMessage responseMessage = await manager.InstallExtension(id: packageId, feedUrl: feedEndpoint); ArmEntry <SiteExtensionInfo> armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); Assert.Equal(HttpStatusCode.Created, responseMessage.StatusCode); return(responseMessage); })); } await Task.WhenAll(tasks); foreach (var packageId in packageIds) { pollingTasks.Add(Task.Run <HttpResponseMessage>(async() => { TestTracer.Trace("Poll '{0}' for status for '{1}'. Expecting 200 response eventually with site operation header.", feedEndpoint, packageId); HttpResponseMessage responseMessage = await PollAndVerifyAfterArmInstallation(manager, packageId); ArmEntry <SiteExtensionInfo> armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(feedEndpoint, armResult.Properties.FeedUrl); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); return(responseMessage); })); } await Task.WhenAll(pollingTasks); TestTracer.Trace("Installation are done, expecting only one site operation header return (trigger site restart)"); // should only trigger restart once IEnumerable <Task <HttpResponseMessage> > responses = pollingTasks.Where((task) => { return(task.Result.Headers.Contains(Constants.SiteOperationHeaderKey)); }); Assert.Equal(1, responses.Count()); }); }
public async Task <HttpResponseMessage> InstallExtensionArm(string id, ArmEntry <SiteExtensionInfo> requestInfo) { if (requestInfo == null) { // Body should not be empty return(Request.CreateResponse(HttpStatusCode.BadRequest)); } return(await InstallExtension(id, requestInfo.Properties)); }
public async Task SiteExtensionInstallPackageToWebRootAsyncTests() { const string appName = "SiteExtensionInstallPackageToWebRootAsyncTests"; const string externalPackageId = "SimpleSvc"; const string externalPackageVersion = "1.0.0"; const string externalFeed = "https://www.myget.org/F/simplesvc/"; // site extension 'webrootxdttest' search for xdt files under site extension 'webrootxdttest' folder, and print out xdt content onto page const string externalPackageWithXdtId = "webrootxdttest"; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; await CleanSiteExtensions(manager); // install/update TestTracer.Trace("Perform InstallExtension with id '{0}', version '{1}' from '{2}'", externalPackageId, externalPackageVersion, externalFeed); UpdateHeaderIfGoingToBeArmRequest(manager.Client, true); HttpResponseMessage responseMessage = await manager.InstallExtension(externalPackageId, externalPackageVersion, externalFeed, SiteExtensionInfo.SiteExtensionType.WebRoot); ArmEntry <SiteExtensionInfo> armResult = null; if (responseMessage.StatusCode == HttpStatusCode.OK) { TestTracer.Trace("Installation done within 15 seconds, no polling needed."); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); } else { Assert.Equal(HttpStatusCode.Created, responseMessage.StatusCode); responseMessage = await PollAndVerifyAfterArmInstallation(manager, externalPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); } // shouldn`t see restart header since package doesn`t come with XDT Assert.False(responseMessage.Headers.Contains(Constants.SiteOperationHeaderKey), "Must not contain restart header"); Assert.Equal(externalFeed, armResult.Properties.FeedUrl); Assert.Equal(externalPackageVersion, armResult.Properties.Version); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); TestTracer.Trace("GET request to verify package content has been copied to wwwroot"); HttpClient client = new HttpClient(); responseMessage = await client.GetAsync(appManager.SiteUrl); string responseContent = await responseMessage.Content.ReadAsStringAsync(); Assert.NotNull(responseContent); Assert.True(responseContent.Contains(@"<h3>Site for testing</h3>")); TestTracer.Trace("GetLocalExtension should return WebRoot type SiteExtensionInfo"); responseMessage = await manager.GetLocalExtension(externalPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(SiteExtensionInfo.SiteExtensionType.WebRoot, armResult.Properties.Type); responseMessage = await manager.GetLocalExtensions(externalPackageId); var results = await responseMessage.Content.ReadAsAsync <ArmListEntry <SiteExtensionInfo> >(); foreach (var item in results.Value) { if (string.Equals(externalPackageId, item.Properties.Id, StringComparison.OrdinalIgnoreCase)) { Assert.Equal(SiteExtensionInfo.SiteExtensionType.WebRoot, item.Properties.Type); } } // delete TestTracer.Trace("Perform UninstallExtension with id '{0}' only.", externalPackageId); responseMessage = await manager.UninstallExtension(externalPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Null(armResult); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); TestTracer.Trace("GET request to verify package content has been removed wwwroot"); responseMessage = await client.GetAsync(appManager.SiteUrl); Assert.Equal(HttpStatusCode.Forbidden, responseMessage.StatusCode); // install package that with xdt file TestTracer.Trace("Perform InstallExtension with id '{0}' from '{1}'", externalPackageWithXdtId, externalFeed); responseMessage = await manager.InstallExtension(externalPackageWithXdtId, feedUrl: externalFeed, type: SiteExtensionInfo.SiteExtensionType.WebRoot); Assert.Equal(HttpStatusCode.Created, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); // package come with XDT, which would require site restart TestTracer.Trace("Poll for status. Expecting 200 response eventually with site operation header."); responseMessage = await PollAndVerifyAfterArmInstallation(manager, externalPackageWithXdtId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); // after successfully installed, should return SiteOperationHeader to notify GEO to restart website Assert.True(responseMessage.Headers.Contains(Constants.SiteOperationHeaderKey)); Assert.Equal(externalFeed, armResult.Properties.FeedUrl); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); TestTracer.Trace("GET request to verify package content has been copied to wwwroot"); responseMessage = await client.GetAsync(appManager.SiteUrl); responseContent = await responseMessage.Content.ReadAsStringAsync(); Assert.NotNull(responseContent); Assert.True(responseContent.Contains(@"1 files")); Assert.True(responseContent.Contains(@"site\path\shall\not\be\found")); // xdt content }); }
public async Task SiteExtensionShouldNotSeeButAbleToInstallUnlistedPackage() { const string appName = "SiteExtensionShouldNotSeeUnlistPackage"; const string externalPackageId = "SimpleSite"; const string unlistedVersion = "3.0.0"; const string latestListedVersion = "2.0.0"; const string externalFeed = "https://www.myget.org/F/simplesvc/"; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; await CleanSiteExtensions(manager); HttpResponseMessage response = await manager.GetRemoteExtension(externalPackageId, feedUrl: externalFeed); SiteExtensionInfo info = await response.Content.ReadAsAsync <SiteExtensionInfo>(); Assert.NotEqual(unlistedVersion, info.Version); response = await manager.GetRemoteExtension(externalPackageId, version: unlistedVersion, feedUrl: externalFeed); info = await response.Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(unlistedVersion, info.Version); response = await manager.GetRemoteExtensions(externalPackageId, allowPrereleaseVersions: true, feedUrl: externalFeed); List <SiteExtensionInfo> infos = await response.Content.ReadAsAsync <List <SiteExtensionInfo> >(); Assert.NotEmpty(infos); foreach (var item in infos) { Assert.NotEqual(unlistedVersion, item.Version); } response = await manager.InstallExtension(externalPackageId, feedUrl: externalFeed); info = await response.Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(externalPackageId, info.Id); Assert.Equal(latestListedVersion, info.Version); Assert.Equal(externalFeed, info.FeedUrl); TestTracer.Trace("Should able to installed unlisted package if specify version"); response = await manager.InstallExtension(externalPackageId, version: unlistedVersion, feedUrl: externalFeed); info = await response.Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(externalPackageId, info.Id); Assert.Equal(unlistedVersion, info.Version); Assert.Equal(externalFeed, info.FeedUrl); UpdateHeaderIfGoingToBeArmRequest(manager.Client, isArmRequest: true); response = await manager.GetRemoteExtension(externalPackageId, feedUrl: externalFeed); ArmEntry <SiteExtensionInfo> armInfo = await response.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.NotEqual(unlistedVersion, armInfo.Properties.Version); response = await manager.GetRemoteExtensions(externalPackageId, allowPrereleaseVersions: true, feedUrl: externalFeed); ArmListEntry <SiteExtensionInfo> armInfos = await response.Content.ReadAsAsync <ArmListEntry <SiteExtensionInfo> >(); Assert.NotEmpty(armInfos.Value); foreach (var item in armInfos.Value) { Assert.NotEqual(unlistedVersion, item.Properties.Version); } response = await manager.InstallExtension(externalPackageId, feedUrl: externalFeed); Assert.Equal(HttpStatusCode.Created, response.StatusCode); await PollAndVerifyAfterArmInstallation(manager, externalPackageId); response = await manager.GetLocalExtension(externalPackageId); armInfo = await response.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(externalPackageId, armInfo.Properties.Id); Assert.Equal(latestListedVersion, armInfo.Properties.Version); Assert.Equal(externalFeed, armInfo.Properties.FeedUrl); response = await manager.InstallExtension(externalPackageId, version: unlistedVersion, feedUrl: externalFeed); Assert.Equal(HttpStatusCode.Created, response.StatusCode); await PollAndVerifyAfterArmInstallation(manager, externalPackageId); response = await manager.GetLocalExtension(externalPackageId); armInfo = await response.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(externalPackageId, armInfo.Properties.Id); Assert.Equal(unlistedVersion, armInfo.Properties.Version); Assert.Equal(externalFeed, armInfo.Properties.FeedUrl); }); }
public async Task SiteExtensionGetArmTest() { const string appName = "SiteExtensionGetAsyncTest"; const string externalPackageId = "filecounter"; const string externalFeed = "https://api.nuget.org/v3/index.json"; const string installationArgument = "arg0"; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; await CleanSiteExtensions(manager); UpdateHeaderIfGoingToBeArmRequest(manager.Client, true); TestTracer.Trace("GetRemoteExtensions with Arm header, expecting site extension info will be wrap inside Arm envelop"); HttpResponseMessage responseMessage = await manager.GetRemoteExtensions(externalPackageId, true, externalFeed); ArmListEntry <SiteExtensionInfo> armResultList = await responseMessage.Content.ReadAsAsync <ArmListEntry <SiteExtensionInfo> >(); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.NotNull(armResultList); Assert.NotEmpty(armResultList.Value); Assert.NotNull(armResultList.Value.Where(item => string.Equals(externalPackageId, item.Properties.Id, StringComparison.OrdinalIgnoreCase))); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); TestTracer.Trace("GetRemoteExtension with Arm header, expecting site extension info will be wrap inside Arm envelop"); responseMessage = await manager.GetRemoteExtension(externalPackageId, feedUrl: externalFeed); ArmEntry <SiteExtensionInfo> armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.NotNull(armResult); Assert.Equal(externalPackageId, armResult.Properties.Id); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); UpdateHeaderIfGoingToBeArmRequest(manager.Client, false); responseMessage = await manager.InstallExtension(externalPackageId, feedUrl: externalFeed, installationArgs: installationArgument); SiteExtensionInfo syncResult = await responseMessage.Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(externalPackageId, syncResult.Id); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); UpdateHeaderIfGoingToBeArmRequest(manager.Client, true); TestTracer.Trace("GetLocalExtensions (no filter) with Arm header, expecting site extension info will be wrap inside Arm envelop"); responseMessage = await manager.GetLocalExtensions(); armResultList = await responseMessage.Content.ReadAsAsync <ArmListEntry <SiteExtensionInfo> >(); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.NotNull(armResultList); Assert.NotEmpty(armResultList.Value); Assert.NotNull(armResultList.Value.Where(item => string.Equals(externalPackageId, item.Properties.Id, StringComparison.OrdinalIgnoreCase))); Assert.Equal(Constants.SiteExtensionProvisioningStateSucceeded, armResultList.Value.First <ArmEntry <SiteExtensionInfo> >().Properties.ProvisioningState); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); foreach (var item in armResultList.Value) { Assert.Equal(Constants.SiteExtensionProvisioningStateSucceeded, item.Properties.ProvisioningState); Assert.Equal(installationArgument, item.Properties.InstallationArgs); } TestTracer.Trace("GetLocalExtensions (with filter) with Arm header, expecting site extension info will be wrap inside Arm envelop"); responseMessage = await manager.GetLocalExtensions(externalPackageId); armResultList = await responseMessage.Content.ReadAsAsync <ArmListEntry <SiteExtensionInfo> >(); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.NotNull(armResultList); Assert.NotEmpty(armResultList.Value); Assert.NotNull(armResultList.Value.Where(item => string.Equals(externalPackageId, item.Properties.Id, StringComparison.OrdinalIgnoreCase))); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); foreach (var item in armResultList.Value) { Assert.Equal(Constants.SiteExtensionProvisioningStateSucceeded, item.Properties.ProvisioningState); Assert.Equal(installationArgument, item.Properties.InstallationArgs); } }); }
[InlineData("https://api.nuget.org/v3/index.json", "filecounter")] // v3 endpoint public async Task SiteExtensionInstallUninstallAsyncTest(string feedEndpoint, string testPackageId) { TestTracer.Trace("Testing against feed: '{0}'", feedEndpoint); const string appName = "SiteExtensionInstallUninstallAsyncTest"; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; await CleanSiteExtensions(manager); // Get the latest package, make sure that call will return right away when we try to update TestTracer.Trace("Get latest package '{0}' from '{1}'", testPackageId, feedEndpoint); SiteExtensionInfo latestPackage = await(await manager.GetRemoteExtension(testPackageId, feedUrl: feedEndpoint)).Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(testPackageId, latestPackage.Id); // install from non-default endpoint UpdateHeaderIfGoingToBeArmRequest(manager.Client, true); TestTracer.Trace("Install package '{0}'-'{1}' fresh from '{2}' async", testPackageId, latestPackage.Version, feedEndpoint); HttpResponseMessage responseMessage = await manager.InstallExtension(id: testPackageId, version: latestPackage.Version, feedUrl: feedEndpoint); ArmEntry <SiteExtensionInfo> armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(string.Empty, armResult.Location); // test "x-ms-geo-location" header is empty, same value should be assign to "Location" Assert.Equal(HttpStatusCode.Created, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); TestTracer.Trace("Poll for status. Expecting 200 response eventually with site operation header."); responseMessage = await PollAndVerifyAfterArmInstallation(manager, testPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); // after successfully installed, should return SiteOperationHeader to notify GEO to restart website Assert.True(responseMessage.Headers.Contains(Constants.SiteOperationHeaderKey)); Assert.Equal(feedEndpoint, armResult.Properties.FeedUrl); Assert.Equal(latestPackage.Version, armResult.Properties.Version); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); TestTracer.Trace("Get '{0}' again. Expecting 200 response without site operation header", testPackageId); responseMessage = await manager.GetLocalExtension(testPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); // get again shouldn`t see SiteOperationHeader anymore Assert.False(responseMessage.Headers.Contains(Constants.SiteOperationHeaderKey)); Assert.Equal(feedEndpoint, armResult.Properties.FeedUrl); Assert.Equal(latestPackage.Version, armResult.Properties.Version); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); TestTracer.Trace("Try to update package '{0}' without given a feed", testPackageId); // Not passing feed endpoint will default to feed endpoint from installed package // Update should return right away, expecting code to look up from feed that store in local package // since we had installed the latest package, there is nothing to update. // We shouldn`t see any site operation header value // And there is no polling, since it finished within 15 seconds responseMessage = await manager.InstallExtension(testPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Equal(string.Empty, armResult.Location); // test "x-ms-geo-location" header is empty, same value should be assign to "Location" Assert.Equal(latestPackage.Id, armResult.Properties.Id); Assert.Equal(feedEndpoint, armResult.Properties.FeedUrl); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); // no installation operation happened, shouldn`t see SiteOperationHeader return Assert.False(responseMessage.Headers.Contains(Constants.SiteOperationHeaderKey)); TestTracer.Trace("Uninstall '{0}' async", testPackageId); responseMessage = await manager.UninstallExtension(testPackageId); armResult = await responseMessage.Content.ReadAsAsync <ArmEntry <SiteExtensionInfo> >(); Assert.Null(armResult); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.True(responseMessage.Headers.Contains(Constants.RequestIdHeader)); TestTracer.Trace("Get '{0}' again. Expecting 404.", testPackageId); var ex = await KuduAssert.ThrowsUnwrappedAsync <HttpUnsuccessfulRequestException>(async() => { await manager.GetLocalExtension(testPackageId); }); Assert.Equal(HttpStatusCode.NotFound, ex.ResponseMessage.StatusCode); }); }
public Task <HttpResponseMessage> CreateOrUpdateArm(string name, ArmEntry <FunctionEnvelope> armFunctionEnvelope) { return(CreateOrUpdateHelper(name, Task.FromResult(armFunctionEnvelope.Properties))); }
public async Task <HttpResponseMessage> InstallExtensionArm(string id, ArmEntry <SiteExtensionInfo> requestInfo) { return(await InstallExtension(id, requestInfo.Properties)); }
public Task<HttpResponseMessage> CreateOrUpdateArm(string name, ArmEntry<FunctionEnvelope> armFunctionEnvelope) { return CreateOrUpdateHelper(name, Task.FromResult(armFunctionEnvelope.Properties)); }
public HttpResponseMessage CreateTriggeredJobArm(string jobName, ArmEntry <TriggeredJob> armTriggeredJob) { return(SetJobSettings(jobName, armTriggeredJob.Properties.Settings, _triggeredJobsManager)); }
public HttpResponseMessage CreateContinuousJobArm(string jobName, ArmEntry <ContinuousJob> armContinuousJob) { return(SetJobSettings(jobName, armContinuousJob.Properties.Settings, _continuousJobsManager)); }
public async Task<HttpResponseMessage> InstallExtensionArm(string id, ArmEntry<SiteExtensionInfo> requestInfo) { return await InstallExtension(id, requestInfo.Properties); }
public ArmBuilder <TObject> AddEntry(ArmEntry entry) { return(entry.IsArrayElement ? AddArrayElement(entry.Key, entry.Value) : AddSingleElement(entry.Key, entry.Value)); }