Merge branch 'feature/labeling-pods'
This commit is contained in:
commit
ea767e23ae
|
@ -8,16 +8,14 @@ namespace CodexNetDeployer
|
||||||
public class CodexNodeStarter
|
public class CodexNodeStarter
|
||||||
{
|
{
|
||||||
private readonly Configuration config;
|
private readonly Configuration config;
|
||||||
private readonly WorkflowCreator workflowCreator;
|
|
||||||
private readonly TestLifecycle lifecycle;
|
private readonly TestLifecycle lifecycle;
|
||||||
private readonly GethStartResult gethResult;
|
private readonly GethStartResult gethResult;
|
||||||
private string bootstrapSpr = "";
|
private string bootstrapSpr = "";
|
||||||
private int validatorsLeft;
|
private int validatorsLeft;
|
||||||
|
|
||||||
public CodexNodeStarter(Configuration config, WorkflowCreator workflowCreator, TestLifecycle lifecycle, GethStartResult gethResult, int numberOfValidators)
|
public CodexNodeStarter(Configuration config, TestLifecycle lifecycle, GethStartResult gethResult, int numberOfValidators)
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.workflowCreator = workflowCreator;
|
|
||||||
this.lifecycle = lifecycle;
|
this.lifecycle = lifecycle;
|
||||||
this.gethResult = gethResult;
|
this.gethResult = gethResult;
|
||||||
validatorsLeft = numberOfValidators;
|
validatorsLeft = numberOfValidators;
|
||||||
|
@ -26,7 +24,7 @@ namespace CodexNetDeployer
|
||||||
public RunningContainer? Start(int i)
|
public RunningContainer? Start(int i)
|
||||||
{
|
{
|
||||||
Console.Write($" - {i} = ");
|
Console.Write($" - {i} = ");
|
||||||
var workflow = workflowCreator.CreateWorkflow();
|
var workflow = lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
var workflowStartup = new StartupConfig();
|
var workflowStartup = new StartupConfig();
|
||||||
workflowStartup.Add(gethResult);
|
workflowStartup.Add(gethResult);
|
||||||
workflowStartup.Add(CreateCodexStartupConfig(bootstrapSpr, i, validatorsLeft));
|
workflowStartup.Add(CreateCodexStartupConfig(bootstrapSpr, i, validatorsLeft));
|
||||||
|
|
|
@ -47,6 +47,10 @@ namespace CodexNetDeployer
|
||||||
[Uniform("record-metrics", "rm", "RECORDMETRICS", false, "If true, metrics will be collected for all Codex nodes.")]
|
[Uniform("record-metrics", "rm", "RECORDMETRICS", false, "If true, metrics will be collected for all Codex nodes.")]
|
||||||
public bool RecordMetrics { get; set; } = false;
|
public bool RecordMetrics { get; set; } = false;
|
||||||
|
|
||||||
|
[Uniform("teststype-podlabel", "ttpl", "TESTSTYPE-PODLABEL", false, "Each kubernetes pod will be created with a label 'teststype' with value 'continuous'. " +
|
||||||
|
"set this option to override the label value.")]
|
||||||
|
public string TestsTypePodLabel { get; set; } = "continuous";
|
||||||
|
|
||||||
public TestRunnerLocation RunnerLocation { get; set; } = TestRunnerLocation.InternalToCluster;
|
public TestRunnerLocation RunnerLocation { get; set; } = TestRunnerLocation.InternalToCluster;
|
||||||
|
|
||||||
public List<string> Validate()
|
public List<string> Validate()
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CodexNetDeployer
|
||||||
public CodexDeployment Deploy()
|
public CodexDeployment Deploy()
|
||||||
{
|
{
|
||||||
Log("Initializing...");
|
Log("Initializing...");
|
||||||
var (workflowCreator, lifecycle) = CreateFacilities();
|
var lifecycle = CreateTestLifecycle();
|
||||||
|
|
||||||
Log("Preparing configuration...");
|
Log("Preparing configuration...");
|
||||||
// We trick the Geth companion node into unlocking all of its accounts, by saying we want to start 999 codex nodes.
|
// We trick the Geth companion node into unlocking all of its accounts, by saying we want to start 999 codex nodes.
|
||||||
|
@ -30,7 +30,7 @@ namespace CodexNetDeployer
|
||||||
setup.MetricsEnabled = config.RecordMetrics;
|
setup.MetricsEnabled = config.RecordMetrics;
|
||||||
|
|
||||||
Log("Creating Geth instance and deploying contracts...");
|
Log("Creating Geth instance and deploying contracts...");
|
||||||
var gethStarter = new GethStarter(lifecycle, workflowCreator);
|
var gethStarter = new GethStarter(lifecycle);
|
||||||
var gethResults = gethStarter.BringOnlineMarketplaceFor(setup);
|
var gethResults = gethStarter.BringOnlineMarketplaceFor(setup);
|
||||||
|
|
||||||
Log("Geth started. Codex contracts deployed.");
|
Log("Geth started. Codex contracts deployed.");
|
||||||
|
@ -44,7 +44,7 @@ namespace CodexNetDeployer
|
||||||
Log("Starting Codex nodes...");
|
Log("Starting Codex nodes...");
|
||||||
|
|
||||||
// Each node must have its own IP, so it needs it own pod. Start them 1 at a time.
|
// Each node must have its own IP, so it needs it own pod. Start them 1 at a time.
|
||||||
var codexStarter = new CodexNodeStarter(config, workflowCreator, lifecycle, gethResults, config.NumberOfValidators!.Value);
|
var codexStarter = new CodexNodeStarter(config, lifecycle, gethResults, config.NumberOfValidators!.Value);
|
||||||
var codexContainers = new List<RunningContainer>();
|
var codexContainers = new List<RunningContainer>();
|
||||||
for (var i = 0; i < config.NumberOfCodexNodes; i++)
|
for (var i = 0; i < config.NumberOfCodexNodes; i++)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ namespace CodexNetDeployer
|
||||||
return new CodexDeployment(gethResults, codexContainers.ToArray(), prometheusContainer, CreateMetadata());
|
return new CodexDeployment(gethResults, codexContainers.ToArray(), prometheusContainer, CreateMetadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
private (WorkflowCreator, TestLifecycle) CreateFacilities()
|
private TestLifecycle CreateTestLifecycle()
|
||||||
{
|
{
|
||||||
var kubeConfig = GetKubeConfig(config.KubeConfigFile);
|
var kubeConfig = GetKubeConfig(config.KubeConfigFile);
|
||||||
|
|
||||||
|
@ -68,19 +68,11 @@ namespace CodexNetDeployer
|
||||||
logDebug: false,
|
logDebug: false,
|
||||||
dataFilesPath: "notUsed",
|
dataFilesPath: "notUsed",
|
||||||
codexLogLevel: config.CodexLogLevel,
|
codexLogLevel: config.CodexLogLevel,
|
||||||
runnerLocation: config.RunnerLocation
|
runnerLocation: config.RunnerLocation,
|
||||||
|
k8sNamespacePrefix: config.KubeNamespace
|
||||||
);
|
);
|
||||||
|
|
||||||
var kubeFlowConfig = new KubernetesWorkflow.Configuration(
|
return new TestLifecycle(log, lifecycleConfig, timeset, config.TestsTypePodLabel, string.Empty);
|
||||||
k8sNamespacePrefix: config.KubeNamespace,
|
|
||||||
kubeConfigFile: kubeConfig,
|
|
||||||
operationTimeout: timeset.K8sOperationTimeout(),
|
|
||||||
retryDelay: timeset.WaitForK8sServiceDelay());
|
|
||||||
|
|
||||||
var workflowCreator = new WorkflowCreator(log, kubeFlowConfig, testNamespacePostfix: string.Empty);
|
|
||||||
var lifecycle = new TestLifecycle(log, lifecycleConfig, timeset, workflowCreator);
|
|
||||||
|
|
||||||
return (workflowCreator, lifecycle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningContainer? StartMetricsService(TestLifecycle lifecycle, CodexSetup setup, List<RunningContainer> codexContainers)
|
private RunningContainer? StartMetricsService(TestLifecycle lifecycle, CodexSetup setup, List<RunningContainer> codexContainers)
|
||||||
|
|
|
@ -9,5 +9,5 @@ dotnet run \
|
||||||
--min-price=1024 \
|
--min-price=1024 \
|
||||||
--max-collateral=1024 \
|
--max-collateral=1024 \
|
||||||
--max-duration=3600000 \
|
--max-duration=3600000 \
|
||||||
--block-ttl=120 \
|
--block-ttl=300 \
|
||||||
-y
|
--record-metrics=true
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class Program
|
||||||
if (!Directory.Exists(config.OutputPath)) Directory.CreateDirectory(config.OutputPath);
|
if (!Directory.Exists(config.OutputPath)) Directory.CreateDirectory(config.OutputPath);
|
||||||
|
|
||||||
var k8sFactory = new K8sFactory();
|
var k8sFactory = new K8sFactory();
|
||||||
var (_, lifecycle) = k8sFactory.CreateFacilities(config.KubeConfigFile, config.OutputPath, "dataPath", config.CodexDeployment.Metadata.KubeNamespace, new DefaultTimeSet(), new NullLog(), config.RunnerLocation);
|
var lifecycle = k8sFactory.CreateTestLifecycle(config.KubeConfigFile, config.OutputPath, "dataPath", config.CodexDeployment.Metadata.KubeNamespace, new DefaultTimeSet(), new NullLog(), config.RunnerLocation);
|
||||||
|
|
||||||
foreach (var container in config.CodexDeployment.CodexContainers)
|
foreach (var container in config.CodexDeployment.CodexContainers)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,8 +60,8 @@ namespace ContinuousTests
|
||||||
if (string.IsNullOrEmpty(test.CustomK8sNamespace)) return;
|
if (string.IsNullOrEmpty(test.CustomK8sNamespace)) return;
|
||||||
|
|
||||||
log.Log($"Clearing namespace '{test.CustomK8sNamespace}'...");
|
log.Log($"Clearing namespace '{test.CustomK8sNamespace}'...");
|
||||||
var (workflowCreator, _) = k8SFactory.CreateFacilities(config.KubeConfigFile, config.LogPath, config.DataPath, test.CustomK8sNamespace, new DefaultTimeSet(), log, config.RunnerLocation);
|
var lifecycle = k8SFactory.CreateTestLifecycle(config.KubeConfigFile, config.LogPath, config.DataPath, test.CustomK8sNamespace, new DefaultTimeSet(), log, config.RunnerLocation);
|
||||||
workflowCreator.CreateWorkflow().DeleteTestResources();
|
lifecycle.WorkflowCreator.CreateWorkflow().DeleteTestResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartLogDownloader(TaskFactory taskFactory)
|
private void StartLogDownloader(TaskFactory taskFactory)
|
||||||
|
@ -71,7 +71,7 @@ namespace ContinuousTests
|
||||||
var path = Path.Combine(config.LogPath, "containers");
|
var path = Path.Combine(config.LogPath, "containers");
|
||||||
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
|
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
|
||||||
|
|
||||||
var (_, lifecycle) = k8SFactory.CreateFacilities(config.KubeConfigFile, config.LogPath, config.DataPath, config.CodexDeployment.Metadata.KubeNamespace, new DefaultTimeSet(), new NullLog(), config.RunnerLocation);
|
var lifecycle = k8SFactory.CreateTestLifecycle(config.KubeConfigFile, config.LogPath, config.DataPath, config.CodexDeployment.Metadata.KubeNamespace, new DefaultTimeSet(), new NullLog(), config.RunnerLocation);
|
||||||
var downloader = new ContinuousLogDownloader(lifecycle, config.CodexDeployment, path, cancelToken);
|
var downloader = new ContinuousLogDownloader(lifecycle, config.CodexDeployment, path, cancelToken);
|
||||||
|
|
||||||
taskFactory.Run(downloader.Run);
|
taskFactory.Run(downloader.Run);
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
using DistTestCore.Codex;
|
using DistTestCore.Codex;
|
||||||
using DistTestCore;
|
using DistTestCore;
|
||||||
using KubernetesWorkflow;
|
|
||||||
using Logging;
|
using Logging;
|
||||||
|
|
||||||
namespace ContinuousTests
|
namespace ContinuousTests
|
||||||
{
|
{
|
||||||
public class K8sFactory
|
public class K8sFactory
|
||||||
{
|
{
|
||||||
public (WorkflowCreator, TestLifecycle) CreateFacilities(string kubeConfigFile, string logPath, string dataFilePath, string customNamespace, ITimeSet timeSet, BaseLog log, TestRunnerLocation runnerLocation)
|
public TestLifecycle CreateTestLifecycle(string kubeConfigFile, string logPath, string dataFilePath, string customNamespace, ITimeSet timeSet, BaseLog log, TestRunnerLocation runnerLocation)
|
||||||
{
|
{
|
||||||
var kubeConfig = GetKubeConfig(kubeConfigFile);
|
var kubeConfig = GetKubeConfig(kubeConfigFile);
|
||||||
var lifecycleConfig = new DistTestCore.Configuration
|
var lifecycleConfig = new DistTestCore.Configuration
|
||||||
|
@ -17,19 +16,11 @@ namespace ContinuousTests
|
||||||
logDebug: false,
|
logDebug: false,
|
||||||
dataFilesPath: dataFilePath,
|
dataFilesPath: dataFilePath,
|
||||||
codexLogLevel: CodexLogLevel.Debug,
|
codexLogLevel: CodexLogLevel.Debug,
|
||||||
runnerLocation: runnerLocation
|
runnerLocation: runnerLocation,
|
||||||
|
k8sNamespacePrefix: customNamespace
|
||||||
);
|
);
|
||||||
|
|
||||||
var kubeFlowConfig = new KubernetesWorkflow.Configuration(
|
return new TestLifecycle(log, lifecycleConfig, timeSet, "continuous-tests", string.Empty);
|
||||||
k8sNamespacePrefix: customNamespace,
|
|
||||||
kubeConfigFile: kubeConfig,
|
|
||||||
operationTimeout: timeSet.K8sOperationTimeout(),
|
|
||||||
retryDelay: timeSet.WaitForK8sServiceDelay());
|
|
||||||
|
|
||||||
var workflowCreator = new WorkflowCreator(log, kubeFlowConfig, testNamespacePostfix: string.Empty);
|
|
||||||
var lifecycle = new TestLifecycle(log, lifecycleConfig, timeSet, workflowCreator);
|
|
||||||
|
|
||||||
return (workflowCreator, lifecycle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? GetKubeConfig(string kubeConfigFile)
|
private static string? GetKubeConfig(string kubeConfigFile)
|
||||||
|
|
|
@ -40,8 +40,8 @@ namespace ContinuousTests
|
||||||
|
|
||||||
public void RunNode(CodexAccess bootstrapNode, Action<CodexAccess, MarketplaceAccess, TestLifecycle> operation, TestToken mintTestTokens)
|
public void RunNode(CodexAccess bootstrapNode, Action<CodexAccess, MarketplaceAccess, TestLifecycle> operation, TestToken mintTestTokens)
|
||||||
{
|
{
|
||||||
var (workflowCreator, lifecycle) = CreateFacilities();
|
var lifecycle = CreateTestLifecycle();
|
||||||
var flow = workflowCreator.CreateWorkflow();
|
var flow = lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -89,9 +89,9 @@ namespace ContinuousTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private (WorkflowCreator, TestLifecycle) CreateFacilities()
|
private TestLifecycle CreateTestLifecycle()
|
||||||
{
|
{
|
||||||
return k8SFactory.CreateFacilities(config.KubeConfigFile, config.LogPath, config.DataPath, customNamespace, timeSet, log, config.RunnerLocation);
|
return k8SFactory.CreateTestLifecycle(config.KubeConfigFile, config.LogPath, config.DataPath, customNamespace, timeSet, log, config.RunnerLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ namespace ContinuousTests
|
||||||
private void DownloadClusterLogs()
|
private void DownloadClusterLogs()
|
||||||
{
|
{
|
||||||
var k8sFactory = new K8sFactory();
|
var k8sFactory = new K8sFactory();
|
||||||
var (_, lifecycle) = k8sFactory.CreateFacilities(config.KubeConfigFile, config.LogPath, "dataPath", config.CodexDeployment.Metadata.KubeNamespace, new DefaultTimeSet(), new NullLog(), config.RunnerLocation);
|
var lifecycle = k8sFactory.CreateTestLifecycle(config.KubeConfigFile, config.LogPath, "dataPath", config.CodexDeployment.Metadata.KubeNamespace, new DefaultTimeSet(), new NullLog(), config.RunnerLocation);
|
||||||
|
|
||||||
foreach (var container in config.CodexDeployment.CodexContainers)
|
foreach (var container in config.CodexDeployment.CodexContainers)
|
||||||
{
|
{
|
||||||
|
@ -221,7 +221,7 @@ namespace ContinuousTests
|
||||||
private DistTestCore.Configuration CreateFileManagerConfiguration()
|
private DistTestCore.Configuration CreateFileManagerConfiguration()
|
||||||
{
|
{
|
||||||
return new DistTestCore.Configuration(null, string.Empty, false, dataFolder,
|
return new DistTestCore.Configuration(null, string.Empty, false, dataFolder,
|
||||||
CodexLogLevel.Error, config.RunnerLocation);
|
CodexLogLevel.Error, config.RunnerLocation, string.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
using KubernetesWorkflow;
|
using Logging;
|
||||||
using Logging;
|
|
||||||
|
|
||||||
namespace DistTestCore
|
namespace DistTestCore
|
||||||
{
|
{
|
||||||
public class BaseStarter
|
public class BaseStarter
|
||||||
{
|
{
|
||||||
protected readonly TestLifecycle lifecycle;
|
protected readonly TestLifecycle lifecycle;
|
||||||
protected readonly WorkflowCreator workflowCreator;
|
|
||||||
private Stopwatch? stopwatch;
|
private Stopwatch? stopwatch;
|
||||||
|
|
||||||
public BaseStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public BaseStarter(TestLifecycle lifecycle)
|
||||||
{
|
{
|
||||||
this.lifecycle = lifecycle;
|
this.lifecycle = lifecycle;
|
||||||
this.workflowCreator = workflowCreator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void LogStart(string msg)
|
protected void LogStart(string msg)
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace DistTestCore.Codex
|
||||||
public static readonly TimeSpan MaxUploadTimePerMegabyte = TimeSpan.FromSeconds(2.0);
|
public static readonly TimeSpan MaxUploadTimePerMegabyte = TimeSpan.FromSeconds(2.0);
|
||||||
public static readonly TimeSpan MaxDownloadTimePerMegabyte = TimeSpan.FromSeconds(2.0);
|
public static readonly TimeSpan MaxDownloadTimePerMegabyte = TimeSpan.FromSeconds(2.0);
|
||||||
|
|
||||||
|
public override string AppName => "codex";
|
||||||
public override string Image { get; }
|
public override string Image { get; }
|
||||||
|
|
||||||
public CodexContainerRecipe()
|
public CodexContainerRecipe()
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
public class CodexStarter : BaseStarter
|
public class CodexStarter : BaseStarter
|
||||||
{
|
{
|
||||||
public CodexStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public CodexStarter(TestLifecycle lifecycle)
|
||||||
: base(lifecycle, workflowCreator)
|
: base(lifecycle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace DistTestCore
|
||||||
|
|
||||||
private StartupWorkflow CreateWorkflow()
|
private StartupWorkflow CreateWorkflow()
|
||||||
{
|
{
|
||||||
return workflowCreator.CreateWorkflow();
|
return lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogSeparator()
|
private void LogSeparator()
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace DistTestCore
|
||||||
private readonly string dataFilesPath;
|
private readonly string dataFilesPath;
|
||||||
private readonly CodexLogLevel codexLogLevel;
|
private readonly CodexLogLevel codexLogLevel;
|
||||||
private readonly TestRunnerLocation runnerLocation;
|
private readonly TestRunnerLocation runnerLocation;
|
||||||
|
private readonly string k8sNamespacePrefix;
|
||||||
|
|
||||||
public Configuration()
|
public Configuration()
|
||||||
{
|
{
|
||||||
|
@ -21,9 +22,10 @@ namespace DistTestCore
|
||||||
dataFilesPath = GetEnvVarOrDefault("DATAFILEPATH", "TestDataFiles");
|
dataFilesPath = GetEnvVarOrDefault("DATAFILEPATH", "TestDataFiles");
|
||||||
codexLogLevel = ParseEnum.Parse<CodexLogLevel>(GetEnvVarOrDefault("LOGLEVEL", nameof(CodexLogLevel.Trace)));
|
codexLogLevel = ParseEnum.Parse<CodexLogLevel>(GetEnvVarOrDefault("LOGLEVEL", nameof(CodexLogLevel.Trace)));
|
||||||
runnerLocation = ParseEnum.Parse<TestRunnerLocation>(GetEnvVarOrDefault("RUNNERLOCATION", nameof(TestRunnerLocation.ExternalToCluster)));
|
runnerLocation = ParseEnum.Parse<TestRunnerLocation>(GetEnvVarOrDefault("RUNNERLOCATION", nameof(TestRunnerLocation.ExternalToCluster)));
|
||||||
|
k8sNamespacePrefix = "ct-";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Configuration(string? kubeConfigFile, string logPath, bool logDebug, string dataFilesPath, CodexLogLevel codexLogLevel, TestRunnerLocation runnerLocation)
|
public Configuration(string? kubeConfigFile, string logPath, bool logDebug, string dataFilesPath, CodexLogLevel codexLogLevel, TestRunnerLocation runnerLocation, string k8sNamespacePrefix)
|
||||||
{
|
{
|
||||||
this.kubeConfigFile = kubeConfigFile;
|
this.kubeConfigFile = kubeConfigFile;
|
||||||
this.logPath = logPath;
|
this.logPath = logPath;
|
||||||
|
@ -31,12 +33,13 @@ namespace DistTestCore
|
||||||
this.dataFilesPath = dataFilesPath;
|
this.dataFilesPath = dataFilesPath;
|
||||||
this.codexLogLevel = codexLogLevel;
|
this.codexLogLevel = codexLogLevel;
|
||||||
this.runnerLocation = runnerLocation;
|
this.runnerLocation = runnerLocation;
|
||||||
|
this.k8sNamespacePrefix = k8sNamespacePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KubernetesWorkflow.Configuration GetK8sConfiguration(ITimeSet timeSet)
|
public KubernetesWorkflow.Configuration GetK8sConfiguration(ITimeSet timeSet)
|
||||||
{
|
{
|
||||||
return new KubernetesWorkflow.Configuration(
|
return new KubernetesWorkflow.Configuration(
|
||||||
k8sNamespacePrefix: "ct-",
|
k8sNamespacePrefix: k8sNamespacePrefix,
|
||||||
kubeConfigFile: kubeConfigFile,
|
kubeConfigFile: kubeConfigFile,
|
||||||
operationTimeout: timeSet.K8sOperationTimeout(),
|
operationTimeout: timeSet.K8sOperationTimeout(),
|
||||||
retryDelay: timeSet.WaitForK8sServiceDelay()
|
retryDelay: timeSet.WaitForK8sServiceDelay()
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace DistTestCore
|
||||||
[Parallelizable(ParallelScope.All)]
|
[Parallelizable(ParallelScope.All)]
|
||||||
public abstract class DistTest
|
public abstract class DistTest
|
||||||
{
|
{
|
||||||
|
private const string TestsType = "dist-tests";
|
||||||
private readonly Configuration configuration = new Configuration();
|
private readonly Configuration configuration = new Configuration();
|
||||||
private readonly Assembly[] testAssemblies;
|
private readonly Assembly[] testAssemblies;
|
||||||
private readonly FixtureLog fixtureLog;
|
private readonly FixtureLog fixtureLog;
|
||||||
|
@ -52,7 +53,7 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
Stopwatch.Measure(fixtureLog, "Global setup", () =>
|
Stopwatch.Measure(fixtureLog, "Global setup", () =>
|
||||||
{
|
{
|
||||||
var wc = new WorkflowCreator(fixtureLog, configuration.GetK8sConfiguration(GetTimeSet()));
|
var wc = new WorkflowCreator(fixtureLog, configuration.GetK8sConfiguration(GetTimeSet()), new PodLabels(TestsType, null!), string.Empty);
|
||||||
wc.CreateWorkflow().DeleteAllResources();
|
wc.CreateWorkflow().DeleteAllResources();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -195,7 +196,9 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
lock (lifecycleLock)
|
lock (lifecycleLock)
|
||||||
{
|
{
|
||||||
lifecycles.Add(testName, new TestLifecycle(fixtureLog.CreateTestLog(), configuration, GetTimeSet()));
|
var testNamespace = Guid.NewGuid().ToString();
|
||||||
|
var lifecycle = new TestLifecycle(fixtureLog.CreateTestLog(), configuration, GetTimeSet(), TestsType, testNamespace);
|
||||||
|
lifecycles.Add(testName, lifecycle);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -206,7 +209,7 @@ namespace DistTestCore
|
||||||
var testResult = GetTestResult();
|
var testResult = GetTestResult();
|
||||||
var testDuration = lifecycle.GetTestDuration();
|
var testDuration = lifecycle.GetTestDuration();
|
||||||
fixtureLog.Log($"{GetCurrentTestName()} = {testResult} ({testDuration})");
|
fixtureLog.Log($"{GetCurrentTestName()} = {testResult} ({testDuration})");
|
||||||
statusLog.ConcludeTest(testResult, testDuration, GetCodexId(lifecycle));
|
statusLog.ConcludeTest(testResult, testDuration, lifecycle.GetApplicationIds());
|
||||||
Stopwatch.Measure(fixtureLog, $"Teardown for {GetCurrentTestName()}", () =>
|
Stopwatch.Measure(fixtureLog, $"Teardown for {GetCurrentTestName()}", () =>
|
||||||
{
|
{
|
||||||
lifecycle.Log.EndTest();
|
lifecycle.Log.EndTest();
|
||||||
|
@ -216,14 +219,6 @@ namespace DistTestCore
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCodexId(TestLifecycle lifecycle)
|
|
||||||
{
|
|
||||||
var v = lifecycle.CodexVersion;
|
|
||||||
if (v == null) return new CodexContainerRecipe().Image;
|
|
||||||
if (v.version != "untagged build") return v.version;
|
|
||||||
return v.revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ITimeSet GetTimeSet()
|
private ITimeSet GetTimeSet()
|
||||||
{
|
{
|
||||||
if (ShouldUseLongTimeouts()) return new LongTimeSet();
|
if (ShouldUseLongTimeouts()) return new LongTimeSet();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using DistTestCore.Marketplace;
|
using DistTestCore.Marketplace;
|
||||||
using KubernetesWorkflow;
|
|
||||||
|
|
||||||
namespace DistTestCore
|
namespace DistTestCore
|
||||||
{
|
{
|
||||||
|
@ -8,13 +7,13 @@ namespace DistTestCore
|
||||||
private readonly MarketplaceNetworkCache marketplaceNetworkCache;
|
private readonly MarketplaceNetworkCache marketplaceNetworkCache;
|
||||||
private readonly GethCompanionNodeStarter companionNodeStarter;
|
private readonly GethCompanionNodeStarter companionNodeStarter;
|
||||||
|
|
||||||
public GethStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public GethStarter(TestLifecycle lifecycle)
|
||||||
: base(lifecycle, workflowCreator)
|
: base(lifecycle)
|
||||||
{
|
{
|
||||||
marketplaceNetworkCache = new MarketplaceNetworkCache(
|
marketplaceNetworkCache = new MarketplaceNetworkCache(
|
||||||
new GethBootstrapNodeStarter(lifecycle, workflowCreator),
|
new GethBootstrapNodeStarter(lifecycle),
|
||||||
new CodexContractsStarter(lifecycle, workflowCreator));
|
new CodexContractsStarter(lifecycle));
|
||||||
companionNodeStarter = new GethCompanionNodeStarter(lifecycle, workflowCreator);
|
companionNodeStarter = new GethCompanionNodeStarter(lifecycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GethStartResult BringOnlineMarketplaceFor(CodexSetup codexSetup)
|
public GethStartResult BringOnlineMarketplaceFor(CodexSetup codexSetup)
|
||||||
|
|
|
@ -7,12 +7,8 @@ namespace DistTestCore.Marketplace
|
||||||
public const string MarketplaceAddressFilename = "/hardhat/deployments/codexdisttestnetwork/Marketplace.json";
|
public const string MarketplaceAddressFilename = "/hardhat/deployments/codexdisttestnetwork/Marketplace.json";
|
||||||
public const string MarketplaceArtifactFilename = "/hardhat/artifacts/contracts/Marketplace.sol/Marketplace.json";
|
public const string MarketplaceArtifactFilename = "/hardhat/artifacts/contracts/Marketplace.sol/Marketplace.json";
|
||||||
|
|
||||||
public override string Image { get; }
|
public override string AppName => "codex-contracts";
|
||||||
|
public override string Image => "codexstorage/dist-tests-codex-contracts-eth:sha-d6fbfdc";
|
||||||
public CodexContractsContainerRecipe()
|
|
||||||
{
|
|
||||||
Image = "codexstorage/dist-tests-codex-contracts-eth:sha-d6fbfdc";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize(StartupConfig startupConfig)
|
protected override void Initialize(StartupConfig startupConfig)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,8 +6,8 @@ namespace DistTestCore.Marketplace
|
||||||
public class CodexContractsStarter : BaseStarter
|
public class CodexContractsStarter : BaseStarter
|
||||||
{
|
{
|
||||||
|
|
||||||
public CodexContractsStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public CodexContractsStarter(TestLifecycle lifecycle)
|
||||||
: base(lifecycle, workflowCreator)
|
: base(lifecycle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ namespace DistTestCore.Marketplace
|
||||||
{
|
{
|
||||||
LogStart("Deploying Codex Marketplace...");
|
LogStart("Deploying Codex Marketplace...");
|
||||||
|
|
||||||
var workflow = workflowCreator.CreateWorkflow();
|
var workflow = lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
var startupConfig = CreateStartupConfig(bootstrapNode.RunningContainers.Containers[0]);
|
var startupConfig = CreateStartupConfig(bootstrapNode.RunningContainers.Containers[0]);
|
||||||
|
|
||||||
var containers = workflow.Start(1, Location.Unspecified, new CodexContractsContainerRecipe(), startupConfig);
|
var containers = workflow.Start(1, Location.Unspecified, new CodexContractsContainerRecipe(), startupConfig);
|
||||||
|
|
|
@ -4,8 +4,8 @@ namespace DistTestCore.Marketplace
|
||||||
{
|
{
|
||||||
public class GethBootstrapNodeStarter : BaseStarter
|
public class GethBootstrapNodeStarter : BaseStarter
|
||||||
{
|
{
|
||||||
public GethBootstrapNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public GethBootstrapNodeStarter(TestLifecycle lifecycle)
|
||||||
: base(lifecycle, workflowCreator)
|
: base(lifecycle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace DistTestCore.Marketplace
|
||||||
LogStart("Starting Geth bootstrap node...");
|
LogStart("Starting Geth bootstrap node...");
|
||||||
var startupConfig = CreateBootstrapStartupConfig();
|
var startupConfig = CreateBootstrapStartupConfig();
|
||||||
|
|
||||||
var workflow = workflowCreator.CreateWorkflow();
|
var workflow = lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
var containers = workflow.Start(1, Location.Unspecified, new GethContainerRecipe(), startupConfig);
|
var containers = workflow.Start(1, Location.Unspecified, new GethContainerRecipe(), startupConfig);
|
||||||
if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected 1 Geth bootstrap node to be created. Test infra failure.");
|
if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected 1 Geth bootstrap node to be created. Test infra failure.");
|
||||||
var bootstrapContainer = containers.Containers[0];
|
var bootstrapContainer = containers.Containers[0];
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace DistTestCore.Marketplace
|
||||||
{
|
{
|
||||||
private int companionAccountIndex = 0;
|
private int companionAccountIndex = 0;
|
||||||
|
|
||||||
public GethCompanionNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public GethCompanionNodeStarter(TestLifecycle lifecycle)
|
||||||
: base(lifecycle, workflowCreator)
|
: base(lifecycle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace DistTestCore.Marketplace
|
||||||
|
|
||||||
var config = CreateCompanionNodeStartupConfig(marketplace.Bootstrap, codexSetup.NumberOfNodes);
|
var config = CreateCompanionNodeStartupConfig(marketplace.Bootstrap, codexSetup.NumberOfNodes);
|
||||||
|
|
||||||
var workflow = workflowCreator.CreateWorkflow();
|
var workflow = lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
var containers = workflow.Start(1, Location.Unspecified, new GethContainerRecipe(), CreateStartupConfig(config));
|
var containers = workflow.Start(1, Location.Unspecified, new GethContainerRecipe(), CreateStartupConfig(config));
|
||||||
if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected one Geth companion node to be created. Test infra failure.");
|
if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected one Geth companion node to be created. Test infra failure.");
|
||||||
var container = containers.Containers[0];
|
var container = containers.Containers[0];
|
||||||
|
|
|
@ -10,12 +10,8 @@ namespace DistTestCore.Marketplace
|
||||||
public const string DiscoveryPortTag = "disc_port";
|
public const string DiscoveryPortTag = "disc_port";
|
||||||
public const string AccountsFilename = "accounts.csv";
|
public const string AccountsFilename = "accounts.csv";
|
||||||
|
|
||||||
public override string Image { get; }
|
public override string AppName => "geth";
|
||||||
|
public override string Image => "codexstorage/dist-tests-geth:sha-b788a2d";
|
||||||
public GethContainerRecipe()
|
|
||||||
{
|
|
||||||
Image = "codexstorage/dist-tests-geth:sha-b788a2d";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize(StartupConfig startupConfig)
|
protected override void Initialize(StartupConfig startupConfig)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,12 +4,8 @@ namespace DistTestCore.Metrics
|
||||||
{
|
{
|
||||||
public class PrometheusContainerRecipe : ContainerRecipeFactory
|
public class PrometheusContainerRecipe : ContainerRecipeFactory
|
||||||
{
|
{
|
||||||
public override string Image { get; }
|
public override string AppName => "prometheus";
|
||||||
|
public override string Image => "codexstorage/dist-tests-prometheus:sha-f97d7fd";
|
||||||
public PrometheusContainerRecipe()
|
|
||||||
{
|
|
||||||
Image = "codexstorage/dist-tests-prometheus:sha-f97d7fd";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize(StartupConfig startupConfig)
|
protected override void Initialize(StartupConfig startupConfig)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
public class PrometheusStarter : BaseStarter
|
public class PrometheusStarter : BaseStarter
|
||||||
{
|
{
|
||||||
public PrometheusStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
|
public PrometheusStarter(TestLifecycle lifecycle)
|
||||||
: base(lifecycle, workflowCreator)
|
: base(lifecycle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace DistTestCore
|
||||||
var startupConfig = new StartupConfig();
|
var startupConfig = new StartupConfig();
|
||||||
startupConfig.Add(new PrometheusStartupConfig(GeneratePrometheusConfig(containers.Containers())));
|
startupConfig.Add(new PrometheusStartupConfig(GeneratePrometheusConfig(containers.Containers())));
|
||||||
|
|
||||||
var workflow = workflowCreator.CreateWorkflow();
|
var workflow = lifecycle.WorkflowCreator.CreateWorkflow();
|
||||||
var runningContainers = workflow.Start(1, Location.Unspecified, new PrometheusContainerRecipe(), startupConfig);
|
var runningContainers = workflow.Start(1, Location.Unspecified, new PrometheusContainerRecipe(), startupConfig);
|
||||||
if (runningContainers.Containers.Length != 1) throw new InvalidOperationException("Expected only 1 Prometheus container to be created.");
|
if (runningContainers.Containers.Length != 1) throw new InvalidOperationException("Expected only 1 Prometheus container to be created.");
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using DistTestCore.Codex;
|
using DistTestCore.Codex;
|
||||||
using DistTestCore.Logs;
|
using DistTestCore.Logs;
|
||||||
|
using DistTestCore.Marketplace;
|
||||||
|
using DistTestCore.Metrics;
|
||||||
using KubernetesWorkflow;
|
using KubernetesWorkflow;
|
||||||
using Logging;
|
using Logging;
|
||||||
using Utils;
|
using Utils;
|
||||||
|
@ -10,21 +12,19 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
private readonly DateTime testStart;
|
private readonly DateTime testStart;
|
||||||
|
|
||||||
public TestLifecycle(BaseLog log, Configuration configuration, ITimeSet timeSet)
|
public TestLifecycle(BaseLog log, Configuration configuration, ITimeSet timeSet, string testsType, string testNamespace)
|
||||||
: this(log, configuration, timeSet, new WorkflowCreator(log, configuration.GetK8sConfiguration(timeSet)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestLifecycle(BaseLog log, Configuration configuration, ITimeSet timeSet, WorkflowCreator workflowCreator)
|
|
||||||
{
|
{
|
||||||
Log = log;
|
Log = log;
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
TimeSet = timeSet;
|
TimeSet = timeSet;
|
||||||
|
|
||||||
|
var podLabels = new PodLabels(testsType, GetApplicationIds());
|
||||||
|
WorkflowCreator = new WorkflowCreator(log, configuration.GetK8sConfiguration(timeSet), podLabels, testNamespace);
|
||||||
|
|
||||||
FileManager = new FileManager(Log, configuration);
|
FileManager = new FileManager(Log, configuration);
|
||||||
CodexStarter = new CodexStarter(this, workflowCreator);
|
CodexStarter = new CodexStarter(this);
|
||||||
PrometheusStarter = new PrometheusStarter(this, workflowCreator);
|
PrometheusStarter = new PrometheusStarter(this);
|
||||||
GethStarter = new GethStarter(this, workflowCreator);
|
GethStarter = new GethStarter(this);
|
||||||
testStart = DateTime.UtcNow;
|
testStart = DateTime.UtcNow;
|
||||||
CodexVersion = null;
|
CodexVersion = null;
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ namespace DistTestCore
|
||||||
public BaseLog Log { get; }
|
public BaseLog Log { get; }
|
||||||
public Configuration Configuration { get; }
|
public Configuration Configuration { get; }
|
||||||
public ITimeSet TimeSet { get; }
|
public ITimeSet TimeSet { get; }
|
||||||
|
public WorkflowCreator WorkflowCreator { get; }
|
||||||
public FileManager FileManager { get; }
|
public FileManager FileManager { get; }
|
||||||
public CodexStarter CodexStarter { get; }
|
public CodexStarter CodexStarter { get; }
|
||||||
public PrometheusStarter PrometheusStarter { get; }
|
public PrometheusStarter PrometheusStarter { get; }
|
||||||
|
@ -68,5 +69,23 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
if (CodexVersion == null) CodexVersion = version;
|
if (CodexVersion == null) CodexVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ApplicationIds GetApplicationIds()
|
||||||
|
{
|
||||||
|
return new ApplicationIds(
|
||||||
|
codexId: GetCodexId(),
|
||||||
|
gethId: new GethContainerRecipe().Image,
|
||||||
|
prometheusId: new PrometheusContainerRecipe().Image,
|
||||||
|
codexContractsId: new CodexContractsContainerRecipe().Image
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetCodexId()
|
||||||
|
{
|
||||||
|
var v = CodexVersion;
|
||||||
|
if (v == null) return new CodexContainerRecipe().Image;
|
||||||
|
if (v.version != "untagged build") return v.version;
|
||||||
|
return v.revision;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
return recipe;
|
return recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract string AppName { get; }
|
||||||
public abstract string Image { get; }
|
public abstract string Image { get; }
|
||||||
protected int ContainerNumber { get; private set; } = 0;
|
protected int ContainerNumber { get; private set; } = 0;
|
||||||
protected int Index { get; private set; } = 0;
|
protected int Index { get; private set; } = 0;
|
||||||
|
|
|
@ -11,14 +11,16 @@ namespace KubernetesWorkflow
|
||||||
private readonly K8sCluster cluster;
|
private readonly K8sCluster cluster;
|
||||||
private readonly KnownK8sPods knownPods;
|
private readonly KnownK8sPods knownPods;
|
||||||
private readonly WorkflowNumberSource workflowNumberSource;
|
private readonly WorkflowNumberSource workflowNumberSource;
|
||||||
|
private readonly PodLabels podLabels;
|
||||||
private readonly K8sClient client;
|
private readonly K8sClient client;
|
||||||
|
|
||||||
public K8sController(BaseLog log, K8sCluster cluster, KnownK8sPods knownPods, WorkflowNumberSource workflowNumberSource, string testNamespace)
|
public K8sController(BaseLog log, K8sCluster cluster, KnownK8sPods knownPods, WorkflowNumberSource workflowNumberSource, string testNamespace, PodLabels podLabels)
|
||||||
{
|
{
|
||||||
this.log = log;
|
this.log = log;
|
||||||
this.cluster = cluster;
|
this.cluster = cluster;
|
||||||
this.knownPods = knownPods;
|
this.knownPods = knownPods;
|
||||||
this.workflowNumberSource = workflowNumberSource;
|
this.workflowNumberSource = workflowNumberSource;
|
||||||
|
this.podLabels = podLabels;
|
||||||
client = new K8sClient(cluster.GetK8sClientConfig());
|
client = new K8sClient(cluster.GetK8sClientConfig());
|
||||||
|
|
||||||
K8sTestNamespace = cluster.Configuration.K8sNamespacePrefix + testNamespace;
|
K8sTestNamespace = cluster.Configuration.K8sNamespacePrefix + testNamespace;
|
||||||
|
@ -362,7 +364,7 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
private IDictionary<string, string> GetSelector()
|
private IDictionary<string, string> GetSelector()
|
||||||
{
|
{
|
||||||
return new Dictionary<string, string> { { "codex-test-node", "dist-test-" + workflowNumberSource.WorkflowNumber } };
|
return podLabels.GetLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IDictionary<string, string> GetRunnerNamespaceSelector()
|
private IDictionary<string, string> GetRunnerNamespaceSelector()
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
using Logging;
|
||||||
|
|
||||||
|
namespace KubernetesWorkflow
|
||||||
|
{
|
||||||
|
public class PodLabels
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, string> labels = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
private PodLabels(PodLabels source)
|
||||||
|
{
|
||||||
|
labels = source.labels.ToDictionary(p => p.Key, p => p.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PodLabels(string testsType, ApplicationIds applicationIds)
|
||||||
|
{
|
||||||
|
Add("tests-type", testsType);
|
||||||
|
Add("runid", NameUtils.GetRunId());
|
||||||
|
Add("testid", NameUtils.GetTestId());
|
||||||
|
Add("category", NameUtils.GetCategoryName());
|
||||||
|
Add("fixturename", NameUtils.GetRawFixtureName());
|
||||||
|
Add("testname", NameUtils.GetTestMethodName());
|
||||||
|
|
||||||
|
if (applicationIds == null) return;
|
||||||
|
Add("codexid", applicationIds.CodexId);
|
||||||
|
Add("gethid", applicationIds.GethId);
|
||||||
|
Add("prometheusid", applicationIds.PrometheusId);
|
||||||
|
Add("codexcontractsid", applicationIds.CodexContractsId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PodLabels GetLabelsForAppName(string appName)
|
||||||
|
{
|
||||||
|
var pl = new PodLabels(this);
|
||||||
|
pl.Add("app", appName);
|
||||||
|
return pl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Add(string key, string value)
|
||||||
|
{
|
||||||
|
labels.Add(key,
|
||||||
|
value.ToLowerInvariant()
|
||||||
|
.Replace(":","-")
|
||||||
|
.Replace("/", "-")
|
||||||
|
.Replace("\\", "-")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Dictionary<string, string> GetLabels()
|
||||||
|
{
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,19 +10,23 @@ namespace KubernetesWorkflow
|
||||||
private readonly K8sCluster cluster;
|
private readonly K8sCluster cluster;
|
||||||
private readonly KnownK8sPods knownK8SPods;
|
private readonly KnownK8sPods knownK8SPods;
|
||||||
private readonly string testNamespace;
|
private readonly string testNamespace;
|
||||||
|
private readonly PodLabels podLabels;
|
||||||
private readonly RecipeComponentFactory componentFactory = new RecipeComponentFactory();
|
private readonly RecipeComponentFactory componentFactory = new RecipeComponentFactory();
|
||||||
|
|
||||||
internal StartupWorkflow(BaseLog log, WorkflowNumberSource numberSource, K8sCluster cluster, KnownK8sPods knownK8SPods, string testNamespace)
|
internal StartupWorkflow(BaseLog log, WorkflowNumberSource numberSource, K8sCluster cluster, KnownK8sPods knownK8SPods, string testNamespace, PodLabels podLabels)
|
||||||
{
|
{
|
||||||
this.log = log;
|
this.log = log;
|
||||||
this.numberSource = numberSource;
|
this.numberSource = numberSource;
|
||||||
this.cluster = cluster;
|
this.cluster = cluster;
|
||||||
this.knownK8SPods = knownK8SPods;
|
this.knownK8SPods = knownK8SPods;
|
||||||
this.testNamespace = testNamespace;
|
this.testNamespace = testNamespace;
|
||||||
|
this.podLabels = podLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunningContainers Start(int numberOfContainers, Location location, ContainerRecipeFactory recipeFactory, StartupConfig startupConfig)
|
public RunningContainers Start(int numberOfContainers, Location location, ContainerRecipeFactory recipeFactory, StartupConfig startupConfig)
|
||||||
{
|
{
|
||||||
|
var pl = podLabels.GetLabelsForAppName(recipeFactory.AppName);
|
||||||
|
|
||||||
return K8s(controller =>
|
return K8s(controller =>
|
||||||
{
|
{
|
||||||
var recipes = CreateRecipes(numberOfContainers, recipeFactory, startupConfig);
|
var recipes = CreateRecipes(numberOfContainers, recipeFactory, startupConfig);
|
||||||
|
@ -30,7 +34,7 @@ namespace KubernetesWorkflow
|
||||||
var runningPod = controller.BringOnline(recipes, location);
|
var runningPod = controller.BringOnline(recipes, location);
|
||||||
|
|
||||||
return new RunningContainers(startupConfig, runningPod, CreateContainers(runningPod, recipes, startupConfig));
|
return new RunningContainers(startupConfig, runningPod, CreateContainers(runningPod, recipes, startupConfig));
|
||||||
});
|
}, pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop(RunningContainers runningContainers)
|
public void Stop(RunningContainers runningContainers)
|
||||||
|
@ -147,14 +151,22 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
private void K8s(Action<K8sController> action)
|
private void K8s(Action<K8sController> action)
|
||||||
{
|
{
|
||||||
var controller = new K8sController(log, cluster, knownK8SPods, numberSource, testNamespace);
|
var controller = new K8sController(log, cluster, knownK8SPods, numberSource, testNamespace, podLabels);
|
||||||
action(controller);
|
action(controller);
|
||||||
controller.Dispose();
|
controller.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private T K8s<T>(Func<K8sController, T> action)
|
private T K8s<T>(Func<K8sController, T> action)
|
||||||
{
|
{
|
||||||
var controller = new K8sController(log, cluster, knownK8SPods, numberSource, testNamespace);
|
var controller = new K8sController(log, cluster, knownK8SPods, numberSource, testNamespace, podLabels);
|
||||||
|
var result = action(controller);
|
||||||
|
controller.Dispose();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private T K8s<T>(Func<K8sController, T> action, PodLabels labels)
|
||||||
|
{
|
||||||
|
var controller = new K8sController(log, cluster, knownK8SPods, numberSource, testNamespace, labels);
|
||||||
var result = action(controller);
|
var result = action(controller);
|
||||||
controller.Dispose();
|
controller.Dispose();
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -10,18 +10,15 @@ namespace KubernetesWorkflow
|
||||||
private readonly KnownK8sPods knownPods = new KnownK8sPods();
|
private readonly KnownK8sPods knownPods = new KnownK8sPods();
|
||||||
private readonly K8sCluster cluster;
|
private readonly K8sCluster cluster;
|
||||||
private readonly BaseLog log;
|
private readonly BaseLog log;
|
||||||
|
private readonly PodLabels podLabels;
|
||||||
private readonly string testNamespace;
|
private readonly string testNamespace;
|
||||||
|
|
||||||
public WorkflowCreator(BaseLog log, Configuration configuration)
|
public WorkflowCreator(BaseLog log, Configuration configuration, PodLabels podLabels, string testNamespace)
|
||||||
: this(log, configuration, Guid.NewGuid().ToString().ToLowerInvariant())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorkflowCreator(BaseLog log, Configuration configuration, string testNamespacePostfix)
|
|
||||||
{
|
{
|
||||||
cluster = new K8sCluster(configuration);
|
cluster = new K8sCluster(configuration);
|
||||||
this.log = log;
|
this.log = log;
|
||||||
testNamespace = testNamespacePostfix;
|
this.podLabels = podLabels;
|
||||||
|
this.testNamespace = testNamespace.ToLowerInvariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StartupWorkflow CreateWorkflow()
|
public StartupWorkflow CreateWorkflow()
|
||||||
|
@ -29,7 +26,7 @@ namespace KubernetesWorkflow
|
||||||
var workflowNumberSource = new WorkflowNumberSource(numberSource.GetNextNumber(),
|
var workflowNumberSource = new WorkflowNumberSource(numberSource.GetNextNumber(),
|
||||||
containerNumberSource);
|
containerNumberSource);
|
||||||
|
|
||||||
return new StartupWorkflow(log, workflowNumberSource, cluster, knownPods, testNamespace);
|
return new StartupWorkflow(log, workflowNumberSource, cluster, knownPods, testNamespace, podLabels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
public class ApplicationIds
|
||||||
|
{
|
||||||
|
public ApplicationIds(string codexId, string gethId, string prometheusId, string codexContractsId)
|
||||||
|
{
|
||||||
|
CodexId = codexId;
|
||||||
|
GethId = gethId;
|
||||||
|
PrometheusId = prometheusId;
|
||||||
|
CodexContractsId = codexContractsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CodexId { get; }
|
||||||
|
public string GethId { get; }
|
||||||
|
public string PrometheusId { get; }
|
||||||
|
public string CodexContractsId { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ namespace Logging
|
||||||
public static string GetRawFixtureName()
|
public static string GetRawFixtureName()
|
||||||
{
|
{
|
||||||
var test = TestContext.CurrentContext.Test;
|
var test = TestContext.CurrentContext.Test;
|
||||||
|
if (test.ClassName!.Contains("AdhocContext")) return "none";
|
||||||
var className = test.ClassName!.Substring(test.ClassName.LastIndexOf('.') + 1);
|
var className = test.ClassName!.Substring(test.ClassName.LastIndexOf('.') + 1);
|
||||||
return className.Replace('.', '-');
|
return className.Replace('.', '-');
|
||||||
}
|
}
|
||||||
|
@ -29,6 +30,7 @@ namespace Logging
|
||||||
public static string GetCategoryName()
|
public static string GetCategoryName()
|
||||||
{
|
{
|
||||||
var test = TestContext.CurrentContext.Test;
|
var test = TestContext.CurrentContext.Test;
|
||||||
|
if (test.ClassName!.Contains("AdhocContext")) return "none";
|
||||||
return test.ClassName!.Substring(0, test.ClassName.LastIndexOf('.'));
|
return test.ClassName!.Substring(0, test.ClassName.LastIndexOf('.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +47,7 @@ namespace Logging
|
||||||
private static string GetEnvVar(string name)
|
private static string GetEnvVar(string name)
|
||||||
{
|
{
|
||||||
var v = Environment.GetEnvironmentVariable(name);
|
var v = Environment.GetEnvironmentVariable(name);
|
||||||
if (string.IsNullOrEmpty(v)) return $"EnvVar'{name}'NotSet";
|
if (string.IsNullOrEmpty(v)) return $"EnvVar-{name}-NotSet";
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Logging
|
||||||
fixtureName = NameUtils.GetRawFixtureName();
|
fixtureName = NameUtils.GetRawFixtureName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConcludeTest(string resultStatus, string testDuration, string codexId)
|
public void ConcludeTest(string resultStatus, string testDuration, ApplicationIds applicationIds)
|
||||||
{
|
{
|
||||||
Write(new StatusLogJson
|
Write(new StatusLogJson
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,10 @@ namespace Logging
|
||||||
runid = NameUtils.GetRunId(),
|
runid = NameUtils.GetRunId(),
|
||||||
status = resultStatus,
|
status = resultStatus,
|
||||||
testid = NameUtils.GetTestId(),
|
testid = NameUtils.GetTestId(),
|
||||||
codexid = codexId,
|
codexid = applicationIds.CodexId,
|
||||||
|
gethid = applicationIds.GethId,
|
||||||
|
prometheusid = applicationIds.PrometheusId,
|
||||||
|
codexcontractsid = applicationIds.CodexContractsId,
|
||||||
category = NameUtils.GetCategoryName(),
|
category = NameUtils.GetCategoryName(),
|
||||||
fixturename = fixtureName,
|
fixturename = fixtureName,
|
||||||
testname = NameUtils.GetTestMethodName(),
|
testname = NameUtils.GetTestMethodName(),
|
||||||
|
@ -53,6 +56,9 @@ namespace Logging
|
||||||
public string status { get; set; } = string.Empty;
|
public string status { get; set; } = string.Empty;
|
||||||
public string testid { get; set; } = string.Empty;
|
public string testid { get; set; } = string.Empty;
|
||||||
public string codexid { get; set; } = string.Empty;
|
public string codexid { get; set; } = string.Empty;
|
||||||
|
public string gethid { get; set; } = string.Empty;
|
||||||
|
public string prometheusid { get; set; } = string.Empty;
|
||||||
|
public string codexcontractsid { get; set; } = string.Empty;
|
||||||
public string category { get; set; } = string.Empty;
|
public string category { get; set; } = string.Empty;
|
||||||
public string fixturename { get; set; } = string.Empty;
|
public string fixturename { get; set; } = string.Empty;
|
||||||
public string testname { get; set; } = string.Empty;
|
public string testname { get; set; } = string.Empty;
|
||||||
|
|
Loading…
Reference in New Issue