1717package org .apache .cloudstack .storage .volume ;
1818
1919import static org .junit .Assert .assertFalse ;
20+ import static org .junit .Assert .assertNotNull ;
21+ import static org .junit .Assert .assertNull ;
2022import static org .junit .Assert .assertTrue ;
23+ import static org .junit .Assert .assertEquals ;
2124import static org .mockito .Mockito .when ;
2225
26+ import com .cloud .host .HostVO ;
27+ import com .cloud .host .dao .HostDao ;
2328import com .cloud .storage .ClvmLockManager ;
29+ import com .cloud .vm .VMInstanceVO ;
30+ import com .cloud .vm .dao .VMInstanceDao ;
2431import org .apache .cloudstack .engine .subsystem .api .storage .VolumeInfo ;
32+ import org .apache .cloudstack .engine .subsystem .api .storage .VolumeDataFactory ;
33+ import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
34+ import org .apache .cloudstack .storage .datastore .db .PrimaryDataStoreDao ;
2535import org .junit .Before ;
2636import org .junit .Test ;
2737import org .junit .runner .RunWith ;
@@ -48,27 +58,55 @@ public class VolumeServiceImplClvmTest {
4858 @ Mock
4959 private VolumeDao volumeDao ;
5060
61+ @ Mock
62+ private PrimaryDataStoreDao storagePoolDao ;
63+
64+ @ Mock
65+ private HostDao _hostDao ;
66+
67+ @ Mock
68+ private VMInstanceDao vmDao ;
69+
70+ @ Mock
71+ private VolumeDataFactory volFactory ;
72+
5173 @ Mock
5274 private VolumeInfo volumeInfoMock ;
5375
5476 @ Mock
5577 private VolumeVO volumeVOMock ;
5678
5779 @ Mock
58- ClvmLockManager clvmLockManager ;
80+ private StoragePoolVO storagePoolVOMock ;
81+
82+ @ Mock
83+ private HostVO hostVOMock ;
84+
85+ @ Mock
86+ private VMInstanceVO vmInstanceVOMock ;
87+
88+ @ Mock
89+ private ClvmLockManager clvmLockManager ;
5990
6091 private static final Long VOLUME_ID = 1L ;
6192 private static final Long POOL_ID_1 = 100L ;
6293 private static final Long POOL_ID_2 = 200L ;
6394 private static final Long HOST_ID_1 = 10L ;
6495 private static final Long HOST_ID_2 = 20L ;
6596 private static final String POOL_PATH_VG1 = "/vg1" ;
66- private static final String POOL_PATH_VG2 = "/vg2" ;
6797
6898 @ Before
6999 public void setup () {
70100 when (volumeInfoMock .getId ()).thenReturn (VOLUME_ID );
71101 when (volumeInfoMock .getUuid ()).thenReturn ("test-volume-uuid" );
102+
103+ // Setup volumeService dependencies
104+ volumeService .storagePoolDao = storagePoolDao ;
105+ volumeService ._hostDao = _hostDao ;
106+ volumeService .vmDao = vmDao ;
107+ volumeService .volFactory = volFactory ;
108+ volumeService ._volumeDao = volumeDao ;
109+ volumeService .clvmLockManager = clvmLockManager ;
72110 }
73111
74112 @ Test
@@ -308,4 +346,157 @@ public void testIsLightweightMigrationNeeded_ComplexVGNames() {
308346 StoragePoolType .CLVM , StoragePoolType .CLVM ,
309347 "/cloudstack-vg-01" , "/cloudstack-vg-02" ));
310348 }
349+
350+ @ Test
351+ public void testTransferVolumeLock_Success () {
352+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
353+ when (volumeInfoMock .getId ()).thenReturn (VOLUME_ID );
354+ when (volumeInfoMock .getPath ()).thenReturn ("/dev/vg1/volume-1" );
355+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
356+ when (storagePoolVOMock .getName ()).thenReturn ("test-pool" );
357+ when (clvmLockManager .transferClvmVolumeLock (
358+ "test-volume-uuid" , VOLUME_ID , "/dev/vg1/volume-1" , storagePoolVOMock , HOST_ID_1 , HOST_ID_2 ))
359+ .thenReturn (true );
360+
361+ assertTrue (volumeService .transferVolumeLock (volumeInfoMock , HOST_ID_1 , HOST_ID_2 ));
362+ }
363+
364+ @ Test
365+ public void testTransferVolumeLock_Failure () {
366+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
367+ when (volumeInfoMock .getId ()).thenReturn (VOLUME_ID );
368+ when (volumeInfoMock .getPath ()).thenReturn ("/dev/vg1/volume-1" );
369+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
370+ when (storagePoolVOMock .getName ()).thenReturn ("test-pool" );
371+ when (clvmLockManager .transferClvmVolumeLock (
372+ "test-volume-uuid" , VOLUME_ID , "/dev/vg1/volume-1" , storagePoolVOMock , HOST_ID_1 , HOST_ID_2 ))
373+ .thenReturn (false );
374+
375+ assertFalse (volumeService .transferVolumeLock (volumeInfoMock , HOST_ID_1 , HOST_ID_2 ));
376+ }
377+
378+ @ Test
379+ public void testTransferVolumeLock_PoolNotFound () {
380+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
381+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (null );
382+
383+ assertFalse (volumeService .transferVolumeLock (volumeInfoMock , HOST_ID_1 , HOST_ID_2 ));
384+ }
385+
386+ @ Test
387+ public void testFindVolumeLockHost_NullVolume () {
388+ Long result = volumeService .findVolumeLockHost (null );
389+ assertNull (result );
390+ }
391+
392+ @ Test
393+ public void testFindVolumeLockHost_ExplicitLockFound () {
394+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" ))
395+ .thenReturn (HOST_ID_1 );
396+
397+ Long result = volumeService .findVolumeLockHost (volumeInfoMock );
398+ assertEquals (HOST_ID_1 , result );
399+ }
400+
401+ @ Test
402+ public void testFindVolumeLockHost_FromAttachedVM () {
403+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" ))
404+ .thenReturn (null );
405+ when (volumeInfoMock .getInstanceId ()).thenReturn (100L );
406+ when (vmDao .findById (100L )).thenReturn (vmInstanceVOMock );
407+ when (vmInstanceVOMock .getUuid ()).thenReturn ("vm-uuid" );
408+ when (vmInstanceVOMock .getHostId ()).thenReturn (HOST_ID_1 );
409+
410+ Long result = volumeService .findVolumeLockHost (volumeInfoMock );
411+ assertEquals (HOST_ID_1 , result );
412+ }
413+
414+ @ Test
415+ public void testFindVolumeLockHost_FallbackToClusterHost () {
416+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" ))
417+ .thenReturn (null );
418+ when (volumeInfoMock .getInstanceId ()).thenReturn (null );
419+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
420+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
421+ when (storagePoolVOMock .getClusterId ()).thenReturn (10L );
422+ when (hostVOMock .getId ()).thenReturn (HOST_ID_1 );
423+ when (hostVOMock .getStatus ()).thenReturn (com .cloud .host .Status .Up );
424+ when (_hostDao .findByClusterId (10L )).thenReturn (java .util .Collections .singletonList (hostVOMock ));
425+
426+ Long result = volumeService .findVolumeLockHost (volumeInfoMock );
427+ assertEquals (HOST_ID_1 , result );
428+ }
429+
430+ @ Test
431+ public void testFindVolumeLockHost_NoHostFound () {
432+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" ))
433+ .thenReturn (null );
434+ when (volumeInfoMock .getInstanceId ()).thenReturn (null );
435+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
436+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
437+ when (storagePoolVOMock .getClusterId ()).thenReturn (10L );
438+ when (_hostDao .findByClusterId (10L )).thenReturn (java .util .Collections .emptyList ());
439+
440+ Long result = volumeService .findVolumeLockHost (volumeInfoMock );
441+ assertNull (result );
442+ }
443+
444+ @ Test
445+ public void testPerformLockMigration_Success () {
446+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
447+ when (volumeInfoMock .getId ()).thenReturn (VOLUME_ID );
448+ when (volumeInfoMock .getPath ()).thenReturn ("/dev/vg1/volume-1" );
449+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" )).thenReturn (HOST_ID_1 );
450+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
451+ when (storagePoolVOMock .getName ()).thenReturn ("test-pool" );
452+ when (clvmLockManager .transferClvmVolumeLock (
453+ "test-volume-uuid" , VOLUME_ID , "/dev/vg1/volume-1" , storagePoolVOMock , HOST_ID_1 , HOST_ID_2 ))
454+ .thenReturn (true );
455+ when (volFactory .getVolume (VOLUME_ID )).thenReturn (volumeInfoMock );
456+
457+ VolumeInfo result = volumeService .performLockMigration (volumeInfoMock , HOST_ID_2 );
458+ assertNotNull (result );
459+ }
460+
461+ @ Test
462+ public void testPerformLockMigration_SameHost () {
463+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" )).thenReturn (HOST_ID_1 );
464+
465+ VolumeInfo result = volumeService .performLockMigration (volumeInfoMock , HOST_ID_1 );
466+ assertEquals (volumeInfoMock , result );
467+ }
468+
469+ @ Test
470+ public void testPerformLockMigration_SourceHostNull () {
471+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
472+ when (volumeInfoMock .getId ()).thenReturn (VOLUME_ID );
473+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" )).thenReturn (null );
474+ when (volumeInfoMock .getInstanceId ()).thenReturn (null );
475+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
476+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
477+ when (storagePoolVOMock .getClusterId ()).thenReturn (null );
478+
479+ VolumeInfo result = volumeService .performLockMigration (volumeInfoMock , HOST_ID_2 );
480+ assertNotNull (result );
481+ }
482+
483+ @ Test (expected = com .cloud .utils .exception .CloudRuntimeException .class )
484+ public void testPerformLockMigration_NullVolume () {
485+ volumeService .performLockMigration (null , HOST_ID_2 );
486+ }
487+
488+ @ Test (expected = com .cloud .utils .exception .CloudRuntimeException .class )
489+ public void testPerformLockMigration_TransferFails () {
490+ when (volumeInfoMock .getPoolId ()).thenReturn (POOL_ID_1 );
491+ when (volumeInfoMock .getId ()).thenReturn (VOLUME_ID );
492+ when (volumeInfoMock .getPath ()).thenReturn ("/dev/vg1/volume-1" );
493+ when (clvmLockManager .getClvmLockHostId (VOLUME_ID , "test-volume-uuid" )).thenReturn (HOST_ID_1 );
494+ when (storagePoolDao .findById (POOL_ID_1 )).thenReturn (storagePoolVOMock );
495+ when (storagePoolVOMock .getName ()).thenReturn ("test-pool" );
496+ when (clvmLockManager .transferClvmVolumeLock (
497+ "test-volume-uuid" , VOLUME_ID , "/dev/vg1/volume-1" , storagePoolVOMock , HOST_ID_1 , HOST_ID_2 ))
498+ .thenReturn (false );
499+
500+ volumeService .performLockMigration (volumeInfoMock , HOST_ID_2 );
501+ }
311502}
0 commit comments