Updated Branches: refs/heads/vmsync 360a48bc7 -> 8b4ec1927
Unit test for power state sync DAO method Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8b4ec192 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8b4ec192 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8b4ec192 Branch: refs/heads/vmsync Commit: 8b4ec1927c4384ed5abad03be3613956fcce00bd Parents: 360a48b Author: Kelven Yang <[email protected]> Authored: Tue Apr 23 17:05:52 2013 -0700 Committer: Kelven Yang <[email protected]> Committed: Tue Apr 23 17:05:52 2013 -0700 ---------------------------------------------------------------------- api/src/com/cloud/vm/VirtualMachine.java | 1 - core/src/com/cloud/async/AsyncJobVO.java | 2 - core/src/com/cloud/vm/VMInstanceVO.java | 39 ++---- server/src/com/cloud/vm/dao/VMInstanceDao.java | 1 + server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java | 30 ++++- server/test/com/cloud/vm/dao/VmDaoTest.java | 111 +++++++++++++++ .../com/cloud/vm/dao/VmDaoTestConfiguration.java | 91 ++++++++++++ server/test/resources/testContext.xml | 38 ----- server/test/resources/vmdaoTestContext.xml | 51 +++++++ setup/db/db/schema-410to420.sql | 3 +- 10 files changed, 296 insertions(+), 71 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/api/src/com/cloud/vm/VirtualMachine.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 62d5eeb..b9c265c 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -159,7 +159,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I } public enum Event { - OperationNop, CreateRequested, StartRequested, StopRequested, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/core/src/com/cloud/async/AsyncJobVO.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/async/AsyncJobVO.java b/core/src/com/cloud/async/AsyncJobVO.java index 73e7b8c..53d2e1e 100644 --- a/core/src/com/cloud/async/AsyncJobVO.java +++ b/core/src/com/cloud/async/AsyncJobVO.java @@ -23,8 +23,6 @@ import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/core/src/com/cloud/vm/VMInstanceVO.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index adf6445..d945e58 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -97,20 +97,16 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi protected Long lastHostId; @Enumerated(value=EnumType.STRING) - @Column(name="last_event", updatable=true) - protected VirtualMachine.Event lastEvent; - - @Column(name="last_event_args", updatable=true, nullable=true) - protected String lastEventArgs; - - @Enumerated(value=EnumType.STRING) @Column(name="power_state", updatable=true) protected PowerState powerState; - @Column(name="power_state_update_time", updatable = true, nullable=false) + @Column(name="power_state_update_time", updatable=true, nullable=false) @Temporal(value=TemporalType.TIMESTAMP) protected Date powerStateUpdateTime; + @Column(name="power_state_update_count", updatable=true) + protected int powerStateUpdateCount; + @Column(name="pod_id", updatable=true, nullable=false) protected Long podIdToDeployIn; @@ -201,7 +197,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi this.hypervisorType = hypervisorType; this.limitCpuUse = false; - this.lastEvent = Event.OperationNop; this.powerState = PowerState.PowerUnknown; this.powerStateUpdateTime = DateUtil.currentGMTTime(); } @@ -222,7 +217,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi this.limitCpuUse = limitResourceUse; this.diskOfferingId = diskOfferingId; - this.lastEvent = Event.OperationNop; this.powerState = PowerState.PowerUnknown; this.powerStateUpdateTime = DateUtil.currentGMTTime(); } @@ -493,7 +487,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi return true; } - public void setServiceOfferingId(long serviceOfferingId) { this.serviceOfferingId = serviceOfferingId; } @@ -503,22 +496,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi return diskOfferingId; } - public VirtualMachine.Event getLastEvent() { - return lastEvent; - } - - public void setLastEvent(VirtualMachine.Event event) { - this.lastEvent = event; - } - - public String getLastEventArgs() { - return this.lastEventArgs; - } - - public void setLastEventArgs(String eventArgs) { - this.lastEventArgs = eventArgs; - } - public VirtualMachine.PowerState getPowerState() { return this.powerState; } @@ -534,4 +511,12 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi public void setPowerStateUpdateTime(Date updateTime) { this.powerStateUpdateTime = updateTime; } + + public int getPowerStateUpdateCount() { + return this.powerStateUpdateCount; + } + + public void setPowerStateUpdateCount(int count) { + this.powerStateUpdateCount = count; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/server/src/com/cloud/vm/dao/VMInstanceDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java index c604027..1b47826 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java @@ -116,4 +116,5 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao< */ List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types); + void updatePowerState(long instanceId, VirtualMachine.PowerState powerState); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index a7d33cf..064ef1c 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -37,6 +37,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.utils.DateUtil; import com.cloud.utils.Pair; import com.cloud.utils.db.Attribute; import com.cloud.utils.db.DB; @@ -63,6 +64,7 @@ import com.cloud.vm.VirtualMachine.Type; public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implements VMInstanceDao { public static final Logger s_logger = Logger.getLogger(VMInstanceDaoImpl.class); + private static final int MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT = 3; protected SearchBuilder<VMInstanceVO> VMClusterSearch; protected SearchBuilder<VMInstanceVO> LHVMClusterSearch; @@ -625,5 +627,31 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem txn.commit(); return result; } - + + @Override @DB + public void updatePowerState(long instanceId, VirtualMachine.PowerState powerState) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + + VMInstanceVO instance = findById(instanceId); + if(instance != null) { + if(instance.getPowerState() != powerState) { + instance.setPowerState(powerState); + instance.setPowerStateUpdateCount(1); + instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); + + update(instanceId, instance); + } else { + // to reduce DB updates, consecutive same state update for more than 3 times + if(instance.getPowerStateUpdateCount() < MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT) { + instance.setPowerStateUpdateCount(instance.getPowerStateUpdateCount() + 1); + instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); + + update(instanceId, instance); + } + } + } + + txn.commit(); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/server/test/com/cloud/vm/dao/VmDaoTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/dao/VmDaoTest.java b/server/test/com/cloud/vm/dao/VmDaoTest.java new file mode 100644 index 0000000..546bba3 --- /dev/null +++ b/server/test/com/cloud/vm/dao/VmDaoTest.java @@ -0,0 +1,111 @@ +// 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.dao; + +import java.sql.SQLException; +import java.sql.Statement; + +import javax.inject.Inject; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.utils.db.Transaction; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; + +import junit.framework.Assert; +import junit.framework.TestCase; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/vmdaoTestContext.xml") +public class VmDaoTest extends TestCase { + + @Inject UserVmDao userVmDao; + @Inject VMInstanceDao instanceDao; + + @Before + public void setup() { + 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 cleanup() { + Transaction.currentTxn().close(); + } + + @Test + public void testPowerStateUpdate() { + UserVmVO userVmInstance = new UserVmVO(1L, "Dummy", "DummyInstance", + 1L, HypervisorType.Any, 1L, true, false, 1L, 1L, 1L, null, null, null); + + userVmDao.persist(userVmInstance); + + VMInstanceVO instance = instanceDao.findById(1L); + Assert.assertTrue(instance.getInstanceName().equals("Dummy")); + + instanceDao.updatePowerState(1L, VirtualMachine.PowerState.PowerOn); + instance = instanceDao.findById(1L); + Assert.assertTrue(instance.getPowerState() == VirtualMachine.PowerState.PowerOn); + Assert.assertTrue(instance.getPowerStateUpdateCount() == 1); + + instanceDao.updatePowerState(1L, VirtualMachine.PowerState.PowerOn); + instance = instanceDao.findById(1L); + Assert.assertTrue(instance.getPowerState() == VirtualMachine.PowerState.PowerOn); + Assert.assertTrue(instance.getPowerStateUpdateCount() == 2); + + instanceDao.updatePowerState(1L, VirtualMachine.PowerState.PowerOn); + instance = instanceDao.findById(1L); + Assert.assertTrue(instance.getPowerState() == VirtualMachine.PowerState.PowerOn); + Assert.assertTrue(instance.getPowerStateUpdateCount() == 3); + + // after 3 times, the update count should stay at 3 + instanceDao.updatePowerState(1L, VirtualMachine.PowerState.PowerOn); + instance = instanceDao.findById(1L); + Assert.assertTrue(instance.getPowerState() == VirtualMachine.PowerState.PowerOn); + Assert.assertTrue(instance.getPowerStateUpdateCount() == 3); + + // after 3 times, the update count should stay at 3 + instanceDao.updatePowerState(1L, VirtualMachine.PowerState.PowerOff); + instance = instanceDao.findById(1L); + Assert.assertTrue(instance.getPowerState() == VirtualMachine.PowerState.PowerOff); + Assert.assertTrue(instance.getPowerStateUpdateCount() == 1); + + userVmDao.expunge(1L); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/server/test/com/cloud/vm/dao/VmDaoTestConfiguration.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/dao/VmDaoTestConfiguration.java b/server/test/com/cloud/vm/dao/VmDaoTestConfiguration.java new file mode 100644 index 0000000..1574c0c --- /dev/null +++ b/server/test/com/cloud/vm/dao/VmDaoTestConfiguration.java @@ -0,0 +1,91 @@ +// 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.dao; + +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.cloud.cluster.agentlb.dao.HostTransferMapDao; +import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.ClusterDaoImpl; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDaoImpl; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.host.dao.HostTagsDao; +import com.cloud.tags.dao.ResourceTagDao; + +@Configuration +public class VmDaoTestConfiguration { + + @Bean + public VMInstanceDao instanceDao() { + return new VMInstanceDaoImpl(); + } + + @Bean + public HostDao hostDao() { + return new HostDaoImpl(); + } + + @Bean + public HostDetailsDao hostDetailsDao() { + return Mockito.mock(HostDetailsDao.class); + } + + @Bean + public HostTagsDao hostTagsDao() { + return Mockito.mock(HostTagsDao.class); + } + + @Bean + public HostTransferMapDao hostTransferMapDao() { + return new HostTransferMapDaoImpl(); + } + + @Bean + public ClusterDao clusterDao() { + return new ClusterDaoImpl(); + } + + @Bean + public HostPodDao hostPodDao() { + return Mockito.mock(HostPodDao.class); + } + + @Bean + public ResourceTagDao resourceTagDao() { + return Mockito.mock(ResourceTagDao.class); + } + + @Bean + public NicDao nicDao() { + return new NicDaoImpl(); + } + + @Bean + public UserVmDao userVmDao() { + return new UserVmDaoImpl(); + } + + @Bean + public UserVmDetailsDao userVmDetailsDao() { + return Mockito.mock(UserVmDetailsDao.class); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/server/test/resources/testContext.xml ---------------------------------------------------------------------- diff --git a/server/test/resources/testContext.xml b/server/test/resources/testContext.xml index 6a21198..b72c58b 100644 --- a/server/test/resources/testContext.xml +++ b/server/test/resources/testContext.xml @@ -32,56 +32,18 @@ <context:annotation-config /> - <context:component-scan base-package="org.apache.cloudstack, com.cloud" /> - <!-- @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 class="com.cloud.network.security.SecurityGroupManagerTestConfiguration" /> - - <!-- - RPC/Async/EventBus - --> - - <bean id="onwireRegistry" class="org.apache.cloudstack.framework.serializer.OnwireClassRegistry" - init-method="scan" > - <property name="packages"> - <list> - <value>org.apache.cloudstack.framework</value> - </list> - </property> - </bean> - - <bean id="messageSerializer" class="org.apache.cloudstack.framework.serializer.JsonMessageSerializer"> - <property name="onwireClassRegistry" ref="onwireRegistry" /> - </bean> - - <bean id="transportProvider" class="org.apache.cloudstack.framework.server.ServerTransportProvider" init-method="initialize"> - <property name="workerPoolSize" value="5" /> - <property name="nodeId" value="Node1" /> - <property name="messageSerializer" ref="messageSerializer" /> - </bean> - - <bean id="rpcProvider" class="org.apache.cloudstack.framework.rpc.RpcProviderImpl" init-method="initialize"> - <constructor-arg ref="transportProvider" /> - <property name="messageSerializer" ref="messageSerializer" /> - </bean> - - <bean id="eventBus" class = "org.apache.cloudstack.framework.eventbus.EventBusBase" /> - - <bean id="apiServlet" class = "com.cloud.api.ApiServlet" /> </beans> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/server/test/resources/vmdaoTestContext.xml ---------------------------------------------------------------------- diff --git a/server/test/resources/vmdaoTestContext.xml b/server/test/resources/vmdaoTestContext.xml new file mode 100644 index 0000000..9fd6e41 --- /dev/null +++ b/server/test/resources/vmdaoTestContext.xml @@ -0,0 +1,51 @@ +<!-- + 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="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor"> + <property name="Interceptors"> + <list> + <ref bean="transactionContextBuilder" /> + </list> + </property> + </bean> + + <bean id="vmdaoTestConfiguration" class="com.cloud.vm.dao.VmDaoTestConfiguration" /> + +</beans> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b4ec192/setup/db/db/schema-410to420.sql ---------------------------------------------------------------------- diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ea31b78..14583b0 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -416,8 +416,7 @@ ALTER TABLE `cloud`.`async_job` ADD COLUMN `job_type` VARCHAR(32); ALTER TABLE `cloud`.`async_job` ADD COLUMN `job_dispatcher` VARCHAR(64); ALTER TABLE `cloud`.`async_job` ADD COLUMN `job_executing_msid` bigint; -ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `last_event` VARCHAR(64) DEFAULT 'OperationNop'; -ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `last_event_args` VARCHAR(256); ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state` VARCHAR(74) DEFAULT 'PowerUnknown'; ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state_update_time` DATETIME; +ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state_update_count` INT DEFAULT 0;
