/*************************************************************************** * Copyright (c) 2012-2014 VMware, Inc. All Rights Reserved. * Licensed 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.vmware.bdd.service; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import mockit.Mock; import mockit.MockClass; import org.apache.log4j.Logger; import org.mockito.Mockito; import com.google.gson.internal.Pair; import com.vmware.aurora.composition.CreateVMFolderSP; import com.vmware.aurora.composition.CreateVmSP; import com.vmware.aurora.composition.DeleteVMFolderSP; import com.vmware.aurora.composition.concurrent.ExecutionResult; import com.vmware.aurora.composition.concurrent.Priority; import com.vmware.aurora.composition.concurrent.Scheduler; import com.vmware.aurora.composition.concurrent.Scheduler.ProgressCallback; import com.vmware.bdd.clone.spec.VmCreateSpec; import com.vmware.bdd.service.sp.ConfigIOShareSP; import com.vmware.bdd.service.sp.CreateResourcePoolSP; import com.vmware.bdd.service.sp.DeleteVmByIdSP; import com.vmware.bdd.service.sp.SetAutoElasticitySP; import com.vmware.bdd.service.sp.StartVmSP; import com.vmware.bdd.service.sp.StopVmSP; import com.vmware.vim.binding.vim.Folder; @MockClass(realClass = Scheduler.class) public class MockTmScheduler { private static final Logger logger = Logger.getLogger(MockTmScheduler.class); public enum VmOperation { CREATE_VM, CREATE_FOLDER, START_VM, STOP_VM, DELETE_VM, DELETE_FOLDER, RECONFIGURE_VM, CREATE_RP, AUTO_ELASTICITY } private static Map<VmOperation, Boolean> flag = new HashMap<VmOperation, Boolean>(); private static boolean resultIsNull = false; public static void cleanFlag() { flag.clear(); resultIsNull = false; } public static boolean isResultIsNull() { return resultIsNull; } public static void setResultIsNull(boolean resultIsNull) { MockTmScheduler.resultIsNull = resultIsNull; } public synchronized static boolean getFlag(VmOperation operation) { if (operation == null) { return true; } if (flag.get(operation) == null) { return true; } return flag.get(operation); } public synchronized static void setFlag(VmOperation operation, boolean success) { flag.put(operation, success); } private static VmOperation getOperation(Callable<Void> sp) { if (sp instanceof CreateVMFolderSP) { return VmOperation.CREATE_FOLDER; } else if (sp instanceof StartVmSP) { return VmOperation.START_VM; } else if (sp instanceof StopVmSP) { return VmOperation.STOP_VM; } else if (sp instanceof DeleteVMFolderSP) { return VmOperation.DELETE_FOLDER; } else if (sp instanceof DeleteVmByIdSP) { return VmOperation.DELETE_VM; } else if (sp instanceof CreateVmSP) { return VmOperation.CREATE_VM; } else if (sp instanceof ConfigIOShareSP) { return VmOperation.RECONFIGURE_VM; } else if (sp instanceof CreateResourcePoolSP) { return VmOperation.CREATE_RP; } else if (sp instanceof SetAutoElasticitySP) { return VmOperation.AUTO_ELASTICITY; } else { logger.error("unsupported vm opration: " + sp); return null; } } @Mock public static ExecutionResult[] executeStoredProcedures(Priority priority, Callable<Void>[] storedProcedures, ProgressCallback callback) throws InterruptedException { logger.info("mock method is invoked."); if (resultIsNull) { return null; } ExecutionResult[] result = new ExecutionResult[storedProcedures.length]; for (int i = 0; i < result.length; i++) { VmOperation operation = getOperation(storedProcedures[i]); boolean flag = getFlag(operation); ExecutionResult r = null; if (flag) { r = new ExecutionResult(true, null); if (operation == VmOperation.CREATE_FOLDER) { CreateVMFolderSP sp = (CreateVMFolderSP)storedProcedures[i]; setReturnFolder(sp); } else if (operation == VmOperation.CREATE_VM) { CreateVmSP sp = (CreateVmSP)storedProcedures[i]; setReturnVM(sp); } r = new ExecutionResult(true, null); } else { r = new ExecutionResult(true, new Throwable("test failure")); } result[i] = r; } return result; } private static void setReturnFolder(CreateVMFolderSP sp) { try { Folder folder = Mockito.mock(Folder.class); List<Folder> folders = new ArrayList<Folder>(); folders.add(folder); Field field = sp.getClass().getDeclaredField("folders"); field.setAccessible(true); field.set(sp, folders); } catch (Exception e) { logger.error("set return value failed.", e); } } private static void setReturnVM(CreateVmSP sp) { try { VmCreateSpec spec = Mockito.mock(VmCreateSpec.class); Mockito.when(spec.getVmName()).thenReturn("cluster-worker-0"); Mockito.when(spec.getVmId()).thenReturn("create-vm-succ"); Field field = sp.getClass().getDeclaredField("targetVmSpec"); field.setAccessible(true); field.set(sp, spec); } catch (Exception e) { logger.error("set return value failed.", e); } } @SuppressWarnings("unchecked") @Mock public static Pair<ExecutionResult, ExecutionResult>[] executeStoredProcedures(Priority priority, Pair<? extends Callable<Void>, ? extends Callable<Void>>[] storedProcedures, int numberOfFailuresAllowed, ProgressCallback callback) throws InterruptedException { logger.info("mock method is invoked."); if (resultIsNull) { return null; } VmOperation operation = getOperation(storedProcedures[0].first); boolean flag = getFlag(operation); Pair<ExecutionResult, ExecutionResult>[] result = new Pair[storedProcedures.length]; for (int i = 0; i < result.length; i++) { ExecutionResult f = null; ExecutionResult s = null; if (flag) { if (operation == VmOperation.CREATE_VM) { CreateVmSP sp = (CreateVmSP)storedProcedures[i].first; setReturnVM(sp); } f = new ExecutionResult(true, null); s = new ExecutionResult(false, null); } else { f = new ExecutionResult(true, new Throwable("Mock failure")); s = new ExecutionResult(true, null); } result[i] = new Pair<ExecutionResult, ExecutionResult>(f, s); } return result; } }