Skip to content

Commit 5c89d5f

Browse files
committed
KAFKA-19941: Standardized property alignment for kafka-features.sh output
1 parent 07092d7 commit 5c89d5f

File tree

2 files changed

+106
-32
lines changed

2 files changed

+106
-32
lines changed

tools/src/main/java/org/apache/kafka/tools/FeatureCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ static void handleDescribe(Admin adminClient) throws ExecutionException, Interru
228228
featureMetadata.supportedFeatures().keySet().stream().sorted().forEach(feature -> {
229229
short finalizedLevel = (featureMetadata.finalizedFeatures().get(feature) == null) ? 0 : featureMetadata.finalizedFeatures().get(feature).maxVersionLevel();
230230
SupportedVersionRange range = featureMetadata.supportedFeatures().get(feature);
231-
System.out.printf("Feature: %s\t\tSupportedMinVersion: %s\t\tSupportedMaxVersion: %s\t\tFinalizedVersionLevel: %s\t\tEpoch: %s%n",
231+
System.out.printf("Feature: %-40s SupportedMinVersion: %-15s SupportedMaxVersion: %-15s FinalizedVersionLevel: %-15s Epoch: %s%n",
232232
feature,
233233
levelToString(feature, range.minVersion()),
234234
levelToString(feature, range.maxVersion()),

tools/src/test/java/org/apache/kafka/tools/FeatureCommandTest.java

Lines changed: 105 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.HashMap;
3232
import java.util.List;
3333
import java.util.Map;
34+
import java.util.regex.Pattern;
3435

3536
import static java.lang.String.format;
3637
import static org.apache.kafka.clients.admin.FeatureUpdate.UpgradeType.SAFE_DOWNGRADE;
@@ -52,21 +53,34 @@ public void testDescribeWithKRaft(ClusterInstance cluster) {
5253

5354
List<String> features = Arrays.stream(commandOutput.split("\n")).sorted().toList();
5455

55-
// Change expected message to reflect latest MetadataVersion (SupportedMaxVersion increases when adding a new version)
56-
assertEquals("Feature: eligible.leader.replicas.version\t\tSupportedMinVersion: 0\t\t" +
57-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(0)));
58-
assertEquals("Feature: group.version\t\tSupportedMinVersion: 0\t\t" +
59-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(1)));
60-
assertEquals("Feature: kraft.version\t\tSupportedMinVersion: 0\t\t" +
61-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(2)));
62-
assertEquals("Feature: metadata.version\t\tSupportedMinVersion: 3.3-IV3\t\t" +
63-
"SupportedMaxVersion: 4.3-IV0\t\tFinalizedVersionLevel: 3.3-IV3\t\t", outputWithoutEpoch(features.get(3)));
64-
assertEquals("Feature: share.version\t\tSupportedMinVersion: 0\t\t" +
65-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(4)));
66-
assertEquals("Feature: streams.version\t\tSupportedMinVersion: 0\t\t" +
67-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(5)));
68-
assertEquals("Feature: transaction.version\t\tSupportedMinVersion: 0\t\t" +
69-
"SupportedMaxVersion: 2\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(6)));
56+
assertFeatureOutput(
57+
"eligible.leader.replicas.version", "0", "1", "0",
58+
outputWithoutEpoch(features.get(0))
59+
);
60+
assertFeatureOutput(
61+
"group.version", "0", "1", "0",
62+
outputWithoutEpoch(features.get(1))
63+
);
64+
assertFeatureOutput(
65+
"kraft.version", "0", "1", "0",
66+
outputWithoutEpoch(features.get(2))
67+
);
68+
assertFeatureOutput(
69+
"metadata.version", "3.3-IV3", "4.3-IV0", "3.3-IV3",
70+
outputWithoutEpoch(features.get(3))
71+
);
72+
assertFeatureOutput(
73+
"share.version", "0", "1", "0",
74+
outputWithoutEpoch(features.get(4))
75+
);
76+
assertFeatureOutput(
77+
"streams.version", "0", "1", "0",
78+
outputWithoutEpoch(features.get(5))
79+
);
80+
assertFeatureOutput(
81+
"transaction.version", "0", "2", "0",
82+
outputWithoutEpoch(features.get(6))
83+
);
7084
}
7185

