diff --git a/.github/workflows/continuous-tests.yaml b/.github/workflows/continuous-tests.yaml index 11947dd..be4d258 100644 --- a/.github/workflows/continuous-tests.yaml +++ b/.github/workflows/continuous-tests.yaml @@ -14,16 +14,16 @@ on: # - '!docker/continuous-tests-job.yaml' workflow_dispatch: inputs: - branch: - description: Branch (master) - required: false - type: string source: description: Repository with tests (current) required: false type: string + branch: + description: Branch with tests (master) + required: false + type: string nameprefix: - description: Runner name prefix (codex-continuous-tests) + description: Runner name prefix (c-tests-runner) required: false type: string namespace: @@ -31,7 +31,7 @@ on: required: false type: string tests_target_duration: - description: Runner target duration (172800s=48h) + description: Runner target duration (172800 = 48h) required: false type: string tests_filter: @@ -39,11 +39,14 @@ on: required: false type: string tests_cleanup: - description: Runner tests cleanup (true) - required: false - type: string + description: Runner tests cleanup + type: choice + options: + - true + - false + default: true deployment_namespace: - description: Deployment namespace (codex-continuous-tests) + description: Deployment namespace (c-tests-$runid) required: false type: string @@ -51,9 +54,9 @@ on: env: BRANCH: ${{ github.ref_name }} SOURCE: ${{ format('{0}/{1}', github.server_url, github.repository) }} - NAMEPREFIX: codex-continuous-tests + NAMEPREFIX: c-tests-runner NAMESPACE: default - DEPLOYMENT_NAMESPACE: codex-continuous-tests + DEPLOYMENT_NAMESPACE: c-tests TESTS_TARGET_DURATION: 172800 TESTS_FILTER: "" TESTS_CLEANUP: true @@ -72,16 +75,18 @@ jobs: - name: Variables run: | - [[ -n "${{ github.event.inputs.branch }}" ]] && echo "BRANCH=${{ github.event.inputs.branch }}" >>"$GITHUB_ENV" || echo "BRANCH=${{ env.BRANCH }}" >>"$GITHUB_ENV" + RUNID=$(date +%Y%m%d-%H%M%S) + echo "RUNID=${RUNID}" >> $GITHUB_ENV + echo "TESTID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV [[ -n "${{ github.event.inputs.source }}" ]] && echo "SOURCE=${{ github.event.inputs.source }}" >>"$GITHUB_ENV" || echo "SOURCE=${{ env.SOURCE }}" >>"$GITHUB_ENV" + [[ -n "${{ github.event.inputs.branch }}" ]] && echo "BRANCH=${{ github.event.inputs.branch }}" >>"$GITHUB_ENV" || echo "BRANCH=${{ env.BRANCH }}" >>"$GITHUB_ENV" [[ -n "${{ github.event.inputs.nameprefix }}" ]] && echo "NAMEPREFIX=${{ github.event.inputs.nameprefix }}" >>"$GITHUB_ENV" || echo "NAMEPREFIX=${{ env.NAMEPREFIX }}" >>"$GITHUB_ENV" [[ -n "${{ github.event.inputs.namespace }}" ]] && echo "NAMESPACE=${{ github.event.inputs.namespace }}" >>"$GITHUB_ENV" || echo "NAMESPACE=${{ env.NAMESPACE }}" >>"$GITHUB_ENV" [[ -n "${{ github.event.inputs.tests_target_duration }}" ]] && echo "TESTS_TARGET_DURATION=${{ github.event.inputs.tests_target_duration }}" >>"$GITHUB_ENV" || echo "TESTS_TARGET_DURATION=${{ env.TESTS_TARGET_DURATION }}" >>"$GITHUB_ENV" [[ -n "${{ github.event.inputs.tests_filter }}" ]] && echo "TESTS_FILTER=${{ github.event.inputs.tests_filter }}" >>"$GITHUB_ENV" || echo "TESTS_FILTERS=${{ env.TESTS_FILTERS }}" >>"$GITHUB_ENV" [[ -n "${{ github.event.inputs.tests_cleanup }}" ]] && echo "TESTS_CLEANUP=${{ github.event.inputs.tests_cleanup }}" >>"$GITHUB_ENV" || echo "TESTS_CLEANUP=${{ env.TESTS_CLEANUP }}" >>"$GITHUB_ENV" - [[ -n "${{ github.event.inputs.deployment_namespace }}" ]] && echo "DEPLOYMENT_NAMESPACE=${{ github.event.inputs.deployment_namespace }}" >>"$GITHUB_ENV" || echo "DEPLOYMENT_NAMESPACE=${{ env.DEPLOYMENT_NAMESPACE }}" >>"$GITHUB_ENV" - echo "RUNID=$(date +%Y%m%d-%H%M%S)" >> $GITHUB_ENV - echo "TESTID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + [[ -n "${{ github.event.inputs.deployment_namespace }}" ]] && echo "DEPLOYMENT_NAMESPACE=${{ github.event.inputs.deployment_namespace }}" >>"$GITHUB_ENV" || echo "DEPLOYMENT_NAMESPACE=${{ env.DEPLOYMENT_NAMESPACE }}-${RUNID}" >>"$GITHUB_ENV" + - name: Kubectl - Install ${{ env.KUBE_VERSION }} uses: azure/setup-kubectl@v3 with: @@ -91,6 +96,22 @@ jobs: run: | mkdir -p "${HOME}"/.kube echo "${{ env.KUBE_CONFIG }}" | base64 -d > "${HOME}"/.kube/config + - name: Kubectl - Create Job run: | envsubst < ${{ env.JOB_MANIFEST }} | kubectl apply -f - + + - name: Tests Identification + run: | + echo "----" + echo "Repository: ${{ env.SOURCE }}" + echo "Branch: ${{ env.BRANCH }}" + echo "Runner Pod: ${{ env.NAMEPREFIX }}-${{ env.RUNID }}" + echo "Runner namespace: ${{ env.NAMESPACE }}" + echo "----" + echo "Tests runid: ${{ env.RUNID }}" + echo "Tests namespace: ${{ env.DEPLOYMENT_NAMESPACE }}" + echo "Tests duration: ${{ env.TESTS_TARGET_DURATION }}" + echo "Tests filter: ${{ env.TESTS_FILTER }}" + echo "Tests cleanup: ${{ env.TESTS_CLEANUP }}" + echo "----" diff --git a/.github/workflows/dist-tests.yaml b/.github/workflows/dist-tests.yaml index 631742c..a46943e 100644 --- a/.github/workflows/dist-tests.yaml +++ b/.github/workflows/dist-tests.yaml @@ -14,16 +14,16 @@ on: # - '!docker/dist-tests-job.yaml' workflow_dispatch: inputs: - branch: - description: Branch (master) - required: false - type: string source: description: Repository with tests (current) required: false type: string + branch: + description: Branch with tests (master) + required: false + type: string nameprefix: - description: Runner prefix (codex-dist-tests) + description: Runner name prefix (d-tests-runner) required: false type: string namespace: @@ -31,7 +31,7 @@ on: required: false type: string command: - description: Runner command (dotnet test Tests) + description: Command (dotnet test Tests/CodexTests) required: false type: string @@ -39,7 +39,7 @@ on: env: BRANCH: ${{ github.ref_name }} SOURCE: ${{ format('{0}/{1}', github.server_url, github.repository) }} - NAMEPREFIX: codex-dist-tests + NAMEPREFIX: d-tests-runner NAMESPACE: default COMMAND: dotnet test Tests/CodexTests JOB_MANIFEST: docker/dist-tests-job.yaml @@ -79,3 +79,15 @@ jobs: - name: Kubectl - Create Job run: | envsubst < ${{ env.JOB_MANIFEST }} | kubectl apply -f - + + - name: Tests Identification + run: | + echo "----" + echo "Repository: ${{ env.SOURCE }}" + echo "Branch: ${{ env.BRANCH }}" + echo "Runner Pod: ${{ env.NAMEPREFIX }}-${{ env.RUNID }}" + echo "Runner namespace: ${{ env.NAMESPACE }}" + echo "----" + echo "Tests runid: ${{ env.RUNID }}" + echo "Tests command: `jq -r '. | join(" ")' <<< '${{ env.COMMAND }}'`" + echo "----" diff --git a/Framework/Core/CoreInterface.cs b/Framework/Core/CoreInterface.cs index 21b9491..b43c1c2 100644 --- a/Framework/Core/CoreInterface.cs +++ b/Framework/Core/CoreInterface.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace Core { diff --git a/Framework/KubernetesWorkflow/K8sCluster.cs b/Framework/KubernetesWorkflow/K8sCluster.cs index 4d21aaf..366855f 100644 --- a/Framework/KubernetesWorkflow/K8sCluster.cs +++ b/Framework/KubernetesWorkflow/K8sCluster.cs @@ -54,16 +54,4 @@ namespace KubernetesWorkflow } } } - - public class K8sNodeLabel - { - public K8sNodeLabel(string key, string value) - { - Key = key; - Value = value; - } - - public string Key { get; } - public string Value { get; } - } } diff --git a/Framework/KubernetesWorkflow/K8sController.cs b/Framework/KubernetesWorkflow/K8sController.cs index a8fcfa4..4d4ca11 100644 --- a/Framework/KubernetesWorkflow/K8sController.cs +++ b/Framework/KubernetesWorkflow/K8sController.cs @@ -1,5 +1,7 @@ using k8s; using k8s.Models; +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; using Logging; using Utils; @@ -623,11 +625,28 @@ namespace KubernetesWorkflow } private V1Pod GetPodForDeployment(RunningDeployment deployment) + { + return Time.Retry(() => GetPodForDeplomentInternal(deployment), + maxRetries: 2, + retryTime: TimeSpan.FromSeconds(10), + description: "Find pod by label for deployment."); + } + + private V1Pod GetPodForDeplomentInternal(RunningDeployment deployment) { var allPods = client.Run(c => c.ListNamespacedPod(K8sNamespace)); var pods = allPods.Items.Where(p => p.GetLabel(PodLabelKey) == deployment.PodLabel).ToArray(); - if (pods.Length != 1) throw new Exception("Expected to find only 1 pod by podLabel."); + if (pods.Length != 1) + { + var allLabels = allPods.Items.Select(p => + { + var labels = string.Join(",", p.Labels().Select(l => $"{l.Key}={l.Value}")); + return $"pod:'{p.Name()}' has labels: [{labels}]"; + }); + throw new Exception($"Expected to find 1 pod by podLabel '{deployment.PodLabel}'. Found: {pods.Length}. " + + $"Total number of pods: {allPods.Items.Count}. Their labels: {string.Join(Environment.NewLine, allLabels)}"); + } return pods[0]; } diff --git a/Framework/KubernetesWorkflow/K8sHooks.cs b/Framework/KubernetesWorkflow/K8sHooks.cs index 91c25a3..74bb93b 100644 --- a/Framework/KubernetesWorkflow/K8sHooks.cs +++ b/Framework/KubernetesWorkflow/K8sHooks.cs @@ -1,4 +1,7 @@ -namespace KubernetesWorkflow +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; + +namespace KubernetesWorkflow { public interface IK8sHooks { diff --git a/Framework/KubernetesWorkflow/Location.cs b/Framework/KubernetesWorkflow/Location.cs index ab0985c..d6d593f 100644 --- a/Framework/KubernetesWorkflow/Location.cs +++ b/Framework/KubernetesWorkflow/Location.cs @@ -1,4 +1,6 @@ -namespace KubernetesWorkflow +using KubernetesWorkflow.Types; + +namespace KubernetesWorkflow { public interface ILocation { diff --git a/Framework/KubernetesWorkflow/LocationProvider.cs b/Framework/KubernetesWorkflow/LocationProvider.cs index 1f4e6bf..8aa2663 100644 --- a/Framework/KubernetesWorkflow/LocationProvider.cs +++ b/Framework/KubernetesWorkflow/LocationProvider.cs @@ -1,4 +1,5 @@ -using Logging; +using KubernetesWorkflow.Types; +using Logging; namespace KubernetesWorkflow { diff --git a/Framework/KubernetesWorkflow/LogHandler.cs b/Framework/KubernetesWorkflow/LogHandler.cs new file mode 100644 index 0000000..77e5746 --- /dev/null +++ b/Framework/KubernetesWorkflow/LogHandler.cs @@ -0,0 +1,23 @@ +namespace KubernetesWorkflow +{ + public interface ILogHandler + { + void Log(Stream log); + } + + public abstract class LogHandler : ILogHandler + { + public void Log(Stream log) + { + using var reader = new StreamReader(log); + var line = reader.ReadLine(); + while (line != null) + { + ProcessLine(line); + line = reader.ReadLine(); + } + } + + protected abstract void ProcessLine(string line); + } +} diff --git a/Framework/KubernetesWorkflow/ContainerAdditionals.cs b/Framework/KubernetesWorkflow/Recipe/ContainerAdditionals.cs similarity index 94% rename from Framework/KubernetesWorkflow/ContainerAdditionals.cs rename to Framework/KubernetesWorkflow/Recipe/ContainerAdditionals.cs index 015e55b..21fe249 100644 --- a/Framework/KubernetesWorkflow/ContainerAdditionals.cs +++ b/Framework/KubernetesWorkflow/Recipe/ContainerAdditionals.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json.Linq; -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public class ContainerAdditionals { @@ -20,7 +20,7 @@ namespace KubernetesWorkflow { var typeName = GetTypeName(typeof(T)); var userData = Additionals.SingleOrDefault(a => a.Type == typeName); - if (userData == null) return default(T); + if (userData == null) return default; var jobject = (JObject)userData.UserData; return jobject.ToObject(); } diff --git a/Framework/KubernetesWorkflow/ContainerRecipe.cs b/Framework/KubernetesWorkflow/Recipe/ContainerRecipe.cs similarity index 99% rename from Framework/KubernetesWorkflow/ContainerRecipe.cs rename to Framework/KubernetesWorkflow/Recipe/ContainerRecipe.cs index 19d063b..b66bd42 100644 --- a/Framework/KubernetesWorkflow/ContainerRecipe.cs +++ b/Framework/KubernetesWorkflow/Recipe/ContainerRecipe.cs @@ -1,4 +1,4 @@ -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public class ContainerRecipe { diff --git a/Framework/KubernetesWorkflow/ContainerRecipeFactory.cs b/Framework/KubernetesWorkflow/Recipe/ContainerRecipeFactory.cs similarity index 99% rename from Framework/KubernetesWorkflow/ContainerRecipeFactory.cs rename to Framework/KubernetesWorkflow/Recipe/ContainerRecipeFactory.cs index 3fdd5de..134b280 100644 --- a/Framework/KubernetesWorkflow/ContainerRecipeFactory.cs +++ b/Framework/KubernetesWorkflow/Recipe/ContainerRecipeFactory.cs @@ -1,6 +1,6 @@ using Utils; -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public abstract class ContainerRecipeFactory { diff --git a/Framework/KubernetesWorkflow/ContainerResources.cs b/Framework/KubernetesWorkflow/Recipe/ContainerResources.cs similarity index 97% rename from Framework/KubernetesWorkflow/ContainerResources.cs rename to Framework/KubernetesWorkflow/Recipe/ContainerResources.cs index 40e5dc5..6b8b8a3 100644 --- a/Framework/KubernetesWorkflow/ContainerResources.cs +++ b/Framework/KubernetesWorkflow/Recipe/ContainerResources.cs @@ -1,6 +1,6 @@ using Utils; -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public class ContainerResources { diff --git a/Framework/KubernetesWorkflow/PodAnnotations.cs b/Framework/KubernetesWorkflow/Recipe/PodAnnotations.cs similarity index 94% rename from Framework/KubernetesWorkflow/PodAnnotations.cs rename to Framework/KubernetesWorkflow/Recipe/PodAnnotations.cs index 16edb8a..4de2e98 100644 --- a/Framework/KubernetesWorkflow/PodAnnotations.cs +++ b/Framework/KubernetesWorkflow/Recipe/PodAnnotations.cs @@ -1,4 +1,4 @@ -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public class PodAnnotations { diff --git a/Framework/KubernetesWorkflow/PodLabels.cs b/Framework/KubernetesWorkflow/Recipe/PodLabels.cs similarity index 94% rename from Framework/KubernetesWorkflow/PodLabels.cs rename to Framework/KubernetesWorkflow/Recipe/PodLabels.cs index d8b7333..c7f8d8e 100644 --- a/Framework/KubernetesWorkflow/PodLabels.cs +++ b/Framework/KubernetesWorkflow/Recipe/PodLabels.cs @@ -1,4 +1,4 @@ -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public class PodLabels { diff --git a/Framework/KubernetesWorkflow/RecipeComponentFactory.cs b/Framework/KubernetesWorkflow/Recipe/RecipeComponentFactory.cs similarity index 95% rename from Framework/KubernetesWorkflow/RecipeComponentFactory.cs rename to Framework/KubernetesWorkflow/Recipe/RecipeComponentFactory.cs index 71f37b3..c144746 100644 --- a/Framework/KubernetesWorkflow/RecipeComponentFactory.cs +++ b/Framework/KubernetesWorkflow/Recipe/RecipeComponentFactory.cs @@ -1,7 +1,7 @@ using System.Globalization; using Utils; -namespace KubernetesWorkflow +namespace KubernetesWorkflow.Recipe { public class RecipeComponentFactory { diff --git a/Framework/KubernetesWorkflow/RunningContainers.cs b/Framework/KubernetesWorkflow/RunningContainers.cs deleted file mode 100644 index 602f6a4..0000000 --- a/Framework/KubernetesWorkflow/RunningContainers.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Logging; -using Newtonsoft.Json; -using Utils; - -namespace KubernetesWorkflow -{ - public class RunningContainers - { - public RunningContainers(StartupConfig startupConfig, StartResult startResult, RunningContainer[] containers) - { - StartupConfig = startupConfig; - StartResult = startResult; - Containers = containers; - - foreach (var c in containers) c.RunningContainers = this; - } - - public StartupConfig StartupConfig { get; } - public StartResult StartResult { get; } - public RunningContainer[] Containers { get; } - - [JsonIgnore] - public string Name - { - get { return $"{Containers.Length}x '{Containers.First().Name}'"; } - } - - public string Describe() - { - return string.Join(",", Containers.Select(c => c.Name)); - } - } - - public class RunningContainer - { - public RunningContainer(string name, ContainerRecipe recipe, ContainerAddress[] addresses) - { - Name = name; - Recipe = recipe; - Addresses = addresses; - } - - public string Name { get; } - public ContainerRecipe Recipe { get; } - public ContainerAddress[] Addresses { get; } - - [JsonIgnore] - public RunningContainers RunningContainers { get; internal set; } = null!; - - public Address GetAddress(ILog log, string portTag) - { - var addresses = Addresses.Where(a => a.PortTag == portTag).ToArray(); - if (!addresses.Any()) throw new Exception("No addresses found for portTag: " + portTag); - - var select = SelectAddress(addresses); - log.Log($"Container '{Name}' selected for tag '{portTag}' address: '{select}'"); - return select.Address; - } - - public Address GetInternalAddress(string portTag) - { - var containerAddress = Addresses.Single(a => a.PortTag == portTag && a.IsInteral); - return containerAddress.Address; - } - - private ContainerAddress SelectAddress(ContainerAddress[] addresses) - { - var location = RunnerLocationUtils.GetRunnerLocation(); - if (location == RunnerLocation.InternalToCluster) - { - return addresses.Single(a => a.IsInteral); - } - if (location == RunnerLocation.ExternalToCluster) - { - return addresses.Single(a => !a.IsInteral); - } - throw new Exception("Running location not known."); - } - } - - public class ContainerAddress - { - public ContainerAddress(string portTag, Address address, bool isInteral) - { - PortTag = portTag; - Address = address; - IsInteral = isInteral; - } - - public string PortTag { get; } - public Address Address { get; } - public bool IsInteral { get; } - - public override string ToString() - { - var indicator = IsInteral ? "int" : "ext"; - return $"{indicator} {PortTag} -> '{Address}'"; - } - } - - public static class RunningContainersExtensions - { - public static RunningContainer[] Containers(this RunningContainers[] runningContainers) - { - return runningContainers.SelectMany(c => c.Containers).ToArray(); - } - - public static string Describe(this RunningContainers[] runningContainers) - { - return string.Join(",", runningContainers.Select(c => c.Describe())); - } - } -} diff --git a/Framework/KubernetesWorkflow/RunningPod.cs b/Framework/KubernetesWorkflow/RunningPod.cs index cdda1dc..e86b2aa 100644 --- a/Framework/KubernetesWorkflow/RunningPod.cs +++ b/Framework/KubernetesWorkflow/RunningPod.cs @@ -1,5 +1,7 @@ using k8s; using k8s.Models; +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; using Newtonsoft.Json; namespace KubernetesWorkflow @@ -64,76 +66,4 @@ namespace KubernetesWorkflow return Array.Empty(); } } - - public class RunningDeployment - { - public RunningDeployment(string name, string podLabel) - { - Name = name; - PodLabel = podLabel; - } - - public string Name { get; } - public string PodLabel { get; } - - public V1Pod GetPod(K8sClient client, string k8sNamespace) - { - var allPods = client.Run(c => c.ListNamespacedPod(k8sNamespace)); - var pods = allPods.Items.Where(p => p.GetLabel(K8sController.PodLabelKey) == PodLabel).ToArray(); - - if (pods.Length != 1) throw new Exception("Expected to find only 1 pod by podLabel."); - return pods[0]; - } - } - - public class RunningService - { - public RunningService(string name, List result) - { - Name = name; - Result = result; - } - - public string Name { get; } - public List Result { get; } - - public Port? GetServicePortForRecipeAndTag(ContainerRecipe recipe, string tag) - { - return GetServicePortsForRecipe(recipe).SingleOrDefault(p => p.Tag == tag); - } - - public Port[] GetServicePortsForRecipe(ContainerRecipe recipe) - { - return Result - .Where(p => p.RecipeNumber == recipe.Number) - .SelectMany(p => p.Ports) - .ToArray(); - } - } - - public class ContainerRecipePortMapEntry - { - public ContainerRecipePortMapEntry(int recipeNumber, Port[] ports) - { - RecipeNumber = recipeNumber; - Ports = ports; - } - - public int RecipeNumber { get; } - public Port[] Ports { get; } - } - - public class PodInfo - { - public PodInfo(string name, string ip, string k8sNodeName) - { - Name = name; - Ip = ip; - K8SNodeName = k8sNodeName; - } - - public string Name { get; } - public string Ip { get; } - public string K8SNodeName { get; } - } } diff --git a/Framework/KubernetesWorkflow/StartupWorkflow.cs b/Framework/KubernetesWorkflow/StartupWorkflow.cs index 6f613ee..20ab753 100644 --- a/Framework/KubernetesWorkflow/StartupWorkflow.cs +++ b/Framework/KubernetesWorkflow/StartupWorkflow.cs @@ -1,4 +1,6 @@ -using Logging; +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; +using Logging; using Newtonsoft.Json; using Utils; @@ -241,25 +243,4 @@ namespace KubernetesWorkflow } } } - - public interface ILogHandler - { - void Log(Stream log); - } - - public abstract class LogHandler : ILogHandler - { - public void Log(Stream log) - { - using var reader = new StreamReader(log); - var line = reader.ReadLine(); - while (line != null) - { - ProcessLine(line); - line = reader.ReadLine(); - } - } - - protected abstract void ProcessLine(string line); - } } diff --git a/Framework/KubernetesWorkflow/Types/ContainerAddress.cs b/Framework/KubernetesWorkflow/Types/ContainerAddress.cs new file mode 100644 index 0000000..e40ee42 --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/ContainerAddress.cs @@ -0,0 +1,24 @@ +using Utils; + +namespace KubernetesWorkflow.Types +{ + public class ContainerAddress + { + public ContainerAddress(string portTag, Address address, bool isInteral) + { + PortTag = portTag; + Address = address; + IsInteral = isInteral; + } + + public string PortTag { get; } + public Address Address { get; } + public bool IsInteral { get; } + + public override string ToString() + { + var indicator = IsInteral ? "int" : "ext"; + return $"{indicator} {PortTag} -> '{Address}'"; + } + } +} diff --git a/Framework/KubernetesWorkflow/Types/ContainerRecipePortMapEntry.cs b/Framework/KubernetesWorkflow/Types/ContainerRecipePortMapEntry.cs new file mode 100644 index 0000000..debdfcf --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/ContainerRecipePortMapEntry.cs @@ -0,0 +1,16 @@ +using KubernetesWorkflow.Recipe; + +namespace KubernetesWorkflow.Types +{ + public class ContainerRecipePortMapEntry + { + public ContainerRecipePortMapEntry(int recipeNumber, Port[] ports) + { + RecipeNumber = recipeNumber; + Ports = ports; + } + + public int RecipeNumber { get; } + public Port[] Ports { get; } + } +} diff --git a/Framework/KubernetesWorkflow/Types/K8sNodeLabel.cs b/Framework/KubernetesWorkflow/Types/K8sNodeLabel.cs new file mode 100644 index 0000000..ba3dc9a --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/K8sNodeLabel.cs @@ -0,0 +1,14 @@ +namespace KubernetesWorkflow.Types +{ + public class K8sNodeLabel + { + public K8sNodeLabel(string key, string value) + { + Key = key; + Value = value; + } + + public string Key { get; } + public string Value { get; } + } +} diff --git a/Framework/KubernetesWorkflow/Types/PodInfo.cs b/Framework/KubernetesWorkflow/Types/PodInfo.cs new file mode 100644 index 0000000..ca8ee37 --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/PodInfo.cs @@ -0,0 +1,16 @@ +namespace KubernetesWorkflow.Types +{ + public class PodInfo + { + public PodInfo(string name, string ip, string k8sNodeName) + { + Name = name; + Ip = ip; + K8SNodeName = k8sNodeName; + } + + public string Name { get; } + public string Ip { get; } + public string K8SNodeName { get; } + } +} diff --git a/Framework/KubernetesWorkflow/Types/RunningContainer.cs b/Framework/KubernetesWorkflow/Types/RunningContainer.cs new file mode 100644 index 0000000..f391e45 --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/RunningContainer.cs @@ -0,0 +1,54 @@ +using KubernetesWorkflow.Recipe; +using Logging; +using Newtonsoft.Json; +using Utils; + +namespace KubernetesWorkflow.Types +{ + public class RunningContainer + { + public RunningContainer(string name, ContainerRecipe recipe, ContainerAddress[] addresses) + { + Name = name; + Recipe = recipe; + Addresses = addresses; + } + + public string Name { get; } + public ContainerRecipe Recipe { get; } + public ContainerAddress[] Addresses { get; } + + [JsonIgnore] + public RunningContainers RunningContainers { get; internal set; } = null!; + + public Address GetAddress(ILog log, string portTag) + { + var addresses = Addresses.Where(a => a.PortTag == portTag).ToArray(); + if (!addresses.Any()) throw new Exception("No addresses found for portTag: " + portTag); + + var select = SelectAddress(addresses); + log.Debug($"Container '{Name}' selected for tag '{portTag}' address: '{select}'"); + return select.Address; + } + + public Address GetInternalAddress(string portTag) + { + var containerAddress = Addresses.Single(a => a.PortTag == portTag && a.IsInteral); + return containerAddress.Address; + } + + private ContainerAddress SelectAddress(ContainerAddress[] addresses) + { + var location = RunnerLocationUtils.GetRunnerLocation(); + if (location == RunnerLocation.InternalToCluster) + { + return addresses.Single(a => a.IsInteral); + } + if (location == RunnerLocation.ExternalToCluster) + { + return addresses.Single(a => !a.IsInteral); + } + throw new Exception("Running location not known."); + } + } +} diff --git a/Framework/KubernetesWorkflow/Types/RunningContainers.cs b/Framework/KubernetesWorkflow/Types/RunningContainers.cs new file mode 100644 index 0000000..9a6e5f3 --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/RunningContainers.cs @@ -0,0 +1,44 @@ +using Newtonsoft.Json; + +namespace KubernetesWorkflow.Types +{ + public class RunningContainers + { + public RunningContainers(StartupConfig startupConfig, StartResult startResult, RunningContainer[] containers) + { + StartupConfig = startupConfig; + StartResult = startResult; + Containers = containers; + + foreach (var c in containers) c.RunningContainers = this; + } + + public StartupConfig StartupConfig { get; } + public StartResult StartResult { get; } + public RunningContainer[] Containers { get; } + + [JsonIgnore] + public string Name + { + get { return $"{Containers.Length}x '{Containers.First().Name}'"; } + } + + public string Describe() + { + return string.Join(",", Containers.Select(c => c.Name)); + } + } + + public static class RunningContainersExtensions + { + public static RunningContainer[] Containers(this RunningContainers[] runningContainers) + { + return runningContainers.SelectMany(c => c.Containers).ToArray(); + } + + public static string Describe(this RunningContainers[] runningContainers) + { + return string.Join(",", runningContainers.Select(c => c.Describe())); + } + } +} diff --git a/Framework/KubernetesWorkflow/Types/RunningDeployment.cs b/Framework/KubernetesWorkflow/Types/RunningDeployment.cs new file mode 100644 index 0000000..05298ed --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/RunningDeployment.cs @@ -0,0 +1,14 @@ +namespace KubernetesWorkflow.Types +{ + public class RunningDeployment + { + public RunningDeployment(string name, string podLabel) + { + Name = name; + PodLabel = podLabel; + } + + public string Name { get; } + public string PodLabel { get; } + } +} diff --git a/Framework/KubernetesWorkflow/Types/RunningService.cs b/Framework/KubernetesWorkflow/Types/RunningService.cs new file mode 100644 index 0000000..6e2e1f9 --- /dev/null +++ b/Framework/KubernetesWorkflow/Types/RunningService.cs @@ -0,0 +1,29 @@ +using KubernetesWorkflow.Recipe; + +namespace KubernetesWorkflow.Types +{ + public class RunningService + { + public RunningService(string name, List result) + { + Name = name; + Result = result; + } + + public string Name { get; } + public List Result { get; } + + public Port? GetServicePortForRecipeAndTag(ContainerRecipe recipe, string tag) + { + return GetServicePortsForRecipe(recipe).SingleOrDefault(p => p.Tag == tag); + } + + public Port[] GetServicePortsForRecipe(ContainerRecipe recipe) + { + return Result + .Where(p => p.RecipeNumber == recipe.Number) + .SelectMany(p => p.Ports) + .ToArray(); + } + } +} diff --git a/Framework/Utils/Time.cs b/Framework/Utils/Time.cs index 3a53b72..d6df480 100644 --- a/Framework/Utils/Time.cs +++ b/Framework/Utils/Time.cs @@ -56,12 +56,12 @@ public static void Retry(Action action, int maxRetries, string description) { - Retry(action, maxRetries, TimeSpan.FromSeconds(1), description); + Retry(action, maxRetries, TimeSpan.FromSeconds(5), description); } public static T Retry(Func action, int maxRetries, string description) { - return Retry(action, maxRetries, TimeSpan.FromSeconds(1), description); + return Retry(action, maxRetries, TimeSpan.FromSeconds(5), description); } public static void Retry(Action action, int maxRetries, TimeSpan retryTime, string description) diff --git a/ProjectPlugins/CodexContractsPlugin/CodexContractsContainerRecipe.cs b/ProjectPlugins/CodexContractsPlugin/CodexContractsContainerRecipe.cs index 1dffe3f..d6dd92f 100644 --- a/ProjectPlugins/CodexContractsPlugin/CodexContractsContainerRecipe.cs +++ b/ProjectPlugins/CodexContractsPlugin/CodexContractsContainerRecipe.cs @@ -1,5 +1,6 @@ using GethPlugin; using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; using Logging; namespace CodexContractsPlugin diff --git a/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs b/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs index 8fb1bfd..acfc0ac 100644 --- a/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs +++ b/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs @@ -1,6 +1,7 @@ using Core; using GethPlugin; using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using Utils; diff --git a/ProjectPlugins/CodexContractsPlugin/ContractsContainerInfoExtractor.cs b/ProjectPlugins/CodexContractsPlugin/ContractsContainerInfoExtractor.cs index 2ea164c..94cf4e6 100644 --- a/ProjectPlugins/CodexContractsPlugin/ContractsContainerInfoExtractor.cs +++ b/ProjectPlugins/CodexContractsPlugin/ContractsContainerInfoExtractor.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/ProjectPlugins/CodexDiscordBotPlugin/CodexDiscordBotPlugin.cs b/ProjectPlugins/CodexDiscordBotPlugin/CodexDiscordBotPlugin.cs index b92230a..91c38e4 100644 --- a/ProjectPlugins/CodexDiscordBotPlugin/CodexDiscordBotPlugin.cs +++ b/ProjectPlugins/CodexDiscordBotPlugin/CodexDiscordBotPlugin.cs @@ -1,5 +1,6 @@ using Core; using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexDiscordBotPlugin { diff --git a/ProjectPlugins/CodexDiscordBotPlugin/CoreInterfaceExtensions.cs b/ProjectPlugins/CodexDiscordBotPlugin/CoreInterfaceExtensions.cs index 86f2129..1c3d673 100644 --- a/ProjectPlugins/CodexDiscordBotPlugin/CoreInterfaceExtensions.cs +++ b/ProjectPlugins/CodexDiscordBotPlugin/CoreInterfaceExtensions.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexDiscordBotPlugin { diff --git a/ProjectPlugins/CodexDiscordBotPlugin/DiscordBotContainerRecipe.cs b/ProjectPlugins/CodexDiscordBotPlugin/DiscordBotContainerRecipe.cs index c65dd9c..b4b1432 100644 --- a/ProjectPlugins/CodexDiscordBotPlugin/DiscordBotContainerRecipe.cs +++ b/ProjectPlugins/CodexDiscordBotPlugin/DiscordBotContainerRecipe.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; using Utils; namespace CodexDiscordBotPlugin diff --git a/ProjectPlugins/CodexPlugin/CodexAccess.cs b/ProjectPlugins/CodexPlugin/CodexAccess.cs index 3d11abe..9fa1683 100644 --- a/ProjectPlugins/CodexPlugin/CodexAccess.cs +++ b/ProjectPlugins/CodexPlugin/CodexAccess.cs @@ -1,5 +1,6 @@ using Core; using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Utils; namespace CodexPlugin diff --git a/ProjectPlugins/CodexPlugin/CodexApiTypes.cs b/ProjectPlugins/CodexPlugin/CodexApiTypes.cs index 03e112f..af52383 100644 --- a/ProjectPlugins/CodexPlugin/CodexApiTypes.cs +++ b/ProjectPlugins/CodexPlugin/CodexApiTypes.cs @@ -76,12 +76,7 @@ namespace CodexPlugin public string peerId { get; set; } = string.Empty; public long seqNo { get; set; } - public CodexDebugPeerAddressResponse[] addresses { get; set; } = Array.Empty(); - } - - public class CodexDebugPeerAddressResponse - { - public string address { get; set; } = string.Empty; + public string[] addresses { get; set; } = Array.Empty(); } public class CodexDebugThresholdBreaches diff --git a/ProjectPlugins/CodexPlugin/CodexContainerRecipe.cs b/ProjectPlugins/CodexPlugin/CodexContainerRecipe.cs index 2d80be2..bfdf52b 100644 --- a/ProjectPlugins/CodexPlugin/CodexContainerRecipe.cs +++ b/ProjectPlugins/CodexPlugin/CodexContainerRecipe.cs @@ -1,5 +1,6 @@ using GethPlugin; using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; using Utils; namespace CodexPlugin diff --git a/ProjectPlugins/CodexPlugin/CodexDeployment.cs b/ProjectPlugins/CodexPlugin/CodexDeployment.cs index 238b116..e1548ed 100644 --- a/ProjectPlugins/CodexPlugin/CodexDeployment.cs +++ b/ProjectPlugins/CodexPlugin/CodexDeployment.cs @@ -1,6 +1,6 @@ using CodexContractsPlugin; using GethPlugin; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexPlugin { diff --git a/ProjectPlugins/CodexPlugin/CodexNode.cs b/ProjectPlugins/CodexPlugin/CodexNode.cs index e688d5d..d0a0636 100644 --- a/ProjectPlugins/CodexPlugin/CodexNode.cs +++ b/ProjectPlugins/CodexPlugin/CodexNode.cs @@ -2,6 +2,7 @@ using FileUtils; using GethPlugin; using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using MetricsPlugin; using Utils; @@ -164,8 +165,9 @@ namespace CodexPlugin throw new Exception($"Invalid version information received from Codex node {GetName()}: {debugInfo.codex}"); } - //lifecycle.Log.AddStringReplace(nodePeerId, nodeName); - //lifecycle.Log.AddStringReplace(debugInfo.table.localNode.nodeId, nodeName); + var log = tools.GetLog(); + log.AddStringReplace(nodePeerId, nodeName); + log.AddStringReplace(debugInfo.table.localNode.nodeId, nodeName); Version = debugInfo.codex; } diff --git a/ProjectPlugins/CodexPlugin/CodexNodeFactory.cs b/ProjectPlugins/CodexPlugin/CodexNodeFactory.cs index 4b9dfdd..f0c7166 100644 --- a/ProjectPlugins/CodexPlugin/CodexNodeFactory.cs +++ b/ProjectPlugins/CodexPlugin/CodexNodeFactory.cs @@ -1,6 +1,7 @@ using Core; using GethPlugin; using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexPlugin { diff --git a/ProjectPlugins/CodexPlugin/CodexNodeGroup.cs b/ProjectPlugins/CodexPlugin/CodexNodeGroup.cs index 01c5661..0b6dee7 100644 --- a/ProjectPlugins/CodexPlugin/CodexNodeGroup.cs +++ b/ProjectPlugins/CodexPlugin/CodexNodeGroup.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using MetricsPlugin; using System.Collections; diff --git a/ProjectPlugins/CodexPlugin/CodexPlugin.cs b/ProjectPlugins/CodexPlugin/CodexPlugin.cs index 1c83d81..205b0d2 100644 --- a/ProjectPlugins/CodexPlugin/CodexPlugin.cs +++ b/ProjectPlugins/CodexPlugin/CodexPlugin.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexPlugin { diff --git a/ProjectPlugins/CodexPlugin/CodexStarter.cs b/ProjectPlugins/CodexPlugin/CodexStarter.cs index 718ef22..ae217c7 100644 --- a/ProjectPlugins/CodexPlugin/CodexStarter.cs +++ b/ProjectPlugins/CodexPlugin/CodexStarter.cs @@ -1,5 +1,6 @@ using Core; using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; namespace CodexPlugin diff --git a/ProjectPlugins/CodexPlugin/CoreInterfaceExtensions.cs b/ProjectPlugins/CodexPlugin/CoreInterfaceExtensions.cs index a79615e..529b7fd 100644 --- a/ProjectPlugins/CodexPlugin/CoreInterfaceExtensions.cs +++ b/ProjectPlugins/CodexPlugin/CoreInterfaceExtensions.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexPlugin { diff --git a/ProjectPlugins/DeployAndRunPlugin/CoreInterfaceExtensions.cs b/ProjectPlugins/DeployAndRunPlugin/CoreInterfaceExtensions.cs index 262e27d..f0d71f4 100644 --- a/ProjectPlugins/DeployAndRunPlugin/CoreInterfaceExtensions.cs +++ b/ProjectPlugins/DeployAndRunPlugin/CoreInterfaceExtensions.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace DeployAndRunPlugin { diff --git a/ProjectPlugins/DeployAndRunPlugin/DeployAndRunContainerRecipe.cs b/ProjectPlugins/DeployAndRunPlugin/DeployAndRunContainerRecipe.cs index 9692225..866cfaf 100644 --- a/ProjectPlugins/DeployAndRunPlugin/DeployAndRunContainerRecipe.cs +++ b/ProjectPlugins/DeployAndRunPlugin/DeployAndRunContainerRecipe.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; namespace DeployAndRunPlugin { diff --git a/ProjectPlugins/DeployAndRunPlugin/DeployAndRunPlugin.cs b/ProjectPlugins/DeployAndRunPlugin/DeployAndRunPlugin.cs index 82d80e0..070b9fe 100644 --- a/ProjectPlugins/DeployAndRunPlugin/DeployAndRunPlugin.cs +++ b/ProjectPlugins/DeployAndRunPlugin/DeployAndRunPlugin.cs @@ -1,5 +1,6 @@ using Core; using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace DeployAndRunPlugin { diff --git a/ProjectPlugins/GethPlugin/GethContainerInfoExtractor.cs b/ProjectPlugins/GethPlugin/GethContainerInfoExtractor.cs index 51c8728..4fc7676 100644 --- a/ProjectPlugins/GethPlugin/GethContainerInfoExtractor.cs +++ b/ProjectPlugins/GethPlugin/GethContainerInfoExtractor.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using Utils; diff --git a/ProjectPlugins/GethPlugin/GethContainerRecipe.cs b/ProjectPlugins/GethPlugin/GethContainerRecipe.cs index e74c2c5..f9eaf79 100644 --- a/ProjectPlugins/GethPlugin/GethContainerRecipe.cs +++ b/ProjectPlugins/GethPlugin/GethContainerRecipe.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; namespace GethPlugin { diff --git a/ProjectPlugins/GethPlugin/GethDeployment.cs b/ProjectPlugins/GethPlugin/GethDeployment.cs index 2461811..8d7f0dd 100644 --- a/ProjectPlugins/GethPlugin/GethDeployment.cs +++ b/ProjectPlugins/GethPlugin/GethDeployment.cs @@ -1,5 +1,6 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; using Newtonsoft.Json; namespace GethPlugin diff --git a/ProjectPlugins/GethPlugin/GethNode.cs b/ProjectPlugins/GethPlugin/GethNode.cs index 2e6a30b..19c3708 100644 --- a/ProjectPlugins/GethPlugin/GethNode.cs +++ b/ProjectPlugins/GethPlugin/GethNode.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using Nethereum.Contracts; using NethereumWorkflow; diff --git a/ProjectPlugins/MetricsPlugin/CoreInterfaceExtensions.cs b/ProjectPlugins/MetricsPlugin/CoreInterfaceExtensions.cs index 279594b..8392082 100644 --- a/ProjectPlugins/MetricsPlugin/CoreInterfaceExtensions.cs +++ b/ProjectPlugins/MetricsPlugin/CoreInterfaceExtensions.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; namespace MetricsPlugin diff --git a/ProjectPlugins/MetricsPlugin/MetricsAccess.cs b/ProjectPlugins/MetricsPlugin/MetricsAccess.cs index 0f8ef01..a35fc80 100644 --- a/ProjectPlugins/MetricsPlugin/MetricsAccess.cs +++ b/ProjectPlugins/MetricsPlugin/MetricsAccess.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Utils; namespace MetricsPlugin diff --git a/ProjectPlugins/MetricsPlugin/MetricsPlugin.cs b/ProjectPlugins/MetricsPlugin/MetricsPlugin.cs index a99ae0b..b2c2b8e 100644 --- a/ProjectPlugins/MetricsPlugin/MetricsPlugin.cs +++ b/ProjectPlugins/MetricsPlugin/MetricsPlugin.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; namespace MetricsPlugin diff --git a/ProjectPlugins/MetricsPlugin/MetricsQuery.cs b/ProjectPlugins/MetricsPlugin/MetricsQuery.cs index 62a0553..427d35d 100644 --- a/ProjectPlugins/MetricsPlugin/MetricsQuery.cs +++ b/ProjectPlugins/MetricsPlugin/MetricsQuery.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using System.Globalization; diff --git a/ProjectPlugins/MetricsPlugin/MetricsScrapeTarget.cs b/ProjectPlugins/MetricsPlugin/MetricsScrapeTarget.cs index 1913712..5c9cbd1 100644 --- a/ProjectPlugins/MetricsPlugin/MetricsScrapeTarget.cs +++ b/ProjectPlugins/MetricsPlugin/MetricsScrapeTarget.cs @@ -1,4 +1,4 @@ -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace MetricsPlugin { diff --git a/ProjectPlugins/MetricsPlugin/PrometheusContainerRecipe.cs b/ProjectPlugins/MetricsPlugin/PrometheusContainerRecipe.cs index 2696915..a4dfdb4 100644 --- a/ProjectPlugins/MetricsPlugin/PrometheusContainerRecipe.cs +++ b/ProjectPlugins/MetricsPlugin/PrometheusContainerRecipe.cs @@ -1,4 +1,5 @@ using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; namespace MetricsPlugin { diff --git a/ProjectPlugins/MetricsPlugin/PrometheusStarter.cs b/ProjectPlugins/MetricsPlugin/PrometheusStarter.cs index 6c04c72..0f0bc13 100644 --- a/ProjectPlugins/MetricsPlugin/PrometheusStarter.cs +++ b/ProjectPlugins/MetricsPlugin/PrometheusStarter.cs @@ -1,5 +1,6 @@ using Core; using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using System.Text; diff --git a/Tests/CodexContinuousTests/ContinuousTestRunner.cs b/Tests/CodexContinuousTests/ContinuousTestRunner.cs index 22d6ea4..77fffea 100644 --- a/Tests/CodexContinuousTests/ContinuousTestRunner.cs +++ b/Tests/CodexContinuousTests/ContinuousTestRunner.cs @@ -28,7 +28,7 @@ namespace ContinuousTests new FixtureLog(logConfig, startTime, "Overview"), new ConsoleLog() ); - var statusLog = new StatusLog(logConfig, startTime, "ContinuousTestRun"); + var statusLog = new StatusLog(logConfig, startTime, "continuous-tests", "ContinuousTestRun"); overviewLog.Log("Initializing..."); diff --git a/Tests/CodexContinuousTests/ElasticSearchLogDownloader.cs b/Tests/CodexContinuousTests/ElasticSearchLogDownloader.cs index 3311efb..9b7e608 100644 --- a/Tests/CodexContinuousTests/ElasticSearchLogDownloader.cs +++ b/Tests/CodexContinuousTests/ElasticSearchLogDownloader.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using Utils; diff --git a/Tests/CodexContinuousTests/NodeRunner.cs b/Tests/CodexContinuousTests/NodeRunner.cs index b9e78e2..488e47a 100644 --- a/Tests/CodexContinuousTests/NodeRunner.cs +++ b/Tests/CodexContinuousTests/NodeRunner.cs @@ -1,9 +1,9 @@ -using KubernetesWorkflow; -using NUnit.Framework; +using NUnit.Framework; using Logging; using Utils; using Core; using CodexPlugin; +using KubernetesWorkflow.Types; namespace ContinuousTests { diff --git a/Tests/CodexContinuousTests/SingleTestRun.cs b/Tests/CodexContinuousTests/SingleTestRun.cs index 213618c..24b47a7 100644 --- a/Tests/CodexContinuousTests/SingleTestRun.cs +++ b/Tests/CodexContinuousTests/SingleTestRun.cs @@ -1,11 +1,11 @@ using Logging; using Utils; -using KubernetesWorkflow; using NUnit.Framework.Internal; using System.Reflection; using CodexPlugin; using DistTestCore.Logs; using Core; +using KubernetesWorkflow.Types; namespace ContinuousTests { diff --git a/Tests/CodexContinuousTests/Tests/PeersTest.cs b/Tests/CodexContinuousTests/Tests/PeersTest.cs index 8d5d08b..38d2f4f 100644 --- a/Tests/CodexContinuousTests/Tests/PeersTest.cs +++ b/Tests/CodexContinuousTests/Tests/PeersTest.cs @@ -1,8 +1,9 @@ using CodexPlugin; -using DistTestCore.Helpers; +using CodexTests.Helpers; +using ContinuousTests; using NUnit.Framework; -namespace ContinuousTests.Tests +namespace CodexContinuousTests.Tests { public class PeersTest : ContinuousTest { diff --git a/Tests/CodexTests/BasicTests/ContinuousSubstitute.cs b/Tests/CodexTests/BasicTests/ContinuousSubstitute.cs index 13a8b2c..9974d7d 100644 --- a/Tests/CodexTests/BasicTests/ContinuousSubstitute.cs +++ b/Tests/CodexTests/BasicTests/ContinuousSubstitute.cs @@ -1,7 +1,7 @@ using CodexContractsPlugin; using CodexPlugin; using GethPlugin; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using MetricsPlugin; using NUnit.Framework; diff --git a/Tests/CodexTests/CodexDistTest.cs b/Tests/CodexTests/CodexDistTest.cs index d651c65..4d6dab2 100644 --- a/Tests/CodexTests/CodexDistTest.cs +++ b/Tests/CodexTests/CodexDistTest.cs @@ -1,11 +1,11 @@ using CodexContractsPlugin; using CodexNetDeployer; using CodexPlugin; +using CodexTests.Helpers; using Core; using DistTestCore; using DistTestCore.Helpers; using DistTestCore.Logs; -using GethPlugin; using NUnit.Framework; using NUnit.Framework.Constraints; diff --git a/Tests/CodexTests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs b/Tests/CodexTests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs index 2f0a445..0acd780 100644 --- a/Tests/CodexTests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs +++ b/Tests/CodexTests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs @@ -1,10 +1,9 @@ using CodexContractsPlugin; -using CodexTests; using GethPlugin; using NUnit.Framework; using Utils; -namespace Tests.DownloadConnectivityTests +namespace CodexTests.DownloadConnectivityTests { [TestFixture] public class FullyConnectedDownloadTests : AutoBootstrapDistTest diff --git a/Tests/CodexTests/Helpers/FullConnectivityHelper.cs b/Tests/CodexTests/Helpers/FullConnectivityHelper.cs index e0ef335..1504c78 100644 --- a/Tests/CodexTests/Helpers/FullConnectivityHelper.cs +++ b/Tests/CodexTests/Helpers/FullConnectivityHelper.cs @@ -2,7 +2,7 @@ using Logging; using NUnit.Framework; -namespace DistTestCore.Helpers +namespace CodexTests.Helpers { public interface IFullConnectivityImplementation { diff --git a/Tests/CodexTests/Helpers/PeerConnectionTestHelpers.cs b/Tests/CodexTests/Helpers/PeerConnectionTestHelpers.cs index 5d42832..d644296 100644 --- a/Tests/CodexTests/Helpers/PeerConnectionTestHelpers.cs +++ b/Tests/CodexTests/Helpers/PeerConnectionTestHelpers.cs @@ -1,8 +1,8 @@ using CodexPlugin; using Logging; -using static DistTestCore.Helpers.FullConnectivityHelper; +using static CodexTests.Helpers.FullConnectivityHelper; -namespace DistTestCore.Helpers +namespace CodexTests.Helpers { public class PeerConnectionTestHelpers : IFullConnectivityImplementation { diff --git a/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs b/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs index 6ad178f..fab2a23 100644 --- a/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs +++ b/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs @@ -2,9 +2,9 @@ using FileUtils; using Logging; using Utils; -using static DistTestCore.Helpers.FullConnectivityHelper; +using static CodexTests.Helpers.FullConnectivityHelper; -namespace DistTestCore.Helpers +namespace CodexTests.Helpers { public class PeerDownloadTestHelpers : IFullConnectivityImplementation { diff --git a/Tests/CodexTests/PeerDiscoveryTests/LayeredDiscoveryTests.cs b/Tests/CodexTests/PeerDiscoveryTests/LayeredDiscoveryTests.cs index 310b6aa..4c8a3b3 100644 --- a/Tests/CodexTests/PeerDiscoveryTests/LayeredDiscoveryTests.cs +++ b/Tests/CodexTests/PeerDiscoveryTests/LayeredDiscoveryTests.cs @@ -1,8 +1,7 @@ using CodexPlugin; -using CodexTests; using NUnit.Framework; -namespace Tests.PeerDiscoveryTests +namespace CodexTests.PeerDiscoveryTests { [TestFixture] public class LayeredDiscoveryTests : CodexDistTest diff --git a/Tests/CodexTests/PeerDiscoveryTests/PeerDiscoveryTests.cs b/Tests/CodexTests/PeerDiscoveryTests/PeerDiscoveryTests.cs index 9eca0c6..e080faa 100644 --- a/Tests/CodexTests/PeerDiscoveryTests/PeerDiscoveryTests.cs +++ b/Tests/CodexTests/PeerDiscoveryTests/PeerDiscoveryTests.cs @@ -1,9 +1,9 @@ using CodexContractsPlugin; -using CodexTests; +using CodexPlugin; using GethPlugin; using NUnit.Framework; -namespace Tests.PeerDiscoveryTests +namespace CodexTests.PeerDiscoveryTests { [TestFixture] public class PeerDiscoveryTests : AutoBootstrapDistTest @@ -49,7 +49,45 @@ namespace Tests.PeerDiscoveryTests private void AssertAllNodesConnected() { - CreatePeerConnectionTestHelpers().AssertFullyConnected(GetAllOnlineCodexNodes()); + var allNodes = GetAllOnlineCodexNodes(); + CreatePeerConnectionTestHelpers().AssertFullyConnected(allNodes); + CheckRoutingTable(allNodes); + } + + private void CheckRoutingTable(IEnumerable allNodes) + { + var allResponses = allNodes.Select(n => n.GetDebugInfo()).ToArray(); + + var errors = new List(); + foreach (var response in allResponses) + { + var error = AreAllPresent(response, allResponses); + if (!string.IsNullOrEmpty(error)) errors.Add(error); + } + + if (errors.Any()) + { + Assert.Fail(string.Join(Environment.NewLine, errors)); + } + } + + private string AreAllPresent(CodexDebugResponse info, CodexDebugResponse[] allResponses) + { + var knownIds = info.table.nodes.Select(n => n.nodeId).ToArray(); + var allOthers = GetAllOtherResponses(info, allResponses); + var expectedIds = allOthers.Select(i => i.table.localNode.nodeId).ToArray(); + + if (!expectedIds.All(ex => knownIds.Contains(ex))) + { + return $"Node {info.id}: Not all of '{string.Join(",", expectedIds)}' were present in routing table: '{string.Join(",", knownIds)}'"; + } + + return string.Empty; + } + + private CodexDebugResponse[] GetAllOtherResponses(CodexDebugResponse exclude, CodexDebugResponse[] allResponses) + { + return allResponses.Where(r => r.id != exclude.id).ToArray(); } } } diff --git a/Tests/DistTestCore/DistTest.cs b/Tests/DistTestCore/DistTest.cs index 95e69a9..0cfdbe5 100644 --- a/Tests/DistTestCore/DistTest.cs +++ b/Tests/DistTestCore/DistTest.cs @@ -29,7 +29,7 @@ namespace DistTestCore var logConfig = configuration.GetLogConfig(); var startTime = DateTime.UtcNow; fixtureLog = new FixtureLog(logConfig, startTime); - statusLog = new StatusLog(logConfig, startTime); + statusLog = new StatusLog(logConfig, startTime, "dist-tests"); globalEntryPoint = new EntryPoint(fixtureLog, configuration.GetK8sConfiguration(new DefaultTimeSet(), TestNamespacePrefix), configuration.GetFileManagerFolder()); diff --git a/Tests/DistTestCore/Logs/StatusLog.cs b/Tests/DistTestCore/Logs/StatusLog.cs index bb41d0f..0bb82f9 100644 --- a/Tests/DistTestCore/Logs/StatusLog.cs +++ b/Tests/DistTestCore/Logs/StatusLog.cs @@ -9,11 +9,13 @@ namespace DistTestCore.Logs private readonly object fileLock = new object(); private readonly string fullName; private readonly string fixtureName; + private readonly string testType; - public StatusLog(LogConfig config, DateTime start, string name = "") + public StatusLog(LogConfig config, DateTime start, string testType, string name = "") { fullName = NameUtils.GetFixtureFullName(config, start, name) + "_STATUS.log"; fixtureName = NameUtils.GetRawFixtureName(); + this.testType = testType; } public void ConcludeTest(string resultStatus, TimeSpan testDuration, Dictionary data) @@ -26,10 +28,11 @@ namespace DistTestCore.Logs data.Add("timestamp", DateTime.UtcNow.ToString("o")); data.Add("runid", NameUtils.GetRunId()); data.Add("status", resultStatus); - data.Add("testid", NameUtils.GetTestId()); data.Add("category", NameUtils.GetCategoryName()); data.Add("fixturename", fixtureName); if (!data.ContainsKey("testname")) data.Add("testname", NameUtils.GetTestMethodName()); + data.Add("testid", NameUtils.GetTestId()); + data.Add("testtype", testType); data.Add("testduration", testDuration); Write(data); } diff --git a/Tests/DistTestCore/TestLifecycle.cs b/Tests/DistTestCore/TestLifecycle.cs index 47a17b3..896ab66 100644 --- a/Tests/DistTestCore/TestLifecycle.cs +++ b/Tests/DistTestCore/TestLifecycle.cs @@ -2,6 +2,8 @@ using DistTestCore.Logs; using FileUtils; using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; using Utils; namespace DistTestCore diff --git a/Tools/CodexNetDeployer/Deployer.cs b/Tools/CodexNetDeployer/Deployer.cs index ff2dd6f..a0263b5 100644 --- a/Tools/CodexNetDeployer/Deployer.cs +++ b/Tools/CodexNetDeployer/Deployer.cs @@ -3,7 +3,7 @@ using CodexDiscordBotPlugin; using CodexPlugin; using Core; using GethPlugin; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using MetricsPlugin; diff --git a/Tools/CodexNetDeployer/K8sHook.cs b/Tools/CodexNetDeployer/K8sHook.cs index f89a3fc..f586613 100644 --- a/Tools/CodexNetDeployer/K8sHook.cs +++ b/Tools/CodexNetDeployer/K8sHook.cs @@ -1,5 +1,7 @@ using DistTestCore; using KubernetesWorkflow; +using KubernetesWorkflow.Recipe; +using KubernetesWorkflow.Types; namespace CodexNetDeployer { diff --git a/Tools/CodexNetDeployer/PeerConnectivityChecker.cs b/Tools/CodexNetDeployer/PeerConnectivityChecker.cs index 87bdc31..06cb1a5 100644 --- a/Tools/CodexNetDeployer/PeerConnectivityChecker.cs +++ b/Tools/CodexNetDeployer/PeerConnectivityChecker.cs @@ -1,4 +1,4 @@ -using DistTestCore.Helpers; +using CodexTests.Helpers; using Logging; namespace CodexNetDeployer diff --git a/Tools/TestClusterStarter/ClusterTestSpec.cs b/Tools/TestClusterStarter/ClusterTestSpec.cs index 88b18c2..f44be21 100644 --- a/Tools/TestClusterStarter/ClusterTestSpec.cs +++ b/Tools/TestClusterStarter/ClusterTestSpec.cs @@ -1,4 +1,4 @@ -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace TestClusterStarter { diff --git a/Tools/TestClusterStarter/Program.cs b/Tools/TestClusterStarter/Program.cs index 2830661..9fe44ce 100644 --- a/Tools/TestClusterStarter/Program.cs +++ b/Tools/TestClusterStarter/Program.cs @@ -1,7 +1,7 @@ using ArgsUniform; using Core; using DeployAndRunPlugin; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; using Logging; using Newtonsoft.Json; using TestClusterStarter;