This is an automated email from the ASF dual-hosted git repository.

joao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 8af08ddafbc3bb4d0737b731ce54ca6dd25eaf60
Merge: be247334a7f a6cef7a78dd
Author: João Jandre <48719461+joaojan...@users.noreply.github.com>
AuthorDate: Mon Nov 4 08:58:48 2024 -0300

    Merge branch '4.19'

 .../kvm/resource/LibvirtComputingResource.java     |  15 ++-
 .../kvm/storage/KVMStorageProcessor.java           |   2 +-
 .../kvm/resource/LibvirtComputingResourceTest.java | 113 +++++++++++++++++++++
 plugins/storage/volume/linstor/CHANGELOG.md        |   7 ++
 ui/src/views/infra/UpdatePrimaryStorage.vue        |  10 +-
 5 files changed, 142 insertions(+), 5 deletions(-)

diff --cc 
plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
index 30d0b2ab163,17bff8325ce..15c2b46e077
--- 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
+++ 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
@@@ -6224,195 -6299,113 +6227,305 @@@ public class LibvirtComputingResourceTe
          }
      }
  
 +    @Test
 +    public void testGetHostTags() throws ConfigurationException {
 +        try (MockedStatic<AgentPropertiesFileHandler> ignored = 
Mockito.mockStatic(AgentPropertiesFileHandler.class)) {
 +            
Mockito.when(AgentPropertiesFileHandler.getPropertyValue(Mockito.eq(AgentProperties.HOST_TAGS)))
 +                    .thenReturn("aa,bb,cc,dd");
 +
 +            List<String> hostTagsList = 
libvirtComputingResourceSpy.getHostTags();
 +            Assert.assertEquals(4, hostTagsList.size());
 +            Assert.assertEquals("aa,bb,cc,dd", StringUtils.join(hostTagsList, 
","));
 +        }
 +    }
 +
 +    @Test
 +    public void testGetHostTagsWithSpace() throws ConfigurationException {
 +        try (MockedStatic<AgentPropertiesFileHandler> ignored = 
Mockito.mockStatic(AgentPropertiesFileHandler.class)) {
 +            
Mockito.when(AgentPropertiesFileHandler.getPropertyValue(Mockito.eq(AgentProperties.HOST_TAGS)))
 +                    .thenReturn(" aa, bb , cc , dd ");
 +
 +            List<String> hostTagsList = 
libvirtComputingResourceSpy.getHostTags();
 +            Assert.assertEquals(4, hostTagsList.size());
 +            Assert.assertEquals("aa,bb,cc,dd", StringUtils.join(hostTagsList, 
","));
 +        }
 +    }
 +
 +    @Test
 +    public void testGetHostTagsWithEmptyPropertyValue() throws 
ConfigurationException {
 +        try (MockedStatic<AgentPropertiesFileHandler> ignored = 
Mockito.mockStatic(AgentPropertiesFileHandler.class)) {
 +            
Mockito.when(AgentPropertiesFileHandler.getPropertyValue(Mockito.eq(AgentProperties.HOST_TAGS)))
 +                    .thenReturn(" ");
 +
 +            List<String> hostTagsList = 
libvirtComputingResourceSpy.getHostTags();
 +            Assert.assertEquals(0, hostTagsList.size());
 +            Assert.assertEquals("", StringUtils.join(hostTagsList, ","));
 +        }
 +    }
 +
 +    @Test
 +    public void getVmStatTestVmIsNullReturnsNull() throws LibvirtException {
 +        doReturn(null).when(libvirtComputingResourceSpy).getDomain(connMock, 
VM_NAME);
 +
 +        VmStatsEntry stat = libvirtComputingResourceSpy.getVmStat(connMock, 
VM_NAME);
 +
 +        verify(libvirtComputingResourceSpy).getDomain(connMock, VM_NAME);
 +        verify(libvirtComputingResourceSpy, 
never()).getVmCurrentStats(domainMock);
 +        verify(libvirtComputingResourceSpy, 
never()).calculateVmMetrics(Mockito.any(), Mockito.any(), Mockito.any());
 +        Assert.assertNull(stat);
 +    }
 +
 +    @Test
 +    public void getVmStatTestVmIsNotNullReturnsMetrics() throws 
