Skip to content

Commit

Permalink
Try running K8S tests using local kind
Browse files Browse the repository at this point in the history
  • Loading branch information
zentron committed Sep 22, 2024
1 parent 590fc6f commit 75bf5ff
Show file tree
Hide file tree
Showing 14 changed files with 1,033 additions and 296 deletions.
4 changes: 2 additions & 2 deletions source/Calamari.Testing/Helpers/CalamariResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,14 @@ public void AssertNoOutput(string expectedOutput)

public void AssertOutput(string expectedOutput)
{
var allOutput = string.Join(Environment.NewLine, captured.Infos);
var allOutput = string.Join(Environment.NewLine, captured.AllMessages);

Assert.That(allOutput, Does.Contain(expectedOutput));
}

public void AssertOutputContains(string expected)
{
var allOutput = string.Join(Environment.NewLine, captured.Infos);
var allOutput = string.Join(Environment.NewLine, captured.AllMessages);

allOutput.Should().Contain(expected);
}
Expand Down
9 changes: 9 additions & 0 deletions source/Calamari.Tests/Calamari.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<StartupObject />
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64;linux-arm;linux-arm64</RuntimeIdentifiers>
<TargetFrameworks>net462;net6.0</TargetFrameworks>
<LangVersion>8</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
<DefineConstants>$(DefineConstants);NETCORE;AWS;AZURE_CORE;JAVA_SUPPORT</DefineConstants>
Expand Down Expand Up @@ -167,6 +168,14 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Compile Remove="Fixtures\StructuredVariables\CalamariFlavourProgramReplacerSelectionFixture.cs" />
<None Remove="KubernetesFixtures\Tools\kind-config.yml" />
<EmbeddedResource Include="KubernetesFixtures\Tools\kind-config.yml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<None Remove="KubernetesFixtures\Tools\docker-desktop-network-routing.yml" />
<EmbeddedResource Include="KubernetesFixtures\Tools\docker-desktop-network-routing.yml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Remove="TestResults\**" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#if NETCORE
using System;
using System.Threading;
using System.Threading.Tasks;
using Calamari.Tests.KubernetesFixtures.Tools;
using NUnit.Framework;

namespace Calamari.Tests.KubernetesFixtures
{
[SetUpFixture]
public class KubernetesClusterOneTimeSetUp
{
KubernetesClusterInstaller installer;
[OneTimeSetUp]
public async Task OneTimeSetUp()
{
var toolDownloader = new RequiredToolDownloader(KubernetesTestsGlobalContext.Instance.TemporaryDirectory, KubernetesTestsGlobalContext.Instance.Logger);
var (kindExePath, helmExePath, kubeCtlPath) = await toolDownloader.DownloadRequiredTools(CancellationToken.None);

installer = new KubernetesClusterInstaller(KubernetesTestsGlobalContext.Instance.TemporaryDirectory, kindExePath, helmExePath, kubeCtlPath, KubernetesTestsGlobalContext.Instance.Logger);
await installer.Install();

KubernetesTestsGlobalContext.Instance.SetToolExePaths(helmExePath, kubeCtlPath);
KubernetesTestsGlobalContext.Instance.KubeConfigPath = installer.KubeConfigPath;

var details = installer.ExtractLoginDetails();
KubernetesTestsGlobalContext.Instance.ClusterUser = details.ClusterUser;
KubernetesTestsGlobalContext.Instance.ClusterEndpoint = details.ClusterEndpoint;
}

[OneTimeTearDown]
public void OneTimeTearDown()
{
installer.Dispose();
KubernetesTestsGlobalContext.Instance.Dispose();
}
}
}
#endif
159 changes: 159 additions & 0 deletions source/Calamari.Tests/KubernetesFixtures/KubernetesCommandTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#if NETCORE
using System;
using System.Collections.Generic;
using System.IO;
using Calamari.Commands;
using Calamari.Common.Features.Scripts;
using Calamari.Common.Plumbing.FileSystem;
using Calamari.Common.Plumbing.Variables;
using Calamari.Kubernetes;
using Calamari.Kubernetes.Commands;
using Calamari.Testing.Helpers;
using Calamari.Tests.Helpers;
using Calamari.Tests.KubernetesFixtures.Tools;
using JetBrains.Annotations;
using NUnit.Framework;

namespace Calamari.Tests.KubernetesFixtures
{
internal static class VariablesExtensionMethods
{
public static void SetInlineScriptVariables(this IVariables variables, string bashScript, string powershellScript)
{
variables.Set(Deployment.SpecialVariables.Action.Script.ScriptBodyBySyntax(ScriptSyntax.Bash), bashScript);
variables.Set(Deployment.SpecialVariables.Action.Script.ScriptBodyBySyntax(ScriptSyntax.PowerShell), powershellScript);
}

public static void SetAuthenticationDetails(this IVariables variables)
{
variables.Set(SpecialVariables.ClientCertificate, "UserCert");
variables.Set(SpecialVariables.CertificatePem("UserCert"), System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(KubernetesTestsGlobalContext.Instance.ClusterUser.ClientCertPem)));
variables.Set(SpecialVariables.PrivateKeyPem("UserCert"), System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(KubernetesTestsGlobalContext.Instance.ClusterUser.ClientCertKey)));
}

public static void SetClusterDetails(this IVariables variables)
{
variables.Set(SpecialVariables.ClusterUrl, KubernetesTestsGlobalContext.Instance.ClusterEndpoint.ClusterUrl);
variables.Set(SpecialVariables.CertificateAuthority, "ClientCert");
variables.Set(SpecialVariables.CertificatePem("ClientCert"), System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(KubernetesTestsGlobalContext.Instance.ClusterEndpoint.ClusterCert)));
}

