2222import java .util .List ;
2323import java .util .UUID ;
2424
25+ import org .apache .cloudstack .engine .subsystem .api .storage .StrategyPriority ;
2526import org .apache .cloudstack .storage .datastore .db .PrimaryDataStoreDao ;
2627import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
2728import org .apache .cloudstack .storage .to .VolumeObjectTO ;
3940import com .cloud .storage .Volume ;
4041import com .cloud .storage .VolumeVO ;
4142import com .cloud .storage .dao .VolumeDao ;
43+ import com .cloud .vm .UserVmVO ;
44+ import com .cloud .vm .VirtualMachine .State ;
45+ import com .cloud .vm .dao .UserVmDao ;
46+ import com .cloud .vm .snapshot .VMSnapshot ;
4247
4348@ RunWith (MockitoJUnitRunner .class )
4449public class DefaultVMSnapshotStrategyTest {
4550 @ Mock
4651 VolumeDao volumeDao ;
4752 @ Mock
4853 PrimaryDataStoreDao primaryDataStoreDao ;
54+ @ Mock
55+ UserVmDao userVmDao ;
4956
5057 @ Spy
5158 @ InjectMocks
@@ -85,7 +92,7 @@ public void testUpdateVolumePath() {
8592 Mockito .when (vol2 .getChainInfo ()).thenReturn (newVolChain );
8693 Mockito .when (vol2 .getSize ()).thenReturn (vmSnapshotChainSize );
8794 Mockito .when (vol2 .getId ()).thenReturn (volumeId );
88- VolumeVO volumeVO = new VolumeVO ("name" , 0l , 0l , 0l , 0l , 0l , "folder" , "path" , Storage .ProvisioningType .THIN , 0l , Volume .Type .ROOT );
95+ VolumeVO volumeVO = new VolumeVO ("name" , 0L , 0L , 0L , 0L , 0L , "folder" , "path" , Storage .ProvisioningType .THIN , 0L , Volume .Type .ROOT );
8996 volumeVO .setPoolId (oldPoolId );
9097 volumeVO .setChainInfo (oldVolChain );
9198 volumeVO .setPath (oldVolPath );
@@ -103,4 +110,110 @@ public void testUpdateVolumePath() {
103110 Assert .assertEquals (vmSnapshotChainSize , persistedVolume .getVmSnapshotChainSize ());
104111 Assert .assertEquals (newVolChain , persistedVolume .getChainInfo ());
105112 }
113+
114+ @ Test
115+ public void testCanHandleRunningVMOnClvmStorageCantHandle () {
116+ Long vmId = 1L ;
117+ VMSnapshot vmSnapshot = Mockito .mock (VMSnapshot .class );
118+ Mockito .when (vmSnapshot .getVmId ()).thenReturn (vmId );
119+
120+ UserVmVO vm = Mockito .mock (UserVmVO .class );
121+ Mockito .when (vm .getId ()).thenReturn (vmId );
122+ Mockito .when (vm .getState ()).thenReturn (State .Running );
123+ Mockito .when (userVmDao .findById (vmId )).thenReturn (vm );
124+
125+ VolumeVO volumeOnClvm = createVolume (vmId , 1L );
126+ List <VolumeVO > volumes = List .of (volumeOnClvm );
127+ Mockito .when (volumeDao .findByInstance (vmId )).thenReturn (volumes );
128+
129+ StoragePoolVO clvmPool = createStoragePool ("clvm-pool" , Storage .StoragePoolType .CLVM );
130+ Mockito .when (primaryDataStoreDao .findById (1L )).thenReturn (clvmPool );
131+
132+ StrategyPriority result = defaultVMSnapshotStrategy .canHandle (vmSnapshot );
133+
134+ Assert .assertEquals ("Should return CANT_HANDLE for running VM on CLVM storage" ,
135+ StrategyPriority .CANT_HANDLE , result );
136+ }
137+
138+ @ Test
139+ public void testCanHandleStoppedVMOnClvmStorageCanHandle () {
140+ Long vmId = 1L ;
141+ VMSnapshot vmSnapshot = Mockito .mock (VMSnapshot .class );
142+ Mockito .when (vmSnapshot .getVmId ()).thenReturn (vmId );
143+
144+ UserVmVO vm = Mockito .mock (UserVmVO .class );
145+ Mockito .when (vm .getId ()).thenReturn (vmId );
146+ Mockito .when (vm .getState ()).thenReturn (State .Stopped );
147+ Mockito .when (userVmDao .findById (vmId )).thenReturn (vm );
148+
149+ StrategyPriority result = defaultVMSnapshotStrategy .canHandle (vmSnapshot );
150+ Assert .assertEquals ("Should return DEFAULT for stopped VM on CLVM storage" ,
151+ StrategyPriority .DEFAULT , result );
152+ }
153+
154+ @ Test
155+ public void testCanHandleRunningVMOnNfsStorageCanHandle () {
156+ Long vmId = 1L ;
157+ VMSnapshot vmSnapshot = Mockito .mock (VMSnapshot .class );
158+ Mockito .when (vmSnapshot .getVmId ()).thenReturn (vmId );
159+
160+ UserVmVO vm = Mockito .mock (UserVmVO .class );
161+ Mockito .when (vm .getId ()).thenReturn (vmId );
162+ Mockito .when (vm .getState ()).thenReturn (State .Running );
163+ Mockito .when (userVmDao .findById (vmId )).thenReturn (vm );
164+
165+ VolumeVO volumeOnNfs = createVolume (vmId , 1L );
166+ List <VolumeVO > volumes = List .of (volumeOnNfs );
167+ Mockito .when (volumeDao .findByInstance (vmId )).thenReturn (volumes );
168+
169+ StoragePoolVO nfsPool = createStoragePool ("nfs-pool" , Storage .StoragePoolType .NetworkFilesystem );
170+ Mockito .when (primaryDataStoreDao .findById (1L )).thenReturn (nfsPool );
171+
172+ StrategyPriority result = defaultVMSnapshotStrategy .canHandle (vmSnapshot );
173+
174+ Assert .assertEquals ("Should return DEFAULT for running VM on NFS storage" ,
175+ StrategyPriority .DEFAULT , result );
176+ }
177+
178+ @ Test
179+ public void testCanHandleRunningVMWithMixedStorageClvmAndNfsCantHandle () {
180+ // Arrange - VM has volumes on both CLVM and NFS
181+ Long vmId = 1L ;
182+ VMSnapshot vmSnapshot = Mockito .mock (VMSnapshot .class );
183+ Mockito .when (vmSnapshot .getVmId ()).thenReturn (vmId );
184+
185+ UserVmVO vm = Mockito .mock (UserVmVO .class );
186+ Mockito .when (vm .getId ()).thenReturn (vmId );
187+ Mockito .when (vm .getState ()).thenReturn (State .Running );
188+ Mockito .when (userVmDao .findById (vmId )).thenReturn (vm );
189+
190+ VolumeVO volumeOnClvm = createVolume (vmId , 1L );
191+ VolumeVO volumeOnNfs = createVolume (vmId , 2L );
192+ List <VolumeVO > volumes = List .of (volumeOnClvm , volumeOnNfs );
193+ Mockito .when (volumeDao .findByInstance (vmId )).thenReturn (volumes );
194+
195+ StoragePoolVO clvmPool = createStoragePool ("clvm-pool" , Storage .StoragePoolType .CLVM );
196+ StoragePoolVO nfsPool = createStoragePool ("nfs-pool" , Storage .StoragePoolType .NetworkFilesystem );
197+ Mockito .when (primaryDataStoreDao .findById (1L )).thenReturn (clvmPool );
198+
199+ StrategyPriority result = defaultVMSnapshotStrategy .canHandle (vmSnapshot );
200+
201+ Assert .assertEquals ("Should return CANT_HANDLE if any volume is on CLVM storage for running VM" ,
202+ StrategyPriority .CANT_HANDLE , result );
203+ }
204+
205+ private VolumeVO createVolume (Long vmId , Long poolId ) {
206+ VolumeVO volume = new VolumeVO ("volume" , 0L , 0L , 0L , 0L , 0L ,
207+ "folder" , "path" , Storage .ProvisioningType .THIN , 0L , Volume .Type .ROOT );
208+ volume .setInstanceId (vmId );
209+ volume .setPoolId (poolId );
210+ return volume ;
211+ }
212+
213+ private StoragePoolVO createStoragePool (String name , Storage .StoragePoolType poolType ) {
214+ StoragePoolVO pool = Mockito .mock (StoragePoolVO .class );
215+ Mockito .when (pool .getName ()).thenReturn (name );
216+ Mockito .when (pool .getPoolType ()).thenReturn (poolType );
217+ return pool ;
218+ }
106219}
0 commit comments