LibvirtException {
 +        
doReturn(domainMock).when(libvirtComputingResourceSpy).getDomain(connMock, 
VM_NAME);
 +        
doReturn(Mockito.mock(LibvirtExtendedVmStatsEntry.class)).when(libvirtComputingResourceSpy).getVmCurrentStats(domainMock);
 +        
doReturn(Mockito.mock(VmStatsEntry.class)).when(libvirtComputingResourceSpy).calculateVmMetrics(Mockito.any(),
 Mockito.any(), Mockito.any());
 +
 +        VmStatsEntry stat = libvirtComputingResourceSpy.getVmStat(connMock, 
VM_NAME);
 +
 +        verify(libvirtComputingResourceSpy).getDomain(connMock, VM_NAME);
 +        verify(libvirtComputingResourceSpy).getVmCurrentStats(domainMock);
 +        verify(libvirtComputingResourceSpy).calculateVmMetrics(Mockito.any(), 
Mockito.any(), Mockito.any());
 +        Assert.assertNotNull(stat);
 +    }
 +
 +    private void prepareVmInfoForGetVmCurrentStats() throws LibvirtException {
 +        final NodeInfo nodeInfo = new NodeInfo();
 +        nodeInfo.cpus = 8;
 +        nodeInfo.memory = 8 * 1024 * 1024;
 +        nodeInfo.sockets = 2;
 +        nodeInfo.threads = 2;
 +        nodeInfo.model = "Foo processor";
 +
 +        Mockito.when(domainMock.getName()).thenReturn(VM_NAME);
 +        Mockito.when(domainMock.getConnect()).thenReturn(connMock);
 +        domainInfoMock.cpuTime = 500L;
 +        domainInfoMock.nrVirtCpu = 4;
 +        domainInfoMock.memory = 2048;
 +        domainInfoMock.maxMem = 4096;
 +        Mockito.when(domainMock.getInfo()).thenReturn(domainInfoMock);
 +        final MemoryStatistic[] domainMem = new MemoryStatistic[2];
 +        domainMem[0] = Mockito.mock(MemoryStatistic.class);
 +        
doReturn(1024L).when(libvirtComputingResourceSpy).getMemoryFreeInKBs(domainMock);
 +
 +        domainInterfaceStatsMock.rx_bytes = 1000L;
 +        domainInterfaceStatsMock.tx_bytes = 2000L;
 +        
doReturn(domainInterfaceStatsMock).when(domainMock).interfaceStats(Mockito.any());
 +        doReturn(List.of(new 
InterfaceDef())).when(libvirtComputingResourceSpy).getInterfaces(connMock, 
VM_NAME);
 +
 +        domainBlockStatsMock.rd_req = 3000L;
 +        domainBlockStatsMock.rd_bytes = 4000L;
 +        domainBlockStatsMock.wr_req = 5000L;
 +        domainBlockStatsMock.wr_bytes = 6000L;
 +        
doReturn(domainBlockStatsMock).when(domainMock).blockStats(Mockito.any());
 +        doReturn(List.of(new 
DiskDef())).when(libvirtComputingResourceSpy).getDisks(connMock, VM_NAME);
 +    }
 +
 +    @Test
 +    public void getVmCurrentStatsTestIfStatsAreAsExpected() throws 
LibvirtException {
 +        prepareVmInfoForGetVmCurrentStats();
 +
 +        LibvirtExtendedVmStatsEntry vmStatsEntry = 
libvirtComputingResourceSpy.getVmCurrentStats(domainMock);
 +
 +        Assert.assertEquals(domainInfoMock.cpuTime, 
vmStatsEntry.getCpuTime());
 +        Assert.assertEquals((double) domainInterfaceStatsMock.rx_bytes / 
1024, vmStatsEntry.getNetworkReadKBs(), 0);
 +        Assert.assertEquals((double) domainInterfaceStatsMock.tx_bytes / 
1024, vmStatsEntry.getNetworkWriteKBs(), 0);
 +        Assert.assertEquals(domainBlockStatsMock.rd_req, 
vmStatsEntry.getDiskReadIOs(), 0);
 +        Assert.assertEquals((double) domainBlockStatsMock.rd_bytes / 1024, 
vmStatsEntry.getDiskReadKBs(), 0);
 +        Assert.assertEquals(domainBlockStatsMock.wr_req, 
vmStatsEntry.getDiskWriteIOs(), 0);
 +        Assert.assertEquals((double) domainBlockStatsMock.wr_bytes / 1024, 
vmStatsEntry.getDiskWriteKBs(), 0);
 +        Assert.assertNotNull(vmStatsEntry.getTimestamp());
 +    }
 +
 +    @Test
 +    public void getVmCurrentCpuStatsTestIfStatsAreAsExpected() throws 
