Adds debug logging support
This commit is contained in:
parent
72bb0132bf
commit
f94f4a6d22
|
@ -1,4 +1,5 @@
|
||||||
using KubernetesWorkflow;
|
using KubernetesWorkflow;
|
||||||
|
using Logging;
|
||||||
|
|
||||||
namespace DistTestCore
|
namespace DistTestCore
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace DistTestCore
|
||||||
|
|
||||||
public Logging.LogConfig GetLogConfig()
|
public Logging.LogConfig GetLogConfig()
|
||||||
{
|
{
|
||||||
return new Logging.LogConfig("CodexTestLogs");
|
return new Logging.LogConfig("CodexTestLogs", debugEnabled: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFileManagerFolder()
|
public string GetFileManagerFolder()
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
Stopwatch.Measure(fixtureLog, "Global setup", () =>
|
Stopwatch.Measure(fixtureLog, "Global setup", () =>
|
||||||
{
|
{
|
||||||
var wc = new WorkflowCreator(configuration.GetK8sConfiguration());
|
var wc = new WorkflowCreator(fixtureLog, configuration.GetK8sConfiguration());
|
||||||
wc.CreateWorkflow().DeleteAllResources();
|
wc.CreateWorkflow().DeleteAllResources();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace DistTestCore
|
||||||
|
|
||||||
private void TransferInitialBalance(MarketplaceNetwork marketplaceNetwork, MarketplaceInitialConfig marketplaceConfig, GethCompanionNodeInfo[] companionNodes)
|
private void TransferInitialBalance(MarketplaceNetwork marketplaceNetwork, MarketplaceInitialConfig marketplaceConfig, GethCompanionNodeInfo[] companionNodes)
|
||||||
{
|
{
|
||||||
var interaction = marketplaceNetwork.StartInteraction();
|
var interaction = marketplaceNetwork.StartInteraction(lifecycle.Log);
|
||||||
var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress;
|
var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress;
|
||||||
|
|
||||||
foreach (var node in companionNodes)
|
foreach (var node in companionNodes)
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace DistTestCore.Marketplace
|
||||||
var marketplaceAddress = extractor.ExtractMarketplaceAddress();
|
var marketplaceAddress = extractor.ExtractMarketplaceAddress();
|
||||||
var abi = extractor.ExtractMarketplaceAbi();
|
var abi = extractor.ExtractMarketplaceAbi();
|
||||||
|
|
||||||
var interaction = bootstrapNode.StartInteraction();
|
var interaction = bootstrapNode.StartInteraction(lifecycle.Log);
|
||||||
var tokenAddress = interaction.GetTokenAddress(marketplaceAddress);
|
var tokenAddress = interaction.GetTokenAddress(marketplaceAddress);
|
||||||
|
|
||||||
LogEnd("Contracts deployed.");
|
LogEnd("Contracts deployed.");
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using IdentityModel.OidcClient;
|
using KubernetesWorkflow;
|
||||||
using KubernetesWorkflow;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using KubernetesWorkflow;
|
using KubernetesWorkflow;
|
||||||
|
using Logging;
|
||||||
using NethereumWorkflow;
|
using NethereumWorkflow;
|
||||||
|
|
||||||
namespace DistTestCore.Marketplace
|
namespace DistTestCore.Marketplace
|
||||||
|
@ -20,14 +21,14 @@ namespace DistTestCore.Marketplace
|
||||||
public string PrivateKey { get; }
|
public string PrivateKey { get; }
|
||||||
public Port DiscoveryPort { get; }
|
public Port DiscoveryPort { get; }
|
||||||
|
|
||||||
public NethereumInteraction StartInteraction()
|
public NethereumInteraction StartInteraction(BaseLog log)
|
||||||
{
|
{
|
||||||
var ip = RunningContainers.RunningPod.Cluster.IP;
|
var ip = RunningContainers.RunningPod.Cluster.IP;
|
||||||
var port = RunningContainers.Containers[0].ServicePorts[0].Number;
|
var port = RunningContainers.Containers[0].ServicePorts[0].Number;
|
||||||
var account = Account;
|
var account = Account;
|
||||||
var privateKey = PrivateKey;
|
var privateKey = PrivateKey;
|
||||||
|
|
||||||
var creator = new NethereumInteractionCreator(ip, port, account, privateKey);
|
var creator = new NethereumInteractionCreator(log, ip, port, account, privateKey);
|
||||||
return creator.CreateWorkflow();
|
return creator.CreateWorkflow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using KubernetesWorkflow;
|
using KubernetesWorkflow;
|
||||||
|
using Logging;
|
||||||
using NethereumWorkflow;
|
using NethereumWorkflow;
|
||||||
|
|
||||||
namespace DistTestCore.Marketplace
|
namespace DistTestCore.Marketplace
|
||||||
|
@ -16,14 +17,14 @@ namespace DistTestCore.Marketplace
|
||||||
public string Account { get; }
|
public string Account { get; }
|
||||||
public string PrivateKey { get; }
|
public string PrivateKey { get; }
|
||||||
|
|
||||||
public NethereumInteraction StartInteraction()
|
public NethereumInteraction StartInteraction(BaseLog log)
|
||||||
{
|
{
|
||||||
var ip = RunningContainer.Pod.Cluster.IP;
|
var ip = RunningContainer.Pod.Cluster.IP;
|
||||||
var port = RunningContainer.ServicePorts[0].Number;
|
var port = RunningContainer.ServicePorts[0].Number;
|
||||||
var account = Account;
|
var account = Account;
|
||||||
var privateKey = PrivateKey;
|
var privateKey = PrivateKey;
|
||||||
|
|
||||||
var creator = new NethereumInteractionCreator(ip, port, account, privateKey);
|
var creator = new NethereumInteractionCreator(log, ip, port, account, privateKey);
|
||||||
return creator.CreateWorkflow();
|
return creator.CreateWorkflow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace DistTestCore.Marketplace
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var interaction = node.StartInteraction();
|
var interaction = node.StartInteraction(lifecycle.Log);
|
||||||
interaction.EnsureSynced(marketplace.Marketplace.Address, marketplace.Marketplace.Abi);
|
interaction.EnsureSynced(marketplace.Marketplace.Address, marketplace.Marketplace.Abi);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace DistTestCore.Marketplace
|
||||||
|
|
||||||
public TestToken GetBalance()
|
public TestToken GetBalance()
|
||||||
{
|
{
|
||||||
var interaction = marketplaceNetwork.StartInteraction();
|
var interaction = marketplaceNetwork.StartInteraction(log);
|
||||||
var account = companionNode.Account;
|
var account = companionNode.Account;
|
||||||
var amount = interaction.GetBalance(marketplaceNetwork.Marketplace.TokenAddress, account);
|
var amount = interaction.GetBalance(marketplaceNetwork.Marketplace.TokenAddress, account);
|
||||||
var balance = new TestToken(amount);
|
var balance = new TestToken(amount);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using NethereumWorkflow;
|
using Logging;
|
||||||
|
using NethereumWorkflow;
|
||||||
|
|
||||||
namespace DistTestCore.Marketplace
|
namespace DistTestCore.Marketplace
|
||||||
{
|
{
|
||||||
|
@ -13,9 +14,9 @@ namespace DistTestCore.Marketplace
|
||||||
public GethBootstrapNodeInfo Bootstrap { get; }
|
public GethBootstrapNodeInfo Bootstrap { get; }
|
||||||
public MarketplaceInfo Marketplace { get; }
|
public MarketplaceInfo Marketplace { get; }
|
||||||
|
|
||||||
public NethereumInteraction StartInteraction()
|
public NethereumInteraction StartInteraction(BaseLog log)
|
||||||
{
|
{
|
||||||
return Bootstrap.StartInteraction();
|
return Bootstrap.StartInteraction(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
using Logging;
|
|
||||||
using Utils;
|
|
||||||
|
|
||||||
namespace DistTestCore
|
|
||||||
{
|
|
||||||
public class Stopwatch
|
|
||||||
{
|
|
||||||
private readonly DateTime start = DateTime.UtcNow;
|
|
||||||
private readonly BaseLog log;
|
|
||||||
private readonly string name;
|
|
||||||
|
|
||||||
public Stopwatch(BaseLog log, string name)
|
|
||||||
{
|
|
||||||
this.log = log;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Measure(BaseLog log, string name, Action action)
|
|
||||||
{
|
|
||||||
var sw = Begin(log, name);
|
|
||||||
action();
|
|
||||||
sw.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stopwatch Begin(BaseLog log, string name)
|
|
||||||
{
|
|
||||||
return new Stopwatch(log, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void End(string msg = "")
|
|
||||||
{
|
|
||||||
var duration = DateTime.UtcNow - start;
|
|
||||||
log.Log($"{name} {msg} ({Time.FormatDuration(duration)})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,7 +11,7 @@ namespace DistTestCore
|
||||||
public TestLifecycle(TestLog log, Configuration configuration)
|
public TestLifecycle(TestLog log, Configuration configuration)
|
||||||
{
|
{
|
||||||
Log = log;
|
Log = log;
|
||||||
workflowCreator = new WorkflowCreator(configuration.GetK8sConfiguration());
|
workflowCreator = new WorkflowCreator(log, configuration.GetK8sConfiguration());
|
||||||
|
|
||||||
FileManager = new FileManager(Log, configuration);
|
FileManager = new FileManager(Log, configuration);
|
||||||
CodexStarter = new CodexStarter(this, workflowCreator);
|
CodexStarter = new CodexStarter(this, workflowCreator);
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
using k8s;
|
using k8s;
|
||||||
using k8s.Models;
|
using k8s.Models;
|
||||||
|
using Logging;
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
namespace KubernetesWorkflow
|
namespace KubernetesWorkflow
|
||||||
{
|
{
|
||||||
public class K8sController
|
public class K8sController
|
||||||
{
|
{
|
||||||
|
private readonly BaseLog log;
|
||||||
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 Kubernetes client;
|
private readonly Kubernetes client;
|
||||||
|
|
||||||
public K8sController(K8sCluster cluster, KnownK8sPods knownPods, WorkflowNumberSource workflowNumberSource)
|
public K8sController(BaseLog log, K8sCluster cluster, KnownK8sPods knownPods, WorkflowNumberSource workflowNumberSource)
|
||||||
{
|
{
|
||||||
|
this.log = log;
|
||||||
this.cluster = cluster;
|
this.cluster = cluster;
|
||||||
this.knownPods = knownPods;
|
this.knownPods = knownPods;
|
||||||
this.workflowNumberSource = workflowNumberSource;
|
this.workflowNumberSource = workflowNumberSource;
|
||||||
|
@ -27,6 +30,7 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
public RunningPod BringOnline(ContainerRecipe[] containerRecipes, Location location)
|
public RunningPod BringOnline(ContainerRecipe[] containerRecipes, Location location)
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
EnsureTestNamespace();
|
EnsureTestNamespace();
|
||||||
|
|
||||||
var deploymentName = CreateDeployment(containerRecipes, location);
|
var deploymentName = CreateDeployment(containerRecipes, location);
|
||||||
|
@ -38,6 +42,7 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
public void Stop(RunningPod pod)
|
public void Stop(RunningPod pod)
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
if (!string.IsNullOrEmpty(pod.ServiceName)) DeleteService(pod.ServiceName);
|
if (!string.IsNullOrEmpty(pod.ServiceName)) DeleteService(pod.ServiceName);
|
||||||
DeleteDeployment(pod.DeploymentName);
|
DeleteDeployment(pod.DeploymentName);
|
||||||
WaitUntilDeploymentOffline(pod.DeploymentName);
|
WaitUntilDeploymentOffline(pod.DeploymentName);
|
||||||
|
@ -46,12 +51,14 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
public void DownloadPodLog(RunningPod pod, ContainerRecipe recipe, ILogHandler logHandler)
|
public void DownloadPodLog(RunningPod pod, ContainerRecipe recipe, ILogHandler logHandler)
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
using var stream = client.ReadNamespacedPodLog(pod.Name, K8sNamespace, recipe.Name);
|
using var stream = client.ReadNamespacedPodLog(pod.Name, K8sNamespace, recipe.Name);
|
||||||
logHandler.Log(stream);
|
logHandler.Log(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ExecuteCommand(RunningPod pod, string containerName, string command, params string[] args)
|
public string ExecuteCommand(RunningPod pod, string containerName, string command, params string[] args)
|
||||||
{
|
{
|
||||||
|
log.Debug($"{containerName}: {command} ({string.Join(",", args)})");
|
||||||
var runner = new CommandRunner(client, K8sNamespace, pod, containerName, command, args);
|
var runner = new CommandRunner(client, K8sNamespace, pod, containerName, command, args);
|
||||||
runner.Run();
|
runner.Run();
|
||||||
return runner.GetStdOut();
|
return runner.GetStdOut();
|
||||||
|
@ -59,6 +66,7 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
public void DeleteAllResources()
|
public void DeleteAllResources()
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
DeleteNamespace();
|
DeleteNamespace();
|
||||||
|
|
||||||
WaitUntilNamespaceDeleted();
|
WaitUntilNamespaceDeleted();
|
||||||
|
@ -345,9 +353,17 @@ namespace KubernetesWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WaitUntil(Func<bool> predicate)
|
private void WaitUntil(Func<bool> predicate)
|
||||||
|
{
|
||||||
|
var sw = Stopwatch.Begin(log, true);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Time.WaitUntil(predicate, cluster.K8sOperationTimeout(), cluster.WaitForK8sServiceDelay());
|
Time.WaitUntil(predicate, cluster.K8sOperationTimeout(), cluster.WaitForK8sServiceDelay());
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.End("", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Logging\Logging.csproj" />
|
||||||
<ProjectReference Include="..\Utils\Utils.csproj" />
|
<ProjectReference Include="..\Utils\Utils.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
using System.IO;
|
using Logging;
|
||||||
|
|
||||||
namespace KubernetesWorkflow
|
namespace KubernetesWorkflow
|
||||||
{
|
{
|
||||||
public class StartupWorkflow
|
public class StartupWorkflow
|
||||||
{
|
{
|
||||||
|
private readonly BaseLog log;
|
||||||
private readonly WorkflowNumberSource numberSource;
|
private readonly WorkflowNumberSource numberSource;
|
||||||
private readonly K8sCluster cluster;
|
private readonly K8sCluster cluster;
|
||||||
private readonly KnownK8sPods knownK8SPods;
|
private readonly KnownK8sPods knownK8SPods;
|
||||||
private readonly RecipeComponentFactory componentFactory = new RecipeComponentFactory();
|
private readonly RecipeComponentFactory componentFactory = new RecipeComponentFactory();
|
||||||
|
|
||||||
internal StartupWorkflow(WorkflowNumberSource numberSource, K8sCluster cluster, KnownK8sPods knownK8SPods)
|
internal StartupWorkflow(BaseLog log, WorkflowNumberSource numberSource, K8sCluster cluster, KnownK8sPods knownK8SPods)
|
||||||
{
|
{
|
||||||
|
this.log = log;
|
||||||
this.numberSource = numberSource;
|
this.numberSource = numberSource;
|
||||||
this.cluster = cluster;
|
this.cluster = cluster;
|
||||||
this.knownK8SPods = knownK8SPods;
|
this.knownK8SPods = knownK8SPods;
|
||||||
|
@ -60,13 +62,15 @@ namespace KubernetesWorkflow
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RunningContainer[] CreateContainers(RunningPod runningPod, ContainerRecipe[] recipes)
|
private RunningContainer[] CreateContainers(RunningPod runningPod, ContainerRecipe[] recipes)
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
return recipes.Select(r => new RunningContainer(runningPod, r, runningPod.GetServicePortsForContainerRecipe(r))).ToArray();
|
return recipes.Select(r => new RunningContainer(runningPod, r, runningPod.GetServicePortsForContainerRecipe(r))).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContainerRecipe[] CreateRecipes(int numberOfContainers, ContainerRecipeFactory recipeFactory, StartupConfig startupConfig)
|
private ContainerRecipe[] CreateRecipes(int numberOfContainers, ContainerRecipeFactory recipeFactory, StartupConfig startupConfig)
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
var result = new List<ContainerRecipe>();
|
var result = new List<ContainerRecipe>();
|
||||||
for (var i = 0; i < numberOfContainers; i++)
|
for (var i = 0; i < numberOfContainers; i++)
|
||||||
{
|
{
|
||||||
|
@ -78,14 +82,14 @@ namespace KubernetesWorkflow
|
||||||
|
|
||||||
private void K8s(Action<K8sController> action)
|
private void K8s(Action<K8sController> action)
|
||||||
{
|
{
|
||||||
var controller = new K8sController(cluster, knownK8SPods, numberSource);
|
var controller = new K8sController(log, cluster, knownK8SPods, numberSource);
|
||||||
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(cluster, knownK8SPods, numberSource);
|
var controller = new K8sController(log, cluster, knownK8SPods, numberSource);
|
||||||
var result = action(controller);
|
var result = action(controller);
|
||||||
controller.Dispose();
|
controller.Dispose();
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Utils;
|
using Logging;
|
||||||
|
using Utils;
|
||||||
|
|
||||||
namespace KubernetesWorkflow
|
namespace KubernetesWorkflow
|
||||||
{
|
{
|
||||||
|
@ -9,10 +10,12 @@ namespace KubernetesWorkflow
|
||||||
private readonly NumberSource containerNumberSource = new NumberSource(0);
|
private readonly NumberSource containerNumberSource = new NumberSource(0);
|
||||||
private readonly KnownK8sPods knownPods = new KnownK8sPods();
|
private readonly KnownK8sPods knownPods = new KnownK8sPods();
|
||||||
private readonly K8sCluster cluster;
|
private readonly K8sCluster cluster;
|
||||||
|
private readonly BaseLog log;
|
||||||
|
|
||||||
public WorkflowCreator(Configuration configuration)
|
public WorkflowCreator(BaseLog log, Configuration configuration)
|
||||||
{
|
{
|
||||||
cluster = new K8sCluster(configuration);
|
cluster = new K8sCluster(configuration);
|
||||||
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StartupWorkflow CreateWorkflow()
|
public StartupWorkflow CreateWorkflow()
|
||||||
|
@ -21,7 +24,7 @@ namespace KubernetesWorkflow
|
||||||
servicePortNumberSource,
|
servicePortNumberSource,
|
||||||
containerNumberSource);
|
containerNumberSource);
|
||||||
|
|
||||||
return new StartupWorkflow(workflowNumberSource, cluster, knownPods);
|
return new StartupWorkflow(log, workflowNumberSource, cluster, knownPods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
namespace Logging
|
using System.Diagnostics;
|
||||||
|
using Utils;
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
{
|
{
|
||||||
public abstract class BaseLog
|
public abstract class BaseLog
|
||||||
{
|
{
|
||||||
private bool hasFailed;
|
private bool hasFailed;
|
||||||
private LogFile? logFile;
|
private LogFile? logFile;
|
||||||
|
private readonly bool debug;
|
||||||
|
|
||||||
|
protected BaseLog(bool debug)
|
||||||
|
{
|
||||||
|
this.debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract LogFile CreateLogFile();
|
protected abstract LogFile CreateLogFile();
|
||||||
|
|
||||||
|
@ -21,6 +30,15 @@
|
||||||
LogFile.Write(message);
|
LogFile.Write(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Debug(string message = "", int skipFrames = 0)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
var callerName = DebugStack.GetCallerName(skipFrames);
|
||||||
|
Log($"(debug)({callerName}) {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Error(string message)
|
public void Error(string message)
|
||||||
{
|
{
|
||||||
Log($"[ERROR] {message}");
|
Log($"[ERROR] {message}");
|
||||||
|
|
|
@ -6,18 +6,21 @@ namespace Logging
|
||||||
{
|
{
|
||||||
private readonly DateTime start;
|
private readonly DateTime start;
|
||||||
private readonly string fullName;
|
private readonly string fullName;
|
||||||
|
private readonly LogConfig config;
|
||||||
|
|
||||||
public FixtureLog(LogConfig config)
|
public FixtureLog(LogConfig config)
|
||||||
|
: base(config.DebugEnabled)
|
||||||
{
|
{
|
||||||
start = DateTime.UtcNow;
|
start = DateTime.UtcNow;
|
||||||
var folder = DetermineFolder(config);
|
var folder = DetermineFolder(config);
|
||||||
var fixtureName = GetFixtureName();
|
var fixtureName = GetFixtureName();
|
||||||
fullName = Path.Combine(folder, fixtureName);
|
fullName = Path.Combine(folder, fixtureName);
|
||||||
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestLog CreateTestLog()
|
public TestLog CreateTestLog()
|
||||||
{
|
{
|
||||||
return new TestLog(fullName);
|
return new TestLog(fullName, config.DebugEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override LogFile CreateLogFile()
|
protected override LogFile CreateLogFile()
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
{
|
{
|
||||||
public class LogConfig
|
public class LogConfig
|
||||||
{
|
{
|
||||||
public LogConfig(string logRoot)
|
public LogConfig(string logRoot, bool debugEnabled)
|
||||||
{
|
{
|
||||||
LogRoot = logRoot;
|
LogRoot = logRoot;
|
||||||
|
DebugEnabled = debugEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LogRoot { get; }
|
public string LogRoot { get; }
|
||||||
|
public bool DebugEnabled { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
using Utils;
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
public class Stopwatch
|
||||||
|
{
|
||||||
|
private readonly DateTime start = DateTime.UtcNow;
|
||||||
|
private readonly BaseLog log;
|
||||||
|
private readonly string name;
|
||||||
|
private readonly bool debug;
|
||||||
|
|
||||||
|
private Stopwatch(BaseLog log, string name, bool debug)
|
||||||
|
{
|
||||||
|
this.log = log;
|
||||||
|
this.name = name;
|
||||||
|
this.debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Measure(BaseLog log, string name, Action action, bool debug = false)
|
||||||
|
{
|
||||||
|
var sw = Begin(log, name, debug);
|
||||||
|
action();
|
||||||
|
sw.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stopwatch Begin(BaseLog log)
|
||||||
|
{
|
||||||
|
return Begin(log, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stopwatch Begin(BaseLog log, string name)
|
||||||
|
{
|
||||||
|
return Begin(log, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stopwatch Begin(BaseLog log, bool debug)
|
||||||
|
{
|
||||||
|
return Begin(log, "", debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stopwatch Begin(BaseLog log, string name, bool debug)
|
||||||
|
{
|
||||||
|
return new Stopwatch(log, name, debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void End(string msg = "", int skipFrames = 0)
|
||||||
|
{
|
||||||
|
var duration = DateTime.UtcNow - start;
|
||||||
|
var entry = $"{name} {msg} ({Time.FormatDuration(duration)})";
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
log.Debug(entry, 1 + skipFrames);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.Log(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,8 @@ namespace Logging
|
||||||
private readonly string methodName;
|
private readonly string methodName;
|
||||||
private readonly string fullName;
|
private readonly string fullName;
|
||||||
|
|
||||||
public TestLog(string folder)
|
public TestLog(string folder, bool debug)
|
||||||
|
: base(debug)
|
||||||
{
|
{
|
||||||
methodName = GetMethodName();
|
methodName = GetMethodName();
|
||||||
fullName = Path.Combine(folder, methodName);
|
fullName = Path.Combine(folder, methodName);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Nethereum.ABI.FunctionEncoding.Attributes;
|
using Logging;
|
||||||
|
using Nethereum.ABI.FunctionEncoding.Attributes;
|
||||||
using Nethereum.Contracts;
|
using Nethereum.Contracts;
|
||||||
using Nethereum.Hex.HexTypes;
|
using Nethereum.Hex.HexTypes;
|
||||||
using Nethereum.Web3;
|
using Nethereum.Web3;
|
||||||
|
@ -10,17 +11,20 @@ namespace NethereumWorkflow
|
||||||
public class NethereumInteraction
|
public class NethereumInteraction
|
||||||
{
|
{
|
||||||
private readonly List<Task> openTasks = new List<Task>();
|
private readonly List<Task> openTasks = new List<Task>();
|
||||||
|
private readonly BaseLog log;
|
||||||
private readonly Web3 web3;
|
private readonly Web3 web3;
|
||||||
private readonly string rootAccount;
|
private readonly string rootAccount;
|
||||||
|
|
||||||
internal NethereumInteraction(Web3 web3, string rootAccount)
|
internal NethereumInteraction(BaseLog log, Web3 web3, string rootAccount)
|
||||||
{
|
{
|
||||||
|
this.log = log;
|
||||||
this.web3 = web3;
|
this.web3 = web3;
|
||||||
this.rootAccount = rootAccount;
|
this.rootAccount = rootAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetTokenAddress(string marketplaceAddress)
|
public string GetTokenAddress(string marketplaceAddress)
|
||||||
{
|
{
|
||||||
|
log.Debug(marketplaceAddress);
|
||||||
var function = new GetTokenFunction();
|
var function = new GetTokenFunction();
|
||||||
|
|
||||||
var handler = web3.Eth.GetContractQueryHandler<GetTokenFunction>();
|
var handler = web3.Eth.GetContractQueryHandler<GetTokenFunction>();
|
||||||
|
@ -29,6 +33,7 @@ namespace NethereumWorkflow
|
||||||
|
|
||||||
public void TransferWeiTo(string account, decimal amount)
|
public void TransferWeiTo(string account, decimal amount)
|
||||||
{
|
{
|
||||||
|
log.Debug($"{amount} --> {account}");
|
||||||
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for AddToBalance");
|
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for AddToBalance");
|
||||||
|
|
||||||
var value = ToHexBig(amount);
|
var value = ToHexBig(amount);
|
||||||
|
@ -38,6 +43,7 @@ namespace NethereumWorkflow
|
||||||
|
|
||||||
public void MintTestTokens(string account, decimal amount, string tokenAddress)
|
public void MintTestTokens(string account, decimal amount, string tokenAddress)
|
||||||
{
|
{
|
||||||
|
log.Debug($"({tokenAddress}) {amount} --> {account}");
|
||||||
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
|
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
|
||||||
|
|
||||||
var function = new MintTokensFunction
|
var function = new MintTokensFunction
|
||||||
|
@ -52,6 +58,7 @@ namespace NethereumWorkflow
|
||||||
|
|
||||||
public decimal GetBalance(string tokenAddress, string account)
|
public decimal GetBalance(string tokenAddress, string account)
|
||||||
{
|
{
|
||||||
|
log.Debug($"({tokenAddress}) {account}");
|
||||||
var function = new GetTokenBalanceFunction
|
var function = new GetTokenBalanceFunction
|
||||||
{
|
{
|
||||||
Owner = account
|
Owner = account
|
||||||
|
@ -77,6 +84,7 @@ namespace NethereumWorkflow
|
||||||
|
|
||||||
private void WaitUntilSynced()
|
private void WaitUntilSynced()
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
Time.WaitUntil(() =>
|
Time.WaitUntil(() =>
|
||||||
{
|
{
|
||||||
var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync());
|
var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync());
|
||||||
|
@ -89,6 +97,7 @@ namespace NethereumWorkflow
|
||||||
|
|
||||||
private void WaitForContract(string marketplaceAddress, string marketplaceAbi)
|
private void WaitForContract(string marketplaceAddress, string marketplaceAbi)
|
||||||
{
|
{
|
||||||
|
log.Debug();
|
||||||
Time.WaitUntil(() =>
|
Time.WaitUntil(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
using Nethereum.Web3;
|
using Logging;
|
||||||
|
using Nethereum.Web3;
|
||||||
|
|
||||||
namespace NethereumWorkflow
|
namespace NethereumWorkflow
|
||||||
{
|
{
|
||||||
public class NethereumInteractionCreator
|
public class NethereumInteractionCreator
|
||||||
{
|
{
|
||||||
|
private readonly BaseLog log;
|
||||||
private readonly string ip;
|
private readonly string ip;
|
||||||
private readonly int port;
|
private readonly int port;
|
||||||
private readonly string rootAccount;
|
private readonly string rootAccount;
|
||||||
private readonly string privateKey;
|
private readonly string privateKey;
|
||||||
|
|
||||||
public NethereumInteractionCreator(string ip, int port, string rootAccount, string privateKey)
|
public NethereumInteractionCreator(BaseLog log, string ip, int port, string rootAccount, string privateKey)
|
||||||
{
|
{
|
||||||
|
this.log = log;
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.rootAccount = rootAccount;
|
this.rootAccount = rootAccount;
|
||||||
|
@ -19,7 +22,7 @@ namespace NethereumWorkflow
|
||||||
|
|
||||||
public NethereumInteraction CreateWorkflow()
|
public NethereumInteraction CreateWorkflow()
|
||||||
{
|
{
|
||||||
return new NethereumInteraction(CreateWeb3(), rootAccount);
|
return new NethereumInteraction(log, CreateWeb3(), rootAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Web3 CreateWeb3()
|
private Web3 CreateWeb3()
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
public class DebugStack
|
||||||
|
{
|
||||||
|
public static string GetCallerName(int skipFrames = 0)
|
||||||
|
{
|
||||||
|
return new StackFrame(2 + skipFrames, true).GetMethod()!.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue