@@ -17,6 +17,7 @@ limitations under the License.
1717package common_controller
1818
1919import (
20+ "encoding/json"
2021 "errors"
2122 "fmt"
2223 "net/http"
@@ -29,8 +30,7 @@ import (
2930 "testing"
3031 "time"
3132
32- "k8s.io/client-go/util/workqueue"
33-
33+ jsonpatch "github.com/evanphx/json-patch"
3434 crdv1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
3535 clientset "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned"
3636 "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake"
@@ -55,6 +55,7 @@ import (
5555 core "k8s.io/client-go/testing"
5656 "k8s.io/client-go/tools/cache"
5757 "k8s.io/client-go/tools/record"
58+ "k8s.io/client-go/util/workqueue"
5859 klog "k8s.io/klog/v2"
5960)
6061
@@ -258,6 +259,46 @@ func (r *snapshotReactor) React(action core.Action) (handled bool, ret runtime.O
258259 klog .V (4 ).Infof ("saved updated content %s" , content .Name )
259260 return true , content , nil
260261
262+ case action .Matches ("patch" , "volumesnapshotcontents" ):
263+ content := & crdv1.VolumeSnapshotContent {}
264+ action := action .(core.PatchAction )
265+
266+ // Check and bump object version
267+ storedSnapshotContent , found := r .contents [action .GetName ()]
268+ if found {
269+ // Apply patch
270+ storedSnapshotBytes , err := json .Marshal (storedSnapshotContent )
271+ if err != nil {
272+ return true , nil , err
273+ }
274+ contentPatch , err := jsonpatch .DecodePatch (action .GetPatch ())
275+ if err != nil {
276+ return true , nil , err
277+ }
278+
279+ modified , err := contentPatch .Apply (storedSnapshotBytes )
280+ if err != nil {
281+ return true , nil , err
282+ }
283+
284+ err = json .Unmarshal (modified , content )
285+ if err != nil {
286+ return true , nil , err
287+ }
288+
289+ storedVer , _ := strconv .Atoi (content .ResourceVersion )
290+ content .ResourceVersion = strconv .Itoa (storedVer + 1 )
291+ } else {
292+ return true , nil , fmt .Errorf ("cannot update snapshot content %s: snapshot content not found" , action .GetName ())
293+ }
294+
295+ // Store the updated object to appropriate places.
296+ r .contents [content .Name ] = content
297+ r .changedObjects = append (r .changedObjects , content )
298+ r .changedSinceLastSync ++
299+ klog .V (4 ).Infof ("saved updated content %s" , content .Name )
300+ return true , content , nil
301+
261302 case action .Matches ("update" , "volumesnapshots" ):
262303 obj := action .(core.UpdateAction ).GetObject ()
263304 snapshot := obj .(* crdv1.VolumeSnapshot )
@@ -284,6 +325,45 @@ func (r *snapshotReactor) React(action core.Action) (handled bool, ret runtime.O
284325 klog .V (4 ).Infof ("saved updated snapshot %s" , snapshot .Name )
285326 return true , snapshot , nil
286327
328+ case action .Matches ("patch" , "volumesnapshots" ):
329+ action := action .(core.PatchAction )
330+ // Check and bump object version
331+ storedSnapshot , found := r .snapshots [action .GetName ()]
332+ if found {
333+ // Apply patch
334+ storedSnapshotBytes , err := json .Marshal (storedSnapshot )
335+ if err != nil {
336+ return true , nil , err
337+ }
338+ snapPatch , err := jsonpatch .DecodePatch (action .GetPatch ())
339+ if err != nil {
340+ return true , nil , err
341+ }
342+
343+ modified , err := snapPatch .Apply (storedSnapshotBytes )
344+ if err != nil {
345+ return true , nil , err
346+ }
347+
348+ err = json .Unmarshal (modified , storedSnapshot )
349+ if err != nil {
350+ return true , nil , err
351+ }
352+
353+ storedVer , _ := strconv .Atoi (storedSnapshot .ResourceVersion )
354+ storedSnapshot .ResourceVersion = strconv .Itoa (storedVer + 1 )
355+ } else {
356+ return true , nil , fmt .Errorf ("cannot update snapshot %s: snapshot not found" , action .GetName ())
357+ }
358+
359+ // Store the updated object to appropriate places.
360+ r .snapshots [storedSnapshot .Name ] = storedSnapshot
361+ r .changedObjects = append (r .changedObjects , storedSnapshot )
362+ r .changedSinceLastSync ++
363+
364+ klog .V (4 ).Infof ("saved updated snapshot %s" , storedSnapshot .Name )
365+ return true , storedSnapshot , nil
366+
287367 case action .Matches ("get" , "volumesnapshotcontents" ):
288368 name := action .(core.GetAction ).GetName ()
289369 content , found := r .contents [name ]
@@ -437,6 +517,7 @@ func (r *snapshotReactor) checkContents(expectedContents []*crdv1.VolumeSnapshot
437517 }
438518 gotMap [v .Name ] = v
439519 }
520+
440521 if ! reflect .DeepEqual (expectedMap , gotMap ) {
441522 // Print ugly but useful diff of expected and received objects for
442523 // easier debugging.
@@ -714,6 +795,8 @@ func newSnapshotReactor(kubeClient *kubefake.Clientset, client *fake.Clientset,
714795 client .AddReactor ("create" , "volumesnapshotcontents" , reactor .React )
715796 client .AddReactor ("update" , "volumesnapshotcontents" , reactor .React )
716797 client .AddReactor ("update" , "volumesnapshots" , reactor .React )
798+ client .AddReactor ("patch" , "volumesnapshotcontents" , reactor .React )
799+ client .AddReactor ("patch" , "volumesnapshots" , reactor .React )
717800 client .AddReactor ("update" , "volumesnapshotclasses" , reactor .React )
718801 client .AddReactor ("get" , "volumesnapshotcontents" , reactor .React )
719802 client .AddReactor ("get" , "volumesnapshots" , reactor .React )
@@ -1169,6 +1252,10 @@ func testAddSnapshotFinalizer(ctrl *csiSnapshotCommonController, reactor *snapsh
11691252 return ctrl .addSnapshotFinalizer (test .initialSnapshots [0 ], true , true )
11701253}
11711254
1255+ func testAddSingleSnapshotFinalizer (ctrl * csiSnapshotCommonController , reactor * snapshotReactor , test controllerTest ) error {
1256+ return ctrl .addSnapshotFinalizer (test .initialSnapshots [0 ], false , true )
1257+ }
1258+
11721259func testRemoveSnapshotFinalizer (ctrl * csiSnapshotCommonController , reactor * snapshotReactor , test controllerTest ) error {
11731260 return ctrl .removeSnapshotFinalizer (test .initialSnapshots [0 ], true , true )
11741261}
@@ -1426,24 +1513,29 @@ func evaluateFinalizerTests(ctrl *csiSnapshotCommonController, reactor *snapshot
14261513 if funcName == "testAddSnapshotFinalizer" {
14271514 for _ , snapshot := range reactor .snapshots {
14281515 if test .initialSnapshots [0 ].Name == snapshot .Name {
1429- if ! utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) && utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) &&
1430- ! utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) && utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) {
1516+ if ! utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) &&
1517+ utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) &&
1518+ ! utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) &&
1519+ utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) {
14311520 klog .V (4 ).Infof ("test %q succeeded. Finalizers are added to snapshot %s" , test .name , snapshot .Name )
14321521 bHasSnapshotFinalizer = true
14331522 }
14341523 break
14351524 }
14361525 }
14371526 if test .expectSuccess && ! bHasSnapshotFinalizer {
1438- t .Errorf ("Test %q: failed to add finalizer to Snapshot %s" , test .name , test .initialSnapshots [0 ].Name )
1527+ t .Errorf ("Test %q: failed to add finalizer to Snapshot %s. Finalizers: %s " , test .name , test .initialSnapshots [0 ].Name , test . initialSnapshots [ 0 ]. GetFinalizers () )
14391528 }
14401529 }
14411530 bHasSnapshotFinalizer = true
14421531 if funcName == "testRemoveSnapshotFinalizer" {
14431532 for _ , snapshot := range reactor .snapshots {
14441533 if test .initialSnapshots [0 ].Name == snapshot .Name {
1445- if utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) && ! utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) &&
1446- utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) && ! utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) {
1534+ if utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) &&
1535+ ! utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotBoundFinalizer ) &&
1536+ utils .ContainsString (test .initialSnapshots [0 ].ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) &&
1537+ ! utils .ContainsString (snapshot .ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer ) {
1538+
14471539 klog .V (4 ).Infof ("test %q succeeded. SnapshotFinalizer is removed from Snapshot %s" , test .name , snapshot .Name )
14481540 bHasSnapshotFinalizer = false
14491541 }
0 commit comments