LibvirtException {
 +        prepareVmInfoForGetVmCurrentStats();
 +
 +        LibvirtExtendedVmStatsEntry vmStatsEntry = new 
LibvirtExtendedVmStatsEntry();
 +        libvirtComputingResourceSpy.getVmCurrentCpuStats(domainMock, 
vmStatsEntry);
 +
 +        Assert.assertEquals(domainInfoMock.cpuTime, 
vmStatsEntry.getCpuTime());
 +    }
 +
 +    @Test
 +    public void getVmCurrentNetworkStatsTestIfStatsAreAsExpected() throws 
LibvirtException {
 +        prepareVmInfoForGetVmCurrentStats();
 +
 +        LibvirtExtendedVmStatsEntry vmStatsEntry = new 
LibvirtExtendedVmStatsEntry();
 +        libvirtComputingResourceSpy.getVmCurrentNetworkStats(domainMock, 
vmStatsEntry);
 +
 +        Assert.assertEquals((double) domainInterfaceStatsMock.rx_bytes / 
1024, vmStatsEntry.getNetworkReadKBs(), 0);
 +        Assert.assertEquals((double) domainInterfaceStatsMock.tx_bytes / 
1024, vmStatsEntry.getNetworkWriteKBs(), 0);
 +    }
 +
 +    @Test
 +    public void getVmCurrentDiskStatsTestIfStatsAreAsExpected() throws 
LibvirtException {
 +        prepareVmInfoForGetVmCurrentStats();
 +
 +        LibvirtExtendedVmStatsEntry vmStatsEntry = new 
LibvirtExtendedVmStatsEntry();
 +        libvirtComputingResourceSpy.getVmCurrentDiskStats(domainMock, 
vmStatsEntry);
 +
 +        Assert.assertEquals(domainBlockStatsMock.rd_req, 
vmStatsEntry.getDiskReadIOs(), 0);
 +        Assert.assertEquals((double) domainBlockStatsMock.rd_bytes / 1024, 
vmStatsEntry.getDiskReadKBs(), 0);
 +        Assert.assertEquals(domainBlockStatsMock.wr_req, 
vmStatsEntry.getDiskWriteIOs(), 0);
 +        Assert.assertEquals((double) domainBlockStatsMock.wr_bytes / 1024, 
vmStatsEntry.getDiskWriteKBs(), 0);
 +    }
 +
 +    @Test
 +    public void 
calculateVmMetricsTestOldStatsIsNullDoesNotCalculateUtilization() throws 
LibvirtException {
 +        prepareVmInfoForGetVmCurrentStats();
 +
 +        LibvirtExtendedVmStatsEntry vmStatsEntry = 
libvirtComputingResourceSpy.getVmCurrentStats(domainMock);
 +        VmStatsEntry metrics = 
libvirtComputingResourceSpy.calculateVmMetrics(domainMock, null, vmStatsEntry);
 +
 +        Assert.assertEquals(domainInfoMock.nrVirtCpu, metrics.getNumCPUs());
 +        Assert.assertEquals(domainInfoMock.maxMem, (long) 
metrics.getMemoryKBs());
 +        
Assert.assertEquals(libvirtComputingResourceSpy.getMemoryFreeInKBs(domainMock), 
(long) metrics.getIntFreeMemoryKBs());
 +        Assert.assertEquals(domainInfoMock.memory, (long) 
metrics.getTargetMemoryKBs());
 +        Assert.assertEquals(0, metrics.getCPUUtilization(), 0);
 +        Assert.assertEquals(0, metrics.getNetworkReadKBs(), 0);
 +        Assert.assertEquals(0, metrics.getNetworkWriteKBs(), 0);
 +        Assert.assertEquals(0, metrics.getDiskReadKBs(), 0);
 +        Assert.assertEquals(0, metrics.getDiskReadIOs(), 0);
 +        Assert.assertEquals(0, metrics.getDiskWriteKBs(), 0);
 +        Assert.assertEquals(0, metrics.getDiskWriteIOs(), 0);
 +    }
 +
 +    @Test
 +    public void 
