Kangs-Claw commented on code in PR #10046:
URL: https://github.com/apache/gravitino/pull/10046#discussion_r2876383403
##########
integration-test-common/src/test/java/org/apache/gravitino/integration/test/container/DorisContainer.java:
##########
@@ -63,78 +84,136 @@ protected DorisContainer(
Map<String, String> envVars,
Optional<Network> network) {
super(image, hostName, ports, extraHosts, filesToMount, envVars, network);
- }
- @Override
- protected void setupContainer() {
- super.setupContainer();
- withLogConsumer(new PrintingContainerLog(format("%-14s| ",
"DorisContainer")));
- withStartupTimeout(Duration.ofMinutes(5));
+ String dir = System.getenv("GRAVITINO_ROOT_DIR");
+ if (dir == null || dir.isEmpty()) {
+ throw new RuntimeException("GRAVITINO_ROOT_DIR is not set");
+ }
+ String composeFile =
+ ITUtils.joinPath(
+ dir, "integration-test-common", "doris-docker-script",
"docker-compose.yaml");
+
+ String effectiveImage =
+ (DEFAULT_IMAGE != null && !DEFAULT_IMAGE.isEmpty()) ? DEFAULT_IMAGE :
image;
+ Preconditions.checkArgument(
+ effectiveImage != null && !effectiveImage.isEmpty(),
+ "Doris Docker image must be configured via
GRAVITINO_CI_DORIS_DOCKER_IMAGE or "
+ + "DorisContainer builder image");
+
+ composeContainer =
+ new ComposeContainer(new File(composeFile))
+ .withEnv("GRAVITINO_CI_DORIS_DOCKER_IMAGE", effectiveImage)
+ .withExposedService(
+ FE_SERVICE,
+ FE_MYSQL_PORT,
+
Wait.forListeningPort().withStartupTimeout(Duration.ofMinutes(3)))
+ .withExposedService(FE_SERVICE, FE_HTTP_PORT)
+ .withScaledService(BE_SERVICE, BE_SCALE)
+ .withStartupTimeout(Duration.ofMinutes(5))
+ .withTailChildContainers(true)
+ .withLocalCompose(true);
+
+ // Expose ports for each BE instance (1-indexed)
+ for (int i = 1; i <= BE_SCALE; i++) {
+ composeContainer
+ .withExposedService(
+ BE_SERVICE,
+ i,
+ BE_HEARTBEAT_PORT,
+
Wait.forListeningPort().withStartupTimeout(Duration.ofMinutes(3)))
+ .withExposedService(BE_SERVICE, i, BE_WEBSERVER_PORT);
+ }
}
@Override
public void start() {
- super.start();
+ composeContainer.start();
+ resolveFeIpAddress();
Preconditions.check("Doris container startup failed!",
checkContainerStatus(5));
Preconditions.check("Doris container password change failed!",
changePassword());
}
@Override
public void close() {
copyDorisLog();
- super.close();
+ if (composeContainer != null) {
+ composeContainer.stop();
+ }
}
private void copyDorisLog() {
try {
- // stop Doris container
String destPath = System.getenv("IT_PROJECT_DIR");
- LOG.info("Copy doris log file to {}", destPath);
-
- String feTarPath = "/doris-be.tar";
- String beTarPath = "/doris-fe.tar";
-
- // Pack the jar files
- container.execInContainer("tar", "cf", feTarPath, DORIS_BE_PATH);
- container.execInContainer("tar", "cf", beTarPath, DORIS_FE_PATH);
-
- container.copyFileFromContainer(feTarPath, destPath + File.separator +
"doris-be.tar");
- container.copyFileFromContainer(beTarPath, destPath + File.separator +
"doris-fe.tar");
+ if (destPath == null || destPath.isEmpty()) {
+ LOG.warn("IT_PROJECT_DIR is not set, skipping Doris log copy");
+ return;
+ }
+ LOG.info("Copy doris log files to {}", destPath);
+ copyContainerLog(FE_SERVICE, DORIS_FE_PATH, destPath, "doris-fe");
+ for (int i = 1; i <= BE_SCALE; i++) {
+ copyContainerLog(BE_SERVICE + "-" + i, DORIS_BE_PATH, destPath,
"doris-be-" + i);
+ }
} catch (Exception e) {
- LOG.error("Failed to copy container log to local", e);
+ LOG.error("Failed to copy Doris container logs to local", e);
+ }
+ }
+
+ private void copyContainerLog(String serviceName, String logPath, String
destPath, String tarName)
+ throws Exception {
+ Optional<ContainerState> container =
composeContainer.getContainerByServiceName(serviceName);
+ if (container.isPresent()) {
+ String tarPath = "/" + tarName + ".tar";
+ container.get().execInContainer("tar", "cf", tarPath, logPath);
+ container.get().copyFileFromContainer(tarPath, destPath + File.separator
+ tarName + ".tar");
+ } else {
+ LOG.warn("Doris {} container not found, skipping log copy", serviceName);
}
}
+ @Override
+ public String getContainerIpAddress() {
+ return feIpAddress;
+ }
+
@Override
protected boolean checkContainerStatus(int retryLimit) {
- String dorisJdbcUrl = format("jdbc:mysql://%s:%d/",
getContainerIpAddress(), FE_MYSQL_PORT);
- LOG.info("Doris url is " + dorisJdbcUrl);
+ String dorisJdbcUrl = format("jdbc:mysql://%s:%d/", feIpAddress,
FE_MYSQL_PORT);
+ LOG.info("Doris JDBC url is {}", dorisJdbcUrl);
await()
- .atMost(30, TimeUnit.SECONDS)
- .pollInterval(30 / retryLimit, TimeUnit.SECONDS)
+ .atMost(120, TimeUnit.SECONDS)
+ .pollInterval(120 / retryLimit, TimeUnit.SECONDS)
.until(
() -> {
try (Connection connection =
DriverManager.getConnection(dorisJdbcUrl, USER_NAME, "");
Statement statement = connection.createStatement()) {
- // execute `SHOW PROC '/backends';` to check if backends is
ready
+ // execute `SHOW PROC '/backends';` to check if all backends
are ready
String query = "SHOW PROC '/backends';";
+ int aliveCount = 0;
try (ResultSet resultSet = statement.executeQuery(query)) {
while (resultSet.next()) {
String alive = resultSet.getString("Alive");
String totalCapacity =
resultSet.getString("TotalCapacity");
float totalCapacityFloat =
Float.parseFloat(totalCapacity.split(" ")[0]);
- // alive should be true and totalCapacity should not be
0.000
if (alive.equalsIgnoreCase("true") && totalCapacityFloat >
0.0f) {
- LOG.info("Doris container startup success!");
- return true;
+ aliveCount++;
}
}
}
- LOG.info("Doris container is not ready yet!");
+
+ if (aliveCount >= BE_SCALE) {
Review Comment:
Good question! In theory, `aliveCount` should not exceed `BE_SCALE` since we
only start 3 BE containers via `withScaledService(BE_SERVICE, BE_SCALE)`.
However, using `>=` instead of `==` is more robust because:
1. It handles edge cases where extra backends might be present from previous
test runs
2. It's more defensive programming - if somehow more backends appear, the
check still passes
3. It aligns with the intent: "we need at least BE_SCALE backends alive"
So while it's unlikely to happen in normal circumstances, the `>=` check is
safer and more correct.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]