| // 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.upgrade; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| import com.cloud.upgrade.dao.VersionDao; |
| import com.cloud.upgrade.dao.VersionDaoImpl; |
| import com.cloud.upgrade.dao.VersionVO; |
| import com.cloud.utils.db.GlobalLock; |
| import org.junit.Test; |
| |
| public class DatabaseUpgradeCheckerDoUpgradesTest { |
| |
| static class StubVersionDao extends VersionDaoImpl implements VersionDao { |
| private final String currentVersion; |
| |
| StubVersionDao(String currentVersion) { |
| this.currentVersion = currentVersion; |
| } |
| |
| @Override |
| public VersionVO findByVersion(String version, VersionVO.Step step) { |
| return null; |
| } |
| |
| @Override |
| public String getCurrentVersion() { |
| return currentVersion; |
| } |
| |
| } |
| |
| private static class TestableChecker extends DatabaseUpgradeChecker { |
| boolean initializeCalled = false; |
| boolean upgradeCalled = false; |
| boolean clusterHandlerCalled = false; |
| String implVersionOverride = null; |
| String sysVmMetadataOverride = "4.8.0"; |
| boolean standaloneOverride = true; |
| |
| TestableChecker(String daoVersion) { |
| // set a stub DAO |
| this._dao = new StubVersionDao(daoVersion); |
| } |
| |
| @Override |
| protected void initializeDatabaseEncryptors() { |
| initializeCalled = true; |
| // noop instead of doing DB work |
| } |
| |
| @Override |
| protected String getImplementationVersion() { |
| return implVersionOverride; |
| } |
| |
| @Override |
| protected String parseSystemVmMetadata() { |
| return sysVmMetadataOverride; |
| } |
| |
| @Override |
| boolean isStandalone() { |
| return standaloneOverride; |
| } |
| |
| @Override |
| protected void upgrade(org.apache.cloudstack.utils.CloudStackVersion dbVersion, org.apache.cloudstack.utils.CloudStackVersion currentVersion) { |
| upgradeCalled = true; |
| } |
| |
| @Override |
| protected void handleClusteredUpgradeRequired() { |
| clusterHandlerCalled = true; |
| } |
| } |
| |
| @Test |
| public void testDoUpgrades_noImplementationVersion_returnsEarly() { |
| TestableChecker checker = new TestableChecker("4.8.0"); |
| checker.implVersionOverride = ""; // blank -> should return early |
| |
| GlobalLock lock = GlobalLock.getInternLock("test-noimpl"); |
| try { |
| // acquire lock so doUpgrades can safely call unlock in finally |
| lock.lock(1); |
| checker.doUpgrades(lock); |
| } finally { |
| // ensure lock released if still held |
| lock.releaseRef(); |
| } |
| |
| assertTrue("initializeDatabaseEncryptors should be called before returning", checker.initializeCalled); |
| assertFalse("upgrade should not be called when implementation version is blank", checker.upgradeCalled); |
| assertFalse("cluster handler should not be called", checker.clusterHandlerCalled); |
| } |
| |
| @Test |
| public void testDoUpgrades_dbUpToDate_noUpgrade() { |
| // DB version = code version -> no upgrade |
| TestableChecker checker = new TestableChecker("4.8.1"); |
| checker.implVersionOverride = "4.8.1"; |
| checker.sysVmMetadataOverride = "4.8.1"; |
| |
| GlobalLock lock = GlobalLock.getInternLock("test-uptodate"); |
| try { |
| lock.lock(1); |
| checker.doUpgrades(lock); |
| } finally { |
| lock.releaseRef(); |
| } |
| |
| assertTrue(checker.initializeCalled); |
| assertFalse(checker.upgradeCalled); |
| assertFalse(checker.clusterHandlerCalled); |
| } |
| |
| @Test |
| public void testDoUpgrades_requiresUpgrade_standalone_invokesUpgrade() { |
| TestableChecker checker = new TestableChecker("4.8.0"); |
| checker.implVersionOverride = "4.8.2"; // code is newer than DB |
| checker.sysVmMetadataOverride = "4.8.2"; |
| checker.standaloneOverride = true; |
| |
| GlobalLock lock = GlobalLock.getInternLock("test-upgrade-standalone"); |
| try { |
| lock.lock(1); |
| checker.doUpgrades(lock); |
| } finally { |
| lock.releaseRef(); |
| } |
| |
| assertTrue(checker.initializeCalled); |
| assertTrue("upgrade should be invoked in standalone mode", checker.upgradeCalled); |
| assertFalse(checker.clusterHandlerCalled); |
| } |
| |
| @Test |
| public void testDoUpgrades_requiresUpgrade_clustered_invokesHandler() { |
| TestableChecker checker = new TestableChecker("4.8.0"); |
| checker.implVersionOverride = "4.8.2"; // code is newer than DB |
| checker.sysVmMetadataOverride = "4.8.2"; |
| checker.standaloneOverride = false; |
| |
| GlobalLock lock = GlobalLock.getInternLock("test-upgrade-clustered"); |
| try { |
| lock.lock(1); |
| checker.doUpgrades(lock); |
| } finally { |
| lock.releaseRef(); |
| } |
| |
| assertTrue(checker.initializeCalled); |
| assertFalse("upgrade should not be invoked in clustered mode", checker.upgradeCalled); |
| assertTrue("cluster handler should be invoked in clustered mode", checker.clusterHandlerCalled); |
| } |
| } |