add more tests

This commit is contained in:
Pearl Dsilva 2026-03-30 21:07:13 -04:00
parent e45a43db29
commit 381dc67ef0
5 changed files with 1852 additions and 7 deletions

View File

@ -369,4 +369,286 @@ public class StorageSystemDataMotionStrategyTest {
assertFalse(strategy.isStoragePoolTypeInList(StoragePoolType.SharedMountPoint, listTypes));
}
/**
* Test updateMigrateDiskInfoForBlockDevice with CLVM destination pool
* Should set driver type to RAW for CLVM
*/
@Test
public void testUpdateMigrateDiskInfoForBlockDevice_ClvmDestination() {
MigrateCommand.MigrateDiskInfo originalDiskInfo = new MigrateCommand.MigrateDiskInfo(
"serial123",
MigrateCommand.MigrateDiskInfo.DiskType.FILE,
MigrateCommand.MigrateDiskInfo.DriverType.QCOW2,
MigrateCommand.MigrateDiskInfo.Source.FILE,
"/source/path",
null
);
StoragePoolVO destStoragePool = new StoragePoolVO();
destStoragePool.setPoolType(StoragePoolType.CLVM);
MigrateCommand.MigrateDiskInfo updatedDiskInfo = strategy.updateMigrateDiskInfoForBlockDevice(
originalDiskInfo, destStoragePool);
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.BLOCK, updatedDiskInfo.getDiskType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.RAW, updatedDiskInfo.getDriverType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.DEV, updatedDiskInfo.getSource());
Assert.assertEquals("serial123", updatedDiskInfo.getSerialNumber());
Assert.assertEquals("/source/path", updatedDiskInfo.getSourceText());
}
/**
* Test updateMigrateDiskInfoForBlockDevice with CLVM_NG destination pool
* Should set driver type to QCOW2 for CLVM_NG
*/
@Test
public void testUpdateMigrateDiskInfoForBlockDevice_ClvmNgDestination() {
MigrateCommand.MigrateDiskInfo originalDiskInfo = new MigrateCommand.MigrateDiskInfo(
"serial456",
MigrateCommand.MigrateDiskInfo.DiskType.FILE,
MigrateCommand.MigrateDiskInfo.DriverType.RAW,
MigrateCommand.MigrateDiskInfo.Source.FILE,
"/source/path",
"/backing/path"
);
StoragePoolVO destStoragePool = new StoragePoolVO();
destStoragePool.setPoolType(StoragePoolType.CLVM_NG);
MigrateCommand.MigrateDiskInfo updatedDiskInfo = strategy.updateMigrateDiskInfoForBlockDevice(
originalDiskInfo, destStoragePool);
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.BLOCK, updatedDiskInfo.getDiskType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.QCOW2, updatedDiskInfo.getDriverType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.DEV, updatedDiskInfo.getSource());
Assert.assertEquals("serial456", updatedDiskInfo.getSerialNumber());
Assert.assertEquals("/source/path", updatedDiskInfo.getSourceText());
Assert.assertEquals("/backing/path", updatedDiskInfo.getBackingStoreText());
}
/**
* Test updateMigrateDiskInfoForBlockDevice with non-CLVM destination pool
* Should return original DiskInfo unchanged
*/
@Test
public void testUpdateMigrateDiskInfoForBlockDevice_NonClvmDestination() {
MigrateCommand.MigrateDiskInfo originalDiskInfo = new MigrateCommand.MigrateDiskInfo(
"serial789",
MigrateCommand.MigrateDiskInfo.DiskType.FILE,
MigrateCommand.MigrateDiskInfo.DriverType.QCOW2,
MigrateCommand.MigrateDiskInfo.Source.FILE,
"/source/path",
null
);
StoragePoolVO destStoragePool = new StoragePoolVO();
destStoragePool.setPoolType(StoragePoolType.NetworkFilesystem);
MigrateCommand.MigrateDiskInfo updatedDiskInfo = strategy.updateMigrateDiskInfoForBlockDevice(
originalDiskInfo, destStoragePool);
Assert.assertSame(originalDiskInfo, updatedDiskInfo);
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.FILE, updatedDiskInfo.getDiskType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.QCOW2, updatedDiskInfo.getDriverType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.FILE, updatedDiskInfo.getSource());
}
/**
* Test supportStoragePoolType with CLVM and CLVM_NG types
*/
@Test
public void testSupportStoragePoolType_ClvmTypes() {
assertTrue(strategy.supportStoragePoolType(StoragePoolType.CLVM, StoragePoolType.CLVM, StoragePoolType.CLVM_NG));
assertTrue(strategy.supportStoragePoolType(StoragePoolType.CLVM_NG, StoragePoolType.CLVM, StoragePoolType.CLVM_NG));
assertFalse(strategy.supportStoragePoolType(StoragePoolType.CLVM));
assertFalse(strategy.supportStoragePoolType(StoragePoolType.CLVM_NG));
}
/**
* Test configureMigrateDiskInfo with CLVM destination
*/
@Test
public void testConfigureMigrateDiskInfo_ForClvm() {
VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject());
Mockito.doReturn("/dev/vg/volume-path").when(srcVolumeInfo).getPath();
MigrateCommand.MigrateDiskInfo migrateDiskInfo = strategy.configureMigrateDiskInfo(
srcVolumeInfo, "/dev/vg/dest-path", null);
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.BLOCK, migrateDiskInfo.getDiskType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.RAW, migrateDiskInfo.getDriverType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.DEV, migrateDiskInfo.getSource());
Assert.assertEquals("/dev/vg/dest-path", migrateDiskInfo.getSourceText());
Assert.assertEquals("/dev/vg/volume-path", migrateDiskInfo.getSerialNumber());
}
/**
* Test configureMigrateDiskInfo with CLVM_NG destination and backing file
*/
@Test
public void testConfigureMigrateDiskInfo_ForClvmNgWithBacking() {
VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject());
Mockito.doReturn("/dev/vg/volume-path").when(srcVolumeInfo).getPath();
MigrateCommand.MigrateDiskInfo migrateDiskInfo = strategy.configureMigrateDiskInfo(
srcVolumeInfo, "/dev/vg/dest-path", "/dev/vg/backing-template");
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.BLOCK, migrateDiskInfo.getDiskType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.RAW, migrateDiskInfo.getDriverType());
Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.DEV, migrateDiskInfo.getSource());
Assert.assertEquals("/dev/vg/dest-path", migrateDiskInfo.getSourceText());
Assert.assertEquals("/dev/vg/backing-template", migrateDiskInfo.getBackingStoreText());
Assert.assertEquals("/dev/vg/volume-path", migrateDiskInfo.getSerialNumber());
}
/**
* Test isStoragePoolTypeInList with CLVM types
*/
@Test
public void testIsStoragePoolTypeInList_WithClvmTypes() {
StoragePoolType[] clvmTypes = new StoragePoolType[] {
StoragePoolType.CLVM,
StoragePoolType.CLVM_NG,
StoragePoolType.Filesystem
};
assertTrue(strategy.isStoragePoolTypeInList(StoragePoolType.CLVM, clvmTypes));
assertTrue(strategy.isStoragePoolTypeInList(StoragePoolType.CLVM_NG, clvmTypes));
assertTrue(strategy.isStoragePoolTypeInList(StoragePoolType.Filesystem, clvmTypes));
assertFalse(strategy.isStoragePoolTypeInList(StoragePoolType.NetworkFilesystem, clvmTypes));
}
/**
* Test supportStoragePoolType with mixed CLVM and NFS types
*/
@Test
public void testSupportStoragePoolType_MixedClvmAndNfs() {
assertTrue(strategy.supportStoragePoolType(
StoragePoolType.CLVM,
StoragePoolType.CLVM,
StoragePoolType.CLVM_NG,
StoragePoolType.NetworkFilesystem
));
assertTrue(strategy.supportStoragePoolType(
StoragePoolType.CLVM_NG,
StoragePoolType.CLVM,
StoragePoolType.CLVM_NG,
StoragePoolType.NetworkFilesystem
));
assertTrue(strategy.supportStoragePoolType(
StoragePoolType.NetworkFilesystem,
StoragePoolType.CLVM,
StoragePoolType.CLVM_NG
));
}
/**
* Test internalCanHandle with CLVM source and managed destination
*/
@Test
public void testInternalCanHandle_ClvmSourceManagedDestination() {
VolumeObject volumeInfo = Mockito.spy(new VolumeObject());
Mockito.doReturn(0L).when(volumeInfo).getPoolId();
DataStore ds = Mockito.spy(new PrimaryDataStoreImpl());
Map<VolumeInfo, DataStore> volumeMap = new HashMap<>();
volumeMap.put(volumeInfo, ds);
StoragePoolVO sourcePool = Mockito.spy(new StoragePoolVO());
Mockito.lenient().doReturn(StoragePoolType.CLVM).when(sourcePool).getPoolType();
Mockito.doReturn(true).when(sourcePool).isManaged();
Mockito.doReturn(sourcePool).when(primaryDataStoreDao).findById(0L);
StrategyPriority result = strategy.internalCanHandle(
volumeMap, new HostVO("srcHostUuid"), new HostVO("destHostUuid"));
Assert.assertEquals(StrategyPriority.HIGHEST, result);
}
/**
* Test internalCanHandle with CLVM_NG source and managed destination
*/
@Test
public void testInternalCanHandle_ClvmNgSourceManagedDestination() {
VolumeObject volumeInfo = Mockito.spy(new VolumeObject());
Mockito.doReturn(0L).when(volumeInfo).getPoolId();
DataStore ds = Mockito.spy(new PrimaryDataStoreImpl());
Map<VolumeInfo, DataStore> volumeMap = new HashMap<>();
volumeMap.put(volumeInfo, ds);
StoragePoolVO sourcePool = Mockito.spy(new StoragePoolVO());
Mockito.lenient().doReturn(StoragePoolType.CLVM_NG).when(sourcePool).getPoolType();
Mockito.doReturn(true).when(sourcePool).isManaged();
Mockito.doReturn(sourcePool).when(primaryDataStoreDao).findById(0L);
StrategyPriority result = strategy.internalCanHandle(
volumeMap, new HostVO("srcHostUuid"), new HostVO("destHostUuid"));
Assert.assertEquals(StrategyPriority.HIGHEST, result);
}
/**
* Test internalCanHandle with both CLVM source and CLVM_NG destination
*/
@Test
public void testInternalCanHandle_ClvmToClvmNg() {
VolumeObject volumeInfo = Mockito.spy(new VolumeObject());
Mockito.doReturn(0L).when(volumeInfo).getPoolId();
DataStore ds = Mockito.spy(new PrimaryDataStoreImpl());
Map<VolumeInfo, DataStore> volumeMap = new HashMap<>();
volumeMap.put(volumeInfo, ds);
StoragePoolVO sourcePool = Mockito.spy(new StoragePoolVO());
Mockito.lenient().doReturn(StoragePoolType.CLVM).when(sourcePool).getPoolType();
Mockito.doReturn(true).when(sourcePool).isManaged();
StoragePoolVO destPool = Mockito.spy(new StoragePoolVO());
Mockito.lenient().doReturn(StoragePoolType.CLVM_NG).when(destPool).getPoolType();
Mockito.doReturn(sourcePool).when(primaryDataStoreDao).findById(0L);
StrategyPriority result = strategy.internalCanHandle(
volumeMap, new HostVO("srcHostUuid"), new HostVO("destHostUuid"));
Assert.assertEquals(StrategyPriority.HIGHEST, result);
}
/**
* Test internalCanHandle with CLVM_NG to CLVM migration
*/
@Test
public void testInternalCanHandle_ClvmNgToClvm() {
VolumeObject volumeInfo = Mockito.spy(new VolumeObject());
Mockito.doReturn(0L).when(volumeInfo).getPoolId();
DataStore ds = Mockito.spy(new PrimaryDataStoreImpl());
Map<VolumeInfo, DataStore> volumeMap = new HashMap<>();
volumeMap.put(volumeInfo, ds);
StoragePoolVO sourcePool = Mockito.spy(new StoragePoolVO());
Mockito.lenient().doReturn(StoragePoolType.CLVM_NG).when(sourcePool).getPoolType();
Mockito.doReturn(true).when(sourcePool).isManaged();
StoragePoolVO destPool = Mockito.spy(new StoragePoolVO());
Mockito.lenient().doReturn(StoragePoolType.CLVM).when(destPool).getPoolType();
Mockito.doReturn(sourcePool).when(primaryDataStoreDao).findById(0L);
StrategyPriority result = strategy.internalCanHandle(
volumeMap, new HostVO("srcHostUuid"), new HostVO("destHostUuid"));
Assert.assertEquals(StrategyPriority.HIGHEST, result);
}
}

