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 fbf0ea7..3e14a91 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 90d0dda..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 @@ -62,14 +63,17 @@ namespace CodexPlugin public string UploadFile(FileStream fileStream) { - // private const string UploadFailedMessage = "Unable to store block"; - - return Http().HttpPostStream("upload", fileStream); + return Http().HttpPostStream("data", fileStream); } public Stream DownloadFile(string contentId) { - return Http().HttpGetStream("download/" + contentId); + return Http().HttpGetStream("data/" + contentId); + } + + public CodexLocalDataResponse[] LocalFiles() + { + return Http().HttpGetJson("local"); } public CodexSalesAvailabilityResponse SalesAvailability(CodexSalesAvailabilityRequest request) diff --git a/ProjectPlugins/CodexPlugin/CodexApiTypes.cs b/ProjectPlugins/CodexPlugin/CodexApiTypes.cs index 49b0d2d..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 @@ -170,4 +165,30 @@ namespace CodexPlugin { public string cid { get; set; } = string.Empty; } + + public class CodexLocalData + { + public CodexLocalData(ContentId cid, CodexLocalDataManifestResponse manifest) + { + Cid = cid; + Manifest = manifest; + } + + public ContentId Cid { get; } + public CodexLocalDataManifestResponse Manifest { get; } + } + + public class CodexLocalDataResponse + { + public string cid { get; set; } = string.Empty; + public CodexLocalDataManifestResponse manifest { get; set; } = new(); + } + + public class CodexLocalDataManifestResponse + { + public string rootHash { get; set; } = string.Empty; + public int originalBytes { get; set; } + public int blockSize { get; set; } + public bool @protected { get; set; } + } } 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 1096a10..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; @@ -18,6 +19,7 @@ namespace CodexPlugin //CodexDebugRepoStoreResponse[] GetDebugRepoStore(); ContentId UploadFile(TrackedFile file); TrackedFile? DownloadContent(ContentId contentId, string fileLabel = ""); + CodexLocalData[] LocalFiles(); void ConnectToPeer(ICodexNode node); CodexDebugVersionResponse Version { get; } IMarketplaceAccess Marketplace { get; } @@ -121,6 +123,11 @@ namespace CodexPlugin return file; } + public CodexLocalData[] LocalFiles() + { + return CodexAccess.LocalFiles().Select(l => new CodexLocalData(new ContentId(l.cid), l.manifest)).ToArray(); + } + public void ConnectToPeer(ICodexNode node) { var peer = (CodexNode)node; @@ -158,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; } @@ -205,5 +213,15 @@ namespace CodexPlugin } public string Id { get; } + + public override bool Equals(object? obj) + { + return obj is ContentId id && Id == id.Id; + } + + public override int GetHashCode() + { + return HashCode.Combine(Id); + } } } 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..3e40a99 100644 --- a/ProjectPlugins/CodexPlugin/CodexPlugin.cs +++ b/ProjectPlugins/CodexPlugin/CodexPlugin.cs @@ -1,5 +1,5 @@ using Core; -using KubernetesWorkflow; +using KubernetesWorkflow.Types; namespace CodexPlugin { @@ -19,12 +19,13 @@ namespace CodexPlugin public void Announce() { - tools.GetLog().Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}'"); + tools.GetLog().Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}' - Revision: {codexStarter.GetCodexRevision()}"); } public void AddMetadata(IAddMetadata metadata) { metadata.Add("codexid", codexStarter.GetCodexId()); + metadata.Add("codexrevision", codexStarter.GetCodexRevision()); } public void Decommission() diff --git a/ProjectPlugins/CodexPlugin/CodexStarter.cs b/ProjectPlugins/CodexPlugin/CodexStarter.cs index 718ef22..af815a8 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 @@ -65,6 +66,12 @@ namespace CodexPlugin return recipe.Image; } + public string GetCodexRevision() + { + if (versionResponse != null) return versionResponse.revision; + return "unknown"; + } + private StartupConfig CreateStartupConfig(CodexSetup codexSetup) { var startupConfig = new StartupConfig(); 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 7e4ffd9..1816960 100644 --- a/Tests/CodexContinuousTests/ContinuousTestRunner.cs +++ b/Tests/CodexContinuousTests/ContinuousTestRunner.cs @@ -1,4 +1,5 @@ -using DistTestCore.Logs; +using DistTestCore; +using DistTestCore.Logs; using Logging; using Newtonsoft.Json; using Utils; @@ -28,7 +29,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..."); @@ -43,6 +44,7 @@ namespace ContinuousTests var taskFactory = new TaskFactory(); overviewLog.Log("Startup checks passed. Configuration:"); overviewLog.Log(JsonConvert.SerializeObject(config, Formatting.Indented)); + overviewLog.Log("Test framework revision: " + GitInfo.GetStatus()); overviewLog.Log("Continuous tests starting..."); overviewLog.Log(""); var allTests = testFactory.CreateTests(); @@ -57,7 +59,7 @@ namespace ContinuousTests } else { - var testLoops = filteredTests.Select(t => new TestLoop(entryPointFactory, taskFactory, config, overviewLog, t.GetType(), t.RunTestEvery, startupChecker, cancelToken)).ToArray(); + var testLoops = filteredTests.Select(t => new TestLoop(entryPointFactory, taskFactory, config, overviewLog, statusLog, t.GetType(), t.RunTestEvery, startupChecker, cancelToken)).ToArray(); foreach (var testLoop in testLoops) { @@ -109,6 +111,7 @@ namespace ContinuousTests Cancellation.Cts.Cancel(); overviewLog.Log($"Congratulations! The targer duration has been reached! ({Time.FormatDuration(targetDuration)})"); statusLog.ConcludeTest("Passed", testDuration, testData); + Environment.ExitCode = 0; return; } } @@ -117,6 +120,7 @@ namespace ContinuousTests cancelToken.WaitHandle.WaitOne(); } statusLog.ConcludeTest("Failed", testDuration, testData); + Environment.ExitCode = 1; } private Dictionary FormatTestRuns(TestLoop[] testLoops) @@ -124,7 +128,8 @@ namespace ContinuousTests var result = new Dictionary(); foreach (var testLoop in testLoops) { - result.Add($"ctest-{testLoop.Name}", $"passes: {testLoop.NumberOfPasses} - failures: {testLoop.NumberOfFailures}"); + result.Add("testname", testLoop.Name); + result.Add($"summary", $"passes: {testLoop.NumberOfPasses} - failures: {testLoop.NumberOfFailures}"); } return result; } 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 f86e502..033e9c9 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 { @@ -16,6 +16,7 @@ namespace ContinuousTests private readonly TaskFactory taskFactory; private readonly Configuration config; private readonly ILog overviewLog; + private readonly StatusLog statusLog; private readonly TestHandle handle; private readonly CancellationToken cancelToken; private readonly ICodexNode[] nodes; @@ -23,11 +24,12 @@ namespace ContinuousTests private readonly string testName; private static int failureCount = 0; - public SingleTestRun(EntryPointFactory entryPointFactory, TaskFactory taskFactory, Configuration config, ILog overviewLog, TestHandle handle, StartupChecker startupChecker, CancellationToken cancelToken) + public SingleTestRun(EntryPointFactory entryPointFactory, TaskFactory taskFactory, Configuration config, ILog overviewLog, StatusLog statusLog, TestHandle handle, StartupChecker startupChecker, CancellationToken cancelToken) { this.taskFactory = taskFactory; this.config = config; this.overviewLog = overviewLog; + this.statusLog = statusLog; this.handle = handle; this.cancelToken = cancelToken; testName = handle.Test.GetType().Name; @@ -63,13 +65,15 @@ namespace ContinuousTests private void RunTest(Action resultHandler) { var testStart = DateTime.UtcNow; - + TimeSpan duration = TimeSpan.Zero; + try { RunTestMoments(); + duration = DateTime.UtcNow - testStart; - var duration = DateTime.UtcNow - testStart; OverviewLog($" > Test passed. ({Time.FormatDuration(duration)})"); + UpdateStatusLogPassed(testStart, duration); if (!config.KeepPassedTestLogs) { @@ -81,6 +85,7 @@ namespace ContinuousTests { fixtureLog.Error("Test run failed with exception: " + ex); fixtureLog.MarkAsFailed(); + UpdateStatusLogFailed(testStart, duration, ex.ToString()); DownloadContainerLogs(testStart); @@ -170,6 +175,25 @@ namespace ContinuousTests throw new Exception(exceptionsMessage); } + private void UpdateStatusLogFailed(DateTime testStart, TimeSpan duration, string error) + { + statusLog.ConcludeTest("Failed", duration, CreateStatusLogData(testStart, error)); + } + + private void UpdateStatusLogPassed(DateTime testStart, TimeSpan duration) + { + statusLog.ConcludeTest("Passed", duration, CreateStatusLogData(testStart, "OK")); + } + + private Dictionary CreateStatusLogData(DateTime testStart, string message) + { + var result = entryPoint.GetPluginMetadata(); + result.Add("teststart", testStart.ToString("o")); + result.Add("testname", testName); + result.Add("message", message); + return result; + } + private string GetCombinedExceptionsMessage(Exception[] exceptions) { return string.Join(Environment.NewLine, exceptions.Select(ex => ex.ToString())); diff --git a/Tests/CodexContinuousTests/TestLoop.cs b/Tests/CodexContinuousTests/TestLoop.cs index 6c1157a..afa438b 100644 --- a/Tests/CodexContinuousTests/TestLoop.cs +++ b/Tests/CodexContinuousTests/TestLoop.cs @@ -1,4 +1,5 @@ -using Logging; +using DistTestCore.Logs; +using Logging; namespace ContinuousTests { @@ -8,6 +9,7 @@ namespace ContinuousTests private readonly TaskFactory taskFactory; private readonly Configuration config; private readonly ILog overviewLog; + private readonly StatusLog statusLog; private readonly Type testType; private readonly TimeSpan runsEvery; private readonly StartupChecker startupChecker; @@ -15,12 +17,13 @@ namespace ContinuousTests private readonly EventWaitHandle runFinishedHandle = new EventWaitHandle(true, EventResetMode.ManualReset); private static object testLock = new object(); - public TestLoop(EntryPointFactory entryPointFactory, TaskFactory taskFactory, Configuration config, ILog overviewLog, Type testType, TimeSpan runsEvery, StartupChecker startupChecker, CancellationToken cancelToken) + public TestLoop(EntryPointFactory entryPointFactory, TaskFactory taskFactory, Configuration config, ILog overviewLog, StatusLog statusLog, Type testType, TimeSpan runsEvery, StartupChecker startupChecker, CancellationToken cancelToken) { this.entryPointFactory = entryPointFactory; this.taskFactory = taskFactory; this.config = config; this.overviewLog = overviewLog; + this.statusLog = statusLog; this.testType = testType; this.runsEvery = runsEvery; this.startupChecker = startupChecker; @@ -73,7 +76,7 @@ namespace ContinuousTests { var test = (ContinuousTest)Activator.CreateInstance(testType)!; var handle = new TestHandle(test); - var run = new SingleTestRun(entryPointFactory, taskFactory, config, overviewLog, handle, startupChecker, cancelToken); + var run = new SingleTestRun(entryPointFactory, taskFactory, config, overviewLog, statusLog, handle, startupChecker, cancelToken); runFinishedHandle.Reset(); run.Run(runFinishedHandle, result => 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/BasicTests/ExampleTests.cs b/Tests/CodexTests/BasicTests/ExampleTests.cs index b7e89e2..44c6dc6 100644 --- a/Tests/CodexTests/BasicTests/ExampleTests.cs +++ b/Tests/CodexTests/BasicTests/ExampleTests.cs @@ -16,7 +16,10 @@ namespace CodexTests.BasicTests { var primary = AddCodex(s => s.WithLogLevel(CodexLogLevel.Trace, new CodexLogCustomTopics(CodexLogLevel.Warn, CodexLogLevel.Warn))); - primary.UploadFile(GenerateTestFile(5.MB())); + var cid = primary.UploadFile(GenerateTestFile(5.MB())); + + var content = primary.LocalFiles(); + CollectionAssert.Contains(content.Select(c => c.Cid), cid); var log = Ci.DownloadLog(primary); 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..74898d5 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()); @@ -58,6 +58,7 @@ namespace DistTestCore throw; } + fixtureLog.Log("Test framework revision: " + GitInfo.GetStatus()); fixtureLog.Log("Global setup cleanup successful"); } diff --git a/Tests/DistTestCore/DistTestCore.csproj b/Tests/DistTestCore/DistTestCore.csproj index 91d1fd0..d86168f 100644 --- a/Tests/DistTestCore/DistTestCore.csproj +++ b/Tests/DistTestCore/DistTestCore.csproj @@ -8,6 +8,7 @@ + diff --git a/Tests/DistTestCore/GitInfo.cs b/Tests/DistTestCore/GitInfo.cs new file mode 100644 index 0000000..a742d4b --- /dev/null +++ b/Tests/DistTestCore/GitInfo.cs @@ -0,0 +1,39 @@ +using KubernetesWorkflow; +using LibGit2Sharp; +using System.Reflection; + +namespace DistTestCore +{ + public static class GitInfo + { + private static string? status = null; + + public static string GetStatus() + { + if (status == null) status = DetermineStatus(); + return status; + } + + private static string DetermineStatus() + { + var path = FindGitPath(); + if (path == null) return "unknown"; + + using var repo = new Repository(path); + var sha = repo.Head.Tip.Sha.Substring(0, 7); + + return K8sNameUtils.Format(sha); + } + + private static string? FindGitPath() + { + var path = Repository.Discover(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); + if (!string.IsNullOrEmpty(path)) return path; + + path = Repository.Discover(Directory.GetCurrentDirectory()); + if (!string.IsNullOrEmpty(path)) return path; + + return null; + } + } +} diff --git a/Tests/DistTestCore/Logs/StatusLog.cs b/Tests/DistTestCore/Logs/StatusLog.cs index b7ce891..8c097ad 100644 --- a/Tests/DistTestCore/Logs/StatusLog.cs +++ b/Tests/DistTestCore/Logs/StatusLog.cs @@ -1,5 +1,6 @@ using Logging; using Newtonsoft.Json; +using Utils; namespace DistTestCore.Logs { @@ -8,11 +9,18 @@ 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) + { + ConcludeTest(resultStatus, Time.FormatDuration(testDuration), data); } public void ConcludeTest(string resultStatus, string testDuration, Dictionary data) @@ -20,11 +28,13 @@ 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); - data.Add("testname", NameUtils.GetTestMethodName()); + if (!data.ContainsKey("testname")) data.Add("testname", NameUtils.GetTestMethodName()); + data.Add("testid", NameUtils.GetTestId()); + data.Add("testtype", testType); data.Add("testduration", testDuration); + data.Add("testframeworkrevision", GitInfo.GetStatus()); Write(data); } diff --git a/Tests/DistTestCore/TestLifecycle.cs b/Tests/DistTestCore/TestLifecycle.cs index 47a17b3..b386343 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 @@ -80,6 +82,7 @@ namespace DistTestCore recipe.PodLabels.Add("category", NameUtils.GetCategoryName()); recipe.PodLabels.Add("fixturename", NameUtils.GetRawFixtureName()); recipe.PodLabels.Add("testname", NameUtils.GetTestMethodName()); + recipe.PodLabels.Add("testframeworkrevision", GitInfo.GetStatus()); foreach (var pair in metadata) { diff --git a/Tools/CodexNetDeployer/Deployer.cs b/Tools/CodexNetDeployer/Deployer.cs index 60415ac..a0cb0ad 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; diff --git a/docker/continuous-tests-job.yaml b/docker/continuous-tests-job.yaml index fe86898..79c914b 100644 --- a/docker/continuous-tests-job.yaml +++ b/docker/continuous-tests-job.yaml @@ -30,7 +30,7 @@ spec: - name: KUBECONFIG value: "/opt/kubeconfig.yaml" - name: LOGPATH - value: "/var/log/codex-continuous-tests" + value: "/var/log/codex-continuous-tests/${DEPLOYMENT_NAMESPACE}" - name: NAMESPACE value: "${NAMESPACE}" - name: BRANCH