@@ -13,6 +13,7 @@ import (
13
13
"helm.sh/helm/v3/pkg/action"
14
14
"helm.sh/helm/v3/pkg/chart"
15
15
"helm.sh/helm/v3/pkg/release"
16
+ "helm.sh/helm/v3/pkg/storage"
16
17
"helm.sh/helm/v3/pkg/storage/driver"
17
18
corev1 "k8s.io/api/core/v1"
18
19
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -50,6 +51,7 @@ type mockActionGetter struct {
50
51
reconcileErr error
51
52
desiredRel * release.Release
52
53
currentRel * release.Release
54
+ config * action.Configuration
53
55
}
54
56
55
57
func (mag * mockActionGetter ) ActionClientFor (ctx context.Context , obj client.Object ) (helmclient.ActionInterface , error ) {
@@ -98,6 +100,10 @@ func (mag *mockActionGetter) Reconcile(rel *release.Release) error {
98
100
return mag .reconcileErr
99
101
}
100
102
103
+ func (mag * mockActionGetter ) Config () * action.Configuration {
104
+ return mag .config
105
+ }
106
+
101
107
var (
102
108
// required for unmockable call to convert.RegistryV1ToHelmChart
103
109
validFS = fstest.MapFS {
@@ -179,6 +185,80 @@ func TestApply_Base(t *testing.T) {
179
185
})
180
186
}
181
187
188
+ func TestApply_InterruptedRelease (t * testing.T ) {
189
+ t .Run ("fails removing an interrupted install release" , func (t * testing.T ) {
190
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingInstall }}
191
+ testStorage := storage .Init (driver .NewMemory ())
192
+
193
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
194
+ helmApplier := applier.Helm {
195
+ ActionClientGetter : mockAcg ,
196
+ BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
197
+ }
198
+
199
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
200
+ require .Error (t , err )
201
+ require .ErrorContains (t , err , "removing interrupted release" )
202
+ require .Nil (t , objs )
203
+ require .Empty (t , state )
204
+ })
205
+
206
+ t .Run ("fails removing an interrupted upgrade release" , func (t * testing.T ) {
207
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingUpgrade }}
208
+ testStorage := storage .Init (driver .NewMemory ())
209
+
210
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
211
+ helmApplier := applier.Helm {
212
+ ActionClientGetter : mockAcg ,
213
+ BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
214
+ }
215
+
216
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
217
+ require .Error (t , err )
218
+ require .ErrorContains (t , err , "removing interrupted release" )
219
+ require .Nil (t , objs )
220
+ require .Empty (t , state )
221
+ })
222
+
223
+ t .Run ("successfully removes an interrupted install release" , func (t * testing.T ) {
224
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingInstall }}
225
+ testStorage := storage .Init (driver .NewMemory ())
226
+ err := testStorage .Create (testRel )
227
+ require .NoError (t , err )
228
+
229
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
230
+ helmApplier := applier.Helm {
231
+ ActionClientGetter : mockAcg ,
232
+ BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
233
+ }
234
+
235
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
236
+ require .Error (t , err )
237
+ require .ErrorContains (t , err , "removed interrupted release" )
238
+ require .Nil (t , objs )
239
+ require .Empty (t , state )
240
+ })
241
+
242
+ t .Run ("successfully removes an interrupted upgrade release" , func (t * testing.T ) {
243
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingUpgrade }}
244
+ testStorage := storage .Init (driver .NewMemory ())
245
+ err := testStorage .Create (testRel )
246
+ require .NoError (t , err )
247
+
248
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
249
+ helmApplier := applier.Helm {
250
+ ActionClientGetter : mockAcg ,
251
+ BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
252
+ }
253
+
254
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
255
+ require .Error (t , err )
256
+ require .ErrorContains (t , err , "removed interrupted release" )
257
+ require .Nil (t , objs )
258
+ require .Empty (t , state )
259
+ })
260
+ }
261
+
182
262
func TestApply_Installation (t * testing.T ) {
183
263
t .Run ("fails during dry-run installation" , func (t * testing.T ) {
184
264
mockAcg := & mockActionGetter {
@@ -340,6 +420,7 @@ func TestApply_Upgrade(t *testing.T) {
340
420
341
421
t .Run ("fails during dry-run upgrade" , func (t * testing.T ) {
342
422
mockAcg := & mockActionGetter {
423
+ currentRel : testCurrentRelease ,
343
424
dryRunUpgradeErr : errors .New ("failed attempting to dry-run upgrade chart" ),
344
425
}
345
426
helmApplier := applier.Helm {
0 commit comments