Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
50 changes: 39 additions & 11 deletions source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void ReportDeployments_WithSingleUpdatedApplication_WritesOneServiceMessa

var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 2, 2, [new UpdatedSourceDetail("abc123", 0, [], [])], [], [])
new("gateway1", new ApplicationName("app1"), 2, 2, [new TrackedSourceDetail("abc123", 0, [], [])], [], [])
};

reporter.ReportFilesUpdated(applicationResults);
Expand All @@ -61,8 +61,8 @@ public void ReportDeployments_WithMultipleUpdatedApplications_WritesMultipleServ

var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 2, 2, [new UpdatedSourceDetail("abc123", 0, [], [])], [], []),
new("gateway2", new ApplicationName("app2"), 1, 1, [new UpdatedSourceDetail("def456", 0, [], [])], [], [])
new("gateway1", new ApplicationName("app1"), 2, 2, [new TrackedSourceDetail("abc123", 0, [], [])], [], []),
new("gateway2", new ApplicationName("app2"), 1, 1, [new TrackedSourceDetail("def456", 0, [], [])], [], [])
};

reporter.ReportFilesUpdated(applicationResults);
Expand Down Expand Up @@ -100,7 +100,7 @@ public void ReportDeployments_WithReplacedFiles_IncludesReplacedFilesInSources()
var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 2, 2,
[new UpdatedSourceDetail("abc123", 0, [new FileHash("values.yaml", "22c0df2cceca5273e4dc569dda52805d27df3360")], [])],
[new TrackedSourceDetail("abc123", 0, [new FileHash("values.yaml", "22c0df2cceca5273e4dc569dda52805d27df3360")], [])],
[], [])
};

Expand All @@ -127,7 +127,7 @@ public void ReportDeployments_WithPatchedFiles_IncludesPatchedFilesInSources()
var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 1, 1,
[new UpdatedSourceDetail("def456", 0, [], [new FileJsonPatch("kustomization.yaml", """[{"op":"replace","path":"/images/0/name","value":"nginx:latest"}]""")])],
[new TrackedSourceDetail("def456", 0, [], [new FileJsonPatch("kustomization.yaml", """[{"op":"replace","path":"/images/0/name","value":"nginx:latest"}]""")])],
[], [])
};