7286
// Use the first MetadataVersion that supports KIP-919
@@ -79,20 +93,34 @@ public void testDescribeWithKRaftAndBootstrapControllers(ClusterInstance cluster
7993
List<String> features = Arrays.stream(commandOutput.split("\n")).sorted().toList();
8094

8195
// Change expected message to reflect latest MetadataVersion (SupportedMaxVersion increases when adding a new version)
82-
assertEquals("Feature: eligible.leader.replicas.version\t\tSupportedMinVersion: 0\t\t" +
83-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(0)));
84-
assertEquals("Feature: group.version\t\tSupportedMinVersion: 0\t\t" +
85-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(1)));
86-
assertEquals("Feature: kraft.version\t\tSupportedMinVersion: 0\t\t" +
87-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(2)));
88-
assertEquals("Feature: metadata.version\t\tSupportedMinVersion: 3.3-IV3\t\t" +
89-
"SupportedMaxVersion: 4.3-IV0\t\tFinalizedVersionLevel: 3.7-IV0\t\t", outputWithoutEpoch(features.get(3)));
90-
assertEquals("Feature: share.version\t\tSupportedMinVersion: 0\t\t" +
91-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(4)));
92-
assertEquals("Feature: streams.version\t\tSupportedMinVersion: 0\t\t" +
93-
"SupportedMaxVersion: 1\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(5)));
94-
assertEquals("Feature: transaction.version\t\tSupportedMinVersion: 0\t\t" +
95-
"SupportedMaxVersion: 2\t\tFinalizedVersionLevel: 0\t\t", outputWithoutEpoch(features.get(6)));
96+
assertFeatureOutput(
97+
"eligible.leader.replicas.version", "0", "1", "0",
98+
outputWithoutEpoch(features.get(0))
99+
);
100+
assertFeatureOutput(
101+
"group.version", "0", "1", "0",
102+
outputWithoutEpoch(features.get(1))
103+
);
104+
assertFeatureOutput(
105+
"kraft.version", "0", "1", "0",
106+
outputWithoutEpoch(features.get(2))
107+
);
108+
assertFeatureOutput(
109+
"metadata.version", "3.3-IV3", "4.3-IV0", "3.7-IV0",
110+
outputWithoutEpoch(features.get(3))
111+
);
112+
assertFeatureOutput(
113+
"share.version", "0", "1", "0",
114+
outputWithoutEpoch(features.get(4))
115+
);
116+
assertFeatureOutput(
117+
"streams.version", "0", "1", "0",
118+
outputWithoutEpoch(features.get(5))
119+
);
120+
assertFeatureOutput(
121+
"transaction.version", "0", "2", "0",
122+
outputWithoutEpoch(features.get(6))
123+
);
96124
}
97125

98126
@ClusterTest(types = {Type.KRAFT}, metadataVersion = MetadataVersion.IBP_3_3_IV3)
@@ -257,8 +285,16 @@ public void testHandleDescribe() {
257285
throw new RuntimeException(e);
258286
}
259287
});
260-
assertEquals(format("Feature: foo.bar\t\tSupportedMinVersion: 0\t\tSupportedMaxVersion: 10\t\tFinalizedVersionLevel: 5\t\tEpoch: 123%n" +
261-
"Feature: metadata.version\t\tSupportedMinVersion: 3.3-IV3\t\tSupportedMaxVersion: 3.5-IV0\t\tFinalizedVersionLevel: 3.4-IV0\t\tEpoch: 123"), describeResult);
288+
289+
List<String> features = Arrays.stream(describeResult.split("\n")).sorted().toList();
290+
assertFeatureOutputWithEpoch(
291+
"foo.bar", "0", "10", "5", "123",
292+
features.get(0)
293+
);
294+
assertFeatureOutputWithEpoch(
295+
"metadata.version", "3.3-IV3", "3.5-IV0", "3.4-IV0", "123",
296+
features.get(1)
297+
);
262298
}
263299

264300
@Test
@@ -571,4 +607,42 @@ public void testHandleFeatureDependenciesForMultipleFeatures() {
571607

572608
assertEquals(expectedOutput.trim(), output.trim());
573609
}
610+
611+
private static void assertFeatureOutput(
612+
String expectedFeature,
613+
String expectedMinVersion,
614+
String expectedMaxVersion,
615+
String expectedFinalizedVersion,
616+
String actualFeature
617+
) {
618+
String featureFormattingRegex = String.format(
619+
"Feature:\\s+%s\\s+SupportedMinVersion:\\s+%s\\s+SupportedMaxVersion:\\s+%s\\s+FinalizedVersionLevel:\\s+%s\\s*$",
620+
Pattern.quote(expectedFeature),
621+
Pattern.quote(expectedMinVersion),
622+
Pattern.quote(expectedMaxVersion),
623+
Pattern.quote(expectedFinalizedVersion)
624+
);
625+
626+
assertTrue(actualFeature.matches(featureFormattingRegex));
627+
}
628+
629+
private static void assertFeatureOutputWithEpoch(
630+
String expectedFeature,
631+
String expectedMinVersion,
632+
String expectedMaxVersion,
633+
String expectedFinalizedVersion,
634+
String expectedEpoch,
635+
String actualFeature
636+
) {
637+
String featureFormattingRegex = String.format(
638+
"Feature:\\s+%s\\s+SupportedMinVersion:\\s+%s\\s+SupportedMaxVersion:\\s+%s\\s+FinalizedVersionLevel:\\s+%s\\s*Epoch:\\s+%s$",
639+
Pattern.quote(expectedFeature),
640+
Pattern.quote(expectedMinVersion),
641+
Pattern.quote(expectedMaxVersion),
642+
Pattern.quote(expectedFinalizedVersion),
643+
Pattern.quote(expectedEpoch)
644+
);
645+
646+
assertTrue(actualFeature.matches(featureFormattingRegex));
647+
}
574648
}

0 commit comments

Comments
 (0)