Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Calamari.Common.Commands;
using Calamari.Common.Features.Packages;
Expand Down Expand Up @@ -76,22 +77,25 @@ public void SetsAppliedResourcesOutputVariable_WhenFeatureToggleIsEnabled()
var executor = CreateExecutor(deployment);

// Act
executor.ExecuteHelmUpgrade(deployment, ReleaseName, RevisionNumber, installCompletedCts, installErrorCts);
executor.ExecuteHelmUpgrade(deployment,
ReleaseName,
RevisionNumber,
installCompletedCts,
installErrorCts);

// Assert
commandLineRunner.Received().Execute(Arg.Is<CommandLineInvocation>(i =>
i.Arguments.Contains("get") &&
i.Arguments.Contains("manifest") &&
i.Arguments.Contains(ReleaseName) &&
i.Arguments.Contains($"--revision {RevisionNumber}")));
commandLineRunner.Received()
.Execute(Arg.Is<CommandLineInvocation>(i =>
i.Arguments.Contains("get") && i.Arguments.Contains("manifest") && i.Arguments.Contains(ReleaseName) && i.Arguments.Contains($"--revision {RevisionNumber}")));

var appliedResourcesJson = variables.Get(SpecialVariables.AppliedResources);
appliedResourcesJson.Should().NotBeNullOrEmpty();

var deserializedResources = JsonConvert.DeserializeAnonymousType(appliedResourcesJson, new[]
{
new { Group = "", Version = "", Kind = "", Name = "", Namespace = "" }
});
var deserializedResources = JsonConvert.DeserializeAnonymousType(appliedResourcesJson,
new[]
{
new { Group = "", Version = "", Kind = "", Name = "", Namespace = "" }
});
deserializedResources.Should().HaveCount(2);
deserializedResources.Should().Contain(r => r.Kind == "Deployment" && r.Name == "my-app");
deserializedResources.Should().Contain(r => r.Kind == "Service" && r.Name == "my-app-service");
Expand All @@ -110,15 +114,57 @@ public void DoesNotSetAppliedResourcesOutputVariable_WhenFeatureToggleIsDisabled
var executor = CreateExecutor(deployment);

// Act
executor.ExecuteHelmUpgrade(deployment, ReleaseName, RevisionNumber, installCompletedCts, installErrorCts);
executor.ExecuteHelmUpgrade(deployment,
ReleaseName,
RevisionNumber,
installCompletedCts,
installErrorCts);

// Assert
var appliedResourcesJson = variables.Get(SpecialVariables.AppliedResources);
appliedResourcesJson.Should().BeNull();

commandLineRunner.DidNotReceive().Execute(Arg.Is<CommandLineInvocation>(i => i.Arguments.Contains("get manifest")));
}

[TestCase("--wait", true)]
[TestCase("--atomic", false)]
[TestCase("--rollback-on-failure", false)]
[TestCase("--timeout", true)]
[TestCase(null, true)]
public void WhenAdditionalArgsHaveSpecificArg_AndKOSEnabled_ShouldAddWaitOrRespectArg(string arg, bool shouldHaveWaitFlagInCommandArgs)
{
// Arrange
var variables = CreateVariables();
variables.Set(SpecialVariables.Helm.AdditionalArguments, $"--fake-arg {arg}");
variables.Set(SpecialVariables.ResourceStatusCheck, bool.TrueString);

SetupHelmUpgradeMock();
SetupHelmGetManifestMock(GetSampleManifest());

var deployment = CreateRunningDeployment(variables);
var executor = CreateExecutor(deployment);

// Act
executor.ExecuteHelmUpgrade(deployment,
ReleaseName,
RevisionNumber,
installCompletedCts,
installErrorCts);

// Assert
if (shouldHaveWaitFlagInCommandArgs)
{
commandLineRunner.Received().Execute(Arg.Is<CommandLineInvocation>(i => i.Arguments.Contains("--wait") && i.Arguments.Split(' ').Count(a => a == "--wait") == 1));
}
else
{
commandLineRunner.Received().Execute(Arg.Is<CommandLineInvocation>(i => i.Arguments.Contains(arg)));
// we don't add --wait when we have the wait-equivalent flag
commandLineRunner.Received().Execute(Arg.Is<CommandLineInvocation>(i => !i.Arguments.Contains("--wait")));
}
}

