Kobi Ianko has uploaded a new change for review. Change subject: <core | restapi | tools | history | engine | userportal | webadmin>: short summary under 50 chars ......................................................................
<core | restapi | tools | history | engine | userportal | webadmin>: short summary under 50 chars Longer description using lines' length under 72 chars. With multiple paragraphs if necessary. Change-Id: Ibda0c843c9e997fad2fcdf634e1c40109ce32ff1 Bug-Url: https://bugzilla.redhat.com/?????? Signed-off-by: Kobi Ianko <[email protected]> --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/Defaults.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/PopulateFactory.java A backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/AbstractWeightPolicyUnitTest.java A backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/HaReservationWeightPolicyUnitTest.java 4 files changed, 410 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/55/25255/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/Defaults.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/Defaults.java new file mode 100644 index 0000000..bfc3aae --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/Defaults.java @@ -0,0 +1,38 @@ +package org.ovirt.engine.core.bll.scheduling.policyunits; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class Defaults { + private Defaults() { + } + + private static final Map<Class<?>, Object> DEFAULTS; + + static { + Map<Class<?>, Object> map = new HashMap<Class<?>, Object>(); + put(map, boolean.class, false); + put(map, char.class, '\0'); + put(map, byte.class, (byte) 0); + put(map, short.class, (short) 0); + put(map, int.class, 0); + put(map, long.class, 0L); + put(map, float.class, 0f); + put(map, double.class, 0d); + DEFAULTS = Collections.unmodifiableMap(map); + } + + private static <T> void put(Map<Class<?>, Object> map, Class<T> type, T value) { + map.put(type, value); + } + + /** + * Returns the default value of {@code type} as defined by JLS --- {@code 0} for numbers, {@code false} for + * {@code boolean} and {@code '\0'} for {@code char}. For non-primitive types and {@code void}, null is returned. + */ + @SuppressWarnings("unchecked") + public static <T> T defaultValue(Class<T> type) { + return (T) DEFAULTS.get(type); + } +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/PopulateFactory.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/PopulateFactory.java new file mode 100644 index 0000000..ee7b07b --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/PopulateFactory.java @@ -0,0 +1,135 @@ +package org.ovirt.engine.core.bll.scheduling.policyunits; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +public class PopulateFactory { + + private Map<Method, Object> methodValues = new HashMap<>(); + + public <T> T populate(Class<T> clazz, Map<Method, Object> methodValues) throws Exception { + this.methodValues = methodValues; + return populate(clazz); + } + + public <T> T populate(Class<T> clazz) throws Exception { + T mockObject = null; + + if (clazz.isPrimitive()) { + mockObject = handlePrimitives(clazz); + } else if (clazz.isEnum()) { + mockObject = getRandomEnumValue(clazz); + } else { + mockObject = createInstance(clazz, mockObject); + + if (mockObject != null) { + setDummyData(mockObject); + } + } + return mockObject; + } + + protected <T> T handlePrimitives(Class<T> clazz) { + T mockObject; + mockObject = Defaults.defaultValue(clazz); + return mockObject; + } + + protected <T> T createInstance(Class<T> clazz, T mockObject) throws InstantiationException, + IllegalAccessException { + try { + clazz.getConstructor(); + mockObject = clazz.newInstance(); + } catch (NoSuchMethodException e) { + + boolean isInvoked = false; + Constructor<T>[] ctors = (Constructor<T>[]) clazz.getConstructors(); + if (ctors != null) { + for (Constructor<T> ctor : ctors) { + Class[] paramClazzes = ctor.getParameterTypes(); + + List paramList = new ArrayList(); + try { + for (Class paramClass : paramClazzes) { + paramList.add(populate(paramClass)); + } + mockObject = ctor.newInstance(paramList.toArray()); + isInvoked = true; + break; + } catch (Throwable t) { + // FIXME: add debug message? + // could not invoke Ctor, will try another one + // t.printStackTrace(); + } + } + + } + + } + return mockObject; + } + + protected <T> T getRandomEnumValue(Class<T> clazz) { + T mockObject; + Random rand = new Random(); + int n = rand.nextInt(clazz.getEnumConstants().length - 1); + mockObject = clazz.getEnumConstants()[n]; + return mockObject; + } + + private <T> void setDummyData(T mockObject) throws Exception { + + final Method[] list = mockObject.getClass().getMethods(); + for (Method method : list) { + method.setAccessible(true); + if (Modifier.isPublic(method.getModifiers()) && method.getName().startsWith("set")) { + + if (methodValues.containsKey(method)) { + method.invoke(mockObject, methodValues.get(method)); + } else { + + final Class<?>[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 1) { + final Class<?> clazz = parameterTypes[0]; + if (clazz == String.class) { + method.invoke(mockObject, "Test String_" + System.currentTimeMillis()); + } else if (clazz.isPrimitive() && Defaults.defaultValue(clazz) != null) { + method.invoke(mockObject, Defaults.defaultValue(clazz)); + } else if (Collection.class.isAssignableFrom(clazz)) { + method.invoke(mockObject, createCollection(clazz)); + } else if (Map.class == (clazz)) { + method.invoke(mockObject, Collections.EMPTY_MAP); + } else /* if (clazz.getPackage().getName().contains("org.ovirt")) */{ + method.invoke(mockObject, populate(clazz)); + } + } + } + + } + } + + } + + protected Object createCollection(Class clazz) { + if(clazz.isInstance(List.class)) { + return Collections.EMPTY_LIST; + } + + if(clazz.isInstance(Set.class)) { + return Collections.EMPTY_SET; + } + return null; + } + + + +} diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/AbstractWeightPolicyUnitTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/AbstractWeightPolicyUnitTest.java new file mode 100644 index 0000000..8572701 --- /dev/null +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/AbstractWeightPolicyUnitTest.java @@ -0,0 +1,80 @@ +package org.ovirt.engine.core.bll.scheduling.policyunits; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; + +@RunWith(MockitoJUnitRunner.class) +public abstract class AbstractWeightPolicyUnitTest { + + @Mock + protected DbFacade dbFacadeMock; + + protected PolicyUnitImpl policyUnitImpl; + + protected int numOfHosts = 10; + + @Before + public void setup() { + + policyUnitImpl = Mockito.spy(setPolicyUnitImpl()); + // dbFacadeMock = Mockito.spy(setPathToDbFacade()); + + try { + Mockito.doReturn(dbFacadeMock) + .when(policyUnitImpl) + .getClass() + .getMethod("getDbFacade", null) + .invoke(policyUnitImpl, null); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException + | SecurityException e) { + + e.printStackTrace(); + } + + } + + @Test + public void testScoreMethod() { + List<Pair<Guid, Integer>> scores = policyUnitImpl.score(createVdsList(), createVm(), createParameters()); + boolean result = isScoreMethodTestSucceeded(scores); + Assert.assertTrue(result); + + } + + // protected abstract DbFacade setPathToDbFacade(); + + protected abstract PolicyUnitImpl setPolicyUnitImpl(); + + protected abstract VM createVm(); + + protected abstract Map<String, String> createParameters(); + + protected abstract VDS createVds(); + + protected List<VDS> createVdsList() { + List<VDS> listOfVds = new ArrayList<VDS>(numOfHosts); + for (int i = 0; i < numOfHosts; i++) { + listOfVds.add(createVds()); + } + return listOfVds; + } + + protected abstract boolean isScoreMethodTestSucceeded(List<Pair<Guid, Integer>> scores); + +} diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/HaReservationWeightPolicyUnitTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/HaReservationWeightPolicyUnitTest.java new file mode 100644 index 0000000..f53a0a9 --- /dev/null +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/policyunits/HaReservationWeightPolicyUnitTest.java @@ -0,0 +1,157 @@ +package org.ovirt.engine.core.bll.scheduling.policyunits; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.common.businessentities.VMStatus; +import org.ovirt.engine.core.common.businessentities.VmBase; +import org.ovirt.engine.core.common.businessentities.VmDynamic; +import org.ovirt.engine.core.common.config.ConfigValues; +import org.ovirt.engine.core.common.scheduling.PolicyUnit; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.compat.Version; +import org.ovirt.engine.core.dao.VdsGroupDAO; +import org.ovirt.engine.core.dao.VmDAO; +import org.ovirt.engine.core.utils.MockConfigRule; + +@RunWith(MockitoJUnitRunner.class) +public class HaReservationWeightPolicyUnitTest extends AbstractWeightPolicyUnitTest { + + @Rule + public MockConfigRule mockConfigRule = + new MockConfigRule((MockConfigRule.mockConfig(ConfigValues.MaxSchedulerWeight, 1000)) + , (MockConfigRule.mockConfig(ConfigValues.ScaleDownForHaReservation, 1)) + ); + + @Mock + VM vmMock; + + @Mock + VdsGroupDAO vdsGroupDaoMock; + + @Mock + VmDAO vmDaoMock; + + @Before + public void setUp() throws Exception { + super.setup(); + + Mockito.doReturn(vdsGroupDaoMock).when(dbFacadeMock).getVdsGroupDao(); + Mockito.doReturn(createVdsGroupMock()).when(vdsGroupDaoMock).get(Mockito.any(Guid.class)); + + Mockito.doReturn(vmDaoMock).when(dbFacadeMock).getVmDao(); + Mockito.doReturn(createVmsMock()).when(vmDaoMock).getAllForVdsGroup(Mockito.any(Guid.class)); + + Mockito.doReturn(true).when(vmMock).isAutoStartup(); + + } + + private VDSGroup createVdsGroupMock() { + VDSGroup vdsGroup = new VDSGroup(); + vdsGroup.setId(Guid.newGuid()); + vdsGroup.setName("Test"); + vdsGroup.setHaReservation(true); + + return vdsGroup; + } + + private List<VM> createVmsMock() { + List<VM> l = new ArrayList<>(); + + VM mockVM = null; + + try { + Map<Method, Object> m2v = new HashMap<>(); + m2v.put(Version.class.getMethod("setValue", String.class), "*"); + m2v.put(VmDynamic.class.getMethod("setStatus", VMStatus.class), VMStatus.Up); + m2v.put(VmBase.class.getMethod("setAutoStartup", boolean.class), true); + m2v.put(VmDynamic.class.getMethod("setRunOnVds", Guid.class), new Guid(FIRST_GUID)); + + for (int i = 0; i < 10; i++) { + mockVM = new PopulateFactory().populate(VM.class, m2v); + l.add(mockVM); + } + + m2v.put(VmDynamic.class.getMethod("setRunOnVds", Guid.class), new Guid(SECOND_GUID)); + for (int i = 0; i < 5; i++) { + mockVM = new PopulateFactory().populate(VM.class, m2v); + l.add(mockVM); + } + } catch (Throwable t) { + t.printStackTrace(); + } + return l; + } + + @Override + protected PolicyUnitImpl setPolicyUnitImpl() { + return new HaReservationWeightPolicyUnit(new PolicyUnit()); + } + + @Override + protected VM createVm() { + return vmMock; + } + + @Override + protected Map<String, String> createParameters() { + return new HashMap<String, String>(); + } + + @Override + protected VDS createVds() { + + VDS mockVds = null; + try { + Map<Method, Object> m2v = new HashMap<>(); + m2v.put(Version.class.getMethod("setValue", String.class), "*"); + mockVds = new PopulateFactory().populate(VDS.class, m2v); + } catch (Exception e) { + e.printStackTrace(); + } + return mockVds; + } + + @Override + protected boolean isScoreMethodTestSucceeded(List<Pair<Guid, Integer>> scores) { + + Integer firstScore = scores.get(0).getSecond(); + Integer secondScore = scores.get(1).getSecond(); + + return firstScore == secondScore * 2; + } + + private static final String FIRST_GUID = "ABC00000-0000-0000-0000-123456789ABC"; + private static final String SECOND_GUID = "CBA00000-0000-0000-0000-123456789CBA"; + + @Override + protected List<VDS> createVdsList() { + numOfHosts = 2; + List<VDS> l = new ArrayList<>(numOfHosts); + + VDS vds = createVds(); + vds.setId(new Guid(FIRST_GUID)); + l.add(vds); + + vds = createVds(); + vds.setId(new Guid(SECOND_GUID)); + l.add(vds); + + return l; + } + +} -- To view, visit http://gerrit.ovirt.org/25255 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibda0c843c9e997fad2fcdf634e1c40109ce32ff1 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Kobi Ianko <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
