diff --git a/CodexDistTestCore/K8sManager.cs b/CodexDistTestCore/K8sManager.cs index 46bf07d..5ee9109 100644 --- a/CodexDistTestCore/K8sManager.cs +++ b/CodexDistTestCore/K8sManager.cs @@ -1,4 +1,6 @@ -namespace CodexDistTestCore +using CodexDistTestCore.Metrics; + +namespace CodexDistTestCore { public interface IK8sManager { diff --git a/CodexDistTestCore/K8sOperations.cs b/CodexDistTestCore/K8sOperations.cs index 6bad053..2354e9d 100644 --- a/CodexDistTestCore/K8sOperations.cs +++ b/CodexDistTestCore/K8sOperations.cs @@ -1,4 +1,5 @@ using CodexDistTestCore.Config; +using CodexDistTestCore.Metrics; using k8s; using k8s.KubeConfigModels; using k8s.Models; diff --git a/CodexDistTestCore/Marketplace/MarketplaceAccess.cs b/CodexDistTestCore/Marketplace/MarketplaceAccess.cs new file mode 100644 index 0000000..25bb63f --- /dev/null +++ b/CodexDistTestCore/Marketplace/MarketplaceAccess.cs @@ -0,0 +1,66 @@ +using NUnit.Framework; +using NUnit.Framework.Constraints; + +namespace CodexDistTestCore.Marketplace +{ + public interface IMarketplaceAccess + { + void AdvertiseStorage(ByteSize size, float pricePerMBPerSecond, float collateral); + void AdvertiseContract(ContentId contentId, float maxPricePerMBPerSecond, float minRequiredCollateral, float minRequiredNumberOfDuplicates); + void AssertThatBalance(IResolveConstraint constraint, string message = ""); + float GetBalance(); + } + + public class MarketplaceAccess : IMarketplaceAccess + { + public void AdvertiseContract(ContentId contentId, float maxPricePerMBPerSecond, float minRequiredCollateral, float minRequiredNumberOfDuplicates) + { + throw new NotImplementedException(); + } + + public void AdvertiseStorage(ByteSize size, float pricePerMBPerSecond, float collateral) + { + throw new NotImplementedException(); + } + + public void AssertThatBalance(IResolveConstraint constraint, string message = "") + { + throw new NotImplementedException(); + } + + public float GetBalance() + { + throw new NotImplementedException(); + } + } + + public class MarketplaceUnavailable : IMarketplaceAccess + { + public void AdvertiseContract(ContentId contentId, float maxPricePerMBPerSecond, float minRequiredCollateral, float minRequiredNumberOfDuplicates) + { + Unavailable(); + } + + public void AdvertiseStorage(ByteSize size, float pricePerMBPerSecond, float collateral) + { + Unavailable(); + } + + public void AssertThatBalance(IResolveConstraint constraint, string message = "") + { + Unavailable(); + } + + public float GetBalance() + { + Unavailable(); + return 0.0f; + } + + private void Unavailable() + { + Assert.Fail("Incorrect test setup: Marketplace was not enabled for this group of Codex nodes. Add 'EnableMarketplace(...)' after 'SetupCodexNodes()' to enable it."); + throw new InvalidOperationException(); + } + } +} diff --git a/CodexDistTestCore/Marketplace/MarketplaceInitialConfig.cs b/CodexDistTestCore/Marketplace/MarketplaceInitialConfig.cs new file mode 100644 index 0000000..f7761f5 --- /dev/null +++ b/CodexDistTestCore/Marketplace/MarketplaceInitialConfig.cs @@ -0,0 +1,12 @@ +namespace CodexDistTestCore.Marketplace +{ + public class MarketplaceInitialConfig + { + public MarketplaceInitialConfig(int initialBalance) + { + InitialBalance = initialBalance; + } + + public int InitialBalance { get; } + } +} diff --git a/CodexDistTestCore/K8sPrometheusSpecs.cs b/CodexDistTestCore/Metrics/K8sPrometheusSpecs.cs similarity index 98% rename from CodexDistTestCore/K8sPrometheusSpecs.cs rename to CodexDistTestCore/Metrics/K8sPrometheusSpecs.cs index dcda941..0fc0865 100644 --- a/CodexDistTestCore/K8sPrometheusSpecs.cs +++ b/CodexDistTestCore/Metrics/K8sPrometheusSpecs.cs @@ -1,7 +1,7 @@ using CodexDistTestCore.Config; using k8s.Models; -namespace CodexDistTestCore +namespace CodexDistTestCore.Metrics { public class K8sPrometheusSpecs { @@ -31,7 +31,7 @@ namespace CodexDistTestCore var deploymentSpec = new V1Deployment { ApiVersion = "apps/v1", - Metadata = new V1ObjectMeta + Metadata = new V1ObjectMeta { Name = GetDeploymentName(), NamespaceProperty = K8sCluster.K8sNamespace diff --git a/CodexDistTestCore/MetricsAccess.cs b/CodexDistTestCore/Metrics/MetricsAccess.cs similarity index 98% rename from CodexDistTestCore/MetricsAccess.cs rename to CodexDistTestCore/Metrics/MetricsAccess.cs index feb3fe7..2f6456e 100644 --- a/CodexDistTestCore/MetricsAccess.cs +++ b/CodexDistTestCore/Metrics/MetricsAccess.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using NUnit.Framework.Constraints; -namespace CodexDistTestCore +namespace CodexDistTestCore.Metrics { public interface IMetricsAccess { diff --git a/CodexDistTestCore/MetricsAggregator.cs b/CodexDistTestCore/Metrics/MetricsAggregator.cs similarity index 97% rename from CodexDistTestCore/MetricsAggregator.cs rename to CodexDistTestCore/Metrics/MetricsAggregator.cs index 59e884d..adf0c3f 100644 --- a/CodexDistTestCore/MetricsAggregator.cs +++ b/CodexDistTestCore/Metrics/MetricsAggregator.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using System.Text; -namespace CodexDistTestCore +namespace CodexDistTestCore.Metrics { public class MetricsAggregator { @@ -27,7 +27,7 @@ namespace CodexDistTestCore log.Log("Metrics service started."); - foreach(var node in nodes) + foreach (var node in nodes) { node.Metrics = new MetricsAccess(query, node); } diff --git a/CodexDistTestCore/MetricsDownloader.cs b/CodexDistTestCore/Metrics/MetricsDownloader.cs similarity index 98% rename from CodexDistTestCore/MetricsDownloader.cs rename to CodexDistTestCore/Metrics/MetricsDownloader.cs index 22ef526..18fd10b 100644 --- a/CodexDistTestCore/MetricsDownloader.cs +++ b/CodexDistTestCore/Metrics/MetricsDownloader.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace CodexDistTestCore +namespace CodexDistTestCore.Metrics { public class MetricsDownloader { diff --git a/CodexDistTestCore/MetricsQuery.cs b/CodexDistTestCore/Metrics/MetricsQuery.cs similarity index 99% rename from CodexDistTestCore/MetricsQuery.cs rename to CodexDistTestCore/Metrics/MetricsQuery.cs index d8ba684..c028a6c 100644 --- a/CodexDistTestCore/MetricsQuery.cs +++ b/CodexDistTestCore/Metrics/MetricsQuery.cs @@ -1,7 +1,7 @@ using CodexDistTestCore.Config; using System.Globalization; -namespace CodexDistTestCore +namespace CodexDistTestCore.Metrics { public class MetricsQuery { @@ -107,7 +107,7 @@ namespace CodexDistTestCore { Timestamp = ToTimestamp(value[0]), Value = ToValue(value[1]) - }; + }; } private string GetInstanceNameForNode(OnlineCodexNode node) diff --git a/CodexDistTestCore/OfflineCodexNodes.cs b/CodexDistTestCore/OfflineCodexNodes.cs index f5527af..d82ed53 100644 --- a/CodexDistTestCore/OfflineCodexNodes.cs +++ b/CodexDistTestCore/OfflineCodexNodes.cs @@ -1,4 +1,6 @@ -namespace CodexDistTestCore +using CodexDistTestCore.Marketplace; + +namespace CodexDistTestCore { public interface IOfflineCodexNodes { @@ -7,6 +9,7 @@ IOfflineCodexNodes WithBootstrapNode(IOnlineCodexNode node); IOfflineCodexNodes WithStorageQuota(ByteSize storageQuota); IOfflineCodexNodes EnableMetrics(); + IOfflineCodexNodes EnableMarketplace(int initialBalance); ICodexNodeGroup BringOnline(); } @@ -36,6 +39,7 @@ public IOnlineCodexNode? BootstrapNode { get; private set; } public ByteSize? StorageQuota { get; private set; } public bool MetricsEnabled { get; private set; } + public MarketplaceInitialConfig? MarketplaceConfig { get; private set; } public OfflineCodexNodes(IK8sManager k8SManager, int numberOfNodes) { @@ -80,6 +84,12 @@ return this; } + public IOfflineCodexNodes EnableMarketplace(int initialBalance) + { + MarketplaceConfig = new MarketplaceInitialConfig(initialBalance); + return this; + } + public string Describe() { var args = string.Join(',', DescribeArgs()); @@ -89,7 +99,7 @@ private IEnumerable DescribeArgs() { if (LogLevel != null) yield return ($"LogLevel={LogLevel}"); - if (BootstrapNode != null) yield return ("BootstrapNode=set"); + if (BootstrapNode != null) yield return ("BootstrapNode=set-not-shown-here"); if (StorageQuota != null) yield return ($"StorageQuote={StorageQuota.SizeInBytes}"); } } diff --git a/CodexDistTestCore/OnlineCodexNode.cs b/CodexDistTestCore/OnlineCodexNode.cs index a9cf511..64f9c6d 100644 --- a/CodexDistTestCore/OnlineCodexNode.cs +++ b/CodexDistTestCore/OnlineCodexNode.cs @@ -1,4 +1,6 @@ using CodexDistTestCore.Config; +using CodexDistTestCore.Marketplace; +using CodexDistTestCore.Metrics; using NUnit.Framework; namespace CodexDistTestCore @@ -11,6 +13,7 @@ namespace CodexDistTestCore void ConnectToPeer(IOnlineCodexNode node); ICodexNodeLog DownloadLog(); IMetricsAccess Metrics { get; } + IMarketplaceAccess Marketplace { get; } } public class OnlineCodexNode : IOnlineCodexNode @@ -32,6 +35,7 @@ namespace CodexDistTestCore public CodexNodeContainer Container { get; } public CodexNodeGroup Group { get; internal set; } = null!; public IMetricsAccess Metrics { get; set; } = new MetricsUnavailable(); + public IMarketplaceAccess Marketplace { set; get; } = new MarketplaceUnavailable(); public string GetName() { diff --git a/CodexDistTestCore/TryContract.cs b/CodexDistTestCore/TryContract.cs index 766054b..efc9d5a 100644 --- a/CodexDistTestCore/TryContract.cs +++ b/CodexDistTestCore/TryContract.cs @@ -16,6 +16,7 @@ namespace CodexDistTestCore public class TryContract { [Test] + [Ignore("aaa")] public void DoThing() { var url = "http://testchain.nethereum.com:8545"; diff --git a/Tests/BasicTests/SimpleTests.cs b/Tests/BasicTests/SimpleTests.cs index 1fd90d4..3785ac3 100644 --- a/Tests/BasicTests/SimpleTests.cs +++ b/Tests/BasicTests/SimpleTests.cs @@ -39,6 +39,32 @@ namespace Tests.BasicTests primary2.Metrics.AssertThat("libp2p_peers", Is.EqualTo(1)); } + [Test] + public void MarketplaceExample() + { + var primary = SetupCodexNodes(1) + .WithStorageQuota(10.GB()) + .EnableMarketplace(initialBalance: 20) + .BringOnline()[0]; + + var secondary = SetupCodexNodes(1) + .EnableMarketplace(initialBalance: 1000) + .BringOnline()[0]; + + primary.ConnectToPeer(secondary); + primary.Marketplace.AdvertiseStorage(10.GB(), pricePerMBPerSecond: 0.01f, collateral: 20); + + var testFile = GenerateTestFile(10.MB()); + var contentId = secondary.UploadFile(testFile); + secondary.Marketplace.AdvertiseContract(contentId, maxPricePerMBPerSecond: 0.02f, minRequiredCollateral: 10, minRequiredNumberOfDuplicates: 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] public void OneClientTest() {