Expand All @@ -154,7 +154,7 @@ public void ReportDeployments_WithBothReplacedAndPatchedFiles_IncludesBothInSour
var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 2, 2,
[new UpdatedSourceDetail("abc123", 0,
[new TrackedSourceDetail("abc123", 0,
[new FileHash("values.yaml", "22c0df2cceca5273e4dc569dda52805d27df3360")],
[new FileJsonPatch("kustomization.yaml", """[{"op":"replace","path":"/images/0/name","value":"nginx:latest"}]""")])],
[], [])
Expand Down Expand Up @@ -183,7 +183,7 @@ public void ReportDeployments_WithMultipleReplacedAndPatchedFiles_IncludesAllFil
var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 2, 2,
[new UpdatedSourceDetail("abc123", 0,
[new TrackedSourceDetail("abc123", 0,
[
new FileHash("values.yaml", "22c0df2cceca5273e4dc569dda52805d27df3360"),
new FileHash("values-prod.yaml", "a3b4c5d6e7f8a3b4c5d6e7f8a3b4c5d6e7f8a3b4")
Expand Down Expand Up @@ -219,8 +219,8 @@ public void ReportDeployments_WithMultipleSourcesWithFiles_IncludesAllSourcesInS
{
new("gateway1", new ApplicationName("app1"), 2, 2,
[
new UpdatedSourceDetail("abc123", 0, [new FileHash("values.yaml", "22c0df2cceca5273e4dc569dda52805d27df3360")], []),
new UpdatedSourceDetail("abc123", 1, [], [new FileJsonPatch("kustomization.yaml", """[{"op":"replace","path":"/images/0/name","value":"redis:latest"}]""")])
new TrackedSourceDetail("abc123", 0, [new FileHash("values.yaml", "22c0df2cceca5273e4dc569dda52805d27df3360")], []),
new TrackedSourceDetail("abc123", 1, [], [new FileJsonPatch("kustomization.yaml", """[{"op":"replace","path":"/images/0/name","value":"redis:latest"}]""")])
],
[], [])
};
Expand Down Expand Up @@ -248,7 +248,7 @@ public void ReportDeployments_WithOsSpecificReplacedFilePaths_ReportsPosixPaths(
var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 1, 1,
[new UpdatedSourceDetail("abc123", 0,
[new TrackedSourceDetail("abc123", 0,
[new FileHash(Path.Combine("some", "nested", "values.yaml"), "22c0df2cceca5273e4dc569dda52805d27df3360")],
[])],
[], [])
Expand All @@ -268,6 +268,34 @@ [new FileHash(Path.Combine("some", "nested", "values.yaml"), "22c0df2cceca5273e4
});
}

[Test]
public void ReportDeployments_WithNoOpSource_EmitsServiceMessageWithNullCommitSha()
{
var log = new InMemoryLog();
var reporter = new ArgoCDFilesUpdatedReporter(log);

var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 1, 1,
[new TrackedSourceDetail(null, 0, [],
[new FileJsonPatch("values.yaml", "[{\"op\":\"replace\",\"path\":\"/image\",\"value\":\"nginx:1.27\"}]")])],
[], [])
};

reporter.ReportFilesUpdated(applicationResults);

log.ServiceMessages.Should().ContainSingle().Which.Should().BeEquivalentTo(new
{
Name = "argocd-files-updated",
Properties = new Dictionary<string, string>
{
["gatewayId"] = "gateway1",
["applicationName"] = "app1",
["sources"] = "[{\"CommitSha\":null,\"SourceIndex\":0,\"ReplacedFiles\":[],\"PatchedFiles\":[{\"FilePath\":\"values.yaml\",\"JsonPatch\":\"[{\\u0022op\\u0022:\\u0022replace\\u0022,\\u0022path\\u0022:\\u0022/image\\u0022,\\u0022value\\u0022:\\u0022nginx:1.27\\u0022}]\"}]}]"
}
});
}

[Test]
public void ReportDeployments_WithMixedUpdatedAndNonUpdatedApplications_WritesOnlyUpdatedMessages()
{
Expand All @@ -277,7 +305,7 @@ public void ReportDeployments_WithMixedUpdatedAndNonUpdatedApplications_WritesOn
var applicationResults = new List<ProcessApplicationResult>
{
new("gateway1", new ApplicationName("app1"), 2, 2, [], [], []),
new("gateway2", new ApplicationName("app2"), 1, 1, [new UpdatedSourceDetail("abc123", 0, [], [])], [], []),
new("gateway2", new ApplicationName("app2"), 1, 1, [new TrackedSourceDetail("abc123", 0, [], [])], [], []),
new("gateway3", new ApplicationName("app3"), 1, 1, [], [], [])
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,7 @@ public void RefSourceWithHelmImageMatches_Update()
// Only values.yaml should be in PatchedFiles — values-extra.yaml had no image match and must not produce a patch entry
using var scope = new AssertionScope();
capturedResults.Should().NotBeNull();
var sourceDetails = capturedResults.Single().UpdatedSourceDetails.First();
Comment thread
scme0 marked this conversation as resolved.
var sourceDetails = capturedResults.Single().TrackedSourceDetails.First();
var expectedPatch = new JsonPatchDocument([
JsonPatchOperation.Replace(new JsonPointer("/0/image/tag"), "1.27.1"),
]);
Expand Down Expand Up @@ -1395,14 +1395,14 @@ public void DirectorySource_ImageMatches_ReportsDeploymentWithNonEmptyCommitSha(
var actual = capturedResults.Single();
actual.UpdatedImages.Should().BeEquivalentTo(["nginx:1.27.1", "alpine:2.2"]);
actual.GitReposUpdated.Should().HaveCount(1);
actual.UpdatedSourceDetails.Should().HaveCount(1);
actual.TrackedSourceDetails.Should().HaveCount(1);

var expectedPatch = new JsonPatchDocument([
JsonPatchOperation.Replace(new JsonPointer("/0/image1/name"), "nginx:1.27.1"),
JsonPatchOperation.Replace(new JsonPointer("/0/image2/tag"), 2.2),
]);

var sourceDetails = actual.UpdatedSourceDetails.First();
var sourceDetails = actual.TrackedSourceDetails.First();
sourceDetails.CommitSha.Should().HaveLength(40);
sourceDetails.ReplacedFiles.Should().BeEmpty();
sourceDetails.PatchedFiles.Should()
Expand Down Expand Up @@ -1613,6 +1613,54 @@ public void MixedHelmReferences_OneWithPathOneWithout_LogsVerboseWarningForImage
"alpine:3.21 will not be updated in helm sources, as no helm yaml path has been specified for it in the step configuration.");
}

[Test]
public void HelmSource_ImageAlreadyAtTargetTag_TracksSourceWithNullCommitSha()
{
// Arrange
argoCdApplicationFromYaml.Metadata.Annotations[ArgoCDConstants.Annotations.OctopusImageReplacementPathsKey(null)] = "{{ .Values.image.name }}";
originRepo.AddFilesToBranch(argoCDBranchName, ("files/values.yml", @"
image:
name: nginx:1.27.1
"));

var updater = CreateConvention();
var variables = new CalamariVariables
{
[ProjectVariables.Slug] = ProjectSlug,
[DeploymentEnvironment.Slug] = EnvironmentSlug,
[PackageVariables.IndexedImage("nginx")] = "nginx:1.27.1",
[PackageVariables.IndexedPackagePurpose("nginx")] = "DockerImageReference",
};
var runningDeployment = new RunningDeployment(null, variables);
runningDeployment.CurrentDirectoryProvider = DeploymentWorkingDirectory.StagingDirectory;
runningDeployment.StagingDirectory = tempDirectory;

IReadOnlyList<ProcessApplicationResult> capturedResults = null;
deploymentReporter.ReportFilesUpdated(Arg.Do<IReadOnlyList<ProcessApplicationResult>>(x => capturedResults = x));

// Act
updater.Install(runningDeployment);

// Assert
using var scope = new AssertionScope();
capturedResults.Should().NotBeNull();
var actual = capturedResults.Single();
actual.Updated.Should().BeFalse("image is already at the target tag so no commit should be made");
actual.UpdatedImages.Should().BeEmpty();
actual.TrackedSourceDetails.Should().HaveCount(1, "source should still be tracked for the no-op case");

var sourceDetails = actual.TrackedSourceDetails.First();
sourceDetails.CommitSha.Should().BeNull("no commit was made");

var expectedPatch = new JsonPatchDocument([
JsonPatchOperation.Replace(new JsonPointer("/0/image/name"), "nginx:1.27.1"),
]);
sourceDetails.PatchedFiles.Should()
.BeEquivalentTo([
new FileJsonPatch(Path.Combine("files", "values.yml"), JsonSerializer.Serialize(expectedPatch)),
]);
}

void AssertFileContents(string clonedRepoPath, string relativeFilePath, string expectedContent)
{
var absolutePath = Path.Combine(clonedRepoPath, relativeFilePath);
Expand Down
Loading