@@ -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
rbacv1 "k8s.io/api/rbac/v1"
@@ -66,6 +67,7 @@ type mockActionGetter struct {
66
67
reconcileErr error
67
68
desiredRel * release.Release
68
69
currentRel * release.Release
70
+ config * action.Configuration
69
71
}
70
72
71
73
func (mag * mockActionGetter ) ActionClientFor (ctx context.Context , obj client.Object ) (helmclient.ActionInterface , error ) {
@@ -114,6 +116,10 @@ func (mag *mockActionGetter) Reconcile(rel *release.Release) error {
114
116
return mag .reconcileErr
115
117
}
116
118
119
+ func (mag * mockActionGetter ) Config () * action.Configuration {
120
+ return mag .config
121
+ }
122
+
117
123
var (
118
124
// required for unmockable call to convert.RegistryV1ToHelmChart
119
125
validFS = fstest.MapFS {
@@ -223,6 +229,80 @@ func TestApply_Base(t *testing.T) {
223
229
})
224
230
}
225
231
232
+ func TestApply_InterruptedRelease (t * testing.T ) {
233
+ t .Run ("fails removing an interrupted install release" , func (t * testing.T ) {
234
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingInstall }}
235
+ testStorage := storage .Init (driver .NewMemory ())
236
+
237
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
238
+ helmApplier := applier.Helm {
239
+ ActionClientGetter : mockAcg ,
240
+ BundleToHelmChartConverter : & convert.BundleToHelmChartConverter {},
241
+ }
242
+
243
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
244
+ require .Error (t , err )
245
+ require .ErrorContains (t , err , "removing interrupted release" )
246
+ require .Nil (t , objs )
247
+ require .Empty (t , state )
248
+ })
249
+
250
+ t .Run ("fails removing an interrupted upgrade release" , func (t * testing.T ) {
251
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingUpgrade }}
252
+ testStorage := storage .Init (driver .NewMemory ())
253
+
254
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
255
+ helmApplier := applier.Helm {
256
+ ActionClientGetter : mockAcg ,
257
+ BundleToHelmChartConverter : & convert.BundleToHelmChartConverter {},
258
+ }
259
+
260
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
261
+ require .Error (t , err )
262
+ require .ErrorContains (t , err , "removing interrupted release" )
263
+ require .Nil (t , objs )
264
+ require .Empty (t , state )
265
+ })
266
+
267
+ t .Run ("successfully removes an interrupted install release" , func (t * testing.T ) {
268
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingInstall }}
269
+ testStorage := storage .Init (driver .NewMemory ())
270
+ err := testStorage .Create (testRel )
271
+ require .NoError (t , err )
272
+
273
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
274
+ helmApplier := applier.Helm {
275
+ ActionClientGetter : mockAcg ,
276
+ BundleToHelmChartConverter : & convert.BundleToHelmChartConverter {},
277
+ }
278
+
279
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
280
+ require .Error (t , err )
281
+ require .ErrorContains (t , err , "removed interrupted release" )
282
+ require .Nil (t , objs )
283
+ require .Empty (t , state )
284
+ })
285
+
286
+ t .Run ("successfully removes an interrupted upgrade release" , func (t * testing.T ) {
287
+ testRel := & release.Release {Name : "testrel" , Version : 0 , Info : & release.Info {Status : release .StatusPendingUpgrade }}
288
+ testStorage := storage .Init (driver .NewMemory ())
289
+ err := testStorage .Create (testRel )
290
+ require .NoError (t , err )
291
+
292
+ mockAcg := & mockActionGetter {currentRel : testRel , config : & action.Configuration {Releases : testStorage }}
293
+ helmApplier := applier.Helm {
294
+ ActionClientGetter : mockAcg ,
295
+ BundleToHelmChartConverter : & convert.BundleToHelmChartConverter {},
296
+ }
297
+
298
+ objs , state , err := helmApplier .Apply (context .TODO (), validFS , testCE , testObjectLabels , testStorageLabels )
299
+ require .Error (t , err )
300
+ require .ErrorContains (t , err , "removed interrupted release" )
301
+ require .Nil (t , objs )
302
+ require .Empty (t , state )
303
+ })
304
+ }
305
+
226
306
func TestApply_Installation (t * testing.T ) {
227
307
t .Run ("fails during dry-run installation" , func (t * testing.T ) {
228
308
mockAcg := & mockActionGetter {
@@ -439,6 +519,7 @@ func TestApply_Upgrade(t *testing.T) {
439
519
440
520
t .Run ("fails during dry-run upgrade" , func (t * testing.T ) {
441
521
mockAcg := & mockActionGetter {
522
+ currentRel : testCurrentRelease ,
442
523
dryRunUpgradeErr : errors .New ("failed attempting to dry-run upgrade chart" ),
443
524
}
444
525
helmApplier := applier.Helm {
0 commit comments