mirror of https://github.com/apache/cassandra
Introduce SemVer4j for version representation, parsing and handling. And correct supported upgrade paths. Add v4X to Java DTests (after cassandra-4.0 branch was created)
Change upgrades from testing only a single path, to testing all upgrade paths that are defined as supported within the specified from-to range. Change all upgrades to v40 and v4X to be open ended (i.e. implicit CURRENT version). patch by Mick Semb Wever; reviewed by Alex Petrov for CASSANDRA-16649
This commit is contained in:
parent
26163bb12a
commit
b3f9921881
|
|
@ -393,7 +393,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency groupId="junit" artifactId="junit" version="4.6" />
|
<dependency groupId="junit" artifactId="junit" version="4.6" />
|
||||||
<dependency groupId="org.mockito" artifactId="mockito-core" version="3.2.4" />
|
<dependency groupId="org.mockito" artifactId="mockito-core" version="3.2.4" />
|
||||||
<dependency groupId="org.apache.cassandra" artifactId="dtest-api" version="0.0.7" />
|
<dependency groupId="org.apache.cassandra" artifactId="dtest-api" version="0.0.8" />
|
||||||
<dependency groupId="org.reflections" artifactId="reflections" version="0.9.12" />
|
<dependency groupId="org.reflections" artifactId="reflections" version="0.9.12" />
|
||||||
<dependency groupId="org.apache.rat" artifactId="apache-rat" version="0.10">
|
<dependency groupId="org.apache.rat" artifactId="apache-rat" version="0.10">
|
||||||
<exclusion groupId="commons-lang" artifactId="commons-lang"/>
|
<exclusion groupId="commons-lang" artifactId="commons-lang"/>
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,8 @@
|
||||||
package org.apache.cassandra.distributed.impl;
|
package org.apache.cassandra.distributed.impl;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -30,15 +28,16 @@ import java.util.TreeMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.cassandra.config.YamlConfigurationLoader;
|
import com.vdurmont.semver4j.Semver;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.apache.cassandra.config.YamlConfigurationLoader;
|
||||||
import org.apache.cassandra.distributed.api.Feature;
|
import org.apache.cassandra.distributed.api.Feature;
|
||||||
import org.apache.cassandra.distributed.api.IInstanceConfig;
|
import org.apache.cassandra.distributed.api.IInstanceConfig;
|
||||||
import org.apache.cassandra.distributed.shared.NetworkTopology;
|
import org.apache.cassandra.distributed.shared.NetworkTopology;
|
||||||
import org.apache.cassandra.distributed.shared.Shared;
|
import org.apache.cassandra.distributed.shared.Shared;
|
||||||
import org.apache.cassandra.distributed.shared.Versions;
|
import org.apache.cassandra.distributed.upgrade.UpgradeTestBase;
|
||||||
import org.apache.cassandra.locator.InetAddressAndPort;
|
import org.apache.cassandra.locator.InetAddressAndPort;
|
||||||
import org.apache.cassandra.locator.SimpleSeedProvider;
|
import org.apache.cassandra.locator.SimpleSeedProvider;
|
||||||
|
|
||||||
|
|
@ -266,15 +265,11 @@ public class InstanceConfig implements IInstanceConfig
|
||||||
return datadirs;
|
return datadirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceConfig forVersion(Versions.Major major)
|
public InstanceConfig forVersion(Semver version)
|
||||||
{
|
{
|
||||||
switch (major)
|
return new InstanceConfig(this)
|
||||||
{
|
|
||||||
case v4: return this;
|
|
||||||
default: return new InstanceConfig(this)
|
|
||||||
.set("seed_provider", new ParameterizedClass(SimpleSeedProvider.class.getName(),
|
.set("seed_provider", new ParameterizedClass(SimpleSeedProvider.class.getName(),
|
||||||
Collections.singletonMap("seeds", "127.0.0.1")));
|
Collections.singletonMap("seeds", "127.0.0.1")));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class MixedModeReadRepairTest extends UpgradeTestBase
|
||||||
{
|
{
|
||||||
new TestCase()
|
new TestCase()
|
||||||
.nodes(2)
|
.nodes(2)
|
||||||
.upgrade(Versions.Major.v22, Versions.Major.v30)
|
.upgradesFrom(v22)
|
||||||
.setup((cluster) -> cluster.schemaChange("CREATE TABLE " + DistributedTestBase.KEYSPACE + ".tbl (pk ascii, b boolean, v blob, PRIMARY KEY (pk)) WITH COMPACT STORAGE"))
|
.setup((cluster) -> cluster.schemaChange("CREATE TABLE " + DistributedTestBase.KEYSPACE + ".tbl (pk ascii, b boolean, v blob, PRIMARY KEY (pk)) WITH COMPACT STORAGE"))
|
||||||
.runAfterNodeUpgrade((cluster, node) -> {
|
.runAfterNodeUpgrade((cluster, node) -> {
|
||||||
if (node != 1)
|
if (node != 1)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public class PagingTest extends UpgradeTestBase
|
||||||
{
|
{
|
||||||
new UpgradeTestBase.TestCase()
|
new UpgradeTestBase.TestCase()
|
||||||
.nodes(2)
|
.nodes(2)
|
||||||
.upgrade(Versions.Major.v22, Versions.Major.v30)
|
.upgradesFrom(v22)
|
||||||
.nodesToUpgrade(2)
|
.nodesToUpgrade(2)
|
||||||
.withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL))
|
.withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL))
|
||||||
.setup((cluster) -> {
|
.setup((cluster) -> {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ public class UpgradeTest extends UpgradeTestBase
|
||||||
public void upgradeTest() throws Throwable
|
public void upgradeTest() throws Throwable
|
||||||
{
|
{
|
||||||
new TestCase()
|
new TestCase()
|
||||||
.upgrade(Versions.Major.v22, Versions.Major.v30, Versions.Major.v3X)
|
.upgradesFrom(v22)
|
||||||
.setup((cluster) -> {
|
.setup((cluster) -> {
|
||||||
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))");
|
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,16 @@
|
||||||
package org.apache.cassandra.distributed.upgrade;
|
package org.apache.cassandra.distributed.upgrade;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.vdurmont.semver4j.Semver;
|
||||||
|
import com.vdurmont.semver4j.Semver.SemverType;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
|
@ -34,11 +38,13 @@ import org.apache.cassandra.distributed.api.IInstanceConfig;
|
||||||
import org.apache.cassandra.distributed.impl.Instance;
|
import org.apache.cassandra.distributed.impl.Instance;
|
||||||
import org.apache.cassandra.distributed.shared.DistributedTestBase;
|
import org.apache.cassandra.distributed.shared.DistributedTestBase;
|
||||||
import org.apache.cassandra.distributed.shared.Versions;
|
import org.apache.cassandra.distributed.shared.Versions;
|
||||||
|
import org.apache.cassandra.utils.ByteBufferUtil;
|
||||||
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
import static org.apache.cassandra.distributed.shared.Versions.Major;
|
|
||||||
import static org.apache.cassandra.distributed.shared.Versions.Version;
|
import static org.apache.cassandra.distributed.shared.Versions.Version;
|
||||||
import static org.apache.cassandra.distributed.shared.Versions.find;
|
import static org.apache.cassandra.distributed.shared.Versions.find;
|
||||||
|
|
||||||
|
|
||||||
public class UpgradeTestBase extends DistributedTestBase
|
public class UpgradeTestBase extends DistributedTestBase
|
||||||
{
|
{
|
||||||
@After
|
@After
|
||||||
|
|
@ -70,12 +76,19 @@ public class UpgradeTestBase extends DistributedTestBase
|
||||||
public void run(UpgradeableCluster cluster, int node) throws Throwable;
|
public void run(UpgradeableCluster cluster, int node) throws Throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Semver v22 = new Semver("2.2.0-beta1", SemverType.LOOSE);
|
||||||
|
|
||||||
|
protected static final List<Pair<Semver,Semver>> SUPPORTED_UPGRADE_PATHS = ImmutableList.of(Pair.create(v22, v22));
|
||||||
|
|
||||||
|
// the last is always the current
|
||||||
|
public static final Semver CURRENT = SUPPORTED_UPGRADE_PATHS.get(SUPPORTED_UPGRADE_PATHS.size() - 1).right;
|
||||||
|
|
||||||
public static class TestVersions
|
public static class TestVersions
|
||||||
{
|
{
|
||||||
final Version initial;
|
final Version initial;
|
||||||
final Version[] upgrade;
|
final Version upgrade;
|
||||||
|
|
||||||
public TestVersions(Version initial, Version ... upgrade)
|
public TestVersions(Version initial, Version upgrade)
|
||||||
{
|
{
|
||||||
this.initial = initial;
|
this.initial = initial;
|
||||||
this.upgrade = upgrade;
|
this.upgrade = upgrade;
|
||||||
|
|
@ -109,18 +122,29 @@ public class UpgradeTestBase extends DistributedTestBase
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestCase upgrade(Major initial, Major ... upgrade)
|
/** performs all supported upgrade paths that exist in between from and CURRENT (inclusive) **/
|
||||||
|
public TestCase upgradesFrom(Semver from)
|
||||||
{
|
{
|
||||||
this.upgrade.add(new TestVersions(versions.getLatest(initial),
|
return upgrades(from, CURRENT);
|
||||||
Arrays.stream(upgrade)
|
}
|
||||||
.map(versions::getLatest)
|
|
||||||
.toArray(Version[]::new)));
|
/** performs all supported upgrade paths that exist in between from and to (inclusive) **/
|
||||||
|
public TestCase upgrades(Semver from, Semver to)
|
||||||
|
{
|
||||||
|
SUPPORTED_UPGRADE_PATHS.stream()
|
||||||
|
.filter(upgradePath -> (upgradePath.left.compareTo(from) >= 0 && upgradePath.right.compareTo(to) <= 0))
|
||||||
|
.forEachOrdered(upgradePath ->
|
||||||
|
{
|
||||||
|
this.upgrade.add(
|
||||||
|
new TestVersions(versions.getLatest(upgradePath.left), versions.getLatest(upgradePath.right)));
|
||||||
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestCase upgrade(Version initial, Version ... upgrade)
|
/** Will test this specific upgrade path **/
|
||||||
|
public TestCase singleUpgrade(Semver from, Semver to)
|
||||||
{
|
{
|
||||||
this.upgrade.add(new TestVersions(initial, upgrade));
|
this.upgrade.add(new TestVersions(versions.getLatest(from), versions.getLatest(to)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,7 +177,7 @@ public class UpgradeTestBase extends DistributedTestBase
|
||||||
if (setup == null)
|
if (setup == null)
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
if (upgrade.isEmpty())
|
if (upgrade.isEmpty())
|
||||||
throw new AssertionError();
|
throw new AssertionError("no upgrade paths have been specified (or exist)");
|
||||||
if (runAfterClusterUpgrade == null && runAfterNodeUpgrade == null)
|
if (runAfterClusterUpgrade == null && runAfterNodeUpgrade == null)
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
if (runAfterClusterUpgrade == null)
|
if (runAfterClusterUpgrade == null)
|
||||||
|
|
@ -166,22 +190,20 @@ public class UpgradeTestBase extends DistributedTestBase
|
||||||
|
|
||||||
for (TestVersions upgrade : this.upgrade)
|
for (TestVersions upgrade : this.upgrade)
|
||||||
{
|
{
|
||||||
|
System.out.printf("testing upgrade from %s to %s%n", upgrade.initial.version, upgrade.upgrade.version);
|
||||||
try (UpgradeableCluster cluster = init(UpgradeableCluster.create(nodeCount, upgrade.initial, configConsumer)))
|
try (UpgradeableCluster cluster = init(UpgradeableCluster.create(nodeCount, upgrade.initial, configConsumer)))
|
||||||
{
|
{
|
||||||
setup.run(cluster);
|
setup.run(cluster);
|
||||||
|
|
||||||
for (Version version : upgrade.upgrade)
|
for (int n : nodesToUpgrade)
|
||||||
{
|
{
|
||||||
for (int n : nodesToUpgrade)
|
cluster.get(n).shutdown().get();
|
||||||
{
|
cluster.get(n).setVersion(upgrade.upgrade);
|
||||||
cluster.get(n).shutdown().get();
|
cluster.get(n).startup();
|
||||||
cluster.get(n).setVersion(version);
|
runAfterNodeUpgrade.run(cluster, n);
|
||||||
cluster.get(n).startup();
|
|
||||||
runAfterNodeUpgrade.run(cluster, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
runAfterClusterUpgrade.run(cluster);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runAfterClusterUpgrade.run(cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -194,6 +216,13 @@ public class UpgradeTestBase extends DistributedTestBase
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TestCase allUpgrades(int nodes, int... toUpgrade)
|
||||||
|
{
|
||||||
|
return new TestCase().nodes(nodes)
|
||||||
|
.upgradesFrom(v22)
|
||||||
|
.nodesToUpgrade(toUpgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue