cs-codex-dist-tests/DistTestCore/DistTest.cs

195 lines
5.8 KiB
C#
Raw Normal View History

2023-04-14 10:37:05 +00:00
using DistTestCore.Codex;
using DistTestCore.Logs;
using DistTestCore.Marketplace;
using DistTestCore.Metrics;
2023-04-14 12:53:39 +00:00
using KubernetesWorkflow;
2023-04-14 10:37:05 +00:00
using Logging;
using NUnit.Framework;
2023-04-14 12:53:39 +00:00
using Utils;
2023-04-12 14:06:04 +00:00
namespace DistTestCore
{
[SetUpFixture]
public abstract class DistTest
{
2023-04-14 12:53:39 +00:00
private readonly Configuration configuration = new Configuration();
private FixtureLog fixtureLog = null!;
2023-04-12 14:06:04 +00:00
private TestLifecycle lifecycle = null!;
2023-04-14 12:53:39 +00:00
private DateTime testStart = DateTime.MinValue;
2023-04-12 14:06:04 +00:00
[OneTimeSetUp]
public void GlobalSetup()
{
// Previous test run may have been interrupted.
// Begin by cleaning everything up.
2023-04-14 12:53:39 +00:00
fixtureLog = new FixtureLog(configuration.GetLogConfig());
2023-04-12 14:06:04 +00:00
try
{
2023-04-14 12:53:39 +00:00
Stopwatch.Measure(fixtureLog, "Global setup", () =>
{
var wc = new WorkflowCreator(configuration.GetK8sConfiguration());
wc.CreateWorkflow().DeleteAllResources();
});
2023-04-12 14:06:04 +00:00
}
catch (Exception ex)
{
GlobalTestFailure.HasFailed = true;
Error($"Global setup cleanup failed with: {ex}");
throw;
}
2023-04-14 12:53:39 +00:00
fixtureLog.Log("Global setup cleanup successful");
fixtureLog.Log($"Codex image: {CodexContainerRecipe.DockerImage}");
fixtureLog.Log($"Prometheus image: {PrometheusContainerRecipe.DockerImage}");
fixtureLog.Log($"Geth image: {GethContainerRecipe.DockerImage}");
2023-04-12 14:06:04 +00:00
}
[SetUp]
public void SetUpDistTest()
{
if (GlobalTestFailure.HasFailed)
{
Assert.Inconclusive("Skip test: Previous test failed during clean up.");
}
else
{
CreateNewTestLifecycle();
}
}
[TearDown]
public void TearDownDistTest()
{
try
{
2023-04-14 12:53:39 +00:00
DisposeTestLifecycle();
2023-04-12 14:06:04 +00:00
}
catch (Exception ex)
{
Error("Cleanup failed: " + ex.Message);
GlobalTestFailure.HasFailed = true;
}
}
public TestFile GenerateTestFile(ByteSize size)
{
return lifecycle.FileManager.GenerateTestFile(size);
}
2023-04-13 07:33:10 +00:00
public ICodexSetup SetupCodexNodes(int numberOfNodes)
2023-04-12 14:06:04 +00:00
{
2023-04-13 07:33:10 +00:00
return new CodexSetup(lifecycle.CodexStarter, numberOfNodes);
2023-04-12 14:06:04 +00:00
}
private void IncludeLogsAndMetricsOnTestFailure()
{
var result = TestContext.CurrentContext.Result;
if (result.Outcome.Status == NUnit.Framework.Interfaces.TestStatus.Failed)
{
2023-04-14 12:53:39 +00:00
fixtureLog.MarkAsFailed();
if (IsDownloadingLogsAndMetricsEnabled())
{
Log("Downloading all CodexNode logs and metrics because of test failure...");
DownloadAllLogs();
DownloadAllMetrics();
}
else
{
Log("Skipping download of all CodexNode logs and metrics due to [DontDownloadLogsAndMetricsOnFailure] attribute.");
}
}
2023-04-12 14:06:04 +00:00
}
private void Log(string msg)
{
lifecycle.Log.Log(msg);
}
private void Error(string msg)
{
lifecycle.Log.Error(msg);
}
private void CreateNewTestLifecycle()
{
2023-04-14 12:53:39 +00:00
Stopwatch.Measure(fixtureLog, $"Setup for {GetCurrentTestName()}", () =>
{
lifecycle = new TestLifecycle(fixtureLog.CreateTestLog(), configuration);
testStart = DateTime.UtcNow;
});
}
private void DisposeTestLifecycle()
{
fixtureLog.Log($"{GetCurrentTestName()} = {GetTestResult()} ({GetTestDuration()})");
Stopwatch.Measure(fixtureLog, $"Teardown for {GetCurrentTestName()}", () =>
{
lifecycle.Log.EndTest();
IncludeLogsAndMetricsOnTestFailure();
lifecycle.DeleteAllResources();
lifecycle = null!;
});
}
private string GetTestDuration()
{
var testDuration = DateTime.UtcNow - testStart;
return Time.FormatDuration(testDuration);
2023-04-12 14:06:04 +00:00
}
private void DownloadAllLogs()
2023-04-12 14:06:04 +00:00
{
OnEachCodexNode(node =>
{
lifecycle.DownloadLog(node);
});
}
private void DownloadAllMetrics()
{
var metricsDownloader = new MetricsDownloader(lifecycle.Log);
OnEachCodexNode(node =>
{
var m = node.Metrics as MetricsAccess;
if (m != null)
{
metricsDownloader.DownloadAllMetricsForNode(node.GetName(), m);
}
});
}
private void OnEachCodexNode(Action<OnlineCodexNode> action)
{
var allNodes = lifecycle.CodexStarter.RunningGroups.SelectMany(g => g.Nodes);
foreach (var node in allNodes)
{
action(node);
}
2023-04-12 14:06:04 +00:00
}
2023-04-14 12:53:39 +00:00
private string GetCurrentTestName()
{
return $"[{TestContext.CurrentContext.Test.Name}]";
}
private string GetTestResult()
{
return TestContext.CurrentContext.Result.Outcome.Status.ToString();
}
private bool IsDownloadingLogsAndMetricsEnabled()
{
var testProperties = TestContext.CurrentContext.Test.Properties;
return !testProperties.ContainsKey(DontDownloadLogsAndMetricsOnFailureAttribute.DontDownloadKey);
}
2023-04-12 14:06:04 +00:00
}
public static class GlobalTestFailure
{
public static bool HasFailed { get; set; } = false;
}
}