OneClient test passed
This commit is contained in:
parent
bb81d7f037
commit
f5c60f0bca
|
@ -4,13 +4,13 @@ namespace DistTestCore.Codex
|
||||||
{
|
{
|
||||||
public class CodexAccess
|
public class CodexAccess
|
||||||
{
|
{
|
||||||
private readonly RunningContainer runningContainer;
|
|
||||||
|
|
||||||
public CodexAccess(RunningContainer runningContainer)
|
public CodexAccess(RunningContainer runningContainer)
|
||||||
{
|
{
|
||||||
this.runningContainer = runningContainer;
|
Container = runningContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RunningContainer Container { get; }
|
||||||
|
|
||||||
public CodexDebugResponse GetDebugInfo()
|
public CodexDebugResponse GetDebugInfo()
|
||||||
{
|
{
|
||||||
var response = Http().HttpGetJson<CodexDebugResponse>("debug/info");
|
var response = Http().HttpGetJson<CodexDebugResponse>("debug/info");
|
||||||
|
@ -18,12 +18,27 @@ namespace DistTestCore.Codex
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string UploadFile(FileStream fileStream)
|
||||||
|
{
|
||||||
|
return Http().HttpPostStream("upload", fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream DownloadFile(string contentId)
|
||||||
|
{
|
||||||
|
return Http().HttpGetStream("download/" + contentId);
|
||||||
|
}
|
||||||
|
|
||||||
private Http Http()
|
private Http Http()
|
||||||
{
|
{
|
||||||
var ip = runningContainer.Pod.Cluster.GetIp();
|
var ip = Container.Pod.Cluster.GetIp();
|
||||||
var port = runningContainer.ServicePorts[0].Number;
|
var port = Container.ServicePorts[0].Number;
|
||||||
return new Http(ip, port, baseUrl: "/api/codex/v1");
|
return new Http(ip, port, baseUrl: "/api/codex/v1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ConnectToPeer(string peerId, string peerMultiAddress)
|
||||||
|
{
|
||||||
|
return Http().HttpGetString($"connect/{peerId}?addrs={peerMultiAddress}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CodexDebugResponse
|
public class CodexDebugResponse
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace DistTestCore.Codex
|
using KubernetesWorkflow;
|
||||||
|
|
||||||
|
namespace DistTestCore.Codex
|
||||||
{
|
{
|
||||||
public class CodexStartupConfig
|
public class CodexStartupConfig
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
using DistTestCore.Codex;
|
||||||
|
using KubernetesWorkflow;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace DistTestCore
|
||||||
|
{
|
||||||
|
public interface ICodexNodeGroup : IEnumerable<IOnlineCodexNode>
|
||||||
|
{
|
||||||
|
//ICodexSetup BringOffline();
|
||||||
|
IOnlineCodexNode this[int index] { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CodexNodeGroup : ICodexNodeGroup
|
||||||
|
{
|
||||||
|
private readonly TestLifecycle lifecycle;
|
||||||
|
|
||||||
|
public CodexNodeGroup(TestLifecycle lifecycle, CodexSetup setup, RunningContainers containers)
|
||||||
|
{
|
||||||
|
this.lifecycle = lifecycle;
|
||||||
|
Setup = setup;
|
||||||
|
Containers = containers;
|
||||||
|
Nodes = containers.Containers.Select(c => CreateOnlineCodexNode(c)).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IOnlineCodexNode this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Nodes[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//public ICodexSetup BringOffline()
|
||||||
|
//{
|
||||||
|
// //return k8SManager.BringOffline(this);
|
||||||
|
//}
|
||||||
|
|
||||||
|
public CodexSetup Setup { get; }
|
||||||
|
public RunningContainers Containers { get; }
|
||||||
|
public OnlineCodexNode[] Nodes { get; }
|
||||||
|
|
||||||
|
//public GethCompanionGroup? GethCompanionGroup { get; set; }
|
||||||
|
|
||||||
|
//public CodexNodeContainer[] GetContainers()
|
||||||
|
//{
|
||||||
|
// return Nodes.Select(n => n.Container).ToArray();
|
||||||
|
//}
|
||||||
|
|
||||||
|
public IEnumerator<IOnlineCodexNode> GetEnumerator()
|
||||||
|
{
|
||||||
|
return Nodes.Cast<IOnlineCodexNode>().GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return Nodes.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
//public CodexNodeLog DownloadLog(IOnlineCodexNode node)
|
||||||
|
//{
|
||||||
|
// var logDownloader = new PodLogDownloader(log, k8SManager);
|
||||||
|
// var n = (OnlineCodexNode)node;
|
||||||
|
// return logDownloader.DownloadLog(n);
|
||||||
|
//}
|
||||||
|
|
||||||
|
public string Describe()
|
||||||
|
{
|
||||||
|
var orderNumber = Containers.RunningPod.Ip;
|
||||||
|
return $"CodexNodeGroup@{orderNumber}-{Setup.Describe()}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private OnlineCodexNode CreateOnlineCodexNode(RunningContainer c)
|
||||||
|
{
|
||||||
|
var access = new CodexAccess(c);
|
||||||
|
return new OnlineCodexNode(lifecycle, access, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,24 +3,24 @@ using KubernetesWorkflow;
|
||||||
|
|
||||||
namespace DistTestCore
|
namespace DistTestCore
|
||||||
{
|
{
|
||||||
public interface ICodexSetupConfig
|
public interface ICodexSetup
|
||||||
{
|
{
|
||||||
ICodexSetupConfig At(Location location);
|
ICodexSetup At(Location location);
|
||||||
ICodexSetupConfig WithLogLevel(CodexLogLevel level);
|
ICodexSetup WithLogLevel(CodexLogLevel level);
|
||||||
//ICodexStartupConfig WithBootstrapNode(IOnlineCodexNode node);
|
//ICodexStartupConfig WithBootstrapNode(IOnlineCodexNode node);
|
||||||
ICodexSetupConfig WithStorageQuota(ByteSize storageQuota);
|
ICodexSetup WithStorageQuota(ByteSize storageQuota);
|
||||||
ICodexSetupConfig EnableMetrics();
|
ICodexSetup EnableMetrics();
|
||||||
//ICodexSetupConfig EnableMarketplace(int initialBalance);
|
//ICodexSetupConfig EnableMarketplace(int initialBalance);
|
||||||
ICodexNodeGroup BringOnline();
|
ICodexNodeGroup BringOnline();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CodexSetupConfig : CodexStartupConfig, ICodexSetupConfig
|
public class CodexSetup : CodexStartupConfig, ICodexSetup
|
||||||
{
|
{
|
||||||
private readonly CodexStarter starter;
|
private readonly CodexStarter starter;
|
||||||
|
|
||||||
public int NumberOfNodes { get; }
|
public int NumberOfNodes { get; }
|
||||||
|
|
||||||
public CodexSetupConfig(CodexStarter starter, int numberOfNodes)
|
public CodexSetup(CodexStarter starter, int numberOfNodes)
|
||||||
{
|
{
|
||||||
this.starter = starter;
|
this.starter = starter;
|
||||||
NumberOfNodes = numberOfNodes;
|
NumberOfNodes = numberOfNodes;
|
||||||
|
@ -31,7 +31,7 @@ namespace DistTestCore
|
||||||
return starter.BringOnline(this);
|
return starter.BringOnline(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICodexSetupConfig At(Location location)
|
public ICodexSetup At(Location location)
|
||||||
{
|
{
|
||||||
Location = location;
|
Location = location;
|
||||||
return this;
|
return this;
|
||||||
|
@ -43,19 +43,19 @@ namespace DistTestCore
|
||||||
// return this;
|
// return this;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public ICodexSetupConfig WithLogLevel(CodexLogLevel level)
|
public ICodexSetup WithLogLevel(CodexLogLevel level)
|
||||||
{
|
{
|
||||||
LogLevel = level;
|
LogLevel = level;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICodexSetupConfig WithStorageQuota(ByteSize storageQuota)
|
public ICodexSetup WithStorageQuota(ByteSize storageQuota)
|
||||||
{
|
{
|
||||||
StorageQuota = storageQuota;
|
StorageQuota = storageQuota;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICodexSetupConfig EnableMetrics()
|
public ICodexSetup EnableMetrics()
|
||||||
{
|
{
|
||||||
MetricsEnabled = true;
|
MetricsEnabled = true;
|
||||||
return this;
|
return this;
|
|
@ -1,27 +1,28 @@
|
||||||
using DistTestCore.Codex;
|
using DistTestCore.Codex;
|
||||||
using KubernetesWorkflow;
|
using KubernetesWorkflow;
|
||||||
using Logging;
|
|
||||||
|
|
||||||
namespace DistTestCore
|
namespace DistTestCore
|
||||||
{
|
{
|
||||||
public class CodexStarter
|
public class CodexStarter
|
||||||
{
|
{
|
||||||
private readonly WorkflowCreator workflowCreator;
|
private readonly WorkflowCreator workflowCreator;
|
||||||
|
private readonly TestLifecycle lifecycle;
|
||||||
|
|
||||||
public CodexStarter(TestLog log, Configuration configuration)
|
public CodexStarter(TestLifecycle lifecycle, Configuration configuration)
|
||||||
{
|
{
|
||||||
workflowCreator = new WorkflowCreator(configuration.GetK8sConfiguration());
|
workflowCreator = new WorkflowCreator(configuration.GetK8sConfiguration());
|
||||||
|
this.lifecycle = lifecycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICodexNodeGroup BringOnline(CodexSetupConfig codexSetupConfig)
|
public ICodexNodeGroup BringOnline(CodexSetup codexSetup)
|
||||||
{
|
{
|
||||||
var workflow = workflowCreator.CreateWorkflow();
|
var workflow = workflowCreator.CreateWorkflow();
|
||||||
var startupConfig = new StartupConfig();
|
var startupConfig = new StartupConfig();
|
||||||
startupConfig.Add(codexSetupConfig);
|
startupConfig.Add(codexSetup);
|
||||||
|
|
||||||
var runningContainers = workflow.Start(codexSetupConfig.NumberOfNodes, codexSetupConfig.Location, new CodexContainerRecipe(), startupConfig);
|
var runningContainers = workflow.Start(codexSetup.NumberOfNodes, codexSetup.Location, new CodexContainerRecipe(), startupConfig);
|
||||||
|
|
||||||
// create access objects. Easy, right?
|
return new CodexNodeGroup(lifecycle, codexSetup, runningContainers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteAllResources()
|
public void DeleteAllResources()
|
||||||
|
|
|
@ -61,27 +61,27 @@ namespace DistTestCore
|
||||||
return lifecycle.FileManager.GenerateTestFile(size);
|
return lifecycle.FileManager.GenerateTestFile(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICodexSetupConfig SetupCodexNodes(int numberOfNodes)
|
public ICodexSetup SetupCodexNodes(int numberOfNodes)
|
||||||
{
|
{
|
||||||
return new CodexSetupConfig(lifecycle.CodexStarter, numberOfNodes);
|
return new CodexSetup(lifecycle.CodexStarter, numberOfNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncludeLogsAndMetricsOnTestFailure()
|
private void IncludeLogsAndMetricsOnTestFailure()
|
||||||
{
|
{
|
||||||
var result = TestContext.CurrentContext.Result;
|
//var result = TestContext.CurrentContext.Result;
|
||||||
if (result.Outcome.Status == NUnit.Framework.Interfaces.TestStatus.Failed)
|
//if (result.Outcome.Status == NUnit.Framework.Interfaces.TestStatus.Failed)
|
||||||
{
|
//{
|
||||||
if (IsDownloadingLogsAndMetricsEnabled())
|
// if (IsDownloadingLogsAndMetricsEnabled())
|
||||||
{
|
// {
|
||||||
log.Log("Downloading all CodexNode logs and metrics because of test failure...");
|
// log.Log("Downloading all CodexNode logs and metrics because of test failure...");
|
||||||
k8sManager.ForEachOnlineGroup(DownloadLogs);
|
// k8sManager.ForEachOnlineGroup(DownloadLogs);
|
||||||
k8sManager.DownloadAllMetrics();
|
// k8sManager.DownloadAllMetrics();
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
log.Log("Skipping download of all CodexNode logs and metrics due to [DontDownloadLogsAndMetricsOnFailure] attribute.");
|
// log.Log("Skipping download of all CodexNode logs and metrics due to [DontDownloadLogsAndMetricsOnFailure] attribute.");
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Log(string msg)
|
private void Log(string msg)
|
||||||
|
@ -101,19 +101,19 @@ namespace DistTestCore
|
||||||
|
|
||||||
private void DownloadLogs(CodexNodeGroup group)
|
private void DownloadLogs(CodexNodeGroup group)
|
||||||
{
|
{
|
||||||
foreach (var node in group)
|
//foreach (var node in group)
|
||||||
{
|
//{
|
||||||
var downloader = new PodLogDownloader(log, k8sManager);
|
// var downloader = new PodLogDownloader(log, k8sManager);
|
||||||
var n = (OnlineCodexNode)node;
|
// var n = (OnlineCodexNode)node;
|
||||||
downloader.DownloadLog(n);
|
// downloader.DownloadLog(n);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsDownloadingLogsAndMetricsEnabled()
|
//private bool IsDownloadingLogsAndMetricsEnabled()
|
||||||
{
|
//{
|
||||||
var testProperties = TestContext.CurrentContext.Test.Properties;
|
// var testProperties = TestContext.CurrentContext.Test.Properties;
|
||||||
return !testProperties.ContainsKey(PodLogDownloader.DontDownloadLogsOnFailureKey);
|
// return !testProperties.ContainsKey(PodLogDownloader.DontDownloadLogsOnFailureKey);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GlobalTestFailure
|
public static class GlobalTestFailure
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
using Utils;
|
||||||
|
|
||||||
namespace DistTestCore
|
namespace DistTestCore
|
||||||
{
|
{
|
||||||
|
@ -26,8 +27,8 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
using var client = GetClient();
|
using var client = GetClient();
|
||||||
var url = GetUrl() + route;
|
var url = GetUrl() + route;
|
||||||
var result = Utils.Wait(client.GetAsync(url));
|
var result = Time.Wait(client.GetAsync(url));
|
||||||
return Utils.Wait(result.Content.ReadAsStringAsync());
|
return Time.Wait(result.Content.ReadAsStringAsync());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +46,9 @@ namespace DistTestCore
|
||||||
|
|
||||||
var content = new StreamContent(stream);
|
var content = new StreamContent(stream);
|
||||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
var response = Utils.Wait(client.PostAsync(url, content));
|
var response = Time.Wait(client.PostAsync(url, content));
|
||||||
|
|
||||||
return Utils.Wait(response.Content.ReadAsStringAsync());
|
return Time.Wait(response.Content.ReadAsStringAsync());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ namespace DistTestCore
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var url = GetUrl() + route;
|
var url = GetUrl() + route;
|
||||||
|
|
||||||
return Utils.Wait(client.GetStreamAsync(url));
|
return Time.Wait(client.GetStreamAsync(url));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
using DistTestCore.Codex;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DistTestCore
|
||||||
|
{
|
||||||
|
public interface IOnlineCodexNode
|
||||||
|
{
|
||||||
|
CodexDebugResponse GetDebugInfo();
|
||||||
|
ContentId UploadFile(TestFile file);
|
||||||
|
TestFile? DownloadContent(ContentId contentId);
|
||||||
|
void ConnectToPeer(IOnlineCodexNode node);
|
||||||
|
//ICodexNodeLog DownloadLog();
|
||||||
|
//IMetricsAccess Metrics { get; }
|
||||||
|
//IMarketplaceAccess Marketplace { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OnlineCodexNode : IOnlineCodexNode
|
||||||
|
{
|
||||||
|
private const string SuccessfullyConnectedMessage = "Successfully connected to peer";
|
||||||
|
private const string UploadFailedMessage = "Unable to store block";
|
||||||
|
private readonly TestLifecycle lifecycle;
|
||||||
|
|
||||||
|
public OnlineCodexNode(TestLifecycle lifecycle, CodexAccess codexAccess, CodexNodeGroup group)
|
||||||
|
{
|
||||||
|
this.lifecycle = lifecycle;
|
||||||
|
CodexAccess = codexAccess;
|
||||||
|
Group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodexAccess CodexAccess { get; }
|
||||||
|
public CodexNodeGroup Group { get; }
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return $"<{CodexAccess.Container.Recipe.Name}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodexDebugResponse GetDebugInfo()
|
||||||
|
{
|
||||||
|
var response = CodexAccess.GetDebugInfo();
|
||||||
|
Log($"Got DebugInfo with id: '{response.id}'.");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentId UploadFile(TestFile file)
|
||||||
|
{
|
||||||
|
Log($"Uploading file of size {file.GetFileSize()}...");
|
||||||
|
using var fileStream = File.OpenRead(file.Filename);
|
||||||
|
var response = CodexAccess.UploadFile(fileStream);
|
||||||
|
if (response.StartsWith(UploadFailedMessage))
|
||||||
|
{
|
||||||
|
Assert.Fail("Node failed to store block.");
|
||||||
|
}
|
||||||
|
Log($"Uploaded file. Received contentId: '{response}'.");
|
||||||
|
return new ContentId(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestFile? DownloadContent(ContentId contentId)
|
||||||
|
{
|
||||||
|
Log($"Downloading for contentId: '{contentId.Id}'...");
|
||||||
|
var file = lifecycle.FileManager.CreateEmptyTestFile();
|
||||||
|
DownloadToFile(contentId.Id, file);
|
||||||
|
Log($"Downloaded file of size {file.GetFileSize()} to '{file.Filename}'.");
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConnectToPeer(IOnlineCodexNode node)
|
||||||
|
{
|
||||||
|
var peer = (OnlineCodexNode)node;
|
||||||
|
|
||||||
|
Log($"Connecting to peer {peer.GetName()}...");
|
||||||
|
var peerInfo = node.GetDebugInfo();
|
||||||
|
var response = CodexAccess.ConnectToPeer(peerInfo.id, GetPeerMultiAddress(peer, peerInfo));
|
||||||
|
|
||||||
|
Assert.That(response, Is.EqualTo(SuccessfullyConnectedMessage), "Unable to connect codex nodes.");
|
||||||
|
Log($"Successfully connected to peer {peer.GetName()}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//public ICodexNodeLog DownloadLog()
|
||||||
|
//{
|
||||||
|
// return Group.DownloadLog(this);
|
||||||
|
//}
|
||||||
|
|
||||||
|
public string Describe()
|
||||||
|
{
|
||||||
|
return $"{Group.Describe()} contains {GetName()}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetPeerMultiAddress(OnlineCodexNode peer, CodexDebugResponse peerInfo)
|
||||||
|
{
|
||||||
|
var multiAddress = peerInfo.addrs.First();
|
||||||
|
// Todo: Is there a case where First address in list is not the way?
|
||||||
|
|
||||||
|
if (Group == peer.Group)
|
||||||
|
{
|
||||||
|
return multiAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The peer we want to connect is in a different pod.
|
||||||
|
// We must replace the default IP with the pod IP in the multiAddress.
|
||||||
|
return multiAddress.Replace("0.0.0.0", peer.Group.Containers.RunningPod.Ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DownloadToFile(string contentId, TestFile file)
|
||||||
|
{
|
||||||
|
using var fileStream = File.OpenWrite(file.Filename);
|
||||||
|
using var downloadStream = CodexAccess.DownloadFile(contentId);
|
||||||
|
downloadStream.CopyTo(fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Log(string msg)
|
||||||
|
{
|
||||||
|
lifecycle.Log.Log($"{GetName()}: {msg}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ContentId
|
||||||
|
{
|
||||||
|
public ContentId(string id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Id { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
Log = new TestLog(configuration.GetLogConfig());
|
Log = new TestLog(configuration.GetLogConfig());
|
||||||
FileManager = new FileManager(Log, configuration);
|
FileManager = new FileManager(Log, configuration);
|
||||||
CodexStarter = new CodexStarter(Log, configuration);
|
CodexStarter = new CodexStarter(this, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestLog Log { get; }
|
public TestLog Log { get; }
|
||||||
|
|
|
@ -187,7 +187,7 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
private string GetNameForPort(ContainerRecipe recipe, Port port)
|
private string GetNameForPort(ContainerRecipe recipe, Port port)
|
||||||
{
|
{
|
||||||
return $"P{workflowNumberSource.WorkflowNumber}-{recipe.Number}-{port.Number}";
|
return $"p{workflowNumberSource.WorkflowNumber}-{recipe.Number}-{port.Number}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using CodexDistTestCore;
|
using DistTestCore;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Tests.BasicTests
|
namespace Tests.BasicTests
|
||||||
|
@ -6,68 +6,6 @@ namespace Tests.BasicTests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class SimpleTests : DistTest
|
public class SimpleTests : DistTest
|
||||||
{
|
{
|
||||||
[Test]
|
|
||||||
public void TwoMetricsExample()
|
|
||||||
{
|
|
||||||
var group = SetupCodexNodes(2)
|
|
||||||
.EnableMetrics()
|
|
||||||
.BringOnline();
|
|
||||||
|
|
||||||
var group2 = SetupCodexNodes(2)
|
|
||||||
.EnableMetrics()
|
|
||||||
.BringOnline();
|
|
||||||
|
|
||||||
var primary = group[0];
|
|
||||||
var secondary = group[1];
|
|
||||||
var primary2 = group2[0];
|
|
||||||
var secondary2 = group2[1];
|
|
||||||
|
|
||||||
primary.ConnectToPeer(secondary);
|
|
||||||
primary2.ConnectToPeer(secondary2);
|
|
||||||
|
|
||||||
Thread.Sleep(TimeSpan.FromMinutes(5));
|
|
||||||
|
|
||||||
primary.Metrics.AssertThat("libp2p_peers", Is.EqualTo(1));
|
|
||||||
primary2.Metrics.AssertThat("libp2p_peers", Is.EqualTo(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void MarketplaceExample()
|
|
||||||
{
|
|
||||||
var group = SetupCodexNodes(4)
|
|
||||||
.WithStorageQuota(10.GB())
|
|
||||||
.EnableMarketplace(initialBalance: 20)
|
|
||||||
.BringOnline();
|
|
||||||
|
|
||||||
foreach (var node in group)
|
|
||||||
{
|
|
||||||
Assert.That(node.Marketplace.GetBalance(), Is.EqualTo(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
// WIP: Balance is now only ETH.
|
|
||||||
// todo: All nodes should have plenty of ETH to pay for transactions.
|
|
||||||
// todo: Upload our own token, use this exclusively. ETH should be invisibile to the tests.
|
|
||||||
|
|
||||||
|
|
||||||
//var secondary = SetupCodexNodes(1)
|
|
||||||
// .EnableMarketplace(initialBalance: 1000)
|
|
||||||
// .BringOnline()[0];
|
|
||||||
|
|
||||||
//primary.ConnectToPeer(secondary);
|
|
||||||
//primary.Marketplace.MakeStorageAvailable(10.GB(), minPricePerBytePerSecond: 1, maxCollateral: 20);
|
|
||||||
|
|
||||||
//var testFile = GenerateTestFile(10.MB());
|
|
||||||
//var contentId = secondary.UploadFile(testFile);
|
|
||||||
//secondary.Marketplace.RequestStorage(contentId, pricePerBytePerSecond: 2,
|
|
||||||
// requiredCollateral: 10, minRequiredNumberOfNodes: 1);
|
|
||||||
|
|
||||||
//primary.Marketplace.AssertThatBalance(Is.LessThan(20), "Collateral was not placed.");
|
|
||||||
//var primaryBalance = primary.Marketplace.GetBalance();
|
|
||||||
|
|
||||||
//secondary.Marketplace.AssertThatBalance(Is.LessThan(1000), "Contractor was not charged for storage.");
|
|
||||||
//primary.Marketplace.AssertThatBalance(Is.GreaterThan(primaryBalance), "Storer was not paid for storage.");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void OneClientTest()
|
public void OneClientTest()
|
||||||
{
|
{
|
||||||
|
@ -82,53 +20,115 @@ namespace Tests.BasicTests
|
||||||
testFile.AssertIsEqual(downloadedFile);
|
testFile.AssertIsEqual(downloadedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void TwoClientsOnePodTest()
|
//public void TwoClientsOnePodTest()
|
||||||
{
|
//{
|
||||||
var group = SetupCodexNodes(2).BringOnline();
|
// var group = SetupCodexNodes(2).BringOnline();
|
||||||
|
|
||||||
var primary = group[0];
|
// var primary = group[0];
|
||||||
var secondary = group[1];
|
// var secondary = group[1];
|
||||||
|
|
||||||
PerformTwoClientTest(primary, secondary);
|
// PerformTwoClientTest(primary, secondary);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void TwoClientsTwoPodsTest()
|
//public void TwoClientsTwoPodsTest()
|
||||||
{
|
//{
|
||||||
var primary = SetupCodexNodes(1).BringOnline()[0];
|
// var primary = SetupCodexNodes(1).BringOnline()[0];
|
||||||
|
|
||||||
var secondary = SetupCodexNodes(1).BringOnline()[0];
|
// var secondary = SetupCodexNodes(1).BringOnline()[0];
|
||||||
|
|
||||||
PerformTwoClientTest(primary, secondary);
|
// PerformTwoClientTest(primary, secondary);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
[Ignore("Requires Location map to be configured for k8s cluster.")]
|
//[Ignore("Requires Location map to be configured for k8s cluster.")]
|
||||||
public void TwoClientsTwoLocationsTest()
|
//public void TwoClientsTwoLocationsTest()
|
||||||
{
|
//{
|
||||||
var primary = SetupCodexNodes(1)
|
// var primary = SetupCodexNodes(1)
|
||||||
.At(Location.BensLaptop)
|
// .At(Location.BensLaptop)
|
||||||
.BringOnline()[0];
|
// .BringOnline()[0];
|
||||||
|
|
||||||
var secondary = SetupCodexNodes(1)
|
// var secondary = SetupCodexNodes(1)
|
||||||
.At(Location.BensOldGamingMachine)
|
// .At(Location.BensOldGamingMachine)
|
||||||
.BringOnline()[0];
|
// .BringOnline()[0];
|
||||||
|
|
||||||
PerformTwoClientTest(primary, secondary);
|
// PerformTwoClientTest(primary, secondary);
|
||||||
}
|
//}
|
||||||
|
|
||||||
private void PerformTwoClientTest(IOnlineCodexNode primary, IOnlineCodexNode secondary)
|
//[Test]
|
||||||
{
|
//public void TwoMetricsExample()
|
||||||
primary.ConnectToPeer(secondary);
|
//{
|
||||||
|
// var group = SetupCodexNodes(2)
|
||||||
|
// .EnableMetrics()
|
||||||
|
// .BringOnline();
|
||||||
|
|
||||||
var testFile = GenerateTestFile(1.MB());
|
// var group2 = SetupCodexNodes(2)
|
||||||
|
// .EnableMetrics()
|
||||||
|
// .BringOnline();
|
||||||
|
|
||||||
var contentId = primary.UploadFile(testFile);
|
// var primary = group[0];
|
||||||
|
// var secondary = group[1];
|
||||||
|
// var primary2 = group2[0];
|
||||||
|
// var secondary2 = group2[1];
|
||||||
|
|
||||||
var downloadedFile = secondary.DownloadContent(contentId);
|
// primary.ConnectToPeer(secondary);
|
||||||
|
// primary2.ConnectToPeer(secondary2);
|
||||||
|
|
||||||
testFile.AssertIsEqual(downloadedFile);
|
// Thread.Sleep(TimeSpan.FromMinutes(5));
|
||||||
}
|
|
||||||
|
// primary.Metrics.AssertThat("libp2p_peers", Is.EqualTo(1));
|
||||||
|
// primary2.Metrics.AssertThat("libp2p_peers", Is.EqualTo(1));
|
||||||
|
//}
|
||||||
|
|
||||||
|
//[Test]
|
||||||
|
//public void MarketplaceExample()
|
||||||
|
//{
|
||||||
|
// var group = SetupCodexNodes(4)
|
||||||
|
// .WithStorageQuota(10.GB())
|
||||||
|
// .EnableMarketplace(initialBalance: 20)
|
||||||
|
// .BringOnline();
|
||||||
|
|
||||||
|
// foreach (var node in group)
|
||||||
|
// {
|
||||||
|
// Assert.That(node.Marketplace.GetBalance(), Is.EqualTo(20));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // WIP: Balance is now only ETH.
|
||||||
|
// // todo: All nodes should have plenty of ETH to pay for transactions.
|
||||||
|
// // todo: Upload our own token, use this exclusively. ETH should be invisibile to the tests.
|
||||||
|
|
||||||
|
|
||||||
|
// //var secondary = SetupCodexNodes(1)
|
||||||
|
// // .EnableMarketplace(initialBalance: 1000)
|
||||||
|
// // .BringOnline()[0];
|
||||||
|
|
||||||
|
// //primary.ConnectToPeer(secondary);
|
||||||
|
// //primary.Marketplace.MakeStorageAvailable(10.GB(), minPricePerBytePerSecond: 1, maxCollateral: 20);
|
||||||
|
|
||||||
|
// //var testFile = GenerateTestFile(10.MB());
|
||||||
|
// //var contentId = secondary.UploadFile(testFile);
|
||||||
|
// //secondary.Marketplace.RequestStorage(contentId, pricePerBytePerSecond: 2,
|
||||||
|
// // requiredCollateral: 10, minRequiredNumberOfNodes: 1);
|
||||||
|
|
||||||
|
// //primary.Marketplace.AssertThatBalance(Is.LessThan(20), "Collateral was not placed.");
|
||||||
|
// //var primaryBalance = primary.Marketplace.GetBalance();
|
||||||
|
|
||||||
|
// //secondary.Marketplace.AssertThatBalance(Is.LessThan(1000), "Contractor was not charged for storage.");
|
||||||
|
// //primary.Marketplace.AssertThatBalance(Is.GreaterThan(primaryBalance), "Storer was not paid for storage.");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private void PerformTwoClientTest(IOnlineCodexNode primary, IOnlineCodexNode secondary)
|
||||||
|
//{
|
||||||
|
// primary.ConnectToPeer(secondary);
|
||||||
|
|
||||||
|
// var testFile = GenerateTestFile(1.MB());
|
||||||
|
|
||||||
|
// var contentId = primary.UploadFile(testFile);
|
||||||
|
|
||||||
|
// var downloadedFile = secondary.DownloadContent(contentId);
|
||||||
|
|
||||||
|
// testFile.AssertIsEqual(downloadedFile);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\CodexDistTestCore\CodexDistTestCore.csproj" />
|
<ProjectReference Include="..\DistTestCore\DistTestCore.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in New Issue