Fix all unit tests for CI (#268)
This commit is contained in:
Родитель
7c5ec947f9
Коммит
68f7db939a
17
build.ps1
17
build.ps1
|
@ -28,7 +28,8 @@
|
|||
Do not uninstall the application after steps are run
|
||||
|
||||
.PARAMETER test
|
||||
Run the functional tests
|
||||
.PARAMETER testFilter
|
||||
Run the functional tests, use testFilter to filter to tests to be performed
|
||||
|
||||
.PARAMETER testPort
|
||||
The port to use for service
|
||||
|
@ -66,6 +67,9 @@ param(
|
|||
[switch]
|
||||
$test,
|
||||
|
||||
[string]
|
||||
$testFilter,
|
||||
|
||||
[int]
|
||||
$testPort = 55539,
|
||||
|
||||
|
@ -193,7 +197,13 @@ function CleanUp() {
|
|||
|
||||
function StartTest() {
|
||||
Write-Host "$(BuildHeader) Functional tests..."
|
||||
dotnet test ([System.IO.Path]::Combine($projectRoot, "test", "Microsoft.IIS.Administration.Tests", "Microsoft.IIS.Administration.Tests.csproj"))
|
||||
$testProj = [System.IO.Path]::Combine($projectRoot, "test", "Microsoft.IIS.Administration.Tests", "Microsoft.IIS.Administration.Tests.csproj")
|
||||
|
||||
if ($testFilter) {
|
||||
dotnet test $testProj --filter $testFilter
|
||||
} else {
|
||||
dotnet test $testProj
|
||||
}
|
||||
}
|
||||
|
||||
function VerifyPath($path) {
|
||||
|
@ -255,6 +265,9 @@ $scriptDir = Join-Path $projectRoot "scripts"
|
|||
# publish script only takes full path
|
||||
$publishPath = Join-Path $projectRoot "dist"
|
||||
$serviceName = GetGlobalVariable DEFAULT_SERVICE_NAME
|
||||
if ($testFilter) {
|
||||
$test = $true
|
||||
}
|
||||
|
||||
Write-Host "$(BuildHeader) Starting clean up..."
|
||||
CleanUp
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace Microsoft.IIS.Administration.Certificates
|
|||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
|
|
|
@ -11,16 +11,20 @@ namespace Microsoft.IIS.Administration.WebServer
|
|||
{
|
||||
private int _exitCode;
|
||||
private string _featureName;
|
||||
private string _errors;
|
||||
private string _outputs;
|
||||
|
||||
public DismException(int exitCode, string featureName) : base()
|
||||
public DismException(int exitCode, string featureName, string errors, string outputs) : base()
|
||||
{
|
||||
_exitCode = exitCode;
|
||||
_featureName = featureName;
|
||||
_errors = errors;
|
||||
_outputs = outputs;
|
||||
}
|
||||
|
||||
public dynamic GetApiError()
|
||||
{
|
||||
return ErrorHelper.DismError(_exitCode, _featureName);
|
||||
return ErrorHelper.DismError(_exitCode, _featureName, _errors, _outputs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
namespace Microsoft.IIS.Administration.WebServer
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class WebServerFeatureManager : IWebServerFeatureManager
|
||||
|
@ -36,10 +37,24 @@ namespace Microsoft.IIS.Administration.WebServer
|
|||
};
|
||||
|
||||
var tcs = new TaskCompletionSource<int>();
|
||||
|
||||
var errorStream = new StringBuilder();
|
||||
var outputStream = new StringBuilder();
|
||||
p.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
errorStream.AppendLine(e.Data);
|
||||
};
|
||||
p.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
outputStream.AppendLine(e.Data);
|
||||
};
|
||||
p.Exited += (sender, args) => {
|
||||
if (p.ExitCode != 0) {
|
||||
tcs.SetException(new DismException(p.ExitCode, string.Join(", ", features)));
|
||||
// 3010 status code: https://github.com/microsoft/IIS.Administration/issues/236
|
||||
tcs.SetException(new DismException(
|
||||
p.ExitCode,
|
||||
string.Join(", ", features),
|
||||
errorStream.ToString(),
|
||||
outputStream.ToString()));
|
||||
}
|
||||
else {
|
||||
tcs.SetResult(p.ExitCode);
|
||||
|
|
|
@ -46,11 +46,11 @@ namespace Microsoft.IIS.Administration.WebServer {
|
|||
};
|
||||
}
|
||||
|
||||
public static dynamic DismError(int exitCode, string featureName)
|
||||
public static dynamic DismError(int exitCode, string featureName, string errors, string outputs)
|
||||
{
|
||||
return new {
|
||||
title = "Server Error",
|
||||
detail = "Dism Error",
|
||||
detail = $"Dism Outputs: {outputs}\n\nError: {errors}",
|
||||
feature = featureName,
|
||||
exit_code = exitCode.ToString("X"),
|
||||
status = (int)HttpStatusCode.InternalServerError
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// NOTE: This test intermittently fails because it tries to disable/enable Windows Features. Details: https://github.com/Microsoft/IIS.Administration/issues/236
|
||||
public class CentralCertificates
|
||||
{
|
||||
private static readonly string CERTIFICATES_API_PATH = $"{Configuration.Instance().TEST_SERVER_URL}/api/certificates";
|
||||
|
@ -40,7 +41,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact(Skip = "Pending https://github.com/Microsoft/IIS.Administration/issues/236")]
|
||||
[Fact]
|
||||
public async Task CanEnable()
|
||||
{
|
||||
RequireCcsTestInfrastructure();
|
||||
|
@ -50,7 +51,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
Assert.True(Enable(FOLDER_PATH, user.Username, user.Password, PVK_PASS));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Pending https://github.com/Microsoft/IIS.Administration/issues/236")]
|
||||
[Fact]
|
||||
public async Task PathMustBeAllowed()
|
||||
{
|
||||
RequireCcsTestInfrastructure();
|
||||
|
@ -79,7 +80,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact(Skip = "Pending https://github.com/Microsoft/IIS.Administration/issues/236")]
|
||||
[Fact]
|
||||
public void CredentialsMustBeValid()
|
||||
{
|
||||
RequireCcsTestInfrastructure();
|
||||
|
@ -107,7 +108,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact(Skip = "Pending https://github.com/Microsoft/IIS.Administration/issues/236")]
|
||||
[Fact]
|
||||
public async Task DynamicallyAddsToStores()
|
||||
{
|
||||
RequireCcsTestInfrastructure();
|
||||
|
@ -121,7 +122,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
Assert.False(GetStores().Any(store => store.Value<string>("name").Equals(NAME, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Pending https://github.com/Microsoft/IIS.Administration/issues/236")]
|
||||
[Fact]
|
||||
public async Task CcsCertificatesShown()
|
||||
{
|
||||
RequireCcsTestInfrastructure();
|
||||
|
@ -134,7 +135,7 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
}));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Pending https://github.com/Microsoft/IIS.Administration/issues/236")]
|
||||
[Fact]
|
||||
public async Task CanCreateCcsBinding()
|
||||
{
|
||||
RequireCcsTestInfrastructure();
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
namespace Microsoft.IIS.Administration.Tests
|
||||
{
|
||||
using Microsoft.IIS.Administration.Tests.Asserts;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
|
||||
|
@ -18,6 +20,19 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
return Globals.Success(responseMessage);
|
||||
}
|
||||
|
||||
public static string AssertGet(this HttpClient client, string uri)
|
||||
{
|
||||
return AssertGet(client, uri, HttpAssertions.Success);
|
||||
}
|
||||
|
||||
public static string AssertGet(this HttpClient client, string uri, Action<HttpResponseMessage> assert)
|
||||
{
|
||||
var responseMessage = client.GetAsync(uri).Result;
|
||||
assert(responseMessage);
|
||||
var result = responseMessage.Content.ReadAsStringAsync().Result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static JObject Get(this HttpClient client, string uri)
|
||||
{
|
||||
string result = null;
|
||||
|
@ -79,6 +94,25 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
return Globals.Success(response);
|
||||
}
|
||||
|
||||
public static string AssertPatch(
|
||||
this HttpClient client,
|
||||
string uri,
|
||||
string body)
|
||||
{
|
||||
return AssertPatch(client, uri, body, HttpAssertions.Success);
|
||||
}
|
||||
|
||||
public static string AssertPatch(
|
||||
this HttpClient client,
|
||||
string uri,
|
||||
string body,
|
||||
Action<HttpResponseMessage> assert)
|
||||
{
|
||||
var response = PatchRaw(client, uri, body);
|
||||
assert(response);
|
||||
return response.Content.ReadAsStringAsync().Result;
|
||||
}
|
||||
|
||||
public static HttpResponseMessage PatchRaw(this HttpClient client, string uri, string body)
|
||||
{
|
||||
HttpContent content = new StringContent(body, Encoding.UTF8, "application/json");
|
||||
|
|
|
@ -105,13 +105,9 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
certificate = GetCertificate(client)
|
||||
}));
|
||||
|
||||
string result;
|
||||
string body = JsonConvert.SerializeObject(site);
|
||||
|
||||
Assert.True(client.Patch(Utils.Self(site), body, out result));
|
||||
|
||||
var result = client.AssertPatch(Utils.Self(site), body);
|
||||
JObject newSite = JsonConvert.DeserializeObject<JObject>(result);
|
||||
|
||||
WaitForStatus(client, ref newSite);
|
||||
|
||||
Assert.True(Utils.JEquals<bool>(site, newSite, "server_auto_start"));
|
||||
|
@ -555,17 +551,22 @@ namespace Microsoft.IIS.Administration.Tests
|
|||
}
|
||||
}
|
||||
|
||||
private static JObject GetCertificate(HttpClient client)
|
||||
private JObject GetCertificate(HttpClient client)
|
||||
{
|
||||
string result;
|
||||
if (!client.Get(CertificatesUrl + $"?intended_purpose={OIDServerAuth}", out result)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
string result = client.AssertGet(CertificatesUrl + $"?intended_purpose={OIDServerAuth}");
|
||||
var certsObj = JObject.Parse(result);
|
||||
var cert = certsObj.Value<JArray>("certificates").FirstOrDefault();
|
||||
|
||||
return cert != null ? cert.ToObject<JObject>() : null;
|
||||
var allCerts = certsObj.Value<JArray>("certificates");
|
||||
Assert.NotEmpty(allCerts);
|
||||
var localCerts = allCerts.Where(c => c["subject"].Value<string>() == "CN=localhost");
|
||||
Assert.NotEmpty(localCerts);
|
||||
var defaultCertName = "Microsoft IIS Administration Server Certificate";
|
||||
var cert = localCerts.FirstOrDefault(c => c["alias"].Value<string>() == defaultCertName);
|
||||
if (cert == null)
|
||||
{
|
||||
cert = localCerts.First();
|
||||
_output.WriteLine($"[WARNING]: unable to find {defaultCertName}, using {cert["alias"].Value<string>()} for tests instead.");
|
||||
}
|
||||
return cert.ToObject<JObject>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.IIS.Administration.Tests.Asserts {
|
||||
public static class Assertions {
|
||||
public static Action<T> All<T>(params Action<T>[] conditions) {
|
||||
return (T v) => {
|
||||
foreach (var c in conditions) {
|
||||
c(v);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.IIS.Administration.Tests.Asserts {
|
||||
public static class HttpAssertions
|
||||
{
|
||||
public static Action<HttpResponseMessage> Success
|
||||
= (HttpResponseMessage msg) => {
|
||||
Assert.True((int)msg.StatusCode >= 200, $"{Format(msg)}");
|
||||
Assert.True((int)msg.StatusCode < 300, $"{Format(msg)}");
|
||||
};
|
||||
|
||||
private static string Format(HttpResponseMessage msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
string content = msg.Content.ReadAsStringAsync().Result;
|
||||
return msg.ToString() + "\nContent:" + content;
|
||||
} catch (Exception e)
|
||||
{
|
||||
return msg.ToString() + "\nError parsing content:" + e.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче