Skip to content

Commit b94c7f9

Browse files
authored
MINOR: Extend @ApiKeyVersionsSource annotation (apache#19516)
This patch extends the `@ApiKeyVersionsSource` annotation to allow specifying the `fromVersion` and the `toVersion`. This is pretty handy when we only want to test a subset of the versions. Reviewers: Kuan-Po Tseng <[email protected]>, TengYao Chi <[email protected]>
1 parent 6e4e0df commit b94c7f9

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed

clients/src/test/java/org/apache/kafka/common/utils/annotation/ApiKeyVersionsProvider.java

+25-1
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,40 @@
2323
import org.junit.jupiter.params.provider.ArgumentsProvider;
2424
import org.junit.jupiter.params.support.AnnotationConsumer;
2525

26+
import java.util.stream.IntStream;
2627
import java.util.stream.Stream;
2728

2829
public class ApiKeyVersionsProvider implements ArgumentsProvider, AnnotationConsumer<ApiKeyVersionsSource> {
2930
private ApiKeys apiKey;
31+
private short fromVersion;
32+
private short toVersion;
3033

3134
public void accept(ApiKeyVersionsSource source) {
3235
apiKey = source.apiKey();
36+
37+
short oldestVersion = apiKey.oldestVersion();
38+
short latestVersion = apiKey.latestVersion(source.enableUnstableLastVersion());
39+
40+
fromVersion = source.fromVersion() == -1 ? oldestVersion : source.fromVersion();
41+
toVersion = source.toVersion() == -1 ? latestVersion : source.toVersion();
42+
43+
if (fromVersion > toVersion) {
44+
throw new IllegalArgumentException(String.format("The fromVersion %s is larger than the toVersion %s",
45+
fromVersion, toVersion));
46+
}
47+
48+
if (fromVersion < oldestVersion) {
49+
throw new IllegalArgumentException(String.format("The fromVersion %s is older than the oldest version %s",
50+
fromVersion, oldestVersion));
51+
}
52+
53+
if (toVersion > latestVersion) {
54+
throw new IllegalArgumentException(String.format("The toVersion %s is newer than the latest version %s",
55+
fromVersion, latestVersion));
56+
}
3357
}
3458

3559
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
36-
return apiKey.allVersions().stream().map(Arguments::of);
60+
return IntStream.rangeClosed(fromVersion, toVersion).mapToObj(i -> Arguments.of((short) i));
3761
}
3862
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.kafka.common.utils.annotation;
18+
19+
import org.apache.kafka.common.protocol.ApiKeys;
20+
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.ExtensionContext;
23+
24+
import java.util.List;
25+
import java.util.stream.Collectors;
26+
import java.util.stream.IntStream;
27+
28+
import static org.junit.jupiter.api.Assertions.assertEquals;
29+
import static org.junit.jupiter.api.Assertions.assertThrows;
30+
import static org.mockito.Mockito.mock;
31+
import static org.mockito.Mockito.when;
32+
33+
public class ApiKeyVersionsProviderTest {
34+
@Test
35+
void testProvideArgumentsWithExplicitRange() {
36+
ApiKeyVersionsProvider provider = new ApiKeyVersionsProvider();
37+
38+
ApiKeyVersionsSource mockSource = mock(ApiKeyVersionsSource.class);
39+
when(mockSource.apiKey()).thenReturn(ApiKeys.FETCH);
40+
when(mockSource.fromVersion()).thenReturn((short) 5);
41+
when(mockSource.toVersion()).thenReturn((short) 7);
42+
when(mockSource.enableUnstableLastVersion()).thenReturn(false);
43+
44+
provider.accept(mockSource);
45+
46+
List<Short> versions = provider.provideArguments(mock(ExtensionContext.class))
47+
.map(arg -> (Short) arg.get()[0])
48+
.collect(Collectors.toList());
49+
50+
assertEquals(List.of((short) 5, (short) 6, (short) 7), versions);
51+
}
52+
53+
@Test
54+
void testProvideArgumentsWithDefaultRange() {
55+
ApiKeyVersionsProvider provider = new ApiKeyVersionsProvider();
56+
57+
ApiKeyVersionsSource mockSource = mock(ApiKeyVersionsSource.class);
58+
when(mockSource.apiKey()).thenReturn(ApiKeys.METADATA);
59+
when(mockSource.fromVersion()).thenReturn((short) -1);
60+
when(mockSource.toVersion()).thenReturn((short) -1);
61+
when(mockSource.enableUnstableLastVersion()).thenReturn(false);
62+
63+
provider.accept(mockSource);
64+
65+
short oldest = ApiKeys.METADATA.oldestVersion();
66+
short latest = ApiKeys.METADATA.latestVersion(false);
67+
68+
List<Short> versions = provider.provideArguments(mock(ExtensionContext.class))
69+
.map(arg -> (Short) arg.get()[0])
70+
.collect(Collectors.toList());
71+
72+
List<Short> expected = IntStream
73+
.rangeClosed(oldest, latest)
74+
.mapToObj(i -> (short) i)
75+
.collect(Collectors.toList());
76+
77+
assertEquals(expected, versions);
78+
}
79+
80+
@Test
81+
void testInvalidRangeThrowsExceptionFromGreaterThanTo() {
82+
ApiKeyVersionsProvider provider = new ApiKeyVersionsProvider();
83+
84+
ApiKeyVersionsSource mockSource = mock(ApiKeyVersionsSource.class);
85+
when(mockSource.apiKey()).thenReturn(ApiKeys.FETCH);
86+
when(mockSource.fromVersion()).thenReturn((short) 10);
87+
when(mockSource.toVersion()).thenReturn((short) 5);
88+
when(mockSource.enableUnstableLastVersion()).thenReturn(false);
89+
90+
assertThrows(IllegalArgumentException.class, () -> provider.accept(mockSource));
91+
}
92+
93+
@Test
94+
void testFromVersionTooOldThrowsException() {
95+
ApiKeyVersionsProvider provider = new ApiKeyVersionsProvider();
96+
97+
ApiKeyVersionsSource mockSource = mock(ApiKeyVersionsSource.class);
98+
when(mockSource.apiKey()).thenReturn(ApiKeys.FETCH);
99+
when(mockSource.fromVersion()).thenReturn((short) (ApiKeys.FETCH.oldestVersion() - 1));
100+
when(mockSource.toVersion()).thenReturn((short) 10);
101+
when(mockSource.enableUnstableLastVersion()).thenReturn(false);
102+
103+
assertThrows(IllegalArgumentException.class, () -> provider.accept(mockSource));
104+
}
105+
106+
@Test
107+
void testToVersionTooNewThrowsException() {
108+
ApiKeyVersionsProvider provider = new ApiKeyVersionsProvider();
109+
110+
ApiKeyVersionsSource mockSource = mock(ApiKeyVersionsSource.class);
111+
when(mockSource.apiKey()).thenReturn(ApiKeys.FETCH);
112+
when(mockSource.fromVersion()).thenReturn((short) 0);
113+
when(mockSource.toVersion()).thenReturn((short) (ApiKeys.FETCH.latestVersion(true) + 1));
114+
when(mockSource.enableUnstableLastVersion()).thenReturn(true);
115+
116+
assertThrows(IllegalArgumentException.class, () -> provider.accept(mockSource));
117+
}
118+
}

clients/src/test/java/org/apache/kafka/common/utils/annotation/ApiKeyVersionsSource.java

+3
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@
3030
@ArgumentsSource(ApiKeyVersionsProvider.class)
3131
public @interface ApiKeyVersionsSource {
3232
ApiKeys apiKey();
33+
short fromVersion() default -1;
34+
short toVersion() default -1;
35+
boolean enableUnstableLastVersion() default true;
3336
}

0 commit comments

Comments
 (0)