View File

@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
@ -39,6 +40,10 @@ import com.cloud.storage.Storage;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.snapshot.VMSnapshot;
@RunWith(MockitoJUnitRunner.class)
public class DefaultVMSnapshotStrategyTest {
@ -46,6 +51,8 @@ public class DefaultVMSnapshotStrategyTest {
VolumeDao volumeDao;
@Mock
PrimaryDataStoreDao primaryDataStoreDao;
@Mock
UserVmDao userVmDao;
@Spy
@InjectMocks
@ -85,7 +92,7 @@ public class DefaultVMSnapshotStrategyTest {
Mockito.when(vol2.getChainInfo()).thenReturn(newVolChain);
Mockito.when(vol2.getSize()).thenReturn(vmSnapshotChainSize);
Mockito.when(vol2.getId()).thenReturn(volumeId);
VolumeVO volumeVO = new VolumeVO("name", 0l, 0l, 0l, 0l, 0l, "folder", "path", Storage.ProvisioningType.THIN, 0l, Volume.Type.ROOT);
VolumeVO volumeVO = new VolumeVO("name", 0L, 0L, 0L, 0L, 0L, "folder", "path", Storage.ProvisioningType.THIN, 0L, Volume.Type.ROOT);
volumeVO.setPoolId(oldPoolId);
volumeVO.setChainInfo(oldVolChain);
volumeVO.setPath(oldVolPath);
@ -103,4 +110,110 @@ public class DefaultVMSnapshotStrategyTest {
Assert.assertEquals(vmSnapshotChainSize, persistedVolume.getVmSnapshotChainSize());
Assert.assertEquals(newVolChain, persistedVolume.getChainInfo());
}
@Test
public void testCanHandleRunningVMOnClvmStorageCantHandle() {
Long vmId = 1L;
VMSnapshot vmSnapshot = Mockito.mock(VMSnapshot.class);
Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
UserVmVO vm = Mockito.mock(UserVmVO.class);
Mockito.when(vm.getId()).thenReturn(vmId);
Mockito.when(vm.getState()).thenReturn(State.Running);
Mockito.when(userVmDao.findById(vmId)).thenReturn(vm);
VolumeVO volumeOnClvm = createVolume(vmId, 1L);
List<VolumeVO> volumes = List.of(volumeOnClvm);
Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(volumes);
StoragePoolVO clvmPool = createStoragePool("clvm-pool", Storage.StoragePoolType.CLVM);
Mockito.when(primaryDataStoreDao.findById(1L)).thenReturn(clvmPool);
StrategyPriority result = defaultVMSnapshotStrategy.canHandle(vmSnapshot);
Assert.assertEquals("Should return CANT_HANDLE for running VM on CLVM storage",
StrategyPriority.CANT_HANDLE, result);
}
@Test
public void testCanHandleStoppedVMOnClvmStorageCanHandle() {
Long vmId = 1L;
VMSnapshot vmSnapshot = Mockito.mock(VMSnapshot.class);
Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
UserVmVO vm = Mockito.mock(UserVmVO.class);
Mockito.when(vm.getId()).thenReturn(vmId);
Mockito.when(vm.getState()).thenReturn(State.Stopped);
Mockito.when(userVmDao.findById(vmId)).thenReturn(vm);
StrategyPriority result = defaultVMSnapshotStrategy.canHandle(vmSnapshot);
Assert.assertEquals("Should return DEFAULT for stopped VM on CLVM storage",
StrategyPriority.DEFAULT, result);
}
@Test
public void testCanHandleRunningVMOnNfsStorageCanHandle() {
Long vmId = 1L;
VMSnapshot vmSnapshot = Mockito.mock(VMSnapshot.class);
Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
UserVmVO vm = Mockito.mock(UserVmVO.class);
Mockito.when(vm.getId()).thenReturn(vmId);
Mockito.when(vm.getState()).thenReturn(State.Running);
Mockito.when(userVmDao.findById(vmId)).thenReturn(vm);
VolumeVO volumeOnNfs = createVolume(vmId, 1L);
List<VolumeVO> volumes = List.of(volumeOnNfs);
Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(volumes);
StoragePoolVO nfsPool = createStoragePool("nfs-pool", Storage.StoragePoolType.NetworkFilesystem);
Mockito.when(primaryDataStoreDao.findById(1L)).thenReturn(nfsPool);
StrategyPriority result = defaultVMSnapshotStrategy.canHandle(vmSnapshot);
Assert.assertEquals("Should return DEFAULT for running VM on NFS storage",
StrategyPriority.DEFAULT, result);
}
@Test
public void testCanHandleRunningVMWithMixedStorageClvmAndNfsCantHandle() {
// Arrange - VM has volumes on both CLVM and NFS
Long vmId = 1L;
VMSnapshot vmSnapshot = Mockito.mock(VMSnapshot.class);
Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
UserVmVO vm = Mockito.mock(UserVmVO.class);
Mockito.when(vm.getId()).thenReturn(vmId);
Mockito.when(vm.getState()).thenReturn(State.Running);
Mockito.when(userVmDao.findById(vmId)).thenReturn(vm);
VolumeVO volumeOnClvm = createVolume(vmId, 1L);
VolumeVO volumeOnNfs = createVolume(vmId, 2L);
List<VolumeVO> volumes = List.of(volumeOnClvm, volumeOnNfs);
Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(volumes);
StoragePoolVO clvmPool = createStoragePool("clvm-pool", Storage.StoragePoolType.CLVM);
StoragePoolVO nfsPool = createStoragePool("nfs-pool", Storage.StoragePoolType.NetworkFilesystem);
Mockito.when(primaryDataStoreDao.findById(1L)).thenReturn(clvmPool);
StrategyPriority result = defaultVMSnapshotStrategy.canHandle(vmSnapshot);
Assert.assertEquals("Should return CANT_HANDLE if any volume is on CLVM storage for running VM",
StrategyPriority.CANT_HANDLE, result);
}
private VolumeVO createVolume(Long vmId, Long poolId) {
VolumeVO volume = new VolumeVO("volume", 0L, 0L, 0L, 0L, 0L,
"folder", "path", Storage.ProvisioningType.THIN, 0L, Volume.Type.ROOT);
volume.setInstanceId(vmId);
volume.setPoolId(poolId);
return volume;
}
private StoragePoolVO createStoragePool(String name, Storage.StoragePoolType poolType) {
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
Mockito.when(pool.getName()).thenReturn(name);
Mockito.when(pool.getPoolType()).thenReturn(poolType);
return pool;
}
}

View File

@ -7209,4 +7209,305 @@ public class LibvirtComputingResourceTest {
libvirtComputingResourceSpy.defineDiskForDefaultPoolType(diskDef, volume, false, false, false, physicalDisk, DEV_ID, DISK_BUS_TYPE, DISK_BUS_TYPE_DATA, null);
Mockito.verify(diskDef).defFileBasedDisk(PHYSICAL_DISK_PATH, DEV_ID, DISK_BUS_TYPE_DATA, DiskDef.DiskFmtType.QCOW2);
}
@Test
public void testExtractVolumeGroupFromPath_ValidPath() {
String devicePath = "/dev/vg1/volume-123";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("vg1", vgName);
}
@Test
public void testExtractVolumeGroupFromPath_ComplexVGName() {
String devicePath = "/dev/cloudstack-vg-primary/volume-456";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("cloudstack-vg-primary", vgName);
}
@Test
public void testExtractVolumeGroupFromPath_MultiLevelPath() {
String devicePath = "/dev/vg-cluster-01/lv-data-001";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("vg-cluster-01", vgName);
}
@Test
public void testExtractVolumeGroupFromPath_NullPath() {
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(null);
assertNull(vgName);
}
@Test
public void testExtractVolumeGroupFromPath_EmptyPath() {
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath("");
assertNull(vgName);
}
@Test
public void testExtractVolumeGroupFromPath_NonDevPath() {
String devicePath = "/var/lib/libvirt/images/disk.qcow2";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertNull(vgName);
}
@Test
public void testExtractVolumeGroupFromPath_InvalidFormat() {
String devicePath = "/dev/";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertNull(vgName);
}
@Test
public void testExtractVolumeGroupFromPath_OnlyVG() {
String devicePath = "/dev/vg1";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
// Implementation extracts parts[2] regardless of whether there's an LV name
assertEquals("vg1", vgName);
}
@Test
public void testExtractVolumeGroupFromPath_MapperPath() {
String devicePath = "/dev/mapper/vg1-volume";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("mapper", vgName);
}
@Test
public void testExtractVolumeGroupFromPath_WithDashes() {
String devicePath = "/dev/vg-name-with-dashes/lv-name";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("vg-name-with-dashes", vgName);
}
@Test
public void testExtractVolumeGroupFromPath_WithUnderscores() {
String devicePath = "/dev/vg_name_with_underscores/lv_name";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("vg_name_with_underscores", vgName);
}
@Test
public void testCheckIfVolumeGroupIsClustered_NullVGName() {
boolean result = LibvirtComputingResource.checkIfVolumeGroupIsClustered(null);
assertFalse(result);
}
@Test
public void testCheckIfVolumeGroupIsClustered_EmptyVGName() {
boolean result = LibvirtComputingResource.checkIfVolumeGroupIsClustered("");
assertFalse(result);
}
@Test
public void testActivateClvmVolumeExclusive_ValidPath() {
try {
String volumePath = "/dev/test-vg/test-lv";
LibvirtComputingResource.activateClvmVolumeExclusive(volumePath);
} catch (Exception e) {
String message = e.getMessage().toLowerCase();
assertTrue("Should be LVM-related error",
message.contains("lvm") ||
message.contains("lvchange") ||
message.contains("volume") ||
message.contains("not found") ||
message.contains("failed"));
}
}
@Test
public void testDeactivateClvmVolume_ValidPath() {
String volumePath = "/dev/test-vg/test-lv";
LibvirtComputingResource.deactivateClvmVolume(volumePath);
assertTrue(true);
}
@Test
public void testSetClvmVolumeToSharedMode_ValidPath() {
String volumePath = "/dev/test-vg/test-lv";
LibvirtComputingResource.setClvmVolumeToSharedMode(volumePath);
assertTrue(true);
}
@Test
public void testDeactivateClvmVolume_NullPath() {
LibvirtComputingResource.deactivateClvmVolume(null);
assertTrue(true);
}
@Test
public void testSetClvmVolumeToSharedMode_NullPath() {
LibvirtComputingResource.setClvmVolumeToSharedMode(null);
assertTrue(true); // Passes if no exception
}
@Test
public void testDeactivateClvmVolume_EmptyPath() {
LibvirtComputingResource.deactivateClvmVolume("");
assertTrue(true);
}
@Test
public void testSetClvmVolumeToSharedMode_EmptyPath() {
LibvirtComputingResource.setClvmVolumeToSharedMode("");
assertTrue(true);
}
@Test
public void testDeactivateClvmVolume_InvalidPath() {
String invalidPath = "/invalid/path/that/does/not/exist";
LibvirtComputingResource.deactivateClvmVolume(invalidPath);
assertTrue(true);
}
@Test
public void testSetClvmVolumeToSharedMode_InvalidPath() {
// Should handle invalid path gracefully without throwing
String invalidPath = "/invalid/path/that/does/not/exist";
LibvirtComputingResource.setClvmVolumeToSharedMode(invalidPath);
assertTrue(true); // Passes if no exception
}
@Test
public void testExtractVolumeGroupFromPath_RealWorldPaths() {
assertEquals("acsvg", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/acsvg/volume-123"));
assertEquals("cloudstack-primary", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/cloudstack-primary/vm-disk-1"));
assertEquals("ceph-vg", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/ceph-vg/snapshot-456"));
assertEquals("vg01", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/vg01/data"));
}
@Test
public void testCheckIfVolumeGroupIsClustered_NonExistentVG() {
String nonExistentVG = "non-existent-vg-" + System.currentTimeMillis();
boolean result = LibvirtComputingResource.checkIfVolumeGroupIsClustered(nonExistentVG);
assertFalse(result);
}
@Test
public void testActivateClvmVolumeExclusive_ComplexPath() {
try {
String complexPath = "/dev/cloudstack-vg-primary-cluster-01/volume-123-456-789-abc";
LibvirtComputingResource.activateClvmVolumeExclusive(complexPath);
} catch (Exception e) {
String message = e.getMessage().toLowerCase();
assertTrue("Should be LVM-related error",
message.contains("lvm") ||
message.contains("lvchange") ||
message.contains("volume") ||
message.contains("not found") ||
message.contains("failed"));
}
}
@Test
public void testDeactivateClvmVolume_ComplexPath() {
String complexPath = "/dev/cloudstack-vg-primary-cluster-01/volume-123-456-789-abc";
LibvirtComputingResource.deactivateClvmVolume(complexPath);
assertTrue(true);
}
@Test
public void testExtractVolumeGroupFromPath_SpecialCharacters() {
assertEquals("vg.name", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/vg.name/lv"));
assertEquals("vg_name", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/vg_name/lv"));
assertEquals("vg-name", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/vg-name/lv"));
assertEquals("vg123", LibvirtComputingResource.extractVolumeGroupFromPath("/dev/vg123/lv456"));
}
@Test
public void testExtractVolumeGroupFromPath_TrailingSlash() {
String devicePath = "/dev/vg1/volume-123/";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("vg1", vgName);
}
@Test
public void testCheckIfVolumeGroupIsClustered_WhitespaceVGName() {
boolean result = LibvirtComputingResource.checkIfVolumeGroupIsClustered(" ");
assertFalse(result);
}
@Test
public void testExtractVolumeGroupFromPath_DevMapperExcluded() {
String mapperPath1 = "/dev/mapper/vg1-lv1";
String mapperPath2 = "/dev/mapper/cloudstack--vg-volume--1";
assertEquals("mapper", LibvirtComputingResource.extractVolumeGroupFromPath(mapperPath1));
assertEquals("mapper", LibvirtComputingResource.extractVolumeGroupFromPath(mapperPath2));
}
@Test
public void testExtractVolumeGroupFromPath_EdgeCases() {
assertNull(LibvirtComputingResource.extractVolumeGroupFromPath("/dev"));
assertNull(LibvirtComputingResource.extractVolumeGroupFromPath("/dev/"));
assertNull(LibvirtComputingResource.extractVolumeGroupFromPath("dev/vg/lv"));
assertNull(LibvirtComputingResource.extractVolumeGroupFromPath("//dev//vg//lv"));
}
@Test
public void testClvmVolumeActivationSequence() {
// Test a typical sequence: deactivate -> activate exclusive -> deactivate -> shared
String volumePath = "/dev/test-vg/test-volume";
LibvirtComputingResource.deactivateClvmVolume(volumePath);
try {
LibvirtComputingResource.activateClvmVolumeExclusive(volumePath);
} catch (Exception e) {
// Expected in test environment
}
LibvirtComputingResource.deactivateClvmVolume(volumePath);
LibvirtComputingResource.setClvmVolumeToSharedMode(volumePath);
assertTrue(true); // Test passes if sequence completes
}
@Test
public void testExtractVolumeGroupFromPath_LongVGName() {
String longVGName = "a".repeat(100);
String devicePath = "/dev/" + longVGName + "/volume";
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals(longVGName, vgName);
}
@Test
public void testExtractVolumeGroupFromPath_LongLVName() {
String longLVName = "volume-" + "b".repeat(100);
String devicePath = "/dev/vg1/" + longLVName;
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(devicePath);
assertEquals("vg1", vgName);
}
@Test
public void testCheckIfVolumeGroupIsClustered_SpecialCharactersInName() {
assertFalse(LibvirtComputingResource.checkIfVolumeGroupIsClustered("vg.test.name"));
assertFalse(LibvirtComputingResource.checkIfVolumeGroupIsClustered("vg_test_name"));
assertFalse(LibvirtComputingResource.checkIfVolumeGroupIsClustered("vg-test-name"));
}
@Test
public void testClvmMethodsWithMultiplePaths() {
String[] paths = {
"/dev/vg1/vol1",
"/dev/vg2/vol2",
"/dev/cloudstack-primary/vol3",
"/dev/test-vg/test-vol"
};
for (String path : paths) {
LibvirtComputingResource.deactivateClvmVolume(path);
LibvirtComputingResource.setClvmVolumeToSharedMode(path);
String vgName = LibvirtComputingResource.extractVolumeGroupFromPath(path);
assertNotNull("Should extract VG from: " + path, vgName);
boolean clustered = LibvirtComputingResource.checkIfVolumeGroupIsClustered(vgName);
}
assertTrue(true); // Passes if all paths processed
}
}

View File

@ -0,0 +1,468 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.kvm.resource.wrapper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.apache.cloudstack.storage.command.ClvmLockTransferCommand;
import org.apache.logging.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import com.cloud.agent.api.Answer;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.utils.script.Script;
/**
* Tests for LibvirtClvmLockTransferCommandWrapper
*/
@RunWith(MockitoJUnitRunner.class)
public class LibvirtClvmLockTransferCommandWrapperTest {
@Mock
private LibvirtComputingResource libvirtComputingResource;
@Mock
private Logger logger;
private LibvirtClvmLockTransferCommandWrapper wrapper;
private static final String TEST_LV_PATH = "/dev/vg1/volume-123";
private static final String TEST_VOLUME_UUID = "test-volume-uuid-456";
@Before
public void setUp() {
wrapper = new LibvirtClvmLockTransferCommandWrapper();
wrapper.logger = logger;
}
@Test
public void testExecute_DeactivateSuccess() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null); // Success
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertTrue(answer.getResult());
assertTrue(answer.getDetails().contains("deactivated"));
assertTrue(answer.getDetails().contains(TEST_VOLUME_UUID));
// Verify script was constructed with correct parameters
assertEquals(1, scriptMock.constructed().size());
Script script = scriptMock.constructed().get(0);
verify(script).add("-an");
verify(script).add(TEST_LV_PATH);
}
}
@Test
public void testExecute_ActivateExclusiveSuccess() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_EXCLUSIVE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null); // Success
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertTrue(answer.getResult());
assertTrue(answer.getDetails().contains("activated exclusively"));
assertTrue(answer.getDetails().contains(TEST_VOLUME_UUID));
// Verify script was constructed with correct parameters
assertEquals(1, scriptMock.constructed().size());
Script script = scriptMock.constructed().get(0);
verify(script).add("-aey");
verify(script).add(TEST_LV_PATH);
}
}
@Test
public void testExecute_ActivateSharedSuccess() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_SHARED,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null); // Success
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertTrue(answer.getResult());
assertTrue(answer.getDetails().contains("activated in shared mode"));
assertTrue(answer.getDetails().contains(TEST_VOLUME_UUID));
// Verify script was constructed with correct parameters
assertEquals(1, scriptMock.constructed().size());
Script script = scriptMock.constructed().get(0);
verify(script).add("-asy");
verify(script).add(TEST_LV_PATH);
}
}
@Test
public void testExecute_LvchangeFailure() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
String errorMessage = "lvchange: Volume is in use";
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(errorMessage);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains("lvchange -an"));
assertTrue(answer.getDetails().contains(TEST_LV_PATH));
assertTrue(answer.getDetails().contains(errorMessage));
}
}
@Test
public void testExecute_ScriptTimeout() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_EXCLUSIVE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
String timeoutMessage = "Script timed out after 30000ms";
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(timeoutMessage);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains("failed"));
assertTrue(answer.getDetails().contains(timeoutMessage));
}
}
@Test
public void testExecute_NullLvPath() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
null,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
// Should still execute, but may fail or succeed depending on lvchange behavior
// At minimum, it should handle null gracefully
assertEquals(1, scriptMock.constructed().size());
}
}
@Test
public void testExecute_EmptyLvPath() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
"",
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn("lvchange: Please specify a logical volume path");
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains("failed"));
}
}
@Test
public void testExecute_InvalidLvPath() {
String invalidPath = "/invalid/path/that/does/not/exist";
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_EXCLUSIVE,
invalidPath,
TEST_VOLUME_UUID
);
String errorMessage = "Failed to find logical volume \"" + invalidPath + "\"";
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(errorMessage);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains("failed"));
assertTrue(answer.getDetails().contains(errorMessage));
}
}
@Test
public void testExecute_ExceptionDuringExecution() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
RuntimeException testException = new RuntimeException("Test exception");
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenThrow(testException);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains("Exception"));
assertTrue(answer.getDetails().contains("Test exception"));
}
}
@Test
public void testExecute_VerifyScriptConstruction() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
// Just set up the mock behavior - don't assert here as it can interfere
when(mock.execute()).thenReturn(null);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
// Verify the answer is successful
assertNotNull("Answer should not be null", answer);
assertTrue("Answer should indicate success. Details: " + answer.getDetails(),
answer.getResult());
// Verify that Script was constructed exactly once
assertEquals("Script should be constructed once", 1, scriptMock.constructed().size());
}
}
@Test
public void testExecute_AllOperationsUseDifferentFlags() {
// Test that each operation uses the correct lvchange flag
// DEACTIVATE -> -an
ClvmLockTransferCommand deactivateCmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
})) {
wrapper.execute(deactivateCmd, libvirtComputingResource);
verify(scriptMock.constructed().get(0)).add("-an");
}
// ACTIVATE_EXCLUSIVE -> -aey
ClvmLockTransferCommand exclusiveCmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_EXCLUSIVE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
})) {
wrapper.execute(exclusiveCmd, libvirtComputingResource);
verify(scriptMock.constructed().get(0)).add("-aey");
}
// ACTIVATE_SHARED -> -asy
ClvmLockTransferCommand sharedCmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_SHARED,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
})) {
wrapper.execute(sharedCmd, libvirtComputingResource);
verify(scriptMock.constructed().get(0)).add("-asy");
}
}
@Test
public void testExecute_LvchangeVolumeInUseError() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
String errorMessage = "Can't deactivate volume group with active logical volumes";
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(errorMessage);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains(errorMessage));
}
}
@Test
public void testExecute_LvchangePermissionDenied() {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_EXCLUSIVE,
TEST_LV_PATH,
TEST_VOLUME_UUID
);
String errorMessage = "Permission denied";
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(errorMessage);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertFalse(answer.getResult());
assertTrue(answer.getDetails().contains(errorMessage));
}
}
@Test
public void testExecute_ComplexLvPath() {
String complexPath = "/dev/cloudstack-vg-primary/volume-123-456-789-abc-def";
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.ACTIVATE_EXCLUSIVE,
complexPath,
TEST_VOLUME_UUID
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertTrue(answer.getResult());
// Verify the complex path was passed correctly
Script script = scriptMock.constructed().get(0);
verify(script).add(complexPath);
}
}
@Test
public void testExecute_SequentialOperations() {
// Test that multiple operations can be executed sequentially
String[] paths = {
"/dev/vg1/vol1",
"/dev/vg1/vol2",
"/dev/vg2/vol3"
};
for (String path : paths) {
ClvmLockTransferCommand cmd = new ClvmLockTransferCommand(
ClvmLockTransferCommand.Operation.DEACTIVATE,
path,
"uuid-" + path.hashCode()
);
try (MockedConstruction<Script> scriptMock = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
})) {
Answer answer = wrapper.execute(cmd, libvirtComputingResource);
assertNotNull(answer);
assertTrue(answer.getResult());
}
}
}
}

