Adds peer connectivity check after deployment

This commit is contained in:
benbierens 2023-08-24 11:32:32 +02:00
parent 7eda26d177
commit eec70a9b8c
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
8 changed files with 103 additions and 23 deletions

View File

@ -21,7 +21,7 @@ namespace CodexNetDeployer
validatorsLeft = numberOfValidators; validatorsLeft = numberOfValidators;
} }
public RunningContainer? Start(int i) public CodexNodeStartResult? Start(int i)
{ {
Console.Write($" - {i} = "); Console.Write($" - {i} = ");
var workflow = lifecycle.WorkflowCreator.CreateWorkflow(); var workflow = lifecycle.WorkflowCreator.CreateWorkflow();
@ -60,7 +60,7 @@ namespace CodexNetDeployer
if (string.IsNullOrEmpty(bootstrapSpr)) bootstrapSpr = debugInfo.spr; if (string.IsNullOrEmpty(bootstrapSpr)) bootstrapSpr = debugInfo.spr;
validatorsLeft--; validatorsLeft--;
return container; return new CodexNodeStartResult(container, codexAccess);
} }
} }
} }
@ -102,4 +102,16 @@ namespace CodexNetDeployer
return codexStart; return codexStart;
} }
} }
public class CodexNodeStartResult
{
public CodexNodeStartResult(RunningContainer container, CodexAccess access)
{
Container = container;
Access = access;
}
public RunningContainer Container { get; }
public CodexAccess Access { get; }
}
} }

View File

