Merge branch 'master' into feature/continuous-test-status-logs
# Conflicts: # Tests/DistTestCore/Logs/StatusLog.cs
This commit is contained in:
commit
344d3cd44f
|
@ -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 "----"
|
||||
|
|
|
@ -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 "----"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
namespace KubernetesWorkflow
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace KubernetesWorkflow
|
||||
{
|
||||
public interface IK8sHooks
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace KubernetesWorkflow
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace KubernetesWorkflow
|
||||
{
|
||||
public interface ILocation
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Logging;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
|
||||
namespace KubernetesWorkflow
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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<T>();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace KubernetesWorkflow
|
||||
namespace KubernetesWorkflow.Recipe
|
||||
{
|
||||
public class ContainerRecipe
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
using Utils;
|
||||
|
||||
namespace KubernetesWorkflow
|
||||
namespace KubernetesWorkflow.Recipe
|
||||
{
|
||||
public abstract class ContainerRecipeFactory
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
using Utils;
|
||||
|
||||
namespace KubernetesWorkflow
|
||||
namespace KubernetesWorkflow.Recipe
|
||||
{
|
||||
public class ContainerResources
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace KubernetesWorkflow
|
||||
namespace KubernetesWorkflow.Recipe
|
||||
{
|
||||
public class PodAnnotations
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace KubernetesWorkflow
|
||||
namespace KubernetesWorkflow.Recipe
|
||||
{
|
||||
public class PodLabels
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
using System.Globalization;
|
||||
using Utils;
|
||||
|
||||
namespace KubernetesWorkflow
|
||||
namespace KubernetesWorkflow.Recipe
|
||||
{
|
||||
public class RecipeComponentFactory
|
||||
{
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Port>();
|
||||
}
|
||||
}
|
||||
|
||||
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<ContainerRecipePortMapEntry> result)
|
||||
{
|
||||
Name = name;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public List<ContainerRecipePortMapEntry> 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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}'";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using KubernetesWorkflow.Recipe;
|
||||
|
||||
namespace KubernetesWorkflow.Types
|
||||
{
|
||||
public class RunningService
|
||||
{
|
||||
public RunningService(string name, List<ContainerRecipePortMapEntry> result)
|
||||
{
|
||||
Name = name;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public List<ContainerRecipePortMapEntry> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<T>(Func<T> 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)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using Logging;
|
||||
|
||||
namespace CodexContractsPlugin
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Core;
|
||||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using Utils;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexDiscordBotPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexDiscordBotPlugin
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using Utils;
|
||||
|
||||
namespace CodexDiscordBotPlugin
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Utils;
|
||||
|
||||
namespace CodexPlugin
|
||||
|
|
|
@ -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<CodexDebugPeerAddressResponse>();
|
||||
}
|
||||
|
||||
public class CodexDebugPeerAddressResponse
|
||||
{
|
||||
public string address { get; set; } = string.Empty;
|
||||
public string[] addresses { get; set; } = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public class CodexDebugThresholdBreaches
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using Utils;
|
||||
|
||||
namespace CodexPlugin
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using CodexContractsPlugin;
|
||||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexPlugin
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Core;
|
||||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using MetricsPlugin;
|
||||
using System.Collections;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
|
||||
namespace CodexPlugin
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace DeployAndRunPlugin
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
|
||||
namespace DeployAndRunPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace DeployAndRunPlugin
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using Utils;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
|
||||
namespace GethPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace GethPlugin
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using Nethereum.Contracts;
|
||||
using NethereumWorkflow;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
|
||||
namespace MetricsPlugin
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Utils;
|
||||
|
||||
namespace MetricsPlugin
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
|
||||
namespace MetricsPlugin
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using System.Globalization;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace MetricsPlugin
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
|
||||
namespace MetricsPlugin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using System.Text;
|
||||
|
||||
|
|
|
@ -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...");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using Utils;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using CodexContractsPlugin;
|
||||
using CodexPlugin;
|
||||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using MetricsPlugin;
|
||||
using NUnit.Framework;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using Logging;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace DistTestCore.Helpers
|
||||
namespace CodexTests.Helpers
|
||||
{
|
||||
public interface IFullConnectivityImplementation
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
using CodexPlugin;
|
||||
using CodexTests;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Tests.PeerDiscoveryTests
|
||||
namespace CodexTests.PeerDiscoveryTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LayeredDiscoveryTests : CodexDistTest
|
||||
|
|
|
@ -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<ICodexNode> allNodes)
|
||||
{
|
||||
var allResponses = allNodes.Select(n => n.GetDebugInfo()).ToArray();
|
||||
|
||||
var errors = new List<string>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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<string, string> 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);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
using DistTestCore.Logs;
|
||||
using FileUtils;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Utils;
|
||||
|
||||
namespace DistTestCore
|
||||
|
|
|
@ -3,7 +3,7 @@ using CodexDiscordBotPlugin;
|
|||
using CodexPlugin;
|
||||
using Core;
|
||||
using GethPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using MetricsPlugin;
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using DistTestCore;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace CodexNetDeployer
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using DistTestCore.Helpers;
|
||||
using CodexTests.Helpers;
|
||||
using Logging;
|
||||
|
||||
namespace CodexNetDeployer
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
|
||||
namespace TestClusterStarter
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using ArgsUniform;
|
||||
using Core;
|
||||
using DeployAndRunPlugin;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using Newtonsoft.Json;
|
||||
using TestClusterStarter;
|
||||
|
|
Loading…
Reference in New Issue