diff --git a/test/EmptyWebTemplateTest.cs b/test/EmptyWebTemplateTest.cs new file mode 100644 index 0000000000..ee2ae747cb --- /dev/null +++ b/test/EmptyWebTemplateTest.cs @@ -0,0 +1,20 @@ +using Xunit; + +namespace Templates.Test +{ + public class EmptyWebTemplateTest : TemplateTestBase + { + [Theory] + [InlineData(null)] + [InlineData("net461")] + public void EmptyWebTemplate_Works(string targetFrameworkOverride) + { + RunDotNetNew("web", targetFrameworkOverride); + + using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride)) + { + aspNetProcess.AssertOk("/"); + } + } + } +} diff --git a/test/Helpers/AspNetProcess.cs b/test/Helpers/AspNetProcess.cs new file mode 100644 index 0000000000..087b35bec9 --- /dev/null +++ b/test/Helpers/AspNetProcess.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading; +using Xunit; + +namespace Templates.Test.Helpers +{ + public class AspNetProcess : IDisposable + { + private const string DefaultFramework = "netcoreapp2.0"; + private const string ListeningMessagePrefix = "Now listening on: "; + + private static int NextKestrelPort = 5000; + + private readonly ProcessEx _process; + private readonly Uri _listeningUri; + private readonly HttpClient _httpClient; + + public AspNetProcess(string workingDirectory, string projectName, string targetFrameworkOverride) + { + _httpClient = new HttpClient(); + + var buildProcess = ProcessEx.Run(workingDirectory, "dotnet", "build --no-restore -c Debug"); + buildProcess.WaitForExit(assertSuccess: true); + + var port = Interlocked.Increment(ref NextKestrelPort); + var envVars = new Dictionary + { + { "ASPNETCORE_URLS", "http://localhost:" + port } + }; + + var framework = string.IsNullOrEmpty(targetFrameworkOverride) ? DefaultFramework : targetFrameworkOverride; + if (framework.StartsWith("netcore")) + { + _process = ProcessEx.Run(workingDirectory, "dotnet", $"exec bin/Debug/{framework}/{projectName}.dll", envVars: envVars); + } + else + { + var exeFullPath = Path.Combine(workingDirectory, "bin", "Debug", framework, $"{projectName}.exe"); + _process = ProcessEx.Run(workingDirectory, exeFullPath, envVars: envVars); + } + + // Wait until the app is accepting HTTP requests + var listeningMessage = _process + .OutputLinesAsEnumerable + .Where(line => line != null) + .FirstOrDefault(line => line.StartsWith(ListeningMessagePrefix, StringComparison.Ordinal)); + Assert.True(!string.IsNullOrEmpty(listeningMessage), $"ASP.NET process exited without listening for requests.\nOutput: { _process.Output }\nError: { _process.Error }"); + + // Verify we have a valid URL to make requests to + var listeningUrlString = listeningMessage.Substring(ListeningMessagePrefix.Length); + _listeningUri = new Uri(listeningUrlString, UriKind.Absolute); + } + + internal void AssertOk(string requestUrl) + => AssertStatusCode(requestUrl, HttpStatusCode.OK); + + internal void AssertNotFound(string requestUrl) + => AssertStatusCode(requestUrl, HttpStatusCode.NotFound); + + internal void AssertStatusCode(string requestUrl, HttpStatusCode statusCode) + { + var request = new HttpRequestMessage( + HttpMethod.Get, + new Uri(_listeningUri, requestUrl)); + + var response = _httpClient.SendAsync(request).Result; + Assert.Equal(statusCode, response.StatusCode); + } + + public void Dispose() + { + _httpClient.Dispose(); + _process.Dispose(); + } + } +} diff --git a/test/Helpers/ProcessEx.cs b/test/Helpers/ProcessEx.cs new file mode 100644 index 0000000000..50437e9744 --- /dev/null +++ b/test/Helpers/ProcessEx.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Text; +using Xunit; + +namespace Templates.Test.Helpers +{ + internal class ProcessEx : IDisposable + { + private readonly Process _process; + private readonly StringBuilder _stderrCapture; + private readonly StringBuilder _stdoutCapture; + private BlockingCollection _stdoutLines; + + public static ProcessEx Run(string workingDirectory, string command, string args = null, IDictionary envVars = null) + { + var startInfo = new ProcessStartInfo(command, args) + { + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + WorkingDirectory = workingDirectory + }; + + if (envVars != null) + { + foreach (var envVar in envVars) + { + startInfo.EnvironmentVariables.Add(envVar.Key, envVar.Value); + } + } + + var proc = Process.Start(startInfo); + + return new ProcessEx(proc); + } + + public ProcessEx(Process proc) + { + _stdoutCapture = new StringBuilder(); + _stderrCapture = new StringBuilder(); + _stdoutLines = new BlockingCollection(); + + _process = proc; + proc.EnableRaisingEvents = true; + proc.OutputDataReceived += OnOutputData; + proc.ErrorDataReceived += OnErrorData; + proc.Exited += OnProcessExited; + proc.BeginOutputReadLine(); + proc.BeginErrorReadLine(); + } + + public string Error => _stderrCapture.ToString(); + + public string Output => _stdoutCapture.ToString(); + + public int ExitCode => _process.ExitCode; + + private void OnErrorData(object sender, DataReceivedEventArgs e) + { + _stderrCapture.AppendLine(e.Data); + Console.Error.WriteLine(e.Data); + } + + private void OnOutputData(object sender, DataReceivedEventArgs e) + { + _stdoutCapture.AppendLine(e.Data); + Console.WriteLine(e.Data); + + if (_stdoutLines != null) + { + _stdoutLines.Add(e.Data); + } + } + + private void OnProcessExited(object sender, EventArgs e) + { + _stdoutLines.CompleteAdding(); + _stdoutLines = null; + } + + public void WaitForExit(bool assertSuccess) + { + _process.WaitForExit(); + + if (assertSuccess && _process.ExitCode != 0) + { + throw new Exception($"Process exited with code {_process.ExitCode}\nStdErr: {Error}\nStdOut: {Output}"); + } + } + + public void Dispose() + { + if (_process != null && !_process.HasExited) + { + _process.Kill(); + _process.WaitForExit(); + } + } + + public IEnumerable OutputLinesAsEnumerable => _stdoutLines.GetConsumingEnumerable(); + } +} diff --git a/test/Helpers/TemplateTestBase.cs b/test/Helpers/TemplateTestBase.cs new file mode 100644 index 0000000000..8727126b97 --- /dev/null +++ b/test/Helpers/TemplateTestBase.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; +using System.Reflection; +using System.Threading; +using Templates.Test.Helpers; +using Xunit; + +namespace Templates.Test +{ + public class TemplateTestBase : IDisposable + { + protected string ProjectName { get; set; } + protected string TemplateOutputDir { get; private set; } + + public TemplateTestBase() + { + ProjectName = Guid.NewGuid().ToString().Replace("-", ""); + + var assemblyPath = GetType().GetTypeInfo().Assembly.CodeBase; + var assemblyUri = new Uri(assemblyPath, UriKind.Absolute); + var basePath = Path.GetDirectoryName(assemblyUri.LocalPath); + TemplateOutputDir = Path.Combine(basePath, "TestTemplates", ProjectName); + Directory.CreateDirectory(TemplateOutputDir); + } + + protected void InstallTemplatePackages() + { + throw new NotImplementedException(); + } + + protected void RunDotNetNew(string templateName, string targetFrameworkOverride, string auth = null, string language = null) + { + var args = $"new {templateName}"; + + if (!string.IsNullOrEmpty(targetFrameworkOverride)) + { + args += $" --target-framework-override {targetFrameworkOverride}"; + } + + if (!string.IsNullOrEmpty(auth)) + { + args += $" -au {auth}"; + } + + if (!string.IsNullOrEmpty(language)) + { + args += $" -lang {language}"; + } + + ProcessEx.Run(TemplateOutputDir, "dotnet", args).WaitForExit(assertSuccess: true); + } + + protected void AssertDirectoryExists(string path, bool shouldExist) + { + var fullPath = Path.Combine(TemplateOutputDir, path); + var doesExist = Directory.Exists(fullPath); + + if (shouldExist) + { + Assert.True(doesExist, "Expected directory to exist, but it doesn't: " + path); + } + else + { + Assert.False(doesExist, "Expected directory not to exist, but it does: " + path); + } + } + + protected void AssertFileExists(string path, bool shouldExist) + { + var fullPath = Path.Combine(TemplateOutputDir, path); + var doesExist = File.Exists(fullPath); + + if (shouldExist) + { + Assert.True(doesExist, "Expected file to exist, but it doesn't: " + path); + } + else + { + Assert.False(doesExist, "Expected file not to exist, but it does: " + path); + } + } + + protected string ReadFile(string path) + { + AssertFileExists(path, shouldExist: true); + return File.ReadAllText(Path.Combine(TemplateOutputDir, path)); + } + + protected AspNetProcess StartAspNetProcess(string targetFrameworkOverride) + { + return new AspNetProcess(TemplateOutputDir, ProjectName, targetFrameworkOverride); + } + + public void Dispose() + { + DeleteOutputDirectory(); + } + + private void DeleteOutputDirectory() + { + var numAttempts = 5; + while (true) + { + try + { + Directory.Delete(TemplateOutputDir, true); + return; + } + catch (IOException) + { + numAttempts--; + if (numAttempts > 0) + { + Thread.Sleep(2000); + } + else + { + throw; + } + } + } + } + } +} diff --git a/test/MvcTemplateTest.cs b/test/MvcTemplateTest.cs new file mode 100644 index 0000000000..862498ea83 --- /dev/null +++ b/test/MvcTemplateTest.cs @@ -0,0 +1,63 @@ +using Xunit; + +namespace Templates.Test +{ + public class MvcTemplateTest : TemplateTestBase + { + [Theory] + [InlineData(/* netcoreapp */ null, /* C# */ null)] + [InlineData("net461", /* C# */ null)] + [InlineData(/* netcoreapp */ null, "F#")] + [InlineData("net461", "F#")] + public void MvcTemplate_NoAuth_Works(string targetFrameworkOverride, string languageOverride) + { + RunDotNetNew("mvc", targetFrameworkOverride, language: languageOverride); + + AssertDirectoryExists("Areas", false); + AssertDirectoryExists("Extensions", false); + AssertFileExists("urlRewrite.config", false); + AssertFileExists("Controllers/AccountController.cs", false); + + var projectExtension = languageOverride == "F#" ? "fsproj" : "csproj"; + var projectFileContents = ReadFile($"{ProjectName}.{projectExtension}"); + Assert.DoesNotContain(".db", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); + Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); + Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); + + using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride)) + { + aspNetProcess.AssertOk("/"); + aspNetProcess.AssertOk("/Home/About"); + aspNetProcess.AssertOk("/Home/Contact"); + } + } + + [Theory] + [InlineData(null)] + [InlineData("net461")] + public void MvcTemplate_IndividualAuth_Works(string targetFrameworkOverride) + { + RunDotNetNew("mvc", targetFrameworkOverride, auth: "Individual"); + + AssertDirectoryExists("Extensions", true); + AssertFileExists("urlRewrite.config", false); + AssertFileExists("Controllers/AccountController.cs", true); + + var projectFileContents = ReadFile($"{ProjectName}.csproj"); + Assert.Contains(".db", projectFileContents); + Assert.Contains("Microsoft.EntityFrameworkCore.Tools", projectFileContents); + Assert.Contains("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); + Assert.Contains("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); + Assert.Contains("Microsoft.Extensions.SecretManager.Tools", projectFileContents); + + using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride)) + { + aspNetProcess.AssertOk("/"); + aspNetProcess.AssertOk("/Home/About"); + aspNetProcess.AssertOk("/Home/Contact"); + } + } + } +} diff --git a/test/RazorPagesTemplateTest.cs b/test/RazorPagesTemplateTest.cs new file mode 100644 index 0000000000..d1e663b770 --- /dev/null +++ b/test/RazorPagesTemplateTest.cs @@ -0,0 +1,57 @@ +using Xunit; + +namespace Templates.Test +{ + public class RazorPagesTemplateTest : TemplateTestBase + { + [Theory] + [InlineData(null)] + [InlineData("net461")] + public void RazorPagesTemplate_NoAuth_Works(string targetFrameworkOverride) + { + RunDotNetNew("razor", targetFrameworkOverride); + + AssertDirectoryExists("Extensions", false); + AssertFileExists("Controllers/AccountController.cs", false); + + var projectFileContents = ReadFile($"{ProjectName}.csproj"); + Assert.DoesNotContain(".db", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); + Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); + Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); + + using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride)) + { + aspNetProcess.AssertOk("/"); + aspNetProcess.AssertOk("/About"); + aspNetProcess.AssertOk("/Contact"); + } + } + + [Theory] + [InlineData(null)] + [InlineData("net461")] + public void RazorPagesTemplate_IndividualAuth_Works(string targetFrameworkOverride) + { + RunDotNetNew("razor", targetFrameworkOverride, auth: "Individual"); + + AssertDirectoryExists("Extensions", true); + AssertFileExists("Controllers/AccountController.cs", true); + + var projectFileContents = ReadFile($"{ProjectName}.csproj"); + Assert.Contains(".db", projectFileContents); + Assert.Contains("Microsoft.EntityFrameworkCore.Tools", projectFileContents); + Assert.Contains("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); + Assert.Contains("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); + Assert.Contains("Microsoft.Extensions.SecretManager.Tools", projectFileContents); + + using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride)) + { + aspNetProcess.AssertOk("/"); + aspNetProcess.AssertOk("/About"); + aspNetProcess.AssertOk("/Contact"); + } + } + } +} diff --git a/test/WebApiTemplateTest.cs b/test/WebApiTemplateTest.cs new file mode 100644 index 0000000000..bdabe0368a --- /dev/null +++ b/test/WebApiTemplateTest.cs @@ -0,0 +1,21 @@ +using Xunit; + +namespace Templates.Test +{ + public class WebApiTemplateTest : TemplateTestBase + { + [Theory] + [InlineData(null)] + [InlineData("net461")] + public void WebApiTemplate_Works(string targetFrameworkOverride) + { + RunDotNetNew("api", targetFrameworkOverride); + + using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride)) + { + aspNetProcess.AssertOk("/api/values"); + aspNetProcess.AssertNotFound("/"); + } + } + } +} diff --git a/test/WebTemplateTest.cs b/test/WebTemplateTest.cs deleted file mode 100644 index 6df8543519..0000000000 --- a/test/WebTemplateTest.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Xunit; - -namespace Templates.Test -{ - public class WebTemplateTest - { - } -} diff --git a/tools/ProjectTestRunner/Battery.cs b/tools/ProjectTestRunner/Battery.cs deleted file mode 100644 index a622970bcf..0000000000 --- a/tools/ProjectTestRunner/Battery.cs +++ /dev/null @@ -1,304 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; -using ProjectTestRunner.Handlers; -using ProjectTestRunner.Helpers; -using Xunit; -using Xunit.Abstractions; - -[assembly: CollectionBehavior(DisableTestParallelization = true)] - -namespace ProjectTestRunner -{ - public class Battery - { - private static readonly IReadOnlyDictionary HandlerLookup = new Dictionary - { - { ExecuteHandler.Handler, new ExecuteHandler() }, - { TaskKillHandler.Handler, new TaskKillHandler() }, - { HttpRequestHandler.Handler, new HttpRequestHandler() }, - { FindProcessHandler.Handler, new FindProcessHandler() }, - { FileInspectHandler.Handler, new FileInspectHandler() }, - { DirectoryInspectHandler.Handler, new DirectoryInspectHandler() }, - }; - - private static readonly string Creator; - private static readonly string BasePath; - - static Battery() - { - string assemblyPath = typeof(Battery).GetTypeInfo().Assembly.CodeBase; - Uri assemblyUri = new Uri(assemblyPath, UriKind.Absolute); - assemblyPath = assemblyUri.LocalPath; - BasePath = Path.GetDirectoryName(assemblyPath); - - Creator = Environment.GetEnvironmentVariable("CREATION_TEST_RUNNER"); - - if (string.IsNullOrWhiteSpace(Creator)) - { - Creator = "new"; - } - - Proc.Run("dotnet", $"--version").WaitForExit(); - - Proc.Run("dotnet", $"{Creator} --debug:reinit").WaitForExit(); - Proc.Run("dotnet", $"{Creator}").WaitForExit(); - - string templateFeedDirectory = FindTemplateFeedDirectory(BasePath); - Proc.Run("dotnet", $"{Creator} -i \"{templateFeedDirectory}\"").WaitForExit(); - } - - public Battery(ITestOutputHelper outputHelper) - { - Console.SetOut(new OutputHelperHelper(outputHelper)); - Console.SetError(new OutputHelperHelper(outputHelper)); - } - - [PrettyTheory, MemberData(nameof(Discover))] - public void Run(TemplateTestData testData) - { - bool success = true; - string[] allParts = new string[testData.Paths.Length + 2]; - allParts[0] = BasePath; - allParts[1] = "TestCases"; - - for (int i = 0; i < testData.Paths.Length; ++i) - { - allParts[i + 2] = testData.Paths[i]; - } - - string contents = File.ReadAllText(Path.Combine(allParts)); - contents = Environment.ExpandEnvironmentVariables(contents); - - JObject json = JObject.Parse(contents); - - if (json["skip"]?.Value() ?? false) - { - Console.WriteLine("Test Skipped"); - return; - } - - string targetPath = Path.Combine(GetTemplatePath(), "_" + Guid.NewGuid().ToString().Replace("-", "")); - try - { - string install = json["install"]?.ToString(); - string command = testData.CreateCommand; - - Console.WriteLine("Testing: " + testData.Name); - Dictionary dict = new Dictionary - { - { "targetPath", targetPath}, - { "targetPathName", Path.GetFileName(targetPath)}, - }; - - List results = new List(); - IHandlerResult current; - string message; - - if (!string.IsNullOrWhiteSpace(install)) - { - Console.WriteLine($"Executing step {(results.Count + 1)} (install)..."); - current = Install(Creator, install); - - message = current.VerificationSuccess ? $"PASS ({current.Duration})" : $"FAIL ({current.Duration}): {current.FailureMessage}"; - Console.WriteLine($" {message}"); - Console.WriteLine(" "); - - if (!current.VerificationSuccess) - { - success = false; - Assert.False(true, current.FailureMessage); - } - } - - Console.WriteLine($"Executing step {(results.Count + 1)} (create)..."); - current = Create(Creator, install, testData.CreateCommand, targetPath); - - message = current.VerificationSuccess ? $"PASS ({current.Duration})" : $"FAIL ({current.Duration}): {current.FailureMessage}"; - Console.WriteLine($" {message}"); - Console.WriteLine(" "); - - if (!current.VerificationSuccess) - { - success = false; - Assert.False(true, current.FailureMessage); - } - - results.Add(current); - - foreach (JObject entry in ((JArray)json["tasks"]).Children().OfType()) - { - string handlerKey = entry["handler"].ToString(); - string variationKey = entry["variation"]?.ToString(); - - // running the right variation, or - if (string.Equals(testData.Variation, variationKey) - || variationKey == null - || (testData.Variation == null && variationKey.Equals(string.Empty))) - { - IHandler handler = HandlerLookup[handlerKey]; - Console.WriteLine($"Executing step {(results.Count + 1)} ({handler.Summarize(dict, entry)})..."); - current = handler.Execute(dict, results, entry); - message = current.VerificationSuccess ? $"PASS ({current.Duration})" : $"FAIL ({current.Duration}): {current.FailureMessage}"; - Console.WriteLine($" {message}"); - Console.WriteLine(" "); - results.Add(current); - } - } - - foreach (IHandlerResult result in results) - { - success = !success ? success : result.VerificationSuccess; - Assert.False(!result.VerificationSuccess, result.FailureMessage); - } - } - finally - { - if (success) - { - for (int i = 0; i < 5; ++i) - { - try - { - DeleteDirectory(targetPath); - break; - } - catch - { - Thread.Sleep(500); - } - } - } - } - } - - public static void DeleteDirectory(string directory) - { - string[] files = Directory.GetFiles(directory); - string[] dirs = Directory.GetDirectories(directory); - - foreach (string file in files) - { - File.SetAttributes(file, FileAttributes.Normal); - File.Delete(file); - } - - foreach (string dir in dirs) - { - DeleteDirectory(dir); - } - - Directory.Delete(directory, true); - } - - - private IHandlerResult Install(string creator, string installPackage) - { - Stopwatch watch = Stopwatch.StartNew(); - try - { - Process install = Proc.Run("dotnet", $"{creator} -i \"{installPackage}\""); - install.WaitForExit(); - - if (install.ExitCode != 0) - { - return new GenericHandlerResult(watch.Elapsed, false, $"\"{installPackage}\" failed to install"); - } - - return new GenericHandlerResult(watch.Elapsed, true, null); - } - finally - { - watch.Stop(); - } - } - - private static string FindTemplateFeedDirectory(string batteryDirectory) - { - DirectoryInfo currentDirectory = new DirectoryInfo(batteryDirectory); - string templateFeed = Path.Combine(currentDirectory.FullName, "template_feed"); - - while (!Directory.Exists(templateFeed)) - { - currentDirectory = currentDirectory.Parent; - templateFeed = Path.Combine(currentDirectory.FullName, "template_feed"); - } - - return templateFeed; - } - - private static IHandlerResult Create(string creator, string installPackage, string command, string targetPath) - { - Stopwatch watch = Stopwatch.StartNew(); - try - { - Directory.CreateDirectory(targetPath); - Process create = Proc.Run("dotnet", $"{creator} {command} -o \"{targetPath}\""); - create.WaitForExit(); - - if (create.ExitCode != 0) - { - return new GenericHandlerResult(watch.Elapsed, false, $"\"{command}\" failed create"); - } - - Directory.SetCurrentDirectory(targetPath); - return new GenericHandlerResult(watch.Elapsed, true, null); - } - finally - { - watch.Stop(); - } - } - - private string GetTemplatePath() - { - return Path.Combine(BasePath, "TestTemplates"); - } - - public static IEnumerable Discover() - { - string basePath = Path.Combine(BasePath, "TestCases"); - - foreach (string testCase in Directory.EnumerateFiles(basePath, "*.json", SearchOption.AllDirectories)) - { - string contents = File.ReadAllText(Path.Combine(testCase)); - contents = Environment.ExpandEnvironmentVariables(contents); - - JObject json = JObject.Parse(contents); - - string relPath = testCase.Substring(basePath.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - - var data = new TemplateTestData() - { - Paths = relPath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar), - Name = json["name"].ToString(), - CreateCommand = json["create"].ToString(), - Variation = null - }; - - yield return new object[] { data }; - - if (json["variations"] != null) - { - foreach (JObject entry in ((JArray)json["variations"]).Children().OfType()) - { - var variation = new TemplateTestData() - { - Paths = relPath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar), - Name = entry["name"]?.ToString() ?? data.Name, - Variation = entry["id"].ToString(), - CreateCommand = entry["create"]?.ToString() ?? data.CreateCommand - }; - yield return new object[] { variation }; - } - } - } - } - } -} diff --git a/tools/ProjectTestRunner/HandlerResults/ExecuteHandlerResult.cs b/tools/ProjectTestRunner/HandlerResults/ExecuteHandlerResult.cs deleted file mode 100644 index d90a007af4..0000000000 --- a/tools/ProjectTestRunner/HandlerResults/ExecuteHandlerResult.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Diagnostics; - -namespace ProjectTestRunner.HandlerResults -{ - internal class ExecuteHandlerResult : IHandlerResult - { - private readonly Process _process; - - public ExecuteHandlerResult(TimeSpan duration, bool verificationSuccess, string failureMessage, Process process = null, string name = null) - { - Duration = duration; - _process = process; - Name = name; - VerificationSuccess = verificationSuccess; - FailureMessage = failureMessage; - } - - public bool VerificationSuccess { get; } - - public string FailureMessage { get; } - - public string Name { get; } - - public TimeSpan Duration { get; } - - public void Kill() - { - _process?.Kill(); - } - } -} \ No newline at end of file diff --git a/tools/ProjectTestRunner/HandlerResults/GenericHandlerResult.cs b/tools/ProjectTestRunner/HandlerResults/GenericHandlerResult.cs deleted file mode 100644 index edfe079638..0000000000 --- a/tools/ProjectTestRunner/HandlerResults/GenericHandlerResult.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace ProjectTestRunner.HandlerResults -{ - internal class GenericHandlerResult : IHandlerResult - { - public GenericHandlerResult(TimeSpan duration, bool verificationSuccess, string failureMessage, string name = null) - { - Duration = duration; - Name = name; - VerificationSuccess = verificationSuccess; - FailureMessage = failureMessage; - } - - public string Name { get; } - - public bool VerificationSuccess { get; } - - public string FailureMessage { get; } - - public TimeSpan Duration { get; } - } -} \ No newline at end of file diff --git a/tools/ProjectTestRunner/HandlerResults/IHandlerResult.cs b/tools/ProjectTestRunner/HandlerResults/IHandlerResult.cs deleted file mode 100644 index 17587f09d4..0000000000 --- a/tools/ProjectTestRunner/HandlerResults/IHandlerResult.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace ProjectTestRunner.HandlerResults -{ - public interface IHandlerResult - { - string Name { get; } - - bool VerificationSuccess { get; } - - string FailureMessage { get; } - - TimeSpan Duration { get; } - } -} diff --git a/tools/ProjectTestRunner/Handlers/DirectoryInspectHandler.cs b/tools/ProjectTestRunner/Handlers/DirectoryInspectHandler.cs deleted file mode 100644 index f12449d815..0000000000 --- a/tools/ProjectTestRunner/Handlers/DirectoryInspectHandler.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; - -namespace ProjectTestRunner.Handlers -{ - // - // directory: rel path to directory - // assertion: exists | does_not_exist - - public class DirectoryInspectHandler : IHandler - { - public static string Handler => "directoryInspect"; - - public string HandlerName => Handler; - - public IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json) - { - Stopwatch watch = Stopwatch.StartNew(); - try - { - string basePath = tokens["targetPath"]; - - string name = json["name"]?.ToString(); - string directoryName = json["directory"].ToString(); - string pathToDirectory = Path.Combine(basePath, directoryName); - string assertion = json["assertion"].ToString(); - bool doesDirectoryExist = Directory.Exists(pathToDirectory); - - if (string.Equals(assertion, "exists", StringComparison.OrdinalIgnoreCase)) - { - if (!doesDirectoryExist) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected directory {directoryName} to exist, but it did not", name: name); - } - } - else if (string.Equals(assertion, "does_not_exist", StringComparison.OrdinalIgnoreCase)) - { - if (doesDirectoryExist) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected directory {directoryName} to not exist, but it did", name: name); - } - } - - return new GenericHandlerResult(watch.Elapsed, true, null); - } - catch (Exception ex) - { - return new GenericHandlerResult(watch.Elapsed, false, ex.Message); - } - } - - public string Summarize(IReadOnlyDictionary tokens, JObject json) - { - string directoryName = json["directory"].ToString(); - string assertion = json["assertion"].ToString().ToLowerInvariant().Replace("_", " "); - - return $"Directory inspection - checking if directory \"{directoryName}\" {assertion}"; - } - } -} diff --git a/tools/ProjectTestRunner/Handlers/ExecuteHandler.cs b/tools/ProjectTestRunner/Handlers/ExecuteHandler.cs deleted file mode 100644 index 6226f11777..0000000000 --- a/tools/ProjectTestRunner/Handlers/ExecuteHandler.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; -using ProjectTestRunner.Helpers; - -namespace ProjectTestRunner.Handlers -{ - public class ExecuteHandler : IHandler - { - public static string Handler => "execute"; - - public string HandlerName => Handler; - - public IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json) - { - Stopwatch watch = Stopwatch.StartNew(); - try - { - string args = json["args"]?.ToString() ?? string.Empty; - - foreach (KeyValuePair entry in tokens) - { - args = args.Replace($"%{entry.Key}%", entry.Value); - } - - string command = json["command"].ToString(); - - foreach (KeyValuePair entry in tokens) - { - command = command.Replace($"%{entry.Key}%", entry.Value); - } - - ProcessEx p = Proc.Run(command, args); - string name = json["name"]?.ToString(); - - if (json["noExit"]?.Value() ?? false) - { - if (p.WaitForExit(json["exitTimeout"]?.Value() ?? 1000)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, "Process exited unexpectedly", name: name); - } - - return new ExecuteHandlerResult(watch.Elapsed, true, null, p, name); - } - else - { - p.WaitForExit(); - int expectedExitCode = json["exitCode"]?.Value() ?? 0; - bool success = expectedExitCode == p.ExitCode; - - if (!success) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Process exited with code {p.ExitCode} instead of {expectedExitCode}", name: name); - } - - JArray expectations = json["expectations"]?.Value(); - - if(expectations != null) - { - foreach(JObject expectation in expectations.Children().OfType()) - { - string assertion = expectation["assertion"]?.Value()?.ToUpperInvariant(); - string s; - StringComparison c; - - switch (assertion) - { - case "OUTPUT_CONTAINS": - s = expectation["text"]?.Value(); - if(!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out c)) - { - c = StringComparison.OrdinalIgnoreCase; - } - - if(p.Output.IndexOf(s, c) < 0) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to contain \"{s}\" ({c}), but it did not", name: name); - } - - break; - case "OUTPUT_DOES_NOT_CONTAIN": - s = expectation["text"]?.Value(); - if (!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out c)) - { - c = StringComparison.OrdinalIgnoreCase; - } - - if (p.Output.IndexOf(s, c) > -1) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to NOT contain \"{s}\" ({c}), but it did", name: name); - } - - break; - default: - return new ExecuteHandlerResult(watch.Elapsed, false, $"Unkown assertion: {assertion}", name: name); - } - } - } - - return new ExecuteHandlerResult(watch.Elapsed, true, null, name: name); - } - } - finally - { - watch.Stop(); - } - } - - public string Summarize(IReadOnlyDictionary tokens, JObject json) - { - string args = json["args"]?.ToString() ?? string.Empty; - - foreach (KeyValuePair entry in tokens) - { - args = args.Replace($"%{entry.Key}%", entry.Value); - } - - string command = json["command"].ToString(); - - foreach (KeyValuePair entry in tokens) - { - command = command.Replace($"%{entry.Key}%", entry.Value); - } - - return $"Execute {command} {args}"; - } - } -} diff --git a/tools/ProjectTestRunner/Handlers/FileInspectHandler.cs b/tools/ProjectTestRunner/Handlers/FileInspectHandler.cs deleted file mode 100644 index b26dd6ef0c..0000000000 --- a/tools/ProjectTestRunner/Handlers/FileInspectHandler.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; - -namespace ProjectTestRunner.Handlers -{ - // file: rel path to file - // Note: For filenames that get modified by the template creation name, use the literal "%targetPathName%". - // It gets replaced with the creation name. - // Example: "filename": "%targetPathName%.csproj" - // expectations: - // assertion: exists | does_not_exist | contains | does_not_contain - // text: text to check for when using (file_contains | file_does_not_contain) - // comparison: a StringComparison enum value - - // Example: - // { - // "handler": "fileInspect", - // "file": "filename" - // "expectations": [ - // { - // "assertion": "exists" - // }, - // { - // "assertion": "contains", - // "text": "netcoreapp1.0", - // "comparison": "Ordinal", - // }, - // { - // "assertion": "does_not_contain", - // "text": "TargetFrameworkOverride", - // } - - public class FileInspectHandler : IHandler - { - public static string Handler => "fileInspect"; - - public string HandlerName => Handler; - - public IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json) - { - Stopwatch watch = Stopwatch.StartNew(); - try - { - string basePath = tokens["targetPath"]; - string outputName = tokens["targetPathName"]; - - string name = json["name"]?.ToString(); - string filename = json["file"].ToString(); - - foreach (KeyValuePair entry in tokens) - { - filename = filename.Replace($"%{entry.Key}%", entry.Value); - } - - string pathToFile = Path.Combine(basePath, filename); - bool doesFileExist = File.Exists(pathToFile); - - string fileContent = null; - - JArray expectations = json["expectations"]?.Value(); - - if (expectations != null) - { - foreach (JObject expectation in expectations.Children().OfType()) - { - string assertion = expectation["assertion"]?.Value()?.ToUpperInvariant(); - string text; - StringComparison comparison; - - switch (assertion) - { - case "EXISTS": - if (!doesFileExist) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to exist, but it did not", name: name); - } - break; - case "DOES_NOT_EXIST": - if (doesFileExist) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to not exist, but it did", name: name); - } - break; - case "CONTAINS": - text = expectation["text"]?.Value(); - if (!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out comparison)) - { - comparison = StringComparison.OrdinalIgnoreCase; - } - - if (!doesFileExist) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to contain \"{text}\" ({comparison}), but file did not exist", name: name); - } - - if (fileContent == null) - { - fileContent = File.ReadAllText(pathToFile); - } - - if (fileContent.IndexOf(text, comparison) < 0) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to contain \"{text}\" ({comparison}), but it did not", name: name); - } - - break; - case "DOES_NOT_CONTAIN": - text = expectation["text"].Value(); - if (!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out comparison)) - { - comparison = StringComparison.OrdinalIgnoreCase; - } - - if (!doesFileExist) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to not contain \"{text}\" ({comparison}), but file did not exist", name: name); - } - - if (fileContent == null) - { - fileContent = File.ReadAllText(pathToFile); - } - - if (fileContent.IndexOf(text, comparison) >= 0) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to not contain \"{text}\" ({comparison}), but it did", name: name); - } - - break; - } - - } - } - - return new GenericHandlerResult(watch.Elapsed, true, null); - } - catch (Exception ex) - { - return new GenericHandlerResult(watch.Elapsed, false, ex.Message); - } - } - - public string Summarize(IReadOnlyDictionary tokens, JObject json) - { - string filename = json["file"].ToString(); - - return $"File Inspection - inspecting file = \"{filename}\""; - } - } -} diff --git a/tools/ProjectTestRunner/Handlers/FindProcessHandler.cs b/tools/ProjectTestRunner/Handlers/FindProcessHandler.cs deleted file mode 100644 index 1197b28388..0000000000 --- a/tools/ProjectTestRunner/Handlers/FindProcessHandler.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; - -namespace ProjectTestRunner.Handlers -{ - public class FindProcessHandler : IHandler - { - public static string Handler => "find"; - - public string HandlerName => Handler; - - public IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json) - { - Stopwatch watch = Stopwatch.StartNew(); - - try - { - string[] args = json["args"].Values().ToArray(); - - for (int i = 0; i < args.Length; ++i) - { - if (tokens.TryGetValue(args[i].Trim('%'), out string val)) - { - args[i] = val; - } - } - - string name = json["name"].ToString(); - Process p = Process.GetProcesses().FirstOrDefault(x => - { - ProcessStartInfo info = null; - - try - { - info = x.StartInfo; - } - catch - { - return false; - } - - return args.All(y => info.Arguments.Contains(y)); - }); - return new ExecuteHandlerResult(watch.Elapsed, p != null, p != null ? null : "Unable to find process", p, name); - } - finally - { - watch.Stop(); - } - } - - public string Summarize(IReadOnlyDictionary tokens, JObject json) - { - string[] args = json["args"].Values().ToArray(); - - for (int i = 0; i < args.Length; ++i) - { - if (tokens.TryGetValue(args[i].Trim('%'), out string val)) - { - args[i] = val; - } - } - - return $"Find process with args [{string.Join(", ", args)}]"; - } - } -} diff --git a/tools/ProjectTestRunner/Handlers/HttpRequestHandler.cs b/tools/ProjectTestRunner/Handlers/HttpRequestHandler.cs deleted file mode 100644 index c038112ca6..0000000000 --- a/tools/ProjectTestRunner/Handlers/HttpRequestHandler.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Net.Http; -using System.Text; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; - -namespace ProjectTestRunner.Handlers -{ - public class HttpRequestHandler : IHandler - { - public static string Handler => "httpRequest"; - - public string HandlerName => Handler; - - public IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json) - { - Stopwatch watch = Stopwatch.StartNew(); - - try - { - string name = json["name"]?.ToString(); - string url = json["url"].ToString(); - int status = json["statusCode"].Value(); - string verb = json["verb"].ToString(); - string body = json["body"]?.ToString(); - string requestMediaType = json["requestMediaType"]?.ToString(); - string requestEncoding = json["requestEncoding"]?.ToString(); - - HttpClient client = new HttpClient(); - HttpRequestMessage message = new HttpRequestMessage(new HttpMethod(verb), url); - - if (body != null) - { - if (!string.IsNullOrEmpty(requestEncoding)) - { - if (!string.IsNullOrEmpty(requestMediaType)) - { - message.Content = new StringContent(body, Encoding.GetEncoding(requestEncoding), requestMediaType); - } - else - { - message.Content = new StringContent(body, Encoding.GetEncoding(requestEncoding)); - } - } - else - { - message.Content = new StringContent(body); - } - } - - try - { - HttpResponseMessage response = client.SendAsync(message).Result; - bool success = status == (int)response.StatusCode; - string responseText = response.Content.ReadAsStringAsync().Result; - - JArray expectations = json["expectations"]?.Value(); - - if(expectations != null) - { - foreach(JObject expectation in expectations.Children().OfType()) - { - string assertion = expectation["assertion"]?.Value()?.ToUpperInvariant(); - string s, key; - StringComparison c; - IEnumerable values; - - switch (assertion) - { - case "RESPONSE_CONTAINS": - s = expectation["text"]?.Value(); - if(!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out c)) - { - c = StringComparison.OrdinalIgnoreCase; - } - - if(responseText.IndexOf(s, c) < 0) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to contain \"{s}\" ({c}), but it did not", name: name); - } - - break; - case "RESPONSE_DOES_NOT_CONTAIN": - s = expectation["text"]?.Value(); - if(!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out c)) - { - c = StringComparison.OrdinalIgnoreCase; - } - - if(responseText.IndexOf(s, c) > -1) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to NOT contain \"{s}\" ({c}), but it did", name: name); - } - - break; - case "RESPONSE_HEADER_CONTAINS": - key = expectation["key"]?.Value(); - s = expectation["text"]?.Value(); - if(!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out c)) - { - c = StringComparison.OrdinalIgnoreCase; - } - - if(!response.Headers.TryGetValues(key, out values)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to be present, but it was not", name: name); - } - - if(!values.Any(x => x.IndexOf(s, c) > -1)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to have a value \"{s}\", but it did not", name: name); - } - - break; - case "HAS_HEADER": - key = expectation["key"]?.Value(); - - if(!response.Headers.TryGetValues(key, out values)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to be present, but it was not", name: name); - } - - break; - - case "RESPONSE_HEADER_DOES_NOT_CONTAIN": - key = expectation["key"]?.Value(); - s = expectation["text"]?.Value(); - if(!Enum.TryParse(expectation["comparison"]?.Value() ?? "OrdinalIgnoreCase", out c)) - { - c = StringComparison.OrdinalIgnoreCase; - } - - if(!response.Headers.TryGetValues(key, out values)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to be present, but it was not", name: name); - } - - if(values.Any(x => x.IndexOf(s, c) > -1)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to NOT have a value \"{s}\", but it did", name: name); - } - - break; - case "DOES_NOT_HAVE_HEADER": - key = expectation["key"]?.Value(); - - if(response.Headers.TryGetValues(key, out values)) - { - return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to NOT be present, but it was", name: name); - } - - break; - } - } - } - - return new GenericHandlerResult(watch.Elapsed, success, success ? null : $"Expected {status} but got {response.StatusCode}"); - } - catch (Exception ex) - { - return new GenericHandlerResult(watch.Elapsed, false, ex.Message); - } - } - finally - { - watch.Stop(); - } - } - - public string Summarize(IReadOnlyDictionary tokens, JObject json) - { - string url = json["url"].ToString(); - int status = json["statusCode"].Value(); - string verb = json["verb"].ToString(); - string body = json["body"]?.ToString(); - string requestMediaType = json["requestMediaType"]?.ToString(); - string requestEncoding = json["requestEncoding"]?.ToString(); - - return $"Web Request - {verb} {url} (Body? {body != null}, Encoding? {requestEncoding}, MediaType? {requestMediaType}) -> Expect {status}"; - } - } -} diff --git a/tools/ProjectTestRunner/Handlers/IHandler.cs b/tools/ProjectTestRunner/Handlers/IHandler.cs deleted file mode 100644 index 3e0fc358ad..0000000000 --- a/tools/ProjectTestRunner/Handlers/IHandler.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; - -namespace ProjectTestRunner.Handlers -{ - public interface IHandler - { - string HandlerName { get; } - - IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json); - - string Summarize(IReadOnlyDictionary tokens, JObject json); - } -} diff --git a/tools/ProjectTestRunner/Handlers/TaskKillHandler.cs b/tools/ProjectTestRunner/Handlers/TaskKillHandler.cs deleted file mode 100644 index 89337bb4a6..0000000000 --- a/tools/ProjectTestRunner/Handlers/TaskKillHandler.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Newtonsoft.Json.Linq; -using ProjectTestRunner.HandlerResults; - -namespace ProjectTestRunner.Handlers -{ - public class TaskKillHandler : IHandler - { - public static string Handler => "taskkill"; - - public string HandlerName => Handler; - - public IHandlerResult Execute(IReadOnlyDictionary tokens, IReadOnlyList results, JObject json) - { - Stopwatch watch = Stopwatch.StartNew(); - - try - { - string targetName = json["name"].ToString(); - IHandlerResult result = results.FirstOrDefault(x => x.Name == targetName); - if (result is ExecuteHandlerResult xr) - { - xr.Kill(); - } - - return new GenericHandlerResult(watch.Elapsed, true, null); - } - finally - { - watch.Stop(); - } - } - - public string Summarize(IReadOnlyDictionary tokens, JObject json) - { - return "Kill process in named step " + json["name"].ToString(); - } - } -} diff --git a/tools/ProjectTestRunner/Helpers/OutputHelperHelper.cs b/tools/ProjectTestRunner/Helpers/OutputHelperHelper.cs deleted file mode 100644 index eada949ffe..0000000000 --- a/tools/ProjectTestRunner/Helpers/OutputHelperHelper.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.IO; -using System.Text; -using Xunit.Abstractions; - -namespace ProjectTestRunner.Helpers -{ - internal class OutputHelperHelper : TextWriter - { - private ITestOutputHelper _outputHelper; - - public OutputHelperHelper(ITestOutputHelper outputHelper) - { - _outputHelper = outputHelper; - } - - public override Encoding Encoding => Encoding.UTF8; - - public override void Write(char value) - { - } - - public override void WriteLine(string format, params object[] arg) - { - _outputHelper.WriteLine(format, arg); - } - - public override void WriteLine(string message) - { - _outputHelper.WriteLine(message ?? ""); - } - } -} \ No newline at end of file diff --git a/tools/ProjectTestRunner/Helpers/PrettyTheoryAttribute.cs b/tools/ProjectTestRunner/Helpers/PrettyTheoryAttribute.cs deleted file mode 100644 index a519bc00fb..0000000000 --- a/tools/ProjectTestRunner/Helpers/PrettyTheoryAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Runtime.CompilerServices; -using Xunit; - -namespace ProjectTestRunner.Helpers -{ - public class PrettyTheoryAttribute : TheoryAttribute - { - public PrettyTheoryAttribute([CallerMemberName] string memberName = null) - { - DisplayName = memberName; - } - } -} diff --git a/tools/ProjectTestRunner/Helpers/Proc.cs b/tools/ProjectTestRunner/Helpers/Proc.cs deleted file mode 100644 index 2a3351b900..0000000000 --- a/tools/ProjectTestRunner/Helpers/Proc.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Diagnostics; - -namespace ProjectTestRunner.Helpers -{ - public class Proc - { - public static ProcessEx Run(string command, string args) - { - ProcessStartInfo psi = new ProcessStartInfo(command, args) - { - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - CreateNoWindow = true - }; - Process p = Process.Start(psi); - ProcessEx wrapper = new ProcessEx(p); - return wrapper; - } - } -} diff --git a/tools/ProjectTestRunner/Helpers/ProcessEx.cs b/tools/ProjectTestRunner/Helpers/ProcessEx.cs deleted file mode 100644 index d662d3a453..0000000000 --- a/tools/ProjectTestRunner/Helpers/ProcessEx.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Diagnostics; -using System.Text; - -namespace ProjectTestRunner.Helpers -{ - public class ProcessEx - { - private readonly Process _process; - private readonly StringBuilder _stderr; - private readonly StringBuilder _stdout; - - public ProcessEx(Process p) - { - _stdout = new StringBuilder(); - _stderr = new StringBuilder(); - - _process = p; - p.OutputDataReceived += OnOutputData; - p.ErrorDataReceived += OnErrorData; - p.BeginOutputReadLine(); - p.BeginErrorReadLine(); - } - - public string Error => _stderr.ToString(); - - public string Output => _stdout.ToString(); - - public int ExitCode => _process.ExitCode; - - public static implicit operator Process(ProcessEx self) - { - return self._process; - } - - private void OnErrorData(object sender, DataReceivedEventArgs e) - { - _stderr.AppendLine(e.Data); - try - { - Console.Error.WriteLine(e.Data); - } - catch - { - } - } - - private void OnOutputData(object sender, DataReceivedEventArgs e) - { - _stdout.AppendLine(e.Data); - - try - { - Console.WriteLine(e.Data); - } - catch - { - } - } - - public bool WaitForExit(int milliseconds) - { - return _process.WaitForExit(milliseconds); - } - - public void WaitForExit() - { - _process.WaitForExit(); - } - } -} diff --git a/tools/ProjectTestRunner/NuGet.config b/tools/ProjectTestRunner/NuGet.config deleted file mode 100644 index 7be9c71eca..0000000000 --- a/tools/ProjectTestRunner/NuGet.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/tools/ProjectTestRunner/ProjectTestRunner.csproj b/tools/ProjectTestRunner/ProjectTestRunner.csproj deleted file mode 100644 index a426f306bb..0000000000 --- a/tools/ProjectTestRunner/ProjectTestRunner.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Exe - netcoreapp2.0 - $(TestFolder) - $(IntermediateFolder)\Test - - - - - - - - - - - - Always - - - - - - - - diff --git a/tools/ProjectTestRunner/TemplateTestData.cs b/tools/ProjectTestRunner/TemplateTestData.cs deleted file mode 100644 index 9b41b1c39e..0000000000 --- a/tools/ProjectTestRunner/TemplateTestData.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Xunit.Abstractions; - -namespace ProjectTestRunner -{ - public class TemplateTestData : IXunitSerializable - { - public TemplateTestData() - { - } - - public string Name { get; set; } - public string Variation { get; set; } - public string CreateCommand { get; set; } - public string[] Paths { get; set; } - - public void Deserialize(IXunitSerializationInfo info) - { - Name = info.GetValue(nameof(Name)); - Variation = info.GetValue(nameof(Variation)); - CreateCommand = info.GetValue(nameof(CreateCommand)); - Paths = info.GetValue(nameof(Paths)); - } - - public void Serialize(IXunitSerializationInfo info) - { - info.AddValue(nameof(Name), Name, typeof(string)); - info.AddValue(nameof(Variation), Variation, typeof(string)); - info.AddValue(nameof(CreateCommand), CreateCommand, typeof(string)); - info.AddValue(nameof(Paths), Paths, typeof(string[])); - } - - public override string ToString() - { - return Name; - } - } - -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/Mvc.json b/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/Mvc.json deleted file mode 100644 index 8f7722aadc..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/Mvc.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "create": "mvc --no-restore", - "name": "MVC (C#, default framework, default auth)", - "variations": [ - { - "id": "fullFramework", - "name": "MVC (C#, net461 framework, default auth)", - "create": "mvc --target-framework-override net461 --no-restore " - } - ], - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "directoryInspect", - "directory": "Areas", - "assertion": "does_not_exist" - }, - { - "handler": "directoryInspect", - "directory": "Extensions", - "assertion": "does_not_exist" - }, - { - "handler": "fileInspect", - "file": "urlRewrite.config", - "expectations": [ - { - "assertion": "does_not_exist" - } - ], - }, - { - "handler": "fileInspect", - "file": "Controllers/AccountController.cs", - "expectations": [ - { - "assertion": "does_not_exist" - } - ] - }, - { - "handler": "fileInspect", - "file": "%targetPathName%.csproj", - "expectations": [ - { - "assertion": "exists" - }, - { - "assertion": "does_not_contain", - "text": ".db" - }, - { - "assertion": "does_not_contain", - "text": "Microsoft.EntityFrameworkCore.Tools" - }, - { - "assertion": "does_not_contain", - "text": "Microsoft.VisualStudio.Web.CodeGeneration.Design" - }, - { - "assertion": "does_not_contain", - "text": "Microsoft.EntityFrameworkCore.Tools.DotNet" - }, - { - "assertion": "does_not_contain", - "text": "Microsoft.Extensions.SecretManager.Tools" - }, - ] - }, - { - "name": "RunApp", - "variation": "", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "name": "RunApp", - "variation": "fullFramework", - "handler": "execute", - "command": "bin/Debug/net461/%targetPathName%.exe", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Home/About", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Home/Contact", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/MvcIndividual.json b/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/MvcIndividual.json deleted file mode 100644 index 1a356d06d6..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/MvcIndividual.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "create": "mvc -au Individual --KestrelPort 5000 --no-restore", - "name": "MVC (C#, default framework, local individual auth)", - "variations": [ - { - "id": "fullFramework", - "name": "MVC (C#, net461 framework, local individual auth)", - "create": "mvc -au Individual --KestrelPort 5000 --target-framework-override net461 --no-restore" - } - ], - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "directoryInspect", - "directory": "Extensions", - "assertion": "exists" - }, - { - "handler": "fileInspect", - "file": "Controllers/AccountController.cs", - "expectations": [ - { - "assertion": "exists" - } - ] - }, - { - "handler": "fileInspect", - "file": "%targetPathName%.csproj", - "expectations": [ - { - "assertion": "exists" - }, - { - "assertion": "contains", - "text": ".db" - }, - { - "assertion": "contains", - "text": "Microsoft.EntityFrameworkCore.Tools" - }, - { - "assertion": "contains", - "text": "Microsoft.VisualStudio.Web.CodeGeneration.Design" - }, - { - "assertion": "contains", - "text": "Microsoft.EntityFrameworkCore.Tools.DotNet" - }, - { - "assertion": "contains", - "text": "Microsoft.Extensions.SecretManager.Tools" - }, - ] - }, - { - "name": "RunApp", - "variation": "", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "name": "RunApp", - "variation": "fullFramework", - "handler": "execute", - "command": "bin/Debug/net461/%targetPathName%.exe", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Home/About", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Home/Contact", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/RazorPages.json b/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/RazorPages.json deleted file mode 100644 index 72699c967e..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/RazorPages.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "create": "razor --no-restore", - "name": "Razor Pages (C#, default framework, default auth)", - "variations": [ - { - "id": "fullFramework", - "name": "Razor Pages (C#, net461 framework, default auth)", - "create": "razor --target-framework-override net461 --no-restore " - } - ], - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "name": "RunApp", - "variation": "", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "name": "RunApp", - "variation": "fullFramework", - "handler": "execute", - "command": "bin/Debug/net461/%targetPathName%.exe", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/About", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Contact", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/RazorPagesIndividual.json b/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/RazorPagesIndividual.json deleted file mode 100644 index 2efd3178fa..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/RazorPagesIndividual.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "create": "razor -au Individual --KestrelPort 5000 --no-restore", - "name": "Razor Pages (C#, default framework, local individual auth)", - "variations": [ - { - "id": "fullFramework", - "name": "Razor Pages (C#, net461 framework, local individual auth)", - "create": "razor -au Individual --KestrelPort 5000 --target-framework-override net461 --no-restore" - } - ], - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "directoryInspect", - "directory": "Extensions", - "assertion": "exists" - }, - { - "handler": "fileInspect", - "file": "Controllers/AccountController.cs", - "expectations": [ - { - "assertion": "exists" - } - ] - }, - { - "handler": "fileInspect", - "file": "%targetPathName%.csproj", - "expectations": [ - { - "assertion": "exists" - }, - { - "assertion": "contains", - "text": ".db" - }, - { - "assertion": "contains", - "text": "Microsoft.EntityFrameworkCore.Tools" - }, - { - "assertion": "contains", - "text": "Microsoft.VisualStudio.Web.CodeGeneration.Design" - }, - { - "assertion": "contains", - "text": "Microsoft.EntityFrameworkCore.Tools.DotNet" - }, - { - "assertion": "contains", - "text": "Microsoft.Extensions.SecretManager.Tools" - }, - ] - }, - { - "name": "RunApp", - "variation": "", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "name": "RunApp", - "variation": "fullFramework", - "handler": "execute", - "command": "bin/Debug/net461/%targetPathName%.exe", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/About", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Contact", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/Web.json b/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/Web.json deleted file mode 100644 index da23bd4737..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/Web.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "create": "web --no-restore", - "name": "Empty Web (C#, default framework, default auth)", - "variations": [ - { - "id": "fullFramework", - "name": "Empty Web (C#, net461 framework, default auth)", - "create": "web --target-framework-override net461 --no-restore " - } - ], - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "name": "RunApp", - "variation": "", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "name": "RunApp", - "variation": "fullFramework", - "handler": "execute", - "command": "bin/Debug/net461/%targetPathName%.exe", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/WebApi.json b/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/WebApi.json deleted file mode 100644 index 5abdcd294d..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/CSharp/Defaults/Web/WebApi.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "create": "api --no-restore", - "name": "WebAPI (C#, default framework, default auth)", - "variations": [ - { - "id": "fullFramework", - "name": "WebAPI (C#, net461 framework, default auth)", - "create": "api --target-framework-override net461 --no-restore" - } - ], - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "name": "RunApp", - "variation": "", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "name": "RunApp", - "variation": "fullFramework", - "handler": "execute", - "command": "bin/Debug/net461/%targetPathName%.exe", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/api/values", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 404, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -} diff --git a/tools/ProjectTestRunner/TestCases/BuiltIn/FSharp/Defaults/Web/Mvc.json b/tools/ProjectTestRunner/TestCases/BuiltIn/FSharp/Defaults/Web/Mvc.json deleted file mode 100644 index 3684d108fa..0000000000 --- a/tools/ProjectTestRunner/TestCases/BuiltIn/FSharp/Defaults/Web/Mvc.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "create": "mvc --language F# --no-restore", - "name": "MVC (F#, default framework, default auth)", - "tasks": [ - { - "handler": "execute", - "command": "dotnet", - "args": "restore -s https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json", - "noExit": false, - "exitCode": 0 - }, - { - "handler": "execute", - "command": "dotnet", - "args": "build -c Debug", - "noExit": false, - "exitCode": 0 - }, - { - "name": "RunApp", - "handler": "execute", - "command": "dotnet", - "args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll", - "noExit": true, - "exitTimeout": 5000 - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Home/About", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "httpRequest", - "url": "http://localhost:5000/Home/Contact", - "statusCode": 200, - "verb": "GET" - }, - { - "handler": "taskkill", - "name": "RunApp" - } - ] -}