Restores continuous test runner.
This commit is contained in:
parent
b5e0c9bfe0
commit
dbf0ed714c
|
@ -38,9 +38,10 @@ namespace Core
|
|||
return new CoreInterface(this);
|
||||
}
|
||||
|
||||
public void Decommission()
|
||||
public void Decommission(bool deleteKubernetesResources, bool deleteTrackedFiles)
|
||||
{
|
||||
manager.DecommissionPlugins();
|
||||
manager.DecommissionPlugins(deleteKubernetesResources, deleteTrackedFiles);
|
||||
Tools.Decommission(deleteKubernetesResources, deleteTrackedFiles);
|
||||
}
|
||||
|
||||
internal T GetPlugin<T>() where T : IProjectPlugin
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
{
|
||||
internal class PluginManager
|
||||
{
|
||||
private readonly List<IProjectPlugin> projectPlugins = new List<IProjectPlugin>();
|
||||
private readonly List<PluginToolsPair> pairs = new List<PluginToolsPair>();
|
||||
|
||||
internal void InstantiatePlugins(Type[] pluginTypes, IToolsFactory provider)
|
||||
{
|
||||
projectPlugins.Clear();
|
||||
pairs.Clear();
|
||||
foreach (var pluginType in pluginTypes)
|
||||
{
|
||||
var tools = provider.CreateTools();
|
||||
|
@ -18,15 +18,15 @@
|
|||
|
||||
internal void AnnouncePlugins()
|
||||
{
|
||||
foreach (var plugin in projectPlugins) plugin.Announce();
|
||||
foreach (var pair in pairs) pair.Plugin.Announce();
|
||||
}
|
||||
|
||||
internal PluginMetadata GatherPluginMetadata()
|
||||
{
|
||||
var metadata = new PluginMetadata();
|
||||
foreach (var plugin in projectPlugins)
|
||||
foreach (var pair in pairs)
|
||||
{
|
||||
if (plugin is IHasMetadata m)
|
||||
if (pair.Plugin is IHasMetadata m)
|
||||
{
|
||||
m.AddMetadata(metadata);
|
||||
}
|
||||
|
@ -34,20 +34,24 @@
|
|||
return metadata;
|
||||
}
|
||||
|
||||
internal void DecommissionPlugins()
|
||||
internal void DecommissionPlugins(bool deleteKubernetesResources, bool deleteTrackedFiles)
|
||||
{
|
||||
foreach (var plugin in projectPlugins) plugin.Decommission();
|
||||
foreach (var pair in pairs)
|
||||
{
|
||||
pair.Plugin.Decommission();
|
||||
pair.Tools.Decommission(deleteKubernetesResources, deleteTrackedFiles);
|
||||
}
|
||||
}
|
||||
|
||||
internal T GetPlugin<T>() where T : IProjectPlugin
|
||||
{
|
||||
return (T)projectPlugins.Single(p => p.GetType() == typeof(T));
|
||||
return (T)pairs.Single(p => p.Plugin.GetType() == typeof(T)).Plugin;
|
||||
}
|
||||
|
||||
private IProjectPlugin InstantiatePlugins(Type pluginType, PluginTools tools)
|
||||
{
|
||||
var plugin = (IProjectPlugin)Activator.CreateInstance(pluginType, args: tools)!;
|
||||
projectPlugins.Add(plugin);
|
||||
pairs.Add(new PluginToolsPair(plugin, tools));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
@ -58,5 +62,17 @@
|
|||
tools.ApplyLogPrefix(hasLogPrefix.LogPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
private class PluginToolsPair
|
||||
{
|
||||
public PluginToolsPair(IProjectPlugin plugin, IPluginTools tools)
|
||||
{
|
||||
Plugin = plugin;
|
||||
Tools = tools;
|
||||
}
|
||||
|
||||
public IProjectPlugin Plugin { get; }
|
||||
public IPluginTools Tools { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Core
|
|||
{
|
||||
public interface IPluginTools : IWorkflowTool, ILogTool, IHttpFactoryTool, IFileTool
|
||||
{
|
||||
void Decommission(bool deleteKubernetesResources, bool deleteTrackedFiles);
|
||||
}
|
||||
|
||||
public interface IWorkflowTool
|
||||
|
@ -65,6 +66,12 @@ namespace Core
|
|||
return workflowCreator.CreateWorkflow(namespaceOverride);
|
||||
}
|
||||
|
||||
public void Decommission(bool deleteKubernetesResources, bool deleteTrackedFiles)
|
||||
{
|
||||
if (deleteKubernetesResources) CreateWorkflow().DeleteNamespace();
|
||||
if (deleteTrackedFiles) fileManager.DeleteAllFiles();
|
||||
}
|
||||
|
||||
public IFileManager GetFileManager()
|
||||
{
|
||||
return fileManager;
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace FileUtils
|
|||
private static NumberSource folderNumberSource = new NumberSource(0);
|
||||
private readonly Random random = new Random();
|
||||
private readonly ILog log;
|
||||
private readonly string rootFolder;
|
||||
private readonly string folder;
|
||||
private readonly List<List<TrackedFile>> fileSetStack = new List<List<TrackedFile>>();
|
||||
|
||||
|
@ -25,13 +26,15 @@ namespace FileUtils
|
|||
{
|
||||
folder = Path.Combine(rootFolder, folderNumberSource.GetNextNumber().ToString("D5"));
|
||||
|
||||
EnsureDirectory();
|
||||
this.log = log;
|
||||
this.rootFolder = rootFolder;
|
||||
}
|
||||
|
||||
public TrackedFile CreateEmptyFile(string label = "")
|
||||
{
|
||||
var path = Path.Combine(folder, Guid.NewGuid().ToString() + "_test.bin");
|
||||
var path = Path.Combine(folder, Guid.NewGuid().ToString() + ".bin");
|
||||
EnsureDirectory();
|
||||
|
||||
var result = new TrackedFile(log, path, label);
|
||||
File.Create(result.Filename).Close();
|
||||
if (fileSetStack.Any()) fileSetStack.Last().Add(result);
|
||||
|
@ -79,12 +82,11 @@ namespace FileUtils
|
|||
|
||||
foreach (var file in pop)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file.Filename);
|
||||
}
|
||||
catch { }
|
||||
File.Delete(file.Filename);
|
||||
}
|
||||
|
||||
// If the folder is now empty, delete it too.
|
||||
if (!Directory.GetFiles(folder).Any()) DeleteDirectory();
|
||||
}
|
||||
|
||||
private TrackedFile GenerateRandomFile(ByteSize size, string label)
|
||||
|
@ -144,12 +146,12 @@ namespace FileUtils
|
|||
|
||||
private void EnsureDirectory()
|
||||
{
|
||||
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
|
||||
private void DeleteDirectory()
|
||||
{
|
||||
Directory.Delete(folder, true);
|
||||
if (Directory.Exists(folder)) Directory.Delete(folder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
namespace Logging
|
||||
{
|
||||
public class ConsoleLog : BaseLog
|
||||
{
|
||||
public ConsoleLog() : base(false)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string GetFullName()
|
||||
{
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
public override void Log(string message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
namespace Logging
|
||||
{
|
||||
public class LogSplitter : ILog
|
||||
{
|
||||
private readonly ILog[] targetLogs;
|
||||
|
||||
public LogSplitter(params ILog[] targetLogs)
|
||||
{
|
||||
this.targetLogs = targetLogs;
|
||||
}
|
||||
|
||||
public void AddStringReplace(string from, string to)
|
||||
{
|
||||
OnAll(l => l.AddStringReplace(from, to));
|
||||
}
|
||||
|
||||
public LogFile CreateSubfile(string ext = "log")
|
||||
{
|
||||
return targetLogs.First().CreateSubfile(ext);
|
||||
}
|
||||
|
||||
public void Debug(string message = "", int skipFrames = 0)
|
||||
{
|
||||
OnAll(l => l.Debug(message, skipFrames + 2));
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
OnAll(l => l.Error(message));
|
||||
}
|
||||
|
||||
public void Log(string message)
|
||||
{
|
||||
OnAll(l => l.Log(message));
|
||||
}
|
||||
|
||||
private void OnAll(Action<ILog> action)
|
||||
{
|
||||
foreach (var t in targetLogs) action(t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -59,7 +59,6 @@ namespace ContinuousTests
|
|||
return GetType().Name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum TestFailMode
|
||||
|
|
|
@ -19,21 +19,29 @@ namespace ContinuousTests
|
|||
|
||||
public void Run()
|
||||
{
|
||||
var overviewLog = new FixtureLog(new LogConfig(config.LogPath, false), DateTime.UtcNow, "Overview");
|
||||
var overviewLog = new LogSplitter(
|
||||
new FixtureLog(new LogConfig(config.LogPath, false), DateTime.UtcNow, "Overview"),
|
||||
new ConsoleLog()
|
||||
);
|
||||
|
||||
overviewLog.Log("Initializing...");
|
||||
|
||||
var entryPoint = entryPointFactory.CreateEntryPoint(config.KubeConfigFile, config.DataPath, config.CodexDeployment.Metadata.KubeNamespace, overviewLog);
|
||||
entryPoint.Announce();
|
||||
|
||||
overviewLog.Log("Initialized. Performing startup checks...");
|
||||
|
||||
var startupChecker = new StartupChecker(entryPoint, config, cancelToken);
|
||||
startupChecker.Check();
|
||||
|
||||
var taskFactory = new TaskFactory();
|
||||
overviewLog.Log("Continuous tests starting...");
|
||||
overviewLog.Log("Startup checks passed. Continuous tests starting...");
|
||||
overviewLog.Log("");
|
||||
var allTests = testFactory.CreateTests();
|
||||
|
||||
ClearAllCustomNamespaces(allTests, overviewLog);
|
||||
|
||||
var testLoops = allTests.Select(t => new TestLoop(entryPoint, taskFactory, config, overviewLog, t.GetType(), t.RunTestEvery, startupChecker, cancelToken)).ToArray();
|
||||
var testLoops = allTests.Select(t => new TestLoop(entryPointFactory, taskFactory, config, overviewLog, t.GetType(), t.RunTestEvery, startupChecker, cancelToken)).ToArray();
|
||||
|
||||
foreach (var testLoop in testLoops)
|
||||
{
|
||||
|
@ -51,12 +59,12 @@ namespace ContinuousTests
|
|||
overviewLog.Log("All tasks cancelled.");
|
||||
}
|
||||
|
||||
private void ClearAllCustomNamespaces(ContinuousTest[] allTests, FixtureLog log)
|
||||
private void ClearAllCustomNamespaces(ContinuousTest[] allTests, ILog log)
|
||||
{
|
||||
foreach (var test in allTests) ClearAllCustomNamespaces(test, log);
|
||||
}
|
||||
|
||||
private void ClearAllCustomNamespaces(ContinuousTest test, FixtureLog log)
|
||||
private void ClearAllCustomNamespaces(ContinuousTest test, ILog log)
|
||||
{
|
||||
if (string.IsNullOrEmpty(test.CustomK8sNamespace)) return;
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ public class Program
|
|||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Codex Continous-Test-Runner.");
|
||||
Console.WriteLine("Running...");
|
||||
|
||||
var runner = new ContinuousTestRunner(args, Cancellation.Cts.Token);
|
||||
|
||||
|
@ -20,14 +19,14 @@ public class Program
|
|||
runner.Run();
|
||||
Console.WriteLine("Done.");
|
||||
}
|
||||
|
||||
public static class Cancellation
|
||||
{
|
||||
static Cancellation()
|
||||
{
|
||||
Cts = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public static CancellationTokenSource Cts { get; }
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cancellation
|
||||
{
|
||||
static Cancellation()
|
||||
{
|
||||
Cts = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public static CancellationTokenSource Cts { get; }
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ using Utils;
|
|||
using KubernetesWorkflow;
|
||||
using NUnit.Framework.Internal;
|
||||
using System.Reflection;
|
||||
using static Program;
|
||||
using FileUtils;
|
||||
using CodexPlugin;
|
||||
using DistTestCore.Logs;
|
||||
using Core;
|
||||
|
@ -17,18 +15,16 @@ namespace ContinuousTests
|
|||
private readonly EntryPoint entryPoint;
|
||||
private readonly TaskFactory taskFactory;
|
||||
private readonly Configuration config;
|
||||
private readonly BaseLog overviewLog;
|
||||
private readonly ILog overviewLog;
|
||||
private readonly TestHandle handle;
|
||||
private readonly CancellationToken cancelToken;
|
||||
private readonly ICodexNode[] nodes;
|
||||
private readonly FixtureLog fixtureLog;
|
||||
private readonly string testName;
|
||||
private readonly string dataFolder;
|
||||
private static int failureCount = 0;
|
||||
|
||||
public SingleTestRun(EntryPoint entryPoint, TaskFactory taskFactory, Configuration config, BaseLog overviewLog, TestHandle handle, StartupChecker startupChecker, CancellationToken cancelToken)
|
||||
public SingleTestRun(EntryPointFactory entryPointFactory, TaskFactory taskFactory, Configuration config, ILog overviewLog, TestHandle handle, StartupChecker startupChecker, CancellationToken cancelToken)
|
||||
{
|
||||
this.entryPoint = entryPoint;
|
||||
this.taskFactory = taskFactory;
|
||||
this.config = config;
|
||||
this.overviewLog = overviewLog;
|
||||
|
@ -36,10 +32,10 @@ namespace ContinuousTests
|
|||
this.cancelToken = cancelToken;
|
||||
testName = handle.Test.GetType().Name;
|
||||
fixtureLog = new FixtureLog(new LogConfig(config.LogPath, true), DateTime.UtcNow, testName);
|
||||
entryPoint = entryPointFactory.CreateEntryPoint(config.KubeConfigFile, config.DataPath, config.CodexDeployment.Metadata.KubeNamespace, fixtureLog);
|
||||
ApplyLogReplacements(fixtureLog, startupChecker);
|
||||
|
||||
nodes = CreateRandomNodes();
|
||||
dataFolder = config.DataPath + "-" + Guid.NewGuid();
|
||||
}
|
||||
|
||||
public void Run(EventWaitHandle runFinishedHandle)
|
||||
|
@ -49,8 +45,11 @@ namespace ContinuousTests
|
|||
try
|
||||
{
|
||||
RunTest();
|
||||
entryPoint.Tools.GetFileManager().DeleteAllFiles();
|
||||
Directory.Delete(dataFolder, true);
|
||||
|
||||
entryPoint.Decommission(
|
||||
deleteKubernetesResources: false, // This would delete the continuous test net.
|
||||
deleteTrackedFiles: true
|
||||
);
|
||||
runFinishedHandle.Set();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
using Core;
|
||||
using Logging;
|
||||
using Logging;
|
||||
|
||||
namespace ContinuousTests
|
||||
{
|
||||
public class TestLoop
|
||||
{
|
||||
private readonly EntryPoint entryPoint;
|
||||
private readonly EntryPointFactory entryPointFactory;
|
||||
private readonly TaskFactory taskFactory;
|
||||
private readonly Configuration config;
|
||||
private readonly BaseLog overviewLog;
|
||||
private readonly ILog overviewLog;
|
||||
private readonly Type testType;
|
||||
private readonly TimeSpan runsEvery;
|
||||
private readonly StartupChecker startupChecker;
|
||||
private readonly CancellationToken cancelToken;
|
||||
private readonly EventWaitHandle runFinishedHandle = new EventWaitHandle(true, EventResetMode.ManualReset);
|
||||
|
||||
public TestLoop(Core.EntryPoint entryPoint, TaskFactory taskFactory, Configuration config, BaseLog overviewLog, Type testType, TimeSpan runsEvery, StartupChecker startupChecker, CancellationToken cancelToken)
|
||||
public TestLoop(EntryPointFactory entryPointFactory, TaskFactory taskFactory, Configuration config, ILog overviewLog, Type testType, TimeSpan runsEvery, StartupChecker startupChecker, CancellationToken cancelToken)
|
||||
{
|
||||
this.entryPoint = entryPoint;
|
||||
this.entryPointFactory = entryPointFactory;
|
||||
this.taskFactory = taskFactory;
|
||||
this.config = config;
|
||||
this.overviewLog = overviewLog;
|
||||
|
@ -63,7 +62,7 @@ namespace ContinuousTests
|
|||
{
|
||||
var test = (ContinuousTest)Activator.CreateInstance(testType)!;
|
||||
var handle = new TestHandle(test);
|
||||
var run = new SingleTestRun(entryPoint, taskFactory, config, overviewLog, handle, startupChecker, cancelToken);
|
||||
var run = new SingleTestRun(entryPointFactory, taskFactory, config, overviewLog, handle, startupChecker, cancelToken);
|
||||
|
||||
runFinishedHandle.Reset();
|
||||
run.Run(runFinishedHandle);
|
||||
|
|
|
@ -62,7 +62,11 @@ namespace DistTestCore
|
|||
[OneTimeTearDown]
|
||||
public void GlobalTearDown()
|
||||
{
|
||||
globalEntryPoint.Decommission();
|
||||
globalEntryPoint.Decommission(
|
||||
// There shouldn't be any of either, but clean everything up regardless.
|
||||
deleteKubernetesResources: true,
|
||||
deleteTrackedFiles: true
|
||||
);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
|
|
|
@ -33,9 +33,10 @@ namespace DistTestCore
|
|||
|
||||
public void DeleteAllResources()
|
||||
{
|
||||
entryPoint.Tools.CreateWorkflow().DeleteNamespace();
|
||||
entryPoint.Tools.GetFileManager().DeleteAllFiles();
|
||||
entryPoint.Decommission();
|
||||
entryPoint.Decommission(
|
||||
deleteKubernetesResources: true,
|
||||
deleteTrackedFiles: true
|
||||
);
|
||||
}
|
||||
|
||||
public TrackedFile GenerateTestFile(ByteSize size, string label = "")
|
||||
|
|
|
@ -14,21 +14,4 @@ namespace CodexNetDeployer
|
|||
checker.AssertFullyConnected(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleLog : BaseLog
|
||||
{
|
||||
public ConsoleLog() : base(false)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string GetFullName()
|
||||
{
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
public override void Log(string message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue