@@ -28,15 +28,19 @@ import (
2828 . "github.com/onsi/ginkgo/v2"
2929 . "github.com/onsi/gomega"
3030 "github.com/spf13/cobra"
31+ "github.com/stretchr/testify/mock"
3132 corev1 "k8s.io/api/core/v1"
3233 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3335 "k8s.io/apimachinery/pkg/runtime"
36+ "k8s.io/apimachinery/pkg/runtime/schema"
3437 "k8s.io/client-go/kubernetes/fake"
3538 ktesting "k8s.io/client-go/testing"
3639
3740 "github.com/NVIDIA/nodewright/operator/api/v1alpha1"
3841 "github.com/NVIDIA/nodewright/operator/internal/cli/client"
3942 "github.com/NVIDIA/nodewright/operator/internal/cli/context"
43+ mockdynamic "github.com/NVIDIA/nodewright/operator/internal/mocks/dynamic"
4044)
4145
4246// Helper function to create a test node with nodeState annotation
@@ -355,16 +359,24 @@ var _ = Describe("Reset Command", func() {
355359
356360 Describe ("--package" , func () {
357361 var (
358- fakeKube * fake.Clientset
359- kubeClient * client.Client
360- cliCtx * context.CLIContext
361- cmd * cobra.Command
362- out * bytes.Buffer
362+ fakeKube * fake.Clientset
363+ mockDynamic * mockdynamic.Interface
364+ kubeClient * client.Client
365+ cliCtx * context.CLIContext
366+ cmd * cobra.Command
367+ out * bytes.Buffer
363368 )
364369
370+ skyhookGVR := schema.GroupVersionResource {
371+ Group : "skyhook.nvidia.com" ,
372+ Version : "v1alpha1" ,
373+ Resource : "skyhooks" ,
374+ }
375+
365376 BeforeEach (func () {
366377 fakeKube = fake .NewClientset ()
367- kubeClient = client .NewWithClientsAndConfig (fakeKube , nil , nil )
378+ mockDynamic = & mockdynamic.Interface {}
379+ kubeClient = client .NewWithClientsAndConfig (fakeKube , mockDynamic , nil )
368380 cliCtx = context .NewCLIContext (nil )
369381 cmd = NewResetCmd (cliCtx )
370382 out = & bytes.Buffer {}
@@ -373,6 +385,22 @@ var _ = Describe("Reset Command", func() {
373385 cmd .SetIn (bytes .NewBufferString ("y\n " ))
374386 })
375387
388+ setupSkyhookCR := func (name , version string ) {
389+ sk := & v1alpha1.Skyhook {}
390+ sk .Name = name
391+ sk .Annotations = map [string ]string {
392+ "skyhook.nvidia.com/version" : version ,
393+ }
394+ u := & unstructured.Unstructured {}
395+ raw , err := json .Marshal (sk )
396+ Expect (err ).NotTo (HaveOccurred ())
397+ Expect (json .Unmarshal (raw , & u .Object )).To (Succeed ())
398+ u .SetGroupVersionKind (schema.GroupVersionKind {Group : "skyhook.nvidia.com" , Version : "v1alpha1" , Kind : "Skyhook" })
399+ mockNSRes := & mockdynamic.NamespaceableResourceInterface {}
400+ mockDynamic .On ("Resource" , skyhookGVR ).Return (mockNSRes )
401+ mockNSRes .On ("Get" , mock .Anything , name , mock .Anything , mock .Anything ).Return (u , nil )
402+ }
403+
376404 addNode := func (name string , ns v1alpha1.NodeState ) {
377405 raw , _ := json .Marshal (ns )
378406 n := & corev1.Node {
@@ -388,6 +416,7 @@ var _ = Describe("Reset Command", func() {
388416 }
389417
390418 It ("removes only the named package entry from each node" , func () {
419+ setupSkyhookCR ("demo" , "v0.15.0" )
391420 addNode ("n1" , v1alpha1.NodeState {
392421 "pkg1|1.0" : {Name : "pkg1" , Version : "1.0" , Stage : v1alpha1 .StageApply , State : v1alpha1 .StateComplete },
393422 "pkg2|2.0" : {Name : "pkg2" , Version : "2.0" , Stage : v1alpha1 .StageConfig , State : v1alpha1 .StateComplete },
@@ -405,6 +434,7 @@ var _ = Describe("Reset Command", func() {
405434 })
406435
407436 It ("with name:version only removes if version matches" , func () {
437+ setupSkyhookCR ("demo" , "v0.15.0" )
408438 addNode ("n1" , v1alpha1.NodeState {
409439 "pkg1|1.0" : {Name : "pkg1" , Version : "1.0" , Stage : v1alpha1 .StageApply , State : v1alpha1 .StateComplete },
410440 })
@@ -420,6 +450,7 @@ var _ = Describe("Reset Command", func() {
420450 })
421451
422452 It ("removes the entire annotation when the last entry is removed" , func () {
453+ setupSkyhookCR ("demo" , "v0.15.0" )
423454 addNode ("n1" , v1alpha1.NodeState {
424455 "pkg1|1.0" : {Name : "pkg1" , Version : "1.0" , Stage : v1alpha1 .StageApply , State : v1alpha1 .StateComplete },
425456 })
@@ -440,5 +471,18 @@ var _ = Describe("Reset Command", func() {
440471 Entry ("empty name with version" , ":1.0" ),
441472 Entry ("empty version with colon" , "pkg1:" ),
442473 )
474+
475+ It ("rejects --package against an operator older than v0.15.0" , func () {
476+ setupSkyhookCR ("demo" , "v0.10.0" )
477+ addNode ("n1" , v1alpha1.NodeState {
478+ "pkg1|1.0" : {Name : "pkg1" , Version : "1.0" , Stage : v1alpha1 .StageApply , State : v1alpha1 .StateComplete },
479+ })
480+ opts := & resetOptions {confirm : true , skipBatchReset : true , pkg : "pkg1" }
481+ err := runReset (gocontext .Background (), cmd , kubeClient , "demo" , opts , cliCtx )
482+ Expect (err ).To (HaveOccurred ())
483+ Expect (err .Error ()).To (ContainSubstring ("does not support" ))
484+ Expect (err .Error ()).To (ContainSubstring ("v0.10.0" ))
485+ Expect (err .Error ()).To (ContainSubstring ("v0.15.0" ))
486+ })
443487 })
444488})
0 commit comments