Skip to content

Commit 546a96d

Browse files
committed
test(kafka-connect): add regression tests for KafkaConnectRestartConnectors action
Add unit and integration tests for the KafkaConnectRestartConnectorsAction to prevent regression of issue #536 where specifying --connect-cluster caused a ClassCastException. Tests verify that: - Config properties have correct List type for CLI handling - Single string values are properly converted to lists - Multiple values work correctly - Specific cluster selection works in integration tests Closes #536
1 parent 85de46c commit 546a96d

2 files changed

Lines changed: 268 additions & 3 deletions

File tree

providers/jikkou-provider-kafka-connect/src/integration-test/java/io/streamthoughts/jikkou/kafka/connect/action/KafkaConnectRestartConnectorsActionIT.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import io.streamthoughts.jikkou.core.action.ExecutionResult;
1111
import io.streamthoughts.jikkou.core.action.ExecutionStatus;
1212
import io.streamthoughts.jikkou.core.config.Configuration;
13-
import io.streamthoughts.jikkou.core.extension.ExtensionContext;
1413
import io.streamthoughts.jikkou.core.models.ApiActionResultSet;
1514
import io.streamthoughts.jikkou.kafka.connect.BaseExtensionProviderIT;
1615
import io.streamthoughts.jikkou.kafka.connect.models.V1KafkaConnector;
@@ -28,8 +27,6 @@
2827
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
2928
class KafkaConnectRestartConnectorsActionIT extends BaseExtensionProviderIT {
3029

31-
private ExtensionContext context;
32-
3330
@BeforeEach
3431
void beforeEach() throws Exception {
3532
deployFilestreamSinkConnectorAndWait();
@@ -83,4 +80,72 @@ void shouldFailToRestartUnknownConnector() {
8380
Assertions.assertEquals(ExecutionStatus.FAILED, result.status());
8481
Assertions.assertEquals(List.of(new ExecutionError("Unknown connector: dummy", 404)), result.errors());
8582
}
83+
84+
@Test
85+
void shouldSucceedToRestartConnectorsForSpecificClusterWithSingleStringValue() {
86+
// GIVEN - Single string value for connect-cluster (simulating CLI: --connect-cluster=test)
87+
Configuration configuration = Configuration.of(
88+
KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER.key(), KAFKA_CONNECTOR_NAME
89+
);
90+
91+
// WHEN - Execute with specific cluster name as single string
92+
ApiActionResultSet<V1KafkaConnector> resultSet = api.execute(
93+
KafkaConnectRestartConnectorsAction.NAME,
94+
configuration
95+
);
96+
97+
// THEN - Should succeed without ClassCastException
98+
Assertions.assertNotNull(resultSet);
99+
Assertions.assertEquals(1, resultSet.results().size());
100+
ExecutionResult<V1KafkaConnector> result = resultSet.results().getFirst();
101+
Assertions.assertEquals(ExecutionStatus.SUCCEEDED, result.status(),
102+
"Should succeed when specifying a single connect-cluster as string value");
103+
Assertions.assertNotNull(result.data());
104+
}
105+
106+
@Test
107+
void shouldSucceedWithBothClusterAndConnectorAsStrings() {
108+
// GIVEN - Single string values for both options
109+
Configuration configuration = Configuration.of(
110+
KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER.key(), KAFKA_CONNECTOR_NAME,
111+
KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME.key(), "test",
112+
KafkaConnectRestartConnectorsAction.Config.INCLUDE_TASKS.key(), true
113+
);
114+
115+
// WHEN
116+
ApiActionResultSet<V1KafkaConnector> resultSet = api.execute(
117+
KafkaConnectRestartConnectorsAction.NAME,
118+
configuration
119+
);
120+
121+
// THEN
122+
Assertions.assertNotNull(resultSet);
123+
Assertions.assertEquals(1, resultSet.results().size());
124+
ExecutionResult<V1KafkaConnector> result = resultSet.results().getFirst();
125+
Assertions.assertEquals(ExecutionStatus.SUCCEEDED, result.status(),
126+
"Should succeed when specifying both connect-cluster and connector-name as strings");
127+
Assertions.assertNotNull(result.data());
128+
}
129+
130+
@Test
131+
void shouldSucceedToRestartConnectorsForSpecificClusterWithListValue() {
132+
// GIVEN - List value for connect-cluster
133+
Configuration configuration = Configuration.of(
134+
KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER.key(),
135+
List.of(KAFKA_CONNECTOR_NAME)
136+
);
137+
138+
// WHEN
139+
ApiActionResultSet<V1KafkaConnector> resultSet = api.execute(
140+
KafkaConnectRestartConnectorsAction.NAME,
141+
configuration
142+
);
143+
144+
// THEN
145+
Assertions.assertNotNull(resultSet);
146+
Assertions.assertEquals(1, resultSet.results().size());
147+
ExecutionResult<V1KafkaConnector> result = resultSet.results().getFirst();
148+
Assertions.assertEquals(ExecutionStatus.SUCCEEDED, result.status());
149+
Assertions.assertNotNull(result.data());
150+
}
86151
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright (c) The original authors
4+
*
5+
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
6+
*/
7+
package io.streamthoughts.jikkou.kafka.connect.action;
8+
9+
import io.streamthoughts.jikkou.core.config.ConfigProperty;
10+
import io.streamthoughts.jikkou.core.config.Configuration;
11+
import java.util.List;
12+
import java.util.Map;
13+
import org.junit.jupiter.api.Assertions;
14+
import org.junit.jupiter.api.Test;
15+
16+
/**
17+
* Unit tests for {@link KafkaConnectRestartConnectorsAction}.
18+
*/
19+
class KafkaConnectRestartConnectorsActionTest {
20+
21+
/**
22+
* Regression test for GitHub issue #536.
23+
* Verifies that CONNECT_CLUSTER config property has List as its raw type.
24+
* This ensures CLI correctly handles the option as a list type.
25+
*
26+
* @see <a href="https://github.com/streamthoughts/jikkou/issues/536">Issue #536</a>
27+
*/
28+
@Test
29+
void shouldHaveListTypeForConnectClusterConfigProperty() {
30+
// GIVEN
31+
ConfigProperty<List<String>> property = KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER;
32+
33+
// THEN
34+
Assertions.assertEquals(List.class, property.rawType(),
35+
"CONNECT_CLUSTER config property must have List as raw type to ensure CLI handles it correctly");
36+
}
37+
38+
/**
39+
* Regression test for GitHub issue #536.
40+
* Verifies that CONNECTOR_NAME config property has List as its raw type.
41+
*
42+
* @see <a href="https://github.com/streamthoughts/jikkou/issues/536">Issue #536</a>
43+
*/
44+
@Test
45+
void shouldHaveListTypeForConnectorNameConfigProperty() {
46+
// GIVEN
47+
ConfigProperty<List<String>> property = KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME;
48+
49+
// THEN
50+
Assertions.assertEquals(List.class, property.rawType(),
51+
"CONNECTOR_NAME config property must have List as raw type");
52+
}
53+
54+
/**
55+
* Regression test for GitHub issue #536.
56+
* Verifies that a single string value for connect-cluster is properly converted to a list.
57+
* This simulates the scenario where CLI passes --connect-cluster=example-cluster.
58+
*
59+
* @see <a href="https://github.com/streamthoughts/jikkou/issues/536">Issue #536</a>
60+
*/
61+
@Test
62+
void shouldHandleSingleStringValueForConnectCluster() {
63+
// GIVEN - Configuration with a single string value (simulating CLI input)
64+
Configuration configuration = Configuration.from(Map.of(
65+
KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER.key(), "example-cluster"
66+
));
67+
68+
// WHEN
69+
List<String> result = KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER
70+
.getOptional(configuration)
71+
.orElse(null);
72+
73+
// THEN - Should return a list containing the single value
74+
Assertions.assertNotNull(result, "Result should not be null");
75+
Assertions.assertEquals(1, result.size(), "Result should contain exactly one element");
76+
Assertions.assertEquals("example-cluster", result.get(0), "Result should contain the single cluster name");
77+
}
78+
79+
/**
80+
* Regression test for GitHub issue #536.
81+
* Verifies that a single string value for connector-name is properly converted to a list.
82+
*
83+
* @see <a href="https://github.com/streamthoughts/jikkou/issues/536">Issue #536</a>
84+
*/
85+
@Test
86+
void shouldHandleSingleStringValueForConnectorName() {
87+
// GIVEN - Configuration with a single string value (simulating CLI input)
88+
Configuration configuration = Configuration.from(Map.of(
89+
KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME.key(), "my-connector"
90+
));
91+
92+
// WHEN
93+
List<String> result = KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME
94+
.getOptional(configuration)
95+
.orElse(null);
96+
97+
// THEN - Should return a list containing the single value
98+
Assertions.assertNotNull(result, "Result should not be null");
99+
Assertions.assertEquals(1, result.size(), "Result should contain exactly one element");
100+
Assertions.assertEquals("my-connector", result.get(0), "Result should contain the single connector name");
101+
}
102+
103+
/**
104+
* Verifies that multiple values for connect-cluster are properly handled.
105+
*/
106+
@Test
107+
void shouldHandleMultipleValuesForConnectCluster() {
108+
// GIVEN - Configuration with a list of values
109+
Configuration configuration = Configuration.from(Map.of(
110+
KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER.key(),
111+
List.of("cluster-1", "cluster-2", "cluster-3")
112+
));
113+
114+
// WHEN
115+
List<String> result = KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER
116+
.getOptional(configuration)
117+
.orElse(null);
118+
119+
// THEN
120+
Assertions.assertNotNull(result, "Result should not be null");
121+
Assertions.assertEquals(3, result.size(), "Result should contain all cluster names");
122+
Assertions.assertTrue(result.contains("cluster-1"));
123+
Assertions.assertTrue(result.contains("cluster-2"));
124+
Assertions.assertTrue(result.contains("cluster-3"));
125+
}
126+
127+
/**
128+
* Verifies that multiple values for connector-name are properly handled.
129+
*/
130+
@Test
131+
void shouldHandleMultipleValuesForConnectorName() {
132+
// GIVEN - Configuration with a list of values
133+
Configuration configuration = Configuration.from(Map.of(
134+
KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME.key(),
135+
List.of("connector-1", "connector-2")
136+
));
137+
138+
// WHEN
139+
List<String> result = KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME
140+
.getOptional(configuration)
141+
.orElse(null);
142+
143+
// THEN
144+
Assertions.assertNotNull(result, "Result should not be null");
145+
Assertions.assertEquals(2, result.size(), "Result should contain all connector names");
146+
Assertions.assertTrue(result.contains("connector-1"));
147+
Assertions.assertTrue(result.contains("connector-2"));
148+
}
149+
150+
/**
151+
* Verifies that empty configuration returns empty Optional for connect-cluster.
152+
*/
153+
@Test
154+
void shouldReturnEmptyOptionalForMissingConnectCluster() {
155+
// GIVEN - Empty configuration
156+
Configuration configuration = Configuration.empty();
157+
158+
// WHEN
159+
var result = KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER
160+
.getOptional(configuration);
161+
162+
// THEN
163+
Assertions.assertTrue(result.isEmpty(), "Result should be empty for missing configuration");
164+
}
165+
166+
/**
167+
* Verifies that empty configuration returns empty Optional for connector-name.
168+
*/
169+
@Test
170+
void shouldReturnEmptyOptionalForMissingConnectorName() {
171+
// GIVEN - Empty configuration
172+
Configuration configuration = Configuration.empty();
173+
174+
// WHEN
175+
var result = KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME
176+
.getOptional(configuration);
177+
178+
// THEN
179+
Assertions.assertTrue(result.isEmpty(), "Result should be empty for missing configuration");
180+
}
181+
182+
/**
183+
* Verifies that configProperties() returns all expected config properties.
184+
*/
185+
@Test
186+
void shouldReturnAllConfigProperties() {
187+
// GIVEN
188+
KafkaConnectRestartConnectorsAction action = new KafkaConnectRestartConnectorsAction();
189+
190+
// WHEN
191+
var properties = action.configProperties();
192+
193+
// THEN
194+
Assertions.assertEquals(4, properties.size(), "Should have 4 config properties");
195+
Assertions.assertTrue(properties.contains(KafkaConnectRestartConnectorsAction.Config.CONNECTOR_NAME));
196+
Assertions.assertTrue(properties.contains(KafkaConnectRestartConnectorsAction.Config.CONNECT_CLUSTER));
197+
Assertions.assertTrue(properties.contains(KafkaConnectRestartConnectorsAction.Config.INCLUDE_TASKS));
198+
Assertions.assertTrue(properties.contains(KafkaConnectRestartConnectorsAction.Config.ONLY_FAILED));
199+
}
200+
}

0 commit comments

Comments
 (0)