Updated Branches: refs/heads/vmsync 86053cd8b -> 17930685e
Unit tests to VM work scheduling Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/17930685 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/17930685 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/17930685 Branch: refs/heads/vmsync Commit: 17930685e443e6291e18e36a0d175dd04bc9522c Parents: 86053cd Author: Kelven Yang <[email protected]> Authored: Wed May 1 16:43:05 2013 -0700 Committer: Kelven Yang <[email protected]> Committed: Wed May 1 16:43:05 2013 -0700 ---------------------------------------------------------------------- client/tomcatconf/applicationContext.xml.in | 3 + server/src/com/cloud/async/AsyncJobManager.java | 2 +- .../src/com/cloud/async/AsyncJobManagerImpl.java | 40 ++- .../com/cloud/async/dao/SyncQueueItemDaoImpl.java | 2 +- server/src/com/cloud/vm/VmWorkJobDispatcher.java | 52 ++- .../com/cloud/async/AsyncJobTestConfiguration.java | 7 + .../cloud/async/MockVirtualMachineManagerImpl.java | 387 ++++++++++++++ .../test/com/cloud/async/TestAsyncJobManager.java | 4 +- .../vm/VmWorkMockVirtualMachineManagerImpl.java | 390 +++++++++++++++ server/test/com/cloud/vm/VmWorkTest.java | 87 +++- .../test/com/cloud/vm/VmWorkTestConfiguration.java | 106 ++++ server/test/resources/VmWorkTestContext.xml | 54 ++ 12 files changed, 1118 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/client/tomcatconf/applicationContext.xml.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index e12ded8..206d890 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -801,6 +801,9 @@ <bean id="ApiAsyncJobDispatcher" class="com.cloud.api.ApiAsyncJobDispatcher"> <property name="name" value="ApiAsyncJobDispatcher" /> </bean> + <bean id="VmWorkJobDispatcher" class="com.cloud.vm.VmWorkJobDispatcher"> + <property name="name" value="VmWorkJobDispatcher" /> + </bean> <!-- Baremetal components http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/src/com/cloud/async/AsyncJobManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/async/AsyncJobManager.java b/server/src/com/cloud/async/AsyncJobManager.java index 668528b..fc8de18 100644 --- a/server/src/com/cloud/async/AsyncJobManager.java +++ b/server/src/com/cloud/async/AsyncJobManager.java @@ -31,6 +31,7 @@ public interface AsyncJobManager extends Manager { public long submitAsyncJob(AsyncJob job); public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext); + public long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId); public AsyncJobResult queryAsyncJobResult(long jobId); public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject); @@ -38,7 +39,6 @@ public interface AsyncJobManager extends Manager { public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId); public void releaseSyncSource(); - public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit); public boolean waitAndCheck(String[] wakupSubjects, long checkIntervalInMilliSeconds, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/src/com/cloud/async/AsyncJobManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java index 8b3d877..e2a65b7 100644 --- a/server/src/com/cloud/async/AsyncJobManagerImpl.java +++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java @@ -145,6 +145,29 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } } + @SuppressWarnings("unchecked") + @Override @DB + public long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId) { + Transaction txt = Transaction.currentTxn(); + try { + @SuppressWarnings("rawtypes") + GenericDao dao = GenericDaoBase.getDao(job.getClass()); + + txt.start(); + job.setInitMsid(getMsid()); + dao.persist(job); + + syncAsyncJobExecution(job, syncObjType, syncObjId, 1); + txt.commit(); + return job.getId(); + } catch(Exception e) { + txt.rollback(); + String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception."; + s_logger.warn(errMsg, e); + throw new CloudRuntimeException(errMsg); + } + } + @Override @DB public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject) { if(s_logger.isDebugEnabled()) { @@ -232,7 +255,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, txt.start(); AsyncJobVO job = _jobDao.createForUpdate(); - //job.setInstanceType(instanceType); + job.setInstanceType(instanceType); job.setInstanceId(instanceId); job.setLastUpdated(DateUtil.currentGMTTime()); _jobDao.update(jobId, job); @@ -243,7 +266,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, txt.rollback(); } } - + @Override public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) { if(s_logger.isDebugEnabled()) { @@ -458,7 +481,8 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } job.setSyncSource(item); - + + job.setExecutingMsid(getMsid()); job.setCompleteMsid(getMsid()); _jobDao.update(job.getId(), job); @@ -467,6 +491,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } catch(RejectedExecutionException e) { s_logger.warn("Execution for job-" + job.getId() + " is rejected, return it to the queue for next turn"); _queueMgr.returnItem(item.getId()); + } finally { + job.setExecutingMsid(null); + _jobDao.update(job.getId(), job); } } else { @@ -538,6 +565,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, return new Runnable() { @Override public void run() { + Transaction txn = Transaction.open("AsyncJobManagerImpl.getHeartbeatTask"); try { List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE); if(l != null && l.size() > 0) { @@ -550,6 +578,12 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } } catch(Throwable e) { s_logger.error("Unexpected exception when trying to execute queue item, ", e); + } finally { + try { + txn.close(); + } catch(Throwable e) { + s_logger.error("Unexpected exception", e); + } } } }; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java b/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java index 29eb841..7c9bf5b 100644 --- a/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java +++ b/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java @@ -77,7 +77,7 @@ public class SyncQueueItemDaoImpl extends GenericDaoBase<SyncQueueItemVO, Long> String sql = "SELECT i.id, i.queue_id, i.content_type, i.content_id, i.created " + " FROM sync_queue AS q JOIN sync_queue_item AS i ON q.id = i.queue_id " + - " WHERE q.queue_size < q.queue_size_limit AND i.queue_proc_number IS NULL " + + " WHERE q.queue_size <= q.queue_size_limit AND i.queue_proc_number IS NULL " + " GROUP BY q.id " + " ORDER BY i.id " + " LIMIT 0, ?"; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/src/com/cloud/vm/VmWorkJobDispatcher.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/VmWorkJobDispatcher.java b/server/src/com/cloud/vm/VmWorkJobDispatcher.java index bd31dd9..4ab4aa0 100644 --- a/server/src/com/cloud/vm/VmWorkJobDispatcher.java +++ b/server/src/com/cloud/vm/VmWorkJobDispatcher.java @@ -16,8 +16,14 @@ // under the License. package com.cloud.vm; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + import javax.inject.Inject; +import org.apache.log4j.Logger; + import com.cloud.api.ApiSerializerHelper; import com.cloud.async.AsyncJob; import com.cloud.async.AsyncJobDispatcher; @@ -29,30 +35,66 @@ import com.cloud.user.dao.AccountDao; import com.cloud.utils.component.AdapterBase; public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatcher { + private static final Logger s_logger = Logger.getLogger(VmWorkJobDispatcher.class); @Inject private VirtualMachineManager _vmMgr; @Inject private AsyncJobManager _asyncJobMgr; @Inject private AccountDao _accountDao; + + private Map<String, Method> _handlerMap = new HashMap<String, Method>(); @Override public void RunJob(AsyncJob job) { try { + String cmd = job.getCmd(); + assert(cmd != null); + VmWork work = (VmWork)ApiSerializerHelper.fromSerializedString(job.getCmdInfo()); assert(work != null); AccountVO account = _accountDao.findById(work.getAccountId()); - UserContext.registerContext(work.getUserId(), account, null, false); + assert(account != null); + UserContext.registerContext(work.getUserId(), account, null, false); try { - - - _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, null); + Method handler = getHandler(cmd); + if(handler != null) { + handler.invoke(_vmMgr, work); + _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, null); + } else { + _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_FAILED, 0, null); + } } finally { UserContext.unregisterContext(); } - } catch(Throwable e) { _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_FAILED, 0, null); } } + + private Method getHandler(String cmd) { + + synchronized(_handlerMap) { + Method method = _handlerMap.get(cmd); + if(method != null) + return method; + + Class<?> clz = _vmMgr.getClass(); + try { + method = clz.getMethod(cmd, VmWork.class); + method.setAccessible(true); + } catch (SecurityException e) { + assert(false); + s_logger.error("Unexpected exception", e); + return null; + } catch (NoSuchMethodException e) { + assert(false); + s_logger.error("Unexpected exception", e); + return null; + } + + _handlerMap.put(cmd, method); + return method; + } + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/com/cloud/async/AsyncJobTestConfiguration.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/async/AsyncJobTestConfiguration.java b/server/test/com/cloud/async/AsyncJobTestConfiguration.java index bcc98b2..9baff59 100644 --- a/server/test/com/cloud/async/AsyncJobTestConfiguration.java +++ b/server/test/com/cloud/async/AsyncJobTestConfiguration.java @@ -33,6 +33,8 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dao.EntityManager; import com.cloud.user.AccountManager; import com.cloud.user.dao.AccountDao; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineManagerImpl; @Configuration public class AsyncJobTestConfiguration { @@ -91,4 +93,9 @@ public class AsyncJobTestConfiguration { public ConfigurationManager configurationManager() { return Mockito.mock(ConfigurationManager.class); } + + @Bean + public VirtualMachineManager virtualMachineManager() { + return Mockito.mock(VirtualMachineManager.class); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/com/cloud/async/MockVirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/async/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/async/MockVirtualMachineManagerImpl.java new file mode 100644 index 0000000..4566e8b --- /dev/null +++ b/server/test/com/cloud/async/MockVirtualMachineManagerImpl.java @@ -0,0 +1,387 @@ +// 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.async; + +import java.net.URI; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.ManagementServerException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.VirtualMachineMigrationException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; +import com.cloud.network.dao.NetworkVO; +import com.cloud.offering.ServiceOffering; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateVO; +import com.cloud.user.Account; +import com.cloud.user.User; +import com.cloud.utils.Pair; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.Event; +import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineGuru; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; + +public class MockVirtualMachineManagerImpl implements VirtualMachineManager { + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setName(String name) { + // TODO Auto-generated method stub + + } + + @Override + public void setConfigParams(Map<String, Object> params) { + // TODO Auto-generated method stub + + } + + @Override + public Map<String, Object> getConfigParams() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getRunLevel() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void setRunLevel(int level) { + // TODO Auto-generated method stub + + } + + @Override + public boolean configure(String name, Map<String, Object> params) + throws ConfigurationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean start() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean stop() { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> T allocate(T vm, VMTemplateVO template, + ServiceOfferingVO serviceOffering, + Pair<? extends DiskOfferingVO, Long> rootDiskOffering, + List<Pair<DiskOfferingVO, Long>> dataDiskOfferings, + List<Pair<NetworkVO, NicProfile>> networks, + Map<Param, Object> params, DeploymentPlan plan, + HypervisorType hyperType, Account owner) + throws InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T allocate(T vm, VMTemplateVO template, + ServiceOfferingVO serviceOffering, Long rootSize, + Pair<DiskOfferingVO, Long> dataDiskOffering, + List<Pair<NetworkVO, NicProfile>> networks, DeploymentPlan plan, + HypervisorType hyperType, Account owner) + throws InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T allocate(T vm, VMTemplateVO template, + ServiceOfferingVO serviceOffering, + List<Pair<NetworkVO, NicProfile>> networkProfiles, + DeploymentPlan plan, HypervisorType hyperType, Account owner) + throws InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T start(T vm, Map<Param, Object> params, + User caller, Account account) throws InsufficientCapacityException, + ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T start(T vm, Map<Param, Object> params, + User caller, Account account, DeploymentPlan planToDeploy) + throws InsufficientCapacityException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> boolean stop(T vm, User caller, + Account account) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean expunge(T vm, User caller, + Account account) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> void registerGuru(Type type, + VirtualMachineGuru<T> guru) { + // TODO Auto-generated method stub + + } + + @Override + public Collection<VirtualMachineGuru<? extends VMInstanceVO>> getRegisteredGurus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean stateTransitTo(VMInstanceVO vm, Event e, Long hostId) + throws NoTransitionException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> T advanceStart(T vm, + Map<Param, Object> params, User caller, Account account) + throws InsufficientCapacityException, ResourceUnavailableException, + ConcurrentOperationException, OperationTimedoutException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T advanceStart(T vm, + Map<Param, Object> params, User caller, Account account, + DeploymentPlan planToDeploy) throws InsufficientCapacityException, + ResourceUnavailableException, ConcurrentOperationException, + OperationTimedoutException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> boolean advanceStop(T vm, boolean forced, + User caller, Account account) throws ResourceUnavailableException, + OperationTimedoutException, ConcurrentOperationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean advanceExpunge(T vm, User caller, + Account account) throws ResourceUnavailableException, + OperationTimedoutException, ConcurrentOperationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean remove(T vm, User caller, + Account account) { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean destroy(T vm, User caller, + Account account) throws AgentUnavailableException, + OperationTimedoutException, ConcurrentOperationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean migrateAway(Type type, long vmid, long hostId) + throws InsufficientServerCapacityException, + VirtualMachineMigrationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> T migrate(T vm, long srcHostId, + DeployDestination dest) throws ResourceUnavailableException, + ConcurrentOperationException, ManagementServerException, + VirtualMachineMigrationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T reboot(T vm, Map<Param, Object> params, + User caller, Account account) throws InsufficientCapacityException, + ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T advanceReboot(T vm, + Map<Param, Object> params, User caller, Account account) + throws InsufficientCapacityException, ResourceUnavailableException, + ConcurrentOperationException, OperationTimedoutException { + // TODO Auto-generated method stub + return null; + } + + @Override + public VMInstanceVO findByIdAndType(Type type, long vmId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isVirtualMachineUpgradable(VirtualMachine vm, + ServiceOffering offering) { + // TODO Auto-generated method stub + return false; + } + + @Override + public VMInstanceVO findById(long vmId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T storageMigration(T vm, + StoragePool storagePoolId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void checkIfCanUpgrade(VirtualMachine vmInstance, + long newServiceOfferingId) { + // TODO Auto-generated method stub + + } + + @Override + public boolean upgradeVmDb(long vmId, long serviceOfferingId) { + // TODO Auto-generated method stub + return false; + } + + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, + NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean removeNicFromVm(VirtualMachine vm, NicVO nic) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, + URI broadcastUri) throws ConcurrentOperationException, + ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + // TODO Auto-generated method stub + return null; + } + + @Override + public VirtualMachineTO toVmTO( + VirtualMachineProfile<? extends VMInstanceVO> profile) { + // TODO Auto-generated method stub + return null; + } + + @Override + public VMInstanceVO reConfigureVm(VMInstanceVO vm, + ServiceOffering newServiceOffering, boolean sameHost) + throws ResourceUnavailableException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public VMInstanceVO findHostAndMigrate(Type vmType, VMInstanceVO vm, + Long newSvcOfferingId) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException, + VirtualMachineMigrationException, ManagementServerException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, + DeployDestination dest, Long newSvcOfferingId) + throws ResourceUnavailableException, ConcurrentOperationException, + ManagementServerException, VirtualMachineMigrationException { + // TODO Auto-generated method stub + return null; + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/com/cloud/async/TestAsyncJobManager.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/async/TestAsyncJobManager.java b/server/test/com/cloud/async/TestAsyncJobManager.java index 7a0840a..e6987ad 100644 --- a/server/test/com/cloud/async/TestAsyncJobManager.java +++ b/server/test/com/cloud/async/TestAsyncJobManager.java @@ -42,7 +42,7 @@ public class TestAsyncJobManager extends TestCase { @Inject AsyncJobManager asyncMgr; @Inject ClusterManager clusterMgr; @Inject MessageBus messageBus; - + @Before public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -57,7 +57,7 @@ public class TestAsyncJobManager extends TestCase { } @Test - public void test() { + public void testWaitAndCheck() { Thread thread = new Thread(new Runnable() { @Override public void run() { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java new file mode 100644 index 0000000..4216aff --- /dev/null +++ b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java @@ -0,0 +1,390 @@ +// 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.vm; + +import java.net.URI; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.framework.async.Void; +import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.PublishScope; + +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.ManagementServerException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.VirtualMachineMigrationException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; +import com.cloud.network.dao.NetworkVO; +import com.cloud.offering.ServiceOffering; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateVO; +import com.cloud.user.Account; +import com.cloud.user.User; +import com.cloud.utils.Pair; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.vm.VirtualMachine.Event; +import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile.Param; + +public class VmWorkMockVirtualMachineManagerImpl implements VirtualMachineManager { + + @Inject MessageBus _msgBus; + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setName(String name) { + // TODO Auto-generated method stub + } + + @Override + public void setConfigParams(Map<String, Object> params) { + // TODO Auto-generated method stub + + } + + @Override + public Map<String, Object> getConfigParams() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getRunLevel() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void setRunLevel(int level) { + // TODO Auto-generated method stub + + } + + @Override + public boolean configure(String name, Map<String, Object> params) + throws ConfigurationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean start() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean stop() { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> T allocate(T vm, VMTemplateVO template, + ServiceOfferingVO serviceOffering, + Pair<? extends DiskOfferingVO, Long> rootDiskOffering, + List<Pair<DiskOfferingVO, Long>> dataDiskOfferings, + List<Pair<NetworkVO, NicProfile>> networks, + Map<Param, Object> params, DeploymentPlan plan, + HypervisorType hyperType, Account owner) + throws InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T allocate(T vm, VMTemplateVO template, + ServiceOfferingVO serviceOffering, Long rootSize, + Pair<DiskOfferingVO, Long> dataDiskOffering, + List<Pair<NetworkVO, NicProfile>> networks, DeploymentPlan plan, + HypervisorType hyperType, Account owner) + throws InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T allocate(T vm, VMTemplateVO template, + ServiceOfferingVO serviceOffering, + List<Pair<NetworkVO, NicProfile>> networkProfiles, + DeploymentPlan plan, HypervisorType hyperType, Account owner) + throws InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T start(T vm, Map<Param, Object> params, + User caller, Account account) throws InsufficientCapacityException, + ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T start(T vm, Map<Param, Object> params, + User caller, Account account, DeploymentPlan planToDeploy) + throws InsufficientCapacityException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> boolean stop(T vm, User caller, + Account account) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean expunge(T vm, User caller, + Account account) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> void registerGuru(Type type, + VirtualMachineGuru<T> guru) { + // TODO Auto-generated method stub + + } + + @Override + public Collection<VirtualMachineGuru<? extends VMInstanceVO>> getRegisteredGurus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean stateTransitTo(VMInstanceVO vm, Event e, Long hostId) + throws NoTransitionException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> T advanceStart(T vm, + Map<Param, Object> params, User caller, Account account) + throws InsufficientCapacityException, ResourceUnavailableException, + ConcurrentOperationException, OperationTimedoutException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T advanceStart(T vm, + Map<Param, Object> params, User caller, Account account, + DeploymentPlan planToDeploy) throws InsufficientCapacityException, + ResourceUnavailableException, ConcurrentOperationException, + OperationTimedoutException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> boolean advanceStop(T vm, boolean forced, + User caller, Account account) throws ResourceUnavailableException, + OperationTimedoutException, ConcurrentOperationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean advanceExpunge(T vm, User caller, + Account account) throws ResourceUnavailableException, + OperationTimedoutException, ConcurrentOperationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean remove(T vm, User caller, + Account account) { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> boolean destroy(T vm, User caller, + Account account) throws AgentUnavailableException, + OperationTimedoutException, ConcurrentOperationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean migrateAway(Type type, long vmid, long hostId) + throws InsufficientServerCapacityException, + VirtualMachineMigrationException { + // TODO Auto-generated method stub + return false; + } + + @Override + public <T extends VMInstanceVO> T migrate(T vm, long srcHostId, + DeployDestination dest) throws ResourceUnavailableException, + ConcurrentOperationException, ManagementServerException, + VirtualMachineMigrationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T reboot(T vm, Map<Param, Object> params, + User caller, Account account) throws InsufficientCapacityException, + ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T advanceReboot(T vm, + Map<Param, Object> params, User caller, Account account) + throws InsufficientCapacityException, ResourceUnavailableException, + ConcurrentOperationException, OperationTimedoutException { + // TODO Auto-generated method stub + return null; + } + + @Override + public VMInstanceVO findByIdAndType(Type type, long vmId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isVirtualMachineUpgradable(VirtualMachine vm, + ServiceOffering offering) { + // TODO Auto-generated method stub + return false; + } + + @Override + public VMInstanceVO findById(long vmId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T storageMigration(T vm, + StoragePool storagePoolId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void checkIfCanUpgrade(VirtualMachine vmInstance, + long newServiceOfferingId) { + // TODO Auto-generated method stub + + } + + @Override + public boolean upgradeVmDb(long vmId, long serviceOfferingId) { + // TODO Auto-generated method stub + return false; + } + + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, + NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean removeNicFromVm(VirtualMachine vm, NicVO nic) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, + URI broadcastUri) throws ConcurrentOperationException, + ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + // TODO Auto-generated method stub + return null; + } + + @Override + public VirtualMachineTO toVmTO( + VirtualMachineProfile<? extends VMInstanceVO> profile) { + // TODO Auto-generated method stub + return null; + } + + @Override + public VMInstanceVO reConfigureVm(VMInstanceVO vm, + ServiceOffering newServiceOffering, boolean sameHost) + throws ResourceUnavailableException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public VMInstanceVO findHostAndMigrate(Type vmType, VMInstanceVO vm, + Long newSvcOfferingId) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException, + VirtualMachineMigrationException, ManagementServerException { + // TODO Auto-generated method stub + return null; + } + + @Override + public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, + DeployDestination dest, Long newSvcOfferingId) + throws ResourceUnavailableException, ConcurrentOperationException, + ManagementServerException, VirtualMachineMigrationException { + // TODO Auto-generated method stub + return null; + } + + public Void doVmWorkStart(VmWork work) { + _msgBus.publish(null, "Done", PublishScope.GLOBAL, null); + return null; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/com/cloud/vm/VmWorkTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/VmWorkTest.java b/server/test/com/cloud/vm/VmWorkTest.java index cbb768a..f16cec1 100644 --- a/server/test/com/cloud/vm/VmWorkTest.java +++ b/server/test/com/cloud/vm/VmWorkTest.java @@ -16,21 +16,76 @@ // under the License. package com.cloud.vm; +import java.sql.SQLException; +import java.sql.Statement; import java.util.HashMap; import java.util.Map; +import javax.inject.Inject; + +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import junit.framework.TestCase; +import com.cloud.api.ApiSerializerHelper; +import com.cloud.async.AsyncJobManager; +import com.cloud.cluster.ClusterManager; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; +import com.cloud.utils.LogUtils; +import com.cloud.utils.Predicate; +import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.db.Transaction; +import com.cloud.vm.VmWorkJobVO.Step; import com.google.gson.Gson; +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/VmWorkTestContext.xml") public class VmWorkTest extends TestCase { - Gson gson = new Gson(); + @Inject AsyncJobManager _jobMgr; + @Inject VirtualMachineManager _vmMgr; + @Inject ClusterManager _clusterMgr; + @Inject VmWorkJobDao _vmworkJobDao; + + Gson _gson = new Gson(); + + @Before + public void setup() { + LogUtils.initLog4j("cloud-log4j.xml"); + ComponentContext.initComponentsLifeCycle(); + _vmMgr = Mockito.spy(_vmMgr); + Mockito.when(_clusterMgr.getManagementNodeId()).thenReturn(1L); + + Transaction.open("dummy"); + + // drop constraint check in order to do single table test + Statement stat = null; + try { + stat = Transaction.currentTxn().getConnection().createStatement(); + stat.execute("SET foreign_key_checks = 0;"); + } catch (SQLException e) { + } finally { + if(stat != null) { + try { + stat.close(); + } catch (SQLException e) { + } + } + } + } + + @After + public void tearDown() { + Transaction.currentTxn().close(); + } @Test public void testDeployPlanSerialization() { @@ -40,8 +95,8 @@ public class VmWorkTest extends TestCase { excludeList.addCluster(1); plan.setAvoids(excludeList); - String json = gson.toJson(plan); - DeploymentPlan planClone = gson.fromJson(json, DataCenterDeployment.class); + String json = _gson.toJson(plan); + DeploymentPlan planClone = _gson.fromJson(json, DataCenterDeployment.class); Assert.assertTrue(planClone.getDataCenterId() == plan.getDataCenterId()); } @@ -53,9 +108,33 @@ public class VmWorkTest extends TestCase { params.put(VirtualMachineProfile.Param.ControlNic, new Long(100)); work.setParams(params); - VmWorkStart workClone = gson.fromJson(gson.toJson(work), VmWorkStart.class); + VmWorkStart workClone = _gson.fromJson(_gson.toJson(work), VmWorkStart.class); Assert.assertTrue(work.getParams().size() == workClone.getParams().size()); Assert.assertTrue(work.getParams().get(VirtualMachineProfile.Param.HaTag).equals(workClone.getParams().get(VirtualMachineProfile.Param.HaTag))); + } + + @Test + public void testVmWorkDispatcher() { + VmWorkJobVO workJob = new VmWorkJobVO(); + workJob.setDispatcher("VmWorkJobDispatcher"); + workJob.setCmd("doVmWorkStart"); + workJob.setAccountId(1L); + workJob.setUserId(2L); + workJob.setStep(Step.Starting); + workJob.setVmType(VirtualMachine.Type.ConsoleProxy); + workJob.setVmInstanceid(1L); + + VmWorkStart workInfo = new VmWorkStart(); + workJob.setCmdInfo(ApiSerializerHelper.toSerializedString(workInfo)); + _jobMgr.submitAsyncJob(workJob, "VM", 1); + + _jobMgr.waitAndCheck(new String[] {"Done"}, 120000, 120000, new Predicate() { + + @Override + public boolean checkCondition() { + return true; + } + }); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/com/cloud/vm/VmWorkTestConfiguration.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/VmWorkTestConfiguration.java b/server/test/com/cloud/vm/VmWorkTestConfiguration.java new file mode 100644 index 0000000..f56e7be --- /dev/null +++ b/server/test/com/cloud/vm/VmWorkTestConfiguration.java @@ -0,0 +1,106 @@ +// 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.vm; + +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.cloud.api.ApiDispatcher; +import com.cloud.async.SyncQueueManager; +import com.cloud.async.SyncQueueManagerImpl; +import com.cloud.async.dao.AsyncJobDao; +import com.cloud.async.dao.AsyncJobDaoImpl; +import com.cloud.async.dao.SyncQueueDao; +import com.cloud.async.dao.SyncQueueDaoImpl; +import com.cloud.async.dao.SyncQueueItemDao; +import com.cloud.async.dao.SyncQueueItemDaoImpl; +import com.cloud.cluster.ClusterManager; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dao.EntityManager; +import com.cloud.user.AccountManager; +import com.cloud.user.dao.AccountDao; + +@Configuration +public class VmWorkTestConfiguration { + + @Bean + public ClusterManager clusterManager() { + return Mockito.mock(ClusterManager.class); + } + + @Bean + public AsyncJobDao asyncJobDao() { + return new AsyncJobDaoImpl(); + } + + @Bean + public AccountManager accountManager() { + return Mockito.mock(AccountManager.class); + } + + @Bean + public ApiDispatcher apiDispatcher() { + return Mockito.mock(ApiDispatcher.class); + } + + @Bean + public EntityManager entityManager() { + return Mockito.mock(EntityManager.class); + } + + @Bean + public SyncQueueManager syncQueueManager() { + return new SyncQueueManagerImpl(); + } + + @Bean + public AccountDao accountDao() { + return Mockito.mock(AccountDao.class); + } + + @Bean + public SyncQueueDao syncQueueDao() { + return new SyncQueueDaoImpl(); + } + + @Bean + public SyncQueueItemDao syncQueueItemDao() { + return new SyncQueueItemDaoImpl(); + } + + @Bean + public ConfigurationDao configurationDao() { + return Mockito.mock(ConfigurationDao.class); + } + + @Bean + public ConfigurationManager configurationManager() { + return Mockito.mock(ConfigurationManager.class); + } + + @Bean + public VirtualMachineManager virtualMachineManager() { + return new VmWorkMockVirtualMachineManagerImpl(); + } + + @Bean + public VmWorkJobDao vmworkJobDao() { + return new VmWorkJobDaoImpl(); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/17930685/server/test/resources/VmWorkTestContext.xml ---------------------------------------------------------------------- diff --git a/server/test/resources/VmWorkTestContext.xml b/server/test/resources/VmWorkTestContext.xml new file mode 100644 index 0000000..43457fc --- /dev/null +++ b/server/test/resources/VmWorkTestContext.xml @@ -0,0 +1,54 @@ +<!-- 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. --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" + xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/tx + http://www.springframework.org/schema/tx/spring-tx-3.0.xsd + http://www.springframework.org/schema/aop + http://www.springframework.org/schema/aop/spring-aop-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + <context:annotation-config /> + + <!-- @DB support --> + + <bean id="componentContext" class="com.cloud.utils.component.ComponentContext" /> + + <bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" /> + <bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" /> + <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor"> + <property name="Interceptors"> + <list> + <ref bean="transactionContextBuilder" /> + <ref bean="actionEventInterceptor" /> + </list> + </property> + </bean> + + <bean id="asyncJobManagerImpl" class="com.cloud.async.AsyncJobManagerImpl"> + <property name="defaultDispatcher" value="ApiAsyncJobDispatcher" /> + </bean> + <bean id="ApiAsyncJobDispatcher" class="com.cloud.api.ApiAsyncJobDispatcher"> + <property name="name" value="ApiAsyncJobDispatcher" /> + </bean> + <bean id="VmWorkJobDispatcher" class="com.cloud.vm.VmWorkJobDispatcher"> + <property name="name" value="VmWorkJobDispatcher" /> + </bean> + + <bean id="messageBus" class = "org.apache.cloudstack.framework.messagebus.MessageBusBase" /> + + <bean class="com.cloud.vm.VmWorkTestConfiguration" /> + +</beans>
