@@ -22,8 +22,11 @@ import (
2222
2323 . "github.com/onsi/ginkgo/v2"
2424 . "github.com/onsi/gomega"
25+ storagev1 "k8s.io/api/storage/v1"
2526 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+ "k8s.io/apimachinery/pkg/runtime"
2628 "sigs.k8s.io/controller-runtime/pkg/client"
29+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
2730 "sigs.k8s.io/controller-runtime/pkg/reconcile"
2831
2932 "github.com/deckhouse/virtualization-controller/pkg/common/testutil"
@@ -289,6 +292,126 @@ var _ = Describe("LifeCycleHandler Run", func() {
289292 vdcondition .DatasourceIsNotFound .String (),
290293 ),
291294 )
295+
296+ It ("should handle a VirtualDisk without data source" , func () {
297+ var sourcesMock SourcesMock
298+ recorder := & eventrecord.EventRecorderLoggerMock {
299+ EventFunc : func (_ client.Object , _ , _ , _ string ) {},
300+ }
301+ ctx := logger .ToContext (context .TODO (), testutil .NewNoOpSlogLogger ())
302+ syncCalled := false
303+ blank := & source.HandlerMock {
304+ SyncFunc : func (_ context.Context , _ * v1alpha2.VirtualDisk ) (reconcile.Result , error ) {
305+ syncCalled = true
306+ return reconcile.Result {}, nil
307+ },
308+ }
309+ vd := v1alpha2.VirtualDisk {
310+ Status : v1alpha2.VirtualDiskStatus {
311+ StorageClassName : "vd-sc" ,
312+ Conditions : []metav1.Condition {
313+ {
314+ Type : vdcondition .DatasourceReadyType .String (),
315+ Status : metav1 .ConditionTrue ,
316+ },
317+ {
318+ Type : vdcondition .StorageClassReadyType .String (),
319+ Status : metav1 .ConditionTrue ,
320+ },
321+ },
322+ },
323+ }
324+
325+ sourcesMock .ChangedFunc = func (_ context.Context , _ * v1alpha2.VirtualDisk ) bool {
326+ return false
327+ }
328+ handler := NewLifeCycleHandler (recorder , blank , & sourcesMock , nil )
329+
330+ Expect (func () {
331+ _ , _ = handler .Handle (ctx , & vd )
332+ }).NotTo (Panic ())
333+ Expect (syncCalled ).To (BeTrue ())
334+ })
335+
336+ It ("should set a dedicated reason when storage class does not match the source virtual image" , func () {
337+ scheme := runtime .NewScheme ()
338+ Expect (v1alpha2 .AddToScheme (scheme )).To (Succeed ())
339+ Expect (storagev1 .AddToScheme (scheme )).To (Succeed ())
340+
341+ vi := & v1alpha2.VirtualImage {
342+ ObjectMeta : metav1.ObjectMeta {
343+ Name : "source-vi" ,
344+ Namespace : "default" ,
345+ },
346+ Spec : v1alpha2.VirtualImageSpec {
347+ Storage : v1alpha2 .StoragePersistentVolumeClaim ,
348+ },
349+ Status : v1alpha2.VirtualImageStatus {
350+ Phase : v1alpha2 .ImageReady ,
351+ StorageClassName : "vi-sc" ,
352+ },
353+ }
354+
355+ vdSC := & storagev1.StorageClass {
356+ ObjectMeta : metav1.ObjectMeta {
357+ Name : "vd-sc" ,
358+ },
359+ Provisioner : "first.csi.example.com" ,
360+ }
361+
362+ viSC := & storagev1.StorageClass {
363+ ObjectMeta : metav1.ObjectMeta {
364+ Name : "vi-sc" ,
365+ },
366+ Provisioner : "second.csi.example.com" ,
367+ }
368+
369+ k8sClient := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (vi , vdSC , viSC ).Build ()
370+ var sourcesMock SourcesMock
371+ sourcesMock .ChangedFunc = func (_ context.Context , _ * v1alpha2.VirtualDisk ) bool {
372+ return false
373+ }
374+ recorder := & eventrecord.EventRecorderLoggerMock {
375+ EventFunc : func (_ client.Object , _ , _ , _ string ) {},
376+ }
377+ ctx := logger .ToContext (context .TODO (), testutil .NewNoOpSlogLogger ())
378+ vd := v1alpha2.VirtualDisk {
379+ ObjectMeta : metav1.ObjectMeta {
380+ Namespace : "default" ,
381+ },
382+ Spec : v1alpha2.VirtualDiskSpec {
383+ DataSource : & v1alpha2.VirtualDiskDataSource {
384+ Type : v1alpha2 .DataSourceTypeObjectRef ,
385+ ObjectRef : & v1alpha2.VirtualDiskObjectRef {
386+ Kind : v1alpha2 .VirtualDiskObjectRefKindVirtualImage ,
387+ Name : vi .Name ,
388+ },
389+ },
390+ },
391+ Status : v1alpha2.VirtualDiskStatus {
392+ StorageClassName : "vd-sc" ,
393+ Conditions : []metav1.Condition {
394+ {
395+ Type : vdcondition .DatasourceReadyType .String (),
396+ Status : metav1 .ConditionTrue ,
397+ },
398+ {
399+ Type : vdcondition .StorageClassReadyType .String (),
400+ Status : metav1 .ConditionTrue ,
401+ },
402+ },
403+ },
404+ }
405+
406+ handler := NewLifeCycleHandler (recorder , & source.HandlerMock {}, & sourcesMock , k8sClient )
407+ _ , err := handler .Handle (ctx , & vd )
408+ Expect (err ).NotTo (HaveOccurred ())
409+
410+ readyCond , ok := conditions .GetCondition (vdcondition .ReadyType , vd .Status .Conditions )
411+ Expect (ok ).To (BeTrue ())
412+ Expect (readyCond .Reason ).To (Equal (vdcondition .StorageClassProvisionerMismatch .String ()))
413+ Expect (readyCond .Message ).To (Equal (`Virtual disk storage class "vd-sc" provisioner does not match virtual image storage class "vi-sc" provisioner: source type with different provisioners is not supported yet` ))
414+ })
292415})
293416
294417type cleanupAfterSpecChangeTestArgs struct {
0 commit comments