use of org.apache.kafka.common.utils.MockTime in project kafka by apache.
the class KafkaAdminClientTest method testClientSideTimeoutAfterFailureToReceiveResponse.
/**
* Test that if the client can send to a node, but doesn't receive a response, it will
* disconnect and try a different node.
*/
@Test
public void testClientSideTimeoutAfterFailureToReceiveResponse() throws Exception {
Cluster cluster = mockCluster(3, 0);
CompletableFuture<String> disconnectFuture = new CompletableFuture<>();
MockTime time = new MockTime();
try (final AdminClientUnitTestEnv env = new AdminClientUnitTestEnv(time, cluster, newStrMap(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, "1", AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, "100000", AdminClientConfig.RETRY_BACKOFF_MS_CONFIG, "0"))) {
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
env.kafkaClient().setDisconnectFuture(disconnectFuture);
final ListTopicsResult result = env.adminClient().listTopics();
TestUtils.waitForCondition(() -> {
time.sleep(1);
return disconnectFuture.isDone();
}, 5000, 1, () -> "Timed out waiting for expected disconnect");
assertFalse(disconnectFuture.isCompletedExceptionally());
assertFalse(result.future.isDone());
TestUtils.waitForCondition(env.kafkaClient()::hasInFlightRequests, "Timed out waiting for retry");
env.kafkaClient().respond(prepareMetadataResponse(cluster, Errors.NONE));
assertEquals(0, result.listings().get().size());
}
}
use of org.apache.kafka.common.utils.MockTime in project kafka by apache.
the class KafkaAdminClientTest method testRemoveMembersFromGroupRetryBackoff.
@Test
public void testRemoveMembersFromGroupRetryBackoff() throws Exception {
MockTime time = new MockTime();
int retryBackoff = 100;
try (final AdminClientUnitTestEnv env = new AdminClientUnitTestEnv(time, mockCluster(3, 0), newStrMap(AdminClientConfig.RETRY_BACKOFF_MS_CONFIG, "" + retryBackoff))) {
MockClient mockClient = env.kafkaClient();
mockClient.setNodeApiVersions(NodeApiVersions.create());
AtomicLong firstAttemptTime = new AtomicLong(0);
AtomicLong secondAttemptTime = new AtomicLong(0);
mockClient.prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(body -> {
firstAttemptTime.set(time.milliseconds());
return true;
}, new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NOT_COORDINATOR.code())));
mockClient.prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
MemberResponse responseOne = new MemberResponse().setGroupInstanceId("instance-1").setErrorCode(Errors.NONE.code());
env.kafkaClient().prepareResponse(body -> {
secondAttemptTime.set(time.milliseconds());
return true;
}, new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NONE.code()).setMembers(Collections.singletonList(responseOne))));
Collection<MemberToRemove> membersToRemove = singletonList(new MemberToRemove("instance-1"));
final KafkaFuture<Void> future = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions(membersToRemove)).all();
TestUtils.waitForCondition(() -> mockClient.numAwaitingResponses() == 1, "Failed awaiting RemoveMembersFromGroup first request failure");
TestUtils.waitForCondition(() -> ((KafkaAdminClient) env.adminClient()).numPendingCalls() == 1, "Failed to add retry RemoveMembersFromGroup call on first failure");
time.sleep(retryBackoff);
future.get();
long actualRetryBackoff = secondAttemptTime.get() - firstAttemptTime.get();
assertEquals(retryBackoff, actualRetryBackoff, "RemoveMembersFromGroup retry did not await expected backoff!");
}
}
use of org.apache.kafka.common.utils.MockTime in project kafka by apache.
the class KafkaAdminClientTest method testCreatePartitionsRetryThrottlingExceptionWhenEnabledUntilRequestTimeOut.
@Test
public void testCreatePartitionsRetryThrottlingExceptionWhenEnabledUntilRequestTimeOut() throws Exception {
long defaultApiTimeout = 60000;
MockTime time = new MockTime();
try (AdminClientUnitTestEnv env = mockClientEnv(time, AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, String.valueOf(defaultApiTimeout))) {
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
env.kafkaClient().prepareResponse(expectCreatePartitionsRequestWithTopics("topic1", "topic2", "topic3"), prepareCreatePartitionsResponse(1000, createPartitionsTopicResult("topic1", Errors.NONE), createPartitionsTopicResult("topic2", Errors.THROTTLING_QUOTA_EXCEEDED), createPartitionsTopicResult("topic3", Errors.TOPIC_ALREADY_EXISTS)));
env.kafkaClient().prepareResponse(expectCreatePartitionsRequestWithTopics("topic2"), prepareCreatePartitionsResponse(1000, createPartitionsTopicResult("topic2", Errors.THROTTLING_QUOTA_EXCEEDED)));
Map<String, NewPartitions> counts = new HashMap<>();
counts.put("topic1", NewPartitions.increaseTo(1));
counts.put("topic2", NewPartitions.increaseTo(2));
counts.put("topic3", NewPartitions.increaseTo(3));
CreatePartitionsResult result = env.adminClient().createPartitions(counts, new CreatePartitionsOptions().retryOnQuotaViolation(true));
// Wait until the prepared attempts have consumed
TestUtils.waitForCondition(() -> env.kafkaClient().numAwaitingResponses() == 0, "Failed awaiting CreatePartitions requests");
// Wait until the next request is sent out
TestUtils.waitForCondition(() -> env.kafkaClient().inFlightRequestCount() == 1, "Failed awaiting next CreatePartitions request");
// Advance time past the default api timeout to time out the inflight request
time.sleep(defaultApiTimeout + 1);
assertNull(result.values().get("topic1").get());
ThrottlingQuotaExceededException e = TestUtils.assertFutureThrows(result.values().get("topic2"), ThrottlingQuotaExceededException.class);
assertEquals(0, e.throttleTimeMs());
TestUtils.assertFutureThrows(result.values().get("topic3"), TopicExistsException.class);
}
}
use of org.apache.kafka.common.utils.MockTime in project kafka by apache.
the class KafkaAdminClientTest method testRequestTimeoutExceedingDefaultApiTimeout.
@Test
public void testRequestTimeoutExceedingDefaultApiTimeout() throws Exception {
HashMap<Integer, Node> nodes = new HashMap<>();
MockTime time = new MockTime();
Node node0 = new Node(0, "localhost", 8121);
nodes.put(0, node0);
Cluster cluster = new Cluster("mockClusterId", nodes.values(), Arrays.asList(new PartitionInfo("foo", 0, node0, new Node[] { node0 }, new Node[] { node0 })), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), nodes.get(0));
// This test assumes the default api timeout value of 60000. When the request timeout
// is set to something larger, we should adjust the api timeout accordingly for compatibility.
final int retryBackoffMs = 100;
final int requestTimeoutMs = 120000;
try (AdminClientUnitTestEnv env = new AdminClientUnitTestEnv(time, cluster, AdminClientConfig.RETRY_BACKOFF_MS_CONFIG, String.valueOf(retryBackoffMs), AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, String.valueOf(requestTimeoutMs))) {
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
ListTopicsOptions options = new ListTopicsOptions();
final ListTopicsResult result = env.adminClient().listTopics(options);
// Wait until the first attempt has been sent, then advance the time by the default api timeout
TestUtils.waitForCondition(() -> env.kafkaClient().hasInFlightRequests(), "Timed out waiting for Metadata request to be sent");
time.sleep(60001);
// The in-flight request should not be cancelled
assertTrue(env.kafkaClient().hasInFlightRequests());
// Now sleep the remaining time for the request timeout to expire
time.sleep(60000);
TestUtils.assertFutureThrows(result.future, TimeoutException.class);
}
}
use of org.apache.kafka.common.utils.MockTime in project kafka by apache.
the class KafkaAdminClientTest method testClientSideTimeoutAfterFailureToSend.
/**
* Test that if the client can obtain a node assignment, but can't send to the given
* node, it will disconnect and try a different node.
*/
@Test
public void testClientSideTimeoutAfterFailureToSend() throws Exception {
Cluster cluster = mockCluster(3, 0);
CompletableFuture<String> disconnectFuture = new CompletableFuture<>();
MockTime time = new MockTime();
try (final AdminClientUnitTestEnv env = new AdminClientUnitTestEnv(time, cluster, newStrMap(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, "1", AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, "100000", AdminClientConfig.RETRY_BACKOFF_MS_CONFIG, "1"))) {
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
for (Node node : cluster.nodes()) {
env.kafkaClient().delayReady(node, 100);
}
// We use a countdown latch to ensure that we get to the first
// call to `ready` before we increment the time below to trigger
// the disconnect.
CountDownLatch readyLatch = new CountDownLatch(2);
env.kafkaClient().setDisconnectFuture(disconnectFuture);
env.kafkaClient().setReadyCallback(node -> readyLatch.countDown());
env.kafkaClient().prepareResponse(prepareMetadataResponse(cluster, Errors.NONE));
final ListTopicsResult result = env.adminClient().listTopics();
readyLatch.await(TestUtils.DEFAULT_MAX_WAIT_MS, TimeUnit.MILLISECONDS);
log.debug("Advancing clock by 25 ms to trigger client-side disconnect.");
time.sleep(25);
disconnectFuture.get();
log.debug("Enabling nodes to send requests again.");
for (Node node : cluster.nodes()) {
env.kafkaClient().delayReady(node, 0);
}
time.sleep(5);
log.info("Waiting for result.");
assertEquals(0, result.listings().get().size());
}
}
Aggregations