[Test]
public void LogsWarningAndContinues_WhenGetManifestFails()
{
Expand All @@ -133,7 +179,11 @@ public void LogsWarningAndContinues_WhenGetManifestFails()
var executor = CreateExecutor(deployment);

// Act - should not throw
executor.ExecuteHelmUpgrade(deployment, ReleaseName, RevisionNumber, installCompletedCts, installErrorCts);
executor.ExecuteHelmUpgrade(deployment,
ReleaseName,
RevisionNumber,
installCompletedCts,
installErrorCts);

// Assert
log.MessagesWarnFormatted.Should().Contain(msg => msg.Contains($"Failed to get manifest for {ReleaseName} revision {RevisionNumber}"));
Expand All @@ -155,7 +205,11 @@ public void SkipsAppliedResourcesVariable_WhenManifestIsEmpty()
var executor = CreateExecutor(deployment);

// Act
executor.ExecuteHelmUpgrade(deployment, ReleaseName, RevisionNumber, installCompletedCts, installErrorCts);
executor.ExecuteHelmUpgrade(deployment,
ReleaseName,
RevisionNumber,
installCompletedCts,
installErrorCts);

// Assert
var appliedResourcesJson = variables.Get(SpecialVariables.AppliedResources);
Expand Down Expand Up @@ -279,22 +333,22 @@ void SetupHelmVersionMock()
//(and its output) reflects a Helm 4 client to prove the executor still works with it.
commandLineRunner.Execute(Arg.Is<CommandLineInvocation>(i => i.Arguments.StartsWith("version") && i.Arguments.Contains("--short")))
.Returns(info =>
{
var invocation = (CommandLineInvocation)info[0];
invocation.AdditionalInvocationOutputSink?.WriteInfo("v4.2.0");
return new CommandResult("helm version", 0);
});
{
var invocation = (CommandLineInvocation)info[0];
invocation.AdditionalInvocationOutputSink?.WriteInfo("v4.2.0");
return new CommandResult("helm version", 0);
});
}

void SetupHelmGetMetadataMock(int revision, string status)
{
commandLineRunner.Execute(Arg.Is<CommandLineInvocation>(i => i.Arguments.Contains("get") && i.Arguments.Contains("metadata")))
.Returns(info =>
{
var invocation = (CommandLineInvocation)info[0];
invocation.AdditionalInvocationOutputSink?.WriteInfo($"{{\"revision\":{revision},\"status\":\"{status}\"}}");
return new CommandResult("helm get metadata", 0);
});
{
var invocation = (CommandLineInvocation)info[0];
invocation.AdditionalInvocationOutputSink?.WriteInfo($"{{\"revision\":{revision},\"status\":\"{status}\"}}");
return new CommandResult("helm get metadata", 0);
});
}

void SetupHelmRollbackMock(int exitCode = 0)
Expand Down Expand Up @@ -325,14 +379,15 @@ void SetupHelmGetManifestMock(string manifestContent)
{
commandLineRunner.Execute(Arg.Is<CommandLineInvocation>(i => i.Arguments.Contains("get") && i.Arguments.Contains("manifest")))
.Returns(info =>
{
var invocation = (CommandLineInvocation)info[0];
if (!string.IsNullOrEmpty(manifestContent))
{
invocation.AdditionalInvocationOutputSink?.WriteInfo(manifestContent);
}
return new CommandResult("helm get manifest", 0);
});
{
var invocation = (CommandLineInvocation)info[0];
if (!string.IsNullOrEmpty(manifestContent))
{
invocation.AdditionalInvocationOutputSink?.WriteInfo(manifestContent);
}

return new CommandResult("helm get manifest", 0);
});
}

void SetupHelmGetManifestMockToFail()
Expand Down Expand Up @@ -364,10 +419,14 @@ HelmUpgradeExecutor CreateExecutor(RunningDeployment deployment)
var helmCli = new HelmCli(log, commandLineRunner, deployment, fileSystem);
var templateValueSourcesParser = new HelmTemplateValueSourcesParser(fileSystem, log);
var namespaceResolver = new KubernetesManifestNamespaceResolver(
new ApiResourcesScopeLookupBuilder().WithDefaults().Build(),
new ApiResourcesScopeLookupBuilder().WithDefaults().Build(),
log);

return new HelmUpgradeExecutor(log, fileSystem, templateValueSourcesParser, helmCli, namespaceResolver);
return new HelmUpgradeExecutor(log,
fileSystem,
templateValueSourcesParser,
helmCli,
namespaceResolver);
}

static string GetSampleManifest()
Expand All @@ -391,4 +450,4 @@ static string GetSampleManifest()
";
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ static void AddKOSArgs(IVariables variables, bool hasAdditionalArgs, List<string

//if wait or atomic is not set, we need it for KOS, so just set wait
//atomic is a superset of wait
if (!additionalArgs.Contains("--wait") || !additionalArgs.Contains("--atomic"))
if (!additionalArgs.Contains("--wait") && !additionalArgs.Contains("--atomic") && !additionalArgs.Contains("--rollback-on-failure"))
{
additionalArgs = $"{additionalArgs} --wait";
}

//update or add the additional args
if (hasAdditionalArgs)
{
args[args.Count - 1] = additionalArgs;
args[^1] = additionalArgs;
}
else
{
Expand Down Expand Up @@ -413,4 +413,4 @@ void AssertSupportedHelmVersion()
}
}
}
}
}