public static void SetVariablesForKubernetesResourceStatusCheck(this IVariables variables, int timeout = 30, string deploymentWait = "wait")
{
variables.Set("Octopus.Action.Kubernetes.ResourceStatusCheck", "True");
variables.Set(SpecialVariables.DeploymentWait, deploymentWait);
variables.Set("Octopus.Action.Kubernetes.DeploymentTimeout", timeout.ToString());
variables.Set("Octopus.Action.Kubernetes.PrintVerboseKubectlOutputOnError", "True");
}
}

[TestFixture]
public class KubernetesCommandTests : CalamariFixture
{
[Test]
public void GivenInvalidYaml_ShouldFail()
{
var variables = new CalamariVariables();
variables.SetClusterDetails();
variables.SetAuthenticationDetails();
variables.SetVariablesForKubernetesResourceStatusCheck();
var ns = CreateString();
variables.Set(SpecialVariables.Namespace, ns);

const string failToDeploymentResource = @"apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
invalid-spec: this-is-not-valid
containers:
- name: nginx
image: nginx";

var output = ExecuteRawYamlCommand(variables, failToDeploymentResource);

output.AssertFailure();
output.AssertOutputContains("Pod in version \"v1\" cannot be handled as a Pod: strict decoding error: unknown field \"spec.invalid-spec\"");
//$"error: error parsing {fileName}: error converting YAML to JSON: yaml: line 7: could not find expected ':'";
}

[Test]
public void GivenKubectlScript_ShouldExecute()
{
var variables = new CalamariVariables();
variables.SetClusterDetails();
variables.SetAuthenticationDetails();
variables.Set(SpecialVariables.Namespace, "default");

var sampleMessage = CreateString();
var cmd = $"echo \"{sampleMessage}\"{Environment.NewLine}kubectl cluster-info";
variables.SetInlineScriptVariables(cmd,cmd);
var output = ExecuteCommand(variables, RunScriptCommand.Name, null);

output.AssertSuccess();
output.AssertOutputContains(sampleMessage);
output.AssertOutputContains($"Kubernetes control plane is running at {KubernetesTestsGlobalContext.Instance.ClusterEndpoint.ClusterUrl}");
}

CalamariResult ExecuteRawYamlCommand(CalamariVariables variables, string yaml)
{
variables.Set(SpecialVariables.CustomResourceYamlFileName, "**/*.{yml,yaml}");
using var workingDirectory = TemporaryDirectory.Create();
CreateResourceYamlFile(workingDirectory.DirectoryPath, DeploymentFileName, yaml);
variables.Set(SpecialVariables.CustomResourceYamlFileName, DeploymentFileName);
variables.Set(KnownVariables.OriginalPackageDirectoryPath, workingDirectory.DirectoryPath);

var output = ExecuteCommand(variables, KubernetesApplyRawYamlCommand.Name, workingDirectory.DirectoryPath);
return output;
}

private static string CreateResourceYamlFile(string directory, string fileName, string content)
{
var pathToCustomResource = Path.Combine(directory, fileName);
File.WriteAllText(pathToCustomResource, content);
return pathToCustomResource;
}
private Func<string,string> CreateAddCustomResourceFileFunc(IVariables variables, string yamlContent)
{
return directory =>
{
CreateResourceYamlFile(directory, DeploymentFileName, yamlContent);
if (!variables.IsSet(SpecialVariables.CustomResourceYamlFileName))
{
variables.Set(SpecialVariables.CustomResourceYamlFileName, DeploymentFileName);
}
return null;
};
}

string CreateString()
{
return $"Test{Guid.NewGuid().ToString("N").Substring(0, 10)}".ToLower();
}


CalamariResult ExecuteCommand(IVariables variables, string command, [CanBeNull] string workingDirectory)
{
using var variablesFile = new TemporaryFile(Path.GetTempFileName());
variables.Save(variablesFile.FilePath);

var calamariCommand = Calamari().Action(command)
.Argument("variables", variablesFile.FilePath)
.WithEnvironmentVariables(new Dictionary<string, string>())
.OutputToLog(true);

if (workingDirectory != null)
{
calamariCommand = calamariCommand.WithWorkingDirectory(workingDirectory);
}

return InvokeInProcess(calamariCommand, variables);
}


private const string DeploymentFileName = "customresource.yml";

}

}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,18 @@
using Calamari.Commands;
using Calamari.Common.Features.Discovery;
using Calamari.Common.Features.Scripts;
using Calamari.Common.FeatureToggles;
using Calamari.Common.Plumbing;
using Calamari.Common.Plumbing.FileSystem;
using Calamari.Common.Plumbing.ServiceMessages;
using Calamari.Common.Plumbing.Variables;
using Calamari.Deployment;
using Calamari.Kubernetes.Commands;
using Calamari.Testing.Helpers;
using Calamari.Tests.Helpers;
using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NUnit.Framework;
using KubernetesSpecialVariables = Calamari.Kubernetes.SpecialVariables;
using SpecialVariables = Calamari.Deployment.SpecialVariables;

namespace Calamari.Tests.KubernetesFixtures
{
Expand Down Expand Up @@ -153,9 +150,9 @@ private void SetInlineScriptVariables(string script)
private void SetInlineScriptVariables(string bashScript, string powershellScript)
{
variables.Set(SpecialVariables.Action.Script.ScriptBodyBySyntax(ScriptSyntax.Bash),
bashScript);
bashScript);
variables.Set(SpecialVariables.Action.Script.ScriptBodyBySyntax(ScriptSyntax.PowerShell),
powershellScript);
powershellScript);
}

private CalamariResult ExecuteCommand(string command, string workingDirectory, string packagePath)
Expand Down
Loading

0 comments on commit 75bf5ff

Please sign in to comment.