Initial implementation runs tests against the InitializrAPI project endpoint.
* for each Steeltoe version, .NET framework, and dependency, download/build project
* for each Steeltoe version and .NET framework, download/build project for with every dependency
* each test runs in dedicated sandbox rooted in (tempdir)/Steeltoe.Initializr.ApiTests
* successful tests remove sandbox
* failed tests leave sandbox for post mortem
[#5]
This commit is contained in:
Chris Cheetham 2021-03-05 13:15:36 -05:00
Родитель 17f1139471
Коммит 9d313eb229
10 изменённых файлов: 381 добавлений и 28 удалений

9
.gitignore поставляемый
Просмотреть файл

@ -1,2 +1,7 @@
build/
.idea/
/build/
# User-specific state
/*.sln.DotSettings.user
# JetBrains Rider state
/.idea/

Просмотреть файл

@ -1,26 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A7A74035-D84B-4459-826D-EA63B87D31D1}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
azure-pipelines.yaml = azure-pipelines.yaml
docker-compose.yaml = docker-compose.yaml
Dockerfile = Dockerfile
LICENSE = LICENSE
README.md = README.md
SteeltoeInitializr.yaml = SteeltoeInitializr.yaml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,44 @@
Microsoft Visual Studio Solution File, Format Version 12.00
#
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A7A74035-D84B-4459-826D-EA63B87D31D1}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
azure-pipelines.yaml = azure-pipelines.yaml
docker-compose.yaml = docker-compose.yaml
Dockerfile = Dockerfile
LICENSE = LICENSE
README.md = README.md
Steeltoe.InitializrConfig.sln.DotSettings.user = Steeltoe.InitializrConfig.sln.DotSettings.user
SteeltoeInitializr.yaml = SteeltoeInitializr.yaml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Steeltoe.Initializr.ApiTests", "test\Initializr.ApiTests\Steeltoe.Initializr.ApiTests.csproj", "{954C08F0-A717-4BF6-944E-EA98F22FD225}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Debug|Any CPU.Build.0 = Debug|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Debug|x64.ActiveCfg = Debug|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Debug|x64.Build.0 = Debug|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Debug|x86.ActiveCfg = Debug|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Debug|x86.Build.0 = Debug|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Release|Any CPU.ActiveCfg = Release|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Release|Any CPU.Build.0 = Release|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Release|x64.ActiveCfg = Release|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Release|x64.Build.0 = Release|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Release|x86.ActiveCfg = Release|Any CPU
{954C08F0-A717-4BF6-944E-EA98F22FD225}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Initializr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Steeltoe/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

1
test-settings.yaml Normal file
Просмотреть файл

@ -0,0 +1 @@
apiUrl: http://localhost:1920/api

2
test/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
bin/
obj/

Просмотреть файл

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using RestSharp;
using Steeltoe.InitializrApi.Models;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace Steeltoe.Initializr.ApiTests
{
public static class Configuration
{
public static string ApiUrl { get; private set; }
public static RestClient RestClient { get; private set; }
public static string[] SteeltoeVersions { get; private set; }
public static string[] DotNetFrameworks { get; private set; }
public static string[] Dependencies { get; private set; }
public static string GetTestDir(string version, string framework, string dependency)
{
return Path.Combine(TestsDir, $"{version}--{framework}--{dependency}");
}
private static string TestsDir { get; } =
Path.Join(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name);
static Configuration()
{
using (var reader = new StreamReader("test-settings.yaml"))
{
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var settings = deserializer.Deserialize<TestSettings>(reader);
InitializeApiUrl(settings);
}
using (var reader = new StreamReader("SteeltoeInitializr.yaml"))
{
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var config = deserializer.Deserialize<InitializrConfig>(reader);
InitializeSteeltoeVersions(config);
InitializeDotNetFrameworks(config);
InitializeDependencies(config);
}
RestClient = new RestClient(ApiUrl);
}
private static void InitializeApiUrl(TestSettings settings)
{
ApiUrl = Environment.GetEnvironmentVariable("INITIALIZR_API_URL") ?? settings.ApiUrl;
}
private static void InitializeSteeltoeVersions(InitializrConfig config)
{
var versions = new List<string>();
foreach (var version in config.ProjectMetadata.SteeltoeVersion.Values)
{
versions.Add(version.Id);
}
SteeltoeVersions = versions.ToArray();
}
private static void InitializeDotNetFrameworks(InitializrConfig config)
{
var frameworks = new List<string>();
foreach (var framework in config.ProjectMetadata.DotNetFramework.Values)
{
frameworks.Add(framework.Id);
}
DotNetFrameworks = frameworks.ToArray();
}
private static void InitializeDependencies(InitializrConfig config)
{
var deps = new List<string>();
foreach (var group in config.ProjectMetadata.Dependencies.Values)
{
foreach (var item in group.Values)
{
deps.Add(item.Id);
}
}
Dependencies = deps.ToArray();
}
}
class TestSettings
{
public string ApiUrl { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,108 @@
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
using FluentAssertions;
using RestSharp;
using Xunit;
using Xunit.Abstractions;
namespace Steeltoe.Initializr.ApiTests
{
public class ProjectTests
{
private readonly ITestOutputHelper _console;
public ProjectTests(ITestOutputHelper output)
{
_console = output;
}
[Theory]
[ClassData(typeof(AllProjectCombinationsWithDependencies))]
public void TestProjectCombinationWithDependency(string version, string framework, string dependency)
{
var request = new RestRequest("project")
.AddParameter("steeltoeVersion", version)
.AddParameter("dotNetFramework", framework)
.AddParameter("dependencies", dependency);
var testDir = Configuration.GetTestDir(version, framework, dependency);
DownloadAndBuildProject(request, testDir);
}
[Theory]
[ClassData(typeof(AllProjectCombinations))]
public void TestProjectCombinationWithAllDependencies(string version, string framework)
{
var deps = string.Join(',', Configuration.Dependencies);
var request = new RestRequest("project")
.AddParameter("steeltoeVersion", version)
.AddParameter("dotNetFramework", framework)
.AddParameter("dependencies", deps);
var testDir = Configuration.GetTestDir(version, framework, "ALL");
DownloadAndBuildProject(request, testDir);
}
private void DownloadAndBuildProject(IRestRequest request, string workingDirectory)
{
var response = Configuration.RestClient.Get(request);
if (response.StatusCode.Equals(HttpStatusCode.NotFound))
{
_console.WriteLine($"skipping unsupported combination");
return;
}
response.StatusCode.Should().Be(HttpStatusCode.OK);
response.IsSuccessful.Should().BeTrue();
_console.WriteLine($"working directory: {workingDirectory}");
if (Directory.Exists(workingDirectory))
{
Directory.Delete(workingDirectory, true);
}
Directory.CreateDirectory(workingDirectory);
using (var buf = new MemoryStream(response.RawBytes))
{
var archive = new ZipArchive(buf);
foreach (var entry in archive.Entries)
{
var path = Path.GetFullPath(Path.Combine(workingDirectory, entry.FullName));
if (path.EndsWith("/"))
{
_console.WriteLine($"creating directory {path}");
Directory.CreateDirectory(path);
}
else
{
_console.WriteLine($"extracting {path}");
entry.ExtractToFile(path);
}
}
}
var pInfo = new ProcessStartInfo
{
FileName = "dotnet",
ArgumentList = {"build"},
WorkingDirectory = Path.Combine(workingDirectory, "Sample"),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
var proc = Process.Start(pInfo);
Assert.NotNull(proc);
proc.WaitForExit();
if (proc.ExitCode != 0)
{
_console.WriteLine("--- process STDOUT ---");
_console.WriteLine(proc.StandardOutput.ReadToEnd());
_console.WriteLine("--- process STDERR ---");
_console.WriteLine(proc.StandardError.ReadToEnd());
proc.ExitCode.Should().Be(0);
}
Directory.Delete(workingDirectory, true);
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\InitializrApi\src\InitializrApi\Steeltoe.InitializrApi.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="RestSharp" Version="106.11.7" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.3.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="YamlDotNet" Version="9.1.4" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\SteeltoeInitializr.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\test-settings.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Target Name="CleanBaseOutput" AfterTargets="Clean">
<RemoveDir Directories="$(BaseOutputPath)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
namespace Steeltoe.Initializr.ApiTests
{
public class AllProjectCombinations : IEnumerable<object[]>
{
private readonly List<object[]> _combinations;
public AllProjectCombinations()
{
_combinations = new List<object[]>();
var versions = Configuration.SteeltoeVersions;
var frameworks = Configuration.DotNetFrameworks;
// versions = new[] {"3.0.2"};
// frameworks = new[] {"netcoreapp3.1"};
foreach (var version in versions)
{
foreach (var framework in frameworks)
{
_combinations.Add(new object[] {version, framework});
}
}
}
public IEnumerator<object[]> GetEnumerator()
{
return _combinations.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class AllProjectCombinationsWithDependencies : IEnumerable<object[]>
{
private readonly List<object[]> _combinations;
public AllProjectCombinationsWithDependencies()
{
_combinations = new List<object[]>();
var versions = Configuration.SteeltoeVersions;
var frameworks = Configuration.DotNetFrameworks;
var deps = Configuration.Dependencies;
// versions = new[] {"3.0.2"};
// frameworks = new[] {"netcoreapp3.1"};
// deps = new[] {"docker"};
foreach (var version in versions)
{
foreach (var framework in frameworks)
{
foreach (var dep in deps)
{
_combinations.Add(new object[] {version, framework, dep});
}
}
}
}
public IEnumerator<object[]> GetEnumerator()
{
return _combinations.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}