calculateVmMetricsTestOldStatsIsNotNullCalculatesUtilization() throws 
LibvirtException {
 +        prepareVmInfoForGetVmCurrentStats();
 +        LibvirtExtendedVmStatsEntry oldStats = 
libvirtComputingResourceSpy.getVmCurrentStats(domainMock);
 +        domainInfoMock.cpuTime *= 3;
 +        domainInterfaceStatsMock.rx_bytes *= 3;
 +        domainInterfaceStatsMock.tx_bytes *= 3;
 +        domainBlockStatsMock.rd_req *= 3;
 +        domainBlockStatsMock.rd_bytes *= 3;
 +        domainBlockStatsMock.wr_req *= 3;
 +        domainBlockStatsMock.wr_bytes *= 3;
 +        LibvirtExtendedVmStatsEntry newStats = 
libvirtComputingResourceSpy.getVmCurrentStats(domainMock);
 +
 +        VmStatsEntry metrics = 
libvirtComputingResourceSpy.calculateVmMetrics(domainMock, oldStats, newStats);
 +
 +        Assert.assertEquals(domainInfoMock.nrVirtCpu, metrics.getNumCPUs());
 +        Assert.assertEquals(domainInfoMock.maxMem, (long) 
metrics.getMemoryKBs());
 +        
Assert.assertEquals(libvirtComputingResourceSpy.getMemoryFreeInKBs(domainMock), 
(long) metrics.getIntFreeMemoryKBs());
 +        Assert.assertEquals(domainInfoMock.memory, (long) 
metrics.getTargetMemoryKBs());
 +        Assert.assertTrue(metrics.getCPUUtilization() > 0);
 +        Assert.assertEquals(newStats.getNetworkReadKBs() - 
oldStats.getNetworkReadKBs(), metrics.getNetworkReadKBs(), 0);
 +        Assert.assertEquals(newStats.getNetworkWriteKBs() - 
oldStats.getNetworkWriteKBs(), metrics.getNetworkWriteKBs(), 0);
 +        Assert.assertEquals(newStats.getDiskReadIOs() - 
oldStats.getDiskReadIOs(), metrics.getDiskReadIOs(), 0);
 +        Assert.assertEquals(newStats.getDiskWriteIOs() - 
oldStats.getDiskWriteIOs(), metrics.getDiskWriteIOs(), 0);
 +        Assert.assertEquals(newStats.getDiskReadKBs() - 
oldStats.getDiskReadKBs(), metrics.getDiskReadKBs(), 0);
 +        Assert.assertEquals(newStats.getDiskWriteKBs() - 
oldStats.getDiskWriteKBs(), metrics.getDiskWriteKBs(), 0);
 +    }