@ -58,6 +58,9 @@ namespace CodexNetDeployer
"set this option to override the label value.")] "set this option to override the label value.")]
public string TestsTypePodLabel { get; set; } = "continuous-tests"; public string TestsTypePodLabel { get; set; } = "continuous-tests";
[Uniform("check-connect", "cc", "CHECKCONNECT", false, "If true, deployer check ensure peer-connectivity between all deployed nodes after deployment.")]
public bool CheckPeerConnection { get; set; } = false;
public List<string> Validate() public List<string> Validate()
{ {
var errors = new List<string>(); var errors = new List<string>();

View File

@ -8,14 +8,14 @@ namespace CodexNetDeployer
public class Deployer public class Deployer
{ {
private readonly Configuration config; private readonly Configuration config;
private readonly NullLog log;
private readonly DefaultTimeSet timeset; private readonly DefaultTimeSet timeset;
private readonly PeerConnectivityChecker peerConnectivityChecker;
public Deployer(Configuration config) public Deployer(Configuration config)
{ {
this.config = config; this.config = config;
log = new NullLog();
timeset = new DefaultTimeSet(); timeset = new DefaultTimeSet();
peerConnectivityChecker = new PeerConnectivityChecker();
} }
public CodexDeployment Deploy() public CodexDeployment Deploy()
@ -45,16 +45,18 @@ namespace CodexNetDeployer
// 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, lifecycle, gethResults, config.NumberOfValidators!.Value); var codexStarter = new CodexNodeStarter(config, lifecycle, gethResults, config.NumberOfValidators!.Value);
var codexContainers = new List<RunningContainer>(); var startResults = new List<CodexNodeStartResult>();
for (var i = 0; i < config.NumberOfCodexNodes; i++) for (var i = 0; i < config.NumberOfCodexNodes; i++)
{ {
var container = codexStarter.Start(i); var result = codexStarter.Start(i);
if (container != null) codexContainers.Add(container); if (result != null) startResults.Add(result);
} }
var (prometheusContainer, grafanaStartInfo) = StartMetricsService(lifecycle, setup, codexContainers); var (prometheusContainer, grafanaStartInfo) = StartMetricsService(lifecycle, setup, startResults.Select(r => r.Container));
return new CodexDeployment(gethResults, codexContainers.ToArray(), prometheusContainer, grafanaStartInfo, CreateMetadata()); CheckPeerConnectivity(startResults);
return new CodexDeployment(gethResults, startResults.Select(r => r.Container).ToArray(), prometheusContainer, grafanaStartInfo, CreateMetadata());
} }
private TestLifecycle CreateTestLifecycle() private TestLifecycle CreateTestLifecycle()
@ -71,10 +73,10 @@ namespace CodexNetDeployer
k8sNamespacePrefix: config.KubeNamespace k8sNamespacePrefix: config.KubeNamespace
); );
return new TestLifecycle(log, lifecycleConfig, timeset, config.TestsTypePodLabel, string.Empty); return new TestLifecycle(new NullLog(), lifecycleConfig, timeset, config.TestsTypePodLabel, string.Empty);
} }
private (RunningContainer?, GrafanaStartInfo?) StartMetricsService(TestLifecycle lifecycle, CodexSetup setup, List<RunningContainer> codexContainers) private (RunningContainer?, GrafanaStartInfo?) StartMetricsService(TestLifecycle lifecycle, CodexSetup setup, IEnumerable<RunningContainer> codexContainers)
{ {
if (setup.MetricsMode == DistTestCore.Metrics.MetricsMode.None) return (null, null); if (setup.MetricsMode == DistTestCore.Metrics.MetricsMode.None) return (null, null);
@ -95,6 +97,15 @@ namespace CodexNetDeployer
return kubeConfigFile; return kubeConfigFile;
} }
private void CheckPeerConnectivity(List<CodexNodeStartResult> codexContainers)
{
if (!config.CheckPeerConnection) return;
Log("Starting peer-connectivity check for deployed nodes...");
peerConnectivityChecker.CheckConnectivity(codexContainers);
Log("Check passed.");
}
private DeploymentMetadata CreateMetadata() private DeploymentMetadata CreateMetadata()
{ {
return new DeploymentMetadata( return new DeploymentMetadata(

View File

@ -0,0 +1,34 @@
using DistTestCore.Helpers;
using Logging;
namespace CodexNetDeployer
{
public class PeerConnectivityChecker
{
public void CheckConnectivity(List<CodexNodeStartResult> startResults)
{
var checker = new PeerConnectionTestHelpers(new ConsoleLogger());
var access = startResults.Select(r => r.Access);
checker.AssertFullyConnected(access);
}
}
public class ConsoleLogger : BaseLog
{
public ConsoleLogger() : base(false)
{
}
protected override string GetFullName()
{
return "CONSOLE";
}
public override void Log(string message)
{
Console.WriteLine(message);
}
}
}

View File

@ -88,6 +88,11 @@ namespace DistTestCore.Codex
return Http().HttpGetString($"connect/{peerId}?addrs={peerMultiAddress}"); return Http().HttpGetString($"connect/{peerId}?addrs={peerMultiAddress}");
} }
public string GetName()
{
return Container.Name;
}
private Http Http() private Http Http()
{ {
CheckContainerCrashed(); CheckContainerCrashed();

View File

@ -24,12 +24,12 @@ namespace DistTestCore.Helpers
this.implementation = implementation; this.implementation = implementation;
} }
public void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes) public void AssertFullyConnected(IEnumerable<CodexAccess> nodes)
{ {
AssertFullyConnected(nodes.ToArray()); AssertFullyConnected(nodes.ToArray());
} }
private void AssertFullyConnected(IOnlineCodexNode[] nodes) private void AssertFullyConnected(CodexAccess[] nodes)
{ {
Log($"Asserting '{implementation.Description()}' for nodes: '{string.Join(",", nodes.Select(n => n.GetName()))}'..."); Log($"Asserting '{implementation.Description()}' for nodes: '{string.Join(",", nodes.Select(n => n.GetName()))}'...");
var entries = CreateEntries(nodes); var entries = CreateEntries(nodes);
@ -85,7 +85,7 @@ namespace DistTestCore.Helpers
Log($"Connections successful:{Nl}{string.Join(Nl, pairDetails)}"); Log($"Connections successful:{Nl}{string.Join(Nl, pairDetails)}");
} }
private Entry[] CreateEntries(IOnlineCodexNode[] nodes) private Entry[] CreateEntries(CodexAccess[] nodes)
{ {
var entries = nodes.Select(n => new Entry(n)).ToArray(); var entries = nodes.Select(n => new Entry(n)).ToArray();
@ -125,13 +125,13 @@ namespace DistTestCore.Helpers
public class Entry public class Entry
{ {
public Entry(IOnlineCodexNode node) public Entry(CodexAccess node)
{ {
Node = node; Node = node;
Response = node.GetDebugInfo(); Response = node.GetDebugInfo();
} }
public IOnlineCodexNode Node { get; } public CodexAccess Node { get; }
public CodexDebugResponse Response { get; } public CodexDebugResponse Response { get; }
public override string ToString() public override string ToString()

View File

@ -14,6 +14,11 @@ namespace DistTestCore.Helpers
} }
public void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes) public void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes)
{
AssertFullyConnected(nodes.Select(n => ((OnlineCodexNode)n).CodexAccess));
}
public void AssertFullyConnected(IEnumerable<CodexAccess> nodes)
{ {
helper.AssertFullyConnected(nodes); helper.AssertFullyConnected(nodes);
} }
@ -58,9 +63,8 @@ namespace DistTestCore.Helpers
var peer = allEntries.SingleOrDefault(e => e.Response.table.localNode.peerId == node.peerId); var peer = allEntries.SingleOrDefault(e => e.Response.table.localNode.peerId == node.peerId);
if (peer == null) return $"peerId: {node.peerId} is not known."; if (peer == null) return $"peerId: {node.peerId} is not known.";
var n = (OnlineCodexNode)peer.Node; var ip = peer.Node.Container.Pod.PodInfo.Ip;
var ip = n.CodexAccess.Container.Pod.PodInfo.Ip; var discPort = peer.Node.Container.Recipe.GetPortByTag(CodexContainerRecipe.DiscoveryPortTag);
var discPort = n.CodexAccess.Container.Recipe.GetPortByTag(CodexContainerRecipe.DiscoveryPortTag);
return $"{ip}:{discPort.Number}"; return $"{ip}:{discPort.Number}";
} }
} }

