diff --git a/.github/actions/upload-coverage/action.yml b/.github/actions/upload-coverage/action.yml
index 2678aaf18fe98..faa4d510350d2 100644
--- a/.github/actions/upload-coverage/action.yml
+++ b/.github/actions/upload-coverage/action.yml
@@ -19,7 +19,8 @@
name: Upload to Codecov with retries
description: |
- Uploads to codecov with multiple retries as a workaround
+ Checks that the current repository is public and then
+ uploads to codecov with multiple retries as a workaround
for these issues
- https://github.com/codecov/codecov-action/issues/598
- https://github.com/codecov/codecov-action/issues/837
@@ -30,8 +31,26 @@ inputs:
runs:
using: composite
steps:
+ - name: "Check that repository is public"
+ id: repo-check
+ shell: bash
+ run: |
+ if [[ "${{ github.server_url }}" != "https://github.com" ]]; then
+ echo "Not using github.com server ('${{ github.server_url }}'). Skipping uploading of coverage metrics."
+ echo "passed=false" >> $GITHUB_OUTPUT
+ exit 0
+ fi
+ REPO_URL="${{ github.server_url }}/${{ github.repository }}"
+ {
+ # public repository url will respond to http HEAD request
+ curl -X HEAD -fs "$REPO_URL" && echo "passed=true" >> $GITHUB_OUTPUT
+ } || {
+ echo "$REPO_URL isn't a public repository. Skipping uploading of coverage metrics."
+ echo "passed=false" >> $GITHUB_OUTPUT
+ }
- name: "Upload to Codecov (attempt #1)"
id: codecov-upload-1
+ if: steps.repo-check.outputs.passed == 'true'
uses: codecov/codecov-action@v3
continue-on-error: true
with:
diff --git a/.github/workflows/pulsar-ci-flaky.yaml b/.github/workflows/pulsar-ci-flaky.yaml
index 6b4da95173ce9..1b17e3ecbc6f2 100644
--- a/.github/workflows/pulsar-ci-flaky.yaml
+++ b/.github/workflows/pulsar-ci-flaky.yaml
@@ -128,7 +128,6 @@ jobs:
uses: ./.github/actions/copy-test-reports
- name: Upload to Codecov
- if: ${{ github.repository == 'apache/pulsar' }}
uses: ./.github/actions/upload-coverage
with:
flags: unittests
diff --git a/.github/workflows/pulsar-ci.yaml b/.github/workflows/pulsar-ci.yaml
index 8e08c65d9a191..abb015ed15c8b 100644
--- a/.github/workflows/pulsar-ci.yaml
+++ b/.github/workflows/pulsar-ci.yaml
@@ -247,7 +247,6 @@ jobs:
uses: ./.github/actions/copy-test-reports
- name: Upload to Codecov
- if: ${{ github.repository == 'apache/pulsar' }}
uses: ./.github/actions/upload-coverage
with:
flags: unittests
@@ -377,6 +376,7 @@ jobs:
include:
- name: Backwards Compatibility
group: BACKWARDS_COMPAT
+ no_coverage: true
- name: Cli
group: CLI
@@ -388,15 +388,18 @@ jobs:
group: SHADE_RUN
runtime_jdk: 8
setup: ./build/run_integration_group.sh SHADE_BUILD
+ no_coverage: true
- name: Shade on Java 11
group: SHADE_RUN
runtime_jdk: 11
setup: ./build/run_integration_group.sh SHADE_BUILD
+ no_coverage: true
- name: Shade on Java 17
group: SHADE_RUN
setup: ./build/run_integration_group.sh SHADE_BUILD
+ no_coverage: true
- name: Standalone
group: STANDALONE
@@ -467,7 +470,15 @@ jobs:
- name: Run integration test group '${{ matrix.group }}'
run: |
- ./build/run_integration_group.sh ${{ matrix.group }}
+ if [[ "${{ matrix.no_coverage }}" != "true" ]]; then
+ coverage_args="--coverage"
+ fi
+ ./build/run_integration_group.sh ${{ matrix.group }} $coverage_args
+
+ - name: Upload to Codecov
+ uses: ./.github/actions/upload-coverage
+ with:
+ flags: inttests
- name: print JVM thread dumps when cancelled
if: cancelled()
@@ -739,7 +750,12 @@ jobs:
- name: Run system test group '${{ matrix.group }}'
run: |
- ./build/run_integration_group.sh ${{ matrix.group }}
+ ./build/run_integration_group.sh ${{ matrix.group }} --coverage
+
+ - name: Upload to Codecov
+ uses: ./.github/actions/upload-coverage
+ with:
+ flags: systests
- name: print JVM thread dumps when cancelled
if: cancelled()
diff --git a/build/run_integration_group.sh b/build/run_integration_group.sh
index 1ba66fbc93c64..974ad96e419ac 100755
--- a/build/run_integration_group.sh
+++ b/build/run_integration_group.sh
@@ -27,6 +27,7 @@ set -o errexit
JAVA_MAJOR_VERSION="$(java -version 2>&1 |grep " version " | awk -F\" '{ print $2 }' | awk -F. '{ if ($1=="1") { print $2 } else { print $1 } }')"
# Used to shade run test on Java 8, because the latest TestNG requires Java 11 or higher.
TESTNG_VERSION="7.3.0"
+COVERAGE_COLLECTED=0
# lists all active maven modules with given parameters
# parses the modules from the "mvn initialize" output
@@ -46,15 +47,14 @@ mvn_list_modules() {
# 2. runs "mvn -pl [active_modules] -am install [given_params]" to build and install required dependencies
# 3. finally runs tests with "mvn -pl [active_modules] test [given_params]"
mvn_run_integration_test() {
- (
set +x
# skip test run if next parameter is "--build-only"
- build_only=0
+ local build_only=0
if [[ "$1" == "--build-only" ]]; then
build_only=1
shift
fi
- skip_build_deps=0
+ local skip_build_deps=0
while [[ "$1" == "--skip-build-deps" ]]; do
skip_build_deps=1
shift
@@ -78,8 +78,19 @@ mvn_run_integration_test() {
else
failfast_args="-DtestFailFast=false --fail-at-end"
fi
+ local coverage_args=""
+ if [[ "$1" == "--coverage" ]]; then
+ if [ ! -d /tmp/jacocoDir ]; then
+ mkdir /tmp/jacocoDir
+ sudo chmod 0777 /tmp/jacocoDir || chmod 0777 /tmp/jacocoDir
+ fi
+ coverage_args="-Pcoverage -Dintegrationtest.coverage.enabled=true -Dintegrationtest.coverage.dir=/tmp/jacocoDir"
+ COVERAGE_COLLECTED=1
+ shift
+ fi
+ (
cd "$SCRIPT_DIR"/../tests
- modules=$(mvn_list_modules -DskipDocker "$@")
+ local modules=$(mvn_list_modules -DskipDocker "$@")
cd ..
set -x
if [ $skip_build_deps -ne 1 ]; then
@@ -90,14 +101,46 @@ mvn_run_integration_test() {
if [[ $build_only -ne 1 ]]; then
echo "::group::Run tests for " "$@"
# use "verify" instead of "test"
- mvn -B -ntp -pl "$modules" $failfast_args -DskipDocker -DskipSourceReleaseAssembly=true -Dspotbugs.skip=true -Dlicense.skip=true -Dcheckstyle.skip=true -Drat.skip=true -DredirectTestOutputToFile=false $clean_arg verify "$@"
+ mvn -B -ntp -pl "$modules" $failfast_args $coverage_args -DskipDocker -DskipSourceReleaseAssembly=true -Dspotbugs.skip=true -Dlicense.skip=true -Dcheckstyle.skip=true -Drat.skip=true -DredirectTestOutputToFile=false $clean_arg verify "$@"
echo "::endgroup::"
set +x
- "$SCRIPT_DIR/pulsar_ci_tool.sh" move_test_reports
+ "$SCRIPT_DIR/pulsar_ci_tool.sh" move_test_reports || true
fi
)
}
+# creates a jacoco xml report of the jacoco exec files produced in docker containers which have /tmp/jacocoDir mounted as /jacocoDir
+# this is used to calculate test coverage for the apache/pulsar code that is run inside the containers in integration tests
+# and system tests
+produce_integration_test_coverage_xml_report() {
+ if [[ -d /tmp/jacocoDir && "$OSTYPE" == "linux-gnu"* && -n "$(find /tmp/jacocoDir -name "*.exec" -print -quit)" ]]; then
+ cd "$GITHUB_WORKSPACE"
+ local jacoco_xml_file=tests/integration/target/site/jacoco/jacoco_inttests.xml
+ echo "Creating coverage report to $jacoco_xml_file"
+ local jacoco_version=$(mvn help:evaluate -Dexpression=jacoco-maven-plugin.version -q -DforceStdout)
+ set -x
+ mkdir -p $(dirname $jacoco_xml_file)
+ # install jacococli.jar command line tool
+ if [ ! -f /tmp/jacocoDir/jacococli.jar ]; then
+ curl -sL -o /tmp/jacocoDir/jacococli.jar "https://repo1.maven.org/maven2/org/jacoco/org.jacoco.cli/${jacoco_version}/org.jacoco.cli-${jacoco_version}-nodeps.jar"
+ fi
+ # extract the Pulsar jar files from the docker image that was used to run the tests in the docker containers
+ # the class files used to produce the jacoco exec files are needed in the xml report generation
+ if [ ! -d /tmp/jacocoDir/pulsar_lib ]; then
+ mkdir /tmp/jacocoDir/pulsar_lib
+ docker run --rm -u "$UID:${GID:-"$(id -g)"}" -v /tmp/jacocoDir/pulsar_lib:/pulsar_lib:rw ${PULSAR_TEST_IMAGE_NAME:-apachepulsar/java-test-image:latest} bash -c "cp -p /pulsar/lib/org.apache.pulsar-* /pulsar_lib"
+ # remove jar file that causes duplicate classes issue
+ rm /tmp/jacocoDir/pulsar_lib/org.apache.pulsar-bouncy-castle*
+ fi
+ # produce jacoco XML coverage report from the exec files and using the extracted jar files
+ java -jar /tmp/jacocoDir/jacococli.jar report /tmp/jacocoDir/*.exec \
+ --classfiles /tmp/jacocoDir/pulsar_lib --encoding UTF-8 --name "Pulsar Integration Tests - coverage in containers" \
+ $(find -path "*/src/main/java" -printf "--sourcefiles %P ") \
+ --xml $jacoco_xml_file
+ set +x
+ fi
+}
+
test_group_shade() {
mvn_run_integration_test "$@" -DShadeTests -DtestForkCount=1 -DtestReuseFork=false
}
@@ -223,6 +266,9 @@ echo "Test Group : $TEST_GROUP"
test_group_function_name="test_group_$(echo "$TEST_GROUP" | tr '[:upper:]' '[:lower:]')"
if [[ "$(LC_ALL=C type -t "${test_group_function_name}")" == "function" ]]; then
eval "$test_group_function_name" "$@"
+ if [ $COVERAGE_COLLECTED -eq 1 ]; then
+ produce_integration_test_coverage_xml_report
+ fi
else
echo "INVALID TEST GROUP"
echo "Available test groups:"
diff --git a/codecov.yml b/codecov.yml
index 139da33607056..a792887012396 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -21,12 +21,17 @@ codecov:
require_ci_to_pass: yes
notify:
# should match the number of builds sending coverage reports
- # currently pulsar-ci.yaml contains 9 builds and pulsar-ci-flaky.yaml contains 1 build
- after_n_builds: 10
+ # pulsar-ci.yaml contains:
+ # - 9 unit test builds
+ # - 4 integration test builds (without 'no_coverage: true')
+ # - 8 system test build
+ # pulsar-ci-flaky.yaml contains:
+ # - 1 build
+ after_n_builds: 22
comment:
# should match the number of builds sending coverage reports
- after_n_builds: 10
+ after_n_builds: 22
layout: "reach, diff, flags, files"
behavior: default
require_changes: false
diff --git a/pom.xml b/pom.xml
index e16471e0c9e62..28f9318caef38 100644
--- a/pom.xml
+++ b/pom.xml
@@ -111,6 +111,8 @@ flexible messaging model and an intuitive client API.
true
+ false
+ ${project.build.directory}
/tmp
kill
apachepulsar
diff --git a/tests/docker-images/latest-version-image/conf/bookie.conf b/tests/docker-images/latest-version-image/conf/bookie.conf
index f5e237c3bbab0..07547bcaef6d3 100644
--- a/tests/docker-images/latest-version-image/conf/bookie.conf
+++ b/tests/docker-images/latest-version-image/conf/bookie.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M -XX:MaxDirectMemorySize=512M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar bookie
user=pulsar
+stopwaitsecs=15
diff --git a/tests/docker-images/latest-version-image/conf/broker.conf b/tests/docker-images/latest-version-image/conf/broker.conf
index 723e0a24704b1..63be36437741b 100644
--- a/tests/docker-images/latest-version-image/conf/broker.conf
+++ b/tests/docker-images/latest-version-image/conf/broker.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar broker
user=pulsar
+stopwaitsecs=15
diff --git a/tests/docker-images/latest-version-image/conf/functions_worker.conf b/tests/docker-images/latest-version-image/conf/functions_worker.conf
index 256739501e30a..8072639a0d4a2 100644
--- a/tests/docker-images/latest-version-image/conf/functions_worker.conf
+++ b/tests/docker-images/latest-version-image/conf/functions_worker.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar functions-worker
user=pulsar
+stopwaitsecs=15
\ No newline at end of file
diff --git a/tests/docker-images/latest-version-image/conf/global-zk.conf b/tests/docker-images/latest-version-image/conf/global-zk.conf
index eb991f2999c62..e5ffd2eb9e769 100644
--- a/tests/docker-images/latest-version-image/conf/global-zk.conf
+++ b/tests/docker-images/latest-version-image/conf/global-zk.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar configuration-store
user=pulsar
+stopwaitsecs=15
\ No newline at end of file
diff --git a/tests/docker-images/latest-version-image/conf/local-zk.conf b/tests/docker-images/latest-version-image/conf/local-zk.conf
index 46d8aeb1484b8..c96543db8a865 100644
--- a/tests/docker-images/latest-version-image/conf/local-zk.conf
+++ b/tests/docker-images/latest-version-image/conf/local-zk.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar zookeeper
user=pulsar
+stopwaitsecs=15
\ No newline at end of file
diff --git a/tests/docker-images/latest-version-image/conf/presto_worker.conf b/tests/docker-images/latest-version-image/conf/presto_worker.conf
index 4e4a3ca581468..5a60ea550031c 100644
--- a/tests/docker-images/latest-version-image/conf/presto_worker.conf
+++ b/tests/docker-images/latest-version-image/conf/presto_worker.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar sql-worker start
user=pulsar
+stopwaitsecs=15
\ No newline at end of file
diff --git a/tests/docker-images/latest-version-image/conf/proxy.conf b/tests/docker-images/latest-version-image/conf/proxy.conf
index 91c3d608cb141..343a0f9614e30 100644
--- a/tests/docker-images/latest-version-image/conf/proxy.conf
+++ b/tests/docker-images/latest-version-image/conf/proxy.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar proxy
user=pulsar
+stopwaitsecs=15
\ No newline at end of file
diff --git a/tests/docker-images/latest-version-image/conf/websocket.conf b/tests/docker-images/latest-version-image/conf/websocket.conf
index 7a0fc3e009659..0418c4cbc26a3 100644
--- a/tests/docker-images/latest-version-image/conf/websocket.conf
+++ b/tests/docker-images/latest-version-image/conf/websocket.conf
@@ -25,3 +25,4 @@ directory=/pulsar
environment=PULSAR_MEM="-Xmx128M",PULSAR_GC="-XX:+UseZGC"
command=/pulsar/bin/pulsar websocket
user=pulsar
+stopwaitsecs=15
\ No newline at end of file
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index 652fc7543500e..d83ce2d891a5c 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -280,7 +280,8 @@
maven-surefire-plugin
${testJacocoAgentArgument} -XX:+ExitOnOutOfMemoryError -Xmx1G -XX:MaxDirectMemorySize=1G
- -Dio.netty.leakDetectionLevel=advanced -Dconfluent.version=${confluent.version}
+ -Dio.netty.leakDetectionLevel=advanced -Dconfluent.version=${confluent.version} -Djacoco.version=${jacoco-maven-plugin.version}
+ -Dintegrationtest.coverage.enabled=${integrationtest.coverage.enabled} -Dintegrationtest.coverage.dir=${integrationtest.coverage.dir}
${test.additional.args}
false
diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ChaosContainer.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ChaosContainer.java
index 90e6660103a2f..eb0acf33a892c 100644
--- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ChaosContainer.java
+++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ChaosContainer.java
@@ -63,6 +63,10 @@ protected void beforeStop() {
@Override
public void stop() {
beforeStop();
+ doStop();
+ }
+
+ protected void doStop() {
super.stop();
}
diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
index cc722cc0891f9..b3d6747bf8646 100644
--- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
+++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
@@ -20,11 +20,17 @@
import static java.time.temporal.ChronoUnit.SECONDS;
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.time.Duration;
import java.util.Objects;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.apache.pulsar.tests.integration.docker.ContainerExecResult;
import org.apache.pulsar.tests.integration.utils.DockerUtils;
+import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy;
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
@@ -149,6 +155,14 @@ protected void beforeStop() {
getContainerId(),
"/var/log/pulsar"
);
+ try {
+ // stop the "tail -f ..." commands started in afterStart method
+ // so that shutdown output doesn't clutter logs
+ execCmd("/usr/bin/pkill", "tail");
+ } catch (Exception e) {
+ // will fail if there's no tail running
+ log.debug("Cannot run 'pkill tail'", e);
+ }
}
}
@@ -161,6 +175,28 @@ public void stop() {
super.stop();
}
+ @Override
+ protected void doStop() {
+ if (getContainerId() != null) {
+ if (serviceEntryPoint.equals("bin/pulsar")) {
+ // attempt graceful shutdown using "docker stop"
+ dockerClient.stopContainerCmd(getContainerId())
+ .withTimeout(15)
+ .exec();
+ } else {
+ // use "supervisorctl stop all" for graceful shutdown
+ try {
+ ContainerExecResult result = execCmd("/usr/bin/supervisorctl", "stop", "all");
+ log.info("Stopped supervisor services exit code: {}\nstdout: {}\nstderr: {}", result.getExitCode(),
+ result.getStdout(), result.getStderr());
+ } catch (Exception e) {
+ log.error("Cannot run 'supervisorctl stop all'", e);
+ }
+ }
+ }
+ super.doStop();
+ }
+
@Override
public String getContainerName() {
return clusterName + "-" + hostname;
@@ -205,12 +241,52 @@ public void start() {
createContainerCmd.withEntrypoint(serviceEntryPoint);
});
+ if (isCodeCoverageEnabled()) {
+ configureCodeCoverage();
+ }
+
beforeStart();
super.start();
afterStart();
log.info("[{}] Start pulsar service {} at container {}", getContainerName(), serviceName, getContainerId());
}
+ protected boolean isCodeCoverageEnabled() {
+ return Boolean.getBoolean("integrationtest.coverage.enabled");
+ }
+
+ protected void configureCodeCoverage() {
+ File coverageDirectory;
+ if (System.getProperty("integrationtest.coverage.dir") != null) {
+ coverageDirectory = new File(System.getProperty("integrationtest.coverage.dir"));
+ } else {
+ coverageDirectory = new File("target");
+ }
+
+ if (!coverageDirectory.isDirectory()) {
+ coverageDirectory.mkdirs();
+ }
+ withFileSystemBind(coverageDirectory.getAbsolutePath(), "/jacocoDir", BindMode.READ_WRITE);
+
+ String jacocoVersion = System.getProperty("jacoco.version");
+ File jacocoAgentJar = new File(System.getProperty("user.home"),
+ ".m2/repository/org/jacoco/org.jacoco.agent/" + jacocoVersion + "/" + "org.jacoco.agent-"
+ + jacocoVersion + "-runtime.jar");
+
+ if (jacocoAgentJar.isFile()) {
+ try {
+ FileUtils.copyFileToDirectory(jacocoAgentJar, coverageDirectory);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ withEnv("OPTS", "-javaagent:/jacocoDir/" + jacocoAgentJar.getName()
+ + "=destfile=/jacocoDir/jacoco_" + getContainerName() + "_" + System.currentTimeMillis() + ".exec"
+ + ",includes=org.apache.pulsar.*:org.apache.bookkeeper.mledger.*");
+ } else {
+ log.error("Cannot find jacoco agent jar from '" + jacocoAgentJar.getAbsolutePath() + "'");
+ }
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof PulsarContainer)) {
diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ZKContainer.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ZKContainer.java
index 898e5d241767a..da3fb05a518f4 100644
--- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ZKContainer.java
+++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/ZKContainer.java
@@ -69,4 +69,9 @@ protected void beforeStop() {
);
}
}
+
+ @Override
+ protected boolean isCodeCoverageEnabled() {
+ return false;
+ }
}
diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarCluster.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarCluster.java
index a15a0e56f4afb..fcc0feec6d44f 100644
--- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarCluster.java
+++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarCluster.java
@@ -35,7 +35,6 @@
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
-import java.util.stream.Collectors;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
@@ -369,37 +368,30 @@ public synchronized void stop() {
return;
}
- List containers = new ArrayList<>();
-
- containers.addAll(workerContainers.values());
- containers.addAll(brokerContainers.values());
- containers.addAll(bookieContainers.values());
+ stopInParallel(workerContainers.values());
if (externalServices != null) {
- containers.addAll(externalServices.values());
+ stopInParallel(externalServices.values());
}
+ stopPrestoWorker();
+
if (null != proxyContainer) {
- containers.add(proxyContainer);
+ proxyContainer.stop();
}
+ stopInParallel(brokerContainers.values());
+
+ stopInParallel(bookieContainers.values());
+
if (!sharedCsContainer && null != csContainer) {
- containers.add(csContainer);
+ csContainer.stop();
}
if (null != zkContainer) {
- containers.add(zkContainer);
- }
- if (null != prestoWorkerContainer) {
- containers.add(prestoWorkerContainer);
+ zkContainer.stop();
}
- containers = containers.parallelStream()
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
-
- containers.parallelStream().forEach(GenericContainer::stop);
-
try {
network.close();
} catch (Exception e) {
@@ -407,6 +399,12 @@ public synchronized void stop() {
}
}
+ private static void stopInParallel(Collection extends GenericContainer>> containers) {
+ containers.parallelStream()
+ .filter(Objects::nonNull)
+ .forEach(GenericContainer::stop);
+ }
+
public void startPrestoWorker() {
startPrestoWorker(null, null);
}