++
+     @Test
+     public void createLinstorVdb() throws LibvirtException, 
InternalErrorException, URISyntaxException {
+         final Connect connect = Mockito.mock(Connect.class);
+ 
+         final int id = random.nextInt(65534);
+         final String name = "test-instance-1";
+ 
+         final int cpus = 2;
+         final int speed = 1024;
+         final int minRam = 256 * 1024;
+         final int maxRam = 512 * 1024;
+         final String os = "Ubuntu";
+         final String vncPassword = "mySuperSecretPassword";
+ 
+         final VirtualMachineTO to = new VirtualMachineTO(id, name, 
VirtualMachine.Type.User, cpus, speed, minRam,
+                 maxRam, BootloaderType.HVM, os, false, false, vncPassword);
+         to.setVncAddr("");
+         to.setArch("x86_64");
+         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
+         to.setVcpuMaxLimit(cpus + 1);
+         final HashMap<String, String> vmToDetails = new HashMap<>();
+         to.setDetails(vmToDetails);
+ 
+         String diskLinPath = "9ebe53c1-3d35-46e5-b7aa-6fc223ba0fcf";
+         final DiskTO diskTO = new DiskTO();
+         diskTO.setDiskSeq(1L);
+         diskTO.setType(Volume.Type.ROOT);
+         diskTO.setDetails(new HashMap<>());
+         diskTO.setPath(diskLinPath);
+ 
+         final PrimaryDataStoreTO primaryDataStoreTO = 
Mockito.mock(PrimaryDataStoreTO.class);
+         String pDSTOUUID = "9ebe53c1-3d35-46e5-b7aa-6fc223ac4fcf";
+         
when(primaryDataStoreTO.getPoolType()).thenReturn(StoragePoolType.Linstor);
+         when(primaryDataStoreTO.getUuid()).thenReturn(pDSTOUUID);
+ 
+         VolumeObjectTO dataTO = new VolumeObjectTO();
+ 
+         dataTO.setUuid("12be53c1-3d35-46e5-b7aa-6fc223ba0f34");
+         dataTO.setPath(diskTO.getPath());
+         dataTO.setDataStore(primaryDataStoreTO);
+         diskTO.setData(dataTO);
+         to.setDisks(new DiskTO[]{diskTO});
+ 
+         String path = "/dev/drbd1020";
+         final KVMStoragePoolManager storagePoolMgr = 
Mockito.mock(KVMStoragePoolManager.class);
+         final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
+         final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+ 
+         
when(libvirtComputingResourceSpy.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+         when(storagePool.getType()).thenReturn(StoragePoolType.Linstor);
+         when(storagePoolMgr.getPhysicalDisk(StoragePoolType.Linstor, 
pDSTOUUID, diskLinPath)).thenReturn(vol);
+         when(vol.getPath()).thenReturn(path);
+         when(vol.getPool()).thenReturn(storagePool);
+         when(vol.getFormat()).thenReturn(PhysicalDiskFormat.RAW);
+ 
+         // 1. test Bus: IDE and broken qemu version -> NO discard
+         
when(libvirtComputingResourceSpy.getHypervisorQemuVersion()).thenReturn(6000000L);
+         vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, 
DiskDef.DiskBus.IDE.name());
+         {
+             LibvirtVMDef vm = new LibvirtVMDef();
+             vm.addComp(new DevicesDef());
+             libvirtComputingResourceSpy.createVbd(connect, to, name, vm);
+ 
+             DiskDef rootDisk = vm.getDevices().getDisks().get(0);
+             assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
+             assertEquals(DiskDef.DiskBus.IDE, rootDisk.getBusType());
+             assertEquals(DiskDef.DiscardType.IGNORE, rootDisk.getDiscard());
+         }
+ 
+         // 2. test Bus: VIRTIO and broken qemu version -> discard unmap
+         vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, 
DiskDef.DiskBus.VIRTIO.name());
+         {
+             LibvirtVMDef vm = new LibvirtVMDef();
+             vm.addComp(new DevicesDef());
+             libvirtComputingResourceSpy.createVbd(connect, to, name, vm);
+ 
+             DiskDef rootDisk = vm.getDevices().getDisks().get(0);
+             assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
+             assertEquals(DiskDef.DiskBus.VIRTIO, rootDisk.getBusType());
+             assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
+         }
+ 
+         // 3. test Bus; IDE and "good" qemu version -> discard unmap
+         vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, 
DiskDef.DiskBus.IDE.name());
+         
when(libvirtComputingResourceSpy.getHypervisorQemuVersion()).thenReturn(7000000L);
+         {
+             LibvirtVMDef vm = new LibvirtVMDef();
+             vm.addComp(new DevicesDef());
+             libvirtComputingResourceSpy.createVbd(connect, to, name, vm);
+ 
+             DiskDef rootDisk = vm.getDevices().getDisks().get(0);
+             assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
+             assertEquals(DiskDef.DiskBus.IDE, rootDisk.getBusType());
+             assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
+         }
+ 
+         // 4. test Bus: VIRTIO and "good" qemu version -> discard unmap
+         vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, 
DiskDef.DiskBus.VIRTIO.name());
+         {
+             LibvirtVMDef vm = new LibvirtVMDef();
+             vm.addComp(new DevicesDef());
+             libvirtComputingResourceSpy.createVbd(connect, to, name, vm);
+ 
+             DiskDef rootDisk = vm.getDevices().getDisks().get(0);
+             assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
+             assertEquals(DiskDef.DiskBus.VIRTIO, rootDisk.getBusType());
+             assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
+         }
+     }
  }

Reply via email to