This commit is contained in:
Peter Hsu 2019-06-20 15:56:19 -07:00 коммит произвёл GitHub
Родитель 7c5ec947f9
Коммит 68f7db939a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 141 добавлений и 29 удалений

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

@ -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();
}
}
}
}