@@ -19,15 +19,14 @@ package cnsnodevmbatchattachment
1919import (
2020 "context"
2121 "fmt"
22- "reflect"
23- "strconv"
2422 "sync"
2523 "testing"
2624 "time"
2725
2826 "github.com/stretchr/testify/assert"
2927 "github.com/vmware/govmomi/object"
3028 v1 "k8s.io/api/core/v1"
29+ "k8s.io/apimachinery/pkg/api/errors"
3130 "k8s.io/apimachinery/pkg/api/resource"
3231 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3332 "k8s.io/apimachinery/pkg/runtime/schema"
@@ -234,6 +233,55 @@ func TestCnsNodeVMBatchAttachmentWhenVmOnVcenterReturnsError(t *testing.T) {
234233 })
235234}
236235
236+ func TestCnsNodeVMBatchAttachmentWhenVmOnVcenterReturnsNotFoundError (t * testing.T ) {
237+
238+ t .Run ("TestCnsNodeVMBatchAttachmentWhenVmOnVcenterReturnsNotFoundError" , func (t * testing.T ) {
239+ testCnsNodeVMBatchAttachment := setupTestCnsNodeVMBatchAttachment ()
240+ testCnsNodeVMBatchAttachment .Spec .InstanceUUID = "test-3"
241+
242+ r := setTestEnvironment (& testCnsNodeVMBatchAttachment , true )
243+
244+ req := reconcile.Request {
245+ NamespacedName : types.NamespacedName {
246+ Name : testCnsNodeVMBatchAttachmentName ,
247+ Namespace : testNamespace ,
248+ },
249+ }
250+
251+ GetVMFromVcenter = MockGetVMFromVcenter
252+ commonco .ContainerOrchestratorUtility = & unittestcommon.FakeK8SOrchestrator {}
253+
254+ // Override with fake client
255+ newClientFunc = func (ctx context.Context ) (kubernetes.Interface , error ) {
256+ fakeK8sClient := getClientSetWithPvc ()
257+ return fakeK8sClient , nil
258+ }
259+
260+ res , err := r .Reconcile (context .TODO (), req )
261+ if err != nil {
262+ t .Fatal ("Unexpected reconcile error" )
263+ }
264+ expectedReconcileResult := reconcile.Result {}
265+ var expectedReconcileError error
266+
267+ assert .Equal (t , expectedReconcileResult , res )
268+ assert .Equal (t , expectedReconcileError , err )
269+
270+ updatedCnsNodeVMBatchAttachment := & v1alpha1.CnsNodeVMBatchAttachment {}
271+ err = r .client .Get (context .TODO (), req .NamespacedName , updatedCnsNodeVMBatchAttachment )
272+ if err == nil {
273+ t .Fatalf ("failed to get cnsnodevmbatchattachemnt instance" )
274+ }
275+
276+ // Error should be not found
277+ if statusErr , ok := err .(* errors.StatusError ); ok {
278+ assert .Equal (t , metav1 .StatusReasonNotFound , statusErr .Status ().Reason )
279+ } else {
280+ t .Fatalf ("Unable to verify CnsNodeVMBatchAttachment error" )
281+ }
282+ })
283+ }
284+
237285func TestCnsNodeVMBatchAttachmentWhenVmOnVcenterReturnsNotFoundErrorAndInstanceIsNotDeleted (t * testing.T ) {
238286 t .Run ("TestCnsNodeVMBatchAttachmentWhenVmOnVcenterReturnsNotFoundErrorAndInstanceIsNotDeleted" ,
239287 func (t * testing.T ) {
@@ -692,143 +740,6 @@ func TestIsSharedPvc(t *testing.T) {
692740 }
693741}
694742
695- func TestGetUniqueVolumeName (t * testing.T ) {
696- tests := []struct {
697- name string
698- currentName string
699- allVolumeNamesInStatus map [string ]bool
700- expected string
701- }{
702- {
703- name : "No existing volumes — first name available" ,
704- currentName : "vol1" ,
705- allVolumeNamesInStatus : map [string ]bool {},
706- expected : "vol1-1" + detachSuffix ,
707- },
708- {
709- name : "First detaching name already exists — use next index" ,
710- currentName : "vol1" ,
711- allVolumeNamesInStatus : map [string ]bool {
712- "vol1-1:detaching" : true ,
713- },
714- expected : "vol1-2" + detachSuffix ,
715- },
716- {
717- name : "Several existing detaching names — find next available" ,
718- currentName : "vol1" ,
719- allVolumeNamesInStatus : map [string ]bool {
720- "vol1-1:detaching" : true ,
721- "vol1-2:detaching" : true ,
722- "vol1-3:detaching" : true ,
723- },
724- expected : "vol1-4" + detachSuffix ,
725- },
726- {
727- name : "Different volume names in status — should not affect result" ,
728- currentName : "volX" ,
729- allVolumeNamesInStatus : map [string ]bool {
730- "volA-1:detaching" : true ,
731- "volB-2:detaching" : true ,
732- },
733- expected : "volX-1" + detachSuffix ,
734- },
735- {
736- name : "Handles long existing name list gracefully" ,
737- currentName : "vol99" ,
738- allVolumeNamesInStatus : func () map [string ]bool {
739- m := make (map [string ]bool )
740- for i := 1 ; i <= 50 ; i ++ {
741- m ["vol99-" + strconv .Itoa (i )+ ":detaching" ] = true
742- }
743- return m
744- }(),
745- expected : "vol99-51" + detachSuffix ,
746- },
747- }
748-
749- for _ , tc := range tests {
750- t .Run (tc .name , func (t * testing.T ) {
751- got := getUniqueVolumeName (tc .currentName , tc .allVolumeNamesInStatus )
752- if got != tc .expected {
753- t .Errorf ("expected %s, got %s" , tc .expected , got )
754- }
755- })
756- }
757- }
758-
759- func TestGetVolumeNamesInStatus (t * testing.T ) {
760- tests := []struct {
761- name string
762- instance v1alpha1.CnsNodeVMBatchAttachment
763- expected map [string ]bool
764- }{
765- {
766- name : "No volumes in status" ,
767- instance : v1alpha1.CnsNodeVMBatchAttachment {
768- Status : v1alpha1.CnsNodeVMBatchAttachmentStatus {
769- VolumeStatus : []v1alpha1.VolumeStatus {},
770- },
771- },
772- expected : map [string ]bool {},
773- },
774- {
775- name : "Single volume in status" ,
776- instance : v1alpha1.CnsNodeVMBatchAttachment {
777- Status : v1alpha1.CnsNodeVMBatchAttachmentStatus {
778- VolumeStatus : []v1alpha1.VolumeStatus {
779- {Name : "vol1" },
780- },
781- },
782- },
783- expected : map [string ]bool {
784- "vol1" : true ,
785- },
786- },
787- {
788- name : "Multiple unique volumes" ,
789- instance : v1alpha1.CnsNodeVMBatchAttachment {
790- Status : v1alpha1.CnsNodeVMBatchAttachmentStatus {
791- VolumeStatus : []v1alpha1.VolumeStatus {
792- {Name : "vol1" },
793- {Name : "vol2" },
794- {Name : "vol3" },
795- },
796- },
797- },
798- expected : map [string ]bool {
799- "vol1" : true ,
800- "vol2" : true ,
801- "vol3" : true ,
802- },
803- },
804- {
805- name : "Duplicate volume names should not create duplicates in map" ,
806- instance : v1alpha1.CnsNodeVMBatchAttachment {
807- Status : v1alpha1.CnsNodeVMBatchAttachmentStatus {
808- VolumeStatus : []v1alpha1.VolumeStatus {
809- {Name : "vol1" },
810- {Name : "vol1" },
811- {Name : "vol2" },
812- },
813- },
814- },
815- expected : map [string ]bool {
816- "vol1" : true ,
817- "vol2" : true ,
818- },
819- },
820- }
821-
822- for _ , tc := range tests {
823- t .Run (tc .name , func (t * testing.T ) {
824- got := getVolumeNamesInStatus (& tc .instance )
825- if ! reflect .DeepEqual (got , tc .expected ) {
826- t .Errorf ("expected %+v, got %+v" , tc .expected , got )
827- }
828- })
829- }
830- }
831-
832743func MockGetVMFromVcenter (ctx context.Context , nodeUUID string ,
833744 configInfo config.ConfigurationInfo ) (* cnsvsphere.VirtualMachine , error ) {
834745 var vm * cnsvsphere.VirtualMachine
0 commit comments