View File

@ -27,6 +27,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@ -454,7 +455,7 @@ public class LibvirtStorageAdaptorTest {
try {
method.invoke(libvirtStorageAdaptor, volumeName, size, mockPool);
} catch (java.lang.reflect.InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@ -542,7 +543,7 @@ public class LibvirtStorageAdaptorTest {
try {
method.invoke(libvirtStorageAdaptor, volumeUuid, timeout, virtualSize,
null, mockPool, Storage.ProvisioningType.THIN);
} catch (java.lang.reflect.InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@ -578,7 +579,7 @@ public class LibvirtStorageAdaptorTest {
try {
method.invoke(libvirtStorageAdaptor, volumeUuid, timeout, virtualSize,
null, mockPool, Storage.ProvisioningType.THIN);
} catch (java.lang.reflect.InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@ -602,7 +603,7 @@ public class LibvirtStorageAdaptorTest {
try {
method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
} catch (java.lang.reflect.InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@ -620,7 +621,7 @@ public class LibvirtStorageAdaptorTest {
try {
method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
} catch (java.lang.reflect.InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@ -638,8 +639,688 @@ public class LibvirtStorageAdaptorTest {
try {
method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
} catch (java.lang.reflect.InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@Test
public void testShouldSecureZeroFill_EnabledInDetails() throws Exception {
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "true");
Mockito.when(mockPool.getDetails()).thenReturn(details);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"shouldSecureZeroFill", KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, mockPool);
assert result : "Should return true when CLVM_SECURE_ZERO_FILL is 'true'";
}
@Test
public void testShouldSecureZeroFill_DisabledInDetails() throws Exception {
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "false");
Mockito.when(mockPool.getDetails()).thenReturn(details);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"shouldSecureZeroFill", KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, mockPool);
assert !result : "Should return false when CLVM_SECURE_ZERO_FILL is 'false'";
}
@Test
public void testShouldSecureZeroFill_NotSetInDetails() throws Exception {
Map<String, String> details = new HashMap<>();
Mockito.when(mockPool.getDetails()).thenReturn(details);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"shouldSecureZeroFill", KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, mockPool);
assert !result : "Should return false when CLVM_SECURE_ZERO_FILL is not set";
}
@Test
public void testShouldSecureZeroFill_NullDetails() throws Exception {
Mockito.when(mockPool.getDetails()).thenReturn(null);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"shouldSecureZeroFill", KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, mockPool);
assert !result : "Should return false when details are null";
}
@Test
public void testExtractVgNameFromPool_SimplePath() throws Exception {
String vgName = "testvg";
Mockito.when(mockPool.getLocalPath()).thenReturn(vgName);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"extractVgNameFromPool", KVMStoragePool.class);
method.setAccessible(true);
String result = (String) method.invoke(libvirtStorageAdaptor, mockPool);
assertEquals("Should extract VG name correctly", vgName, result);
}
@Test
public void testExtractVgNameFromPool_PathWithSlash() throws Exception {
String vgName = "testvg";
String path = "/" + vgName;
Mockito.when(mockPool.getLocalPath()).thenReturn(path);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"extractVgNameFromPool", KVMStoragePool.class);
method.setAccessible(true);
String result = (String) method.invoke(libvirtStorageAdaptor, mockPool);
assertEquals("Should extract VG name from path with leading slash", vgName, result);
}
@Test(expected = CloudRuntimeException.class)
public void testExtractVgNameFromPool_NullPath() throws Throwable {
Mockito.when(mockPool.getLocalPath()).thenReturn(null);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"extractVgNameFromPool", KVMStoragePool.class);
method.setAccessible(true);
try {
method.invoke(libvirtStorageAdaptor, mockPool);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@Test
public void testLvExists_VolumeExists() throws Exception {
String lvPath = "/dev/testvg/test-volume";
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn(null);
});
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"lvExists", String.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, lvPath);
assert result : "Should return true when LV exists (lvs returns null)";
}
@Test
public void testLvExists_VolumeDoesNotExist() throws Exception {
String lvPath = "/dev/testvg/nonexistent-volume";
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> {
when(mock.execute()).thenReturn("Volume not found");
});
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"lvExists", String.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, lvPath);
assert !result : "Should return false when LV does not exist";
}
@Test
public void testGetVgName_SimpleName() throws Exception {
String vgName = "acsvg";
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"getVgName", String.class);
method.setAccessible(true);
String result = (String) method.invoke(libvirtStorageAdaptor, vgName);
assertEquals("Should return VG name as-is for simple name", vgName, result);
}
@Test
public void testGetVgName_PathWithSlash() throws Exception {
String vgName = "acsvg";
String path = "/" + vgName;
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"getVgName", String.class);
method.setAccessible(true);
String result = (String) method.invoke(libvirtStorageAdaptor, path);
assertEquals("Should extract VG name from path with leading slash", vgName, result);
}
@Test
public void testGetVgName_DevPath() throws Exception {
String vgName = "acsvg";
String path = "/dev/" + vgName;
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"getVgName", String.class);
method.setAccessible(true);
String result = (String) method.invoke(libvirtStorageAdaptor, path);
assertEquals("Should extract VG name from /dev/ path", vgName, result);
}
@Test
public void testCreatePhysicalDiskFromClvmLv_CLVM() throws Exception {
String lvPath = "/dev/testvg/test-volume";
String volumeUuid = "test-volume";
long size = 10737418240L;
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"createPhysicalDiskFromClvmLv",
String.class, String.class, KVMStoragePool.class, long.class);
method.setAccessible(true);
KVMPhysicalDisk result = (KVMPhysicalDisk) method.invoke(
libvirtStorageAdaptor, lvPath, volumeUuid, mockPool, size);
assertNotNull("Physical disk should be created", result);
assertEquals("Format should be RAW for CLVM", PhysicalDiskFormat.RAW, result.getFormat());
assertEquals("Size should match", size, result.getSize());
assertEquals("Path should match", lvPath, result.getPath());
}
@Test
public void testCreatePhysicalDiskFromClvmLv_CLVM_NG() throws Exception {
String lvPath = "/dev/testvg-ng/test-volume";
String volumeUuid = "test-volume";
long size = 10737418240L;
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"createPhysicalDiskFromClvmLv",
String.class, String.class, KVMStoragePool.class, long.class);
method.setAccessible(true);
KVMPhysicalDisk result = (KVMPhysicalDisk) method.invoke(
libvirtStorageAdaptor, lvPath, volumeUuid, mockPool, size);
assertNotNull("Physical disk should be created", result);
assertEquals("Format should be QCOW2 for CLVM_NG", PhysicalDiskFormat.QCOW2, result.getFormat());
assertEquals("Size should match", size, result.getSize());
assertEquals("Path should match", lvPath, result.getPath());
}
@Test
public void testCLVMPoolSecureZeroFill_TrueValue() {
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "true");
Mockito.when(mockPool.getDetails()).thenReturn(details);
String value = mockPool.getDetails().get(KVMStoragePool.CLVM_SECURE_ZERO_FILL);
assert "true".equals(value) : "CLVM_SECURE_ZERO_FILL should be 'true'";
}
@Test
public void testCLVMPoolSecureZeroFill_FalseValue() {
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "false");
Mockito.when(mockPool.getDetails()).thenReturn(details);
String value = mockPool.getDetails().get(KVMStoragePool.CLVM_SECURE_ZERO_FILL);
assert "false".equals(value) : "CLVM_SECURE_ZERO_FILL should be 'false'";
}
@Test
public void testCLVMVolumePathConstruction() {
String vgName = "acsvg";
String volumeUuid = "550e8400-e29b-41d4-a716-446655440000";
String expectedPath = "/dev/" + vgName + "/" + volumeUuid;
assertEquals("/dev/acsvg/550e8400-e29b-41d4-a716-446655440000", expectedPath);
}
@Test
public void testCLVMNGPoolSupportsQCOW2Format() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
Storage.StoragePoolType type = mockPool.getType();
PhysicalDiskFormat expectedFormat = PhysicalDiskFormat.QCOW2;
assert type == Storage.StoragePoolType.CLVM_NG : "Pool type should be CLVM_NG";
assertNotNull("QCOW2 format should be available", expectedFormat);
}
@Test
public void testCLVMPoolSupportsRAWFormat() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
Storage.StoragePoolType type = mockPool.getType();
PhysicalDiskFormat expectedFormat = PhysicalDiskFormat.RAW;
assert type == Storage.StoragePoolType.CLVM : "Pool type should be CLVM";
assertNotNull("RAW format should be available", expectedFormat);
}
@Test
public void testVerifyLvExistsInVg_VolumeExists() throws Exception {
String volumeUuid = "test-volume-uuid";
String vgName = "testvg";
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn(null));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"verifyLvExistsInVg", String.class, String.class);
method.setAccessible(true);
method.invoke(libvirtStorageAdaptor, volumeUuid, vgName);
}
@Test(expected = CloudRuntimeException.class)
public void testVerifyLvExistsInVg_VolumeDoesNotExist() throws Throwable {
String volumeUuid = "nonexistent-volume";
String vgName = "testvg";
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn(" Volume not found"));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"verifyLvExistsInVg", String.class, String.class);
method.setAccessible(true);
try {
method.invoke(libvirtStorageAdaptor, volumeUuid, vgName);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
@Test
public void testGetClvmVolumeSize_MethodExists() throws Exception {
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"getClvmVolumeSize", String.class);
method.setAccessible(true);
assertNotNull("getClvmVolumeSize method should exist", method);
}
@Test
public void testCLVMPoolIsBlockBased() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
boolean isBlockBased = mockPool.getType() == Storage.StoragePoolType.CLVM ||
mockPool.getType() == Storage.StoragePoolType.CLVM_NG;
assert isBlockBased : "CLVM should be recognized as block-based storage";
}
@Test
public void testCLVMNGPoolIsBlockBased() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
boolean isBlockBased = mockPool.getType() == Storage.StoragePoolType.CLVM ||
mockPool.getType() == Storage.StoragePoolType.CLVM_NG;
assert isBlockBased : "CLVM_NG should be recognized as block-based storage";
}
@Test
public void testGetVgName_ComplexPath() throws Exception {
String vgName = "acsvg-ng";
String path = "/dev/mapper/" + vgName;
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"getVgName", String.class);
method.setAccessible(true);
String result = (String) method.invoke(libvirtStorageAdaptor, path);
assertNotNull("VG name should not be null", result);
}
@Test
public void testExtractVgNameFromPool_EmptyPath() throws Exception {
Mockito.when(mockPool.getLocalPath()).thenReturn("");
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"extractVgNameFromPool", KVMStoragePool.class);
method.setAccessible(true);
try {
method.invoke(libvirtStorageAdaptor, mockPool);
assert false : "Should throw CloudRuntimeException for empty path";
} catch (InvocationTargetException e) {
assert e.getCause() instanceof CloudRuntimeException :
"Should throw CloudRuntimeException";
}
}
@Test
public void testCleanupCLVMVolume_VolumeExists_WithSecureZeroFill() throws Exception {
String volumeUuid = UUID.randomUUID().toString();
String vgName = "testvg";
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "true");
Mockito.when(mockPool.getLocalPath()).thenReturn(vgName);
Mockito.when(mockPool.getUuid()).thenReturn(UUID.randomUUID().toString());
Mockito.when(mockPool.getDetails()).thenReturn(details);
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn(null));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"cleanupCLVMVolume", String.class, KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
assert result : "Cleanup should succeed";
}
@Test
public void testCleanupCLVMVolume_VolumeExists_WithoutSecureZeroFill() throws Exception {
String volumeUuid = UUID.randomUUID().toString();
String vgName = "testvg";
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "false");
Mockito.when(mockPool.getLocalPath()).thenReturn(vgName);
Mockito.when(mockPool.getUuid()).thenReturn(UUID.randomUUID().toString());
Mockito.when(mockPool.getDetails()).thenReturn(details);
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn(null));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"cleanupCLVMVolume", String.class, KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
assert result : "Cleanup should succeed without zero-fill";
}
@Test
public void testCleanupCLVMVolume_VolumeNotFound() throws Exception {
String volumeUuid = "nonexistent-volume";
String vgName = "testvg";
Mockito.when(mockPool.getLocalPath()).thenReturn(vgName);
Mockito.when(mockPool.getUuid()).thenReturn(UUID.randomUUID().toString());
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn("Volume not found"));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"cleanupCLVMVolume", String.class, KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
assert result : "Should return true when volume not found (already deleted)";
}
@Test
public void testCleanupCLVMVolume_NullSourceDir() throws Exception {
String volumeUuid = UUID.randomUUID().toString();
Mockito.when(mockPool.getLocalPath()).thenReturn(null);
Mockito.when(mockPool.getUuid()).thenReturn(UUID.randomUUID().toString());
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"cleanupCLVMVolume", String.class, KVMStoragePool.class);
method.setAccessible(true);
boolean result = (boolean) method.invoke(libvirtStorageAdaptor, volumeUuid, mockPool);
assert result : "Should return true when source dir is null";
}
@Test
public void testRemoveLvOnFailure_Success() throws Exception {
String lvPath = "/dev/testvg/test-volume";
int timeout = 30000;
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn(null));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"removeLvOnFailure", String.class, int.class);
method.setAccessible(true);
method.invoke(libvirtStorageAdaptor, lvPath, timeout);
}
@Test
public void testEnsureTemplateAccessibility_CLVM_NG_TemplateVolume() throws Exception {
String volumeUuid = "template-550e8400-e29b-41d4-a716-446655440000";
String lvPath = "/dev/testvg/template-550e8400-e29b-41d4-a716-446655440000";
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
mockScriptConstruction = Mockito.mockConstruction(Script.class,
(mock, context) -> when(mock.execute()).thenReturn(null));
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"ensureTemplateAccessibility", String.class, String.class, KVMStoragePool.class);
method.setAccessible(true);
method.invoke(libvirtStorageAdaptor, volumeUuid, lvPath, mockPool);
}
@Test
public void testEnsureTemplateAccessibility_CLVM_NonTemplate() throws Exception {
String volumeUuid = UUID.randomUUID().toString();
String lvPath = "/dev/testvg/" + volumeUuid;
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"ensureTemplateAccessibility", String.class, String.class, KVMStoragePool.class);
method.setAccessible(true);
method.invoke(libvirtStorageAdaptor, volumeUuid, lvPath, mockPool);
}
@Test
public void testCreateVirtualClvmPool_MethodExists() throws Exception {
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"createVirtualClvmPool",
String.class, String.class, String.class,
Storage.StoragePoolType.class, Map.class);
method.setAccessible(true);
assertNotNull("createVirtualClvmPool method should exist", method);
}
@Test
public void testFindDeviceNodeAfterActivation_MethodExists() throws Exception {
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"findDeviceNodeAfterActivation",
String.class, String.class, String.class);
method.setAccessible(true);
assertNotNull("findDeviceNodeAfterActivation method should exist", method);
}
@Test
public void testHandleMissingDeviceNode_MethodExists() throws Exception {
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"handleMissingDeviceNode",
String.class, String.class, KVMStoragePool.class);
method.setAccessible(true);
assertNotNull("handleMissingDeviceNode method should exist", method);
}
@Test
public void testHandleMissingDeviceNode_NonTemplate_MethodExists() throws Exception {
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"handleMissingDeviceNode",
String.class, String.class, KVMStoragePool.class);
method.setAccessible(true);
assertNotNull("handleMissingDeviceNode method should exist", method);
}
@Test
public void testFindAccessibleDeviceNode_MethodExists() throws Exception {
Method method = LibvirtStorageAdaptor.class.getDeclaredMethod(
"findAccessibleDeviceNode",
String.class, String.class, KVMStoragePool.class);
method.setAccessible(true);
assertNotNull("findAccessibleDeviceNode method should exist", method);
}
@Test
public void testCLVMNGDiskFormat_IsQCOW2() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
PhysicalDiskFormat format = (mockPool.getType() == Storage.StoragePoolType.CLVM_NG)
? PhysicalDiskFormat.QCOW2
: PhysicalDiskFormat.RAW;
assertEquals("CLVM_NG should use QCOW2 format", PhysicalDiskFormat.QCOW2, format);
}
@Test
public void testCLVMDiskFormat_IsRAW() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
PhysicalDiskFormat format = (mockPool.getType() == Storage.StoragePoolType.CLVM_NG)
? PhysicalDiskFormat.QCOW2
: PhysicalDiskFormat.RAW;
assertEquals("CLVM should use RAW format", PhysicalDiskFormat.RAW, format);
}
@Test
public void testCLVMPoolDetails_DefaultSecureZeroFill() {
Map<String, String> details = new HashMap<>();
String value = details.get(KVMStoragePool.CLVM_SECURE_ZERO_FILL);
assert value == null : "CLVM_SECURE_ZERO_FILL should default to null";
}
@Test
public void testCLVMPoolDetails_CustomSecureZeroFill() {
Map<String, String> details = new HashMap<>();
details.put(KVMStoragePool.CLVM_SECURE_ZERO_FILL, "true");
String value = details.get(KVMStoragePool.CLVM_SECURE_ZERO_FILL);
assertEquals("CLVM_SECURE_ZERO_FILL should be 'true'", "true", value);
}
@Test
public void testCLVMVolumeDeviceMapperPathEscaping() {
String vgName = "acsvg-ng";
String volumeUuid = "ea19580e-0882-4ab8-973b-a320637037f4";
String vgNameEscaped = vgName.replace("-", "--");
String volumeUuidEscaped = volumeUuid.replace("-", "--");
String mapperPath = "/dev/mapper/" + vgNameEscaped + "-" + volumeUuidEscaped;
String expectedPath = "/dev/mapper/acsvg--ng-ea19580e--0882--4ab8--973b--a320637037f4";
assertEquals("Mapper path should have escaped hyphens", expectedPath, mapperPath);
}
@Test
public void testCLVMTemplateNamePrefix() {
String templateUuid = UUID.randomUUID().toString();
String templateName = "template-" + templateUuid;
assert templateName.startsWith("template-");
assert templateName.length() > 9;
}
@Test
public void testCLVMPoolTypeIsNotFileSystem() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
boolean isFileSystem = mockPool.getType() == Storage.StoragePoolType.Filesystem;
assert !isFileSystem : "CLVM is not a file system pool type";
}
@Test
public void testCLVMNGPoolTypeIsNotFileSystem() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
boolean isFileSystem = mockPool.getType() == Storage.StoragePoolType.Filesystem;
assert !isFileSystem : "CLVM_NG is not a file system pool type";
}
@Test
public void testCLVMPoolTypeIsNotNFS() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM);
boolean isNFS = mockPool.getType() == Storage.StoragePoolType.NetworkFilesystem;
assert !isNFS : "CLVM is not an NFS pool type";
}
@Test
public void testCLVMNGPoolTypeIsNotRBD() {
Mockito.when(mockPool.getType()).thenReturn(Storage.StoragePoolType.CLVM_NG);
boolean isRBD = mockPool.getType() == Storage.StoragePoolType.RBD;
assert !isRBD : "CLVM_NG is not an RBD pool type";
}
@Test
public void testCLVMVolumeUUIDFormat() {
String volumeUuid = UUID.randomUUID().toString();
assert volumeUuid.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
}
@Test
public void testCLVMNGBackingFileFormat() {
String vgName = "testvg";
String templateUuid = UUID.randomUUID().toString();
String backingFile = "/dev/" + vgName + "/template-" + templateUuid;
assert backingFile.startsWith("/dev/");
assert backingFile.contains("template-");
assert backingFile.contains(templateUuid);
}
@Test
public void testCLVMPoolLocalPathValidation() {
String vgName = "acsvg";
Mockito.when(mockPool.getLocalPath()).thenReturn(vgName);
String localPath = mockPool.getLocalPath();
assertNotNull("Local path should not be null", localPath);
assert !localPath.isEmpty() : "Local path should not be empty";
}
}