package org.ovirt.engine.core.vdsbroker.vdsbroker;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.ovirt.engine.core.common.businessentities.LeaseStatus;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VmStatistics;
import org.ovirt.engine.core.common.businessentities.network.VmInterfaceType;
import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
import org.ovirt.engine.core.common.businessentities.storage.DiskImageDynamic;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.utils.serialization.json.JsonObjectDeserializer;
public class VdsBrokerObjectBuilderTest {
private static final long SIZE_FOR_DISK_STATS = 100L;
private static final Guid IMAGE_ID = Guid.createGuidFromString("ed185868-3f9e-4040-a340-e1a64726ebc0");
private static final Guid VM_ID = Guid.createGuidFromString("71ca53fb-c223-4b31-926d-de1c2ab0b0a9");
private static final String DEFAULT_VALUE = "0.00";
@Test
public void testDisksUsages() {
Object[] disksUsages = initDisksUsageData();
Map<String, Object> map = setDisksUsage(disksUsages);
validateDisksUsagesList(getVmStatistics(), disksUsages, map);
}
@Test
public void testEmptyDisksUsages() {
Object[] disksUsages = new Object[0];
Map<String, Object> xml = setDisksUsage(disksUsages);
validateDisksUsagesList(getVmStatistics(), disksUsages, xml);
}
@Test
public void testDisksUsagesWithEmptyEntry() {
Object[] disksUsages = initDisksUsageData();
disksUsages[1] = new HashMap<>();
Map<String, Object> xml = setDisksUsage(disksUsages);
validateDisksUsagesList(getVmStatistics(), disksUsages, xml);
}
@Test
public void testDisksUsagesWithNullEntry() {
Object[] disksUsages = initDisksUsageData();
disksUsages[1] = null;
Map<String, Object> xml = setDisksUsage(disksUsages);
validateDisksUsagesList(getVmStatistics(), disksUsages, xml);
}
@Test
public void testNullDisksUsages() {
VmStatistics vmStatistics = getVmStatistics();
Map<String, Object> xml = setDisksUsage(null);
VdsBrokerObjectsBuilder.updateVMStatisticsData(vmStatistics, xml);
assertNull(vmStatistics.getDisksUsage());
}
@Test
public void testFlushLatency() {
String doubleValue = "1";
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_flush_latency, doubleValue);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(new Double("0.000000001"), disks.get(0).getFlushLatency());
}
@Test
public void testReadLatency() {
String doubleValue = "2";
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_read_latency, doubleValue);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(new Double("0.000000002"), disks.get(0).getReadLatency());
}
@Test
public void testWriteLatency() {
String doubleValue = "3";
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_write_latency, doubleValue);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(new Double("0.000000003"), disks.get(0).getWriteLatency());
}
@Test
public void testOneSecondLatency() {
String doubleValue = "1000000000";
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_write_latency, doubleValue);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(new Double("1"), disks.get(0).getWriteLatency());
}
@Test
public void testZeroLatency() {
String doubleValue = "0";
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_write_latency, doubleValue);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(new Double("0"), disks.get(0).getWriteLatency());
}
@Test
public void testMaximumLatency() {
String doubleValue = "999999999000000000";
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_write_latency, doubleValue);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(new Double("999999999"), disks.get(0).getWriteLatency());
}
@Test
public void testNullValuesLatency() {
Map<String, Object> diskData = setDiskData();
diskData.put(VdsProperties.vm_disk_write_latency, null);
diskData.put(VdsProperties.vm_disk_read_latency, null);
diskData.put(VdsProperties.vm_disk_flush_latency, null);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertEquals(disks.get(0).getWriteLatency(), new Double(DEFAULT_VALUE));
assertEquals(disks.get(0).getReadLatency(), new Double(DEFAULT_VALUE));
assertEquals(disks.get(0).getFlushLatency(), new Double(DEFAULT_VALUE));
}
@Test
public void testWhenVDSMNotSendingFields() {
Map<String, Object> diskData = new HashMap<>();
diskData.put(VdsProperties.vm_disk_read_rate, DEFAULT_VALUE);
diskData.put(VdsProperties.ImageId, IMAGE_ID.toString());
diskData.put(VdsProperties.vm_disk_write_rate, DEFAULT_VALUE);
// Set the default values to the fields.
diskData.put(VdsProperties.vm_disk_flush_latency, DEFAULT_VALUE);
Map<String, Object> xml = setMockForTesting(diskData);
List<DiskImageDynamic> disks = VdsBrokerObjectsBuilder.buildVmDiskStatistics(xml);
assertNull(disks.get(0).getWriteLatency());
assertNull(disks.get(0).getReadLatency());
assertEquals(disks.get(0).getFlushLatency(), new Double(DEFAULT_VALUE));
}
@Test
public void testDiskStats() {
Map<String, Object> disksStats = new HashMap<>();
Map<String, Object> disk = new HashMap<>();
disk.put(VdsProperties.DISK_STATS_FREE, SIZE_FOR_DISK_STATS);
disksStats.put("a", disk);
disksStats.put("b", disk);
Map<String, Object> xml = setDisksStats(disksStats);
validateDisksStatsList(getVds(), xml, false);
}
@Test
public void testEmptyDiskStats() {
Map<String, Object> disksStats = new HashMap<>();
Map<String, Object> xml = setDisksStats(disksStats);
validateDisksStatsList(getVds(), xml, false);
}
@Test
public void testNoDiskStats() {
VDS vds = getVds();
VdsBrokerObjectsBuilder.updateLocalDisksUsage(vds, new HashMap<>());
assertNull(vds.getLocalDisksUsage());
}
@Test
public void testNoDiskStatsDataForDisks() {
Map<String, Object> disksStats = new HashMap<>();
Map<String, Object> disk = new HashMap<>();
disksStats.put("a", disk);
disksStats.put("b", disk);
Map<String, Object> xml = setDisksStats(disksStats);
validateDisksStatsList(getVds(), xml, true);
}
@Test
public void testAddNicWithId(){
String nicId = Guid.newGuid().toString();
Map<String, Object> vmStruct = createNicDeviceStruct(nicId);
validateVmNetworkInterfaceId(nicId, vmStruct);
}
@Test
public void testAddNicWithNullId(){
String nicId = null;
Map<String, Object> vmStruct = createNicDeviceStruct(nicId);
validateVmNetworkInterfaceId(nicId, vmStruct);
}
private Map<String, Object> createNicDeviceStruct(String nicId) {
Map<String, Object> device = new HashMap<>();
device.put(VdsProperties.DeviceId, nicId);
device.put(VdsProperties.Type, VdsProperties.VM_INTERFACE_DEVICE_TYPE);
device.put(VdsProperties.NIC_TYPE, VmInterfaceType.e1000.getInternalName());
Object[] devices = new Object[1];
devices[0] = device;
Map<String, Object> vmStruct = new HashMap<>();
vmStruct.put(VdsProperties.Devices, devices);
return vmStruct;
}
private void validateVmNetworkInterfaceId(String nicId, Map<String, Object> vmStruct) {
List<VmNetworkInterface> vmNetworkInterfaceList = VdsBrokerObjectsBuilder.buildVmNetworkInterfacesFromDevices(vmStruct);
assertNotNull(vmNetworkInterfaceList);
assertEquals(1, vmNetworkInterfaceList.size());
VmNetworkInterface vmNetworkInterface = vmNetworkInterfaceList.get(0);
assertEquals(Guid.createGuidFromString(nicId), vmNetworkInterface.getId());
}
private static void validateDisksUsagesList(VmStatistics vmStatistics, Object[] disksUsages, Map<String, Object> xml) {
VdsBrokerObjectsBuilder.updateVMStatisticsData(vmStatistics, xml);
assertEquals(Arrays.asList(disksUsages),
new JsonObjectDeserializer().deserializeUnformattedJson(vmStatistics.getDisksUsage(), ArrayList.class));
}
private static void validateDisksStatsList(VDS vds, Map<String, Object> xml, boolean assertNullValues) {
VdsBrokerObjectsBuilder.updateLocalDisksUsage(vds, xml);
assertNotNull(vds.getLocalDisksUsage());
for (Long usage : vds.getLocalDisksUsage().values()) {
if (assertNullValues) {
assertNull(usage);
} else {
assertEquals(SIZE_FOR_DISK_STATS, usage.longValue());
}
}
}
private static Map<String, Object> setMockForTesting(Map<String, Object> diskData) {
Map<String, Map<String, Object>> disksData = new HashMap<>();
disksData.put("vda", diskData);
return setDisks(disksData);
}
private static VDS getVds() {
return new VDS();
}
private static VmStatistics getVmStatistics() {
VmStatistics vmStatistics = new VmStatistics();
vmStatistics.setId(VM_ID);
return vmStatistics;
}
private static Map<String, Object> setDisks(Map<String, Map<String, Object>> disksData) {
Map<String, Object> map = new HashMap<>();
map.put(VdsProperties.vm_disks, disksData);
return map;
}
private static Map<String, Object> setDisksUsage(Object[] disksUsageData) {
Map<String, Object> map = new HashMap<>();
map.put(VdsProperties.VM_DISKS_USAGE, disksUsageData);
return map;
}
private static Map<String, Object> setDisksStats(Object disksStatsData) {
Map<String, Object> map = new HashMap<>();
map.put(VdsProperties.DISK_STATS, disksStatsData);
return map;
}
private static Map<String, Object> setDiskData() {
Map<String, Object> diskData = new HashMap<>();
diskData.put(VdsProperties.vm_disk_read_rate, DEFAULT_VALUE);
diskData.put(VdsProperties.ImageId, IMAGE_ID.toString());
diskData.put(VdsProperties.vm_disk_write_rate, DEFAULT_VALUE);
// Set the default values to the fields.
diskData.put(VdsProperties.vm_disk_flush_latency, DEFAULT_VALUE);
diskData.put(VdsProperties.vm_disk_write_latency, DEFAULT_VALUE);
diskData.put(VdsProperties.vm_disk_read_latency, DEFAULT_VALUE);
return diskData;
}
private static Object[] initDisksUsageData() {
Object[] disksUsage = new Object[2];
disksUsage[0] = getDiskUsageAsMap("11704201216", "FAT32", "c:\\", "9516027904");
disksUsage[1] = getDiskUsageAsMap("133543936", "CDFS", "d:\\", "133543936");
return disksUsage;
}
private static Map<String, String> getDiskUsageAsMap(String total, String fs, String path, String used) {
Map<String, String> diskUsage = new HashMap<>();
diskUsage.put("total", total);
diskUsage.put("fs", fs);
diskUsage.put("path", path);
diskUsage.put("used", used);
return diskUsage;
}
@Test
public void leaseFree() {
assertTrue(getLeaseStatus(new Object[0]).isFree());
}
@Test
public void leaseNotFreeMultipleOwners() {
Object[] owners = { 1, 2, 3 }; // Currently not expected to happen
assertFalse(getLeaseStatus(owners).isFree());
}
@Test
public void leaseNotFreeSingleOwner() {
Object[] owners = { 1 };
assertFalse(getLeaseStatus(owners).isFree());
}
private LeaseStatus getLeaseStatus(Object[] owners) {
return VdsBrokerObjectsBuilder.buildLeaseStatus(Collections.singletonMap("owners", owners));
}
}