Skip to content

Commit

Permalink
Merge branch '4.8' into 4.9
Browse files Browse the repository at this point in the history
  • Loading branch information
rohityadavcloud committed Sep 1, 2016
2 parents 3e6f49d + f4ae87c commit 08edd0c
Show file tree
Hide file tree
Showing 6 changed files with 666 additions and 80 deletions.
258 changes: 180 additions & 78 deletions engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions engine/schema/src/com/cloud/upgrade/dao/Upgrade490to491.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public class Upgrade490to491 implements DbUpgrade {

@Override
public String[] getUpgradableVersionRange() {
return new String[] {"4.9.0", "4.9.1"};
return new String[] {"4.9.0", "4.9.1.0"};
}

@Override
public String getUpgradedVersion() {
return "4.9.1";
return "4.9.1.0";
}

@Override
Expand Down
122 changes: 122 additions & 0 deletions engine/schema/test/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// 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 com.cloud.upgrade.dao.DbUpgrade;
import com.cloud.upgrade.dao.Upgrade452to460;
import com.cloud.upgrade.dao.Upgrade460to461;
import com.cloud.upgrade.dao.Upgrade461to470;
import com.cloud.upgrade.dao.Upgrade470to471;
import com.cloud.upgrade.dao.Upgrade471to480;
import com.cloud.upgrade.dao.Upgrade480to481;
import com.cloud.upgrade.dao.Upgrade490to491;
import org.apache.cloudstack.utils.CloudStackVersion;
import org.junit.Test;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class DatabaseUpgradeCheckerTest {

@Test
public void testCalculateUpgradePath480to481() {

final CloudStackVersion dbVersion = CloudStackVersion.parse("4.8.0");
assertNotNull(dbVersion);

final CloudStackVersion currentVersion = CloudStackVersion.parse("4.8.1");
assertNotNull(currentVersion);

final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);

assertNotNull(upgrades);
assertTrue(upgrades.length >= 1);
assertTrue(upgrades[0] instanceof Upgrade480to481);

}

@Test
public void testCalculateUpgradePath490to4910() {

final CloudStackVersion dbVersion = CloudStackVersion.parse("4.9.0");
assertNotNull(dbVersion);

final CloudStackVersion currentVersion = CloudStackVersion.parse("4.9.1.0");
assertNotNull(currentVersion);

final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);

assertNotNull(upgrades);
assertEquals(1, upgrades.length);
assertTrue(upgrades[0] instanceof Upgrade490to491);

assertTrue(Arrays.equals(new String[] { "4.9.0", currentVersion.toString()}, upgrades[0].getUpgradableVersionRange()));
assertEquals(currentVersion.toString(), upgrades[0].getUpgradedVersion());

}

@Test
public void testFindUpgradePath470to481() {

final CloudStackVersion dbVersion = CloudStackVersion.parse("4.7.0");
assertNotNull(dbVersion);

final CloudStackVersion currentVersion = CloudStackVersion.parse("4.8.1");
assertNotNull(currentVersion);

final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);

assertNotNull(upgrades);

assertTrue(upgrades[0] instanceof Upgrade470to471);
assertTrue(upgrades[1] instanceof Upgrade471to480);
assertTrue(upgrades[2] instanceof Upgrade480to481);

}

@Test
public void testFindUpgradePath452to490() {

final CloudStackVersion dbVersion = CloudStackVersion.parse("4.5.2");
assertNotNull(dbVersion);

final CloudStackVersion currentVersion = CloudStackVersion.parse("4.9.0");
assertNotNull(currentVersion);

final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);

assertNotNull(upgrades);

assertTrue(upgrades[0] instanceof Upgrade452to460);
assertTrue(upgrades[1] instanceof Upgrade460to461);
assertTrue(upgrades[2] instanceof Upgrade461to470);
assertTrue(upgrades[3] instanceof Upgrade470to471);
assertTrue(upgrades[4] instanceof Upgrade471to480);
assertTrue(upgrades[5] instanceof Upgrade480to481);

assertTrue(Arrays.equals(new String[] { "4.8.1", currentVersion.toString()}, upgrades[6].getUpgradableVersionRange()));
assertEquals(currentVersion.toString(), upgrades[6].getUpgradedVersion());

}
}
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<!-- do not forget to also upgrade hamcrest library with junit -->
<cs.junit.version>4.12</cs.junit.version>
<cs.hamcrest.version>1.3</cs.hamcrest.version>
<cs.junit.dataprovider.version>1.10.0</cs.junit.dataprovider.version>
<cs.bcprov.version>1.46</cs.bcprov.version>
<cs.jsch.version>0.1.53</cs.jsch.version>
<cs.jpa.version>2.1.1</cs.jpa.version>
Expand Down Expand Up @@ -514,6 +515,12 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.tngtech.java</groupId>
<artifactId>junit-dataprovider</artifactId>
<version>${cs.junit.dataprovider.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
Expand Down
235 changes: 235 additions & 0 deletions utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
//
// 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 org.apache.cloudstack.utils;

import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;

import java.util.regex.Pattern;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang.StringUtils.substringBefore;

/**
*
* A value object representing a version of the Management or Usage Server (as opposed to a Virtual Router). It is
* intended to supersede {@link com.cloud.maint.Version}.
*
* @since 4.8.2.0
*
*/
public final class CloudStackVersion implements Comparable<CloudStackVersion> {

private final static Pattern VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+");

/**
*
* Parses a <code>String</code> representation of a version that conforms one of the following
* formats into a <code>CloudStackVersion</code> instance:
* <ul>
* <li><code><major version>.<minor version>.<patch release></code></li>
* <li><code><major version>.<minor version>.<patch release>.<security release></code></li>
* <li><code><major version>.<minor version>.<patch release>.<security release>-<any string></code></li>
* </ul>
*
* If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
* will be dropped.
*
* @param value The value to parse which must be non-blank and conform the formats listed above
*
* @return <code>value</code> parsed into a <code>CloudStackVersion</code> instance
*
* @since 4.8.2
*
*/
public static CloudStackVersion parse(final String value) {

// Strip out any legacy patch information from the version string ...
final String trimmedValue = substringBefore(value, "-");

checkArgument(isNotBlank(trimmedValue), CloudStackVersion.class.getName() + ".parse(String) requires a non-blank value");
checkArgument(VERSION_FORMAT.matcher(trimmedValue).matches(), CloudStackVersion.class.getName() + "parse(String) passed " +
value + ", but requires a value in the format of int.int.int(.int)(-<legacy patch>)");

final String[] components = trimmedValue.split("\\.");

checkState(components != null && (components.length == 3 || components.length == 4), "Expected " + value +
" to parse to 3 or 4 positions.");

final int majorRelease = Integer.valueOf(components[0]);
final int minorRelease = Integer.valueOf(components[1]);
final int patchRelease = Integer.valueOf(components[2]);
final Integer securityRelease = components.length == 3 ? null : Integer.valueOf(components[3]);

return new CloudStackVersion(majorRelease, minorRelease, patchRelease, securityRelease);

}

private final int majorRelease;
private final int minorRelease;
private final int patchRelease;
private final Integer securityRelease;

private CloudStackVersion(final int majorRelease, final int minorRelease, final int patchRelease, final Integer securityRelease) {

super();

checkArgument(majorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a majorRelease greater than 0.");
checkArgument(minorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a minorRelease greater than 0.");
checkArgument(patchRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a patchRelease greater than 0.");
checkArgument((securityRelease != null && securityRelease >= 0) || (securityRelease == null),
CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a null securityRelease or a non-null value greater than 0.");

this.majorRelease = majorRelease;
this.minorRelease = minorRelease;
this.patchRelease = patchRelease;
this.securityRelease = securityRelease;

}

private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList<Integer> values) {

checkArgument(values != null);
checkArgument(values.size() == 3 || values.size() == 4);

if (values.size() == 3) {
return ImmutableList.<Integer>builder().addAll(values).add(0).build();
}

return values;

}

/**
* {@inheritDoc}
*
* A couple of notes about the comparison rules for this method:
* <ul>
* <li>Three position versions are normalized to four position versions with the security release being
* defaulted to zero (0). For example, for the purposes of comparision, <code>4.8.1</code> would be
* normalized to <code>4.8.1.0</code> for all comparison operations.</li>
* <li>A three position version with a null security release is considered equal to a four position
* version number where the major release, minor release, and patch release are the same and the security
* release for the four position version is zero (0). Therefore, the results of this method are <b>not</b>
* symmetric with <code>equals</code></li>
* <li>When comparing to <code>null</code>, this version is always considered greater than (i.e. returning
* a value greater than zero (0).</li>
* </ul>
*
* @param thatVersion The version to which to compare this instance
*
* @return A value less than zero (0) indicates this version is less than <code>thatVersion</code>. A value
* equal to zero (0) indicates this value equals <code>thatValue</code>. A value greater than zero (0)
* indicates this version is greater than <code>thatVersion</code>.
*
* @since 4.8.2.0
*
*/
@Override
public int compareTo(final CloudStackVersion thatVersion) {

if (thatVersion == null) {
return 1;
}

// Normalize the versions to be 4 positions for the purposes of comparison ...
final ImmutableList<Integer> values = normalizeVersionValues(asList());
final ImmutableList<Integer> thoseValues = normalizeVersionValues(thatVersion.asList());

for (int i = 0; i < values.size(); i++) {
final int result = values.get(i).compareTo(thoseValues.get(i));
if (result != 0) {
return result;
}
}

return 0;

}

/**
*
* @return The components of this version as an {@link ImmutableList} in order of major release, minor release,
* patch release, and security release
*
* @since 4.8.2.0
*
*/
public ImmutableList<Integer> asList() {

final ImmutableList.Builder<Integer> values = ImmutableList.<Integer>builder().add
(majorRelease, minorRelease, patchRelease);

if (securityRelease != null) {
values.add(securityRelease);
}

return values.build();

}

@Override
public boolean equals(final Object thatObject) {

if (this == thatObject) {
return true;
}

if (thatObject == null || getClass() != thatObject.getClass()) {
return false;
}

final CloudStackVersion thatVersion = (CloudStackVersion) thatObject;
return majorRelease == thatVersion.majorRelease &&
minorRelease == thatVersion.minorRelease &&
patchRelease == thatVersion.patchRelease &&
Objects.equal(securityRelease, thatVersion.securityRelease);

}

@Override
public int hashCode() {
return Objects.hashCode(majorRelease, minorRelease, patchRelease, securityRelease);
}

@Override
public String toString() {
return Joiner.on(".").join(asList());
}

public int getMajorRelease() {
return majorRelease;
}

public int getMinorRelease() {
return minorRelease;
}

public int getPatchRelease() {
return patchRelease;
}

public Integer getSecurityRelease() {
return securityRelease;
}

}
Loading

0 comments on commit 08edd0c

Please sign in to comment.