mirror of https://github.com/apache/kafka.git
KAFKA-16921 [5/N] Migrate test of connect module to Junit5 (Runtime subpackage) (#16350)
Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
This commit is contained in:
parent
3a3f9ce48e
commit
d5592d8fe6
|
@ -17,7 +17,7 @@
|
|||
package org.apache.kafka.connect.runtime.distributed;
|
||||
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
@ -25,8 +25,8 @@ import java.util.Collections;
|
|||
|
||||
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V1;
|
||||
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V2;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
public class ConnectProtocolCompatibilityTest {
|
||||
private static final String LEADER = "leader";
|
||||
|
|
|
@ -20,9 +20,11 @@ package org.apache.kafka.connect.runtime.distributed;
|
|||
import org.apache.kafka.clients.CommonClientConfigs;
|
||||
import org.apache.kafka.common.config.ConfigException;
|
||||
import org.apache.kafka.common.security.auth.SecurityProtocol;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
|
@ -43,18 +45,19 @@ import static org.apache.kafka.connect.runtime.distributed.DistributedConfig.GRO
|
|||
import static org.apache.kafka.connect.runtime.distributed.DistributedConfig.INTER_WORKER_KEY_GENERATION_ALGORITHM_CONFIG;
|
||||
import static org.apache.kafka.connect.runtime.distributed.DistributedConfig.INTER_WORKER_SIGNATURE_ALGORITHM_CONFIG;
|
||||
import static org.apache.kafka.connect.runtime.distributed.DistributedConfig.INTER_WORKER_VERIFICATION_ALGORITHMS_CONFIG;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class DistributedConfigTest {
|
||||
|
||||
public Map<String, String> configs() {
|
||||
|
@ -148,7 +151,7 @@ public class DistributedConfigTest {
|
|||
Set<String> supportedAlgorithms = DistributedConfig.supportedAlgorithms(type);
|
||||
Set<String> unsupportedAlgorithms = new HashSet<>(Arrays.asList(expectedAlgorithms));
|
||||
unsupportedAlgorithms.removeAll(supportedAlgorithms);
|
||||
assertEquals(type + " algorithms were found that should be supported by this JVM but are not", Collections.emptySet(), unsupportedAlgorithms);
|
||||
assertEquals(Collections.emptySet(), unsupportedAlgorithms, type + " algorithms were found that should be supported by this JVM but are not");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -72,13 +72,15 @@ import org.apache.kafka.connect.util.Callback;
|
|||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.apache.kafka.connect.util.FutureCallback;
|
||||
import org.apache.kafka.connect.util.Stage;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
@ -122,11 +124,11 @@ import static org.apache.kafka.connect.runtime.distributed.DistributedConfig.INT
|
|||
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V1;
|
||||
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V2;
|
||||
import static org.apache.kafka.connect.source.SourceTask.TransactionBoundary.CONNECTOR;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.mockito.AdditionalMatchers.leq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
@ -147,7 +149,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DistributedHerderTest {
|
||||
private static final Map<String, String> HERDER_CONFIG = new HashMap<>();
|
||||
|
@ -301,12 +304,11 @@ public class DistributedHerderTest {
|
|||
private final SampleConnectorClientConfigOverridePolicy
|
||||
noneConnectorClientConfigOverridePolicy = new SampleConnectorClientConfigOverridePolicy();
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
time = new MockTime();
|
||||
metrics = new MockConnectMetrics(time);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
AutoCloseable uponShutdown = () -> shutdownCalled.countDown();
|
||||
AutoCloseable uponShutdown = shutdownCalled::countDown;
|
||||
|
||||
// Default to the old protocol unless specified otherwise
|
||||
connectProtocolVersion = CONNECT_PROTOCOL_V0;
|
||||
|
@ -319,11 +321,9 @@ public class DistributedHerderTest {
|
|||
rebalanceListener = herder.new RebalanceListener(time);
|
||||
conn1SinkConfig = new SinkConnectorConfig(plugins, CONN1_CONFIG);
|
||||
conn1SinkConfigUpdated = new SinkConnectorConfig(plugins, CONN1_CONFIG_UPDATED);
|
||||
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
if (metrics != null) metrics.stop();
|
||||
if (herderExecutor != null) {
|
||||
|
@ -333,10 +333,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testJoinAssignment() throws Exception {
|
||||
public void testJoinAssignment() {
|
||||
// Join group and get assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, singletonList(CONN1), singletonList(TASK1));
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -357,10 +359,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRebalance() throws Exception {
|
||||
public void testRebalance() {
|
||||
// Join group and get assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, singletonList(CONN1), singletonList(TASK1));
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -401,12 +405,14 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testIncrementalCooperativeRebalanceForNewMember() throws Exception {
|
||||
public void testIncrementalCooperativeRebalanceForNewMember() {
|
||||
connectProtocolVersion = CONNECT_PROTOCOL_V1;
|
||||
// Join group. First rebalance contains revocations from other members. For the new
|
||||
// member the assignment should be empty
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V1);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList());
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -478,7 +484,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testIncrementalCooperativeRebalanceWithDelay() throws Exception {
|
||||
public void testIncrementalCooperativeRebalanceWithDelay() {
|
||||
connectProtocolVersion = CONNECT_PROTOCOL_V1;
|
||||
// Join group. First rebalance contains some assignments but also a delay, because a
|
||||
// member was detected missing
|
||||
|
@ -486,6 +492,8 @@ public class DistributedHerderTest {
|
|||
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V1);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(Collections.emptyList(), Collections.emptyList(),
|
||||
ConnectProtocol.Assignment.NO_ERROR, 1,
|
||||
Collections.emptyList(), singletonList(TASK2),
|
||||
|
@ -530,10 +538,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRebalanceFailedConnector() throws Exception {
|
||||
public void testRebalanceFailedConnector() {
|
||||
// Join group and get assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, singletonList(CONN1), singletonList(TASK1));
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -574,16 +584,20 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRevoke() throws TimeoutException {
|
||||
public void testRevoke() {
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
revokeAndReassign(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncompleteRebalanceBeforeRevoke() throws TimeoutException {
|
||||
public void testIncompleteRebalanceBeforeRevoke() {
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
revokeAndReassign(true);
|
||||
}
|
||||
|
||||
public void revokeAndReassign(boolean incompleteRebalance) throws TimeoutException {
|
||||
public void revokeAndReassign(boolean incompleteRebalance) {
|
||||
connectProtocolVersion = CONNECT_PROTOCOL_V1;
|
||||
int configOffset = 1;
|
||||
|
||||
|
@ -681,9 +695,10 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConnector() throws Exception {
|
||||
public void testCreateConnector() {
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -736,9 +751,10 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConnectorWithInitialState() throws Exception {
|
||||
public void testCreateConnectorWithInitialState() {
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -843,7 +859,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConnectorFailedValidation() throws Exception {
|
||||
public void testCreateConnectorFailedValidation() {
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
|
@ -933,7 +949,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConnectorAlreadyExists() throws Exception {
|
||||
public void testCreateConnectorAlreadyExists() {
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
|
@ -976,7 +992,8 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyConnector() throws Exception {
|
||||
public void testDestroyConnector() {
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
// Start with one connector
|
||||
|
@ -1045,6 +1062,7 @@ public class DistributedHerderTest {
|
|||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList(), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -1077,7 +1095,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartUnknownConnector() throws Exception {
|
||||
public void testRestartUnknownConnector() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1101,7 +1119,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorRedirectToLeader() throws Exception {
|
||||
public void testRestartConnectorRedirectToLeader() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1125,7 +1143,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorRedirectToOwner() throws Exception {
|
||||
public void testRestartConnectorRedirectToOwner() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1160,7 +1178,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksUnknownConnector() throws Exception {
|
||||
public void testRestartConnectorAndTasksUnknownConnector() {
|
||||
String connectorName = "UnknownConnector";
|
||||
RestartRequest restartRequest = new RestartRequest(connectorName, false, true);
|
||||
|
||||
|
@ -1189,7 +1207,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksNotLeader() throws Exception {
|
||||
public void testRestartConnectorAndTasksNotLeader() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1214,7 +1232,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksUnknownStatus() throws Exception {
|
||||
public void testRestartConnectorAndTasksUnknownStatus() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1345,6 +1363,7 @@ public class DistributedHerderTest {
|
|||
when(herder.assignment.connectors()).thenReturn(Collections.emptyList());
|
||||
// But only one task is assigned to this worker
|
||||
when(herder.assignment.tasks()).thenReturn(Collections.singletonList(TASK0));
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
herder.configState = SNAPSHOT;
|
||||
|
||||
|
@ -1368,6 +1387,7 @@ public class DistributedHerderTest {
|
|||
when(restartPlan.shouldRestartConnector()).thenReturn(true);
|
||||
when(restartPlan.taskIdsToRestart()).thenReturn(Collections.singletonList(taskId));
|
||||
when(restartPlan.totalTaskCount()).thenReturn(1);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
doReturn(Optional.of(restartPlan)).when(herder).buildRestartPlan(restartRequest);
|
||||
|
||||
herder.assignment = mock(ExtendedAssignment.class);
|
||||
|
@ -1405,6 +1425,7 @@ public class DistributedHerderTest {
|
|||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, Collections.emptyList(), singletonList(TASK0), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -1429,7 +1450,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartUnknownTask() throws Exception {
|
||||
public void testRestartUnknownTask() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1451,7 +1472,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartTaskRedirectToLeader() throws Exception {
|
||||
public void testRestartTaskRedirectToLeader() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1474,7 +1495,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRestartTaskRedirectToOwner() throws Exception {
|
||||
public void testRestartTaskRedirectToOwner() {
|
||||
// get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -1519,8 +1540,9 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorConfigAdded() throws Exception {
|
||||
public void testConnectorConfigAdded() {
|
||||
// If a connector was added, we need to rebalance
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
||||
|
@ -1531,7 +1553,7 @@ public class DistributedHerderTest {
|
|||
herder.tick(); // join
|
||||
|
||||
// Checks for config updates and starts rebalance
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
when(configBackingStore.snapshot()).thenReturn(SNAPSHOT);
|
||||
// Rebalance will be triggered when the new config is detected
|
||||
doNothing().when(member).requestRejoin();
|
||||
|
||||
|
@ -1556,11 +1578,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorConfigUpdate() throws Exception {
|
||||
public void testConnectorConfigUpdate() {
|
||||
// Connector config can be applied without any rebalance
|
||||
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
|
||||
// join
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList());
|
||||
|
@ -1590,11 +1613,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorConfigUpdateFailedTransformation() throws Exception {
|
||||
public void testConnectorConfigUpdateFailedTransformation() {
|
||||
// Connector config can be applied without any rebalance
|
||||
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
|
||||
WorkerConfigTransformer configTransformer = mock(WorkerConfigTransformer.class);
|
||||
// join
|
||||
|
@ -1647,11 +1671,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorPaused() throws Exception {
|
||||
public void testConnectorPaused() {
|
||||
// ensure that target state changes are propagated to the worker
|
||||
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
|
||||
// join
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList());
|
||||
|
@ -1686,9 +1711,10 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorResumed() throws Exception {
|
||||
public void testConnectorResumed() {
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
|
||||
// start with the connector paused
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList());
|
||||
|
@ -1724,11 +1750,12 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorStopped() throws Exception {
|
||||
public void testConnectorStopped() {
|
||||
// ensure that target state changes are propagated to the worker
|
||||
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
|
||||
// join
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList());
|
||||
|
@ -1763,9 +1790,10 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownConnectorPaused() throws Exception {
|
||||
public void testUnknownConnectorPaused() {
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
// join
|
||||
expectRebalance(1, Collections.emptyList(), singletonList(TASK0));
|
||||
|
@ -1788,6 +1816,7 @@ public class DistributedHerderTest {
|
|||
|
||||
@Test
|
||||
public void testStopConnector() throws Exception {
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
||||
|
@ -1813,16 +1842,17 @@ public class DistributedHerderTest {
|
|||
herder.stopConnector(CONN1, cb); // external request
|
||||
herder.tick(); // continue
|
||||
|
||||
assertTrue("Callback should already have been invoked by herder", cb.isDone());
|
||||
assertTrue(cb.isDone(), "Callback should already have been invoked by herder");
|
||||
cb.get(0, TimeUnit.MILLISECONDS);
|
||||
|
||||
verifyNoMoreInteractions(worker, member, configBackingStore, statusBackingStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopConnectorNotLeader() throws Exception {
|
||||
public void testStopConnectorNotLeader() {
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
// join as member (non-leader)
|
||||
expectRebalance(1, Collections.emptyList(), singletonList(TASK0));
|
||||
|
@ -1840,11 +1870,11 @@ public class DistributedHerderTest {
|
|||
herder.stopConnector(CONN1, cb); // external request
|
||||
herder.tick(); // continue
|
||||
|
||||
assertTrue("Callback should already have been invoked by herder", cb.isDone());
|
||||
assertTrue(cb.isDone(), "Callback should already have been invoked by herder");
|
||||
ExecutionException e = assertThrows(
|
||||
"Should not be able to handle request to stop connector when not leader",
|
||||
ExecutionException.class,
|
||||
() -> cb.get(0, TimeUnit.SECONDS)
|
||||
ExecutionException.class,
|
||||
() -> cb.get(0, TimeUnit.SECONDS),
|
||||
"Should not be able to handle request to stop connector when not leader"
|
||||
);
|
||||
assertInstanceOf(NotLeaderException.class, e.getCause());
|
||||
|
||||
|
@ -1852,9 +1882,10 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testStopConnectorFailToWriteTaskConfigs() throws Exception {
|
||||
public void testStopConnectorFailToWriteTaskConfigs() {
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
// join as leader
|
||||
expectRebalance(1, Collections.emptyList(), singletonList(TASK0), true);
|
||||
|
@ -1880,11 +1911,11 @@ public class DistributedHerderTest {
|
|||
herder.stopConnector(CONN1, cb); // external request
|
||||
herder.tick(); // continue
|
||||
|
||||
assertTrue("Callback should already have been invoked by herder", cb.isDone());
|
||||
assertTrue(cb.isDone(), "Callback should already have been invoked by herder");
|
||||
ExecutionException e = assertThrows(
|
||||
"Should not be able to handle request to stop connector when not leader",
|
||||
ExecutionException.class,
|
||||
() -> cb.get(0, TimeUnit.SECONDS)
|
||||
ExecutionException.class,
|
||||
() -> cb.get(0, TimeUnit.SECONDS),
|
||||
"Should not be able to handle request to stop connector when not leader"
|
||||
);
|
||||
assertEquals(e.getCause(), taskConfigsWriteException);
|
||||
|
||||
|
@ -1892,10 +1923,11 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorPausedRunningTaskOnly() throws Exception {
|
||||
public void testConnectorPausedRunningTaskOnly() {
|
||||
// even if we don't own the connector, we should still propagate target state
|
||||
// changes to the worker so that tasks will transition correctly
|
||||
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
||||
|
@ -1926,10 +1958,11 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConnectorResumedRunningTaskOnly() throws Exception {
|
||||
public void testConnectorResumedRunningTaskOnly() {
|
||||
// even if we don't own the connector, we should still propagate target state
|
||||
// changes to the worker so that tasks will transition correctly
|
||||
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
||||
|
@ -1951,7 +1984,6 @@ public class DistributedHerderTest {
|
|||
onStart.getValue().onCompletion(null, TargetState.PAUSED);
|
||||
return null;
|
||||
}).when(worker).setTargetState(eq(CONN1), eq(TargetState.STARTED), onStart.capture());
|
||||
expectExecuteTaskReconfiguration(false, null, null);
|
||||
|
||||
configUpdateListener.onConnectorTargetStateChange(CONN1); // state changes to paused
|
||||
herder.tick(); // apply state change
|
||||
|
@ -1966,6 +1998,7 @@ public class DistributedHerderTest {
|
|||
// Task config always requires rebalance
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
// join
|
||||
expectRebalance(-1, Collections.emptyList(), Collections.emptyList());
|
||||
|
@ -1985,7 +2018,6 @@ public class DistributedHerderTest {
|
|||
expectRebalance(Collections.emptyList(), Collections.emptyList(),
|
||||
ConnectProtocol.Assignment.NO_ERROR, 1, Collections.emptyList(),
|
||||
singletonList(TASK0));
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
when(worker.startSourceTask(eq(TASK0), any(), any(), any(), eq(herder), eq(TargetState.STARTED))).thenReturn(true);
|
||||
|
||||
herder.tick(); // do rebalance
|
||||
|
@ -2000,6 +2032,8 @@ public class DistributedHerderTest {
|
|||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(configBackingStore.snapshot()).thenReturn(SNAPSHOT);
|
||||
when(statusBackingStore.connectors()).thenReturn(Collections.emptySet());
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
expectRebalance(Collections.emptyList(), Collections.emptyList(),
|
||||
ConnectProtocol.Assignment.CONFIG_MISMATCH, 1, "leader", "leaderUrl", Collections.emptyList(),
|
||||
|
@ -2059,6 +2093,8 @@ public class DistributedHerderTest {
|
|||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V1);
|
||||
when(statusBackingStore.connectors()).thenReturn(Collections.emptySet());
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, singletonList(CONN1), singletonList(TASK1), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -2133,6 +2169,8 @@ public class DistributedHerderTest {
|
|||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V1);
|
||||
when(statusBackingStore.connectors()).thenReturn(Collections.emptySet());
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, singletonList(CONN1), singletonList(TASK1), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -2212,6 +2250,7 @@ public class DistributedHerderTest {
|
|||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(statusBackingStore.connectors()).thenReturn(Collections.emptySet());
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
|
||||
|
@ -2275,6 +2314,8 @@ public class DistributedHerderTest {
|
|||
|
||||
@Test
|
||||
public void testPutConnectorConfig() throws Exception {
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList(), true);
|
||||
when(statusBackingStore.connectors()).thenReturn(Collections.emptySet());
|
||||
|
@ -2398,7 +2439,6 @@ public class DistributedHerderTest {
|
|||
|
||||
// Patch the connector config.
|
||||
|
||||
expectMemberEnsureActive();
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList(), false);
|
||||
|
||||
FutureCallback<Herder.Created<ConnectorInfo>> patchCallback = new FutureCallback<>();
|
||||
|
@ -2411,8 +2451,8 @@ public class DistributedHerderTest {
|
|||
|
||||
@Test
|
||||
public void testPatchConnectorConfig() throws Exception {
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList(), true);
|
||||
when(statusBackingStore.connectors()).thenReturn(Collections.emptySet());
|
||||
|
||||
Map<String, String> originalConnConfig = new HashMap<>(CONN1_CONFIG);
|
||||
|
@ -2451,7 +2491,6 @@ public class DistributedHerderTest {
|
|||
patchedConnConfig.remove("foo2");
|
||||
patchedConnConfig.put("foo3", "added");
|
||||
|
||||
expectMemberEnsureActive();
|
||||
expectRebalance(1, singletonList(CONN1), Collections.emptyList(), true);
|
||||
|
||||
ArgumentCaptor<Callback<ConfigInfos>> validateCallback = ArgumentCaptor.forClass(Callback.class);
|
||||
|
@ -2476,7 +2515,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testKeyRotationWhenWorkerBecomesLeader() throws Exception {
|
||||
public void testKeyRotationWhenWorkerBecomesLeader() {
|
||||
long rotationTtlDelay = DistributedConfig.INTER_WORKER_KEY_TTL_MS_MS_DEFAULT;
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V2);
|
||||
|
@ -2529,7 +2568,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testKeyRotationDisabledWhenWorkerBecomesFollower() throws Exception {
|
||||
public void testKeyRotationDisabledWhenWorkerBecomesFollower() {
|
||||
long rotationTtlDelay = DistributedConfig.INTER_WORKER_KEY_TTL_MS_MS_DEFAULT;
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V2);
|
||||
|
@ -2710,7 +2749,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testFailedToWriteSessionKey() throws Exception {
|
||||
public void testFailedToWriteSessionKey() {
|
||||
// First tick -- after joining the group, we try to write a new
|
||||
// session key to the config topic, and fail
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
|
@ -2878,6 +2917,7 @@ public class DistributedHerderTest {
|
|||
|
||||
@Test
|
||||
public void testExternalZombieFencingRequestForAlreadyFencedConnector() throws Exception {
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
ClusterConfigState configState = exactlyOnceSnapshot(
|
||||
expectNewSessionKey(),
|
||||
TASK_CONFIGS_MAP,
|
||||
|
@ -2890,6 +2930,7 @@ public class DistributedHerderTest {
|
|||
|
||||
@Test
|
||||
public void testExternalZombieFencingRequestForSingleTaskConnector() throws Exception {
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
ClusterConfigState configState = exactlyOnceSnapshot(
|
||||
expectNewSessionKey(),
|
||||
Collections.singletonMap(TASK1, TASK_CONFIG),
|
||||
|
@ -2902,6 +2943,7 @@ public class DistributedHerderTest {
|
|||
|
||||
@Test
|
||||
public void testExternalZombieFencingRequestForFreshConnector() throws Exception {
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
ClusterConfigState configState = exactlyOnceSnapshot(
|
||||
expectNewSessionKey(),
|
||||
TASK_CONFIGS_MAP,
|
||||
|
@ -2954,6 +2996,7 @@ public class DistributedHerderTest {
|
|||
expectHerderStartup();
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V2);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
SessionKey sessionKey = expectNewSessionKey();
|
||||
|
@ -3013,6 +3056,7 @@ public class DistributedHerderTest {
|
|||
expectHerderStartup();
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V2);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
SessionKey sessionKey = expectNewSessionKey();
|
||||
|
@ -3056,6 +3100,7 @@ public class DistributedHerderTest {
|
|||
expectHerderStartup();
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V2);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
SessionKey sessionKey = expectNewSessionKey();
|
||||
|
@ -3125,6 +3170,7 @@ public class DistributedHerderTest {
|
|||
expectHerderStartup();
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V2);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
SessionKey sessionKey = expectNewSessionKey();
|
||||
|
@ -3335,6 +3381,7 @@ public class DistributedHerderTest {
|
|||
final long maxPollWaitMs = rebalanceDelayMs - operationDelayMs;
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(connectProtocolVersion);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
|
||||
// Assign the connector to this worker, and have it start
|
||||
expectRebalance(Collections.emptyList(), Collections.emptyList(), ConnectProtocol.Assignment.NO_ERROR, 1, singletonList(CONN1), Collections.emptyList(), rebalanceDelayMs);
|
||||
|
@ -3396,6 +3443,7 @@ public class DistributedHerderTest {
|
|||
public void testTaskReconfigurationRetriesWithConnectorTaskConfigsException() {
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -3417,6 +3465,7 @@ public class DistributedHerderTest {
|
|||
// initial tick
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -3463,6 +3512,7 @@ public class DistributedHerderTest {
|
|||
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(worker.isSinkConnector(CONN1)).thenReturn(Boolean.TRUE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), false);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT);
|
||||
|
||||
|
@ -3615,8 +3665,8 @@ public class DistributedHerderTest {
|
|||
List<String> errors = validatedConfigs.get(SourceConnectorConfig.EXACTLY_ONCE_SUPPORT_CONFIG).errorMessages();
|
||||
assertFalse(errors.isEmpty());
|
||||
assertTrue(
|
||||
"Error message did not contain expected text: " + errors.get(0),
|
||||
errors.get(0).contains("The connector does not implement the API required for preflight validation of exactly-once source support."));
|
||||
errors.get(0).contains("The connector does not implement the API required for preflight validation of exactly-once source support."),
|
||||
"Error message did not contain expected text: " + errors.get(0));
|
||||
assertEquals(1, errors.size());
|
||||
}
|
||||
|
||||
|
@ -3636,8 +3686,8 @@ public class DistributedHerderTest {
|
|||
List<String> errors = validatedConfigs.get(SourceConnectorConfig.EXACTLY_ONCE_SUPPORT_CONFIG).errorMessages();
|
||||
assertFalse(errors.isEmpty());
|
||||
assertTrue(
|
||||
"Error message did not contain expected text: " + errors.get(0),
|
||||
errors.get(0).contains(errorMessage));
|
||||
errors.get(0).contains(errorMessage),
|
||||
"Error message did not contain expected text: " + errors.get(0));
|
||||
assertEquals(1, errors.size());
|
||||
}
|
||||
|
||||
|
@ -3672,8 +3722,8 @@ public class DistributedHerderTest {
|
|||
List<String> errors = validatedConfigs.get(SourceConnectorConfig.EXACTLY_ONCE_SUPPORT_CONFIG).errorMessages();
|
||||
assertFalse(errors.isEmpty());
|
||||
assertTrue(
|
||||
"Error message did not contain expected text: " + errors.get(0),
|
||||
errors.get(0).contains("String must be one of (case insensitive): "));
|
||||
errors.get(0).contains("String must be one of (case insensitive): "),
|
||||
"Error message did not contain expected text: " + errors.get(0));
|
||||
assertEquals(1, errors.size());
|
||||
}
|
||||
|
||||
|
@ -3710,8 +3760,8 @@ public class DistributedHerderTest {
|
|||
List<String> errors = validatedConfigs.get(SourceConnectorConfig.TRANSACTION_BOUNDARY_CONFIG).errorMessages();
|
||||
assertFalse(errors.isEmpty());
|
||||
assertTrue(
|
||||
"Error message did not contain expected text: " + errors.get(0),
|
||||
errors.get(0).contains("The connector does not support connector-defined transaction boundaries with the given configuration."));
|
||||
errors.get(0).contains("The connector does not support connector-defined transaction boundaries with the given configuration."),
|
||||
"Error message did not contain expected text: " + errors.get(0));
|
||||
assertEquals(1, errors.size());
|
||||
}
|
||||
|
||||
|
@ -3731,8 +3781,8 @@ public class DistributedHerderTest {
|
|||
List<String> errors = validatedConfigs.get(SourceConnectorConfig.TRANSACTION_BOUNDARY_CONFIG).errorMessages();
|
||||
assertFalse(errors.isEmpty());
|
||||
assertTrue(
|
||||
"Error message did not contain expected text: " + errors.get(0),
|
||||
errors.get(0).contains(errorMessage));
|
||||
errors.get(0).contains(errorMessage),
|
||||
"Error message did not contain expected text: " + errors.get(0));
|
||||
assertEquals(1, errors.size());
|
||||
}
|
||||
|
||||
|
@ -3750,8 +3800,8 @@ public class DistributedHerderTest {
|
|||
List<String> errors = validatedConfigs.get(SourceConnectorConfig.TRANSACTION_BOUNDARY_CONFIG).errorMessages();
|
||||
assertFalse(errors.isEmpty());
|
||||
assertTrue(
|
||||
"Error message did not contain expected text: " + errors.get(0),
|
||||
errors.get(0).contains("String must be one of (case insensitive): "));
|
||||
errors.get(0).contains("String must be one of (case insensitive): "),
|
||||
"Error message did not contain expected text: " + errors.get(0));
|
||||
assertEquals(1, errors.size());
|
||||
}
|
||||
|
||||
|
@ -3787,7 +3837,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testModifyConnectorOffsetsUnknownConnector() throws Exception {
|
||||
public void testModifyConnectorOffsetsUnknownConnector() {
|
||||
// Get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -3805,7 +3855,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testModifyOffsetsConnectorNotInStoppedState() throws Exception {
|
||||
public void testModifyOffsetsConnectorNotInStoppedState() {
|
||||
// Get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -3823,7 +3873,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testModifyOffsetsNotLeader() throws Exception {
|
||||
public void testModifyOffsetsNotLeader() {
|
||||
// Get the initial assignment
|
||||
when(member.memberId()).thenReturn("member");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
|
@ -3875,6 +3925,7 @@ public class DistributedHerderTest {
|
|||
// Get the initial assignment
|
||||
when(member.memberId()).thenReturn("leader");
|
||||
when(member.currentProtocolVersion()).thenReturn(CONNECT_PROTOCOL_V0);
|
||||
when(herder.connectorType(anyMap())).thenReturn(ConnectorType.SOURCE);
|
||||
expectRebalance(1, Collections.emptyList(), Collections.emptyList(), true);
|
||||
expectConfigRefreshAndSnapshot(SNAPSHOT_STOPPED_CONN1);
|
||||
herder.tick();
|
||||
|
@ -3960,7 +4011,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testModifyOffsetsSourceConnectorExactlyOnceEnabledZombieFencingFailure() throws Exception {
|
||||
public void testModifyOffsetsSourceConnectorExactlyOnceEnabledZombieFencingFailure() {
|
||||
// Setup herder with exactly-once support for source connectors enabled
|
||||
herder = exactlyOnceHerder();
|
||||
rebalanceListener = herder.new RebalanceListener(time);
|
||||
|
@ -4209,7 +4260,7 @@ public class DistributedHerderTest {
|
|||
private void stopBackgroundHerder() throws Exception {
|
||||
herder.stop();
|
||||
herderExecutor.shutdown();
|
||||
assertTrue("herder thread did not finish in time", herderExecutor.awaitTermination(10, TimeUnit.SECONDS));
|
||||
assertTrue(herderExecutor.awaitTermination(10, TimeUnit.SECONDS), "herder thread did not finish in time");
|
||||
herderFuture.get();
|
||||
assertTrue(noneConnectorClientConfigOverridePolicy.isClosed());
|
||||
}
|
||||
|
@ -4313,7 +4364,7 @@ public class DistributedHerderTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
|
||||
public boolean awaitTermination(long timeout, TimeUnit unit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@ import org.apache.kafka.connect.storage.AppliedConnectorConfig;
|
|||
import org.apache.kafka.connect.util.ConnectUtils;
|
||||
import org.apache.kafka.connect.storage.ClusterConfigState;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
@ -49,16 +51,17 @@ import java.util.stream.IntStream;
|
|||
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeAssignor.ClusterAssignment;
|
||||
import static org.apache.kafka.connect.runtime.distributed.WorkerCoordinator.WorkerLoad;
|
||||
import static org.apache.kafka.connect.util.ConnectUtils.transformValues;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.notNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class IncrementalCooperativeAssignorTest {
|
||||
|
||||
// Offset isn't used in most tests but is required for creating a config snapshot object,
|
||||
|
@ -73,7 +76,7 @@ public class IncrementalCooperativeAssignorTest {
|
|||
private ClusterAssignment returnedAssignments;
|
||||
private Map<String, ConnectorsAndTasks> memberAssignments;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
generationId = 1000;
|
||||
time = Time.SYSTEM;
|
||||
|
@ -730,9 +733,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
|
||||
|
@ -747,9 +750,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -762,9 +765,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.singleton(flakyWorker),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.singleton(flakyWorker),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -775,17 +778,17 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertTrue("Wrong assignment of lost connectors",
|
||||
configuredAssignment.getOrDefault(flakyWorker, new WorkerLoad.Builder(flakyWorker).build())
|
||||
.connectors()
|
||||
.containsAll(lostAssignments.connectors()));
|
||||
assertTrue("Wrong assignment of lost tasks",
|
||||
configuredAssignment.getOrDefault(flakyWorker, new WorkerLoad.Builder(flakyWorker).build())
|
||||
.tasks()
|
||||
.containsAll(lostAssignments.tasks()));
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertTrue(configuredAssignment.getOrDefault(flakyWorker, new WorkerLoad.Builder(flakyWorker).build())
|
||||
.connectors()
|
||||
.containsAll(lostAssignments.connectors()),
|
||||
"Wrong assignment of lost connectors");
|
||||
assertTrue(configuredAssignment.getOrDefault(flakyWorker, new WorkerLoad.Builder(flakyWorker).build())
|
||||
.tasks()
|
||||
.containsAll(lostAssignments.tasks()),
|
||||
"Wrong assignment of lost tasks");
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
}
|
||||
|
@ -810,9 +813,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
|
||||
|
@ -827,9 +830,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -841,9 +844,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -853,13 +856,13 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, lostAssignmentsToReassign,
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertTrue("Wrong assignment of lost connectors",
|
||||
lostAssignmentsToReassign.build().connectors().containsAll(lostAssignments.connectors()));
|
||||
assertTrue("Wrong assignment of lost tasks",
|
||||
lostAssignmentsToReassign.build().tasks().containsAll(lostAssignments.tasks()));
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertTrue(lostAssignmentsToReassign.build().connectors().containsAll(lostAssignments.connectors()),
|
||||
"Wrong assignment of lost connectors");
|
||||
assertTrue(lostAssignmentsToReassign.build().tasks().containsAll(lostAssignments.tasks()),
|
||||
"Wrong assignment of lost tasks");
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
}
|
||||
|
@ -884,9 +887,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
|
||||
|
@ -904,9 +907,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.singleton(newWorker),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.singleton(newWorker),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -921,9 +924,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
|
||||
Set<String> expectedWorkers = new HashSet<>();
|
||||
expectedWorkers.addAll(Arrays.asList(newWorker, flakyWorker));
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
expectedWorkers,
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(expectedWorkers,
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -949,13 +952,13 @@ public class IncrementalCooperativeAssignorTest {
|
|||
.tasks());
|
||||
listOfTasksInLast2Workers.addAll(configuredAssignment.getOrDefault(flakyWorker, new WorkerLoad.Builder(flakyWorker).build())
|
||||
.tasks());
|
||||
assertTrue("Wrong assignment of lost connectors",
|
||||
listOfConnectorsInLast2Workers.containsAll(lostAssignments.connectors()));
|
||||
assertTrue("Wrong assignment of lost tasks",
|
||||
listOfTasksInLast2Workers.containsAll(lostAssignments.tasks()));
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertTrue(listOfConnectorsInLast2Workers.containsAll(lostAssignments.connectors()),
|
||||
"Wrong assignment of lost connectors");
|
||||
assertTrue(listOfTasksInLast2Workers.containsAll(lostAssignments.tasks()),
|
||||
"Wrong assignment of lost tasks");
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
}
|
||||
|
@ -980,9 +983,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
|
||||
|
@ -997,9 +1000,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -1012,9 +1015,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.singleton(veryFlakyWorker),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.singleton(veryFlakyWorker),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(time.milliseconds() + rebalanceDelay, assignor.scheduledRebalance);
|
||||
assertEquals(rebalanceDelay, assignor.delay);
|
||||
|
||||
|
@ -1027,13 +1030,13 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, lostAssignmentsToReassign,
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertTrue("Wrong assignment of lost connectors",
|
||||
lostAssignmentsToReassign.build().connectors().containsAll(lostAssignments.connectors()));
|
||||
assertTrue("Wrong assignment of lost tasks",
|
||||
lostAssignmentsToReassign.build().tasks().containsAll(lostAssignments.tasks()));
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertTrue(lostAssignmentsToReassign.build().connectors().containsAll(lostAssignments.connectors()),
|
||||
"Wrong assignment of lost connectors");
|
||||
assertTrue(lostAssignmentsToReassign.build().tasks().containsAll(lostAssignments.tasks()),
|
||||
"Wrong assignment of lost tasks");
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
}
|
||||
|
@ -1059,9 +1062,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
new ConnectorsAndTasks.Builder(),
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
|
||||
|
@ -1077,15 +1080,15 @@ public class IncrementalCooperativeAssignorTest {
|
|||
assignor.handleLostAssignments(lostAssignments, lostAssignmentsToReassign,
|
||||
new ArrayList<>(configuredAssignment.values()));
|
||||
|
||||
assertEquals("Wrong set of workers for reassignments",
|
||||
Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment);
|
||||
assertEquals(Collections.emptySet(),
|
||||
assignor.candidateWorkersForReassignment,
|
||||
"Wrong set of workers for reassignments");
|
||||
assertEquals(0, assignor.scheduledRebalance);
|
||||
assertEquals(0, assignor.delay);
|
||||
assertEquals("Wrong assignment of lost connectors",
|
||||
lostAssignments.connectors(), lostAssignmentsToReassign.build().connectors());
|
||||
assertEquals("Wrong assignment of lost tasks",
|
||||
lostAssignments.tasks(), lostAssignmentsToReassign.build().tasks());
|
||||
assertEquals(lostAssignments.connectors(),
|
||||
lostAssignmentsToReassign.build().connectors(), "Wrong assignment of lost connectors");
|
||||
assertEquals(lostAssignments.tasks(),
|
||||
lostAssignmentsToReassign.build().tasks(), "Wrong assignment of lost tasks");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1240,9 +1243,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
serializedAssignments.forEach((worker, serializedAssignment) -> {
|
||||
ExtendedAssignment assignment = IncrementalCooperativeConnectProtocol.deserializeAssignment(serializedAssignment);
|
||||
assertEquals(
|
||||
"Incorrect protocol version in assignment for worker " + worker,
|
||||
IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V1,
|
||||
assignment.version()
|
||||
assignment.version(),
|
||||
"Incorrect protocol version in assignment for worker " + worker
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -1281,9 +1284,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
serializedAssignments.forEach((worker, serializedAssignment) -> {
|
||||
ExtendedAssignment assignment = IncrementalCooperativeConnectProtocol.deserializeAssignment(serializedAssignment);
|
||||
assertEquals(
|
||||
"Incorrect protocol version in assignment for worker " + worker,
|
||||
IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V2,
|
||||
assignment.version()
|
||||
assignment.version(),
|
||||
"Incorrect protocol version in assignment for worker " + worker
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -1332,16 +1335,16 @@ public class IncrementalCooperativeAssignorTest {
|
|||
private void addNewWorker(String worker, List<String> connectors, List<ConnectorTaskId> tasks) {
|
||||
ConnectorsAndTasks assignment = new ConnectorsAndTasks.Builder().with(connectors, tasks).build();
|
||||
assertNull(
|
||||
"Worker " + worker + " already exists",
|
||||
memberAssignments.put(worker, assignment)
|
||||
memberAssignments.put(worker, assignment),
|
||||
"Worker " + worker + " already exists"
|
||||
);
|
||||
}
|
||||
|
||||
private void removeWorkers(String... workers) {
|
||||
for (String worker : workers) {
|
||||
assertNotNull(
|
||||
"Worker " + worker + " does not exist",
|
||||
memberAssignments.remove(worker)
|
||||
memberAssignments.remove(worker),
|
||||
"Worker " + worker + " does not exist"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1375,15 +1378,15 @@ public class IncrementalCooperativeAssignorTest {
|
|||
|
||||
private void addNewConnector(String connector, int taskCount) {
|
||||
assertNull(
|
||||
"Connector " + connector + " already exists",
|
||||
connectors.put(connector, taskCount)
|
||||
connectors.put(connector, taskCount),
|
||||
"Connector " + connector + " already exists"
|
||||
);
|
||||
}
|
||||
|
||||
private void removeConnector(String connector) {
|
||||
assertNotNull(
|
||||
"Connector " + connector + " does not exist",
|
||||
connectors.remove(connector)
|
||||
connectors.remove(connector),
|
||||
"Connector " + connector + " does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1425,50 +1428,34 @@ public class IncrementalCooperativeAssignorTest {
|
|||
workerAssignment.tasks().removeAll(returnedAssignments.newlyRevokedTasks(worker));
|
||||
workerAssignment.tasks().addAll(returnedAssignments.newlyAssignedTasks(worker));
|
||||
|
||||
assertEquals(
|
||||
"Complete connector assignment for worker " + worker + " does not match expectations " +
|
||||
"based on prior assignment and new revocations and assignments",
|
||||
new HashSet<>(workerAssignment.connectors()),
|
||||
new HashSet<>(returnedAssignments.allAssignedConnectors().get(worker))
|
||||
);
|
||||
assertEquals(
|
||||
"Complete task assignment for worker " + worker + " does not match expectations " +
|
||||
"based on prior assignment and new revocations and assignments",
|
||||
new HashSet<>(workerAssignment.tasks()),
|
||||
new HashSet<>(returnedAssignments.allAssignedTasks().get(worker))
|
||||
);
|
||||
assertEquals(new HashSet<>(workerAssignment.connectors()),
|
||||
new HashSet<>(returnedAssignments.allAssignedConnectors().get(worker)),
|
||||
"Complete connector assignment for worker " + worker + " does not match expectations " +
|
||||
"based on prior assignment and new revocations and assignments");
|
||||
assertEquals(new HashSet<>(workerAssignment.tasks()),
|
||||
new HashSet<>(returnedAssignments.allAssignedTasks().get(worker)),
|
||||
"Complete task assignment for worker " + worker + " does not match expectations " +
|
||||
"based on prior assignment and new revocations and assignments");
|
||||
});
|
||||
}
|
||||
|
||||
private void assertEmptyAssignment() {
|
||||
assertEquals(
|
||||
"No connectors should have been newly assigned during this round",
|
||||
Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyAssignedConnectors().values())
|
||||
);
|
||||
assertEquals(
|
||||
"No tasks should have been newly assigned during this round",
|
||||
Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyAssignedTasks().values())
|
||||
);
|
||||
assertEquals(
|
||||
"No connectors should have been revoked during this round",
|
||||
Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyRevokedConnectors().values())
|
||||
);
|
||||
assertEquals(
|
||||
"No tasks should have been revoked during this round",
|
||||
Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyRevokedTasks().values())
|
||||
);
|
||||
assertEquals(Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyAssignedConnectors().values()),
|
||||
"No connectors should have been newly assigned during this round");
|
||||
assertEquals(Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyAssignedTasks().values()),
|
||||
"No tasks should have been newly assigned during this round");
|
||||
assertEquals(Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyRevokedConnectors().values()),
|
||||
"No connectors should have been revoked during this round");
|
||||
assertEquals(Collections.emptyList(),
|
||||
ConnectUtils.combineCollections(returnedAssignments.newlyRevokedTasks().values()),
|
||||
"No tasks should have been revoked during this round");
|
||||
}
|
||||
|
||||
private void assertWorkers(String... workers) {
|
||||
assertEquals(
|
||||
"Wrong set of workers",
|
||||
new HashSet<>(Arrays.asList(workers)),
|
||||
returnedAssignments.allWorkers()
|
||||
);
|
||||
assertEquals(new HashSet<>(Arrays.asList(workers)), returnedAssignments.allWorkers(), "Wrong set of workers");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1497,11 +1484,9 @@ public class IncrementalCooperativeAssignorTest {
|
|||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
List<Integer> actualAllocations = allocations(allocation);
|
||||
assertEquals(
|
||||
"Allocation of assigned " + allocated + " across cluster does not match expected counts",
|
||||
expectedAllocations,
|
||||
actualAllocations
|
||||
);
|
||||
assertEquals(expectedAllocations,
|
||||
actualAllocations,
|
||||
"Allocation of assigned " + allocated + " across cluster does not match expected counts");
|
||||
}
|
||||
|
||||
private List<Integer> allocations(Function<ConnectorsAndTasks, ? extends Collection<?>> allocation) {
|
||||
|
@ -1515,25 +1500,25 @@ public class IncrementalCooperativeAssignorTest {
|
|||
private void assertNoRevocations() {
|
||||
returnedAssignments.newlyRevokedConnectors().forEach((worker, revocations) ->
|
||||
assertEquals(
|
||||
"Expected no revocations to take place during this round, but connector revocations were issued for worker " + worker,
|
||||
Collections.emptySet(),
|
||||
new HashSet<>(revocations)
|
||||
)
|
||||
Collections.emptySet(),
|
||||
new HashSet<>(revocations),
|
||||
"Expected no revocations to take place during this round, but connector revocations were issued for worker " + worker
|
||||
)
|
||||
);
|
||||
returnedAssignments.newlyRevokedTasks().forEach((worker, revocations) ->
|
||||
assertEquals(
|
||||
"Expected no revocations to take place during this round, but task revocations were issued for worker " + worker,
|
||||
Collections.emptySet(),
|
||||
new HashSet<>(revocations)
|
||||
)
|
||||
Collections.emptySet(),
|
||||
new HashSet<>(revocations),
|
||||
"Expected no revocations to take place during this round, but task revocations were issued for worker " + worker
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void assertDelay(int expectedDelay) {
|
||||
assertEquals(
|
||||
"Wrong rebalance delay",
|
||||
expectedDelay,
|
||||
assignor.delay
|
||||
assignor.delay,
|
||||
"Wrong rebalance delay"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1557,13 +1542,13 @@ public class IncrementalCooperativeAssignorTest {
|
|||
);
|
||||
|
||||
existingConnectors.retainAll(newConnectors);
|
||||
assertEquals("Found connectors in new assignment that already exist in current assignment",
|
||||
Collections.emptyList(),
|
||||
existingConnectors);
|
||||
assertEquals(Collections.emptyList(),
|
||||
existingConnectors,
|
||||
"Found connectors in new assignment that already exist in current assignment");
|
||||
existingTasks.retainAll(newTasks);
|
||||
assertEquals("Found tasks in new assignment that already exist in current assignment",
|
||||
Collections.emptyList(),
|
||||
existingConnectors);
|
||||
assertEquals(Collections.emptyList(),
|
||||
existingConnectors,
|
||||
"Found tasks in new assignment that already exist in current assignment");
|
||||
}
|
||||
|
||||
private void assertBalancedAndCompleteAllocation() {
|
||||
|
@ -1581,23 +1566,17 @@ public class IncrementalCooperativeAssignorTest {
|
|||
int minTasks = taskCounts.get(0);
|
||||
int maxTasks = taskCounts.get(taskCounts.size() - 1);
|
||||
|
||||
assertTrue(
|
||||
"Assignments are imbalanced. The spread of connectors across each worker is: " + connectorCounts,
|
||||
maxConnectors - minConnectors <= 1
|
||||
);
|
||||
assertTrue(
|
||||
"Assignments are imbalanced. The spread of tasks across each worker is: " + taskCounts,
|
||||
maxTasks - minTasks <= 1
|
||||
);
|
||||
assertTrue(maxConnectors - minConnectors <= 1,
|
||||
"Assignments are imbalanced. The spread of connectors across each worker is: " + connectorCounts);
|
||||
assertTrue(maxTasks - minTasks <= 1,
|
||||
"Assignments are imbalanced. The spread of tasks across each worker is: " + taskCounts);
|
||||
}
|
||||
|
||||
private void assertCompleteAllocation() {
|
||||
List<String> allAssignedConnectors = ConnectUtils.combineCollections(memberAssignments.values(), ConnectorsAndTasks::connectors);
|
||||
assertEquals(
|
||||
"The set of connectors assigned across the cluster does not match the set of connectors in the config topic",
|
||||
connectors.keySet(),
|
||||
new HashSet<>(allAssignedConnectors)
|
||||
);
|
||||
assertEquals(connectors.keySet(),
|
||||
new HashSet<>(allAssignedConnectors),
|
||||
"The set of connectors assigned across the cluster does not match the set of connectors in the config topic");
|
||||
|
||||
Map<String, List<ConnectorTaskId>> allAssignedTasks = ConnectUtils.combineCollections(memberAssignments.values(), ConnectorsAndTasks::tasks)
|
||||
.stream()
|
||||
|
@ -1607,20 +1586,14 @@ public class IncrementalCooperativeAssignorTest {
|
|||
Set<ConnectorTaskId> expectedTasks = IntStream.range(0, taskCount)
|
||||
.mapToObj(i -> new ConnectorTaskId(connector, i))
|
||||
.collect(Collectors.toSet());
|
||||
assertEquals(
|
||||
"The set of tasks assigned across the cluster for connector " + connector + " does not match the set of tasks in the config topic",
|
||||
expectedTasks,
|
||||
new HashSet<>(allAssignedTasks.get(connector))
|
||||
);
|
||||
assertEquals(expectedTasks,
|
||||
new HashSet<>(allAssignedTasks.get(connector)),
|
||||
"The set of tasks assigned across the cluster for connector " + connector + " does not match the set of tasks in the config topic");
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void assertNoDuplicates(List<T> collection, String assertionMessage) {
|
||||
assertEquals(
|
||||
assertionMessage,
|
||||
new HashSet<>(collection).size(),
|
||||
collection.size()
|
||||
);
|
||||
assertEquals(new HashSet<>(collection).size(), collection.size(), assertionMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,15 +29,14 @@ import org.apache.kafka.common.utils.MockTime;
|
|||
import org.apache.kafka.connect.storage.ClusterConfigState;
|
||||
import org.apache.kafka.connect.storage.KafkaConfigBackingStore;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -49,6 +48,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.apache.kafka.common.message.JoinGroupRequestData.JoinGroupRequestProtocol;
|
||||
import static org.apache.kafka.common.message.JoinGroupRequestData.JoinGroupRequestProtocolCollection;
|
||||
|
@ -58,22 +58,18 @@ import static org.apache.kafka.connect.runtime.WorkerTestUtils.clusterConfigStat
|
|||
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocol.WorkerState;
|
||||
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.COMPATIBLE;
|
||||
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.EAGER;
|
||||
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.SESSIONED;
|
||||
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V1;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.runners.Parameterized.Parameter;
|
||||
import static org.junit.runners.Parameterized.Parameters;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class WorkerCoordinatorIncrementalTest {
|
||||
@Rule
|
||||
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
|
||||
|
||||
private final String connectorId1 = "connector1";
|
||||
private final String connectorId2 = "connector2";
|
||||
|
@ -116,19 +112,14 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
// Arguments are:
|
||||
// - Protocol type
|
||||
// - Expected metadata size
|
||||
@Parameters
|
||||
public static Iterable<?> mode() {
|
||||
return Arrays.asList(new Object[][]{{COMPATIBLE, 2}, {SESSIONED, 3}});
|
||||
static Stream<Arguments> mode() {
|
||||
return Stream.of(
|
||||
Arguments.of(ConnectProtocolCompatibility.COMPATIBLE, 2),
|
||||
Arguments.of(ConnectProtocolCompatibility.SESSIONED, 3)
|
||||
);
|
||||
}
|
||||
|
||||
@Parameter
|
||||
public ConnectProtocolCompatibility compatibility;
|
||||
|
||||
@Parameter(1)
|
||||
public int expectedMetadataSize;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
public void init(ConnectProtocolCompatibility compatibility) {
|
||||
LogContext loggerFactory = new LogContext();
|
||||
|
||||
this.time = new MockTime();
|
||||
|
@ -137,7 +128,7 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
this.client.updateMetadata(RequestTestUtils.metadataUpdateWith(1, Collections.singletonMap("topic", 1)));
|
||||
this.node = metadata.fetch().nodes().get(0);
|
||||
this.consumerClient = new ConsumerNetworkClient(loggerFactory, client, metadata, time,
|
||||
retryBackoffMs, requestTimeoutMs, heartbeatIntervalMs);
|
||||
retryBackoffMs, requestTimeoutMs, heartbeatIntervalMs);
|
||||
this.metrics = new Metrics(time);
|
||||
this.rebalanceListener = new MockRebalanceListener();
|
||||
|
||||
|
@ -153,29 +144,29 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
this.configStorageCalls = 0;
|
||||
|
||||
this.rebalanceConfig = new GroupRebalanceConfig(sessionTimeoutMs,
|
||||
rebalanceTimeoutMs,
|
||||
heartbeatIntervalMs,
|
||||
groupId,
|
||||
Optional.empty(),
|
||||
retryBackoffMs,
|
||||
retryBackoffMaxMs,
|
||||
true);
|
||||
rebalanceTimeoutMs,
|
||||
heartbeatIntervalMs,
|
||||
groupId,
|
||||
Optional.empty(),
|
||||
retryBackoffMs,
|
||||
retryBackoffMaxMs,
|
||||
true);
|
||||
this.coordinator = new WorkerCoordinator(rebalanceConfig,
|
||||
loggerFactory,
|
||||
consumerClient,
|
||||
metrics,
|
||||
"worker" + groupId,
|
||||
time,
|
||||
expectedUrl(leaderId),
|
||||
configStorage,
|
||||
rebalanceListener,
|
||||
compatibility,
|
||||
rebalanceDelay);
|
||||
loggerFactory,
|
||||
consumerClient,
|
||||
metrics,
|
||||
"worker" + groupId,
|
||||
time,
|
||||
expectedUrl(leaderId),
|
||||
configStorage,
|
||||
rebalanceListener,
|
||||
compatibility,
|
||||
rebalanceDelay);
|
||||
|
||||
configState1 = clusterConfigState(offset, 2, 4);
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
this.metrics.close();
|
||||
verifyNoMoreInteractions(configStorage);
|
||||
|
@ -188,8 +179,11 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
// We only test functionality unique to WorkerCoordinator. Other functionality is already
|
||||
// well tested via the tests that cover AbstractCoordinator & ConsumerCoordinator.
|
||||
|
||||
@Test
|
||||
public void testMetadata() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testMetadata(ConnectProtocolCompatibility compatibility, int expectedMetadataSize) {
|
||||
init(compatibility);
|
||||
System.err.println(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
JoinGroupRequestProtocolCollection serialized = coordinator.metadata();
|
||||
|
@ -206,8 +200,10 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
verify(configStorage, times(1)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataWithExistingAssignment() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testMetadataWithExistingAssignment(ConnectProtocolCompatibility compatibility, int expectedMetadataSize) {
|
||||
init(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
ExtendedAssignment assignment = new ExtendedAssignment(
|
||||
|
@ -237,8 +233,10 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
verify(configStorage, times(1)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataWithExistingAssignmentButOlderProtocolSelection() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testMetadataWithExistingAssignmentButOlderProtocolSelection(ConnectProtocolCompatibility compatibility, int expectedMetadataSize) {
|
||||
init(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
ExtendedAssignment assignment = new ExtendedAssignment(
|
||||
|
@ -266,16 +264,18 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
verify(configStorage, times(1)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTaskAssignmentWhenWorkerJoins() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testTaskAssignmentWhenWorkerJoins(ConnectProtocolCompatibility compatibility) {
|
||||
init(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
coordinator.metadata();
|
||||
++configStorageCalls;
|
||||
|
||||
List<JoinGroupResponseMember> responseMembers = new ArrayList<>();
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, null, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, null, compatibility);
|
||||
|
||||
Map<String, ByteBuffer> result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
|
@ -295,9 +295,9 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
++configStorageCalls;
|
||||
|
||||
responseMembers = new ArrayList<>();
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, leaderAssignment);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, memberAssignment);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, leaderAssignment, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, memberAssignment, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null, compatibility);
|
||||
|
||||
result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
|
@ -323,8 +323,10 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
verify(configStorage, times(configStorageCalls)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTaskAssignmentWhenWorkerLeavesPermanently() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testTaskAssignmentWhenWorkerLeavesPermanently(ConnectProtocolCompatibility compatibility) {
|
||||
init(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
// First assignment distributes configured connectors and tasks
|
||||
|
@ -332,9 +334,9 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
++configStorageCalls;
|
||||
|
||||
List<JoinGroupResponseMember> responseMembers = new ArrayList<>();
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, null, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, null, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null, compatibility);
|
||||
|
||||
Map<String, ByteBuffer> result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
|
@ -362,8 +364,8 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
|
||||
// Mark everyone as in sync with configState1
|
||||
responseMembers = new ArrayList<>();
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, leaderAssignment);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, memberAssignment);
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, leaderAssignment, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, memberAssignment, compatibility);
|
||||
|
||||
result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
|
@ -421,8 +423,10 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
verify(configStorage, times(configStorageCalls)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTaskAssignmentWhenWorkerBounces() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testTaskAssignmentWhenWorkerBounces(ConnectProtocolCompatibility compatibility) {
|
||||
init(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
// First assignment distributes configured connectors and tasks
|
||||
|
@ -430,9 +434,9 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
++configStorageCalls;
|
||||
|
||||
List<JoinGroupResponseMember> responseMembers = new ArrayList<>();
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, null, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, null, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null, compatibility);
|
||||
|
||||
Map<String, ByteBuffer> result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
|
@ -459,8 +463,8 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
++configStorageCalls;
|
||||
|
||||
responseMembers = new ArrayList<>();
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, leaderAssignment);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, memberAssignment);
|
||||
addJoinGroupResponseMember(responseMembers, leaderId, offset, leaderAssignment, compatibility);
|
||||
addJoinGroupResponseMember(responseMembers, memberId, offset, memberAssignment, compatibility);
|
||||
|
||||
result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
|
@ -483,7 +487,7 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
|
||||
// A third rebalance before the delay expires won't change the assignments even if the
|
||||
// member returns in the meantime
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null);
|
||||
addJoinGroupResponseMember(responseMembers, anotherMemberId, offset, null, compatibility);
|
||||
result = coordinator.onLeaderElected(leaderId, compatibility.protocol(), responseMembers, false);
|
||||
|
||||
leaderAssignment = deserializeAssignment(result, leaderId);
|
||||
|
@ -569,10 +573,12 @@ public class WorkerCoordinatorIncrementalTest {
|
|||
return IncrementalCooperativeConnectProtocol.deserializeAssignment(assignment.get(member));
|
||||
}
|
||||
|
||||
|
||||
private void addJoinGroupResponseMember(List<JoinGroupResponseMember> responseMembers,
|
||||
String member,
|
||||
long offset,
|
||||
ExtendedAssignment assignment) {
|
||||
String member,
|
||||
long offset,
|
||||
ExtendedAssignment assignment,
|
||||
ConnectProtocolCompatibility compatibility) {
|
||||
responseMembers.add(new JoinGroupResponseMember()
|
||||
.setMemberId(member)
|
||||
.setMetadata(
|
||||
|
|
|
@ -41,15 +41,14 @@ import org.apache.kafka.connect.storage.AppliedConnectorConfig;
|
|||
import org.apache.kafka.connect.storage.ClusterConfigState;
|
||||
import org.apache.kafka.connect.storage.KafkaConfigBackingStore;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -63,26 +62,23 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.COMPATIBLE;
|
||||
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.EAGER;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.runners.Parameterized.Parameter;
|
||||
import static org.junit.runners.Parameterized.Parameters;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class WorkerCoordinatorTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
|
||||
|
||||
private static final String LEADER_URL = "leaderUrl:8083";
|
||||
private static final String MEMBER_URL = "memberUrl:8083";
|
||||
|
||||
|
@ -118,21 +114,14 @@ public class WorkerCoordinatorTest {
|
|||
// Arguments are:
|
||||
// - Protocol type
|
||||
// - Expected metadata size
|
||||
@Parameters
|
||||
public static Iterable<?> mode() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{EAGER, 1},
|
||||
{COMPATIBLE, 2}});
|
||||
static Stream<Arguments> mode() {
|
||||
return Stream.of(
|
||||
Arguments.of(EAGER, 1),
|
||||
Arguments.of(COMPATIBLE, 2)
|
||||
);
|
||||
}
|
||||
|
||||
@Parameter
|
||||
public ConnectProtocolCompatibility compatibility;
|
||||
|
||||
@Parameter(1)
|
||||
public int expectedMetadataSize;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
public void setup(ConnectProtocolCompatibility compatibility) {
|
||||
LogContext logContext = new LogContext();
|
||||
|
||||
this.time = new MockTime();
|
||||
|
@ -241,7 +230,7 @@ public class WorkerCoordinatorTest {
|
|||
);
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
this.metrics.close();
|
||||
}
|
||||
|
@ -249,8 +238,10 @@ public class WorkerCoordinatorTest {
|
|||
// We only test functionality unique to WorkerCoordinator. Most functionality is already well tested via the tests
|
||||
// that cover AbstractCoordinator & ConsumerCoordinator.
|
||||
|
||||
@Test
|
||||
public void testMetadata() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testMetadata(ConnectProtocolCompatibility compatibility, int expectedMetadataSize) {
|
||||
setup(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
JoinGroupRequestData.JoinGroupRequestProtocolCollection serialized = coordinator.metadata();
|
||||
|
@ -267,8 +258,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalJoinGroupLeader() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testNormalJoinGroupLeader(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
final String memberId = "leader";
|
||||
|
@ -302,8 +295,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalJoinGroupFollower() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testNormalJoinGroupFollower(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
final String memberId = "member";
|
||||
|
@ -333,8 +328,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinLeaderCannotAssign() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testJoinLeaderCannotAssign(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
// If the selected leader can't get up to the maximum offset, it will fail to assign and we should immediately
|
||||
// need to retry the join.
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
@ -366,8 +363,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage, times(2)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRejoinGroup() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testRejoinGroup(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
when(configStorage.snapshot()).thenReturn(configState1);
|
||||
|
||||
client.prepareResponse(FindCoordinatorResponse.prepareResponse(Errors.NONE, groupId, node));
|
||||
|
@ -405,8 +404,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage, times(2)).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeaderPerformAssignment1() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testLeaderPerformAssignment1(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
// Since all the protocol responses are mocked, the other tests validate doSync runs, but don't validate its
|
||||
// output. So we test it directly here.
|
||||
|
||||
|
@ -445,8 +446,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeaderPerformAssignment2() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testLeaderPerformAssignment2(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
// Since all the protocol responses are mocked, the other tests validate doSync runs, but don't validate its
|
||||
// output. So we test it directly here.
|
||||
|
||||
|
@ -486,8 +489,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeaderPerformAssignmentSingleTaskConnectors() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testLeaderPerformAssignmentSingleTaskConnectors(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
// Since all the protocol responses are mocked, the other tests validate doSync runs, but don't validate its
|
||||
// output. So we test it directly here.
|
||||
|
||||
|
@ -528,8 +533,10 @@ public class WorkerCoordinatorTest {
|
|||
verify(configStorage).snapshot();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkippingAssignmentFails() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("mode")
|
||||
public void testSkippingAssignmentFails(ConnectProtocolCompatibility compatibility) {
|
||||
setup(compatibility);
|
||||
// Connect does not support static membership so skipping assignment should
|
||||
// never be set to true by the group coordinator. It is treated as an
|
||||
// illegal state if it would.
|
||||
|
|
|
@ -26,10 +26,12 @@ import org.apache.kafka.common.utils.Time;
|
|||
import org.apache.kafka.connect.runtime.MockConnectMetrics;
|
||||
import org.apache.kafka.connect.runtime.WorkerConfig;
|
||||
import org.apache.kafka.connect.storage.ConfigBackingStore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
@ -37,15 +39,16 @@ import java.lang.management.ManagementFactory;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class WorkerGroupMemberTest {
|
||||
@Mock
|
||||
private ConfigBackingStore configBackingStore;
|
||||
|
@ -83,8 +86,8 @@ public class WorkerGroupMemberTest {
|
|||
foundJmxReporter = true;
|
||||
}
|
||||
}
|
||||
assertTrue("Failed to find MockMetricsReporter", foundMockReporter);
|
||||
assertTrue("Failed to find JmxReporter", foundJmxReporter);
|
||||
assertTrue(foundMockReporter, "Failed to find MockMetricsReporter");
|
||||
assertTrue(foundJmxReporter, "Failed to find JmxReporter");
|
||||
|
||||
MetricName name = member.metrics().metricName("test.avg", "grp1");
|
||||
member.metrics().addMetric(name, new Avg());
|
||||
|
|
|
@ -31,12 +31,14 @@ import org.apache.kafka.connect.runtime.isolation.Plugins;
|
|||
import org.apache.kafka.connect.sink.SinkTask;
|
||||
import org.apache.kafka.connect.transforms.Transformation;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -55,11 +57,11 @@ import static org.apache.kafka.connect.runtime.errors.DeadLetterQueueReporter.ER
|
|||
import static org.apache.kafka.connect.runtime.errors.DeadLetterQueueReporter.ERROR_HEADER_ORIG_TOPIC;
|
||||
import static org.apache.kafka.connect.runtime.errors.DeadLetterQueueReporter.ERROR_HEADER_STAGE;
|
||||
import static org.apache.kafka.connect.runtime.errors.DeadLetterQueueReporter.ERROR_HEADER_TASK_ID;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
@ -67,7 +69,8 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class ErrorReporterTest {
|
||||
|
||||
private static final String TOPIC = "test-topic";
|
||||
|
@ -86,13 +89,13 @@ public class ErrorReporterTest {
|
|||
private ErrorHandlingMetrics errorHandlingMetrics;
|
||||
private MockConnectMetrics metrics;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
metrics = new MockConnectMetrics();
|
||||
errorHandlingMetrics = new ErrorHandlingMetrics(new ConnectorTaskId("connector-", 1), metrics);
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
if (metrics != null) {
|
||||
metrics.stop();
|
||||
|
|
|
@ -35,10 +35,12 @@ import org.apache.kafka.connect.sink.SinkConnector;
|
|||
import org.apache.kafka.connect.sink.SinkTask;
|
||||
import org.apache.kafka.connect.source.SourceRecord;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.OngoingStubbing;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -65,11 +67,11 @@ import static org.apache.kafka.connect.runtime.ConnectorConfig.ERRORS_TOLERANCE_
|
|||
import static org.apache.kafka.connect.runtime.ConnectorConfig.ERRORS_TOLERANCE_DEFAULT;
|
||||
import static org.apache.kafka.connect.runtime.errors.ToleranceType.ALL;
|
||||
import static org.apache.kafka.connect.runtime.errors.ToleranceType.NONE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
|
@ -80,7 +82,8 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class RetryWithToleranceOperatorTest {
|
||||
|
||||
private static final Map<String, String> PROPERTIES = new HashMap<String, String>() {{
|
||||
|
@ -358,15 +361,15 @@ public class RetryWithToleranceOperatorTest {
|
|||
public void testToleranceLimit() {
|
||||
RetryWithToleranceOperator<ConsumerRecord<byte[], byte[]>> retryWithToleranceOperator = genericOperator(ERRORS_RETRY_TIMEOUT_DEFAULT, NONE, errorHandlingMetrics);
|
||||
retryWithToleranceOperator.markAsFailed();
|
||||
assertFalse("should not tolerate any errors", retryWithToleranceOperator.withinToleranceLimits());
|
||||
assertFalse(retryWithToleranceOperator.withinToleranceLimits(), "should not tolerate any errors");
|
||||
|
||||
retryWithToleranceOperator = genericOperator(ERRORS_RETRY_TIMEOUT_DEFAULT, ALL, errorHandlingMetrics);
|
||||
retryWithToleranceOperator.markAsFailed();
|
||||
retryWithToleranceOperator.markAsFailed();
|
||||
assertTrue("should tolerate all errors", retryWithToleranceOperator.withinToleranceLimits());
|
||||
assertTrue(retryWithToleranceOperator.withinToleranceLimits(), "should tolerate all errors");
|
||||
|
||||
retryWithToleranceOperator = genericOperator(ERRORS_RETRY_TIMEOUT_DEFAULT, NONE, errorHandlingMetrics);
|
||||
assertTrue("no tolerance is within limits if no failures", retryWithToleranceOperator.withinToleranceLimits());
|
||||
assertTrue(retryWithToleranceOperator.withinToleranceLimits(), "no tolerance is within limits if no failures");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -25,24 +25,27 @@ import org.apache.kafka.connect.runtime.ConnectorConfig;
|
|||
import org.apache.kafka.connect.runtime.InternalSinkRecord;
|
||||
import org.apache.kafka.connect.storage.Converter;
|
||||
import org.apache.kafka.connect.storage.HeaderConverter;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class WorkerErrantRecordReporterTest {
|
||||
|
||||
private WorkerErrantRecordReporter reporter;
|
||||
|
|
|
@ -19,12 +19,14 @@ package org.apache.kafka.connect.runtime.health;
|
|||
import org.apache.kafka.connect.errors.ConnectException;
|
||||
import org.apache.kafka.connect.runtime.Herder;
|
||||
import org.apache.kafka.connect.util.Callback;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -33,13 +35,14 @@ import java.util.Map;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class ConnectClusterStateImplTest {
|
||||
protected static final String KAFKA_CLUSTER_ID = "franzwashere";
|
||||
|
||||
|
@ -49,7 +52,7 @@ public class ConnectClusterStateImplTest {
|
|||
protected long herderRequestTimeoutMs = TimeUnit.SECONDS.toMillis(10);
|
||||
protected Collection<String> expectedConnectors;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
expectedConnectors = Arrays.asList("sink1", "source1", "source2");
|
||||
connectClusterState = new ConnectClusterStateImpl(
|
||||
|
@ -86,11 +89,9 @@ public class ConnectClusterStateImplTest {
|
|||
Map<String, String> actualConfig = connectClusterState.connectorConfig(connName);
|
||||
|
||||
assertEquals(expectedConfig, actualConfig);
|
||||
assertNotSame(
|
||||
"Config should be copied in order to avoid mutation by REST extensions",
|
||||
expectedConfig,
|
||||
actualConfig
|
||||
);
|
||||
assertNotSame(expectedConfig,
|
||||
actualConfig,
|
||||
"Config should be copied in order to avoid mutation by REST extensions");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -17,10 +17,12 @@
|
|||
package org.apache.kafka.connect.runtime.isolation;
|
||||
|
||||
import org.apache.kafka.connect.sink.SinkConnector;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
@ -28,12 +30,13 @@ import java.util.Collections;
|
|||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class DelegatingClassLoaderTest {
|
||||
|
||||
public PluginClassLoader parent;
|
||||
|
@ -55,7 +58,7 @@ public class DelegatingClassLoaderTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public void setUp() {
|
||||
parent = mock(PluginClassLoader.class);
|
||||
|
|
|
@ -26,16 +26,16 @@ import org.apache.kafka.connect.storage.Converter;
|
|||
import org.apache.kafka.connect.storage.HeaderConverter;
|
||||
import org.apache.kafka.connect.transforms.Transformation;
|
||||
import org.apache.kafka.connect.transforms.predicates.Predicate;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class PluginDescTest {
|
|||
private PluginClassLoader pluginLoader;
|
||||
private PluginClassLoader otherPluginLoader;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
// Fairly simple use case, thus no need to create a random directory here yet.
|
||||
URL location = Paths.get("/tmp").toUri().toURL();
|
||||
|
@ -285,8 +285,8 @@ public class PluginDescTest {
|
|||
otherPluginLoader
|
||||
);
|
||||
|
||||
assertTrue("Different plugin loaders should have an ordering",
|
||||
configProviderDescPluginPath.compareTo(configProviderDescOtherPluginLoader) != 0);
|
||||
assertTrue(configProviderDescPluginPath.compareTo(configProviderDescOtherPluginLoader) != 0,
|
||||
"Different plugin loaders should have an ordering");
|
||||
|
||||
|
||||
PluginDesc<Converter> jsonConverterPlugin = new PluginDesc<>(
|
||||
|
@ -339,6 +339,6 @@ public class PluginDescTest {
|
|||
}
|
||||
|
||||
private static void assertNewer(PluginDesc<?> older, PluginDesc<?> newer) {
|
||||
assertTrue(newer + " should be newer than " + older, older.compareTo(newer) < 0);
|
||||
assertTrue(older.compareTo(newer) < 0, newer + " should be newer than " + older);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,161 +17,141 @@
|
|||
|
||||
package org.apache.kafka.connect.runtime.isolation;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class PluginScannerTest {
|
||||
|
||||
private enum ScannerType { Reflection, ServiceLoader }
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder pluginDir = new TemporaryFolder();
|
||||
@TempDir
|
||||
File pluginDir;
|
||||
|
||||
private final PluginScanner scanner;
|
||||
private Map<ScannerType, PluginScanner> scannerMap;
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> parameters() {
|
||||
List<Object[]> values = new ArrayList<>();
|
||||
for (ScannerType type : ScannerType.values()) {
|
||||
values.add(new Object[]{type});
|
||||
}
|
||||
return values;
|
||||
static Stream<PluginScanner> parameters() {
|
||||
return Stream.of(new ReflectionScanner(), new ServiceLoaderScanner());
|
||||
}
|
||||
|
||||
public PluginScannerTest(ScannerType scannerType) {
|
||||
switch (scannerType) {
|
||||
case Reflection:
|
||||
this.scanner = new ReflectionScanner();
|
||||
break;
|
||||
case ServiceLoader:
|
||||
this.scanner = new ServiceLoaderScanner();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown type " + scannerType);
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
// Work around a circular-dependency in TestPlugins.
|
||||
TestPlugins.pluginPath();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningEmptyPluginPath() {
|
||||
PluginScanResult result = scan(
|
||||
Collections.emptySet()
|
||||
);
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningEmptyPluginPath(PluginScanner scanner) {
|
||||
PluginScanResult result = scan(scanner, Collections.emptySet());
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningPluginClasses() {
|
||||
PluginScanResult result = scan(
|
||||
TestPlugins.pluginPath()
|
||||
);
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningPluginClasses(PluginScanner scanner) {
|
||||
PluginScanResult result = scan(scanner, TestPlugins.pluginPath());
|
||||
Set<String> classes = new HashSet<>();
|
||||
result.forEach(pluginDesc -> classes.add(pluginDesc.className()));
|
||||
Set<String> expectedClasses = new HashSet<>(TestPlugins.pluginClasses());
|
||||
assertEquals(expectedClasses, classes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningInvalidUberJar() throws Exception {
|
||||
pluginDir.newFile("invalid.jar");
|
||||
|
||||
PluginScanResult result = scan(
|
||||
Collections.singleton(pluginDir.getRoot().toPath().toAbsolutePath())
|
||||
);
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningInvalidUberJar(PluginScanner scanner) throws Exception {
|
||||
File newFile = new File(pluginDir, "invalid.jar");
|
||||
newFile.createNewFile();
|
||||
PluginScanResult result = scan(scanner, Collections.singleton(pluginDir.toPath()));
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningPluginDirContainsInvalidJarsOnly() throws Exception {
|
||||
pluginDir.newFolder("my-plugin");
|
||||
pluginDir.newFile("my-plugin/invalid.jar");
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningPluginDirContainsInvalidJarsOnly(PluginScanner scanner) throws Exception {
|
||||
File newFile = new File(pluginDir, "my-plugin");
|
||||
newFile.mkdir();
|
||||
newFile = new File(newFile, "invalid.jar");
|
||||
newFile.createNewFile();
|
||||
|
||||
PluginScanResult result = scan(
|
||||
Collections.singleton(pluginDir.getRoot().toPath().toAbsolutePath())
|
||||
);
|
||||
PluginScanResult result = scan(scanner, Collections.singleton(pluginDir.toPath()));
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningNoPlugins() {
|
||||
PluginScanResult result = scan(
|
||||
Collections.singleton(pluginDir.getRoot().toPath().toAbsolutePath())
|
||||
);
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningNoPlugins(PluginScanner scanner) {
|
||||
PluginScanResult result = scan(scanner, Collections.singleton(pluginDir.toPath()));
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningPluginDirEmpty() throws Exception {
|
||||
pluginDir.newFolder("my-plugin");
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningPluginDirEmpty(PluginScanner scanner) {
|
||||
File newFile = new File(pluginDir, "my-plugin");
|
||||
newFile.mkdir();
|
||||
|
||||
PluginScanResult result = scan(
|
||||
Collections.singleton(pluginDir.getRoot().toPath().toAbsolutePath())
|
||||
);
|
||||
PluginScanResult result = scan(scanner, Collections.singleton(pluginDir.toPath()));
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanningMixOfValidAndInvalidPlugins() throws Exception {
|
||||
pluginDir.newFile("invalid.jar");
|
||||
pluginDir.newFolder("my-plugin");
|
||||
pluginDir.newFile("my-plugin/invalid.jar");
|
||||
Path pluginPath = this.pluginDir.getRoot().toPath();
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testScanningMixOfValidAndInvalidPlugins(PluginScanner scanner) throws Exception {
|
||||
new File(pluginDir, "invalid.jar").createNewFile();
|
||||
File newFile = new File(pluginDir, "my-plugin");
|
||||
newFile.mkdir();
|
||||
newFile = new File(newFile, "invalid.jar");
|
||||
newFile.createNewFile();
|
||||
Path pluginPath = this.pluginDir.toPath();
|
||||
|
||||
for (Path source : TestPlugins.pluginPath()) {
|
||||
Files.copy(source, pluginPath.resolve(source.getFileName()));
|
||||
}
|
||||
|
||||
PluginScanResult result = scan(
|
||||
Collections.singleton(pluginDir.getRoot().toPath().toAbsolutePath())
|
||||
);
|
||||
PluginScanResult result = scan(scanner, Collections.singleton(pluginDir.toPath()));
|
||||
Set<String> classes = new HashSet<>();
|
||||
result.forEach(pluginDesc -> classes.add(pluginDesc.className()));
|
||||
Set<String> expectedClasses = new HashSet<>(TestPlugins.pluginClasses());
|
||||
assertEquals(expectedClasses, classes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonVersionedPluginHasUndefinedVersion() {
|
||||
PluginScanResult unversionedPluginsResult = scan(TestPlugins.pluginPath(TestPlugins.TestPlugin.SAMPLING_HEADER_CONVERTER));
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testNonVersionedPluginHasUndefinedVersion(PluginScanner scanner) {
|
||||
PluginScanResult unversionedPluginsResult = scan(scanner,
|
||||
TestPlugins.pluginPath(TestPlugins.TestPlugin.SAMPLING_HEADER_CONVERTER));
|
||||
assertFalse(unversionedPluginsResult.isEmpty());
|
||||
unversionedPluginsResult.forEach(pluginDesc -> assertEquals(PluginDesc.UNDEFINED_VERSION, pluginDesc.version()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionedPluginsHasVersion() {
|
||||
PluginScanResult versionedPluginResult = scan(TestPlugins.pluginPath(TestPlugins.TestPlugin.READ_VERSION_FROM_RESOURCE_V1));
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testVersionedPluginsHasVersion(PluginScanner scanner) {
|
||||
PluginScanResult versionedPluginResult = scan(scanner,
|
||||
TestPlugins.pluginPath(TestPlugins.TestPlugin.READ_VERSION_FROM_RESOURCE_V1));
|
||||
assertFalse(versionedPluginResult.isEmpty());
|
||||
versionedPluginResult.forEach(pluginDesc -> assertEquals("1.0.0", pluginDesc.version()));
|
||||
|
||||
}
|
||||
|
||||
private PluginScanResult scan(Set<Path> pluginLocations) {
|
||||
private PluginScanResult scan(PluginScanner scanner, Set<Path> pluginLocations) {
|
||||
ClassLoaderFactory factory = new ClassLoaderFactory();
|
||||
Set<PluginSource> pluginSources = PluginUtils.pluginSources(pluginLocations, PluginScannerTest.class.getClassLoader(), factory);
|
||||
return scanner.discoverPlugins(pluginSources);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -28,10 +28,9 @@ import org.apache.kafka.connect.storage.HeaderConverter;
|
|||
import org.apache.kafka.connect.tools.MockSinkConnector;
|
||||
import org.apache.kafka.connect.tools.MockSourceConnector;
|
||||
import org.apache.kafka.connect.transforms.Transformation;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -46,18 +45,21 @@ import java.util.Map;
|
|||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class PluginUtilsTest {
|
||||
@Rule
|
||||
public TemporaryFolder rootDir = new TemporaryFolder();
|
||||
@TempDir
|
||||
Path rootDir;
|
||||
|
||||
private Path pluginPath;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
pluginPath = rootDir.newFolder("plugins").toPath().toRealPath();
|
||||
pluginPath = rootDir.resolve("plugins");
|
||||
Files.createDirectories(pluginPath);
|
||||
pluginPath = pluginPath.toRealPath();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -190,10 +192,8 @@ public class PluginUtilsTest {
|
|||
);
|
||||
// Classes in the API should never be loaded in isolation.
|
||||
for (String clazz : apiClasses) {
|
||||
assertFalse(
|
||||
clazz + " from 'api' is loaded in isolation but should not be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertFalse(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'api' is loaded in isolation but should not be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,10 +221,8 @@ public class PluginUtilsTest {
|
|||
"org.apache.kafka.connect.util."
|
||||
);
|
||||
for (String clazz : runtimeClasses) {
|
||||
assertFalse(
|
||||
clazz + " from 'runtime' is loaded in isolation but should not be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertFalse(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'runtime' is loaded in isolation but should not be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,10 +248,8 @@ public class PluginUtilsTest {
|
|||
"org.apache.kafka.connect.storage.SimpleHeaderConverter"
|
||||
);
|
||||
for (String clazz : jsonConverterClasses) {
|
||||
assertTrue(
|
||||
clazz + " from 'runtime' is not loaded in isolation but should be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertTrue(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'runtime' is not loaded in isolation but should be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,10 +301,8 @@ public class PluginUtilsTest {
|
|||
"org.apache.kafka.connect.transforms.predicates.TopicNameMatches"
|
||||
);
|
||||
for (String clazz : transformsClasses) {
|
||||
assertTrue(
|
||||
clazz + " from 'transforms' is not loaded in isolation but should be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertTrue(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'transforms' is not loaded in isolation but should be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,10 +318,8 @@ public class PluginUtilsTest {
|
|||
"org.apache.kafka.connect.json.JsonSerializer"
|
||||
);
|
||||
for (String clazz : jsonConverterClasses) {
|
||||
assertTrue(
|
||||
clazz + " from 'json' is not loaded in isolation but should be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertTrue(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'json' is not loaded in isolation but should be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,10 +333,8 @@ public class PluginUtilsTest {
|
|||
"org.apache.kafka.connect.file.FileStreamSourceTask"
|
||||
);
|
||||
for (String clazz : jsonConverterClasses) {
|
||||
assertTrue(
|
||||
clazz + " from 'file' is not loaded in isolation but should be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertTrue(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'file' is not loaded in isolation but should be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,10 +346,8 @@ public class PluginUtilsTest {
|
|||
//"org.apache.kafka.connect.rest.basic.auth.extension.PropertyFileLoginModule" TODO fix?
|
||||
);
|
||||
for (String clazz : basicAuthExtensionClasses) {
|
||||
assertTrue(
|
||||
clazz + " from 'basic-auth-extension' is not loaded in isolation but should be",
|
||||
PluginUtils.shouldLoadInIsolation(clazz)
|
||||
);
|
||||
assertTrue(PluginUtils.shouldLoadInIsolation(clazz),
|
||||
clazz + " from 'basic-auth-extension' is not loaded in isolation but should be");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,7 +445,9 @@ public class PluginUtilsTest {
|
|||
public void testPluginUrlsWithAbsoluteSymlink() throws Exception {
|
||||
createBasicDirectoryLayout();
|
||||
|
||||
Path anotherPath = rootDir.newFolder("moreplugins").toPath().toRealPath();
|
||||
Path anotherPath = rootDir.resolve("moreplugins");
|
||||
Files.createDirectories(anotherPath);
|
||||
anotherPath = anotherPath.toRealPath();
|
||||
Files.createDirectories(anotherPath.resolve("connectorB-deps"));
|
||||
Files.createSymbolicLink(
|
||||
pluginPath.resolve("connectorB/deps/symlink"),
|
||||
|
@ -474,7 +464,9 @@ public class PluginUtilsTest {
|
|||
public void testPluginUrlsWithRelativeSymlinkBackwards() throws Exception {
|
||||
createBasicDirectoryLayout();
|
||||
|
||||
Path anotherPath = rootDir.newFolder("moreplugins").toPath().toRealPath();
|
||||
Path anotherPath = rootDir.resolve("moreplugins");
|
||||
Files.createDirectories(anotherPath);
|
||||
anotherPath = anotherPath.toRealPath();
|
||||
Files.createDirectories(anotherPath.resolve("connectorB-deps"));
|
||||
Files.createSymbolicLink(
|
||||
pluginPath.resolve("connectorB/deps/symlink"),
|
||||
|
|
|
@ -54,8 +54,8 @@ import org.apache.kafka.connect.storage.ConverterConfig;
|
|||
import org.apache.kafka.connect.storage.ConverterType;
|
||||
import org.apache.kafka.connect.storage.HeaderConverter;
|
||||
import org.apache.kafka.connect.storage.SimpleHeaderConverter;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -64,13 +64,13 @@ import java.util.Set;
|
|||
import java.util.SortedSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
|
||||
public class PluginsTest {
|
||||
|
@ -85,7 +85,7 @@ public class PluginsTest {
|
|||
private PluginScanResult empty;
|
||||
private String missingPluginClass;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Map<String, String> pluginProps = new HashMap<>();
|
||||
|
||||
|
@ -183,10 +183,10 @@ public class PluginsTest {
|
|||
config,
|
||||
ConnectRestExtension.class);
|
||||
assertNotNull(connectRestExtensions);
|
||||
assertEquals("One Rest Extension expected", 1, connectRestExtensions.size());
|
||||
assertEquals(1, connectRestExtensions.size(), "One Rest Extension expected");
|
||||
assertNotNull(connectRestExtensions.get(0));
|
||||
assertTrue("Should be instance of TestConnectRestExtension",
|
||||
connectRestExtensions.get(0) instanceof TestConnectRestExtension);
|
||||
assertTrue(connectRestExtensions.get(0) instanceof TestConnectRestExtension,
|
||||
"Should be instance of TestConnectRestExtension");
|
||||
assertNotNull(((TestConnectRestExtension) connectRestExtensions.get(0)).configs);
|
||||
assertEquals(config.originals(),
|
||||
((TestConnectRestExtension) connectRestExtensions.get(0)).configs);
|
||||
|
@ -482,7 +482,7 @@ public class PluginsTest {
|
|||
.stream()
|
||||
.filter(pluginDesc -> ByteArrayConverter.class.equals(pluginDesc.pluginClass()))
|
||||
.collect(Collectors.toSet());
|
||||
assertFalse("Could not find superclass of " + TestPlugin.SUBCLASS_OF_CLASSPATH_CONVERTER + " as plugin", converters.isEmpty());
|
||||
assertFalse(converters.isEmpty(), "Could not find superclass of " + TestPlugin.SUBCLASS_OF_CLASSPATH_CONVERTER + " as plugin");
|
||||
for (PluginDesc<Converter> byteArrayConverter : converters) {
|
||||
assertEquals("classpath", byteArrayConverter.location());
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ public class PluginsTest {
|
|||
.stream()
|
||||
.filter(pluginDesc -> AllConnectorClientConfigOverridePolicy.class.equals(pluginDesc.pluginClass()))
|
||||
.collect(Collectors.toSet());
|
||||
assertFalse("Could not find superclass of " + TestPlugin.SUBCLASS_OF_CLASSPATH_OVERRIDE_POLICY + " as plugin", overridePolicies.isEmpty());
|
||||
assertFalse(overridePolicies.isEmpty(), "Could not find superclass of " + TestPlugin.SUBCLASS_OF_CLASSPATH_OVERRIDE_POLICY + " as plugin");
|
||||
for (PluginDesc<ConnectorClientConfigOverridePolicy> allOverridePolicy : overridePolicies) {
|
||||
assertEquals("classpath", allOverridePolicy.location());
|
||||
}
|
||||
|
@ -620,10 +620,10 @@ public class PluginsTest {
|
|||
);
|
||||
plugins = new Plugins(pluginProps, parent, new ClassLoaderFactory());
|
||||
|
||||
assertTrue("Should find plugin in plugin classloader",
|
||||
plugins.converters().stream().anyMatch(desc -> desc.loader() instanceof PluginClassLoader));
|
||||
assertTrue("Should find plugin in parent classloader",
|
||||
plugins.converters().stream().anyMatch(desc -> parent.equals(desc.loader())));
|
||||
assertTrue(plugins.converters().stream().anyMatch(desc -> desc.loader() instanceof PluginClassLoader),
|
||||
"Should find plugin in plugin classloader");
|
||||
assertTrue(plugins.converters().stream().anyMatch(desc -> parent.equals(desc.loader())),
|
||||
"Should find plugin in parent classloader");
|
||||
|
||||
Converter converter = plugins.newPlugin(
|
||||
className,
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.apache.kafka.connect.runtime.isolation;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.management.LockInfo;
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
@ -45,36 +44,35 @@ import org.apache.kafka.common.config.ConfigDef;
|
|||
import org.apache.kafka.common.config.ConfigDef.Importance;
|
||||
import org.apache.kafka.common.config.ConfigDef.Type;
|
||||
import org.apache.kafka.connect.runtime.WorkerConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class SynchronizationTest {
|
||||
|
||||
public static final Logger log = LoggerFactory.getLogger(SynchronizationTest.class);
|
||||
|
||||
@Rule
|
||||
public final TestName testName = new TestName();
|
||||
|
||||
private String threadPrefix;
|
||||
private Plugins plugins;
|
||||
private ThreadPoolExecutor exec;
|
||||
private Breakpoint<String> dclBreakpoint;
|
||||
private Breakpoint<String> pclBreakpoint;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@BeforeEach
|
||||
public void setup(TestInfo testInfo) {
|
||||
Map<String, String> pluginProps = Collections.singletonMap(
|
||||
WorkerConfig.PLUGIN_PATH_CONFIG,
|
||||
TestPlugins.pluginPathJoined()
|
||||
);
|
||||
threadPrefix = SynchronizationTest.class.getSimpleName()
|
||||
+ "." + testName.getMethodName() + "-";
|
||||
+ "." + testInfo.getDisplayName() + "-";
|
||||
dclBreakpoint = new Breakpoint<>();
|
||||
pclBreakpoint = new Breakpoint<>();
|
||||
plugins = new Plugins(pluginProps, Plugins.class.getClassLoader(), new SynchronizedClassLoaderFactory());
|
||||
|
@ -89,7 +87,7 @@ public class SynchronizationTest {
|
|||
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() throws InterruptedException {
|
||||
dclBreakpoint.clear();
|
||||
pclBreakpoint.clear();
|
||||
|
@ -113,7 +111,6 @@ public class SynchronizationTest {
|
|||
public synchronized void set(Predicate<T> predicate) {
|
||||
clear();
|
||||
this.predicate = predicate;
|
||||
// As soon as the barrier is tripped, the barrier will be reset for the next round.
|
||||
barrier = new CyclicBarrier(2);
|
||||
}
|
||||
|
||||
|
@ -125,7 +122,7 @@ public class SynchronizationTest {
|
|||
Predicate<T> predicate;
|
||||
CyclicBarrier barrier;
|
||||
synchronized (this) {
|
||||
predicate = this.predicate;
|
||||
predicate = this.predicate;
|
||||
barrier = this.barrier;
|
||||
}
|
||||
if (predicate != null && !predicate.test(obj)) {
|
||||
|
@ -206,7 +203,6 @@ public class SynchronizationTest {
|
|||
|
||||
private final Breakpoint<String> pclBreakpoint;
|
||||
|
||||
|
||||
public SynchronizedPluginClassLoader(
|
||||
URL pluginLocation, URL[] urls, ClassLoader parent, Breakpoint<String> pclBreakpoint
|
||||
) {
|
||||
|
@ -221,8 +217,9 @@ public class SynchronizationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(15)
|
||||
// If the test times out, then there's a deadlock in the test but not necessarily the code
|
||||
@Test(timeout = 15000L)
|
||||
public void testSimultaneousUpwardAndDownwardDelegating() throws Exception {
|
||||
String t1Class = TestPlugins.TestPlugin.SAMPLING_CONVERTER.className();
|
||||
// Grab a reference to the target PluginClassLoader before activating breakpoints
|
||||
|
@ -300,8 +297,9 @@ public class SynchronizationTest {
|
|||
}
|
||||
|
||||
// If the test times out, then there's a deadlock in the test but not necessarily the code
|
||||
@Test(timeout = 15000L)
|
||||
@Test
|
||||
// Ensure the PluginClassLoader is parallel capable and not synchronized on its monitor lock
|
||||
@Timeout(15)
|
||||
public void testPluginClassLoaderDoesntHoldMonitorLock()
|
||||
throws InterruptedException, TimeoutException, BrokenBarrierException {
|
||||
String t1Class = TestPlugins.TestPlugin.SAMPLING_CONVERTER.className();
|
||||
|
|
|
@ -35,13 +35,14 @@ import org.apache.kafka.connect.rest.ConnectRestExtension;
|
|||
import org.apache.kafka.connect.runtime.Herder;
|
||||
import org.apache.kafka.connect.runtime.isolation.Plugins;
|
||||
import org.apache.kafka.connect.runtime.rest.entities.LoggerLevel;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
@ -56,15 +57,17 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class ConnectRestServerTest {
|
||||
|
||||
@Mock private RestClient restClient;
|
||||
|
@ -76,12 +79,12 @@ public class ConnectRestServerTest {
|
|||
|
||||
protected static final String KAFKA_CLUSTER_ID = "Xbafgnagvar";
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
httpClient = HttpClients.createMinimal();
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() throws IOException {
|
||||
for (CloseableHttpResponse response: responses) {
|
||||
response.close();
|
||||
|
@ -117,7 +120,7 @@ public class ConnectRestServerTest {
|
|||
configMap.put(RestServerConfig.LISTENERS_CONFIG, "http://localhost:8080,https://localhost:8443");
|
||||
|
||||
server = new ConnectRestServer(null, restClient, configMap);
|
||||
Assert.assertEquals("http://localhost:8080/", server.advertisedUrl().toString());
|
||||
assertEquals("http://localhost:8080/", server.advertisedUrl().toString());
|
||||
server.stop();
|
||||
|
||||
// Advertised URI from listeners with protocol
|
||||
|
@ -126,7 +129,7 @@ public class ConnectRestServerTest {
|
|||
configMap.put(RestServerConfig.REST_ADVERTISED_LISTENER_CONFIG, "https");
|
||||
|
||||
server = new ConnectRestServer(null, restClient, configMap);
|
||||
Assert.assertEquals("https://localhost:8443/", server.advertisedUrl().toString());
|
||||
assertEquals("https://localhost:8443/", server.advertisedUrl().toString());
|
||||
server.stop();
|
||||
|
||||
// Advertised URI from listeners with only SSL available
|
||||
|
@ -134,7 +137,7 @@ public class ConnectRestServerTest {
|
|||
configMap.put(RestServerConfig.LISTENERS_CONFIG, "https://localhost:8443");
|
||||
|
||||
server = new ConnectRestServer(null, restClient, configMap);
|
||||
Assert.assertEquals("https://localhost:8443/", server.advertisedUrl().toString());
|
||||
assertEquals("https://localhost:8443/", server.advertisedUrl().toString());
|
||||
server.stop();
|
||||
|
||||
// Listener is overridden by advertised values
|
||||
|
@ -145,7 +148,7 @@ public class ConnectRestServerTest {
|
|||
configMap.put(RestServerConfig.REST_ADVERTISED_PORT_CONFIG, "10000");
|
||||
|
||||
server = new ConnectRestServer(null, restClient, configMap);
|
||||
Assert.assertEquals("http://somehost:10000/", server.advertisedUrl().toString());
|
||||
assertEquals("http://somehost:10000/", server.advertisedUrl().toString());
|
||||
server.stop();
|
||||
|
||||
// correct listener is chosen when https listener is configured before http listener and advertised listener is http
|
||||
|
@ -154,7 +157,7 @@ public class ConnectRestServerTest {
|
|||
configMap.put(RestServerConfig.REST_ADVERTISED_LISTENER_CONFIG, "http");
|
||||
|
||||
server = new ConnectRestServer(null, restClient, configMap);
|
||||
Assert.assertEquals("http://plaintext-localhost:4761/", server.advertisedUrl().toString());
|
||||
assertEquals("http://plaintext-localhost:4761/", server.advertisedUrl().toString());
|
||||
server.stop();
|
||||
}
|
||||
|
||||
|
@ -173,10 +176,10 @@ public class ConnectRestServerTest {
|
|||
HttpOptions request = new HttpOptions("/connectors");
|
||||
request.addHeader("Content-Type", MediaType.WILDCARD);
|
||||
HttpResponse response = executeRequest(server.advertisedUrl(), request);
|
||||
Assert.assertEquals(MediaType.TEXT_PLAIN, response.getEntity().getContentType().getValue());
|
||||
assertEquals(MediaType.TEXT_PLAIN, response.getEntity().getContentType().getValue());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
response.getEntity().writeTo(baos);
|
||||
Assert.assertArrayEquals(
|
||||
assertArrayEquals(
|
||||
request.getAllowedMethods(response).toArray(),
|
||||
new String(baos.toByteArray(), StandardCharsets.UTF_8).split(", ")
|
||||
);
|
||||
|
@ -203,10 +206,10 @@ public class ConnectRestServerTest {
|
|||
request.addHeader("Origin", origin);
|
||||
HttpResponse response = executeRequest(serverUrl, request);
|
||||
|
||||
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
|
||||
if (expectedHeader != null) {
|
||||
Assert.assertEquals(expectedHeader,
|
||||
assertEquals(expectedHeader,
|
||||
response.getFirstHeader("Access-Control-Allow-Origin").getValue());
|
||||
}
|
||||
|
||||
|
@ -215,13 +218,13 @@ public class ConnectRestServerTest {
|
|||
request.addHeader("Origin", origin);
|
||||
request.addHeader("Access-Control-Request-Method", method);
|
||||
response = executeRequest(serverUrl, request);
|
||||
Assert.assertEquals(404, response.getStatusLine().getStatusCode());
|
||||
assertEquals(404, response.getStatusLine().getStatusCode());
|
||||
if (expectedHeader != null) {
|
||||
Assert.assertEquals(expectedHeader,
|
||||
assertEquals(expectedHeader,
|
||||
response.getFirstHeader("Access-Control-Allow-Origin").getValue());
|
||||
}
|
||||
if (method != null) {
|
||||
Assert.assertEquals(method,
|
||||
assertEquals(method,
|
||||
response.getFirstHeader("Access-Control-Allow-Methods").getValue());
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +245,7 @@ public class ConnectRestServerTest {
|
|||
HttpRequest request = new HttpGet("/connectors");
|
||||
HttpResponse response = executeRequest(server.advertisedUrl(), request);
|
||||
|
||||
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -304,7 +307,7 @@ public class ConnectRestServerTest {
|
|||
|
||||
HttpRequest request = new HttpGet("/admin/loggers");
|
||||
HttpResponse response = executeRequest(server.advertisedUrl(), request);
|
||||
Assert.assertEquals(404, response.getStatusLine().getStatusCode());
|
||||
assertEquals(404, response.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -324,7 +327,7 @@ public class ConnectRestServerTest {
|
|||
|
||||
HttpRequest request = new HttpGet("/admin/loggers");
|
||||
HttpResponse response = executeRequest(server.advertisedUrl(), request);
|
||||
Assert.assertEquals(404, response.getStatusLine().getStatusCode());
|
||||
assertEquals(404, response.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -386,12 +389,12 @@ public class ConnectRestServerTest {
|
|||
server.initializeResources(herder);
|
||||
HttpRequest request = new HttpGet("/connectors");
|
||||
HttpResponse response = executeRequest(server.advertisedUrl(), request);
|
||||
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
if (!headerConfig.isEmpty()) {
|
||||
expectedHeaders.forEach((k, v) ->
|
||||
Assert.assertEquals(response.getFirstHeader(k).getValue(), v));
|
||||
assertEquals(response.getFirstHeader(k).getValue(), v));
|
||||
} else {
|
||||
Assert.assertNull(response.getFirstHeader("X-Frame-Options"));
|
||||
assertNull(response.getFirstHeader("X-Frame-Options"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,7 +402,7 @@ public class ConnectRestServerTest {
|
|||
HttpRequest request = new HttpGet(endpoint);
|
||||
HttpResponse response = executeRequest(serverUrl, request);
|
||||
|
||||
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
return new BasicResponseHandler().handleResponse(response);
|
||||
}
|
||||
|
||||
|
@ -410,7 +413,7 @@ public class ConnectRestServerTest {
|
|||
request.setEntity(entity);
|
||||
HttpResponse response = executeRequest(serverUrl, request);
|
||||
|
||||
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
return new BasicResponseHandler().handleResponse(response);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,12 @@ import org.apache.kafka.connect.errors.ConnectException;
|
|||
import org.apache.kafka.connect.runtime.distributed.Crypto;
|
||||
import org.apache.kafka.connect.runtime.rest.errors.BadRequestException;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
|
@ -34,18 +36,19 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class InternalRequestSignatureTest {
|
||||
|
||||
private static final byte[] REQUEST_BODY =
|
||||
|
@ -123,16 +126,12 @@ public class InternalRequestSignatureTest {
|
|||
|
||||
InternalRequestSignature.addToRequest(crypto, KEY, REQUEST_BODY, SIGNATURE_ALGORITHM, request);
|
||||
|
||||
assertEquals(
|
||||
"Request should have valid base 64-encoded signature added as header",
|
||||
ENCODED_SIGNATURE,
|
||||
signatureCapture.getValue()
|
||||
);
|
||||
assertEquals(
|
||||
"Request should have provided signature algorithm added as header",
|
||||
SIGNATURE_ALGORITHM,
|
||||
signatureAlgorithmCapture.getValue()
|
||||
);
|
||||
assertEquals(ENCODED_SIGNATURE,
|
||||
signatureCapture.getValue(),
|
||||
"Request should have valid base 64-encoded signature added as header");
|
||||
assertEquals(SIGNATURE_ALGORITHM,
|
||||
signatureAlgorithmCapture.getValue(),
|
||||
"Request should have provided signature algorithm added as header");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.apache.kafka.connect.runtime.rest;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.kafka.connect.runtime.rest.entities.ErrorMessage;
|
||||
|
@ -27,25 +26,23 @@ import org.apache.kafka.connect.runtime.rest.errors.ConnectRestException;
|
|||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.runners.Enclosed;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -61,18 +58,21 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(Enclosed.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class RestClientTest {
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
private static final String MOCK_URL = "http://localhost:1234/api/endpoint";
|
||||
private static final String TEST_METHOD = "GET";
|
||||
private static final TestDTO TEST_DTO = new TestDTO("requestBodyData");
|
||||
private static final TypeReference<TestDTO> TEST_TYPE = new TypeReference<TestDTO>() {
|
||||
};
|
||||
private static final TypeReference<TestDTO> TEST_TYPE = new TypeReference<TestDTO>() { };
|
||||
private static final SecretKey MOCK_SECRET_KEY = getMockSecretKey();
|
||||
private static final String TEST_SIGNATURE_ALGORITHM = "HmacSHA1";
|
||||
|
||||
@Mock
|
||||
private HttpClient httpClient;
|
||||
|
||||
private static void assertIsInternalServerError(ConnectRestException e) {
|
||||
assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.statusCode());
|
||||
assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.errorCode());
|
||||
|
@ -80,7 +80,7 @@ public class RestClientTest {
|
|||
|
||||
private static SecretKey getMockSecretKey() {
|
||||
SecretKey mockKey = mock(SecretKey.class);
|
||||
when(mockKey.getFormat()).thenReturn("RAW"); // supported format by
|
||||
when(mockKey.getFormat()).thenReturn("RAW");
|
||||
when(mockKey.getEncoded()).thenReturn("SomeKey".getBytes(StandardCharsets.UTF_8));
|
||||
return mockKey;
|
||||
}
|
||||
|
@ -105,227 +105,230 @@ public class RestClientTest {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public static class RequestFailureParameterizedTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule initRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
|
||||
|
||||
@Mock
|
||||
private HttpClient httpClient;
|
||||
|
||||
@Parameterized.Parameter
|
||||
public Throwable requestException;
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> requestExceptions() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{new InterruptedException()},
|
||||
{new ExecutionException(null)},
|
||||
{new TimeoutException()}
|
||||
});
|
||||
}
|
||||
|
||||
private static Request buildThrowingMockRequest(Throwable t) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
Request req = mock(Request.class);
|
||||
when(req.header(anyString(), anyString())).thenReturn(req);
|
||||
when(req.send()).thenThrow(t);
|
||||
return req;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureDuringRequestCausesInternalServerError() throws Exception {
|
||||
Request request = buildThrowingMockRequest(requestException);
|
||||
when(httpClient.newRequest(anyString())).thenReturn(request);
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
assertEquals(requestException, e.getCause());
|
||||
}
|
||||
private static Stream<Arguments> requestExceptions() {
|
||||
return Stream.of(
|
||||
Arguments.of(new InterruptedException()),
|
||||
Arguments.of(new ExecutionException(null)),
|
||||
Arguments.of(new TimeoutException())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public static class Tests {
|
||||
@Mock
|
||||
private HttpClient httpClient;
|
||||
|
||||
private static String toJsonString(Object obj) {
|
||||
try {
|
||||
return OBJECT_MAPPER.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupHttpClient(int responseCode, String responseJsonString) throws Exception {
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
when(resp.getStatus()).thenReturn(responseCode);
|
||||
when(resp.getContentAsString()).thenReturn(responseJsonString);
|
||||
when(req.send()).thenReturn(resp);
|
||||
when(req.header(anyString(), anyString())).thenReturn(req);
|
||||
when(httpClient.newRequest(anyString())).thenReturn(req);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullUrl() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
setupHttpClient(statusCode, toJsonString(TEST_DTO));
|
||||
|
||||
assertThrows(NullPointerException.class, () -> httpRequest(
|
||||
httpClient, null, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullMethod() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
setupHttpClient(statusCode, toJsonString(TEST_DTO));
|
||||
|
||||
assertThrows(NullPointerException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, null, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullResponseType() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
setupHttpClient(statusCode, toJsonString(TEST_DTO));
|
||||
|
||||
assertThrows(NullPointerException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, null, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
setupHttpClient(statusCode, toJsonString(TEST_DTO));
|
||||
|
||||
RestClient.HttpResponse<TestDTO> httpResp = httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
assertEquals(statusCode, httpResp.status());
|
||||
assertEquals(TEST_DTO, httpResp.body());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoContent() throws Exception {
|
||||
int statusCode = Response.Status.NO_CONTENT.getStatusCode();
|
||||
setupHttpClient(statusCode, null);
|
||||
|
||||
RestClient.HttpResponse<TestDTO> httpResp = httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
assertEquals(statusCode, httpResp.status());
|
||||
assertNull(httpResp.body());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusCodeAndErrorMessagePreserved() throws Exception {
|
||||
int statusCode = Response.Status.CONFLICT.getStatusCode();
|
||||
ErrorMessage errorMsg = new ErrorMessage(Response.Status.GONE.getStatusCode(), "Some Error Message");
|
||||
setupHttpClient(statusCode, toJsonString(errorMsg));
|
||||
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertEquals(statusCode, e.statusCode());
|
||||
assertEquals(errorMsg.errorCode(), e.errorCode());
|
||||
assertEquals(errorMsg.message(), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonEmptyResponseWithVoidResponseType() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
setupHttpClient(statusCode, toJsonString(TEST_DTO));
|
||||
|
||||
TypeReference<Void> voidResponse = new TypeReference<Void>() { };
|
||||
RestClient.HttpResponse<Void> httpResp = httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, voidResponse, TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
assertEquals(statusCode, httpResp.status());
|
||||
assertNull(httpResp.body());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnexpectedHttpResponseCausesInternalServerError() throws Exception {
|
||||
int statusCode = Response.Status.NOT_MODIFIED.getStatusCode(); // never thrown explicitly -
|
||||
// should be treated as an unexpected error and translated into 500 INTERNAL_SERVER_ERROR
|
||||
|
||||
setupHttpClient(statusCode, null);
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRuntimeExceptionCausesInternalServerError() {
|
||||
when(httpClient.newRequest(anyString())).thenThrow(new RuntimeException());
|
||||
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestSignatureFailureCausesInternalServerError() throws Exception {
|
||||
setupHttpClient(0, null);
|
||||
|
||||
String invalidRequestSignatureAlgorithm = "Foo";
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, invalidRequestSignatureAlgorithm
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIOExceptionCausesInternalServerError() throws Exception {
|
||||
String invalidJsonString = "Invalid";
|
||||
setupHttpClient(201, invalidJsonString);
|
||||
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseSslConfigsOnlyWhenNecessary() throws Exception {
|
||||
// See KAFKA-14816; we want to make sure that even if the worker is configured with invalid SSL properties,
|
||||
// REST requests only fail if we try to contact a URL using HTTPS (but not HTTP)
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
setupHttpClient(statusCode, toJsonString(TEST_DTO));
|
||||
|
||||
assertDoesNotThrow(() -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
String httpsUrl = "https://localhost:1234/api/endpoint";
|
||||
assertThrows(RuntimeException.class, () -> httpRequest(
|
||||
httpClient, httpsUrl, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpRequestInterrupted() throws ExecutionException, InterruptedException, TimeoutException {
|
||||
Request req = mock(Request.class);
|
||||
doThrow(new InterruptedException()).when(req).send();
|
||||
doReturn(req).when(req).header(anyString(), anyString());
|
||||
doReturn(req).when(httpClient).newRequest(anyString());
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
assertInstanceOf(InterruptedException.class, e.getCause());
|
||||
assertTrue(Thread.interrupted());
|
||||
}
|
||||
private static Request buildThrowingMockRequest(Throwable t) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
Request req = mock(Request.class);
|
||||
when(req.header(anyString(), anyString())).thenReturn(req);
|
||||
when(req.send()).thenThrow(t);
|
||||
return req;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("requestExceptions")
|
||||
public void testFailureDuringRequestCausesInternalServerError(Throwable requestException) throws Exception {
|
||||
Request request = buildThrowingMockRequest(requestException);
|
||||
when(httpClient.newRequest(anyString())).thenReturn(request);
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
assertEquals(requestException, e.getCause());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullUrl() {
|
||||
RestClient client = spy(new RestClient(null));
|
||||
assertThrows(NullPointerException.class, () -> {
|
||||
client.httpRequest(
|
||||
null,
|
||||
TEST_METHOD,
|
||||
null,
|
||||
TEST_DTO,
|
||||
TEST_TYPE,
|
||||
MOCK_SECRET_KEY,
|
||||
TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullMethod() {
|
||||
RestClient client = spy(new RestClient(null));
|
||||
assertThrows(NullPointerException.class, () -> client.httpRequest(
|
||||
MOCK_URL,
|
||||
null,
|
||||
null,
|
||||
TEST_DTO,
|
||||
TEST_TYPE,
|
||||
MOCK_SECRET_KEY,
|
||||
TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullResponseType() {
|
||||
RestClient client = spy(new RestClient(null));
|
||||
assertThrows(NullPointerException.class, () -> client.httpRequest(
|
||||
MOCK_URL,
|
||||
TEST_METHOD,
|
||||
null,
|
||||
TEST_DTO,
|
||||
null,
|
||||
MOCK_SECRET_KEY,
|
||||
TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
when(resp.getContentAsString()).thenReturn(toJsonString(TEST_DTO));
|
||||
setupHttpClient(statusCode, req, resp);
|
||||
|
||||
RestClient.HttpResponse<TestDTO> httpResp = httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
assertEquals(statusCode, httpResp.status());
|
||||
assertEquals(TEST_DTO, httpResp.body());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoContent() throws Exception {
|
||||
int statusCode = Response.Status.NO_CONTENT.getStatusCode();
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
setupHttpClient(statusCode, req, resp);
|
||||
|
||||
RestClient.HttpResponse<TestDTO> httpResp = httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
assertEquals(statusCode, httpResp.status());
|
||||
assertNull(httpResp.body());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusCodeAndErrorMessagePreserved() throws Exception {
|
||||
int statusCode = Response.Status.CONFLICT.getStatusCode();
|
||||
ErrorMessage errorMsg = new ErrorMessage(Response.Status.GONE.getStatusCode(), "Some Error Message");
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
when(resp.getContentAsString()).thenReturn(toJsonString(errorMsg));
|
||||
setupHttpClient(statusCode, req, resp);
|
||||
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertEquals(statusCode, e.statusCode());
|
||||
assertEquals(errorMsg.errorCode(), e.errorCode());
|
||||
assertEquals(errorMsg.message(), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonEmptyResponseWithVoidResponseType() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
when(resp.getContentAsString()).thenReturn(toJsonString(TEST_DTO));
|
||||
setupHttpClient(statusCode, req, resp);
|
||||
|
||||
TypeReference<Void> voidResponse = new TypeReference<Void>() { };
|
||||
RestClient.HttpResponse<Void> httpResp = httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, voidResponse, TEST_SIGNATURE_ALGORITHM
|
||||
);
|
||||
assertEquals(statusCode, httpResp.status());
|
||||
assertNull(httpResp.body());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnexpectedHttpResponseCausesInternalServerError() throws Exception {
|
||||
int statusCode = Response.Status.NOT_MODIFIED.getStatusCode();
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
|
||||
setupHttpClient(statusCode, req, resp);
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRuntimeExceptionCausesInternalServerError() {
|
||||
when(httpClient.newRequest(anyString())).thenThrow(new RuntimeException());
|
||||
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestSignatureFailureCausesInternalServerError() {
|
||||
String invalidRequestSignatureAlgorithm = "Foo";
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, invalidRequestSignatureAlgorithm
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIOExceptionCausesInternalServerError() throws Exception {
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
setupHttpClient(201, req, resp);
|
||||
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseSslConfigsOnlyWhenNecessary() throws Exception {
|
||||
int statusCode = Response.Status.OK.getStatusCode();
|
||||
Request req = mock(Request.class);
|
||||
ContentResponse resp = mock(ContentResponse.class);
|
||||
when(resp.getContentAsString()).thenReturn(toJsonString(TEST_DTO));
|
||||
setupHttpClient(statusCode, req, resp);
|
||||
assertDoesNotThrow(() -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
String httpsUrl = "https://localhost:1234/api/endpoint";
|
||||
RestClient client = spy(new RestClient(null));
|
||||
assertThrows(RuntimeException.class, () -> client.httpRequest(
|
||||
httpsUrl,
|
||||
TEST_METHOD,
|
||||
null,
|
||||
TEST_DTO,
|
||||
TEST_TYPE,
|
||||
MOCK_SECRET_KEY,
|
||||
TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpRequestInterrupted() throws ExecutionException, InterruptedException, TimeoutException {
|
||||
Request req = mock(Request.class);
|
||||
doThrow(new InterruptedException()).when(req).send();
|
||||
doReturn(req).when(req).header(anyString(), anyString());
|
||||
doReturn(req).when(httpClient).newRequest(anyString());
|
||||
ConnectRestException e = assertThrows(ConnectRestException.class, () -> httpRequest(
|
||||
httpClient, MOCK_URL, TEST_METHOD, TEST_TYPE, TEST_SIGNATURE_ALGORITHM
|
||||
));
|
||||
assertIsInternalServerError(e);
|
||||
assertInstanceOf(InterruptedException.class, e.getCause());
|
||||
assertTrue(Thread.interrupted());
|
||||
}
|
||||
|
||||
private void setupHttpClient(int responseCode, Request req, ContentResponse resp) throws Exception {
|
||||
when(resp.getStatus()).thenReturn(responseCode);
|
||||
when(req.send()).thenReturn(resp);
|
||||
when(req.header(anyString(), anyString())).thenReturn(req);
|
||||
when(httpClient.newRequest(anyString())).thenReturn(req);
|
||||
}
|
||||
|
||||
private String toJsonString(Object obj) {
|
||||
return assertDoesNotThrow(() -> OBJECT_MAPPER.writeValueAsString(obj));
|
||||
}
|
||||
|
||||
private static class TestDTO {
|
||||
private final String content;
|
||||
|
@ -352,4 +355,4 @@ public class RestClientTest {
|
|||
return Objects.hash(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ package org.apache.kafka.connect.runtime.rest;
|
|||
|
||||
import org.apache.kafka.common.config.ConfigException;
|
||||
import org.apache.kafka.common.config.internals.BrokerSecurityConfigs;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -27,10 +27,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.apache.kafka.connect.runtime.rest.RestServerConfig.LISTENERS_DEFAULT;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class RestServerConfigTest {
|
||||
|
||||
|
@ -106,7 +106,7 @@ public class RestServerConfigTest {
|
|||
|
||||
// no value set for "admin.listeners"
|
||||
RestServerConfig config = RestServerConfig.forPublic(null, props);
|
||||
assertNull("Default value should be null.", config.adminListeners());
|
||||
assertNull(config.adminListeners(), "Default value should be null.");
|
||||
|
||||
props.put(RestServerConfig.ADMIN_LISTENERS_CONFIG, "");
|
||||
config = RestServerConfig.forPublic(null, props);
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
package org.apache.kafka.connect.runtime.rest.entities;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ConnectorOffsetsTest {
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
*/
|
||||
package org.apache.kafka.connect.runtime.rest.entities;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ConnectorTypeTest {
|
||||
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
package org.apache.kafka.connect.runtime.rest.entities;
|
||||
|
||||
import org.apache.kafka.connect.runtime.TargetState;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class CreateConnectorRequestTest {
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package org.apache.kafka.connect.runtime.rest.entities;
|
||||
|
||||
import org.apache.kafka.connect.runtime.isolation.PluginDesc;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
|
|
@ -59,11 +59,13 @@ import org.apache.kafka.connect.transforms.TimestampConverter;
|
|||
import org.apache.kafka.connect.transforms.predicates.HasHeaderKey;
|
||||
import org.apache.kafka.connect.transforms.predicates.RecordIsTombstone;
|
||||
import org.apache.kafka.connect.util.Callback;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import javax.ws.rs.BadRequestException;
|
||||
import java.net.URL;
|
||||
|
@ -83,10 +85,10 @@ import java.util.stream.Collectors;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
|
@ -97,7 +99,8 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class ConnectorPluginsResourceTest {
|
||||
|
||||
private static final Map<String, String> PROPS;
|
||||
|
@ -201,7 +204,7 @@ public class ConnectorPluginsResourceTest {
|
|||
private final Plugins plugins = mock(Plugins.class);
|
||||
private ConnectorPluginsResource connectorPluginsResource;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
doReturn(plugins).when(herder).plugins();
|
||||
doReturn(SINK_CONNECTOR_PLUGINS).when(plugins).sinkConnectors();
|
||||
|
|
|
@ -42,14 +42,15 @@ import org.apache.kafka.connect.runtime.rest.entities.TaskInfo;
|
|||
import org.apache.kafka.connect.runtime.rest.errors.ConnectRestException;
|
||||
import org.apache.kafka.connect.util.Callback;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Stubber;
|
||||
|
||||
import javax.ws.rs.BadRequestException;
|
||||
|
@ -69,9 +70,9 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
|
@ -83,7 +84,8 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ConnectorsResourceTest {
|
||||
// Note trailing / and that we do *not* use LEADER_URL to construct our reference values. This checks that we handle
|
||||
|
@ -166,18 +168,15 @@ public class ConnectorsResourceTest {
|
|||
@Mock
|
||||
private RestServerConfig serverConfig;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
when(serverConfig.topicTrackingEnabled()).thenReturn(true);
|
||||
when(serverConfig.topicTrackingResetEnabled()).thenReturn(true);
|
||||
connectorsResource = new ConnectorsResource(herder, serverConfig, restClient, REQUEST_TIMEOUT);
|
||||
forward = mock(UriInfo.class);
|
||||
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<>();
|
||||
queryParams.putSingle("forward", "true");
|
||||
when(forward.getQueryParameters()).thenReturn(queryParams);
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
verifyNoMoreInteractions(herder);
|
||||
}
|
||||
|
@ -188,6 +187,9 @@ public class ConnectorsResourceTest {
|
|||
|
||||
@Test
|
||||
public void testListConnectors() {
|
||||
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<>();
|
||||
queryParams.putSingle("forward", "true");
|
||||
when(forward.getQueryParameters()).thenReturn(queryParams);
|
||||
when(herder.connectors()).thenReturn(Arrays.asList(CONNECTOR2_NAME, CONNECTOR_NAME));
|
||||
|
||||
Collection<String> connectors = (Collection<String>) connectorsResource.listConnectors(forward, NULL_HEADERS).getEntity();
|
||||
|
@ -539,7 +541,7 @@ public class ConnectorsResourceTest {
|
|||
|
||||
String rspLocation = connectorsResource.createConnector(FORWARD, NULL_HEADERS, body).getLocation().toString();
|
||||
String decoded = new URI(rspLocation).getPath();
|
||||
Assert.assertEquals("/connectors/" + CONNECTOR_NAME_SPECIAL_CHARS, decoded);
|
||||
assertEquals("/connectors/" + CONNECTOR_NAME_SPECIAL_CHARS, decoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -554,7 +556,7 @@ public class ConnectorsResourceTest {
|
|||
|
||||
String rspLocation = connectorsResource.createConnector(FORWARD, NULL_HEADERS, body).getLocation().toString();
|
||||
String decoded = new URI(rspLocation).getPath();
|
||||
Assert.assertEquals("/connectors/" + CONNECTOR_NAME_CONTROL_SEQUENCES1, decoded);
|
||||
assertEquals("/connectors/" + CONNECTOR_NAME_CONTROL_SEQUENCES1, decoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -567,7 +569,7 @@ public class ConnectorsResourceTest {
|
|||
|
||||
String rspLocation = connectorsResource.putConnectorConfig(CONNECTOR_NAME_SPECIAL_CHARS, NULL_HEADERS, FORWARD, CONNECTOR_CONFIG_SPECIAL_CHARS).getLocation().toString();
|
||||
String decoded = new URI(rspLocation).getPath();
|
||||
Assert.assertEquals("/connectors/" + CONNECTOR_NAME_SPECIAL_CHARS, decoded);
|
||||
assertEquals("/connectors/" + CONNECTOR_NAME_SPECIAL_CHARS, decoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -580,7 +582,7 @@ public class ConnectorsResourceTest {
|
|||
|
||||
String rspLocation = connectorsResource.putConnectorConfig(CONNECTOR_NAME_CONTROL_SEQUENCES1, NULL_HEADERS, FORWARD, CONNECTOR_CONFIG_CONTROL_SEQUENCES).getLocation().toString();
|
||||
String decoded = new URI(rspLocation).getPath();
|
||||
Assert.assertEquals("/connectors/" + CONNECTOR_NAME_CONTROL_SEQUENCES1, decoded);
|
||||
assertEquals("/connectors/" + CONNECTOR_NAME_CONTROL_SEQUENCES1, decoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -23,12 +23,14 @@ import org.apache.kafka.connect.runtime.rest.InternalRequestSignature;
|
|||
import org.apache.kafka.connect.runtime.rest.RestClient;
|
||||
import org.apache.kafka.connect.runtime.rest.RestServer;
|
||||
import org.apache.kafka.connect.util.Callback;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Stubber;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
|
@ -41,8 +43,8 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.eq;
|
||||
|
@ -50,7 +52,8 @@ import static org.mockito.Mockito.isNull;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class InternalConnectResourceTest {
|
||||
|
||||
private static final Boolean FORWARD = true;
|
||||
|
@ -73,7 +76,7 @@ public class InternalConnectResourceTest {
|
|||
|
||||
private InternalConnectResource internalResource;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
internalResource = new InternalConnectResource(herder, restClient, () -> RestServer.DEFAULT_REST_REQUEST_TIMEOUT_MS);
|
||||
internalResource.uriInfo = uriInfo;
|
||||
|
|
|
@ -21,11 +21,13 @@ import org.apache.kafka.connect.errors.NotFoundException;
|
|||
import org.apache.kafka.connect.runtime.Herder;
|
||||
import org.apache.kafka.connect.runtime.rest.entities.LoggerLevel;
|
||||
import org.apache.kafka.connect.runtime.rest.errors.BadRequestException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -33,13 +35,14 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class LoggingResourceTest {
|
||||
|
||||
private LoggingResource loggingResource;
|
||||
|
@ -47,7 +50,7 @@ public class LoggingResourceTest {
|
|||
@Mock
|
||||
private Herder herder;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
loggingResource = new LoggingResource(herder);
|
||||
}
|
||||
|
|
|
@ -20,23 +20,26 @@ import org.apache.kafka.clients.admin.MockAdminClient;
|
|||
import org.apache.kafka.common.utils.AppInfoParser;
|
||||
import org.apache.kafka.connect.runtime.Herder;
|
||||
import org.apache.kafka.connect.runtime.rest.entities.ServerInfo;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
public class RootResourceTest {
|
||||
|
||||
@Mock private Herder herder;
|
||||
private RootResource rootResource;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
rootResource = new RootResource(herder);
|
||||
}
|
||||
|
|
|
@ -19,13 +19,17 @@ package org.apache.kafka.connect.runtime.rest.util;
|
|||
import org.apache.kafka.common.config.SslConfigs;
|
||||
import org.apache.kafka.connect.runtime.rest.RestServerConfig;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class SSLUtilsTest {
|
||||
|
||||
@Test
|
||||
|
@ -37,8 +41,8 @@ public class SSLUtilsTest {
|
|||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("exists", "value");
|
||||
|
||||
Assert.assertEquals(SSLUtils.getOrDefault(map, existingKey, defaultValue), value);
|
||||
Assert.assertEquals(SSLUtils.getOrDefault(map, missingKey, defaultValue), defaultValue);
|
||||
assertEquals(SSLUtils.getOrDefault(map, existingKey, defaultValue), value);
|
||||
assertEquals(SSLUtils.getOrDefault(map, missingKey, defaultValue), defaultValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -64,19 +68,19 @@ public class SSLUtilsTest {
|
|||
RestServerConfig config = RestServerConfig.forPublic(null, configMap);
|
||||
SslContextFactory.Server ssl = SSLUtils.createServerSideSslContextFactory(config);
|
||||
|
||||
Assert.assertEquals("file:///path/to/keystore", ssl.getKeyStorePath());
|
||||
Assert.assertEquals("file:///path/to/truststore", ssl.getTrustStorePath());
|
||||
Assert.assertEquals("SunJSSE", ssl.getProvider());
|
||||
Assert.assertArrayEquals(new String[] {"SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5"}, ssl.getIncludeCipherSuites());
|
||||
Assert.assertEquals("SHA1PRNG", ssl.getSecureRandomAlgorithm());
|
||||
Assert.assertTrue(ssl.getNeedClientAuth());
|
||||
Assert.assertFalse(ssl.getWantClientAuth());
|
||||
Assert.assertEquals("JKS", ssl.getKeyStoreType());
|
||||
Assert.assertEquals("JKS", ssl.getTrustStoreType());
|
||||
Assert.assertEquals("TLS", ssl.getProtocol());
|
||||
Assert.assertArrayEquals(new String[] {"TLSv1.2", "TLSv1.1", "TLSv1"}, ssl.getIncludeProtocols());
|
||||
Assert.assertEquals("SunX509", ssl.getKeyManagerFactoryAlgorithm());
|
||||
Assert.assertEquals("PKIX", ssl.getTrustManagerFactoryAlgorithm());
|
||||
assertEquals("file:///path/to/keystore", ssl.getKeyStorePath());
|
||||
assertEquals("file:///path/to/truststore", ssl.getTrustStorePath());
|
||||
assertEquals("SunJSSE", ssl.getProvider());
|
||||
assertArrayEquals(new String[] {"SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5"}, ssl.getIncludeCipherSuites());
|
||||
assertEquals("SHA1PRNG", ssl.getSecureRandomAlgorithm());
|
||||
assertTrue(ssl.getNeedClientAuth());
|
||||
assertFalse(ssl.getWantClientAuth());
|
||||
assertEquals("JKS", ssl.getKeyStoreType());
|
||||
assertEquals("JKS", ssl.getTrustStoreType());
|
||||
assertEquals("TLS", ssl.getProtocol());
|
||||
assertArrayEquals(new String[] {"TLSv1.2", "TLSv1.1", "TLSv1"}, ssl.getIncludeProtocols());
|
||||
assertEquals("SunX509", ssl.getKeyManagerFactoryAlgorithm());
|
||||
assertEquals("PKIX", ssl.getTrustManagerFactoryAlgorithm());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -102,17 +106,17 @@ public class SSLUtilsTest {
|
|||
RestServerConfig config = RestServerConfig.forPublic(null, configMap);
|
||||
SslContextFactory.Client ssl = SSLUtils.createClientSideSslContextFactory(config);
|
||||
|
||||
Assert.assertEquals("file:///path/to/keystore", ssl.getKeyStorePath());
|
||||
Assert.assertEquals("file:///path/to/truststore", ssl.getTrustStorePath());
|
||||
Assert.assertEquals("SunJSSE", ssl.getProvider());
|
||||
Assert.assertArrayEquals(new String[] {"SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5"}, ssl.getIncludeCipherSuites());
|
||||
Assert.assertEquals("SHA1PRNG", ssl.getSecureRandomAlgorithm());
|
||||
Assert.assertEquals("JKS", ssl.getKeyStoreType());
|
||||
Assert.assertEquals("JKS", ssl.getTrustStoreType());
|
||||
Assert.assertEquals("TLS", ssl.getProtocol());
|
||||
Assert.assertArrayEquals(new String[] {"TLSv1.2", "TLSv1.1", "TLSv1"}, ssl.getIncludeProtocols());
|
||||
Assert.assertEquals("SunX509", ssl.getKeyManagerFactoryAlgorithm());
|
||||
Assert.assertEquals("PKIX", ssl.getTrustManagerFactoryAlgorithm());
|
||||
assertEquals("file:///path/to/keystore", ssl.getKeyStorePath());
|
||||
assertEquals("file:///path/to/truststore", ssl.getTrustStorePath());
|
||||
assertEquals("SunJSSE", ssl.getProvider());
|
||||
assertArrayEquals(new String[] {"SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5"}, ssl.getIncludeCipherSuites());
|
||||
assertEquals("SHA1PRNG", ssl.getSecureRandomAlgorithm());
|
||||
assertEquals("JKS", ssl.getKeyStoreType());
|
||||
assertEquals("JKS", ssl.getTrustStoreType());
|
||||
assertEquals("TLS", ssl.getProtocol());
|
||||
assertArrayEquals(new String[] {"TLSv1.2", "TLSv1.1", "TLSv1"}, ssl.getIncludeProtocols());
|
||||
assertEquals("SunX509", ssl.getKeyManagerFactoryAlgorithm());
|
||||
assertEquals("PKIX", ssl.getTrustManagerFactoryAlgorithm());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -130,14 +134,14 @@ public class SSLUtilsTest {
|
|||
RestServerConfig config = RestServerConfig.forPublic(null, configMap);
|
||||
SslContextFactory.Server ssl = SSLUtils.createServerSideSslContextFactory(config);
|
||||
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE, ssl.getKeyStoreType());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE, ssl.getTrustStoreType());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_PROTOCOL, ssl.getProtocol());
|
||||
Assert.assertArrayEquals(Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split("\\s*,\\s*")).toArray(), ssl.getIncludeProtocols());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_KEYMANGER_ALGORITHM, ssl.getKeyManagerFactoryAlgorithm());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_TRUSTMANAGER_ALGORITHM, ssl.getTrustManagerFactoryAlgorithm());
|
||||
Assert.assertFalse(ssl.getNeedClientAuth());
|
||||
Assert.assertFalse(ssl.getWantClientAuth());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE, ssl.getKeyStoreType());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE, ssl.getTrustStoreType());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_PROTOCOL, ssl.getProtocol());
|
||||
assertArrayEquals(Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split("\\s*,\\s*")).toArray(), ssl.getIncludeProtocols());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_KEYMANGER_ALGORITHM, ssl.getKeyManagerFactoryAlgorithm());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_TRUSTMANAGER_ALGORITHM, ssl.getTrustManagerFactoryAlgorithm());
|
||||
assertFalse(ssl.getNeedClientAuth());
|
||||
assertFalse(ssl.getWantClientAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -155,11 +159,11 @@ public class SSLUtilsTest {
|
|||
RestServerConfig config = RestServerConfig.forPublic(null, configMap);
|
||||
SslContextFactory.Client ssl = SSLUtils.createClientSideSslContextFactory(config);
|
||||
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE, ssl.getKeyStoreType());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE, ssl.getTrustStoreType());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_PROTOCOL, ssl.getProtocol());
|
||||
Assert.assertArrayEquals(Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split("\\s*,\\s*")).toArray(), ssl.getIncludeProtocols());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_KEYMANGER_ALGORITHM, ssl.getKeyManagerFactoryAlgorithm());
|
||||
Assert.assertEquals(SslConfigs.DEFAULT_SSL_TRUSTMANAGER_ALGORITHM, ssl.getTrustManagerFactoryAlgorithm());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE, ssl.getKeyStoreType());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE, ssl.getTrustStoreType());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_PROTOCOL, ssl.getProtocol());
|
||||
assertArrayEquals(Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split("\\s*,\\s*")).toArray(), ssl.getIncludeProtocols());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_KEYMANGER_ALGORITHM, ssl.getKeyManagerFactoryAlgorithm());
|
||||
assertEquals(SslConfigs.DEFAULT_SSL_TRUSTMANAGER_ALGORITHM, ssl.getTrustManagerFactoryAlgorithm());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ import org.apache.kafka.common.config.ConfigDef;
|
|||
import org.apache.kafka.common.config.SslConfigs;
|
||||
import org.apache.kafka.common.config.types.Password;
|
||||
import org.apache.kafka.connect.runtime.WorkerConfig;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class StandaloneConfigTest {
|
||||
|
||||
|
|
|
@ -60,13 +60,14 @@ import org.apache.kafka.connect.storage.StatusBackingStore;
|
|||
import org.apache.kafka.connect.util.Callback;
|
||||
import org.apache.kafka.connect.util.ConnectorTaskId;
|
||||
import org.apache.kafka.connect.util.FutureCallback;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -87,11 +88,10 @@ import static java.util.Collections.singletonMap;
|
|||
import static org.apache.kafka.connect.runtime.TopicCreationConfig.DEFAULT_TOPIC_CREATION_PREFIX;
|
||||
import static org.apache.kafka.connect.runtime.TopicCreationConfig.PARTITIONS_CONFIG;
|
||||
import static org.apache.kafka.connect.runtime.TopicCreationConfig.REPLICATION_FACTOR_CONFIG;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
|
@ -110,7 +110,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class StandaloneHerderTest {
|
||||
private static final String CONNECTOR_NAME = "test";
|
||||
|
@ -139,19 +140,19 @@ public class StandaloneHerderTest {
|
|||
@Mock
|
||||
protected StatusBackingStore statusBackingStore;
|
||||
private final SampleConnectorClientConfigOverridePolicy
|
||||
noneConnectorClientConfigOverridePolicy = new SampleConnectorClientConfigOverridePolicy();
|
||||
noneConnectorClientConfigOverridePolicy = new SampleConnectorClientConfigOverridePolicy();
|
||||
|
||||
@Before
|
||||
public void setup() throws ExecutionException, InterruptedException {
|
||||
public void initialize(boolean mockTransform) {
|
||||
herder = mock(StandaloneHerder.class, withSettings()
|
||||
.useConstructor(worker, WORKER_ID, KAFKA_CLUSTER_ID, statusBackingStore, new MemoryConfigBackingStore(transformer), noneConnectorClientConfigOverridePolicy, new MockTime())
|
||||
.defaultAnswer(CALLS_REAL_METHODS));
|
||||
.useConstructor(worker, WORKER_ID, KAFKA_CLUSTER_ID, statusBackingStore, new MemoryConfigBackingStore(transformer), noneConnectorClientConfigOverridePolicy, new MockTime())
|
||||
.defaultAnswer(CALLS_REAL_METHODS));
|
||||
createCallback = new FutureCallback<>();
|
||||
final ArgumentCaptor<Map<String, String>> configCapture = ArgumentCaptor.forClass(Map.class);
|
||||
when(transformer.transform(eq(CONNECTOR_NAME), configCapture.capture())).thenAnswer(invocation -> configCapture.getValue());
|
||||
if (mockTransform)
|
||||
when(transformer.transform(eq(CONNECTOR_NAME), configCapture.capture())).thenAnswer(invocation -> configCapture.getValue());
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
verifyNoMoreInteractions(worker, statusBackingStore);
|
||||
herder.stop();
|
||||
|
@ -159,6 +160,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testCreateSourceConnector() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -171,6 +173,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testCreateConnectorFailedValidation() {
|
||||
initialize(false);
|
||||
// Basic validation should be performed and return an error, but should still evaluate the connector's config
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -201,6 +204,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testCreateConnectorAlreadyExists() throws Throwable {
|
||||
initialize(true);
|
||||
// First addition should succeed
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
|
@ -224,6 +228,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testCreateSinkConnector() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SINK);
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SINK);
|
||||
|
@ -236,6 +241,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testCreateConnectorWithStoppedInitialState() throws Exception {
|
||||
initialize(true);
|
||||
Map<String, String> config = connectorConfig(SourceSink.SINK);
|
||||
expectConfigValidation(SourceSink.SINK, config);
|
||||
|
||||
|
@ -248,14 +254,15 @@ public class StandaloneHerderTest {
|
|||
herder.putConnectorConfig(CONNECTOR_NAME, config, TargetState.STOPPED, false, createCallback);
|
||||
Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
assertEquals(
|
||||
new ConnectorInfo(CONNECTOR_NAME, connectorConfig(SourceSink.SINK), Collections.emptyList(), ConnectorType.SINK),
|
||||
connectorInfo.result()
|
||||
new ConnectorInfo(CONNECTOR_NAME, connectorConfig(SourceSink.SINK), Collections.emptyList(), ConnectorType.SINK),
|
||||
connectorInfo.result()
|
||||
);
|
||||
verify(loaderSwap).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyConnector() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -279,16 +286,17 @@ public class StandaloneHerderTest {
|
|||
FutureCallback<Herder.Created<ConnectorInfo>> failedDeleteCallback = new FutureCallback<>();
|
||||
herder.deleteConnectorConfig(CONNECTOR_NAME, failedDeleteCallback);
|
||||
ExecutionException e = assertThrows(
|
||||
"Should have thrown NotFoundException",
|
||||
ExecutionException.class,
|
||||
() -> failedDeleteCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS)
|
||||
ExecutionException.class,
|
||||
() -> failedDeleteCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS),
|
||||
"Should have thrown NotFoundException"
|
||||
);
|
||||
assertInstanceOf(NotFoundException.class, e.getCause());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorSameTaskConfigs() throws Exception {
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE, false);
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SOURCE);
|
||||
expectConfigValidation(SourceSink.SOURCE, config);
|
||||
|
@ -299,7 +307,7 @@ public class StandaloneHerderTest {
|
|||
when(worker.getPlugins()).thenReturn(plugins);
|
||||
// same task configs as earlier, so don't expect a new set of tasks to be brought up
|
||||
when(worker.connectorTaskConfigs(CONNECTOR_NAME, new SourceConnectorConfig(plugins, config, true)))
|
||||
.thenReturn(Collections.singletonList(taskConfig(SourceSink.SOURCE)));
|
||||
.thenReturn(Collections.singletonList(taskConfig(SourceSink.SOURCE)));
|
||||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, config, false, createCallback);
|
||||
Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
|
@ -313,6 +321,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorNewTaskConfigs() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -331,7 +340,7 @@ public class StandaloneHerderTest {
|
|||
Map<String, String> taskConfigs = taskConfig(SourceSink.SOURCE);
|
||||
taskConfigs.put("k", "v");
|
||||
when(worker.connectorTaskConfigs(CONNECTOR_NAME, new SourceConnectorConfig(plugins, config, true)))
|
||||
.thenReturn(Collections.singletonList(taskConfigs));
|
||||
.thenReturn(Collections.singletonList(taskConfigs));
|
||||
|
||||
when(worker.startSourceTask(eq(new ConnectorTaskId(CONNECTOR_NAME, 0)), any(), eq(connectorConfig(SourceSink.SOURCE)), eq(taskConfigs), eq(herder), eq(TargetState.STARTED))).thenReturn(true);
|
||||
|
||||
|
@ -344,6 +353,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorFailureOnStart() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
Map<String, String> config = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -360,16 +370,13 @@ public class StandaloneHerderTest {
|
|||
FutureCallback<Void> restartCallback = new FutureCallback<>();
|
||||
mockStartConnector(config, null, TargetState.STARTED, exception);
|
||||
herder.restartConnector(CONNECTOR_NAME, restartCallback);
|
||||
try {
|
||||
restartCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
fail();
|
||||
} catch (ExecutionException e) {
|
||||
assertEquals(exception, e.getCause());
|
||||
}
|
||||
ExecutionException e = assertThrows(ExecutionException.class, () -> restartCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
|
||||
assertEquals(exception, e.getCause());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartTask() throws Exception {
|
||||
initialize(true);
|
||||
ConnectorTaskId taskId = new ConnectorTaskId(CONNECTOR_NAME, 0);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
|
@ -380,20 +387,20 @@ public class StandaloneHerderTest {
|
|||
doNothing().when(worker).stopAndAwaitTask(taskId);
|
||||
|
||||
ClusterConfigState configState = new ClusterConfigState(
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(taskId, taskConfig(SourceSink.SOURCE)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(taskId, taskConfig(SourceSink.SOURCE)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
when(worker.startSourceTask(taskId, configState, connectorConfig, taskConfig(SourceSink.SOURCE), herder, TargetState.STARTED))
|
||||
.thenReturn(true);
|
||||
.thenReturn(true);
|
||||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, connectorConfig, false, createCallback);
|
||||
Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
|
@ -407,6 +414,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartTaskFailureOnStart() throws Exception {
|
||||
initialize(true);
|
||||
ConnectorTaskId taskId = new ConnectorTaskId(CONNECTOR_NAME, 0);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
|
@ -414,20 +422,20 @@ public class StandaloneHerderTest {
|
|||
expectConfigValidation(SourceSink.SOURCE, connectorConfig);
|
||||
|
||||
ClusterConfigState configState = new ClusterConfigState(
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(new ConnectorTaskId(CONNECTOR_NAME, 0), taskConfig(SourceSink.SOURCE)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(new ConnectorTaskId(CONNECTOR_NAME, 0), taskConfig(SourceSink.SOURCE)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
when(worker.startSourceTask(taskId, configState, connectorConfig, taskConfig(SourceSink.SOURCE), herder, TargetState.STARTED))
|
||||
.thenReturn(false);
|
||||
.thenReturn(false);
|
||||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, connectorConfig, false, createCallback);
|
||||
Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
|
@ -436,16 +444,13 @@ public class StandaloneHerderTest {
|
|||
FutureCallback<Void> cb = new FutureCallback<>();
|
||||
herder.restartTask(taskId, cb);
|
||||
verify(worker).stopAndAwaitTask(taskId);
|
||||
try {
|
||||
cb.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
fail("Expected restart callback to raise an exception");
|
||||
} catch (ExecutionException exception) {
|
||||
assertEquals(ConnectException.class, exception.getCause().getClass());
|
||||
}
|
||||
ExecutionException exception = assertThrows(ExecutionException.class, () -> cb.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
|
||||
assertEquals(ConnectException.class, exception.getCause().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksUnknownConnector() {
|
||||
initialize(false);
|
||||
FutureCallback<ConnectorStateInfo> restartCallback = new FutureCallback<>();
|
||||
RestartRequest restartRequest = new RestartRequest("UnknownConnector", false, true);
|
||||
herder.restartConnectorAndTasks(restartRequest, restartCallback);
|
||||
|
@ -455,6 +460,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksNoStatus() throws Exception {
|
||||
initialize(true);
|
||||
RestartRequest restartRequest = new RestartRequest(CONNECTOR_NAME, false, true);
|
||||
doReturn(Optional.empty()).when(herder).buildRestartPlan(restartRequest);
|
||||
|
||||
|
@ -476,6 +482,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksNoRestarts() throws Exception {
|
||||
initialize(true);
|
||||
RestartRequest restartRequest = new RestartRequest(CONNECTOR_NAME, false, true);
|
||||
RestartPlan restartPlan = mock(RestartPlan.class);
|
||||
ConnectorStateInfo connectorStateInfo = mock(ConnectorStateInfo.class);
|
||||
|
@ -500,6 +507,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksOnlyConnector() throws Exception {
|
||||
initialize(true);
|
||||
RestartRequest restartRequest = new RestartRequest(CONNECTOR_NAME, false, true);
|
||||
RestartPlan restartPlan = mock(RestartPlan.class);
|
||||
ConnectorStateInfo connectorStateInfo = mock(ConnectorStateInfo.class);
|
||||
|
@ -508,7 +516,7 @@ public class StandaloneHerderTest {
|
|||
when(restartPlan.restartConnectorStateInfo()).thenReturn(connectorStateInfo);
|
||||
doReturn(Optional.of(restartPlan)).when(herder).buildRestartPlan(restartRequest);
|
||||
|
||||
expectAdd(SourceSink.SINK);
|
||||
expectAdd(SourceSink.SINK, false);
|
||||
|
||||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SINK);
|
||||
expectConfigValidation(SourceSink.SINK, connectorConfig);
|
||||
|
@ -530,6 +538,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksOnlyTasks() throws Exception {
|
||||
initialize(true);
|
||||
ConnectorTaskId taskId = new ConnectorTaskId(CONNECTOR_NAME, 0);
|
||||
RestartRequest restartRequest = new RestartRequest(CONNECTOR_NAME, false, true);
|
||||
RestartPlan restartPlan = mock(RestartPlan.class);
|
||||
|
@ -550,20 +559,20 @@ public class StandaloneHerderTest {
|
|||
doNothing().when(worker).stopAndAwaitTasks(Collections.singletonList(taskId));
|
||||
|
||||
ClusterConfigState configState = new ClusterConfigState(
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(taskId, taskConfig(SourceSink.SINK)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(taskId, taskConfig(SourceSink.SINK)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
when(worker.startSinkTask(taskId, configState, connectorConfig, taskConfig(SourceSink.SINK), herder, TargetState.STARTED))
|
||||
.thenReturn(true);
|
||||
.thenReturn(true);
|
||||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, connectorConfig, false, createCallback);
|
||||
Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
|
@ -580,6 +589,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testRestartConnectorAndTasksBoth() throws Exception {
|
||||
initialize(true);
|
||||
ConnectorTaskId taskId = new ConnectorTaskId(CONNECTOR_NAME, 0);
|
||||
RestartRequest restartRequest = new RestartRequest(CONNECTOR_NAME, false, true);
|
||||
RestartPlan restartPlan = mock(RestartPlan.class);
|
||||
|
@ -594,7 +604,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
ArgumentCaptor<TaskStatus> taskStatus = ArgumentCaptor.forClass(TaskStatus.class);
|
||||
|
||||
expectAdd(SourceSink.SINK);
|
||||
expectAdd(SourceSink.SINK, false);
|
||||
|
||||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SINK);
|
||||
expectConfigValidation(SourceSink.SINK, connectorConfig);
|
||||
|
@ -605,20 +615,20 @@ public class StandaloneHerderTest {
|
|||
mockStartConnector(connectorConfig, null, TargetState.STARTED, null);
|
||||
|
||||
ClusterConfigState configState = new ClusterConfigState(
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(taskId, taskConfig(SourceSink.SINK)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(taskId, taskConfig(SourceSink.SINK)),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
when(worker.startSinkTask(taskId, configState, connectorConfig, taskConfig(SourceSink.SINK), herder, TargetState.STARTED))
|
||||
.thenReturn(true);
|
||||
.thenReturn(true);
|
||||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, connectorConfig, false, createCallback);
|
||||
Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
|
||||
|
@ -636,6 +646,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testCreateAndStop() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -657,6 +668,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testAccessors() throws Exception {
|
||||
initialize(true);
|
||||
Map<String, String> connConfig = connectorConfig(SourceSink.SOURCE);
|
||||
System.out.println(connConfig);
|
||||
|
||||
|
@ -680,14 +692,14 @@ public class StandaloneHerderTest {
|
|||
// Validate accessors with 1 connector
|
||||
doNothing().when(listConnectorsCb).onCompletion(null, singleton(CONNECTOR_NAME));
|
||||
ConnectorInfo connInfo = new ConnectorInfo(CONNECTOR_NAME, connConfig, singletonList(new ConnectorTaskId(CONNECTOR_NAME, 0)),
|
||||
ConnectorType.SOURCE);
|
||||
ConnectorType.SOURCE);
|
||||
doNothing().when(connectorInfoCb).onCompletion(null, connInfo);
|
||||
|
||||
TaskInfo taskInfo = new TaskInfo(new ConnectorTaskId(CONNECTOR_NAME, 0), taskConfig(SourceSink.SOURCE));
|
||||
doNothing().when(taskConfigsCb).onCompletion(null, singletonList(taskInfo));
|
||||
|
||||
Map<ConnectorTaskId, Map<String, String>> tasksConfig = Collections.singletonMap(new ConnectorTaskId(CONNECTOR_NAME, 0),
|
||||
taskConfig(SourceSink.SOURCE));
|
||||
taskConfig(SourceSink.SOURCE));
|
||||
doNothing().when(tasksConfigCb).onCompletion(null, tasksConfig);
|
||||
|
||||
// All operations are synchronous for StandaloneHerder, so we don't need to actually wait after making each call
|
||||
|
@ -713,6 +725,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testPutConnectorConfig() throws Exception {
|
||||
initialize(true);
|
||||
Map<String, String> connConfig = connectorConfig(SourceSink.SOURCE);
|
||||
Map<String, String> newConnConfig = new HashMap<>(connConfig);
|
||||
newConnConfig.put("foo", "bar");
|
||||
|
@ -720,7 +733,7 @@ public class StandaloneHerderTest {
|
|||
Callback<Map<String, String>> connectorConfigCb = mock(Callback.class);
|
||||
|
||||
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
expectAdd(SourceSink.SOURCE, false);
|
||||
expectConfigValidation(SourceSink.SOURCE, connConfig, newConnConfig);
|
||||
|
||||
// Should get first config
|
||||
|
@ -733,12 +746,12 @@ public class StandaloneHerderTest {
|
|||
onStart.getValue().onCompletion(null, TargetState.STARTED);
|
||||
return true;
|
||||
}).when(worker).startConnector(eq(CONNECTOR_NAME), capturedConfig.capture(), any(),
|
||||
eq(herder), eq(TargetState.STARTED), onStart.capture());
|
||||
eq(herder), eq(TargetState.STARTED), onStart.capture());
|
||||
ConnectorTaskId taskId = new ConnectorTaskId(CONNECTOR_NAME, 0);
|
||||
// Generate same task config, but from different connector config, resulting
|
||||
// in task restarts
|
||||
when(worker.connectorTaskConfigs(CONNECTOR_NAME, new SourceConnectorConfig(plugins, newConnConfig, true)))
|
||||
.thenReturn(singletonList(taskConfig(SourceSink.SOURCE)));
|
||||
.thenReturn(singletonList(taskConfig(SourceSink.SOURCE)));
|
||||
doNothing().when(worker).stopAndAwaitTasks(Collections.singletonList(taskId));
|
||||
doNothing().when(statusBackingStore).put(new TaskStatus(taskId, TaskStatus.State.DESTROYED, WORKER_ID, 0));
|
||||
when(worker.startSourceTask(eq(taskId), any(), eq(newConnConfig), eq(taskConfig(SourceSink.SOURCE)), eq(herder), eq(TargetState.STARTED))).thenReturn(true);
|
||||
|
@ -754,7 +767,7 @@ public class StandaloneHerderTest {
|
|||
herder.putConnectorConfig(CONNECTOR_NAME, newConnConfig, true, reconfigureCallback);
|
||||
Herder.Created<ConnectorInfo> newConnectorInfo = reconfigureCallback.get(1000L, TimeUnit.SECONDS);
|
||||
ConnectorInfo newConnInfo = new ConnectorInfo(CONNECTOR_NAME, newConnConfig, singletonList(new ConnectorTaskId(CONNECTOR_NAME, 0)),
|
||||
ConnectorType.SOURCE);
|
||||
ConnectorType.SOURCE);
|
||||
assertEquals(newConnInfo, newConnectorInfo.result());
|
||||
|
||||
assertEquals("bar", capturedConfig.getValue().get("foo"));
|
||||
|
@ -764,6 +777,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testPatchConnectorConfigNotFound() {
|
||||
initialize(false);
|
||||
Map<String, String> connConfigPatch = new HashMap<>();
|
||||
connConfigPatch.put("foo1", "baz1");
|
||||
|
||||
|
@ -777,6 +791,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testPatchConnectorConfig() throws ExecutionException, InterruptedException, TimeoutException {
|
||||
initialize(true);
|
||||
// Create the connector.
|
||||
Map<String, String> originalConnConfig = connectorConfig(SourceSink.SOURCE);
|
||||
originalConnConfig.put("foo0", "unaffected");
|
||||
|
@ -794,15 +809,15 @@ public class StandaloneHerderTest {
|
|||
patchedConnConfig.remove("foo2");
|
||||
patchedConnConfig.put("foo3", "added");
|
||||
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
expectAdd(SourceSink.SOURCE, false, false, false);
|
||||
expectConfigValidation(SourceSink.SOURCE, originalConnConfig, patchedConnConfig);
|
||||
|
||||
expectConnectorStartingWithoutTasks(originalConnConfig, SourceSink.SOURCE);
|
||||
expectConnectorStartingWithoutTasks(originalConnConfig, true);
|
||||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, originalConnConfig, false, createCallback);
|
||||
createCallback.get(1000L, TimeUnit.SECONDS);
|
||||
|
||||
expectConnectorStartingWithoutTasks(patchedConnConfig, SourceSink.SOURCE);
|
||||
expectConnectorStartingWithoutTasks(patchedConnConfig, false);
|
||||
|
||||
FutureCallback<Herder.Created<ConnectorInfo>> patchCallback = new FutureCallback<>();
|
||||
herder.patchConnectorConfig(CONNECTOR_NAME, connConfigPatch, patchCallback);
|
||||
|
@ -818,31 +833,33 @@ public class StandaloneHerderTest {
|
|||
assertEquals(patchedConnConfig, returnedConfig2);
|
||||
}
|
||||
|
||||
private void expectConnectorStartingWithoutTasks(Map<String, String> config, SourceSink sourceSink) {
|
||||
doNothing().when(worker).stopAndAwaitConnector(CONNECTOR_NAME);
|
||||
private void expectConnectorStartingWithoutTasks(Map<String, String> config, boolean mockStop) {
|
||||
if (mockStop) {
|
||||
doNothing().when(worker).stopAndAwaitConnector(CONNECTOR_NAME);
|
||||
}
|
||||
final ArgumentCaptor<Callback<TargetState>> onStart = ArgumentCaptor.forClass(Callback.class);
|
||||
doAnswer(invocation -> {
|
||||
onStart.getValue().onCompletion(null, TargetState.STARTED);
|
||||
return true;
|
||||
}).when(worker).startConnector(eq(CONNECTOR_NAME), any(Map.class), any(),
|
||||
eq(herder), eq(TargetState.STARTED), onStart.capture());
|
||||
ConnectorConfig connConfig = sourceSink == SourceSink.SOURCE ?
|
||||
new SourceConnectorConfig(plugins, config, true) :
|
||||
new SinkConnectorConfig(plugins, config);
|
||||
eq(herder), eq(TargetState.STARTED), onStart.capture());
|
||||
ConnectorConfig connConfig = new SourceConnectorConfig(plugins, config, true);
|
||||
when(worker.connectorTaskConfigs(CONNECTOR_NAME, connConfig))
|
||||
.thenReturn(emptyList());
|
||||
.thenReturn(emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutTaskConfigs() {
|
||||
initialize(false);
|
||||
Callback<Void> cb = mock(Callback.class);
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> herder.putTaskConfigs(CONNECTOR_NAME,
|
||||
singletonList(singletonMap("config", "value")), cb, null));
|
||||
singletonList(singletonMap("config", "value")), cb, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorruptConfig() {
|
||||
initialize(false);
|
||||
Map<String, String> config = new HashMap<>();
|
||||
config.put(ConnectorConfig.NAME_CONFIG, CONNECTOR_NAME);
|
||||
config.put(ConnectorConfig.CONNECTOR_CLASS_CONFIG, BogusSinkConnector.class.getName());
|
||||
|
@ -852,9 +869,9 @@ public class StandaloneHerderTest {
|
|||
List<String> errors = new ArrayList<>(singletonList(error));
|
||||
String key = "foo.invalid.key";
|
||||
when(connectorMock.validate(config)).thenReturn(
|
||||
new Config(
|
||||
singletonList(new ConfigValue(key, null, Collections.emptyList(), errors))
|
||||
)
|
||||
new Config(
|
||||
singletonList(new ConfigValue(key, null, Collections.emptyList(), errors))
|
||||
)
|
||||
);
|
||||
ConfigDef configDef = new ConfigDef();
|
||||
configDef.define(key, ConfigDef.Type.STRING, ConfigDef.Importance.HIGH, "");
|
||||
|
@ -869,24 +886,25 @@ public class StandaloneHerderTest {
|
|||
|
||||
herder.putConnectorConfig(CONNECTOR_NAME, config, true, createCallback);
|
||||
ExecutionException e = assertThrows(
|
||||
"Should have failed to configure connector",
|
||||
ExecutionException.class,
|
||||
() -> createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS)
|
||||
ExecutionException.class,
|
||||
() -> createCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS),
|
||||
"Should have failed to configure connector"
|
||||
);
|
||||
assertNotNull(e.getCause());
|
||||
Throwable cause = e.getCause();
|
||||
assertInstanceOf(BadRequestException.class, cause);
|
||||
assertEquals(
|
||||
cause.getMessage(),
|
||||
"Connector configuration is invalid and contains the following 1 error(s):\n" +
|
||||
error + "\n" +
|
||||
"You can also find the above list of errors at the endpoint `/connector-plugins/{connectorType}/config/validate`"
|
||||
cause.getMessage(),
|
||||
"Connector configuration is invalid and contains the following 1 error(s):\n" +
|
||||
error + "\n" +
|
||||
"You can also find the above list of errors at the endpoint `/connector-plugins/{connectorType}/config/validate`"
|
||||
);
|
||||
verify(loaderSwap).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetStates() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SOURCE);
|
||||
|
@ -922,10 +940,11 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testModifyConnectorOffsetsUnknownConnector() {
|
||||
initialize(false);
|
||||
FutureCallback<Message> alterOffsetsCallback = new FutureCallback<>();
|
||||
herder.alterConnectorOffsets("unknown-connector",
|
||||
Collections.singletonMap(Collections.singletonMap("partitionKey", "partitionValue"), Collections.singletonMap("offsetKey", "offsetValue")),
|
||||
alterOffsetsCallback);
|
||||
Collections.singletonMap(Collections.singletonMap("partitionKey", "partitionValue"), Collections.singletonMap("offsetKey", "offsetValue")),
|
||||
alterOffsetsCallback);
|
||||
ExecutionException e = assertThrows(ExecutionException.class, () -> alterOffsetsCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
|
||||
assertInstanceOf(NotFoundException.class, e.getCause());
|
||||
|
||||
|
@ -937,26 +956,27 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testModifyConnectorOffsetsConnectorNotInStoppedState() {
|
||||
initialize(false);
|
||||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SOURCE);
|
||||
|
||||
herder.configState = new ClusterConfigState(
|
||||
10,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 3),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig(SourceSink.SOURCE)),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.PAUSED),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet()
|
||||
10,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 3),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig(SourceSink.SOURCE)),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.PAUSED),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet()
|
||||
);
|
||||
|
||||
FutureCallback<Message> alterOffsetsCallback = new FutureCallback<>();
|
||||
herder.alterConnectorOffsets(CONNECTOR_NAME,
|
||||
Collections.singletonMap(Collections.singletonMap("partitionKey", "partitionValue"), Collections.singletonMap("offsetKey", "offsetValue")),
|
||||
alterOffsetsCallback);
|
||||
Collections.singletonMap(Collections.singletonMap("partitionKey", "partitionValue"), Collections.singletonMap("offsetKey", "offsetValue")),
|
||||
alterOffsetsCallback);
|
||||
ExecutionException e = assertThrows(ExecutionException.class, () -> alterOffsetsCallback.get(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
|
||||
assertInstanceOf(BadRequestException.class, e.getCause());
|
||||
|
||||
|
@ -968,6 +988,7 @@ public class StandaloneHerderTest {
|
|||
|
||||
@Test
|
||||
public void testAlterConnectorOffsets() throws Exception {
|
||||
initialize(false);
|
||||
ArgumentCaptor<Callback<Message>> workerCallbackCapture = ArgumentCaptor.forClass(Callback.class);
|
||||
Message msg = new Message("The offsets for this connector have been altered successfully");
|
||||
doAnswer(invocation -> {
|
||||
|
@ -978,27 +999,28 @@ public class StandaloneHerderTest {
|
|||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SOURCE);
|
||||
|
||||
herder.configState = new ClusterConfigState(
|
||||
10,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 0),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig(SourceSink.SOURCE)),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STOPPED),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet()
|
||||
10,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 0),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig(SourceSink.SOURCE)),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STOPPED),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet()
|
||||
);
|
||||
FutureCallback<Message> alterOffsetsCallback = new FutureCallback<>();
|
||||
herder.alterConnectorOffsets(CONNECTOR_NAME,
|
||||
Collections.singletonMap(Collections.singletonMap("partitionKey", "partitionValue"), Collections.singletonMap("offsetKey", "offsetValue")),
|
||||
alterOffsetsCallback);
|
||||
Collections.singletonMap(Collections.singletonMap("partitionKey", "partitionValue"), Collections.singletonMap("offsetKey", "offsetValue")),
|
||||
alterOffsetsCallback);
|
||||
assertEquals(msg, alterOffsetsCallback.get(1000, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetConnectorOffsets() throws Exception {
|
||||
initialize(false);
|
||||
ArgumentCaptor<Callback<Message>> workerCallbackCapture = ArgumentCaptor.forClass(Callback.class);
|
||||
Message msg = new Message("The offsets for this connector have been reset successfully");
|
||||
|
||||
|
@ -1010,25 +1032,26 @@ public class StandaloneHerderTest {
|
|||
Map<String, String> connectorConfig = connectorConfig(SourceSink.SOURCE);
|
||||
|
||||
herder.configState = new ClusterConfigState(
|
||||
10,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 0),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig(SourceSink.SOURCE)),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STOPPED),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet()
|
||||
10,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 0),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig(SourceSink.SOURCE)),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STOPPED),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet()
|
||||
);
|
||||
FutureCallback<Message> resetOffsetsCallback = new FutureCallback<>();
|
||||
herder.resetConnectorOffsets(CONNECTOR_NAME, resetOffsetsCallback);
|
||||
assertEquals(msg, resetOffsetsCallback.get(1000, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Test()
|
||||
@Test
|
||||
public void testRequestTaskReconfigurationDoesNotDeadlock() throws Exception {
|
||||
initialize(true);
|
||||
expectAdd(SourceSink.SOURCE);
|
||||
|
||||
// Start the connector
|
||||
|
@ -1056,9 +1079,9 @@ public class StandaloneHerderTest {
|
|||
Map<String, String> updatedTaskConfig2 = taskConfig(SourceSink.SOURCE);
|
||||
updatedTaskConfig2.put("dummy-task-property", "2");
|
||||
when(worker.connectorTaskConfigs(eq(CONNECTOR_NAME), any()))
|
||||
.thenReturn(
|
||||
Collections.singletonList(updatedTaskConfig1),
|
||||
Collections.singletonList(updatedTaskConfig2));
|
||||
.thenReturn(
|
||||
Collections.singletonList(updatedTaskConfig1),
|
||||
Collections.singletonList(updatedTaskConfig2));
|
||||
|
||||
// Set new config on the connector and tasks
|
||||
FutureCallback<Herder.Created<ConnectorInfo>> reconfigureCallback = new FutureCallback<>();
|
||||
|
@ -1076,12 +1099,25 @@ public class StandaloneHerderTest {
|
|||
}
|
||||
|
||||
private void expectAdd(SourceSink sourceSink) {
|
||||
expectAdd(sourceSink, true);
|
||||
}
|
||||
private void expectAdd(SourceSink sourceSink, boolean mockStartConnector) {
|
||||
expectAdd(sourceSink, mockStartConnector, true, true);
|
||||
}
|
||||
|
||||
private void expectAdd(SourceSink sourceSink,
|
||||
boolean mockStartConnector,
|
||||
boolean mockConnectorTaskConfigs,
|
||||
boolean mockStartSourceTask) {
|
||||
Map<String, String> connectorProps = connectorConfig(sourceSink);
|
||||
ConnectorConfig connConfig = sourceSink == SourceSink.SOURCE ?
|
||||
new SourceConnectorConfig(plugins, connectorProps, true) :
|
||||
new SinkConnectorConfig(plugins, connectorProps);
|
||||
new SourceConnectorConfig(plugins, connectorProps, true) :
|
||||
new SinkConnectorConfig(plugins, connectorProps);
|
||||
|
||||
if (mockStartConnector) {
|
||||
mockStartConnector(connectorProps, TargetState.STARTED, TargetState.STARTED, null);
|
||||
}
|
||||
|
||||
mockStartConnector(connectorProps, TargetState.STARTED, TargetState.STARTED, null);
|
||||
when(worker.isRunning(CONNECTOR_NAME)).thenReturn(true);
|
||||
if (sourceSink == SourceSink.SOURCE) {
|
||||
when(worker.isTopicCreationEnabled()).thenReturn(true);
|
||||
|
@ -1092,25 +1128,29 @@ public class StandaloneHerderTest {
|
|||
Map<String, String> connectorConfig = connectorConfig(sourceSink);
|
||||
Map<String, String> generatedTaskProps = taskConfig(sourceSink);
|
||||
|
||||
when(worker.connectorTaskConfigs(CONNECTOR_NAME, connConfig))
|
||||
.thenReturn(singletonList(generatedTaskProps));
|
||||
if (mockConnectorTaskConfigs) {
|
||||
when(worker.connectorTaskConfigs(CONNECTOR_NAME, connConfig)).thenReturn(singletonList(generatedTaskProps));
|
||||
}
|
||||
|
||||
ClusterConfigState configState = new ClusterConfigState(
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(new ConnectorTaskId(CONNECTOR_NAME, 0), generatedTaskProps),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
if (sourceSink.equals(SourceSink.SOURCE)) {
|
||||
-1,
|
||||
null,
|
||||
Collections.singletonMap(CONNECTOR_NAME, 1),
|
||||
Collections.singletonMap(CONNECTOR_NAME, connectorConfig),
|
||||
Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED),
|
||||
Collections.singletonMap(new ConnectorTaskId(CONNECTOR_NAME, 0), generatedTaskProps),
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
Collections.singletonMap(CONNECTOR_NAME, new AppliedConnectorConfig(connectorConfig)),
|
||||
new HashSet<>(),
|
||||
new HashSet<>(),
|
||||
transformer);
|
||||
|
||||
if (sourceSink.equals(SourceSink.SOURCE) && mockStartSourceTask) {
|
||||
when(worker.startSourceTask(new ConnectorTaskId(CONNECTOR_NAME, 0), configState, connectorConfig(sourceSink), generatedTaskProps, herder, TargetState.STARTED)).thenReturn(true);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (sourceSink.equals(SourceSink.SINK)) {
|
||||
when(worker.startSinkTask(new ConnectorTaskId(CONNECTOR_NAME, 0), configState, connectorConfig(sourceSink), generatedTaskProps, herder, TargetState.STARTED)).thenReturn(true);
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1166,7 @@ public class StandaloneHerderTest {
|
|||
});
|
||||
|
||||
when(worker.isSinkConnector(CONNECTOR_NAME))
|
||||
.thenReturn(sourceSink == SourceSink.SINK);
|
||||
.thenReturn(sourceSink == SourceSink.SINK);
|
||||
}
|
||||
|
||||
private void expectTargetState(String connector, TargetState state) {
|
||||
|
@ -1140,8 +1180,8 @@ public class StandaloneHerderTest {
|
|||
|
||||
private ConnectorInfo createdInfo(SourceSink sourceSink) {
|
||||
return new ConnectorInfo(CONNECTOR_NAME, connectorConfig(sourceSink),
|
||||
singletonList(new ConnectorTaskId(CONNECTOR_NAME, 0)),
|
||||
SourceSink.SOURCE == sourceSink ? ConnectorType.SOURCE : ConnectorType.SINK);
|
||||
singletonList(new ConnectorTaskId(CONNECTOR_NAME, 0)),
|
||||
SourceSink.SOURCE == sourceSink ? ConnectorType.SOURCE : ConnectorType.SINK);
|
||||
}
|
||||
|
||||
private void expectStop() {
|
||||
|
@ -1181,8 +1221,8 @@ public class StandaloneHerderTest {
|
|||
}
|
||||
|
||||
private void expectConfigValidation(
|
||||
SourceSink sourceSink,
|
||||
Map<String, String>... configs
|
||||
SourceSink sourceSink,
|
||||
Map<String, String>... configs
|
||||
) {
|
||||
// config validation
|
||||
Connector connectorMock = sourceSink == SourceSink.SOURCE ? mock(SourceConnector.class) : mock(SinkConnector.class);
|
||||
|
|
Loading…
Reference in New Issue