@@ -18,6 +18,7 @@ package controller_test
1818
1919import (
2020 "context"
21+ "fmt"
2122 "testing"
2223 "time"
2324
@@ -54,7 +55,7 @@ func TestExternalArtifact_LifeCycle(t *testing.T) {
5455 Namespace : ns .Name ,
5556 Name : "test-ea" ,
5657 }
57- ea , err := applyExternalArtifact (eaKey , revision )
58+ ea , err := applyExternalArtifact (eaKey , revision , "" )
5859 g .Expect (err ).ToNot (HaveOccurred (), "failed to create ExternalArtifact" )
5960
6061 // Create a HelmRelease that references the ExternalArtifact
@@ -80,24 +81,26 @@ func TestExternalArtifact_LifeCycle(t *testing.T) {
8081 g .Expect (err ).ToNot (HaveOccurred ())
8182
8283 t .Run ("installs from external artifact" , func (t * testing.T ) {
83- g .Eventually (func () bool {
84+ gt := NewWithT (t )
85+ gt .Eventually (func () bool {
8486 err = testEnv .Get (context .Background (), client .ObjectKeyFromObject (hr ), hr )
8587 if err != nil {
8688 return false
8789 }
8890 return apimeta .IsStatusConditionTrue (hr .Status .Conditions , meta .ReadyCondition )
8991 }, 5 * time .Second , time .Second ).Should (BeTrue (), "HelmRelease did not become ready" )
9092
91- g .Expect (hr .Status .LastAttemptedRevision ).To (Equal (revision ))
92- g .Expect (hr .Status .LastAttemptedReleaseAction ).To (Equal (v2 .ReleaseActionInstall ))
93+ gt .Expect (hr .Status .LastAttemptedRevision ).To (Equal (revision ))
94+ gt .Expect (hr .Status .LastAttemptedReleaseAction ).To (Equal (v2 .ReleaseActionInstall ))
9395 })
9496
9597 t .Run ("upgrades at external artifact revision change" , func (t * testing.T ) {
98+ gt := NewWithT (t )
9699 newRevision := "2.0.0"
97- ea , err = applyExternalArtifact (eaKey , newRevision )
98- g .Expect (err ).ToNot (HaveOccurred ())
100+ ea , err = applyExternalArtifact (eaKey , newRevision , "" )
101+ gt .Expect (err ).ToNot (HaveOccurred ())
99102
100- g .Eventually (func () bool {
103+ gt .Eventually (func () bool {
101104 err = testEnv .Get (context .Background (), client .ObjectKeyFromObject (hr ), hr )
102105 if err != nil {
103106 return false
@@ -106,42 +109,81 @@ func TestExternalArtifact_LifeCycle(t *testing.T) {
106109 hr .Status .LastAttemptedRevision == newRevision
107110 }, 5 * time .Second , time .Second ).Should (BeTrue (), "HelmRelease did not upgrade" )
108111
109- g .Expect (hr .Status .LastAttemptedReleaseAction ).To (Equal (v2 .ReleaseActionUpgrade ))
112+ gt .Expect (hr .Status .LastAttemptedReleaseAction ).To (Equal (v2 .ReleaseActionUpgrade ))
113+ })
114+
115+ t .Run ("upgrades at external artifact revision switch to digest" , func (t * testing.T ) {
116+ gt := NewWithT (t )
117+ fixedRevision := "2.0.0"
118+ newDigest := fmt .Sprintf ("latest@%s" , digest .FromString ("1" ))
119+ ea , err = applyExternalArtifact (eaKey , fixedRevision , newDigest )
120+ gt .Expect (err ).ToNot (HaveOccurred ())
121+
122+ gt .Eventually (func () bool {
123+ err = testEnv .Get (context .Background (), client .ObjectKeyFromObject (hr ), hr )
124+ if err != nil {
125+ return false
126+ }
127+ return apimeta .IsStatusConditionTrue (hr .Status .Conditions , meta .ReadyCondition ) &&
128+ hr .Status .LastAttemptedRevisionDigest == newDigest
129+ }, 5 * time .Second , time .Second ).Should (BeTrue (), "HelmRelease did not upgrade" )
130+
131+ gt .Expect (hr .Status .LastAttemptedReleaseAction ).To (Equal (v2 .ReleaseActionUpgrade ))
132+ })
133+
134+ t .Run ("upgrades at external artifact digest change" , func (t * testing.T ) {
135+ gt := NewWithT (t )
136+ fixedRevision := "2.0.0"
137+ newDigest := digest .FromString ("2" ).String ()
138+ ea , err = applyExternalArtifact (eaKey , fixedRevision , newDigest )
139+ gt .Expect (err ).ToNot (HaveOccurred ())
140+
141+ gt .Eventually (func () bool {
142+ err = testEnv .Get (context .Background (), client .ObjectKeyFromObject (hr ), hr )
143+ if err != nil {
144+ return false
145+ }
146+ return apimeta .IsStatusConditionTrue (hr .Status .Conditions , meta .ReadyCondition ) &&
147+ hr .Status .LastAttemptedRevisionDigest == newDigest
148+ }, 5 * time .Second , time .Second ).Should (BeTrue (), "HelmRelease did not upgrade" )
149+
150+ gt .Expect (hr .Status .LastAttemptedReleaseAction ).To (Equal (v2 .ReleaseActionUpgrade ))
110151 })
111152
112153 t .Run ("fails when external artifact feature gate is disable" , func (t * testing.T ) {
113- newRevision := "3.0.0"
154+ gt := NewWithT ( t )
114155 reconciler .AllowExternalArtifact = false
156+ newRevision := "3.0.0"
157+ ea , err = applyExternalArtifact (eaKey , newRevision , "" )
158+ gt .Expect (err ).ToNot (HaveOccurred ())
115159
116- ea , err = applyExternalArtifact (eaKey , newRevision )
117- g .Expect (err ).ToNot (HaveOccurred ())
118-
119- g .Eventually (func () bool {
160+ gt .Eventually (func () bool {
120161 err = testEnv .Get (context .Background (), client .ObjectKeyFromObject (hr ), hr )
121162 if err != nil {
122163 return false
123164 }
124165 return apimeta .IsStatusConditionFalse (hr .Status .Conditions , meta .ReadyCondition )
125166 }, 5 * time .Second , time .Second ).Should (BeTrue ())
126167
127- g .Expect (apimeta .IsStatusConditionTrue (hr .Status .Conditions , meta .StalledCondition )).Should (BeTrue ())
168+ gt .Expect (apimeta .IsStatusConditionTrue (hr .Status .Conditions , meta .StalledCondition )).Should (BeTrue ())
128169 readyCondition := apimeta .FindStatusCondition (hr .Status .Conditions , meta .ReadyCondition )
129- g .Expect (readyCondition .Reason ).To (Equal (aclv1 .AccessDeniedReason ))
170+ gt .Expect (readyCondition .Reason ).To (Equal (aclv1 .AccessDeniedReason ))
130171 })
131172
132173 t .Run ("uninstalls successfully" , func (t * testing.T ) {
174+ gt := NewWithT (t )
133175 err = k8sClient .Delete (context .Background (), hr )
134- g .Expect (err ).ToNot (HaveOccurred ())
176+ gt .Expect (err ).ToNot (HaveOccurred ())
135177
136- g .Eventually (func () bool {
178+ gt .Eventually (func () bool {
137179 err = testEnv .Get (context .Background (), client .ObjectKeyFromObject (hr ), hr )
138180 return err != nil && client .IgnoreNotFound (err ) == nil
139181 }, 5 * time .Second , time .Second ).Should (BeTrue (), "HelmRelease was not deleted" )
140182 })
141183}
142184
143- func applyExternalArtifact (objKey client.ObjectKey , revision string ) (* sourcev1.ExternalArtifact , error ) {
144- chart := testutil .BuildChart (testutil .ChartWithVersion (revision ))
185+ func applyExternalArtifact (objKey client.ObjectKey , aVersion , aDigest string ) (* sourcev1.ExternalArtifact , error ) {
186+ chart := testutil .BuildChart (testutil .ChartWithVersion (aVersion ))
145187 artifact , err := testutil .SaveChartAsArtifact (chart , digest .SHA256 , testServer .URL (), testServer .Root ())
146188 if err != nil {
147189 return nil , err
@@ -169,6 +211,9 @@ func applyExternalArtifact(objKey client.ObjectKey, revision string) (*sourcev1.
169211 }
170212
171213 ea .ManagedFields = nil
214+ if aDigest != "" {
215+ artifact .Revision = aDigest
216+ }
172217 ea .Status = sourcev1.ExternalArtifactStatus {
173218 Artifact : artifact ,
174219 Conditions : []metav1.Condition {
0 commit comments