using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using NUnit.Framework;
namespace OpenTap.Package.UnitTests
{
[TestFixture]
public class PackageTestTest
{
#region Utils
(string Timestamp, string Source, string Type, string Message)? Parse(string line)
{
var logParts = line.Split(new string[] {" : "}, StringSplitOptions.None);
if (logParts.Length == 4)
return (logParts[0].Trim(), logParts[1].Trim(), logParts[2].Trim(), logParts[3].Trim());
return null;
}
(string Timestamp, string Source, string Type, string Message)[] ParseStdout(string stdout)
{
return stdout.Split('\n')
.Select(Parse)
.Where(v => v.HasValue)
.Select(v => v.Value).ToArray();
}
private (string Stdout, string Stderr, int ExitCode) RunTest(bool verbose)
{
string arguments = "package test MyPlugin5";
if (verbose)
arguments += " -v";
var process = new Process
{
StartInfo =
{
FileName = "tap",
Arguments = arguments,
WorkingDirectory = WorkingDirectory,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
process.Start();
// For some reason, the process is kept open when running in verbose.. ?
if (verbose)
process.WaitForExit(5000);
else
{
process.WaitForExit();
}
return (process.StandardOutput.ReadToEnd(), process.StandardError.ReadToEnd(), process.ExitCode);
}
private void InstallTestPackage()
{
var process = new Process
{
StartInfo =
{
FileName = "tap",
Arguments = $"package install -f ./TapPackages/MyPlugin5.TapPackage",
WorkingDirectory = WorkingDirectory,
UseShellExecute = false,
RedirectStandardOutput = false,
RedirectStandardError = false,
CreateNoWindow = true
}
};
process.Start();
process.WaitForExit();
}
private void Backup()
{
var original = PackageXml;
var backup = Path.Combine(PackageDir, "backup.xml");
if (File.Exists(backup) == false)
File.Copy(original, backup);
}
private string PackageDir => Path.Combine(WorkingDirectory, "Packages", "MyPlugin5");
private string PackageXml => Path.Combine(PackageDir, "package.xml");
private void AddTestElement(string testAction)
{
var xmlContent = $@"
{testAction}
";
string content = "";
using (var reader = new StreamReader(PackageXml))
content = reader.ReadToEnd();
var lines = content.Split('\n').ToList();
var idx = lines.FindIndex(l => l.Contains(""));
lines.Insert(idx, xmlContent);
using (var writer = new StreamWriter(PackageXml))
writer.Write(string.Join("\n", lines));
}
private void Restore()
{
var original = PackageXml;
var backup = Path.Combine(PackageDir, "backup.xml");
if (File.Exists(original))
File.Delete(original);
File.Copy(backup, original);
}
private string WorkingDirectory => Directory.GetCurrentDirectory();
#endregion
public PackageTestTest()
{
InstallTestPackage();
Backup();
Restore();
}
[Test]
public void BasicTest()
{
Restore();
var (stdout, stderr, exitCode) = RunTest(true);
StringAssert.Contains("Tried to test MyPlugin5, but there was nothing to do.", stdout);
Assert.AreEqual(exitCode, 0);
}
[Ignore("Echo not available on Windows runner")]
[Test]
public void EchoTest()
{
Restore();
var testAction = @"";
AddTestElement(testAction);
var normalOutput = RunTest(false);
StringAssert.Contains("Starting test step 'echo hello'", normalOutput.Stdout);
// The echoed "hello" should only appear in debug output
CollectionAssert.DoesNotContain(normalOutput.Stdout.Split('\n'), "hello");
StringAssert.Contains("Successfully ran test step 'echo hello'", normalOutput.Stdout);
Assert.AreEqual(0, normalOutput.ExitCode);
var verboseOutput = RunTest(true);
var verboseLines = ParseStdout(verboseOutput.Stdout);
CollectionAssert.Contains(verboseLines.Select(v => v.Message), "hello");
Assert.AreEqual(0, verboseOutput.ExitCode);
}
[Test]
public void LogInheritTest()
{
Restore();
var testAction = @"";
AddTestElement(testAction);
var actualGitversion = new GitVersionCalulator(WorkingDirectory).GetVersion().ToString();
{ // Normal output tests
var normalOutput = RunTest(false);
StringAssert.Contains("Starting test step 'tap sdk gitversion'", normalOutput.Stdout);
StringAssert.Contains("Successfully tested MyPlugin5 version 1.0.0.", normalOutput.Stdout);
StringAssert.Contains("Successfully ran test step 'tap sdk gitversion'", normalOutput.Stdout);
StringAssert.Contains(actualGitversion, normalOutput.Stdout);
Assert.AreEqual(0, normalOutput.ExitCode);
}
{ // Verbose output tests
var verboseOutput = RunTest(true);
StringAssert.Contains("Successfully tested MyPlugin5 version 1.0.0.", verboseOutput.Stdout);
var verboseLines = ParseStdout(verboseOutput.Stdout);
var gitversionInfos = verboseLines.Where(l => l.Source == "GitVersion" && l.Type == "Information");
var gitversionMessages = gitversionInfos.Select(i => i.Message).ToArray();
Assert.Contains(actualGitversion, gitversionMessages);
Assert.AreEqual(0, verboseOutput.ExitCode);
}
}
[Test]
public void FailingTest()
{
var exeName = "SomeExeFileWhichDoesNotExist";
Restore();
var testAction = $@"";
AddTestElement(testAction);
var normalOutput = RunTest(false);
StringAssert.Contains($"Starting test step '{exeName} hello'", normalOutput.Stdout);
StringAssert.DoesNotContain("Successfully ran test step", normalOutput.Stdout);
Assert.AreNotEqual(0, normalOutput.ExitCode);
StringAssert.Contains("Failed to run test package action", normalOutput.Stderr);
}
}
}