View File

@ -1,4 +1,5 @@
using Logging; using DistTestCore.Codex;
using Logging;
using static DistTestCore.Helpers.FullConnectivityHelper; using static DistTestCore.Helpers.FullConnectivityHelper;
namespace DistTestCore.Helpers namespace DistTestCore.Helpers
@ -17,6 +18,11 @@ namespace DistTestCore.Helpers
} }
public void AssertFullDownloadInterconnectivity(IEnumerable<IOnlineCodexNode> nodes, ByteSize testFileSize) public void AssertFullDownloadInterconnectivity(IEnumerable<IOnlineCodexNode> nodes, ByteSize testFileSize)
{
AssertFullDownloadInterconnectivity(nodes.Select(n => ((OnlineCodexNode)n).CodexAccess), testFileSize);
}
public void AssertFullDownloadInterconnectivity(IEnumerable<CodexAccess> nodes, ByteSize testFileSize)
{ {
this.testFileSize = testFileSize; this.testFileSize = testFileSize;
helper.AssertFullyConnected(nodes); helper.AssertFullyConnected(nodes);
@ -37,11 +43,16 @@ namespace DistTestCore.Helpers
fileManager.PushFileSet(); fileManager.PushFileSet();
var expectedFile = GenerateTestFile(from.Node, to.Node); var expectedFile = GenerateTestFile(from.Node, to.Node);
var contentId = from.Node.UploadFile(expectedFile); using var uploadStream = File.OpenRead(expectedFile.Filename);
var contentId = from.Node.UploadFile(uploadStream);
try try
{ {
var downloadedFile = to.Node.DownloadContent(contentId, expectedFile.Label + "_downloaded"); var downloadedFile = fileManager.CreateEmptyTestFile(expectedFile.Label + "_downloaded");
using var downloadStream = File.OpenWrite(downloadedFile.Filename);
using var stream = to.Node.DownloadFile(contentId);
stream.CopyTo(downloadStream);
expectedFile.AssertIsEqual(downloadedFile); expectedFile.AssertIsEqual(downloadedFile);
return PeerConnectionState.Connection; return PeerConnectionState.Connection;
} }
@ -59,7 +70,7 @@ namespace DistTestCore.Helpers
// Should an exception occur during upload, then this try is inconclusive and we try again next loop. // Should an exception occur during upload, then this try is inconclusive and we try again next loop.
} }
private TestFile GenerateTestFile(IOnlineCodexNode uploader, IOnlineCodexNode downloader) private TestFile GenerateTestFile(CodexAccess uploader, CodexAccess downloader)
{ {
var up = uploader.GetName().Replace("<", "").Replace(">", ""); var up = uploader.GetName().Replace("<", "").Replace(">", "");
var down = downloader.GetName().Replace("<", "").Replace(">", ""); var down = downloader.GetName().Replace("<", "").Replace(">", "");