Compare commits

...
Author SHA1 Message Date
benbierens 77cdd3e2d8 Merge branch 'master' into feature/waku-plugin
# Conflicts:
#	Framework/KubernetesWorkflow/Recipe/ContainerRecipeFactory.cs
#	cs-codex-dist-testing.sln
2024-04-09 08:19:34 +02:00
benbierens 3776f46c02 Setting up basic test for waku 2023-09-25 15:43:16 +02:00
benbierens 12f6710a56 Bootstrapping waku nodes 2023-09-25 15:14:51 +02:00
benbierens 30ba382db7 Can start waku node 2023-09-25 13:02:44 +02:00
benbierens ab4f4695cb Setup waku plugin and test 2023-09-25 10:16:34 +02:00
14 changed files with 375 additions and 1 deletions
@@ -73,6 +73,13 @@ namespace KubernetesWorkflow.Recipe
return p;
}
protected Port AddInternalPort(int number, string tag = "", PortProtocol protocol = PortProtocol.TCP)
{
var p = factory.CreateInternalPort(number, tag, protocol);
internalPorts.Add(p);
return p;
}
protected void AddExposedPortAndVar(string name, string tag, PortProtocol protocol = PortProtocol.TCP)
{
AddEnvVar(name, AddExposedPort(tag, protocol));
@@ -16,7 +16,12 @@ namespace KubernetesWorkflow.Recipe
public Port CreateInternalPort(string tag, PortProtocol protocol)
{
return new Port(internalNumberSource.GetNextNumber(), tag, protocol);
return CreateInternalPort(internalNumberSource.GetNextNumber(), tag, protocol);
}
public Port CreateInternalPort(int number, string tag, PortProtocol protocol)
{
return new Port(number, tag, protocol);
}
public Port CreateExternalPort(int number, string tag, PortProtocol protocol)
@@ -0,0 +1,34 @@
using Core;
using KubernetesWorkflow.Types;
namespace WakuPlugin
{
public static class CoreInterfaceExtensions
{
public static RunningContainers[] DeployWakuNodes(this CoreInterface ci, int number, Action<IWakuSetup> setup)
{
return Plugin(ci).DeployWakuNodes(number, setup);
}
public static IWakuNode WrapWakuContainer(this CoreInterface ci, RunningContainer container)
{
return Plugin(ci).WrapWakuContainer(container);
}
public static IWakuNode StartWakuNode(this CoreInterface ci)
{
return ci.StartWakuNode(s => { });
}
public static IWakuNode StartWakuNode(this CoreInterface ci, Action<IWakuSetup> setup)
{
var rc = ci.DeployWakuNodes(1, setup);
return ci.WrapWakuContainer(rc.First().Containers.First());
}
private static WakuPlugin Plugin(CoreInterface ci)
{
return ci.GetPlugin<WakuPlugin>();
}
}
}
@@ -0,0 +1,8 @@
namespace WakuPlugin
{
public class DebugInfoResponse
{
public string[] listenAddresses { get; set; } = Array.Empty<string>();
public string enrUri { get; set; } = string.Empty;
}
}
@@ -0,0 +1,38 @@
using KubernetesWorkflow;
using KubernetesWorkflow.Recipe;
using Utils;
namespace WakuPlugin
{
public class WakuContainerRecipe : ContainerRecipeFactory
{
public override string AppName => "waku";
//public override string Image => "statusteam/nim-waku:deploy-wakuv2-test";
public override string Image => "thatbenbierens/nim-waku:try";
public static string RestPortTag = "REST_PORT";
protected override void Initialize(StartupConfig startupConfig)
{
var config = startupConfig.Get<WakuSetup>();
SetResourcesRequest(milliCPUs: 100, memory: 100.MB());
AddEnvVar("WAKUNODE2_LOG_LEVEL", "TRACE");
AddEnvVar("WAKUNODE2_REST", "1");
AddExposedPortAndVar("WAKUNODE2_REST_PORT", RestPortTag);
AddEnvVar("WAKUNODE2_REST_ADDRESS", "0.0.0.0");
AddInternalPortAndVar("WAKUNODE2_TCP_PORT");
AddEnvVar("WAKUNODE2_RPC_ADDRESS", "0.0.0.0");
AddEnvVar("WAKUNODE2_DISCV5_DISCOVERY", "1");
AddInternalPortAndVar("WAKUNODE2_DISCV5_UDP_PORT");
AddEnvVar("WAKUNODE2_DISCV5_ENR_AUTO_UPDATEY", "1");
if (!string.IsNullOrEmpty(config.BootstrapEnr))
{
AddEnvVar("WAKUNODE2_DISCV5_BOOTSTRAP_NODE", config.BootstrapEnr);
}
}
}
}
+53
View File
@@ -0,0 +1,53 @@
using Core;
using KubernetesWorkflow.Types;
namespace WakuPlugin
{
public interface IWakuNode : IHasContainer
{
DebugInfoResponse DebugInfo();
void SubscribeToTopic(string topic);
void SendMessage(string topic, string message);
string[] GetMessages(string topic);
}
public class WakuNode : IWakuNode
{
private readonly IPluginTools tools;
public WakuNode(IPluginTools tools, RunningContainer container)
{
this.tools = tools;
Container = container;
}
public RunningContainer Container { get; }
public DebugInfoResponse DebugInfo()
{
return Api().HttpGetJson<DebugInfoResponse>("debug/v1/info");
}
public void SubscribeToTopic(string topic)
{
var response = Api().HttpPostString<string>(route: "relay/v1/subscriptions", body: topic);
}
public void SendMessage(string topic, string message)
{
var response = Api().HttpPostString<string>($"relay/v1/messages/{topic}", message);
}
public string[] GetMessages(string topic)
{
var response = Api().HttpGetString($"relay/v1/messages/{topic}");
return new[] { "" };
}
private IEndpoint Api()
{
var address = Container.GetAddress(tools.GetLog(), WakuContainerRecipe.RestPortTag);
return tools.CreateHttp().CreateEndpoint(address, "", logAlias: "waku");
}
}
}
+71
View File
@@ -0,0 +1,71 @@
using Core;
using KubernetesWorkflow.Types;
namespace WakuPlugin
{
public class WakuPlugin : IProjectPlugin, IHasLogPrefix, IHasMetadata
{
private readonly IPluginTools tools;
private readonly WakuStarter starter;
public WakuPlugin(IPluginTools tools)
{
this.tools = tools;
starter = new WakuStarter(tools);
}
public string LogPrefix => "(Waku) ";
public void Announce()
{
tools.GetLog().Log($"Loaded with Waku plugin.");
}
public void AddMetadata(IAddMetadata metadata)
{
//metadata.Add("codexid", codexStarter.GetCodexId());
}
public void Decommission()
{
}
public RunningContainers[] DeployWakuNodes(int numberOfNodes, Action<IWakuSetup> setup)
{
return starter.Start(numberOfNodes, setup);
}
public IWakuNode WrapWakuContainer(RunningContainer container)
{
container = SerializeGate.Gate(container);
return starter.Wrap(container);
}
//public ICodexNodeGroup WrapCodexContainers(CoreInterface coreInterface, RunningContainers[] containers)
//{
// containers = containers.Select(c => SerializeGate.Gate(c)).ToArray();
// return codexStarter.WrapCodexContainers(coreInterface, containers);
//}
//public void WireUpMarketplace(ICodexNodeGroup result, Action<ICodexSetup> setup)
//{
// var codexSetup = GetSetup(1, setup);
// if (codexSetup.MarketplaceConfig == null) return;
// var mconfig = codexSetup.MarketplaceConfig;
// foreach (var node in result)
// {
// mconfig.GethNode.SendEth(node, mconfig.InitialEth);
// mconfig.CodexContracts.MintTestTokens(mconfig.GethNode, node, mconfig.InitialTokens);
// }
//}
//private CodexSetup GetSetup(int numberOfNodes, Action<ICodexSetup> setup)
//{
// var codexSetup = new CodexSetup(numberOfNodes);
// codexSetup.LogLevel = defaultLogLevel;
// setup(codexSetup);
// return codexSetup;
//}
}
}
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Framework\Core\Core.csproj" />
</ItemGroup>
</Project>
+26
View File
@@ -0,0 +1,26 @@
namespace WakuPlugin
{
public interface IWakuSetup
{
IWakuSetup WithName(string name);
IWakuSetup WithBootstrapNode(IWakuNode node);
}
public class WakuSetup : IWakuSetup
{
internal string? Name { get; private set; }
internal string? BootstrapEnr { get; private set; }
public IWakuSetup WithName(string name)
{
Name = name;
return this;
}
public IWakuSetup WithBootstrapNode(IWakuNode node)
{
BootstrapEnr = node.DebugInfo().enrUri;
return this;
}
}
}
+45
View File
@@ -0,0 +1,45 @@
using Core;
using KubernetesWorkflow;
using KubernetesWorkflow.Types;
namespace WakuPlugin
{
public class WakuStarter
{
private readonly IPluginTools tools;
public WakuStarter(IPluginTools tools)
{
this.tools = tools;
}
public RunningContainers[] Start(int numberOfNodes, Action<IWakuSetup> setup)
{
var result = new List<RunningContainers>();
var workflow = tools.CreateWorkflow();
var startupConfig = CreateStartupConfig(setup);
for (var i = 0; i < numberOfNodes; i++)
{
result.Add(workflow.Start(1, new WakuContainerRecipe(), startupConfig));
}
return result.ToArray();
}
public IWakuNode Wrap(RunningContainer container)
{
return new WakuNode(tools, container);
}
private StartupConfig CreateStartupConfig(Action<IWakuSetup> setup)
{
var config = new WakuSetup();
setup(config);
var startupConfig = new StartupConfig();
startupConfig.Add(config);
startupConfig.NameOverride = config.Name;
return startupConfig;
}
}
}
+27
View File
@@ -0,0 +1,27 @@
using NUnit.Framework;
using WakuPlugin;
namespace WakuTests
{
public class BasicTests : WakuDistTest
{
[Test]
public void Hi()
{
var bootNode = Ci.StartWakuNode(s => s.WithName("BootstrapNode"));
var node = Ci.StartWakuNode(s => s.WithName("Waku1").WithBootstrapNode(bootNode));
var topic = "cheeseWheels";
var message = "hmm, cheese...";
bootNode.SubscribeToTopic(topic);
node.SubscribeToTopic(topic);
node.SendMessage(topic, message);
var received = bootNode.GetMessages(topic);
CollectionAssert.Contains(received, message);
}
}
}
+13
View File
@@ -0,0 +1,13 @@
using Core;
using DistTestCore;
namespace WakuTests
{
public class WakuDistTest : DistTest
{
public WakuDistTest()
{
ProjectPlugin.Load<WakuPlugin.WakuPlugin>();
}
}
}
+20
View File
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ProjectPlugins\WakuPlugin\WakuPlugin.csproj" />
<ProjectReference Include="..\..\Tests\DistTestCore\DistTestCore.csproj" />
</ItemGroup>
</Project>
+14
View File
@@ -66,6 +66,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WakuTests", "Tests\WakuTests\WakuTests.csproj", "{DF69D56E-854E-45CD-B130-76386B5BB959}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WakuPlugin", "ProjectPlugins\WakuPlugin\WakuPlugin.csproj", "{2DB199E1-78D3-4A69-9773-C522F7D2FE69}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -172,6 +176,14 @@ Global
{88C212E9-308A-46A4-BAAD-468E8EBD8EDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88C212E9-308A-46A4-BAAD-468E8EBD8EDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88C212E9-308A-46A4-BAAD-468E8EBD8EDF}.Release|Any CPU.Build.0 = Release|Any CPU
{DF69D56E-854E-45CD-B130-76386B5BB959}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF69D56E-854E-45CD-B130-76386B5BB959}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF69D56E-854E-45CD-B130-76386B5BB959}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF69D56E-854E-45CD-B130-76386B5BB959}.Release|Any CPU.Build.0 = Release|Any CPU
{2DB199E1-78D3-4A69-9773-C522F7D2FE69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DB199E1-78D3-4A69-9773-C522F7D2FE69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DB199E1-78D3-4A69-9773-C522F7D2FE69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DB199E1-78D3-4A69-9773-C522F7D2FE69}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -202,6 +214,8 @@ Global
{F730DA73-1C92-4107-BCFB-D33759DAB0C3} = {81AE04BC-CBFA-4E6F-B039-8208E9AFAAE7}
{B07820C4-309F-4454-BCC1-1D4902C9C67B} = {81AE04BC-CBFA-4E6F-B039-8208E9AFAAE7}
{88C212E9-308A-46A4-BAAD-468E8EBD8EDF} = {8F1F1C2A-E313-4E0C-BE40-58FB0BA91124}
{DF69D56E-854E-45CD-B130-76386B5BB959} = {88C2A621-8A98-4D07-8625-7900FC8EF89E}
{2DB199E1-78D3-4A69-9773-C522F7D2FE69} = {8F1F1C2A-E313-4E0C-BE40-58FB0BA91124}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {237BF0AA-9EC4-4659-AD9A-65DEB974250C}