mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-15 19:56:39 +00:00
feat: Add standalone Java SeekToBeginning test to reproduce the issue
Created: - SeekToBeginningTest.java: Standalone Java test that reproduces the seekToBeginning() hang - Dockerfile.seektest: Docker setup for running the test - pom.xml: Maven build configuration - Updated docker-compose.yml to include seek-test service This test simulates what Schema Registry does: 1. Create KafkaConsumer connected to gateway 2. Assign to _schemas topic partition 0 3. Call seekToBeginning() 4. Poll for records Expected behavior: Should send ListOffsets and then Fetch Actual behavior: Blocks indefinitely after seekToBeginning()
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
FROM openjdk:11-jdk-slim
|
||||
|
||||
# Install Maven
|
||||
RUN apt-get update && apt-get install -y maven && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Create source directory
|
||||
RUN mkdir -p src/main/java
|
||||
|
||||
# Copy source and build files
|
||||
COPY SeekToBeginningTest.java src/main/java/
|
||||
COPY pom.xml .
|
||||
|
||||
# Compile and package
|
||||
RUN mvn clean package -DskipTests
|
||||
|
||||
# Run the test
|
||||
ENTRYPOINT ["java", "-cp", "target/seek-test.jar", "SeekToBeginningTest"]
|
||||
CMD ["kafka-gateway:9093"]
|
||||
@@ -0,0 +1,73 @@
|
||||
import org.apache.kafka.clients.consumer.*;
|
||||
import org.apache.kafka.common.TopicPartition;
|
||||
import org.apache.kafka.common.serialization.ByteArrayDeserializer;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Test program to reproduce the seekToBeginning() hang issue
|
||||
*
|
||||
* This simulates what Schema Registry does:
|
||||
* 1. Create KafkaConsumer
|
||||
* 2. Assign to partition
|
||||
* 3. Call seekToBeginning()
|
||||
* 4. Poll for records
|
||||
*
|
||||
* Expected behavior: Consumer should send ListOffsets and then Fetch requests
|
||||
* Observed behavior: Consumer sends InitProducerId but not ListOffsets, then
|
||||
* hangs
|
||||
*/
|
||||
public class SeekToBeginningTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String bootstrapServers = "localhost:9093";
|
||||
String topicName = "_schemas";
|
||||
|
||||
if (args.length > 0) {
|
||||
bootstrapServers = args[0];
|
||||
}
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
|
||||
props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-seek-group");
|
||||
props.put(ConsumerConfig.CLIENT_ID_CONFIG, "test-seek-client");
|
||||
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
|
||||
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class);
|
||||
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class);
|
||||
props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "45000");
|
||||
props.put(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, "60000");
|
||||
|
||||
System.out.println("[TEST] Creating KafkaConsumer connecting to " + bootstrapServers);
|
||||
KafkaConsumer<byte[], byte[]> consumer = new KafkaConsumer<>(props);
|
||||
|
||||
TopicPartition tp = new TopicPartition(topicName, 0);
|
||||
List<TopicPartition> partitions = Arrays.asList(tp);
|
||||
|
||||
System.out.println("[TEST] Assigning to partition: " + tp);
|
||||
consumer.assign(partitions);
|
||||
|
||||
System.out.println("[TEST] Calling seekToBeginning()...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
consumer.seekToBeginning(partitions);
|
||||
long seekTime = System.currentTimeMillis() - startTime;
|
||||
System.out.println("[TEST] seekToBeginning() completed in " + seekTime + "ms");
|
||||
|
||||
System.out.println("[TEST] Starting poll loop (30 second timeout per poll)...");
|
||||
for (int i = 0; i < 3; i++) {
|
||||
System.out.println("[POLL " + (i + 1) + "] Polling for records...");
|
||||
long pollStart = System.currentTimeMillis();
|
||||
ConsumerRecords<byte[], byte[]> records = consumer.poll(java.time.Duration.ofSeconds(30));
|
||||
long pollTime = System.currentTimeMillis() - pollStart;
|
||||
System.out.println("[POLL " + (i + 1) + "] Got " + records.count() + " records in " + pollTime + "ms");
|
||||
|
||||
for (ConsumerRecord<byte[], byte[]> record : records) {
|
||||
System.out.println(" [RECORD] offset=" + record.offset() + ", key.len=" +
|
||||
(record.key() != null ? record.key().length : 0) +
|
||||
", value.len=" + (record.value() != null ? record.value().length : 0));
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("[TEST] Closing consumer...");
|
||||
consumer.close();
|
||||
System.out.println("[TEST] Done!");
|
||||
}
|
||||
}
|
||||
@@ -307,6 +307,24 @@ services:
|
||||
profiles:
|
||||
- debug
|
||||
|
||||
# SeekToBeginning test - reproduces the hang issue
|
||||
seek-test:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.seektest
|
||||
container_name: loadtest-seek-test
|
||||
depends_on:
|
||||
kafka-gateway:
|
||||
condition: service_healthy
|
||||
schema-registry:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- KAFKA_BOOTSTRAP_SERVERS=kafka-gateway:9093
|
||||
networks:
|
||||
- kafka-loadtest-net
|
||||
entrypoint: ["java", "-cp", "target/seek-test.jar", "SeekToBeginningTest"]
|
||||
command: ["kafka-gateway:9093"]
|
||||
|
||||
volumes:
|
||||
prometheus-data:
|
||||
grafana-data:
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>io.confluent.test</groupId>
|
||||
<artifactId>seek-test</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<kafka.version>3.6.0</kafka.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-clients</artifactId>
|
||||
<version>${kafka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>SeekToBeginningTest</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<finalName>seek-test</finalName>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
Reference in New Issue
Block a user