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

155 lines
5.9 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.Azure.Management.AppService.Fluent;
using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Core;
using Microsoft.Azure.Management.ResourceManager.Fluent.Models;
using Microsoft.Azure.Management.Storage.Fluent;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using Microsoft.Rest;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.AzureAppServices.FunctionalTests
{
public class AzureFixture : IDisposable
{
public string Timestamp { get; set; }
public AzureFixture()
{
TestLog = AssemblyTestLog.ForAssembly(typeof(AzureFixture).Assembly);
// TODO: Temporary to see if it's useful and worth exposing
var globalLoggerFactory =
(ILoggerFactory) TestLog.GetType().GetField("_globalLoggerFactory", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(TestLog);
var logger = globalLoggerFactory.CreateLogger<AzureFixture>();
ServiceClientTracing.IsEnabled = true;
ServiceClientTracing.AddTracingInterceptor(new LoggingInterceptor(globalLoggerFactory.CreateLogger(nameof(ServiceClientTracing))));
var clientId = GetRequiredEnvironmentVariable("AZURE_AUTH_CLIENT_ID");
var clientSecret = GetRequiredEnvironmentVariable("AZURE_AUTH_CLIENT_SECRET");
var tenant = GetRequiredEnvironmentVariable("AZURE_AUTH_TENANT");
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(clientId, clientSecret, tenant, AzureEnvironment.AzureGlobalCloud);
Azure = Microsoft.Azure.Management.Fluent.Azure.Configure()
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Authenticate(credentials)
.WithDefaultSubscription();
Timestamp = DateTime.Now.ToString("yyyyMMddhhmmss");
var testRunName = GetTimestampedName("FunctionalTests");
logger.LogInformation("Creating resource group {TestRunName}", testRunName);
ResourceGroup = Azure.ResourceGroups
.Define(testRunName)
.WithRegion(Region.USWest2)
.Create();
var servicePlanName = GetTimestampedName("TestPlan");
logger.LogInformation("Creating service plan {servicePlanName}", testRunName);
Plan = Azure.AppServices.AppServicePlans.Define(servicePlanName)
.WithRegion(Region.USWest2)
.WithExistingResourceGroup(ResourceGroup)
.WithFreePricingTier()
.Create();
}
public static string GetRequiredEnvironmentVariable(string name)
{
var authFile = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(authFile))
{
throw new InvalidOperationException($"{name} environment variable has to be set to run these tests.");
}
return authFile;
}
public IAppServicePlan Plan { get; set; }
public IStorageAccount DeploymentStorageAccount { get; set; }
public AssemblyTestLog TestLog { get; set; }
public bool DeleteResourceGroup { get; set; } = true;
public IResourceGroup ResourceGroup { get; set; }
public IAzure Azure { get; set; }
public string GetTimestampedName(string name)
{
return name + Timestamp;
}
public async Task<IWebApp> Deploy(string template, IDictionary<string, string> additionalArguments = null, [CallerMemberName] string baseName = null)
{
var siteName = GetTimestampedName(baseName);
var parameters = new Dictionary<string, string>
{
{"siteName", siteName},
{"hostingPlanName", Plan.Name},
{"resourceGroupName", ResourceGroup.Name},
};
foreach (var pair in additionalArguments ?? Enumerable.Empty<KeyValuePair<string, string>>())
{
parameters[pair.Key] = pair.Value;
}
var readAllText = File.ReadAllText(template);
var deployment = await Azure.Deployments.Define(GetTimestampedName("Deployment"))
.WithExistingResourceGroup(ResourceGroup)
.WithTemplate(readAllText)
.WithParameters(ToParametersObject(parameters))
.WithMode(DeploymentMode.Incremental)
.CreateAsync();
deployment = await deployment.RefreshAsync();
var outputs = (JObject)deployment.Outputs;
var siteIdOutput = outputs["siteId"];
if (siteIdOutput == null)
{
throw new InvalidOperationException("Deployment was expected to have 'siteId' output parameter");
}
var siteId = siteIdOutput["value"].Value<string>();
return await Azure.AppServices.WebApps.GetByIdAsync(siteId);
}
private JObject ToParametersObject(Dictionary<string, string> parameters)
{
return new JObject(
parameters.Select(parameter =>
new JProperty(
parameter.Key,
new JObject(
new JProperty("value", parameter.Value)))));
}
public void Dispose()
{
TestLog.Dispose();
if (DeleteResourceGroup && ResourceGroup != null)
{
Azure.ResourceGroups.DeleteByName(ResourceGroup.Name);
}
}
}
}