aspnetcore/test/Microsoft.AspNetCore.AzureA.../WebAppExtensions.cs

148 lines
6.8 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.Azure.Management.AppService.Fluent;
using Microsoft.Azure.Management.AppService.Fluent.Models;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests
{
internal static class WebAppExtensions
{
private static readonly TimeSpan GitDeployDelay = TimeSpan.FromSeconds(15);
private static readonly TimeSpan HttpClientTimeout = TimeSpan.FromMinutes(3);
public static HttpClient CreateClient(this IWebApp site)
{
var domain = site.GetHostNameBindings().First().Key;
return new HttpClient { BaseAddress = new Uri("http://" + domain), Timeout = HttpClientTimeout };
}
public static async Task UploadFilesAsync(this IWebApp site, DirectoryInfo from, string to, IPublishingProfile publishingProfile, ILogger logger)
{
foreach (var info in from.GetFileSystemInfos("*"))
{
var address = new Uri(
"ftp://" + publishingProfile.FtpUrl + to + info.FullName.Substring(from.FullName.Length + 1).Replace('\\', '/'));
if (info is FileInfo file)
{
logger.LogInformation($"Uploading {file.FullName} to {address}");
var request = CreateRequest(publishingProfile, address, WebRequestMethods.Ftp.UploadFile);
using (var fileStream = File.OpenRead(file.FullName))
{
using (var requestStream = await request.GetRequestStreamAsync())
{
await fileStream.CopyToAsync(requestStream);
}
}
await request.GetResponseAsync();
}
if (info is DirectoryInfo directory)
{
var request = CreateRequest(publishingProfile, address, WebRequestMethods.Ftp.MakeDirectory);
await request.GetResponseAsync();
await UploadFilesAsync(site, directory, to + directory.Name + '/', publishingProfile, logger);
}
}
}
private static FtpWebRequest CreateRequest(IPublishingProfile publishingProfile, Uri address, string method)
{
var request = (FtpWebRequest) WebRequest.Create(address);
request.Method = method;
request.KeepAlive = true;
request.UseBinary = true;
request.UsePassive = false;
request.Credentials = new NetworkCredential(publishingProfile.FtpUsername, publishingProfile.FtpPassword);
request.ConnectionGroupName = "group";
return request;
}
public static async Task Deploy(this IWebApp site, WebAppDeploymentKind kind, DirectoryInfo from, TestCommand dotnet, ILogger logger)
{
switch (kind)
{
case WebAppDeploymentKind.Git:
await site.GitDeploy(from, logger);
break;
case WebAppDeploymentKind.WebDeploy:
await site.BuildPublishProfileAsync(from.FullName);
await dotnet.ExecuteAndAssertAsync("publish /p:PublishProfile=Profile");
break;
case WebAppDeploymentKind.Ftp:
var publishDirectory = from.CreateSubdirectory("publish");
await dotnet.ExecuteAndAssertAsync("restore");
await dotnet.ExecuteAndAssertAsync("publish -o " + publishDirectory.FullName);
await site.UploadFilesAsync(publishDirectory, "/", await site.GetPublishingProfileAsync(), logger);
break;
default:
throw new ArgumentOutOfRangeException(nameof(kind), kind, null);
}
}
public static async Task GitDeploy(this IWebApp site, DirectoryInfo workingDirectory, ILogger logger)
{
// Allow site to restart after site extension installation
await Task.Delay(GitDeployDelay);
var git = new TestCommand("git")
{
Logger = logger,
WorkingDirectory = workingDirectory.FullName
};
var publishingProfile = await site.GetPublishingProfileAsync();
await git.ExecuteAndAssertAsync("init");
await git.ExecuteAndAssertAsync($"remote add origin https://{publishingProfile.GitUsername}:{publishingProfile.GitPassword}@{publishingProfile.GitUrl}");
await git.ExecuteAndAssertAsync("add .");
await git.ExecuteAndAssertAsync("commit -am Initial");
var result = await git.ExecuteAndAssertAsync("push origin master");
Assert.DoesNotContain("An error has occurred during web site deployment", result.StdErr);
Assert.DoesNotContain("deployment to website failed", result.StdErr);
}
public static async Task BuildPublishProfileAsync(this IWebApp site, string projectDirectory)
{
var result = await site.Manager.WebApps.Inner.ListPublishingProfileXmlWithSecretsAsync(
site.ResourceGroupName,
site.Name,
new CsmPublishingProfileOptionsInner());
var targetDirectory = Path.Combine(projectDirectory, "Properties", "PublishProfiles");
Directory.CreateDirectory(targetDirectory);
var publishSettings = XDocument.Load(result);
foreach (var profile in publishSettings.Root.Elements("publishProfile"))
{
if ((string) profile.Attribute("publishMethod") == "MSDeploy")
{
new XDocument(
new XElement("Project",
new XElement("PropertyGroup",
new XElement("WebPublishMethod", "MSDeploy"),
new XElement("PublishProvider", "AzureWebSite"),
new XElement("UserName", (string)profile.Attribute("userName")),
new XElement("Password", (string)profile.Attribute("userPWD")),
new XElement("MSDeployServiceURL", (string)profile.Attribute("publishUrl")),
new XElement("DeployIisAppPath", (string)profile.Attribute("msdeploySite"))
)))
.Save(Path.Combine(targetDirectory, "Profile.pubxml"));
}
}
}
}
}