@@ -508,6 +508,133 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
508508 Expect (err ).NotTo (HaveOccurred ())
509509 cl .UnregisterVolume (name )
510510 })
511+
512+ It ("should create volume from an existing source snapshot" , func () {
513+ if ! isControllerCapabilitySupported (c , csi .ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT ) {
514+ Skip ("Snapshot not supported" )
515+ }
516+
517+ By ("creating a volume" )
518+ vol1Name := uniqueString ("sanity-controller-source-vol" )
519+ vol1Req := MakeCreateVolumeReq (sc , vol1Name )
520+ volume1 , err := c .CreateVolume (context .Background (), vol1Req )
521+ Expect (err ).NotTo (HaveOccurred ())
522+
523+ By ("creating a snapshot" )
524+ snapName := uniqueString ("sanity-controller-snap-from-vol" )
525+ snapReq := MakeCreateSnapshotReq (sc , snapName , volume1 .GetVolume ().GetVolumeId (), nil )
526+ snap , err := c .CreateSnapshot (context .Background (), snapReq )
527+ Expect (err ).NotTo (HaveOccurred ())
528+ Expect (snap ).NotTo (BeNil ())
529+ verifySnapshotInfo (snap .GetSnapshot ())
530+
531+ By ("creating a volume from source snapshot" )
532+ vol2Name := uniqueString ("sanity-controller-vol-from-snap" )
533+ vol2Req := MakeCreateVolumeReq (sc , vol2Name )
534+ vol2Req .VolumeContentSource = & csi.VolumeContentSource {
535+ Type : & csi.VolumeContentSource_Snapshot {
536+ Snapshot : & csi.VolumeContentSource_SnapshotSource {
537+ SnapshotId : snap .GetSnapshot ().GetSnapshotId (),
538+ },
539+ },
540+ }
541+ volume2 , err := c .CreateVolume (context .Background (), vol2Req )
542+ Expect (err ).NotTo (HaveOccurred ())
543+
544+ By ("cleaning up deleting the volume created from snapshot" )
545+ delVol2Req := MakeDeleteVolumeReq (sc , volume2 .GetVolume ().GetVolumeId ())
546+ _ , err = c .DeleteVolume (context .Background (), delVol2Req )
547+ Expect (err ).NotTo (HaveOccurred ())
548+
549+ By ("cleaning up deleting the snapshot" )
550+ delSnapReq := MakeDeleteSnapshotReq (sc , snap .GetSnapshot ().GetSnapshotId ())
551+ _ , err = c .DeleteSnapshot (context .Background (), delSnapReq )
552+ Expect (err ).NotTo (HaveOccurred ())
553+
554+ By ("cleaning up deleting the source volume" )
555+ delVol1Req := MakeDeleteVolumeReq (sc , volume1 .GetVolume ().GetVolumeId ())
556+ _ , err = c .DeleteVolume (context .Background (), delVol1Req )
557+ Expect (err ).NotTo (HaveOccurred ())
558+ })
559+
560+ It ("should fail when the volume source snapshot is not found" , func () {
561+ if ! isControllerCapabilitySupported (c , csi .ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT ) {
562+ Skip ("Snapshot not supported" )
563+ }
564+
565+ By ("creating a volume from source snapshot" )
566+ volName := uniqueString ("sanity-controller-vol-from-snap" )
567+ volReq := MakeCreateVolumeReq (sc , volName )
568+ volReq .VolumeContentSource = & csi.VolumeContentSource {
569+ Type : & csi.VolumeContentSource_Snapshot {
570+ Snapshot : & csi.VolumeContentSource_SnapshotSource {
571+ SnapshotId : "non-existing-snapshot-id" ,
572+ },
573+ },
574+ }
575+ _ , err := c .CreateVolume (context .Background (), volReq )
576+ Expect (err ).To (HaveOccurred ())
577+ serverError , ok := status .FromError (err )
578+ Expect (ok ).To (BeTrue ())
579+ Expect (serverError .Code ()).To (Equal (codes .NotFound ))
580+ })
581+
582+ It ("should create volume from an existing source volume" , func () {
583+ if ! isControllerCapabilitySupported (c , csi .ControllerServiceCapability_RPC_CLONE_VOLUME ) {
584+ Skip ("Volume Cloning not supported" )
585+ }
586+
587+ By ("creating a volume" )
588+ vol1Name := uniqueString ("sanity-controller-source-vol" )
589+ vol1Req := MakeCreateVolumeReq (sc , vol1Name )
590+ volume1 , err := c .CreateVolume (context .Background (), vol1Req )
591+ Expect (err ).NotTo (HaveOccurred ())
592+
593+ By ("creating a volume from source volume" )
594+ vol2Name := uniqueString ("sanity-controller-vol-from-vol" )
595+ vol2Req := MakeCreateVolumeReq (sc , vol2Name )
596+ vol2Req .VolumeContentSource = & csi.VolumeContentSource {
597+ Type : & csi.VolumeContentSource_Volume {
598+ Volume : & csi.VolumeContentSource_VolumeSource {
599+ VolumeId : volume1 .GetVolume ().GetVolumeId (),
600+ },
601+ },
602+ }
603+ volume2 , err := c .CreateVolume (context .Background (), vol2Req )
604+ Expect (err ).NotTo (HaveOccurred ())
605+
606+ By ("cleaning up deleting the volume created from source volume" )
607+ delVol2Req := MakeDeleteVolumeReq (sc , volume2 .GetVolume ().GetVolumeId ())
608+ _ , err = c .DeleteVolume (context .Background (), delVol2Req )
609+ Expect (err ).NotTo (HaveOccurred ())
610+
611+ By ("cleaning up deleting the source volume" )
612+ delVol1Req := MakeDeleteVolumeReq (sc , volume1 .GetVolume ().GetVolumeId ())
613+ _ , err = c .DeleteVolume (context .Background (), delVol1Req )
614+ Expect (err ).NotTo (HaveOccurred ())
615+ })
616+
617+ It ("should fail when the volume source volume is not found" , func () {
618+ if ! isControllerCapabilitySupported (c , csi .ControllerServiceCapability_RPC_CLONE_VOLUME ) {
619+ Skip ("Volume Cloning not supported" )
620+ }
621+
622+ By ("creating a volume from source snapshot" )
623+ volName := uniqueString ("sanity-controller-vol-from-snap" )
624+ volReq := MakeCreateVolumeReq (sc , volName )
625+ volReq .VolumeContentSource = & csi.VolumeContentSource {
626+ Type : & csi.VolumeContentSource_Volume {
627+ Volume : & csi.VolumeContentSource_VolumeSource {
628+ VolumeId : "non-existing-volume-id" ,
629+ },
630+ },
631+ }
632+ _ , err := c .CreateVolume (context .Background (), volReq )
633+ Expect (err ).To (HaveOccurred ())
634+ serverError , ok := status .FromError (err )
635+ Expect (ok ).To (BeTrue ())
636+ Expect (serverError .Code ()).To (Equal (codes .NotFound ))
637+ })
511638 })
512639
513640 Describe ("DeleteVolume" , func () {
0 commit comments