mirror of https://github.com/apache/kafka.git
KAFKA-16308 [4/4]: Add release-version flag to upgrade and downgrade commands (#17362)
I've added the release-version flag to the upgrade and downgrade commands. I've also added tests. While working on this, I realized that we reveal non-production features to be returned in the version-mapping and dependencies commands. I have changed this to only return production features (except in tests) and added tests for this. Reviewers: Jun Rao <jun@confluent.io>
This commit is contained in:
parent
c11a38f9df
commit
c3f13b5c57
|
@ -88,11 +88,11 @@ object StorageTool extends Logging {
|
|||
0
|
||||
|
||||
case "version-mapping" =>
|
||||
runVersionMappingCommand(namespace, printStream)
|
||||
runVersionMappingCommand(namespace, printStream, Features.PRODUCTION_FEATURES)
|
||||
0
|
||||
|
||||
case "feature-dependencies" =>
|
||||
runFeatureDependenciesCommand(namespace, printStream)
|
||||
runFeatureDependenciesCommand(namespace, printStream, Features.PRODUCTION_FEATURES)
|
||||
0
|
||||
|
||||
case "random-uuid" =>
|
||||
|
@ -151,10 +151,12 @@ object StorageTool extends Logging {
|
|||
*
|
||||
* @param namespace Arguments containing the release version.
|
||||
* @param printStream The print stream to output the version mapping.
|
||||
* @param validFeatures List of features to be considered in the output
|
||||
*/
|
||||
def runVersionMappingCommand(
|
||||
namespace: Namespace,
|
||||
printStream: PrintStream
|
||||
printStream: PrintStream,
|
||||
validFeatures: java.util.List[Features]
|
||||
): Unit = {
|
||||
val releaseVersion = Option(namespace.getString("release_version")).getOrElse(MetadataVersion.LATEST_PRODUCTION.toString)
|
||||
try {
|
||||
|
@ -163,7 +165,7 @@ object StorageTool extends Logging {
|
|||
val metadataVersionLevel = metadataVersion.featureLevel()
|
||||
printStream.print(f"metadata.version=$metadataVersionLevel%d ($releaseVersion%s)%n")
|
||||
|
||||
for (feature <- Features.values()) {
|
||||
for (feature <- validFeatures.asScala) {
|
||||
val featureLevel = feature.defaultValue(metadataVersion)
|
||||
printStream.print(f"${feature.featureName}%s=$featureLevel%d%n")
|
||||
}
|
||||
|
@ -176,12 +178,12 @@ object StorageTool extends Logging {
|
|||
|
||||
def runFeatureDependenciesCommand(
|
||||
namespace: Namespace,
|
||||
printStream: PrintStream
|
||||
printStream: PrintStream,
|
||||
validFeatures: java.util.List[Features]
|
||||
): Unit = {
|
||||
val featureArgs = Option(namespace.getList[String]("feature")).map(_.asScala.toList).getOrElse(List.empty)
|
||||
|
||||
// Iterate over each feature specified with --feature
|
||||
if (featureArgs != null) {
|
||||
for (featureArg <- featureArgs) {
|
||||
val Array(featureName, versionStr) = featureArg.split("=")
|
||||
|
||||
|
@ -201,7 +203,7 @@ object StorageTool extends Logging {
|
|||
}
|
||||
printStream.printf("%s=%d (%s) has no dependencies.%n", featureName, featureLevel, metadataVersion.version())
|
||||
} else {
|
||||
Features.values().find(_.featureName == featureName) match {
|
||||
validFeatures.asScala.find(_.featureName == featureName) match {
|
||||
case Some(feature) =>
|
||||
val featureVersion = try {
|
||||
feature.fromFeatureLevel(featureLevel, true)
|
||||
|
@ -231,7 +233,6 @@ object StorageTool extends Logging {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def createStandaloneDynamicVoters(
|
||||
config: KafkaConfig
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.junit.jupiter.params.ParameterizedTest
|
|||
import org.junit.jupiter.params.provider.ValueSource
|
||||
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.jdk.CollectionConverters.IterableHasAsScala
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
@Timeout(value = 40)
|
||||
class StorageToolTest {
|
||||
|
@ -54,7 +54,7 @@ class StorageToolTest {
|
|||
properties
|
||||
}
|
||||
|
||||
val allFeatures = Features.FEATURES.toList
|
||||
val testingFeatures = Features.FEATURES.toList.asJava
|
||||
|
||||
@Test
|
||||
def testConfigToLogDirectories(): Unit = {
|
||||
|
@ -441,8 +441,6 @@ Found problem:
|
|||
stream: ByteArrayOutputStream,
|
||||
releaseVersion: String
|
||||
): Int = {
|
||||
val tempDir = TestUtils.tempDir()
|
||||
try {
|
||||
// Prepare the arguments list
|
||||
val arguments = ListBuffer[String]("version-mapping")
|
||||
|
||||
|
@ -454,10 +452,6 @@ Found problem:
|
|||
|
||||
// Execute the StorageTool with the arguments
|
||||
StorageTool.execute(arguments.toArray, new PrintStream(stream))
|
||||
|
||||
} finally {
|
||||
Utils.delete(tempDir)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -473,7 +467,7 @@ Found problem:
|
|||
s"Output did not contain expected Metadata Version: $output"
|
||||
)
|
||||
|
||||
for (feature <- Features.values()) {
|
||||
for (feature <- Features.PRODUCTION_FEATURES.asScala) {
|
||||
val featureLevel = feature.defaultValue(metadataVersion)
|
||||
assertTrue(output.contains(s"${feature.featureName()}=$featureLevel"),
|
||||
s"Output did not contain expected feature mapping: $output"
|
||||
|
@ -496,7 +490,7 @@ Found problem:
|
|||
s"Output did not contain expected Metadata Version: $output"
|
||||
)
|
||||
|
||||
for (feature <- Features.values()) {
|
||||
for (feature <- Features.PRODUCTION_FEATURES.asScala) {
|
||||
val featureLevel = feature.defaultValue(metadataVersion)
|
||||
assertTrue(output.contains(s"${feature.featureName()}=$featureLevel"),
|
||||
s"Output did not contain expected feature mapping: $output"
|
||||
|
@ -534,37 +528,20 @@ Found problem:
|
|||
stream: ByteArrayOutputStream,
|
||||
features: Seq[String]
|
||||
): Int = {
|
||||
val tempDir = TestUtils.tempDir()
|
||||
try {
|
||||
val arguments = ListBuffer[String]("feature-dependencies")
|
||||
features.foreach(feature => {
|
||||
arguments += "--feature"
|
||||
arguments += feature
|
||||
})
|
||||
StorageTool.execute(arguments.toArray, new PrintStream(stream))
|
||||
} finally {
|
||||
Utils.delete(tempDir)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
def testHandleFeatureDependenciesForFeatureWithDependencies(): Unit = {
|
||||
def testTestingFeatureDependencies(): Unit = {
|
||||
val stream = new ByteArrayOutputStream()
|
||||
assertEquals(0, runFeatureDependenciesCommand(stream, Seq("test.feature.version=2")))
|
||||
val namespace = StorageTool.parseArguments(Array("feature-dependencies", "--feature", "test.feature.version=2"))
|
||||
|
||||
val output = stream.toString
|
||||
val metadataVersion = MetadataVersion.latestTesting()
|
||||
|
||||
val expectedOutput = s"test.feature.version=2 requires:\n metadata.version=${metadataVersion.featureLevel()} (${metadataVersion.version()})\n"
|
||||
assertEquals(expectedOutput.trim, output.trim)
|
||||
}
|
||||
|
||||
@Test
|
||||
def testMultipleFeatureDependencies(): Unit = {
|
||||
val stream = new ByteArrayOutputStream()
|
||||
val features = Seq("transaction.version=2", "group.version=1", "test.feature.version=2")
|
||||
|
||||
assertEquals(0, runFeatureDependenciesCommand(stream, features))
|
||||
StorageTool.runFeatureDependenciesCommand(namespace, new PrintStream(stream), testingFeatures)
|
||||
|
||||
val output = stream.toString.trim
|
||||
System.out.println(output)
|
||||
|
@ -572,11 +549,27 @@ Found problem:
|
|||
val latestTestingVersion = MetadataVersion.latestTesting()
|
||||
val latestTestingVersionString = s"metadata.version=${latestTestingVersion.featureLevel()} (${latestTestingVersion.version()})"
|
||||
|
||||
val expectedOutput =
|
||||
s"""test.feature.version=2 requires:
|
||||
| $latestTestingVersionString
|
||||
|""".stripMargin.trim
|
||||
|
||||
assertEquals(expectedOutput, output)
|
||||
}
|
||||
|
||||
@Test
|
||||
def testMultipleFeatureDependencies(): Unit = {
|
||||
val stream = new ByteArrayOutputStream()
|
||||
val features = Seq("transaction.version=2", "group.version=1")
|
||||
|
||||
assertEquals(0, runFeatureDependenciesCommand(stream, features))
|
||||
|
||||
val output = stream.toString.trim
|
||||
System.out.println(output)
|
||||
|
||||
val expectedOutput =
|
||||
s"""transaction.version=2 has no dependencies.
|
||||
|group.version=1 has no dependencies.
|
||||
|test.feature.version=2 requires:
|
||||
| $latestTestingVersionString
|
||||
|""".stripMargin.trim
|
||||
|
||||
assertEquals(expectedOutput, output)
|
||||
|
|
|
@ -118,10 +118,10 @@ public class FeatureCommand {
|
|||
handleDisable(namespace, adminClient);
|
||||
break;
|
||||
case "version-mapping":
|
||||
handleVersionMapping(namespace);
|
||||
handleVersionMapping(namespace, Features.PRODUCTION_FEATURES);
|
||||
break;
|
||||
case "feature-dependencies":
|
||||
handleFeatureDependencies(namespace);
|
||||
handleFeatureDependencies(namespace, Features.PRODUCTION_FEATURES);
|
||||
break;
|
||||
default:
|
||||
throw new TerseException("Unknown command " + command);
|
||||
|
@ -138,7 +138,11 @@ public class FeatureCommand {
|
|||
Subparser upgradeParser = subparsers.addParser("upgrade")
|
||||
.help("Upgrade one or more feature flags.");
|
||||
upgradeParser.addArgument("--metadata")
|
||||
.help("The level to which we should upgrade the metadata. For example, 3.3-IV3.")
|
||||
.help("DEPRECATED -- The level to which we should upgrade the metadata. For example, 3.3-IV3.")
|
||||
.action(store());
|
||||
upgradeParser.addArgument("--release-version")
|
||||
.help("The release version to update all features to. For example, 3.9-IV0 will set metadata.version=21 and kraft.version=1." +
|
||||
" Use the version-mapping command to learn which features will be set for any given version.")
|
||||
.action(store());
|
||||
upgradeParser.addArgument("--feature")
|
||||
.help("A feature upgrade we should perform, in feature=level format. For example: `metadata.version=5`.")
|
||||
|
@ -153,7 +157,11 @@ public class FeatureCommand {
|
|||
Subparser downgradeParser = subparsers.addParser("downgrade")
|
||||
.help("Upgrade one or more feature flags.");
|
||||
downgradeParser.addArgument("--metadata")
|
||||
.help("The level to which we should downgrade the metadata. For example, 3.3-IV0.")
|
||||
.help("DEPRECATED -- The level to which we should downgrade the metadata. For example, 3.3-IV0.")
|
||||
.action(store());
|
||||
downgradeParser.addArgument("--release-version")
|
||||
.help("The release version to downgrade all features to. For example, 3.9-IV0 will set metadata.version=21 and kraft.version=1." +
|
||||
" Use the version-mapping command to learn which features will be set for any given version.")
|
||||
.action(store());
|
||||
downgradeParser.addArgument("--feature")
|
||||
.help("A feature downgrade we should perform, in feature=level format. For example: `metadata.version=5`.")
|
||||
|
@ -272,21 +280,51 @@ public class FeatureCommand {
|
|||
}
|
||||
|
||||
private static void handleUpgradeOrDowngrade(String op, Namespace namespace, Admin admin, FeatureUpdate.UpgradeType upgradeType) throws TerseException {
|
||||
Map<String, FeatureUpdate> updates = new HashMap<>();
|
||||
MetadataVersion version;
|
||||
String metadata = namespace.getString("metadata");
|
||||
if (metadata != null) {
|
||||
List<String> features = namespace.getList("feature");
|
||||
String releaseVersion = namespace.getString("release_version");
|
||||
|
||||
if (releaseVersion != null && (metadata != null || features != null)) {
|
||||
throw new TerseException("Can not specify `release-version` with other feature flags.");
|
||||
}
|
||||
|
||||
Map<String, FeatureUpdate> updates = new HashMap<>();
|
||||
MetadataVersion metadataVersion;
|
||||
|
||||
if (releaseVersion != null) {
|
||||
try {
|
||||
version = MetadataVersion.fromVersionString(metadata);
|
||||
metadataVersion = MetadataVersion.fromVersionString(releaseVersion);
|
||||
updates.put(metadataVersion.featureName(), new FeatureUpdate(metadataVersion.featureLevel(), upgradeType));
|
||||
} catch (Throwable e) {
|
||||
throw new TerseException("Unknown metadata.version " + releaseVersion +
|
||||
". Supported metadata.version are " + metadataVersionsToString(
|
||||
MetadataVersion.MINIMUM_BOOTSTRAP_VERSION, MetadataVersion.latestProduction()));
|
||||
}
|
||||
try {
|
||||
for (Features feature : Features.PRODUCTION_FEATURES) {
|
||||
short featureLevel = feature.defaultValue(metadataVersion);
|
||||
// Don't send a request to upgrade a feature to 0.
|
||||
if (upgradeType != FeatureUpdate.UpgradeType.UPGRADE || featureLevel > 0) {
|
||||
updates.put(feature.featureName(), new FeatureUpdate(featureLevel, upgradeType));
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new TerseException(upgradeType.name() + " for release version " + releaseVersion +
|
||||
" failed because at least one feature had the following error: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
if (metadata != null) {
|
||||
System.out.println(" `metadata` flag is deprecated and may be removed in a future release.");
|
||||
try {
|
||||
metadataVersion = MetadataVersion.fromVersionString(metadata);
|
||||
} catch (Throwable e) {
|
||||
throw new TerseException("Unknown metadata.version " + metadata +
|
||||
". Supported metadata.version are " + metadataVersionsToString(
|
||||
MetadataVersion.MINIMUM_BOOTSTRAP_VERSION, MetadataVersion.latestProduction()));
|
||||
}
|
||||
updates.put(MetadataVersion.FEATURE_NAME, new FeatureUpdate(version.featureLevel(), upgradeType));
|
||||
updates.put(MetadataVersion.FEATURE_NAME, new FeatureUpdate(metadataVersion.featureLevel(), upgradeType));
|
||||
}
|
||||
|
||||
List<String> features = namespace.getList("feature");
|
||||
if (features != null) {
|
||||
features.forEach(feature -> {
|
||||
String[] nameAndLevel;
|
||||
|
@ -297,6 +335,7 @@ public class FeatureCommand {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
update(op, admin, updates, namespace.getBoolean("dry_run"));
|
||||
}
|
||||
|
@ -317,7 +356,7 @@ public class FeatureCommand {
|
|||
update("disable", adminClient, updates, namespace.getBoolean("dry_run"));
|
||||
}
|
||||
|
||||
static void handleVersionMapping(Namespace namespace) throws TerseException {
|
||||
static void handleVersionMapping(Namespace namespace, List<Features> validFeatures) throws TerseException {
|
||||
// Get the release version from the command-line arguments or default to the latest stable version
|
||||
String releaseVersion = Optional.ofNullable(namespace.getString("release_version"))
|
||||
.orElseGet(() -> MetadataVersion.latestProduction().version());
|
||||
|
@ -328,7 +367,7 @@ public class FeatureCommand {
|
|||
short metadataVersionLevel = version.featureLevel();
|
||||
System.out.printf("metadata.version=%d (%s)%n", metadataVersionLevel, releaseVersion);
|
||||
|
||||
for (Features feature : Features.values()) {
|
||||
for (Features feature : validFeatures) {
|
||||
short featureLevel = feature.defaultValue(version);
|
||||
System.out.printf("%s=%d%n", feature.featureName(), featureLevel);
|
||||
}
|
||||
|
@ -339,7 +378,7 @@ public class FeatureCommand {
|
|||
}
|
||||
}
|
||||
|
||||
static void handleFeatureDependencies(Namespace namespace) throws TerseException {
|
||||
static void handleFeatureDependencies(Namespace namespace, List<Features> validFeatures) throws TerseException {
|
||||
List<String> featureArgs = namespace.getList("feature");
|
||||
|
||||
// Iterate over each feature specified with --feature
|
||||
|
@ -361,7 +400,7 @@ public class FeatureCommand {
|
|||
// Assuming metadata versions do not have dependencies.
|
||||
System.out.printf("%s=%d (%s) has no dependencies.%n", featureName, featureLevel, metadataVersion.version());
|
||||
} else {
|
||||
Features featureEnum = Arrays.stream(Features.FEATURES)
|
||||
Features featureEnum = validFeatures.stream()
|
||||
.filter(f -> f.featureName().equals(featureName))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new TerseException("Unknown feature: " + featureName));
|
||||
|
|
|
@ -49,6 +49,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
@ExtendWith(value = ClusterTestExtensions.class)
|
||||
public class FeatureCommandTest {
|
||||
|
||||
private final List<Features> testingFeatures = Arrays.stream(Features.FEATURES).collect(Collectors.toList());
|
||||
|
||||
@ClusterTest(types = {Type.KRAFT}, metadataVersion = MetadataVersion.IBP_3_3_IV1)
|
||||
public void testDescribeWithKRaft(ClusterInstance cluster) {
|
||||
String commandOutput = ToolsTestUtils.captureStandardOut(() ->
|
||||
|
@ -100,7 +102,7 @@ public class FeatureCommandTest {
|
|||
assertEquals(0, FeatureCommand.mainNoExit("--bootstrap-server", cluster.bootstrapServers(),
|
||||
"upgrade", "--metadata", "3.3-IV2"))
|
||||
);
|
||||
assertEquals("metadata.version was upgraded to 6.", commandOutput);
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nmetadata.version was upgraded to 6."), commandOutput);
|
||||
}
|
||||
|
||||
@ClusterTest(types = {Type.KRAFT}, metadataVersion = MetadataVersion.IBP_3_3_IV1)
|
||||
|
@ -118,16 +120,62 @@ public class FeatureCommandTest {
|
|||
"downgrade", "--metadata", "3.3-IV0"))
|
||||
|
||||
);
|
||||
assertEquals("Could not downgrade metadata.version to 4. The update failed for all features since the following " +
|
||||
"feature had an error: Invalid metadata.version 4. Refusing to perform the requested downgrade because it might delete metadata information.", commandOutput);
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nCould not downgrade metadata.version to 4." +
|
||||
" The update failed for all features since the following feature had an error: Invalid metadata.version 4." +
|
||||
" Refusing to perform the requested downgrade because it might delete metadata information."), commandOutput);
|
||||
|
||||
commandOutput = ToolsTestUtils.captureStandardOut(() ->
|
||||
assertEquals(1, FeatureCommand.mainNoExit("--bootstrap-server", cluster.bootstrapServers(),
|
||||
"downgrade", "--unsafe", "--metadata", "3.3-IV0"))
|
||||
|
||||
);
|
||||
assertEquals("Could not downgrade metadata.version to 4. The update failed for all features since the following " +
|
||||
"feature had an error: Invalid metadata.version 4. Unsafe metadata downgrade is not supported in this version.", commandOutput);
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nCould not downgrade metadata.version to 4." +
|
||||
" The update failed for all features since the following feature had an error: Invalid metadata.version 4." +
|
||||
" Unsafe metadata downgrade is not supported in this version."), commandOutput);
|
||||
}
|
||||
|
||||
@ClusterTest(types = {Type.KRAFT}, metadataVersion = MetadataVersion.IBP_3_8_IV0)
|
||||
public void testUpgradeWithReleaseVersion(ClusterInstance cluster) {
|
||||
String commandOutput = ToolsTestUtils.captureStandardOut(() ->
|
||||
assertEquals(1, FeatureCommand.mainNoExit("--bootstrap-server", cluster.bootstrapServers(),
|
||||
"upgrade", "--release-version", "3.7-IV3"))
|
||||
|
||||
);
|
||||
assertEquals("Could not upgrade metadata.version to 18. The update failed for all features since the following feature had an error:" +
|
||||
" Invalid update version 18 for feature metadata.version. Can't downgrade the version of this feature without setting the upgrade type to either safe or unsafe downgrade.", commandOutput);
|
||||
|
||||
commandOutput = ToolsTestUtils.captureStandardOut(() ->
|
||||
assertEquals(0, FeatureCommand.mainNoExit("--bootstrap-server", cluster.bootstrapServers(),
|
||||
"upgrade", "--release-version", "3.9-IV0"))
|
||||
);
|
||||
|
||||
assertEquals("kraft.version was upgraded to 1.\n" +
|
||||
"metadata.version was upgraded to 21.", commandOutput);
|
||||
}
|
||||
|
||||
@ClusterTest(types = {Type.KRAFT}, metadataVersion = MetadataVersion.IBP_3_8_IV0)
|
||||
public void testDowngradeWithReleaseVersion(ClusterInstance cluster) {
|
||||
String commandOutput = ToolsTestUtils.captureStandardOut(() ->
|
||||
assertEquals(1, FeatureCommand.mainNoExit("--bootstrap-server", cluster.bootstrapServers(),
|
||||
"downgrade", "--release-version", "3.9-IV0"))
|
||||
|
||||
);
|
||||
assertTrue(commandOutput.contains("The update failed for all features since the following feature had an error:" +
|
||||
" Invalid update version 1 for feature kraft.version. Can't downgrade to a newer version."));
|
||||
assertTrue(commandOutput.contains("Could not downgrade group.version to 0."));
|
||||
assertTrue(commandOutput.contains("Could not downgrade transaction.version to 0."));
|
||||
assertTrue(commandOutput.contains("Could not downgrade kraft.version to 1."));
|
||||
assertTrue(commandOutput.contains("Could not downgrade metadata.version to 21."));
|
||||
|
||||
commandOutput = ToolsTestUtils.captureStandardOut(() ->
|
||||
assertEquals(0, FeatureCommand.mainNoExit("--bootstrap-server", cluster.bootstrapServers(),
|
||||
"downgrade", "--release-version", "3.7-IV3"))
|
||||
|
||||
);
|
||||
assertEquals("group.version was downgraded to 0.\n" +
|
||||
"kraft.version was downgraded to 0.\n" +
|
||||
"metadata.version was downgraded to 18.\n" +
|
||||
"transaction.version was downgraded to 0.", commandOutput);
|
||||
}
|
||||
|
||||
private String outputWithoutEpoch(String output) {
|
||||
|
@ -213,7 +261,8 @@ public class FeatureCommandTest {
|
|||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleUpgrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("2 out of 2 operation(s) failed."));
|
||||
});
|
||||
assertEquals(format("Could not upgrade foo.bar to 6. Invalid update version 5 for feature metadata.version. Can't upgrade to lower version.%n" +
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nCould not upgrade foo.bar to 6." +
|
||||
" Invalid update version 5 for feature metadata.version. Can't upgrade to lower version.%n" +
|
||||
"Could not upgrade metadata.version to 5. Invalid update version 5 for feature metadata.version. Can't upgrade to lower version."), upgradeOutput);
|
||||
}
|
||||
|
||||
|
@ -227,7 +276,8 @@ public class FeatureCommandTest {
|
|||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleUpgrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("2 out of 2 operation(s) failed."));
|
||||
});
|
||||
assertEquals(format("Can not upgrade foo.bar to 6. Invalid update version 5 for feature metadata.version. Can't upgrade to lower version.%n" +
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nCan not upgrade foo.bar to 6." +
|
||||
" Invalid update version 5 for feature metadata.version. Can't upgrade to lower version.%n" +
|
||||
"Can not upgrade metadata.version to 5. Invalid update version 5 for feature metadata.version. Can't upgrade to lower version."), upgradeOutput);
|
||||
}
|
||||
|
||||
|
@ -241,7 +291,8 @@ public class FeatureCommandTest {
|
|||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleDowngrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("2 out of 2 operation(s) failed."));
|
||||
});
|
||||
assertEquals(format("Could not downgrade foo.bar to 1. Invalid update version 7 for feature metadata.version. Can't downgrade to newer version.%n" +
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nCould not downgrade foo.bar to 1." +
|
||||
" Invalid update version 7 for feature metadata.version. Can't downgrade to newer version.%n" +
|
||||
"Could not downgrade metadata.version to 7. Invalid update version 7 for feature metadata.version. Can't downgrade to newer version."), downgradeOutput);
|
||||
}
|
||||
|
||||
|
@ -255,8 +306,8 @@ public class FeatureCommandTest {
|
|||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleDowngrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("2 out of 2 operation(s) failed."));
|
||||
});
|
||||
assertEquals(format("Can not downgrade foo.bar to 1. Invalid update version 7 for feature metadata.version. Can't downgrade to newer version.%n" +
|
||||
"Can not downgrade metadata.version to 7. Invalid update version 7 for feature metadata.version. Can't downgrade to newer version."), downgradeOutput);
|
||||
assertEquals(format("`metadata` flag is deprecated and may be removed in a future release.%nCan not downgrade foo.bar to 1. Invalid update version 7 for feature metadata.version." +
|
||||
" Can't downgrade to newer version.%nCan not downgrade metadata.version to 7. Invalid update version 7 for feature metadata.version. Can't downgrade to newer version."), downgradeOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -287,13 +338,42 @@ public class FeatureCommandTest {
|
|||
"Can not disable quux. Invalid update version 0 for feature metadata.version. Can't downgrade below 4"), disableOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidReleaseVersion() {
|
||||
Map<String, Object> namespace = new HashMap<>();
|
||||
namespace.put("release_version", "foo");
|
||||
ToolsTestUtils.captureStandardOut(() -> {
|
||||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleUpgrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("Unknown metadata.version foo."));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncompatibleUpgradeFlags() {
|
||||
Map<String, Object> namespace = new HashMap<>();
|
||||
namespace.put("release_version", "3.3-IV3");
|
||||
namespace.put("feature", Arrays.asList("foo.bar", "metadata.version", "quux"));
|
||||
ToolsTestUtils.captureStandardOut(() -> {
|
||||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleUpgrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("Can not specify `release-version` with other feature flags."));
|
||||
});
|
||||
|
||||
|
||||
namespace.put("release_version", "3.3-IV3");
|
||||
namespace.put("metadata", "3.3-IV3");
|
||||
ToolsTestUtils.captureStandardOut(() -> {
|
||||
Throwable t = assertThrows(TerseException.class, () -> FeatureCommand.handleUpgrade(new Namespace(namespace), buildAdminClient()));
|
||||
assertTrue(t.getMessage().contains("Can not specify `release-version` with other feature flags."));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleVersionMappingWithValidReleaseVersion() {
|
||||
Map<String, Object> namespace = new HashMap<>();
|
||||
namespace.put("release_version", "3.3-IV3");
|
||||
String versionMappingOutput = ToolsTestUtils.captureStandardOut(() -> {
|
||||
try {
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace));
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace), testingFeatures);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -317,7 +397,7 @@ public class FeatureCommandTest {
|
|||
Map<String, Object> namespace = new HashMap<>();
|
||||
String versionMappingOutput = ToolsTestUtils.captureStandardOut(() -> {
|
||||
try {
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace));
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace), testingFeatures);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -342,7 +422,7 @@ public class FeatureCommandTest {
|
|||
namespace.put("release_version", "2.9-IV2");
|
||||
|
||||
TerseException exception1 = assertThrows(TerseException.class, () ->
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace))
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace), testingFeatures)
|
||||
);
|
||||
|
||||
assertEquals("Unknown release version '2.9-IV2'." +
|
||||
|
@ -352,7 +432,7 @@ public class FeatureCommandTest {
|
|||
namespace.put("release_version", "invalid");
|
||||
|
||||
TerseException exception2 = assertThrows(TerseException.class, () ->
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace))
|
||||
FeatureCommand.handleVersionMapping(new Namespace(namespace), testingFeatures)
|
||||
);
|
||||
|
||||
assertEquals("Unknown release version 'invalid'." +
|
||||
|
@ -367,7 +447,7 @@ public class FeatureCommandTest {
|
|||
|
||||
String output = ToolsTestUtils.captureStandardOut(() -> {
|
||||
try {
|
||||
FeatureCommand.handleFeatureDependencies(new Namespace(namespace));
|
||||
FeatureCommand.handleFeatureDependencies(new Namespace(namespace), testingFeatures);
|
||||
} catch (TerseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -389,7 +469,7 @@ public class FeatureCommandTest {
|
|||
|
||||
String output = ToolsTestUtils.captureStandardOut(() -> {
|
||||
try {
|
||||
FeatureCommand.handleFeatureDependencies(new Namespace(namespace));
|
||||
FeatureCommand.handleFeatureDependencies(new Namespace(namespace), testingFeatures);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -405,8 +485,8 @@ public class FeatureCommandTest {
|
|||
|
||||
Exception exception = assertThrows(
|
||||
TerseException.class,
|
||||
() -> FeatureCommand.handleFeatureDependencies(new Namespace(namespace)
|
||||
));
|
||||
() -> FeatureCommand.handleFeatureDependencies(new Namespace(namespace), testingFeatures)
|
||||
);
|
||||
|
||||
assertEquals("Unknown feature: unknown.feature", exception.getMessage());
|
||||
}
|
||||
|
@ -418,8 +498,8 @@ public class FeatureCommandTest {
|
|||
|
||||
Exception exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> FeatureCommand.handleFeatureDependencies(new Namespace(namespace)
|
||||
));
|
||||
() -> FeatureCommand.handleFeatureDependencies(new Namespace(namespace), testingFeatures)
|
||||
);
|
||||
|
||||
assertEquals("No feature:transaction.version with feature level 1000", exception.getMessage());
|
||||
}
|
||||
|
@ -431,7 +511,7 @@ public class FeatureCommandTest {
|
|||
|
||||
RuntimeException exception = assertThrows(
|
||||
RuntimeException.class,
|
||||
() -> FeatureCommand.handleFeatureDependencies(new Namespace(namespace))
|
||||
() -> FeatureCommand.handleFeatureDependencies(new Namespace(namespace), testingFeatures)
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
|
@ -451,7 +531,7 @@ public class FeatureCommandTest {
|
|||
|
||||
String output = ToolsTestUtils.captureStandardOut(() -> {
|
||||
try {
|
||||
FeatureCommand.handleFeatureDependencies(new Namespace(namespace));
|
||||
FeatureCommand.handleFeatureDependencies(new Namespace(namespace), testingFeatures);
|
||||
} catch (TerseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue