diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 1fe2b3f2d9c..df5e60e7a1a 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -456,6 +456,9 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem // state is same, don't need to update return true; } + if(ifStateUnchanged(oldState,newState, oldHostId, newHostId)) { + return true; + } // lock the target row at beginning to avoid lock-promotion caused deadlock lockRow(vm.getId(), true); @@ -503,6 +506,14 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return result > 0; } + boolean ifStateUnchanged(State oldState, State newState, Long oldHostId, Long newHostId ) { + if (oldState == State.Stopped && newState == State.Stopped && newHostId == null && oldHostId == null) { + // No change , no need to update + return true; + } + return false; + } + @Override public List listByLastHostId(Long hostId) { SearchCriteria sc = AllFieldsSearch.create(); diff --git a/engine/schema/test/com/cloud/vm/dao/VMInstanceDaoImplTest.java b/engine/schema/test/com/cloud/vm/dao/VMInstanceDaoImplTest.java new file mode 100644 index 00000000000..95a57ed582f --- /dev/null +++ b/engine/schema/test/com/cloud/vm/dao/VMInstanceDaoImplTest.java @@ -0,0 +1,72 @@ +// 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 com.cloud.utils.Pair; +import com.cloud.vm.VirtualMachine; +import org.joda.time.DateTime; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.mockito.Mock; + +import static com.cloud.vm.VirtualMachine.State.Running; +import static com.cloud.vm.VirtualMachine.State.Stopped; + +import static org.mockito.Mockito.when; +import com.cloud.vm.VMInstanceVO; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +/** + * Created by sudharma_jain on 3/2/17. + */ + +public class VMInstanceDaoImplTest { + + @Spy + VMInstanceDaoImpl vmInstanceDao = new VMInstanceDaoImpl(); + + @Mock + VMInstanceVO vm; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + Long hostId = null; + when(vm.getHostId()).thenReturn(hostId); + when(vm.getUpdated()).thenReturn(5L); + when(vm.getUpdateTime()).thenReturn(DateTime.now().toDate()); + } + + @Test + public void testUpdateState() throws Exception { + Long destHostId = null; + Pair opaqueMock = new Pair(new Long(1), destHostId); + vmInstanceDao.updateState(Stopped, VirtualMachine.Event.FollowAgentPowerOffReport, Stopped, vm , opaqueMock); + } + + @Test + public void testIfStateAndHostUnchanged() throws Exception { + Assert.assertEquals(vmInstanceDao.ifStateUnchanged(Stopped, Stopped, null, null), true); + Assert.assertEquals(vmInstanceDao.ifStateUnchanged(Stopped, Running, null, null), false); + } + +} + +