Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try running K8S tests using local kind #1319

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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