From b9d9d8c2dd7aad7737bbf3fdd8580db8578af0c7 Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Tue, 21 Jul 2026 21:55:22 +0800 Subject: [PATCH 01/10] feat(server): support RocksDB on RISC-V --- .dockerignore | 2 +- .github/workflows/docker-build-ci.yml | 53 ++++- hugegraph-pd/hg-pd-grpc/pom.xml | 37 +++- hugegraph-server/Dockerfile | 69 +++++-- hugegraph-server/README.md | 75 +++++++ hugegraph-server/hugegraph-core/pom.xml | 24 ++- .../docker/docker-entrypoint.sh | 3 +- hugegraph-server/hugegraph-dist/pom.xml | 123 ++++++++---- .../assembly/static/bin/hugegraph-server.sh | 2 + .../src/assembly/static/bin/init-store.sh | 1 + .../src/assembly/static/bin/util.sh | 39 ++++ .../src/assembly/travis/build-report.sh | 10 +- .../travis/check-rocksdb-only-dist.sh | 97 ++++++++++ .../assembly/travis/rocksdb-jni-smoke.groovy | 55 ++++++ .../src/assembly/travis/run-api-test.sh | 57 +++++- .../src/assembly/travis/run-core-test.sh | 17 +- .../travis/run-docker-runtime-smoke-test.sh | 176 +++++++++++++++++ .../travis/run-native-runtime-smoke-test.sh | 72 +++++++ .../travis/run-rocksdb-jni-smoke-test.sh | 119 ++++++++++++ .../travis/run-server-e2e-smoke-test.sh | 183 ++++++++++++++++++ .../src/assembly/travis/start-server.sh | 10 +- .../src/assembly/travis/stop-server.sh | 1 - .../src/main/resources/backend.properties | 2 +- hugegraph-server/hugegraph-test/pom.xml | 83 +++++--- .../apache/hugegraph/core/TaskCoreTest.java | 37 +++- hugegraph-server/pom.xml | 26 ++- pom.xml | 33 +++- 27 files changed, 1292 insertions(+), 114 deletions(-) create mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh create mode 100644 hugegraph-server/hugegraph-dist/src/assembly/travis/rocksdb-jni-smoke.groovy create mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh create mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh create mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh create mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh diff --git a/.dockerignore b/.dockerignore index ee61478a15..a6ae8a3fce 100644 --- a/.dockerignore +++ b/.dockerignore @@ -21,7 +21,7 @@ **/target/ # Pre-extracted release dirs / archives -apache-hugegraph-*/ +**/apache-hugegraph-*/ **/*.tar **/*.tar.gz **/*.zip diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index 8d31ff266f..5a45bad731 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -26,6 +26,18 @@ on: paths: - '**/Dockerfile*' - '.dockerignore' + - '.github/workflows/docker-build-ci.yml' + - 'pom.xml' + - 'hugegraph-pd/hg-pd-grpc/pom.xml' + - 'hugegraph-server/pom.xml' + - 'hugegraph-server/hugegraph-core/pom.xml' + - 'hugegraph-server/hugegraph-rocksdb/pom.xml' + - 'hugegraph-server/hugegraph-dist/pom.xml' + - 'hugegraph-server/hugegraph-dist/docker/**' + - 'hugegraph-server/hugegraph-dist/src/main/resources/backend.properties' + - 'hugegraph-server/hugegraph-dist/src/assembly/static/**' + - 'hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh' + - 'hugegraph-server/hugegraph-dist/src/assembly/travis/*smoke*' jobs: docker-build: @@ -36,7 +48,6 @@ jobs: dockerfile: - hugegraph-pd/Dockerfile - hugegraph-store/Dockerfile - - hugegraph-server/Dockerfile - hugegraph-server/Dockerfile-hstore steps: @@ -50,3 +61,43 @@ jobs: HC=$(docker inspect --format='{{json .Config.Healthcheck}}' "$IMAGE_ID") echo "Healthcheck: $HC" [[ "$HC" != "null" ]] || { echo "ERROR: HEALTHCHECK missing in ${{ matrix.dockerfile }}"; exit 1; } + + server-runtime-smoke: + runs-on: ubuntu-24.04 + timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + arch: [amd64, arm64, riscv64] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + if: matrix.arch != 'amd64' + uses: docker/setup-qemu-action@v3 + with: + platforms: ${{ matrix.arch }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build HugeGraph Server for linux/${{ matrix.arch }} + run: | + docker buildx build \ + --platform linux/${{ matrix.arch }} \ + --load \ + --tag hugegraph-server-smoke:${{ matrix.arch }} \ + --file hugegraph-server/Dockerfile . + + - name: Check healthcheck and run runtime smoke + env: + IMAGE: hugegraph-server-smoke:${{ matrix.arch }} + ARCH: ${{ matrix.arch }} + run: | + HC=$(docker inspect --format='{{json .Config.Healthcheck}}' "$IMAGE") + echo "Healthcheck: $HC" + [[ "$HC" != "null" ]] || { echo "ERROR: HEALTHCHECK missing"; exit 1; } + hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh \ + "$IMAGE" "$ARCH" diff --git a/hugegraph-pd/hg-pd-grpc/pom.xml b/hugegraph-pd/hg-pd-grpc/pom.xml index 7df8622e19..be8ccc44fd 100644 --- a/hugegraph-pd/hg-pd-grpc/pom.xml +++ b/hugegraph-pd/hg-pd-grpc/pom.xml @@ -32,7 +32,7 @@ - 1.6.0 + 1.7.1 1.39.0 3.17.2 0.6.1 @@ -127,4 +127,39 @@ + + + + riscv64-protobuf-tools + + + riscv64 + + + + + 1.47.0 + 3.21.7 + + + + com.google.protobuf + protobuf-java + ${riscv64.protobuf.java.version} + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + + /usr/bin/protoc + /usr/bin/grpc_java_plugin + + + + + + diff --git a/hugegraph-server/Dockerfile b/hugegraph-server/Dockerfile index 2ca946e6ba..1b14f142f8 100644 --- a/hugegraph-server/Dockerfile +++ b/hugegraph-server/Dockerfile @@ -17,7 +17,25 @@ # # Dockerfile for HugeGraph Server -# 1st stage: build source code +ARG TARGETARCH + +# Prepare the RISC-V Java runtime on the native build platform +FROM --platform=$BUILDPLATFORM maven:3.9.0-eclipse-temurin-11 AS riscv64-java + +ARG TARGETARCH +ARG DRAGONWELL_RISCV64_URL="https://github.com/dragonwell-project/dragonwell11/releases/download/dragonwell-extended-11.0.31.28_jdk-11.0.31-ga/Alibaba_Dragonwell_Extended_11.0.31.28.11_riscv64_linux.tar.gz" +ARG DRAGONWELL_RISCV64_SHA256="7df2d308f0dca7a779d2854e6da19214f99cd77aa6d4982c3bf981a77266a79b" + +RUN mkdir -p /opt/dragonwell \ + && if [ "$TARGETARCH" = "riscv64" ]; then \ + curl --fail --location --retry 3 --show-error \ + "$DRAGONWELL_RISCV64_URL" --output /tmp/dragonwell.tar.gz; \ + echo "$DRAGONWELL_RISCV64_SHA256 /tmp/dragonwell.tar.gz" | sha256sum -c -; \ + tar -xzf /tmp/dragonwell.tar.gz --strip-components=1 -C /opt/dragonwell; \ + rm /tmp/dragonwell.tar.gz; \ + fi + +# Build source code FROM --platform=$BUILDPLATFORM maven:3.9.0-eclipse-temurin-11 AS build WORKDIR /pkg @@ -25,14 +43,41 @@ WORKDIR /pkg COPY . . ARG MAVEN_ARGS +ARG TARGETARCH RUN --mount=type=cache,target=/root/.m2 \ - mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true -Dmaven.javadoc.skip=true \ - && rm ./hugegraph-server/*.tar.gz ./hugegraph-pd/*.tar.gz ./hugegraph-store/*.tar.gz + if [ "$TARGETARCH" = "riscv64" ]; then \ + mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true \ + -Dmaven.javadoc.skip=true -Drocksdb-only \ + -pl hugegraph-server/hugegraph-dist -am \ + && hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ + hugegraph-server/apache-hugegraph-server-*/; \ + else \ + mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true \ + -Dmaven.javadoc.skip=true \ + && rm ./hugegraph-server/*.tar.gz ./hugegraph-pd/*.tar.gz \ + ./hugegraph-store/*.tar.gz; \ + fi -# 2nd stage: runtime env +# Keep the existing Temurin 11 runtime for every architecture it supports. +FROM --platform=linux/amd64 eclipse-temurin:11-jre-jammy AS runtime-amd64 +FROM --platform=linux/arm/v7 eclipse-temurin:11-jre-jammy AS runtime-arm +FROM --platform=linux/arm64 eclipse-temurin:11-jre-jammy AS runtime-arm64 +FROM --platform=linux/ppc64le eclipse-temurin:11-jre-jammy AS runtime-ppc64le +FROM --platform=linux/s390x eclipse-temurin:11-jre-jammy AS runtime-s390x + +# Temurin 11 has no RISC-V image, so use Ubuntu with the verified Dragonwell archive. +FROM ubuntu:24.04 AS runtime-riscv64 +COPY --from=riscv64-java /opt/dragonwell/ /opt/dragonwell/ +ENV JAVA_HOME="/opt/dragonwell" \ + PATH="/opt/dragonwell/bin:${PATH}" + +# Runtime environment # Note: ZGC (The Z Garbage Collector) is only supported on ARM-Mac with java > 13 -FROM eclipse-temurin:11-jre-jammy +FROM runtime-${TARGETARCH} AS runtime + +ARG TARGETARCH +ARG DEBIAN_FRONTEND=noninteractive COPY --from=build /pkg/hugegraph-server/apache-hugegraph-server-*/ /hugegraph-server/ LABEL maintainer="HugeGraph Docker Maintainers " @@ -47,12 +92,14 @@ WORKDIR /hugegraph-server/ # 1. Install runtime dependencies and configure server RUN apt-get -q update \ - && apt-get -q install -y --no-install-recommends --no-install-suggests \ - dumb-init \ - procps \ - curl \ - lsof \ - vim \ + && runtime_packages="dumb-init procps curl lsof vim" \ + && if [ "$TARGETARCH" = "riscv64" ]; then \ + runtime_packages="$runtime_packages ca-certificates libatomic1 libstdc++6 libgcc-s1"; \ + fi \ + && apt-get -q install -y --no-install-recommends --no-install-suggests $runtime_packages \ + && if [ "$TARGETARCH" = "riscv64" ]; then \ + test -x /opt/dragonwell/bin/java; \ + fi \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && sed -i "s/^restserver.url.*$/restserver.url=http:\/\/0.0.0.0:8080/g" ./conf/rest-server.properties diff --git a/hugegraph-server/README.md b/hugegraph-server/README.md index c145190bf0..0fed69f69c 100644 --- a/hugegraph-server/README.md +++ b/hugegraph-server/README.md @@ -30,3 +30,78 @@ HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose-3pd-3store-3server.yml ``` See [docker/README.md](../docker/README.md) for the full setup guide. + +## RISC-V Development and Testing + +The supported RISC-V target is 64-bit `linux/riscv64` LP64D with glibc 2.30 or newer. +This target covers HugeGraph Server with the embedded RocksDB backend only. It does not +cover musl/Alpine, 32-bit RISC-V, PD, Store, HStore, or other storage backends. + +The RISC-V image uses the checksum-pinned Alibaba Dragonwell 11 Extended Server VM from +the [Dockerfile](Dockerfile). The runtime also provides `libstdc++6`, `libgcc-s1`, and +`libatomic.so.1`, which are required by the packaged RocksDB JNI library. + +### Docker and QEMU + +Docker Desktop includes emulation support. On Linux, install the RISC-V emulator only if +it is not already registered: + +```bash +docker run --privileged --rm tonistiigi/binfmt --install riscv64 +``` + +From the repository root, build and run the complete runtime smoke test: + +```bash +IMAGE=hugegraph-server:riscv64-test +docker buildx build --platform linux/riscv64 --load --tag "$IMAGE" \ + --file hugegraph-server/Dockerfile . +hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh \ + "$IMAGE" riscv64 +docker image rm "$IMAGE" +``` + +The smoke helper removes its test containers, anonymous volumes, and temporary files. It +keeps the input image and does not create or remove a Buildx builder or host emulator. If +you created those resources specifically for this test, remove them separately: + +```bash +docker buildx rm hugegraph-riscv64 +docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-riscv64 +``` + +Do not uninstall Docker Desktop's built-in emulator. QEMU is substantially slower than +native RISC-V and is intended for correctness testing, not performance measurements. + +### Native RISC-V + +Use Dragonwell 11 Extended `11.0.31.28.11` and verify its archive with the URL and SHA-256 +declared in the Dockerfile. On a Debian-derived glibc system, install the native tools and +runtime libraries: + +```bash +sudo apt-get update +sudo apt-get install -y maven protobuf-compiler \ + protobuf-compiler-grpc-java-plugin libatomic1 libstdc++6 libgcc-s1 curl jq +``` + +After selecting Dragonwell as `JAVA_HOME`, build and verify the RocksDB-only distribution: + +```bash +test "$(uname -m)" = riscv64 +java -XshowSettings:vm -version +mvn clean package -Drocksdb-only -pl hugegraph-server/hugegraph-dist -am \ + -Dmaven.test.skip=true -Dmaven.javadoc.skip=true +hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ + hugegraph-server/apache-hugegraph-server-*/ +hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh \ + hugegraph-server/apache-hugegraph-server-*/ +``` + +Run the existing Core and API gates with the same RocksDB-only dependency boundary: + +```bash +hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh rocksdb +hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh \ + rocksdb target/riscv64-api-report +``` diff --git a/hugegraph-server/hugegraph-core/pom.xml b/hugegraph-server/hugegraph-core/pom.xml index 2334496329..14f5274cb4 100644 --- a/hugegraph-server/hugegraph-core/pom.xml +++ b/hugegraph-server/hugegraph-core/pom.xml @@ -335,7 +335,7 @@ kr.motd.maven os-maven-plugin - 1.5.0.Final + 1.7.1 @@ -408,4 +408,26 @@ + + + + riscv64-protobuf-tools + + + riscv64 + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + + /usr/bin/protoc + + + + + + diff --git a/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh b/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh index 2c76a54435..db0593b5bf 100755 --- a/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh +++ b/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh @@ -81,7 +81,8 @@ else log "HugeGraph initialization already done. Skipping re-init..." fi -./bin/start-hugegraph.sh -j "${JAVA_OPTS:-}" -t 120 +./bin/start-hugegraph.sh -j "${JAVA_OPTS:-}" \ + -t "${HG_SERVER_STARTUP_TIMEOUT:-120}" # Post-startup cluster stabilization check (hstore only — rocksdb has no partitions) ACTUAL_BACKEND=$(grep -E '^[[:space:]]*backend[[:space:]]*=' "${GRAPH_CONF}" | head -n 1 | sed 's/.*=//' | tr -d '[:space:]' || true) diff --git a/hugegraph-server/hugegraph-dist/pom.xml b/hugegraph-server/hugegraph-dist/pom.xml index 5914b038be..430a213900 100644 --- a/hugegraph-server/hugegraph-dist/pom.xml +++ b/hugegraph-server/hugegraph-dist/pom.xml @@ -34,6 +34,8 @@ ${assembly.dir}/descriptor ${assembly.dir}/static 2.4.0 + 0.3.2 + rocksdb, hbase, hstore @@ -59,53 +61,11 @@ - - org.apache.hugegraph - hugegraph-cassandra - ${revision} - - - metrics-core - io.dropwizard.metrics - - - - - org.apache.hugegraph - hugegraph-scylladb - ${revision} - org.apache.hugegraph hugegraph-rocksdb ${revision} - - org.apache.hugegraph - hugegraph-mysql - ${revision} - - - org.apache.hugegraph - hugegraph-palo - ${revision} - - - org.apache.hugegraph - hugegraph-hbase - ${revision} - - - org.apache.hugegraph - hugegraph-postgresql - ${revision} - - - org.apache.hugegraph - hugegraph-hstore - ${revision} - - org.apache.tinkerpop gremlin-console @@ -133,6 +93,13 @@ ${jansi.version} runtime + + + com.github.jbellis + jamm + ${jamm.version} + runtime + @@ -144,6 +111,16 @@ ${basedir}/src/main/resources false + + backend.properties + + + + ${basedir}/src/main/resources + true + + backend.properties + @@ -289,6 +266,68 @@ + + rocksdb-only + + + rocksdb-only + + + + rocksdb + + + + all-backends + + + !rocksdb-only + + + + + org.apache.hugegraph + hugegraph-cassandra + ${revision} + + + metrics-core + io.dropwizard.metrics + + + + + org.apache.hugegraph + hugegraph-scylladb + ${revision} + + + org.apache.hugegraph + hugegraph-mysql + ${revision} + + + org.apache.hugegraph + hugegraph-palo + ${revision} + + + org.apache.hugegraph + hugegraph-hbase + ${revision} + + + org.apache.hugegraph + hugegraph-postgresql + ${revision} + + + org.apache.hugegraph + hugegraph-hstore + ${revision} + + + assembly-hugegraph diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh index c5f84d4933..3915a5f63e 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh @@ -45,6 +45,8 @@ GITHUB="https://github.com" export HUGEGRAPH_HOME="$TOP" . "${BIN}"/util.sh +configure_riscv64_libatomic || exit 1 + # Parse the server arguments in array way SERVER_ARGS=("$@") GREMLIN_SERVER_CONF="${SERVER_ARGS[0]:-}" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh index 9aefd1160b..b9da84166b 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh @@ -33,6 +33,7 @@ PLUGINS="$TOP/plugins" . "${BIN}"/util.sh +configure_riscv64_libatomic || exit 1 ensure_path_writable "${PLUGINS}" if [[ -n "$JAVA_HOME" ]]; then diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/util.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/util.sh index e2655c69d3..91c0c3efbf 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/util.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/util.sh @@ -25,6 +25,45 @@ function command_available() { fi } +function configure_riscv64_libatomic() { + if [[ "$(uname -s)" != "Linux" || "$(uname -m)" != "riscv64" ]]; then + return 0 + fi + + if [[ "${LD_PRELOAD:-}" == *"libatomic.so.1"* ]]; then + return 0 + fi + + local libatomic="" + if command_available "ldconfig"; then + libatomic=$(ldconfig -p 2>/dev/null | \ + awk '/libatomic\.so\.1 .*=>/ && !path {path=$NF} + END {if (path) print path}') + fi + + if [[ -z "$libatomic" ]]; then + local candidate + for candidate in /lib/riscv64-linux-gnu/libatomic.so.1 \ + /usr/lib/riscv64-linux-gnu/libatomic.so.1 \ + /lib64/lp64d/libatomic.so.1 \ + /usr/lib64/lp64d/libatomic.so.1 \ + /lib64/libatomic.so.1 \ + /usr/lib64/libatomic.so.1; do + if [[ -r "$candidate" ]]; then + libatomic="$candidate" + break + fi + done + fi + + if [[ -z "$libatomic" ]]; then + echo "RISC-V RocksDB requires libatomic.so.1; install libatomic1" >&2 + return 1 + fi + + export LD_PRELOAD="${LD_PRELOAD:+${LD_PRELOAD}:}${libatomic}" +} + # read a property from .properties file function read_property() { # file path diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh index 920914267d..d38ca0d661 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh @@ -20,6 +20,13 @@ set -ev BACKEND=$1 JACOCO_PORT=$2 JACOCO_REPORT_FILE=$3 +MAVEN_SCOPE_ARGS=() + +if [[ "$BACKEND" == "rocksdb" && + "$(uname -s)" == "Linux" && + "$(uname -m)" == "riscv64" ]]; then + MAVEN_SCOPE_ARGS+=("-Drocksdb-only") +fi TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) @@ -58,7 +65,8 @@ esac mkdir -p "$(dirname "$REPORT_FILE")" cd "$REPO_ROOT/hugegraph-server/hugegraph-test" -mvn jacoco:dump@pull-test-data -Dapp.host=localhost -Dapp.port=$JACOCO_PORT -Dskip.dump=false +mvn jacoco:dump@pull-test-data -Dapp.host=localhost -Dapp.port=$JACOCO_PORT \ + -Dskip.dump=false "${MAVEN_SCOPE_ARGS[@]}" cd "$REPO_ROOT/hugegraph-server" if [[ ! -e "${TRAVIS_DIR}/jacococli.jar" ]]; then diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh new file mode 100755 index 0000000000..133739422d --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "USAGE: $0 SERVER_DIR" >&2 + exit 1 +fi + +SERVER_DIR=$1 +LIB_DIR="$SERVER_DIR/lib" +DIST_JAR="" +WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-dist-check.XXXXXX") + +cleanup() { + rm -rf "$WORK_DIR" +} +trap cleanup EXIT + +if [[ ! -d "$LIB_DIR" ]]; then + echo "Distribution lib directory does not exist: $LIB_DIR" >&2 + exit 1 +fi + +function require_jar() { + local pattern=$1 + if ! find "$LIB_DIR" -maxdepth 1 -type f -name "$pattern" -print -quit | grep -q .; then + echo "Missing required RocksDB distribution artifact: $pattern" >&2 + exit 1 + fi +} + +function forbid_jar() { + local pattern=$1 + local match + match=$(find "$LIB_DIR" -maxdepth 1 -type f -name "$pattern" -print -quit) + if [[ -n "$match" ]]; then + echo "Unrelated backend artifact found in RocksDB-only distribution: $match" >&2 + exit 1 + fi +} + +for pattern in hugegraph-core-*.jar \ + hugegraph-api-*.jar \ + hugegraph-rocksdb-*.jar \ + hugegraph-dist-*.jar \ + jamm-*.jar \ + rocksdbjni-*.jar; do + require_jar "$pattern" +done + +DIST_JAR=$(find "$LIB_DIR" -maxdepth 1 -type f \ + -name 'hugegraph-dist-*.jar' -print -quit) +DIST_JAR=$(cd "$(dirname "$DIST_JAR")" && pwd)/$(basename "$DIST_JAR") +if command -v unzip >/dev/null 2>&1; then + BACKEND_PROPERTIES=$(unzip -p "$DIST_JAR" backend.properties) +elif command -v jar >/dev/null 2>&1; then + (cd "$WORK_DIR" && jar xf "$DIST_JAR" backend.properties) + BACKEND_PROPERTIES=$(cat "$WORK_DIR/backend.properties") +else + echo "The distribution check requires unzip or a JDK jar command" >&2 + exit 1 +fi + +if ! grep -qx 'backends=\[rocksdb\]' <<< "$BACKEND_PROPERTIES"; then + echo "RocksDB-only distribution has an invalid backend registry" >&2 + printf '%s\n' "$BACKEND_PROPERTIES" >&2 + exit 1 +fi + +for pattern in hugegraph-cassandra-*.jar \ + hugegraph-scylladb-*.jar \ + hugegraph-mysql-*.jar \ + hugegraph-palo-*.jar \ + hugegraph-hbase-*.jar \ + hugegraph-postgresql-*.jar \ + hugegraph-hstore-*.jar; do + forbid_jar "$pattern" +done + +echo "RocksDB-only distribution contains the required backend and no unrelated backend JARs" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/rocksdb-jni-smoke.groovy b/hugegraph-server/hugegraph-dist/src/assembly/travis/rocksdb-jni-smoke.groovy new file mode 100644 index 0000000000..1baa856bf9 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/rocksdb-jni-smoke.groovy @@ -0,0 +1,55 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import java.nio.charset.StandardCharsets +import java.util.Arrays + +import org.rocksdb.Options +import org.rocksdb.RocksDB + +rocksdbSmokePath = System.getenv('ROCKSDB_SMOKE_DIR') +if (!rocksdbSmokePath) { + throw new IllegalArgumentException('ROCKSDB_SMOKE_DIR is required') +} + +rocksdbSmokeKey = 'hugegraph-riscv64-key'.getBytes(StandardCharsets.UTF_8) +rocksdbSmokeExpected = 'hugegraph-riscv64-value'.getBytes(StandardCharsets.UTF_8) + +RocksDB.loadLibrary() + +rocksdbSmokeOptions = new Options().setCreateIfMissing(true) +rocksdbSmokeDb = null +try { + rocksdbSmokeDb = RocksDB.open(rocksdbSmokeOptions, rocksdbSmokePath) + rocksdbSmokeDb.put(rocksdbSmokeKey, rocksdbSmokeExpected) + def actual = rocksdbSmokeDb.get(rocksdbSmokeKey) + if (!Arrays.equals(rocksdbSmokeExpected, actual)) { + throw new IllegalStateException('RocksDB value differs after put/get') + } + rocksdbSmokeDb.close() + rocksdbSmokeDb = null + + rocksdbSmokeDb = RocksDB.open(rocksdbSmokeOptions, rocksdbSmokePath) + actual = rocksdbSmokeDb.get(rocksdbSmokeKey) + if (!Arrays.equals(rocksdbSmokeExpected, actual)) { + throw new IllegalStateException('RocksDB value differs after reopen') + } + println('rocksdb-jni-smoke-ok') +} finally { + rocksdbSmokeDb?.close() + rocksdbSmokeOptions.close() +} diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh index a038370ad7..c960e46f27 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -set -ev +set -euo pipefail BACKEND=$1 REPORT_DIR=$2 @@ -58,18 +58,58 @@ function download_to_dir() { cd "$REPO_ROOT" -VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) +MAVEN_SCOPE_ARGS=() +ROCKSDB_ONLY=false + +if [[ "$BACKEND" == "rocksdb" && + "$(uname -s)" == "Linux" && + "$(uname -m)" == "riscv64" ]]; then + . "$TRAVIS_DIR/../static/bin/util.sh" + configure_riscv64_libatomic + MAVEN_SCOPE_ARGS+=("-Drocksdb-only") + ROCKSDB_ONLY=true +fi + +VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout \ + "${MAVEN_SCOPE_ARGS[@]}") SERVER_DIR=hugegraph-server/apache-hugegraph-server-$VERSION/ CONF=$SERVER_DIR/conf/graphs/hugegraph.properties REST_SERVER_CONF=$SERVER_DIR/conf/rest-server.properties GREMLIN_SERVER_CONF=$SERVER_DIR/conf/gremlin-server.yaml JACOCO_PORT=36320 +SERVER_START_ATTEMPTED=false + +function cleanup() { + local status=$? + trap - EXIT + + if [[ "$SERVER_START_ATTEMPTED" == "true" ]]; then + if ! "$TRAVIS_DIR"/stop-server.sh "$SERVER_DIR"; then + echo "Failed to stop the HugeGraph Server started by this test" >&2 + status=1 + fi + fi + exit "$status" +} -mvn package -Dmaven.test.skip=true -ntp +trap cleanup EXIT + +if [[ "$ROCKSDB_ONLY" == "true" ]]; then + mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -ntp \ + -pl hugegraph-server/hugegraph-dist -am "${MAVEN_SCOPE_ARGS[@]}" +else + mvn package -Dmaven.test.skip=true -ntp +fi + +if [[ "$ROCKSDB_ONLY" == "true" ]]; then + "$TRAVIS_DIR"/check-rocksdb-only-dist.sh "$SERVER_DIR" +fi # add mysql dependency -download_to_dir "$SERVER_DIR/lib/" \ - "https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar" +if [[ "$ROCKSDB_ONLY" != "true" ]]; then + download_to_dir "$SERVER_DIR/lib/" \ + "https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar" +fi if [[ ! -e "$SERVER_DIR/lib/ikanalyzer-2012_u6.jar" ]]; then download_to_dir "$SERVER_DIR/lib/" \ @@ -94,10 +134,12 @@ authentication: { }" >> $GREMLIN_SERVER_CONF # start server +SERVER_START_ATTEMPTED=true $TRAVIS_DIR/start-server.sh $SERVER_DIR $BACKEND $JACOCO_PORT || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) # run api-test -mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) +mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND \ + "${MAVEN_SCOPE_ARGS[@]}" || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) if [ "$RUN_GREMLIN_CONSOLE_SMOKE_TEST" == "true" ]; then bash "$TRAVIS_DIR/run-gremlin-console-smoke-test.sh" "$SERVER_DIR" || \ @@ -105,6 +147,3 @@ if [ "$RUN_GREMLIN_CONSOLE_SMOKE_TEST" == "true" ]; then fi $TRAVIS_DIR/build-report.sh $BACKEND $JACOCO_PORT $REPORT_FILE - -# stop server -$TRAVIS_DIR/stop-server.sh $SERVER_DIR diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh index a95d2f0806..412d94a1da 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh @@ -15,8 +15,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # -set -ev +set -euo pipefail BACKEND=$1 +TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) +REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) +MAVEN_SCOPE_ARGS=() -mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,$BACKEND +if [[ "$BACKEND" == "rocksdb" && + "$(uname -s)" == "Linux" && + "$(uname -m)" == "riscv64" ]]; then + . "$TRAVIS_DIR/../static/bin/util.sh" + configure_riscv64_libatomic + MAVEN_SCOPE_ARGS+=("-Drocksdb-only") +fi + +cd "$REPO_ROOT" +mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,"$BACKEND" \ + "${MAVEN_SCOPE_ARGS[@]}" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh new file mode 100755 index 0000000000..2ca13f646d --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -euo pipefail + +if [[ $# -lt 1 || $# -gt 2 ]]; then + echo "USAGE: $0 IMAGE [ARCH]" >&2 + exit 1 +fi + +IMAGE=$1 +EXPECTED_ARCH=${2:-riscv64} +TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) +CONTAINER_NAME="hugegraph-runtime-smoke-${EXPECTED_ARCH}-$$" +CONTAINER_STARTED=false +WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-docker-runtime-smoke.XXXXXX") +CONTAINER_LOG="$WORK_DIR/container.log" +RUN_ID="$(date +%s)_$$" + +case "$EXPECTED_ARCH" in + amd64) + EXPECTED_UNAME_ARCH=x86_64 + SERVER_STARTUP_TIMEOUT=300 + CONTAINER_READY_TIMEOUT=300 + ;; + arm64) + EXPECTED_UNAME_ARCH=aarch64 + SERVER_STARTUP_TIMEOUT=300 + CONTAINER_READY_TIMEOUT=300 + ;; + riscv64) + EXPECTED_UNAME_ARCH=riscv64 + SERVER_STARTUP_TIMEOUT=300 + CONTAINER_READY_TIMEOUT=600 + ;; + *) + echo "Unsupported Docker architecture: $EXPECTED_ARCH" >&2 + exit 1 + ;; +esac + +cleanup() { + local status=$? + trap - EXIT + if [[ "$CONTAINER_STARTED" == "true" ]]; then + docker rm --force --volumes "$CONTAINER_NAME" >/dev/null 2>&1 || status=1 + fi + rm -rf "$WORK_DIR" + exit "$status" +} +trap cleanup EXIT + +for command in docker curl jq; do + if ! command -v "$command" >/dev/null 2>&1; then + echo "Required command is unavailable: $command" >&2 + exit 1 + fi +done + +IMAGE_ARCH=$(docker image inspect --format '{{.Architecture}}' "$IMAGE") +if [[ "$IMAGE_ARCH" != "$EXPECTED_ARCH" ]]; then + echo "Expected image architecture $EXPECTED_ARCH, got $IMAGE_ARCH" >&2 + exit 1 +fi + +docker run --rm --platform "linux/$EXPECTED_ARCH" \ + --env EXPECTED_ARCH="$EXPECTED_UNAME_ARCH" \ + --env EXPECTED_JAVA_MAJOR=11 \ + --volume "$TRAVIS_DIR:/smoke:ro" \ + --entrypoint /bin/bash "$IMAGE" \ + /smoke/run-rocksdb-jni-smoke-test.sh /hugegraph-server + +docker run --detach --platform "linux/$EXPECTED_ARCH" \ + --name "$CONTAINER_NAME" \ + --env HG_SERVER_STARTUP_TIMEOUT="$SERVER_STARTUP_TIMEOUT" \ + --publish 127.0.0.1::8080 \ + "$IMAGE" >/dev/null +CONTAINER_STARTED=true + +update_server_url() { + local port_binding + local server_port + + port_binding=$(docker port "$CONTAINER_NAME" 8080/tcp | head -n 1) + if [[ -z "$port_binding" ]]; then + echo "HugeGraph container has no published port for 8080/tcp" >&2 + return 1 + fi + server_port=${port_binding##*:} + SERVER_URL="http://127.0.0.1:$server_port" +} + +wait_for_container_server() { + local attempt + local running + for attempt in $(seq 1 "$CONTAINER_READY_TIMEOUT"); do + running=$(docker inspect --format '{{.State.Running}}' "$CONTAINER_NAME") + if [[ "$running" != "true" ]]; then + echo "HugeGraph container exited before becoming ready" >&2 + docker logs "$CONTAINER_NAME" >&2 + return 1 + fi + if curl --silent --show-error --fail \ + "$SERVER_URL/versions" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + echo "HugeGraph container did not become ready at $SERVER_URL" >&2 + docker logs "$CONTAINER_NAME" >&2 + return 1 +} + +wait_for_container_health() { + local attempt + local health + for attempt in $(seq 1 60); do + health=$(docker inspect --format \ + '{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}' \ + "$CONTAINER_NAME") + if [[ "$health" == "healthy" ]]; then + return 0 + fi + if [[ "$health" == "missing" ]]; then + echo "HugeGraph container has no health status" >&2 + return 1 + fi + sleep 1 + done + echo "HugeGraph container health did not become healthy" >&2 + docker inspect --format '{{json .State.Health}}' "$CONTAINER_NAME" >&2 + return 1 +} + +update_server_url +wait_for_container_server +wait_for_container_health +"$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" create "$RUN_ID" | \ + tee "$WORK_DIR/create.log" +grep -q '^server-e2e-smoke-create-ok$' "$WORK_DIR/create.log" +docker restart --time 30 "$CONTAINER_NAME" >/dev/null +update_server_url +wait_for_container_server +wait_for_container_health +"$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" verify "$RUN_ID" | \ + tee "$WORK_DIR/verify.log" +grep -q '^server-e2e-smoke-verify-ok$' "$WORK_DIR/verify.log" + +if ! docker logs "$CONTAINER_NAME" > "$CONTAINER_LOG" 2>&1; then + echo "Failed to read HugeGraph container logs" >&2 + cat "$CONTAINER_LOG" >&2 + exit 1 +fi +if grep -Eiq \ + 'undefined symbol|UnsatisfiedLinkError|UnsupportedClassVersionError|NoClassDefFoundError' \ + "$CONTAINER_LOG"; then + echo "Native linkage or Java compatibility error found in container logs" >&2 + cat "$CONTAINER_LOG" >&2 + exit 1 +fi + +echo "docker-runtime-smoke-$EXPECTED_ARCH-ok" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh new file mode 100755 index 0000000000..2c1261924b --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "USAGE: $0 SERVER_DIR" >&2 + exit 1 +fi + +TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) +SERVER_DIR=$(cd "$1" && pwd) +SERVER_URL=${SERVER_URL:-http://127.0.0.1:8080} +EXPECTED_ARCH=${EXPECTED_ARCH:-riscv64} +EXPECTED_JAVA_MAJOR=${EXPECTED_JAVA_MAJOR:-11} +SERVER_START_ATTEMPTED=false +SERVER_STARTUP_TIMEOUT=${SERVER_STARTUP_TIMEOUT:-300} +WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-native-runtime-smoke.XXXXXX") +RUN_ID="$(date +%s)_$$" + +export EXPECTED_ARCH EXPECTED_JAVA_MAJOR + +cleanup() { + local status=$? + trap - EXIT + if [[ "$SERVER_START_ATTEMPTED" == "true" ]]; then + "$SERVER_DIR/bin/stop-hugegraph.sh" -m false >/dev/null 2>&1 || status=1 + fi + rm -rf "$WORK_DIR" + exit "$status" +} +trap cleanup EXIT + +"$TRAVIS_DIR/run-rocksdb-jni-smoke-test.sh" "$SERVER_DIR" + +"$SERVER_DIR/bin/init-store.sh" +SERVER_START_ATTEMPTED=true +"$SERVER_DIR/bin/start-hugegraph.sh" -t "$SERVER_STARTUP_TIMEOUT" +"$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" create "$RUN_ID" | \ + tee "$WORK_DIR/create.log" +grep -q '^server-e2e-smoke-create-ok$' "$WORK_DIR/create.log" + +"$SERVER_DIR/bin/stop-hugegraph.sh" -m false +"$SERVER_DIR/bin/start-hugegraph.sh" -t "$SERVER_STARTUP_TIMEOUT" +"$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" verify "$RUN_ID" | \ + tee "$WORK_DIR/verify.log" +grep -q '^server-e2e-smoke-verify-ok$' "$WORK_DIR/verify.log" + +if [[ -d "$SERVER_DIR/logs" ]] && \ + grep -Eirq 'undefined symbol|UnsatisfiedLinkError|UnsupportedClassVersionError|NoClassDefFoundError' \ + "$SERVER_DIR/logs"; then + echo "Native linkage or Java compatibility error found in $SERVER_DIR/logs" >&2 + grep -Eirn 'undefined symbol|UnsatisfiedLinkError|UnsupportedClassVersionError|NoClassDefFoundError' \ + "$SERVER_DIR/logs" >&2 + exit 1 +fi + +echo "native-runtime-smoke-ok" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh new file mode 100755 index 0000000000..1693065e91 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "USAGE: $0 SERVER_DIR" >&2 + exit 1 +fi + +TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) +SERVER_DIR=$(cd "$1" && pwd) +EXPECTED_ARCH=${EXPECTED_ARCH:-} +EXPECTED_JAVA_MAJOR=${EXPECTED_JAVA_MAJOR:-11} +ACTUAL_ARCH=$(uname -m) + +if [[ -n "$EXPECTED_ARCH" && "$ACTUAL_ARCH" != "$EXPECTED_ARCH" ]]; then + echo "Expected architecture $EXPECTED_ARCH, got $ACTUAL_ARCH" >&2 + exit 1 +fi + +JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2; exit}') +JAVA_MAJOR=${JAVA_VERSION%%.*} +if [[ "$JAVA_MAJOR" == "1" ]]; then + JAVA_MAJOR=$(echo "$JAVA_VERSION" | cut -d. -f2) +fi +if [[ "$JAVA_MAJOR" != "$EXPECTED_JAVA_MAJOR" ]]; then + echo "Expected Java $EXPECTED_JAVA_MAJOR, got $JAVA_VERSION" >&2 + exit 1 +fi + +JAVA_PROPERTIES=$(java -XshowSettings:properties -version 2>&1) +java_property() { + local key=$1 + awk -F ' = ' -v key="$key" '{ + name = $1 + sub(/^[[:space:]]*/, "", name) + if (name == key) { + print $2 + exit + } + }' <<< "$JAVA_PROPERTIES" +} + +JAVA_VM_NAME=$(java_property java.vm.name) +JAVA_VM_VENDOR=$(java_property java.vm.vendor) +JAVA_VM_VERSION=$(java_property java.vm.version) +JAVA_VM_INFO=$(java_property java.vm.info) + +if [[ -z "$JAVA_VM_NAME" || -z "$JAVA_VM_VENDOR" || -z "$JAVA_VM_INFO" ]]; then + echo "Failed to read Java VM properties" >&2 + exit 1 +fi + +echo "Architecture: $ACTUAL_ARCH" +echo "Java: $JAVA_VERSION" +echo "Java VM: $JAVA_VM_NAME ($JAVA_VM_VENDOR, $JAVA_VM_VERSION, $JAVA_VM_INFO)" +if command -v getconf >/dev/null 2>&1; then + echo "C library: $(getconf GNU_LIBC_VERSION 2>/dev/null || echo unknown)" +fi + +. "$SERVER_DIR/bin/util.sh" +configure_riscv64_libatomic + +if [[ "$ACTUAL_ARCH" == "riscv64" ]]; then + EXPECTED_RISCV64_JAVA_VERSION=${EXPECTED_RISCV64_JAVA_VERSION:-11.0.31.28} + if [[ "$JAVA_VERSION" != "$EXPECTED_RISCV64_JAVA_VERSION" ]]; then + echo "Expected RISC-V Java $EXPECTED_RISCV64_JAVA_VERSION, got $JAVA_VERSION" >&2 + exit 1 + fi + if [[ "$JAVA_VM_NAME" != "OpenJDK 64-Bit Server VM" ]]; then + echo "Expected RISC-V Server VM, got $JAVA_VM_NAME" >&2 + exit 1 + fi + if [[ "$JAVA_VM_VENDOR" != "Alibaba" ]]; then + echo "Expected RISC-V Java vendor Alibaba, got $JAVA_VM_VENDOR" >&2 + exit 1 + fi + if [[ "$JAVA_VM_INFO" != *"mixed mode"* ]]; then + echo "Expected RISC-V Java mixed mode, got $JAVA_VM_INFO" >&2 + exit 1 + fi + if [[ "${LD_PRELOAD:-}" != *"libatomic.so.1"* ]]; then + echo "libatomic.so.1 was not added to LD_PRELOAD on riscv64" >&2 + exit 1 + fi + echo "LD_PRELOAD: $LD_PRELOAD" +fi + +WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-rocksdb-jni-smoke.XXXXXX") +SMOKE_LOG="$WORK_DIR/rocksdb-jni-smoke.log" +export ROCKSDB_SMOKE_DIR="$WORK_DIR/db" + +cleanup() { + rm -rf "$WORK_DIR" +} +trap cleanup EXIT + +java -cp "$SERVER_DIR/lib/*" groovy.ui.GroovyMain \ + "$TRAVIS_DIR/rocksdb-jni-smoke.groovy" | tee "$SMOKE_LOG" + +if ! grep -q '^rocksdb-jni-smoke-ok$' "$SMOKE_LOG"; then + echo "RocksDB JNI smoke marker not found" >&2 + exit 1 +fi diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh new file mode 100755 index 0000000000..b71ab1fc0e --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh @@ -0,0 +1,183 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -euo pipefail + +if [[ $# -ne 3 || ( "$2" != "create" && "$2" != "verify" ) ]]; then + echo "USAGE: $0 SERVER_URL create|verify RUN_ID" >&2 + exit 1 +fi + +SERVER_URL=${1%/} +MODE=$2 +RUN_ID=$3 + +if [[ ! "$RUN_ID" =~ ^[a-zA-Z0-9_]+$ ]]; then + echo "RUN_ID must contain only letters, numbers, and underscores" >&2 + exit 1 +fi + +GRAPH_PATH=/graphspaces/DEFAULT/graphs/hugegraph +WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-server-smoke.XXXXXX") +RESPONSE_FILE="$WORK_DIR/response.json" +PROPERTY_KEY="riscv_smoke_name_$RUN_ID" +VERTEX_LABEL="riscv_smoke_node_$RUN_ID" +EDGE_LABEL="riscv_smoke_link_$RUN_ID" +VERTEX_ONE="riscv-smoke-v1-$RUN_ID" +VERTEX_TWO="riscv-smoke-v2-$RUN_ID" + +cleanup() { + rm -rf "$WORK_DIR" +} +trap cleanup EXIT + +for command in curl jq; do + if ! command -v "$command" >/dev/null 2>&1; then + echo "Required command is unavailable: $command" >&2 + exit 1 + fi +done + +if [[ -n "${HUGEGRAPH_USERNAME:-}" || -n "${HUGEGRAPH_PASSWORD:-}" ]]; then + if [[ -z "${HUGEGRAPH_USERNAME:-}" || -z "${HUGEGRAPH_PASSWORD:-}" ]]; then + echo "Set both HUGEGRAPH_USERNAME and HUGEGRAPH_PASSWORD" >&2 + exit 1 + fi +fi + +curl_request() { + if [[ -n "${HUGEGRAPH_USERNAME:-}" ]]; then + curl --compressed --user "$HUGEGRAPH_USERNAME:$HUGEGRAPH_PASSWORD" "$@" + else + curl --compressed "$@" + fi +} + +wait_for_server() { + local attempt + for attempt in $(seq 1 240); do + if curl_request --silent --show-error --fail \ + "$SERVER_URL/versions" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + echo "HugeGraph did not become ready at $SERVER_URL" >&2 + return 1 +} + +request() { + local method=$1 + local path=$2 + local expected_status=$3 + local body=${4:-} + local status + local curl_args=(--silent --show-error --output "$RESPONSE_FILE" \ + --write-out '%{http_code}' --request "$method" \ + --header 'Content-Type: application/json') + + if [[ -n "$body" ]]; then + curl_args+=(--data "$body") + fi + status=$(curl_request "${curl_args[@]}" "$SERVER_URL$path") + if [[ "$status" != "$expected_status" ]]; then + echo "$method $path returned HTTP $status, expected $expected_status" >&2 + cat "$RESPONSE_FILE" >&2 + return 1 + fi +} + +assert_json() { + local expression=$1 + shift + if ! jq --exit-status "$@" "$expression" "$RESPONSE_FILE" >/dev/null; then + echo "JSON assertion failed: $expression" >&2 + cat "$RESPONSE_FILE" >&2 + return 1 + fi +} + +verify_graph() { + request GET "$GRAPH_PATH/graph/vertices/%22$VERTEX_ONE%22" 200 + assert_json '.id == $id and .label == $label and .properties[$key] == "first"' \ + --arg id "$VERTEX_ONE" --arg label "$VERTEX_LABEL" \ + --arg key "$PROPERTY_KEY" + + request GET "$GRAPH_PATH/graph/vertices/%22$VERTEX_TWO%22" 200 + assert_json '.id == $id and .label == $label and .properties[$key] == "second"' \ + --arg id "$VERTEX_TWO" --arg label "$VERTEX_LABEL" \ + --arg key "$PROPERTY_KEY" + + request GET "$GRAPH_PATH/graph/edges" 200 + assert_json '.edges | any(.label == $label and .outV == $out and .inV == $in)' \ + --arg label "$EDGE_LABEL" --arg out "$VERTEX_ONE" \ + --arg in "$VERTEX_TWO" + + request POST /gremlin 200 \ + "$(jq -cn --arg query "g.V().hasLabel('$VERTEX_LABEL').count()" \ + '{gremlin:$query, bindings:{}, language:"gremlin-groovy", + aliases:{g:"__g_DEFAULT-hugegraph"}}')" + assert_json '.result.data == [2]' +} + +wait_for_server +request GET /versions 200 +assert_json 'type == "object" and length > 0' + +if [[ "$MODE" == "create" ]]; then + request POST "$GRAPH_PATH/schema/propertykeys" 202 \ + "$(jq -cn --arg name "$PROPERTY_KEY" \ + '{name:$name, data_type:"TEXT", cardinality:"SINGLE", properties:[]}')" + assert_json '.property_key.name == $name and .task_id == 0' \ + --arg name "$PROPERTY_KEY" + + request POST "$GRAPH_PATH/schema/vertexlabels" 201 \ + "$(jq -cn --arg name "$VERTEX_LABEL" --arg key "$PROPERTY_KEY" \ + '{name:$name, id_strategy:"CUSTOMIZE_STRING", properties:[$key], + primary_keys:[], nullable_keys:[]}')" + assert_json '.name == $name' --arg name "$VERTEX_LABEL" + + request POST "$GRAPH_PATH/schema/edgelabels" 201 \ + "$(jq -cn --arg name "$EDGE_LABEL" --arg label "$VERTEX_LABEL" \ + '{name:$name, source_label:$label, target_label:$label, + frequency:"SINGLE", properties:[], sort_keys:[], nullable_keys:[]}')" + assert_json '.name == $name' --arg name "$EDGE_LABEL" + + request POST "$GRAPH_PATH/graph/vertices" 201 \ + "$(jq -cn --arg id "$VERTEX_ONE" --arg label "$VERTEX_LABEL" \ + --arg key "$PROPERTY_KEY" \ + '{id:$id, label:$label, properties:{($key):"first"}}')" + assert_json '.id == $id' --arg id "$VERTEX_ONE" + + request POST "$GRAPH_PATH/graph/vertices" 201 \ + "$(jq -cn --arg id "$VERTEX_TWO" --arg label "$VERTEX_LABEL" \ + --arg key "$PROPERTY_KEY" \ + '{id:$id, label:$label, properties:{($key):"second"}}')" + assert_json '.id == $id' --arg id "$VERTEX_TWO" + + request POST "$GRAPH_PATH/graph/edges" 201 \ + "$(jq -cn --arg label "$EDGE_LABEL" --arg vertexLabel "$VERTEX_LABEL" \ + --arg out "$VERTEX_ONE" --arg in "$VERTEX_TWO" \ + '{label:$label, outVLabel:$vertexLabel, inVLabel:$vertexLabel, + outV:$out, inV:$in, properties:{}}')" + assert_json '.label == $label and .outV == $out and .inV == $in' \ + --arg label "$EDGE_LABEL" --arg out "$VERTEX_ONE" \ + --arg in "$VERTEX_TWO" +fi + +verify_graph +echo "server-e2e-smoke-$MODE-ok" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh index b7b70e8cc9..2e5c5bb9f8 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh @@ -24,6 +24,14 @@ JACOCO_PORT=$3 JACOCO_DIR=${TRAVIS_DIR} JACOCO_JAR=${JACOCO_DIR}/jacocoagent.jar +SERVER_STARTUP_TIMEOUT=${SERVER_STARTUP_TIMEOUT:-} + +if [[ -z "$SERVER_STARTUP_TIMEOUT" ]]; then + case "$(uname -m)" in + riscv64) SERVER_STARTUP_TIMEOUT=300 ;; + *) SERVER_STARTUP_TIMEOUT=60 ;; + esac +fi BIN=$BASE_DIR/bin CONF=$BASE_DIR/conf/graphs/hugegraph.properties @@ -95,4 +103,4 @@ if [ -n "$SERVER_JAVA_OPTIONS" ]; then fi echo -e "pa" | $BIN/init-store.sh -$BIN/start-hugegraph.sh -j "$JACOCO_OPTION" -t 60 +$BIN/start-hugegraph.sh -j "$JACOCO_OPTION" -t "$SERVER_STARTUP_TIMEOUT" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh index 2751757884..9e29fed63d 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh @@ -19,6 +19,5 @@ set -ev BASE_DIR=$1 BIN=$BASE_DIR/bin -VERSION=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` $BIN/stop-hugegraph.sh diff --git a/hugegraph-server/hugegraph-dist/src/main/resources/backend.properties b/hugegraph-server/hugegraph-dist/src/main/resources/backend.properties index 45060f90c2..119ee02441 100644 --- a/hugegraph-server/hugegraph-dist/src/main/resources/backend.properties +++ b/hugegraph-server/hugegraph-dist/src/main/resources/backend.properties @@ -15,4 +15,4 @@ # limitations under the License. # -backends=[rocksdb, hbase, hstore] +backends=[${hugegraph.backends}] diff --git a/hugegraph-server/hugegraph-test/pom.xml b/hugegraph-server/hugegraph-test/pom.xml index b3fc645f79..935184194f 100644 --- a/hugegraph-server/hugegraph-test/pom.xml +++ b/hugegraph-server/hugegraph-test/pom.xml @@ -45,36 +45,11 @@ hugegraph-api ${revision} - - org.apache.hugegraph - hugegraph-cassandra - ${revision} - - - org.apache.hugegraph - hugegraph-scylladb - ${revision} - org.apache.hugegraph hugegraph-rocksdb ${revision} - - org.apache.hugegraph - hugegraph-hbase - ${revision} - - - org.apache.hugegraph - hugegraph-mysql - ${revision} - - - org.apache.hugegraph - hugegraph-postgresql - ${revision} - org.apache.hugegraph hugegraph-dist @@ -308,6 +283,64 @@ + + all-backends + + + !rocksdb-only + + + + + org.apache.hugegraph + hugegraph-cassandra + ${revision} + + + org.apache.hugegraph + hugegraph-scylladb + ${revision} + + + org.apache.hugegraph + hugegraph-hbase + ${revision} + + + org.apache.hugegraph + hugegraph-mysql + ${revision} + + + org.apache.hugegraph + hugegraph-postgresql + ${revision} + + + + + rocksdb-only + + + rocksdb-only + + + + + + maven-compiler-plugin + + + + org/apache/hugegraph/unit/cassandra/** + org/apache/hugegraph/unit/mysql/** + org/apache/hugegraph/unit/UnitTestSuite.java + + + + + + memory diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java index 9e82692689..dffd443fab 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java @@ -53,6 +53,8 @@ public class TaskCoreTest extends BaseCoreTest { + private static final long GREMLIN_JOB_TIMEOUT = 30L; + @Before @Override public void setup() { @@ -112,6 +114,29 @@ private static void waitUntilTaskRunning(TaskScheduler scheduler) { Assert.fail("Timed out waiting for task to start running"); } + private static void waitUntilTaskProgress(TaskScheduler scheduler, Id id, + int expectedProgress, + long timeoutSeconds) { + long deadline = System.nanoTime() + + TimeUnit.SECONDS.toNanos(timeoutSeconds); + do { + HugeTask task = scheduler.task(id); + if (task.progress() >= expectedProgress) { + return; + } + if (task.completed()) { + Assert.fail(String.format( + "Task '%s' completed at progress %s before " + + "reaching progress %s", + id, task.progress(), expectedProgress)); + } + sleepAWhile(100L); + } while (System.nanoTime() < deadline); + Assert.fail(String.format( + "Timed out waiting for task '%s' to reach progress %s", + id, expectedProgress)); + } + private static void deleteTaskAndWaitGone(TaskScheduler scheduler, Id id) { for (int pass = 0; pass < 30; pass++) { try { @@ -669,7 +694,8 @@ public void testGremlinJobWithScript() throws TimeoutException { "}"; HugeTask task = runGremlinJob(script); - task = scheduler.waitUntilTaskCompleted(task.id(), 10); + task = scheduler.waitUntilTaskCompleted(task.id(), + GREMLIN_JOB_TIMEOUT); Assert.assertEquals("test-gremlin-job", task.name()); Assert.assertEquals("gremlin", task.type()); Assert.assertEquals(TaskStatus.SUCCESS, task.status()); @@ -974,7 +1000,8 @@ public void testGremlinJobAndCancel() throws TimeoutException { // Cancel success task HugeTask task2 = runGremlinJob("1+2"); - task2 = scheduler.waitUntilTaskCompleted(task2.id(), 10); + task2 = scheduler.waitUntilTaskCompleted(task2.id(), + GREMLIN_JOB_TIMEOUT); Assert.assertEquals(TaskStatus.SUCCESS, task2.status()); scheduler.cancel(task2); task2 = scheduler.task(task2.id()); @@ -1007,7 +1034,8 @@ public void testGremlinJobAndCancel() throws TimeoutException { "};" + "rs;"; HugeTask task4 = runGremlinJob(bigResults); - task4 = scheduler.waitUntilTaskCompleted(task4.id(), 10); + task4 = scheduler.waitUntilTaskCompleted(task4.id(), + GREMLIN_JOB_TIMEOUT); Assert.assertEquals(TaskStatus.FAILED, task4.status()); scheduler.cancel(task4); task4 = scheduler.task(task4.id()); @@ -1031,7 +1059,8 @@ public void testGremlinJobAndRestore() throws Exception { "}; 100;"; HugeTask task = runGremlinJob(gremlin); - sleepAWhile(200 * 6); + waitUntilTaskProgress(scheduler, task.id(), 1, + GREMLIN_JOB_TIMEOUT); task = scheduler.task(task.id()); scheduler.cancel(task); diff --git a/hugegraph-server/pom.xml b/hugegraph-server/pom.xml index 226199cdc8..16c3f188c7 100644 --- a/hugegraph-server/pom.xml +++ b/hugegraph-server/pom.xml @@ -61,17 +61,9 @@ hugegraph-core hugegraph-api - hugegraph-example hugegraph-dist hugegraph-test - hugegraph-cassandra - hugegraph-scylladb hugegraph-rocksdb - hugegraph-mysql - hugegraph-palo - hugegraph-hbase - hugegraph-postgresql - hugegraph-hstore @@ -355,6 +347,24 @@ + + all-backends + + + !rocksdb-only + + + + hugegraph-example + hugegraph-cassandra + hugegraph-scylladb + hugegraph-mysql + hugegraph-palo + hugegraph-hbase + hugegraph-postgresql + hugegraph-hstore + + core-test diff --git a/pom.xml b/pom.xml index 045a24ad56..5b8952110c 100644 --- a/pom.xml +++ b/pom.xml @@ -99,11 +99,7 @@ hugegraph-server - hugegraph-pd - hugegraph-store hugegraph-commons - install-dist - hugegraph-cluster-test hugegraph-struct @@ -322,6 +318,35 @@ + + all-modules + + + !rocksdb-only + + + + hugegraph-pd + hugegraph-store + install-dist + hugegraph-cluster-test + + + + rocksdb-only + + + rocksdb-only + + + + + hugegraph-pd/hg-pd-grpc + hugegraph-pd/hg-pd-common + hugegraph-pd/hg-pd-client + hugegraph-store/hg-store-common + + apache-release From 5972a6f5322f89191cae84de233c6effed88fd94 Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Wed, 22 Jul 2026 15:24:12 +0800 Subject: [PATCH 02/10] fix(server): stabilize RISC-V validation --- .github/workflows/docker-build-ci.yml | 67 +++++++++++++++++-- .../src/assembly/travis/build-report.sh | 13 ++-- .../src/assembly/travis/run-api-test.sh | 24 ++++--- .../src/assembly/travis/run-core-test.sh | 15 +++-- .../travis/run-docker-runtime-smoke-test.sh | 8 +-- .../travis/run-rocksdb-jni-smoke-test.sh | 19 ++++-- .../travis/run-server-e2e-smoke-test.sh | 12 +++- .../apache/hugegraph/core/TaskCoreTest.java | 26 +++---- 8 files changed, 137 insertions(+), 47 deletions(-) diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index 5a45bad731..eb92d8c8e3 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -17,6 +17,10 @@ name: "Docker Build CI" +env: + BINFMT_IMAGE: >- + tonistiigi/binfmt@sha256:400a4873b838d1b89194d982c45e5fb3cda4593fbfd7e08a02e76b03b21166f0 + on: push: branches: @@ -64,7 +68,7 @@ jobs: server-runtime-smoke: runs-on: ubuntu-24.04 - timeout-minutes: 45 + timeout-minutes: ${{ matrix.arch == 'riscv64' && 90 || 45 }} strategy: fail-fast: false matrix: @@ -74,14 +78,19 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Set up QEMU + - name: Set up emulation if: matrix.arch != 'amd64' - uses: docker/setup-qemu-action@v3 - with: - platforms: ${{ matrix.arch }} + run: | + docker run --privileged --rm "$BINFMT_IMAGE" \ + --install "${{ matrix.arch }}" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + run: | + BUILDER_NAME="hugegraph-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${{ matrix.arch }}" + echo "BUILDER_NAME=$BUILDER_NAME" >> "$GITHUB_ENV" + docker buildx create --name "$BUILDER_NAME" \ + --driver docker-container --use + docker buildx inspect --bootstrap - name: Build HugeGraph Server for linux/${{ matrix.arch }} run: | @@ -101,3 +110,49 @@ jobs: [[ "$HC" != "null" ]] || { echo "ERROR: HEALTHCHECK missing"; exit 1; } hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh \ "$IMAGE" "$ARCH" + + - name: Verify native RISC-V Maven build + if: matrix.arch == 'riscv64' + env: + IMAGE: hugegraph-server-smoke:riscv64 + run: | + CONTAINER_NAME="hugegraph-riscv64-maven-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + cleanup() { + docker rm --force --volumes "$CONTAINER_NAME" >/dev/null 2>&1 || true + } + trap cleanup EXIT + + docker run --detach --platform linux/riscv64 \ + --name "$CONTAINER_NAME" --entrypoint sleep "$IMAGE" infinity + docker exec "$CONTAINER_NAME" mkdir -p /workspace + git ls-files -z | tar --null --files-from=- -cf - | \ + docker exec -i "$CONTAINER_NAME" tar -xf - -C /workspace + + docker exec "$CONTAINER_NAME" bash -euo pipefail -c ' + test "$(uname -m)" = riscv64 + apt-get -q update + apt-get -q install -y --no-install-recommends \ + maven protobuf-compiler protobuf-compiler-grpc-java-plugin + java -version + test -x /usr/bin/protoc + test -x /usr/bin/grpc_java_plugin + # Limit JIT work for the QEMU build; runtime smoke uses the default JVM. + export MAVEN_OPTS="-XX:TieredStopAtLevel=1 -XX:ActiveProcessorCount=2" + cd /workspace + mvn clean package -B -ntp -Drocksdb-only \ + -P riscv64-protobuf-tools \ + -pl hugegraph-server/hugegraph-dist -am \ + -Dmaven.test.skip=true -Dmaven.javadoc.skip=true + hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ + hugegraph-server/apache-hugegraph-server-*/ + ' + + - name: Clean up Docker resources + if: always() + env: + IMAGE: hugegraph-server-smoke:${{ matrix.arch }} + run: | + docker image rm "$IMAGE" >/dev/null 2>&1 || true + if [[ -n "${BUILDER_NAME:-}" ]]; then + docker buildx rm "$BUILDER_NAME" >/dev/null 2>&1 || true + fi diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh index d38ca0d661..9ffd47c970 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh @@ -20,12 +20,12 @@ set -ev BACKEND=$1 JACOCO_PORT=$2 JACOCO_REPORT_FILE=$3 -MAVEN_SCOPE_ARGS=() +ROCKSDB_ONLY=false if [[ "$BACKEND" == "rocksdb" && "$(uname -s)" == "Linux" && "$(uname -m)" == "riscv64" ]]; then - MAVEN_SCOPE_ARGS+=("-Drocksdb-only") + ROCKSDB_ONLY=true fi TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) @@ -65,8 +65,13 @@ esac mkdir -p "$(dirname "$REPORT_FILE")" cd "$REPO_ROOT/hugegraph-server/hugegraph-test" -mvn jacoco:dump@pull-test-data -Dapp.host=localhost -Dapp.port=$JACOCO_PORT \ - -Dskip.dump=false "${MAVEN_SCOPE_ARGS[@]}" +if [[ "$ROCKSDB_ONLY" == "true" ]]; then + mvn jacoco:dump@pull-test-data -Dapp.host=localhost \ + -Dapp.port=$JACOCO_PORT -Dskip.dump=false -Drocksdb-only +else + mvn jacoco:dump@pull-test-data -Dapp.host=localhost \ + -Dapp.port=$JACOCO_PORT -Dskip.dump=false +fi cd "$REPO_ROOT/hugegraph-server" if [[ ! -e "${TRAVIS_DIR}/jacococli.jar" ]]; then diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh index c960e46f27..c2b6252500 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -set -euo pipefail +set -ev BACKEND=$1 REPORT_DIR=$2 @@ -58,7 +58,6 @@ function download_to_dir() { cd "$REPO_ROOT" -MAVEN_SCOPE_ARGS=() ROCKSDB_ONLY=false if [[ "$BACKEND" == "rocksdb" && @@ -66,12 +65,15 @@ if [[ "$BACKEND" == "rocksdb" && "$(uname -m)" == "riscv64" ]]; then . "$TRAVIS_DIR/../static/bin/util.sh" configure_riscv64_libatomic - MAVEN_SCOPE_ARGS+=("-Drocksdb-only") ROCKSDB_ONLY=true fi -VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout \ - "${MAVEN_SCOPE_ARGS[@]}") +if [[ "$ROCKSDB_ONLY" == "true" ]]; then + VERSION=$(mvn help:evaluate -Dexpression=project.version -q \ + -DforceStdout -Drocksdb-only) +else + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) +fi SERVER_DIR=hugegraph-server/apache-hugegraph-server-$VERSION/ CONF=$SERVER_DIR/conf/graphs/hugegraph.properties REST_SERVER_CONF=$SERVER_DIR/conf/rest-server.properties @@ -96,7 +98,7 @@ trap cleanup EXIT if [[ "$ROCKSDB_ONLY" == "true" ]]; then mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -ntp \ - -pl hugegraph-server/hugegraph-dist -am "${MAVEN_SCOPE_ARGS[@]}" + -pl hugegraph-server/hugegraph-dist -am -Drocksdb-only else mvn package -Dmaven.test.skip=true -ntp fi @@ -138,8 +140,14 @@ SERVER_START_ATTEMPTED=true $TRAVIS_DIR/start-server.sh $SERVER_DIR $BACKEND $JACOCO_PORT || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) # run api-test -mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND \ - "${MAVEN_SCOPE_ARGS[@]}" || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) +if [[ "$ROCKSDB_ONLY" == "true" ]]; then + mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND \ + -Drocksdb-only || \ + (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) +else + mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND || \ + (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) +fi if [ "$RUN_GREMLIN_CONSOLE_SMOKE_TEST" == "true" ]; then bash "$TRAVIS_DIR/run-gremlin-console-smoke-test.sh" "$SERVER_DIR" || \ diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh index 412d94a1da..7463cc4417 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh @@ -15,21 +15,22 @@ # See the License for the specific language governing permissions and # limitations under the License. # -set -euo pipefail +set -ev BACKEND=$1 TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) -MAVEN_SCOPE_ARGS=() if [[ "$BACKEND" == "rocksdb" && "$(uname -s)" == "Linux" && "$(uname -m)" == "riscv64" ]]; then . "$TRAVIS_DIR/../static/bin/util.sh" configure_riscv64_libatomic - MAVEN_SCOPE_ARGS+=("-Drocksdb-only") + cd "$REPO_ROOT" + mvn test -pl hugegraph-server/hugegraph-test -am \ + -P core-test,"$BACKEND" -Drocksdb-only +else + cd "$REPO_ROOT" + mvn test -pl hugegraph-server/hugegraph-test -am \ + -P core-test,"$BACKEND" fi - -cd "$REPO_ROOT" -mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,"$BACKEND" \ - "${MAVEN_SCOPE_ARGS[@]}" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh index 2ca13f646d..618ce68660 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh @@ -105,9 +105,9 @@ update_server_url() { } wait_for_container_server() { - local attempt + local deadline=$((SECONDS + CONTAINER_READY_TIMEOUT)) local running - for attempt in $(seq 1 "$CONTAINER_READY_TIMEOUT"); do + while ((SECONDS < deadline)); do running=$(docker inspect --format '{{.State.Running}}' "$CONTAINER_NAME") if [[ "$running" != "true" ]]; then echo "HugeGraph container exited before becoming ready" >&2 @@ -115,6 +115,7 @@ wait_for_container_server() { return 1 fi if curl --silent --show-error --fail \ + --connect-timeout 3 --max-time 5 \ "$SERVER_URL/versions" >/dev/null 2>&1; then return 0 fi @@ -126,9 +127,8 @@ wait_for_container_server() { } wait_for_container_health() { - local attempt local health - for attempt in $(seq 1 60); do + for _ in $(seq 1 60); do health=$(docker inspect --format \ '{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}' \ "$CONTAINER_NAME") diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh index 1693065e91..5603431d5d 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-rocksdb-jni-smoke-test.sh @@ -28,12 +28,23 @@ EXPECTED_ARCH=${EXPECTED_ARCH:-} EXPECTED_JAVA_MAJOR=${EXPECTED_JAVA_MAJOR:-11} ACTUAL_ARCH=$(uname -m) +if [[ -n "${JAVA_HOME:-}" ]]; then + JAVA_CMD="$JAVA_HOME/bin/java" +else + JAVA_CMD=$(command -v java || true) +fi +if [[ -z "$JAVA_CMD" || ! -x "$JAVA_CMD" ]]; then + echo "Java executable is unavailable: ${JAVA_CMD:-not found}" >&2 + exit 1 +fi + if [[ -n "$EXPECTED_ARCH" && "$ACTUAL_ARCH" != "$EXPECTED_ARCH" ]]; then echo "Expected architecture $EXPECTED_ARCH, got $ACTUAL_ARCH" >&2 exit 1 fi -JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2; exit}') +JAVA_VERSION=$("$JAVA_CMD" -version 2>&1 | \ + awk -F '"' '/version/ {print $2; exit}') JAVA_MAJOR=${JAVA_VERSION%%.*} if [[ "$JAVA_MAJOR" == "1" ]]; then JAVA_MAJOR=$(echo "$JAVA_VERSION" | cut -d. -f2) @@ -43,7 +54,7 @@ if [[ "$JAVA_MAJOR" != "$EXPECTED_JAVA_MAJOR" ]]; then exit 1 fi -JAVA_PROPERTIES=$(java -XshowSettings:properties -version 2>&1) +JAVA_PROPERTIES=$("$JAVA_CMD" -XshowSettings:properties -version 2>&1) java_property() { local key=$1 awk -F ' = ' -v key="$key" '{ @@ -110,8 +121,8 @@ cleanup() { } trap cleanup EXIT -java -cp "$SERVER_DIR/lib/*" groovy.ui.GroovyMain \ - "$TRAVIS_DIR/rocksdb-jni-smoke.groovy" | tee "$SMOKE_LOG" +"$JAVA_CMD" -cp "$SERVER_DIR/lib/*" groovy.ui.GroovyMain \ + "$TRAVIS_DIR/rocksdb-jni-smoke.groovy" | tee "$SMOKE_LOG" if ! grep -q '^rocksdb-jni-smoke-ok$' "$SMOKE_LOG"; then echo "RocksDB JNI smoke marker not found" >&2 diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh index b71ab1fc0e..9762e4fa26 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh @@ -39,6 +39,10 @@ VERTEX_LABEL="riscv_smoke_node_$RUN_ID" EDGE_LABEL="riscv_smoke_link_$RUN_ID" VERTEX_ONE="riscv-smoke-v1-$RUN_ID" VERTEX_TWO="riscv-smoke-v2-$RUN_ID" +CURL_CONNECT_TIMEOUT=3 +CURL_PROBE_TIMEOUT=5 +CURL_REQUEST_TIMEOUT=60 +SERVER_READY_TIMEOUT=240 cleanup() { rm -rf "$WORK_DIR" @@ -68,9 +72,11 @@ curl_request() { } wait_for_server() { - local attempt - for attempt in $(seq 1 240); do + local deadline=$((SECONDS + SERVER_READY_TIMEOUT)) + while ((SECONDS < deadline)); do if curl_request --silent --show-error --fail \ + --connect-timeout "$CURL_CONNECT_TIMEOUT" \ + --max-time "$CURL_PROBE_TIMEOUT" \ "$SERVER_URL/versions" >/dev/null 2>&1; then return 0 fi @@ -88,6 +94,8 @@ request() { local status local curl_args=(--silent --show-error --output "$RESPONSE_FILE" \ --write-out '%{http_code}' --request "$method" \ + --connect-timeout "$CURL_CONNECT_TIMEOUT" \ + --max-time "$CURL_REQUEST_TIMEOUT" \ --header 'Content-Type: application/json') if [[ -n "$body" ]]; then diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java index dffd443fab..91bcd3ac6e 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java @@ -114,27 +114,28 @@ private static void waitUntilTaskRunning(TaskScheduler scheduler) { Assert.fail("Timed out waiting for task to start running"); } - private static void waitUntilTaskProgress(TaskScheduler scheduler, Id id, - int expectedProgress, - long timeoutSeconds) { + private static HugeTask waitUntilTaskProgress( + TaskScheduler scheduler, Id id, int expectedProgress, + long timeoutSeconds) { long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSeconds); do { HugeTask task = scheduler.task(id); - if (task.progress() >= expectedProgress) { - return; - } if (task.completed()) { Assert.fail(String.format( "Task '%s' completed at progress %s before " + "reaching progress %s", id, task.progress(), expectedProgress)); } + if (task.progress() >= expectedProgress) { + return task; + } sleepAWhile(100L); } while (System.nanoTime() < deadline); Assert.fail(String.format( "Timed out waiting for task '%s' to reach progress %s", id, expectedProgress)); + return null; } private static void deleteTaskAndWaitGone(TaskScheduler scheduler, Id id) { @@ -1051,17 +1052,17 @@ public void testGremlinJobAndRestore() throws Exception { HugeGraph graph = graph(); TaskScheduler scheduler = graph.taskScheduler(); - String gremlin = "println('task start');" + + String gremlin = "gremlinJob.setMinSaveInterval(1);" + + "println('task start');" + "for(int i=gremlinJob.progress(); i<=10; i++) {" + " gremlinJob.updateProgress(i);" + - " Thread.sleep(200); " + + " Thread.sleep(1000); " + " println('sleep=>'+i);" + "}; 100;"; HugeTask task = runGremlinJob(gremlin); - waitUntilTaskProgress(scheduler, task.id(), 1, - GREMLIN_JOB_TIMEOUT); - task = scheduler.task(task.id()); + task = waitUntilTaskProgress(scheduler, task.id(), 1, + GREMLIN_JOB_TIMEOUT); scheduler.cancel(task); task = scheduler.task(task.id()); @@ -1104,7 +1105,8 @@ public void testGremlinJobAndRestore() throws Exception { }, e -> { Assert.assertContains("is already in the queue", e.getMessage()); }); - scheduler.waitUntilTaskCompleted(task2.id(), 10); + scheduler.waitUntilTaskCompleted(task2.id(), + GREMLIN_JOB_TIMEOUT); sleepAWhile(500); Assert.assertEquals(10, task2.progress()); Assert.assertEquals(1, task2.retries()); From 3e6f4d8d7b8a4734e32325128ed1adf4763e1b2b Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Wed, 22 Jul 2026 22:12:15 +0800 Subject: [PATCH 03/10] fix(server): propagate shutdown failures --- .../src/assembly/static/bin/stop-hugegraph.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/stop-hugegraph.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/stop-hugegraph.sh index 7407746348..c63035e072 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/stop-hugegraph.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/stop-hugegraph.sh @@ -63,6 +63,8 @@ fi PID=$(cat $PID_FILE) -if kill_process_and_wait "HugeGraphServer" "$PID" "$SERVER_SHUTDOWN_TIMEOUT_S"; then - rm "$PID_FILE" +if ! kill_process_and_wait "HugeGraphServer" "$PID" "$SERVER_SHUTDOWN_TIMEOUT_S"; then + exit 1 fi + +rm "$PID_FILE" From e2189b328bdaeae06e3b725dd35fdcdf7aadf49e Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Thu, 23 Jul 2026 13:57:06 +0800 Subject: [PATCH 04/10] fix(server): preserve default test coverage --- .github/workflows/docker-build-ci.yml | 7 +- .github/workflows/server-ci.yml | 5 + hugegraph-server/README.md | 10 +- .../travis/check-default-maven-profiles.sh | 124 ++++++++++++++++++ .../src/assembly/travis/run-api-test.sh | 13 +- hugegraph-server/hugegraph-test/pom.xml | 8 +- hugegraph-server/pom.xml | 26 ++-- 7 files changed, 161 insertions(+), 32 deletions(-) create mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index eb92d8c8e3..d535d1bafe 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -32,10 +32,11 @@ on: - '.dockerignore' - '.github/workflows/docker-build-ci.yml' - 'pom.xml' - - 'hugegraph-pd/hg-pd-grpc/pom.xml' + - 'hugegraph-pd/hg-pd-grpc/**' - 'hugegraph-server/pom.xml' - 'hugegraph-server/hugegraph-core/pom.xml' - - 'hugegraph-server/hugegraph-rocksdb/pom.xml' + - 'hugegraph-server/hugegraph-core/src/main/resources/proto/**' + - 'hugegraph-server/hugegraph-rocksdb/**' - 'hugegraph-server/hugegraph-dist/pom.xml' - 'hugegraph-server/hugegraph-dist/docker/**' - 'hugegraph-server/hugegraph-dist/src/main/resources/backend.properties' @@ -77,6 +78,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up emulation if: matrix.arch != 'amd64' diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index 586e36da49..6a316c1db0 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -66,6 +66,11 @@ jobs: cp $HOME/.m2/settings.xml /tmp/settings.xml cp -vf .github/configs/settings.xml $HOME/.m2/settings.xml && cat $HOME/.m2/settings.xml + - name: Check default Maven profiles + if: ${{ env.BACKEND == 'memory' }} + run: | + "$TRAVIS_DIR/check-default-maven-profiles.sh" + - name: Compile run: | mvn clean compile -U -Dmaven.javadoc.skip=true -ntp diff --git a/hugegraph-server/README.md b/hugegraph-server/README.md index 0fed69f69c..dad2be2a78 100644 --- a/hugegraph-server/README.md +++ b/hugegraph-server/README.md @@ -50,7 +50,8 @@ it is not already registered: docker run --privileged --rm tonistiigi/binfmt --install riscv64 ``` -From the repository root, build and run the complete runtime smoke test: +The smoke helper requires Docker Buildx, `curl`, and `jq` on the host. From the repository +root, build and run the complete runtime smoke test: ```bash IMAGE=hugegraph-server:riscv64-test @@ -62,11 +63,10 @@ docker image rm "$IMAGE" ``` The smoke helper removes its test containers, anonymous volumes, and temporary files. It -keeps the input image and does not create or remove a Buildx builder or host emulator. If -you created those resources specifically for this test, remove them separately: +keeps the input image, uses the current Buildx builder, and does not remove the host +emulator. If you registered the emulator specifically for this test, remove it separately: ```bash -docker buildx rm hugegraph-riscv64 docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-riscv64 ``` @@ -89,7 +89,7 @@ After selecting Dragonwell as `JAVA_HOME`, build and verify the RocksDB-only dis ```bash test "$(uname -m)" = riscv64 -java -XshowSettings:vm -version +"$JAVA_HOME/bin/java" -XshowSettings:vm -version mvn clean package -Drocksdb-only -pl hugegraph-server/hugegraph-dist -am \ -Dmaven.test.skip=true -Dmaven.javadoc.skip=true hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh new file mode 100755 index 0000000000..f291d97809 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh @@ -0,0 +1,124 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -euo pipefail + +TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) +REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) +TEST_MODULE=hugegraph-server/hugegraph-test +WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-maven-profile-check.XXXXXX") + +cleanup() { + rm -rf "$WORK_DIR" +} +trap cleanup EXIT + +cd "$REPO_ROOT" + +DEFAULT_PROFILES="$WORK_DIR/default-profiles.txt" +ROCKSDB_ONLY_PROFILES="$WORK_DIR/rocksdb-only-profiles.txt" + +mvn help:active-profiles -pl "$TEST_MODULE" -ntp -Dstyle.color=never \ + > "$DEFAULT_PROFILES" +mvn help:active-profiles -pl "$TEST_MODULE" -Drocksdb-only -ntp \ + -Dstyle.color=never > "$ROCKSDB_ONLY_PROFILES" + +require_active_profile() { + local profile=$1 + local profiles_file=$2 + if ! grep -Eq "^[[:space:]]*-[[:space:]]+${profile}[[:space:]]+\\(source:" \ + "$profiles_file"; then + echo "Required Maven profile is inactive: $profile" >&2 + cat "$profiles_file" >&2 + exit 1 + fi +} + +require_inactive_profile() { + local profile=$1 + local profiles_file=$2 + if grep -Eq "^[[:space:]]*-[[:space:]]+${profile}[[:space:]]+\\(source:" \ + "$profiles_file"; then + echo "Maven profile should be inactive: $profile" >&2 + cat "$profiles_file" >&2 + exit 1 + fi +} + +for profile in core-test all-backends memory; do + require_active_profile "$profile" "$DEFAULT_PROFILES" +done + +for profile in core-test rocksdb-only; do + require_active_profile "$profile" "$ROCKSDB_ONLY_PROFILES" +done +for profile in all-backends memory; do + require_inactive_profile "$profile" "$ROCKSDB_ONLY_PROFILES" +done + +DEFAULT_POM="$WORK_DIR/default-effective-pom.xml" +ROCKSDB_POM="$WORK_DIR/rocksdb-effective-pom.xml" +mvn help:effective-pom -pl "$TEST_MODULE" -ntp -Dstyle.color=never \ + -Doutput="$DEFAULT_POM" +mvn help:effective-pom -pl "$TEST_MODULE" -P rocksdb -ntp \ + -Dstyle.color=never -Doutput="$ROCKSDB_POM" + +DEFAULT_MODEL=$(awk '/^[[:space:]]*/{exit} {print}' "$DEFAULT_POM") +ROCKSDB_MODEL=$(awk '/^[[:space:]]*/{exit} {print}' "$ROCKSDB_POM") +CORE_EXECUTION=$(awk ' + // { + in_execution = 1 + block = $0 + next + } + in_execution { + block = block "\n" $0 + } + in_execution && /<\/execution>/ { + if (block ~ /core-test<\/id>/) { + print block + exit + } + in_execution = 0 + block = "" + } +' "$DEFAULT_POM") + +for expected in 'memory' \ + 'text'; do + grep -Fq "$expected" <<< "$DEFAULT_MODEL" || { + echo "Default test configuration is missing: $expected" >&2 + exit 1 + } +done + +for expected in 'test' 'test'; do + grep -Fq "$expected" <<< "$CORE_EXECUTION" || { + echo "Default Core Surefire execution is missing: $expected" >&2 + exit 1 + } +done + +for expected in 'rocksdb' \ + 'binary'; do + grep -Fq "$expected" <<< "$ROCKSDB_MODEL" || { + echo "Explicit RocksDB configuration is missing: $expected" >&2 + exit 1 + } +done + +echo "Default and explicit Maven test profiles are valid" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh index c2b6252500..fafd8d5ba6 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh @@ -137,16 +137,17 @@ authentication: { # start server SERVER_START_ATTEMPTED=true -$TRAVIS_DIR/start-server.sh $SERVER_DIR $BACKEND $JACOCO_PORT || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) +"$TRAVIS_DIR/start-server.sh" "$SERVER_DIR" "$BACKEND" "$JACOCO_PORT" || \ + (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) # run api-test if [[ "$ROCKSDB_ONLY" == "true" ]]; then - mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND \ + mvn test -pl hugegraph-server/hugegraph-test -am -P "api-test,$BACKEND" \ -Drocksdb-only || \ - (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) + (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) else - mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND || \ - (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) + mvn test -pl hugegraph-server/hugegraph-test -am -P "api-test,$BACKEND" || \ + (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) fi if [ "$RUN_GREMLIN_CONSOLE_SMOKE_TEST" == "true" ]; then @@ -154,4 +155,4 @@ if [ "$RUN_GREMLIN_CONSOLE_SMOKE_TEST" == "true" ]; then (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) fi -$TRAVIS_DIR/build-report.sh $BACKEND $JACOCO_PORT $REPORT_FILE +"$TRAVIS_DIR/build-report.sh" "$BACKEND" "$JACOCO_PORT" "$REPORT_FILE" diff --git a/hugegraph-server/hugegraph-test/pom.xml b/hugegraph-server/hugegraph-test/pom.xml index 935184194f..ca77a27601 100644 --- a/hugegraph-server/hugegraph-test/pom.xml +++ b/hugegraph-server/hugegraph-test/pom.xml @@ -325,6 +325,10 @@ rocksdb-only + + rocksdb + binary + @@ -344,7 +348,9 @@ memory - true + + !rocksdb-only + memory diff --git a/hugegraph-server/pom.xml b/hugegraph-server/pom.xml index 16c3f188c7..226199cdc8 100644 --- a/hugegraph-server/pom.xml +++ b/hugegraph-server/pom.xml @@ -61,9 +61,17 @@ hugegraph-core hugegraph-api + hugegraph-example hugegraph-dist hugegraph-test + hugegraph-cassandra + hugegraph-scylladb hugegraph-rocksdb + hugegraph-mysql + hugegraph-palo + hugegraph-hbase + hugegraph-postgresql + hugegraph-hstore @@ -347,24 +355,6 @@ - - all-backends - - - !rocksdb-only - - - - hugegraph-example - hugegraph-cassandra - hugegraph-scylladb - hugegraph-mysql - hugegraph-palo - hugegraph-hbase - hugegraph-postgresql - hugegraph-hstore - - core-test From 6227b2b9b0b1c4aef3cc12fc532ed799c4952b1a Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Thu, 23 Jul 2026 15:14:32 +0800 Subject: [PATCH 05/10] fix(ci): isolate RISC-V server validation Restore the existing Docker and default test paths unchanged. Run the native RocksDB-only build and runtime smoke in a dedicated QEMU job. --- .dockerignore | 2 +- .github/workflows/docker-build-ci.yml | 111 +---------- .github/workflows/riscv64-ci.yml | 164 ++++++++++++++++ .github/workflows/server-ci.yml | 5 - hugegraph-server/Dockerfile | 69 ++----- hugegraph-server/README.md | 64 ++----- .../docker/docker-entrypoint.sh | 3 +- .../src/assembly/travis/build-report.sh | 15 +- .../travis/check-default-maven-profiles.sh | 124 ------------ .../src/assembly/travis/run-api-test.sh | 68 +------ .../src/assembly/travis/run-core-test.sh | 16 +- .../travis/run-docker-runtime-smoke-test.sh | 176 ------------------ .../travis/run-native-runtime-smoke-test.sh | 15 +- .../src/assembly/travis/start-server.sh | 10 +- .../src/assembly/travis/stop-server.sh | 1 + hugegraph-server/hugegraph-test/pom.xml | 91 +++------ .../apache/hugegraph/core/TaskCoreTest.java | 47 +---- 17 files changed, 253 insertions(+), 728 deletions(-) create mode 100644 .github/workflows/riscv64-ci.yml delete mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh delete mode 100755 hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh diff --git a/.dockerignore b/.dockerignore index a6ae8a3fce..ee61478a15 100644 --- a/.dockerignore +++ b/.dockerignore @@ -21,7 +21,7 @@ **/target/ # Pre-extracted release dirs / archives -**/apache-hugegraph-*/ +apache-hugegraph-*/ **/*.tar **/*.tar.gz **/*.zip diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index d535d1bafe..8d31ff266f 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -17,10 +17,6 @@ name: "Docker Build CI" -env: - BINFMT_IMAGE: >- - tonistiigi/binfmt@sha256:400a4873b838d1b89194d982c45e5fb3cda4593fbfd7e08a02e76b03b21166f0 - on: push: branches: @@ -30,19 +26,6 @@ on: paths: - '**/Dockerfile*' - '.dockerignore' - - '.github/workflows/docker-build-ci.yml' - - 'pom.xml' - - 'hugegraph-pd/hg-pd-grpc/**' - - 'hugegraph-server/pom.xml' - - 'hugegraph-server/hugegraph-core/pom.xml' - - 'hugegraph-server/hugegraph-core/src/main/resources/proto/**' - - 'hugegraph-server/hugegraph-rocksdb/**' - - 'hugegraph-server/hugegraph-dist/pom.xml' - - 'hugegraph-server/hugegraph-dist/docker/**' - - 'hugegraph-server/hugegraph-dist/src/main/resources/backend.properties' - - 'hugegraph-server/hugegraph-dist/src/assembly/static/**' - - 'hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh' - - 'hugegraph-server/hugegraph-dist/src/assembly/travis/*smoke*' jobs: docker-build: @@ -53,6 +36,7 @@ jobs: dockerfile: - hugegraph-pd/Dockerfile - hugegraph-store/Dockerfile + - hugegraph-server/Dockerfile - hugegraph-server/Dockerfile-hstore steps: @@ -66,96 +50,3 @@ jobs: HC=$(docker inspect --format='{{json .Config.Healthcheck}}' "$IMAGE_ID") echo "Healthcheck: $HC" [[ "$HC" != "null" ]] || { echo "ERROR: HEALTHCHECK missing in ${{ matrix.dockerfile }}"; exit 1; } - - server-runtime-smoke: - runs-on: ubuntu-24.04 - timeout-minutes: ${{ matrix.arch == 'riscv64' && 90 || 45 }} - strategy: - fail-fast: false - matrix: - arch: [amd64, arm64, riscv64] - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Set up emulation - if: matrix.arch != 'amd64' - run: | - docker run --privileged --rm "$BINFMT_IMAGE" \ - --install "${{ matrix.arch }}" - - - name: Set up Docker Buildx - run: | - BUILDER_NAME="hugegraph-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${{ matrix.arch }}" - echo "BUILDER_NAME=$BUILDER_NAME" >> "$GITHUB_ENV" - docker buildx create --name "$BUILDER_NAME" \ - --driver docker-container --use - docker buildx inspect --bootstrap - - - name: Build HugeGraph Server for linux/${{ matrix.arch }} - run: | - docker buildx build \ - --platform linux/${{ matrix.arch }} \ - --load \ - --tag hugegraph-server-smoke:${{ matrix.arch }} \ - --file hugegraph-server/Dockerfile . - - - name: Check healthcheck and run runtime smoke - env: - IMAGE: hugegraph-server-smoke:${{ matrix.arch }} - ARCH: ${{ matrix.arch }} - run: | - HC=$(docker inspect --format='{{json .Config.Healthcheck}}' "$IMAGE") - echo "Healthcheck: $HC" - [[ "$HC" != "null" ]] || { echo "ERROR: HEALTHCHECK missing"; exit 1; } - hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh \ - "$IMAGE" "$ARCH" - - - name: Verify native RISC-V Maven build - if: matrix.arch == 'riscv64' - env: - IMAGE: hugegraph-server-smoke:riscv64 - run: | - CONTAINER_NAME="hugegraph-riscv64-maven-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" - cleanup() { - docker rm --force --volumes "$CONTAINER_NAME" >/dev/null 2>&1 || true - } - trap cleanup EXIT - - docker run --detach --platform linux/riscv64 \ - --name "$CONTAINER_NAME" --entrypoint sleep "$IMAGE" infinity - docker exec "$CONTAINER_NAME" mkdir -p /workspace - git ls-files -z | tar --null --files-from=- -cf - | \ - docker exec -i "$CONTAINER_NAME" tar -xf - -C /workspace - - docker exec "$CONTAINER_NAME" bash -euo pipefail -c ' - test "$(uname -m)" = riscv64 - apt-get -q update - apt-get -q install -y --no-install-recommends \ - maven protobuf-compiler protobuf-compiler-grpc-java-plugin - java -version - test -x /usr/bin/protoc - test -x /usr/bin/grpc_java_plugin - # Limit JIT work for the QEMU build; runtime smoke uses the default JVM. - export MAVEN_OPTS="-XX:TieredStopAtLevel=1 -XX:ActiveProcessorCount=2" - cd /workspace - mvn clean package -B -ntp -Drocksdb-only \ - -P riscv64-protobuf-tools \ - -pl hugegraph-server/hugegraph-dist -am \ - -Dmaven.test.skip=true -Dmaven.javadoc.skip=true - hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ - hugegraph-server/apache-hugegraph-server-*/ - ' - - - name: Clean up Docker resources - if: always() - env: - IMAGE: hugegraph-server-smoke:${{ matrix.arch }} - run: | - docker image rm "$IMAGE" >/dev/null 2>&1 || true - if [[ -n "${BUILDER_NAME:-}" ]]; then - docker buildx rm "$BUILDER_NAME" >/dev/null 2>&1 || true - fi diff --git a/.github/workflows/riscv64-ci.yml b/.github/workflows/riscv64-ci.yml new file mode 100644 index 0000000000..d4a5af7141 --- /dev/null +++ b/.github/workflows/riscv64-ci.yml @@ -0,0 +1,164 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: "RISC-V Server CI" + +on: + push: + branches: + - master + - 'release-*' + paths: + - '.github/workflows/riscv64-ci.yml' + - 'pom.xml' + - 'hugegraph-pd/pom.xml' + - 'hugegraph-pd/hg-pd-grpc/**' + - 'hugegraph-pd/hg-pd-common/**' + - 'hugegraph-pd/hg-pd-client/**' + - 'hugegraph-store/pom.xml' + - 'hugegraph-store/hg-store-common/**' + - 'hugegraph-commons/**' + - 'hugegraph-struct/**' + - 'hugegraph-server/pom.xml' + - 'hugegraph-server/hugegraph-core/**' + - 'hugegraph-server/hugegraph-rpc/**' + - 'hugegraph-server/hugegraph-api/**' + - 'hugegraph-server/hugegraph-rocksdb/**' + - 'hugegraph-server/hugegraph-dist/**' + pull_request: + paths: + - '.github/workflows/riscv64-ci.yml' + - 'pom.xml' + - 'hugegraph-pd/pom.xml' + - 'hugegraph-pd/hg-pd-grpc/**' + - 'hugegraph-pd/hg-pd-common/**' + - 'hugegraph-pd/hg-pd-client/**' + - 'hugegraph-store/pom.xml' + - 'hugegraph-store/hg-store-common/**' + - 'hugegraph-commons/**' + - 'hugegraph-struct/**' + - 'hugegraph-server/pom.xml' + - 'hugegraph-server/hugegraph-core/**' + - 'hugegraph-server/hugegraph-rpc/**' + - 'hugegraph-server/hugegraph-api/**' + - 'hugegraph-server/hugegraph-rocksdb/**' + - 'hugegraph-server/hugegraph-dist/**' + +permissions: + contents: read + +env: + BINFMT_IMAGE: >- + tonistiigi/binfmt@sha256:400a4873b838d1b89194d982c45e5fb3cda4593fbfd7e08a02e76b03b21166f0 + RISCV64_BASE_IMAGE: >- + ubuntu@sha256:4edded5722eb644868b7b976033d241d2ab3fff0a170924df69b200a59a2b994 + DRAGONWELL_RISCV64_ARCHIVE: >- + Alibaba_Dragonwell_Extended_11.0.31.28.11_riscv64_linux.tar.gz + DRAGONWELL_RISCV64_SHA256: >- + 7df2d308f0dca7a779d2854e6da19214f99cd77aa6d4982c3bf981a77266a79b + DRAGONWELL_RISCV64_URL: >- + https://github.com/dragonwell-project/dragonwell11/releases/download/dragonwell-extended-11.0.31.28_jdk-11.0.31-ga/Alibaba_Dragonwell_Extended_11.0.31.28.11_riscv64_linux.tar.gz + RISCV64_CONTAINER: >- + hugegraph-riscv64-ci-${{ github.run_id }}-${{ github.run_attempt }} + +jobs: + build-server-riscv64: + runs-on: ubuntu-24.04 + timeout-minutes: 90 + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Start isolated RISC-V environment + run: | + docker run --privileged --rm "$BINFMT_IMAGE" --install riscv64 + docker run --detach --platform linux/riscv64 \ + --name "$RISCV64_CONTAINER" "$RISCV64_BASE_IMAGE" sleep infinity + test "$(docker exec "$RISCV64_CONTAINER" uname -m)" = riscv64 + + - name: Prepare source and Java 11 + run: | + ARCHIVE_PATH="$RUNNER_TEMP/$DRAGONWELL_RISCV64_ARCHIVE" + curl --fail --location --retry 3 --show-error \ + "$DRAGONWELL_RISCV64_URL" --output "$ARCHIVE_PATH" + echo "$DRAGONWELL_RISCV64_SHA256 $ARCHIVE_PATH" | sha256sum -c - + + docker exec "$RISCV64_CONTAINER" mkdir -p /workspace /opt/dragonwell + git ls-files -z | tar --null --files-from=- -cf - | \ + docker exec -i "$RISCV64_CONTAINER" tar -xf - -C /workspace + docker cp "$ARCHIVE_PATH" \ + "$RISCV64_CONTAINER:/tmp/$DRAGONWELL_RISCV64_ARCHIVE" + + - name: Build and smoke test on RISC-V + run: | + docker exec \ + --env DRAGONWELL_RISCV64_ARCHIVE="$DRAGONWELL_RISCV64_ARCHIVE" \ + --env DRAGONWELL_RISCV64_SHA256="$DRAGONWELL_RISCV64_SHA256" \ + "$RISCV64_CONTAINER" bash -euo pipefail -c ' + test "$(uname -m)" = riscv64 + apt-get -q update + apt-get -q install -y --no-install-recommends \ + ca-certificates curl jq libatomic1 libgcc-s1 libstdc++6 \ + lsof maven procps \ + protobuf-compiler protobuf-compiler-grpc-java-plugin + + ARCHIVE_PATH="/tmp/$DRAGONWELL_RISCV64_ARCHIVE" + echo "$DRAGONWELL_RISCV64_SHA256 $ARCHIVE_PATH" | sha256sum -c - + tar -xzf "$ARCHIVE_PATH" --strip-components=1 -C /opt/dragonwell + rm "$ARCHIVE_PATH" + export JAVA_HOME=/opt/dragonwell + export PATH="$JAVA_HOME/bin:$PATH" + + java -XshowSettings:vm -version + test -x /usr/bin/protoc + test -x /usr/bin/grpc_java_plugin + + cd /workspace + MAVEN_OPTS="-XX:TieredStopAtLevel=1 -XX:ActiveProcessorCount=2" \ + mvn clean package -B -ntp -Drocksdb-only \ + -P riscv64-protobuf-tools \ + -pl hugegraph-server/hugegraph-dist -am \ + -Dmaven.test.skip=true -Dmaven.javadoc.skip=true + hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ + hugegraph-server/apache-hugegraph-server-*/ + hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh \ + hugegraph-server/apache-hugegraph-server-*/ + ' + + - name: Show server log on failure + if: failure() + run: | + if docker container inspect "$RISCV64_CONTAINER" >/dev/null 2>&1; then + docker exec "$RISCV64_CONTAINER" bash -c ' + find /workspace -path "*/logs/hugegraph-server.log" \ + -exec tail -n 200 {} \; + ' || true + fi + + - name: Clean up RISC-V environment + if: always() + run: | + if docker container inspect "$RISCV64_CONTAINER" >/dev/null 2>&1; then + docker rm --force --volumes "$RISCV64_CONTAINER" + fi + if docker container inspect "$RISCV64_CONTAINER" >/dev/null 2>&1; then + echo "RISC-V CI container still exists: $RISCV64_CONTAINER" >&2 + exit 1 + fi diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index 6a316c1db0..586e36da49 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -66,11 +66,6 @@ jobs: cp $HOME/.m2/settings.xml /tmp/settings.xml cp -vf .github/configs/settings.xml $HOME/.m2/settings.xml && cat $HOME/.m2/settings.xml - - name: Check default Maven profiles - if: ${{ env.BACKEND == 'memory' }} - run: | - "$TRAVIS_DIR/check-default-maven-profiles.sh" - - name: Compile run: | mvn clean compile -U -Dmaven.javadoc.skip=true -ntp diff --git a/hugegraph-server/Dockerfile b/hugegraph-server/Dockerfile index 1b14f142f8..2ca946e6ba 100644 --- a/hugegraph-server/Dockerfile +++ b/hugegraph-server/Dockerfile @@ -17,25 +17,7 @@ # # Dockerfile for HugeGraph Server -ARG TARGETARCH - -# Prepare the RISC-V Java runtime on the native build platform -FROM --platform=$BUILDPLATFORM maven:3.9.0-eclipse-temurin-11 AS riscv64-java - -ARG TARGETARCH -ARG DRAGONWELL_RISCV64_URL="https://github.com/dragonwell-project/dragonwell11/releases/download/dragonwell-extended-11.0.31.28_jdk-11.0.31-ga/Alibaba_Dragonwell_Extended_11.0.31.28.11_riscv64_linux.tar.gz" -ARG DRAGONWELL_RISCV64_SHA256="7df2d308f0dca7a779d2854e6da19214f99cd77aa6d4982c3bf981a77266a79b" - -RUN mkdir -p /opt/dragonwell \ - && if [ "$TARGETARCH" = "riscv64" ]; then \ - curl --fail --location --retry 3 --show-error \ - "$DRAGONWELL_RISCV64_URL" --output /tmp/dragonwell.tar.gz; \ - echo "$DRAGONWELL_RISCV64_SHA256 /tmp/dragonwell.tar.gz" | sha256sum -c -; \ - tar -xzf /tmp/dragonwell.tar.gz --strip-components=1 -C /opt/dragonwell; \ - rm /tmp/dragonwell.tar.gz; \ - fi - -# Build source code +# 1st stage: build source code FROM --platform=$BUILDPLATFORM maven:3.9.0-eclipse-temurin-11 AS build WORKDIR /pkg @@ -43,41 +25,14 @@ WORKDIR /pkg COPY . . ARG MAVEN_ARGS -ARG TARGETARCH RUN --mount=type=cache,target=/root/.m2 \ - if [ "$TARGETARCH" = "riscv64" ]; then \ - mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true \ - -Dmaven.javadoc.skip=true -Drocksdb-only \ - -pl hugegraph-server/hugegraph-dist -am \ - && hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ - hugegraph-server/apache-hugegraph-server-*/; \ - else \ - mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true \ - -Dmaven.javadoc.skip=true \ - && rm ./hugegraph-server/*.tar.gz ./hugegraph-pd/*.tar.gz \ - ./hugegraph-store/*.tar.gz; \ - fi + mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true -Dmaven.javadoc.skip=true \ + && rm ./hugegraph-server/*.tar.gz ./hugegraph-pd/*.tar.gz ./hugegraph-store/*.tar.gz -# Keep the existing Temurin 11 runtime for every architecture it supports. -FROM --platform=linux/amd64 eclipse-temurin:11-jre-jammy AS runtime-amd64 -FROM --platform=linux/arm/v7 eclipse-temurin:11-jre-jammy AS runtime-arm -FROM --platform=linux/arm64 eclipse-temurin:11-jre-jammy AS runtime-arm64 -FROM --platform=linux/ppc64le eclipse-temurin:11-jre-jammy AS runtime-ppc64le -FROM --platform=linux/s390x eclipse-temurin:11-jre-jammy AS runtime-s390x - -# Temurin 11 has no RISC-V image, so use Ubuntu with the verified Dragonwell archive. -FROM ubuntu:24.04 AS runtime-riscv64 -COPY --from=riscv64-java /opt/dragonwell/ /opt/dragonwell/ -ENV JAVA_HOME="/opt/dragonwell" \ - PATH="/opt/dragonwell/bin:${PATH}" - -# Runtime environment +# 2nd stage: runtime env # Note: ZGC (The Z Garbage Collector) is only supported on ARM-Mac with java > 13 -FROM runtime-${TARGETARCH} AS runtime - -ARG TARGETARCH -ARG DEBIAN_FRONTEND=noninteractive +FROM eclipse-temurin:11-jre-jammy COPY --from=build /pkg/hugegraph-server/apache-hugegraph-server-*/ /hugegraph-server/ LABEL maintainer="HugeGraph Docker Maintainers " @@ -92,14 +47,12 @@ WORKDIR /hugegraph-server/ # 1. Install runtime dependencies and configure server RUN apt-get -q update \ - && runtime_packages="dumb-init procps curl lsof vim" \ - && if [ "$TARGETARCH" = "riscv64" ]; then \ - runtime_packages="$runtime_packages ca-certificates libatomic1 libstdc++6 libgcc-s1"; \ - fi \ - && apt-get -q install -y --no-install-recommends --no-install-suggests $runtime_packages \ - && if [ "$TARGETARCH" = "riscv64" ]; then \ - test -x /opt/dragonwell/bin/java; \ - fi \ + && apt-get -q install -y --no-install-recommends --no-install-suggests \ + dumb-init \ + procps \ + curl \ + lsof \ + vim \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && sed -i "s/^restserver.url.*$/restserver.url=http:\/\/0.0.0.0:8080/g" ./conf/rest-server.properties diff --git a/hugegraph-server/README.md b/hugegraph-server/README.md index dad2be2a78..fe9be5eeab 100644 --- a/hugegraph-server/README.md +++ b/hugegraph-server/README.md @@ -33,51 +33,22 @@ See [docker/README.md](../docker/README.md) for the full setup guide. ## RISC-V Development and Testing -The supported RISC-V target is 64-bit `linux/riscv64` LP64D with glibc 2.30 or newer. -This target covers HugeGraph Server with the embedded RocksDB backend only. It does not -cover musl/Alpine, 32-bit RISC-V, PD, Store, HStore, or other storage backends. +The RISC-V validation target is 64-bit `linux/riscv64` LP64D with glibc 2.30 or newer, +HugeGraph Server, and the embedded RocksDB backend. PD, Store, HStore, other backends, +musl/Alpine, and 32-bit RISC-V are out of scope. -The RISC-V image uses the checksum-pinned Alibaba Dragonwell 11 Extended Server VM from -the [Dockerfile](Dockerfile). The runtime also provides `libstdc++6`, `libgcc-s1`, and -`libatomic.so.1`, which are required by the packaged RocksDB JNI library. +The dedicated [RISC-V Server CI](../.github/workflows/riscv64-ci.yml) runs a RocksDB-only +native build and runtime smoke test in an isolated QEMU environment. It uses the +checksum-pinned Alibaba Dragonwell 11 Extended Server VM and installs `libatomic1` for the +packaged RocksDB JNI library. QEMU is for correctness testing and is not a performance +benchmark. -### Docker and QEMU +The repository Dockerfile and published HugeGraph image do not include RISC-V support. +Image publication requires separate multi-architecture design and validation. -Docker Desktop includes emulation support. On Linux, install the RISC-V emulator only if -it is not already registered: - -```bash -docker run --privileged --rm tonistiigi/binfmt --install riscv64 -``` - -The smoke helper requires Docker Buildx, `curl`, and `jq` on the host. From the repository -root, build and run the complete runtime smoke test: - -```bash -IMAGE=hugegraph-server:riscv64-test -docker buildx build --platform linux/riscv64 --load --tag "$IMAGE" \ - --file hugegraph-server/Dockerfile . -hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh \ - "$IMAGE" riscv64 -docker image rm "$IMAGE" -``` - -The smoke helper removes its test containers, anonymous volumes, and temporary files. It -keeps the input image, uses the current Buildx builder, and does not remove the host -emulator. If you registered the emulator specifically for this test, remove it separately: - -```bash -docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-riscv64 -``` - -Do not uninstall Docker Desktop's built-in emulator. QEMU is substantially slower than -native RISC-V and is intended for correctness testing, not performance measurements. - -### Native RISC-V - -Use Dragonwell 11 Extended `11.0.31.28.11` and verify its archive with the URL and SHA-256 -declared in the Dockerfile. On a Debian-derived glibc system, install the native tools and -runtime libraries: +For the same validation on a native Debian-derived RISC-V system, use Dragonwell 11 +Extended `11.0.31.28.11` with the archive checksum declared in the CI workflow, then +install the build and runtime dependencies: ```bash sudo apt-get update @@ -91,17 +62,10 @@ After selecting Dragonwell as `JAVA_HOME`, build and verify the RocksDB-only dis test "$(uname -m)" = riscv64 "$JAVA_HOME/bin/java" -XshowSettings:vm -version mvn clean package -Drocksdb-only -pl hugegraph-server/hugegraph-dist -am \ + -P riscv64-protobuf-tools \ -Dmaven.test.skip=true -Dmaven.javadoc.skip=true hugegraph-server/hugegraph-dist/src/assembly/travis/check-rocksdb-only-dist.sh \ hugegraph-server/apache-hugegraph-server-*/ hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh \ hugegraph-server/apache-hugegraph-server-*/ ``` - -Run the existing Core and API gates with the same RocksDB-only dependency boundary: - -```bash -hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh rocksdb -hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh \ - rocksdb target/riscv64-api-report -``` diff --git a/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh b/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh index db0593b5bf..2c76a54435 100755 --- a/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh +++ b/hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh @@ -81,8 +81,7 @@ else log "HugeGraph initialization already done. Skipping re-init..." fi -./bin/start-hugegraph.sh -j "${JAVA_OPTS:-}" \ - -t "${HG_SERVER_STARTUP_TIMEOUT:-120}" +./bin/start-hugegraph.sh -j "${JAVA_OPTS:-}" -t 120 # Post-startup cluster stabilization check (hstore only — rocksdb has no partitions) ACTUAL_BACKEND=$(grep -E '^[[:space:]]*backend[[:space:]]*=' "${GRAPH_CONF}" | head -n 1 | sed 's/.*=//' | tr -d '[:space:]' || true) diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh index 9ffd47c970..920914267d 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/build-report.sh @@ -20,13 +20,6 @@ set -ev BACKEND=$1 JACOCO_PORT=$2 JACOCO_REPORT_FILE=$3 -ROCKSDB_ONLY=false - -if [[ "$BACKEND" == "rocksdb" && - "$(uname -s)" == "Linux" && - "$(uname -m)" == "riscv64" ]]; then - ROCKSDB_ONLY=true -fi TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) @@ -65,13 +58,7 @@ esac mkdir -p "$(dirname "$REPORT_FILE")" cd "$REPO_ROOT/hugegraph-server/hugegraph-test" -if [[ "$ROCKSDB_ONLY" == "true" ]]; then - mvn jacoco:dump@pull-test-data -Dapp.host=localhost \ - -Dapp.port=$JACOCO_PORT -Dskip.dump=false -Drocksdb-only -else - mvn jacoco:dump@pull-test-data -Dapp.host=localhost \ - -Dapp.port=$JACOCO_PORT -Dskip.dump=false -fi +mvn jacoco:dump@pull-test-data -Dapp.host=localhost -Dapp.port=$JACOCO_PORT -Dskip.dump=false cd "$REPO_ROOT/hugegraph-server" if [[ ! -e "${TRAVIS_DIR}/jacococli.jar" ]]; then diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh deleted file mode 100755 index f291d97809..0000000000 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/check-default-maven-profiles.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -set -euo pipefail - -TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) -REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) -TEST_MODULE=hugegraph-server/hugegraph-test -WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-maven-profile-check.XXXXXX") - -cleanup() { - rm -rf "$WORK_DIR" -} -trap cleanup EXIT - -cd "$REPO_ROOT" - -DEFAULT_PROFILES="$WORK_DIR/default-profiles.txt" -ROCKSDB_ONLY_PROFILES="$WORK_DIR/rocksdb-only-profiles.txt" - -mvn help:active-profiles -pl "$TEST_MODULE" -ntp -Dstyle.color=never \ - > "$DEFAULT_PROFILES" -mvn help:active-profiles -pl "$TEST_MODULE" -Drocksdb-only -ntp \ - -Dstyle.color=never > "$ROCKSDB_ONLY_PROFILES" - -require_active_profile() { - local profile=$1 - local profiles_file=$2 - if ! grep -Eq "^[[:space:]]*-[[:space:]]+${profile}[[:space:]]+\\(source:" \ - "$profiles_file"; then - echo "Required Maven profile is inactive: $profile" >&2 - cat "$profiles_file" >&2 - exit 1 - fi -} - -require_inactive_profile() { - local profile=$1 - local profiles_file=$2 - if grep -Eq "^[[:space:]]*-[[:space:]]+${profile}[[:space:]]+\\(source:" \ - "$profiles_file"; then - echo "Maven profile should be inactive: $profile" >&2 - cat "$profiles_file" >&2 - exit 1 - fi -} - -for profile in core-test all-backends memory; do - require_active_profile "$profile" "$DEFAULT_PROFILES" -done - -for profile in core-test rocksdb-only; do - require_active_profile "$profile" "$ROCKSDB_ONLY_PROFILES" -done -for profile in all-backends memory; do - require_inactive_profile "$profile" "$ROCKSDB_ONLY_PROFILES" -done - -DEFAULT_POM="$WORK_DIR/default-effective-pom.xml" -ROCKSDB_POM="$WORK_DIR/rocksdb-effective-pom.xml" -mvn help:effective-pom -pl "$TEST_MODULE" -ntp -Dstyle.color=never \ - -Doutput="$DEFAULT_POM" -mvn help:effective-pom -pl "$TEST_MODULE" -P rocksdb -ntp \ - -Dstyle.color=never -Doutput="$ROCKSDB_POM" - -DEFAULT_MODEL=$(awk '/^[[:space:]]*/{exit} {print}' "$DEFAULT_POM") -ROCKSDB_MODEL=$(awk '/^[[:space:]]*/{exit} {print}' "$ROCKSDB_POM") -CORE_EXECUTION=$(awk ' - // { - in_execution = 1 - block = $0 - next - } - in_execution { - block = block "\n" $0 - } - in_execution && /<\/execution>/ { - if (block ~ /core-test<\/id>/) { - print block - exit - } - in_execution = 0 - block = "" - } -' "$DEFAULT_POM") - -for expected in 'memory' \ - 'text'; do - grep -Fq "$expected" <<< "$DEFAULT_MODEL" || { - echo "Default test configuration is missing: $expected" >&2 - exit 1 - } -done - -for expected in 'test' 'test'; do - grep -Fq "$expected" <<< "$CORE_EXECUTION" || { - echo "Default Core Surefire execution is missing: $expected" >&2 - exit 1 - } -done - -for expected in 'rocksdb' \ - 'binary'; do - grep -Fq "$expected" <<< "$ROCKSDB_MODEL" || { - echo "Explicit RocksDB configuration is missing: $expected" >&2 - exit 1 - } -done - -echo "Default and explicit Maven test profiles are valid" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh index fafd8d5ba6..a038370ad7 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh @@ -58,60 +58,18 @@ function download_to_dir() { cd "$REPO_ROOT" -ROCKSDB_ONLY=false - -if [[ "$BACKEND" == "rocksdb" && - "$(uname -s)" == "Linux" && - "$(uname -m)" == "riscv64" ]]; then - . "$TRAVIS_DIR/../static/bin/util.sh" - configure_riscv64_libatomic - ROCKSDB_ONLY=true -fi - -if [[ "$ROCKSDB_ONLY" == "true" ]]; then - VERSION=$(mvn help:evaluate -Dexpression=project.version -q \ - -DforceStdout -Drocksdb-only) -else - VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) -fi +VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) SERVER_DIR=hugegraph-server/apache-hugegraph-server-$VERSION/ CONF=$SERVER_DIR/conf/graphs/hugegraph.properties REST_SERVER_CONF=$SERVER_DIR/conf/rest-server.properties GREMLIN_SERVER_CONF=$SERVER_DIR/conf/gremlin-server.yaml JACOCO_PORT=36320 -SERVER_START_ATTEMPTED=false - -function cleanup() { - local status=$? - trap - EXIT - - if [[ "$SERVER_START_ATTEMPTED" == "true" ]]; then - if ! "$TRAVIS_DIR"/stop-server.sh "$SERVER_DIR"; then - echo "Failed to stop the HugeGraph Server started by this test" >&2 - status=1 - fi - fi - exit "$status" -} - -trap cleanup EXIT -if [[ "$ROCKSDB_ONLY" == "true" ]]; then - mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -ntp \ - -pl hugegraph-server/hugegraph-dist -am -Drocksdb-only -else - mvn package -Dmaven.test.skip=true -ntp -fi - -if [[ "$ROCKSDB_ONLY" == "true" ]]; then - "$TRAVIS_DIR"/check-rocksdb-only-dist.sh "$SERVER_DIR" -fi +mvn package -Dmaven.test.skip=true -ntp # add mysql dependency -if [[ "$ROCKSDB_ONLY" != "true" ]]; then - download_to_dir "$SERVER_DIR/lib/" \ - "https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar" -fi +download_to_dir "$SERVER_DIR/lib/" \ + "https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar" if [[ ! -e "$SERVER_DIR/lib/ikanalyzer-2012_u6.jar" ]]; then download_to_dir "$SERVER_DIR/lib/" \ @@ -136,23 +94,17 @@ authentication: { }" >> $GREMLIN_SERVER_CONF # start server -SERVER_START_ATTEMPTED=true -"$TRAVIS_DIR/start-server.sh" "$SERVER_DIR" "$BACKEND" "$JACOCO_PORT" || \ - (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) +$TRAVIS_DIR/start-server.sh $SERVER_DIR $BACKEND $JACOCO_PORT || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) # run api-test -if [[ "$ROCKSDB_ONLY" == "true" ]]; then - mvn test -pl hugegraph-server/hugegraph-test -am -P "api-test,$BACKEND" \ - -Drocksdb-only || \ - (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) -else - mvn test -pl hugegraph-server/hugegraph-test -am -P "api-test,$BACKEND" || \ - (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) -fi +mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,$BACKEND || (cat $SERVER_DIR/logs/hugegraph-server.log && exit 1) if [ "$RUN_GREMLIN_CONSOLE_SMOKE_TEST" == "true" ]; then bash "$TRAVIS_DIR/run-gremlin-console-smoke-test.sh" "$SERVER_DIR" || \ (cat "$SERVER_DIR/logs/hugegraph-server.log" && exit 1) fi -"$TRAVIS_DIR/build-report.sh" "$BACKEND" "$JACOCO_PORT" "$REPORT_FILE" +$TRAVIS_DIR/build-report.sh $BACKEND $JACOCO_PORT $REPORT_FILE + +# stop server +$TRAVIS_DIR/stop-server.sh $SERVER_DIR diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh index 7463cc4417..a95d2f0806 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh @@ -18,19 +18,5 @@ set -ev BACKEND=$1 -TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) -REPO_ROOT=$(cd "$TRAVIS_DIR/../../../../.." && pwd) -if [[ "$BACKEND" == "rocksdb" && - "$(uname -s)" == "Linux" && - "$(uname -m)" == "riscv64" ]]; then - . "$TRAVIS_DIR/../static/bin/util.sh" - configure_riscv64_libatomic - cd "$REPO_ROOT" - mvn test -pl hugegraph-server/hugegraph-test -am \ - -P core-test,"$BACKEND" -Drocksdb-only -else - cd "$REPO_ROOT" - mvn test -pl hugegraph-server/hugegraph-test -am \ - -P core-test,"$BACKEND" -fi +mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,$BACKEND diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh deleted file mode 100755 index 618ce68660..0000000000 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-docker-runtime-smoke-test.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/bin/bash -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -set -euo pipefail - -if [[ $# -lt 1 || $# -gt 2 ]]; then - echo "USAGE: $0 IMAGE [ARCH]" >&2 - exit 1 -fi - -IMAGE=$1 -EXPECTED_ARCH=${2:-riscv64} -TRAVIS_DIR=$(cd "$(dirname "$0")" && pwd) -CONTAINER_NAME="hugegraph-runtime-smoke-${EXPECTED_ARCH}-$$" -CONTAINER_STARTED=false -WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-docker-runtime-smoke.XXXXXX") -CONTAINER_LOG="$WORK_DIR/container.log" -RUN_ID="$(date +%s)_$$" - -case "$EXPECTED_ARCH" in - amd64) - EXPECTED_UNAME_ARCH=x86_64 - SERVER_STARTUP_TIMEOUT=300 - CONTAINER_READY_TIMEOUT=300 - ;; - arm64) - EXPECTED_UNAME_ARCH=aarch64 - SERVER_STARTUP_TIMEOUT=300 - CONTAINER_READY_TIMEOUT=300 - ;; - riscv64) - EXPECTED_UNAME_ARCH=riscv64 - SERVER_STARTUP_TIMEOUT=300 - CONTAINER_READY_TIMEOUT=600 - ;; - *) - echo "Unsupported Docker architecture: $EXPECTED_ARCH" >&2 - exit 1 - ;; -esac - -cleanup() { - local status=$? - trap - EXIT - if [[ "$CONTAINER_STARTED" == "true" ]]; then - docker rm --force --volumes "$CONTAINER_NAME" >/dev/null 2>&1 || status=1 - fi - rm -rf "$WORK_DIR" - exit "$status" -} -trap cleanup EXIT - -for command in docker curl jq; do - if ! command -v "$command" >/dev/null 2>&1; then - echo "Required command is unavailable: $command" >&2 - exit 1 - fi -done - -IMAGE_ARCH=$(docker image inspect --format '{{.Architecture}}' "$IMAGE") -if [[ "$IMAGE_ARCH" != "$EXPECTED_ARCH" ]]; then - echo "Expected image architecture $EXPECTED_ARCH, got $IMAGE_ARCH" >&2 - exit 1 -fi - -docker run --rm --platform "linux/$EXPECTED_ARCH" \ - --env EXPECTED_ARCH="$EXPECTED_UNAME_ARCH" \ - --env EXPECTED_JAVA_MAJOR=11 \ - --volume "$TRAVIS_DIR:/smoke:ro" \ - --entrypoint /bin/bash "$IMAGE" \ - /smoke/run-rocksdb-jni-smoke-test.sh /hugegraph-server - -docker run --detach --platform "linux/$EXPECTED_ARCH" \ - --name "$CONTAINER_NAME" \ - --env HG_SERVER_STARTUP_TIMEOUT="$SERVER_STARTUP_TIMEOUT" \ - --publish 127.0.0.1::8080 \ - "$IMAGE" >/dev/null -CONTAINER_STARTED=true - -update_server_url() { - local port_binding - local server_port - - port_binding=$(docker port "$CONTAINER_NAME" 8080/tcp | head -n 1) - if [[ -z "$port_binding" ]]; then - echo "HugeGraph container has no published port for 8080/tcp" >&2 - return 1 - fi - server_port=${port_binding##*:} - SERVER_URL="http://127.0.0.1:$server_port" -} - -wait_for_container_server() { - local deadline=$((SECONDS + CONTAINER_READY_TIMEOUT)) - local running - while ((SECONDS < deadline)); do - running=$(docker inspect --format '{{.State.Running}}' "$CONTAINER_NAME") - if [[ "$running" != "true" ]]; then - echo "HugeGraph container exited before becoming ready" >&2 - docker logs "$CONTAINER_NAME" >&2 - return 1 - fi - if curl --silent --show-error --fail \ - --connect-timeout 3 --max-time 5 \ - "$SERVER_URL/versions" >/dev/null 2>&1; then - return 0 - fi - sleep 1 - done - echo "HugeGraph container did not become ready at $SERVER_URL" >&2 - docker logs "$CONTAINER_NAME" >&2 - return 1 -} - -wait_for_container_health() { - local health - for _ in $(seq 1 60); do - health=$(docker inspect --format \ - '{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}' \ - "$CONTAINER_NAME") - if [[ "$health" == "healthy" ]]; then - return 0 - fi - if [[ "$health" == "missing" ]]; then - echo "HugeGraph container has no health status" >&2 - return 1 - fi - sleep 1 - done - echo "HugeGraph container health did not become healthy" >&2 - docker inspect --format '{{json .State.Health}}' "$CONTAINER_NAME" >&2 - return 1 -} - -update_server_url -wait_for_container_server -wait_for_container_health -"$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" create "$RUN_ID" | \ - tee "$WORK_DIR/create.log" -grep -q '^server-e2e-smoke-create-ok$' "$WORK_DIR/create.log" -docker restart --time 30 "$CONTAINER_NAME" >/dev/null -update_server_url -wait_for_container_server -wait_for_container_health -"$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" verify "$RUN_ID" | \ - tee "$WORK_DIR/verify.log" -grep -q '^server-e2e-smoke-verify-ok$' "$WORK_DIR/verify.log" - -if ! docker logs "$CONTAINER_NAME" > "$CONTAINER_LOG" 2>&1; then - echo "Failed to read HugeGraph container logs" >&2 - cat "$CONTAINER_LOG" >&2 - exit 1 -fi -if grep -Eiq \ - 'undefined symbol|UnsatisfiedLinkError|UnsupportedClassVersionError|NoClassDefFoundError' \ - "$CONTAINER_LOG"; then - echo "Native linkage or Java compatibility error found in container logs" >&2 - cat "$CONTAINER_LOG" >&2 - exit 1 -fi - -echo "docker-runtime-smoke-$EXPECTED_ARCH-ok" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh index 2c1261924b..b4faf7785f 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh @@ -29,6 +29,7 @@ EXPECTED_ARCH=${EXPECTED_ARCH:-riscv64} EXPECTED_JAVA_MAJOR=${EXPECTED_JAVA_MAJOR:-11} SERVER_START_ATTEMPTED=false SERVER_STARTUP_TIMEOUT=${SERVER_STARTUP_TIMEOUT:-300} +SERVER_START_COMMAND_TIMEOUT=$((SERVER_STARTUP_TIMEOUT + 30)) WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-native-runtime-smoke.XXXXXX") RUN_ID="$(date +%s)_$$" @@ -45,17 +46,27 @@ cleanup() { } trap cleanup EXIT +start_server() { + if ! command -v timeout >/dev/null 2>&1; then + echo "Required command is unavailable: timeout" >&2 + return 1 + fi + timeout --foreground --kill-after=15s \ + "${SERVER_START_COMMAND_TIMEOUT}s" \ + "$SERVER_DIR/bin/start-hugegraph.sh" -t "$SERVER_STARTUP_TIMEOUT" +} + "$TRAVIS_DIR/run-rocksdb-jni-smoke-test.sh" "$SERVER_DIR" "$SERVER_DIR/bin/init-store.sh" SERVER_START_ATTEMPTED=true -"$SERVER_DIR/bin/start-hugegraph.sh" -t "$SERVER_STARTUP_TIMEOUT" +start_server "$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" create "$RUN_ID" | \ tee "$WORK_DIR/create.log" grep -q '^server-e2e-smoke-create-ok$' "$WORK_DIR/create.log" "$SERVER_DIR/bin/stop-hugegraph.sh" -m false -"$SERVER_DIR/bin/start-hugegraph.sh" -t "$SERVER_STARTUP_TIMEOUT" +start_server "$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" verify "$RUN_ID" | \ tee "$WORK_DIR/verify.log" grep -q '^server-e2e-smoke-verify-ok$' "$WORK_DIR/verify.log" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh index 2e5c5bb9f8..b7b70e8cc9 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/start-server.sh @@ -24,14 +24,6 @@ JACOCO_PORT=$3 JACOCO_DIR=${TRAVIS_DIR} JACOCO_JAR=${JACOCO_DIR}/jacocoagent.jar -SERVER_STARTUP_TIMEOUT=${SERVER_STARTUP_TIMEOUT:-} - -if [[ -z "$SERVER_STARTUP_TIMEOUT" ]]; then - case "$(uname -m)" in - riscv64) SERVER_STARTUP_TIMEOUT=300 ;; - *) SERVER_STARTUP_TIMEOUT=60 ;; - esac -fi BIN=$BASE_DIR/bin CONF=$BASE_DIR/conf/graphs/hugegraph.properties @@ -103,4 +95,4 @@ if [ -n "$SERVER_JAVA_OPTIONS" ]; then fi echo -e "pa" | $BIN/init-store.sh -$BIN/start-hugegraph.sh -j "$JACOCO_OPTION" -t "$SERVER_STARTUP_TIMEOUT" +$BIN/start-hugegraph.sh -j "$JACOCO_OPTION" -t 60 diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh index 9e29fed63d..2751757884 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/stop-server.sh @@ -19,5 +19,6 @@ set -ev BASE_DIR=$1 BIN=$BASE_DIR/bin +VERSION=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` $BIN/stop-hugegraph.sh diff --git a/hugegraph-server/hugegraph-test/pom.xml b/hugegraph-server/hugegraph-test/pom.xml index ca77a27601..b3fc645f79 100644 --- a/hugegraph-server/hugegraph-test/pom.xml +++ b/hugegraph-server/hugegraph-test/pom.xml @@ -45,11 +45,36 @@ hugegraph-api ${revision} + + org.apache.hugegraph + hugegraph-cassandra + ${revision} + + + org.apache.hugegraph + hugegraph-scylladb + ${revision} + org.apache.hugegraph hugegraph-rocksdb ${revision} + + org.apache.hugegraph + hugegraph-hbase + ${revision} + + + org.apache.hugegraph + hugegraph-mysql + ${revision} + + + org.apache.hugegraph + hugegraph-postgresql + ${revision} + org.apache.hugegraph hugegraph-dist @@ -283,74 +308,10 @@ - - all-backends - - - !rocksdb-only - - - - - org.apache.hugegraph - hugegraph-cassandra - ${revision} - - - org.apache.hugegraph - hugegraph-scylladb - ${revision} - - - org.apache.hugegraph - hugegraph-hbase - ${revision} - - - org.apache.hugegraph - hugegraph-mysql - ${revision} - - - org.apache.hugegraph - hugegraph-postgresql - ${revision} - - - - - rocksdb-only - - - rocksdb-only - - - - rocksdb - binary - - - - - maven-compiler-plugin - - - - org/apache/hugegraph/unit/cassandra/** - org/apache/hugegraph/unit/mysql/** - org/apache/hugegraph/unit/UnitTestSuite.java - - - - - - memory - - !rocksdb-only - + true memory diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java index 91bcd3ac6e..9e82692689 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java @@ -53,8 +53,6 @@ public class TaskCoreTest extends BaseCoreTest { - private static final long GREMLIN_JOB_TIMEOUT = 30L; - @Before @Override public void setup() { @@ -114,30 +112,6 @@ private static void waitUntilTaskRunning(TaskScheduler scheduler) { Assert.fail("Timed out waiting for task to start running"); } - private static HugeTask waitUntilTaskProgress( - TaskScheduler scheduler, Id id, int expectedProgress, - long timeoutSeconds) { - long deadline = System.nanoTime() + - TimeUnit.SECONDS.toNanos(timeoutSeconds); - do { - HugeTask task = scheduler.task(id); - if (task.completed()) { - Assert.fail(String.format( - "Task '%s' completed at progress %s before " + - "reaching progress %s", - id, task.progress(), expectedProgress)); - } - if (task.progress() >= expectedProgress) { - return task; - } - sleepAWhile(100L); - } while (System.nanoTime() < deadline); - Assert.fail(String.format( - "Timed out waiting for task '%s' to reach progress %s", - id, expectedProgress)); - return null; - } - private static void deleteTaskAndWaitGone(TaskScheduler scheduler, Id id) { for (int pass = 0; pass < 30; pass++) { try { @@ -695,8 +669,7 @@ public void testGremlinJobWithScript() throws TimeoutException { "}"; HugeTask task = runGremlinJob(script); - task = scheduler.waitUntilTaskCompleted(task.id(), - GREMLIN_JOB_TIMEOUT); + task = scheduler.waitUntilTaskCompleted(task.id(), 10); Assert.assertEquals("test-gremlin-job", task.name()); Assert.assertEquals("gremlin", task.type()); Assert.assertEquals(TaskStatus.SUCCESS, task.status()); @@ -1001,8 +974,7 @@ public void testGremlinJobAndCancel() throws TimeoutException { // Cancel success task HugeTask task2 = runGremlinJob("1+2"); - task2 = scheduler.waitUntilTaskCompleted(task2.id(), - GREMLIN_JOB_TIMEOUT); + task2 = scheduler.waitUntilTaskCompleted(task2.id(), 10); Assert.assertEquals(TaskStatus.SUCCESS, task2.status()); scheduler.cancel(task2); task2 = scheduler.task(task2.id()); @@ -1035,8 +1007,7 @@ public void testGremlinJobAndCancel() throws TimeoutException { "};" + "rs;"; HugeTask task4 = runGremlinJob(bigResults); - task4 = scheduler.waitUntilTaskCompleted(task4.id(), - GREMLIN_JOB_TIMEOUT); + task4 = scheduler.waitUntilTaskCompleted(task4.id(), 10); Assert.assertEquals(TaskStatus.FAILED, task4.status()); scheduler.cancel(task4); task4 = scheduler.task(task4.id()); @@ -1052,17 +1023,16 @@ public void testGremlinJobAndRestore() throws Exception { HugeGraph graph = graph(); TaskScheduler scheduler = graph.taskScheduler(); - String gremlin = "gremlinJob.setMinSaveInterval(1);" + - "println('task start');" + + String gremlin = "println('task start');" + "for(int i=gremlinJob.progress(); i<=10; i++) {" + " gremlinJob.updateProgress(i);" + - " Thread.sleep(1000); " + + " Thread.sleep(200); " + " println('sleep=>'+i);" + "}; 100;"; HugeTask task = runGremlinJob(gremlin); - task = waitUntilTaskProgress(scheduler, task.id(), 1, - GREMLIN_JOB_TIMEOUT); + sleepAWhile(200 * 6); + task = scheduler.task(task.id()); scheduler.cancel(task); task = scheduler.task(task.id()); @@ -1105,8 +1075,7 @@ public void testGremlinJobAndRestore() throws Exception { }, e -> { Assert.assertContains("is already in the queue", e.getMessage()); }); - scheduler.waitUntilTaskCompleted(task2.id(), - GREMLIN_JOB_TIMEOUT); + scheduler.waitUntilTaskCompleted(task2.id(), 10); sleepAWhile(500); Assert.assertEquals(10, task2.progress()); Assert.assertEquals(1, task2.retries()); From e8986dc327b307dd3940882f71e6e866c136a0a5 Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Thu, 23 Jul 2026 15:30:36 +0800 Subject: [PATCH 06/10] fix(ci): invoke RISC-V validation from server CI --- .github/workflows/riscv64-ci.yml | 40 +------------------------------- .github/workflows/server-ci.yml | 5 ++++ 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/.github/workflows/riscv64-ci.yml b/.github/workflows/riscv64-ci.yml index d4a5af7141..62caa84015 100644 --- a/.github/workflows/riscv64-ci.yml +++ b/.github/workflows/riscv64-ci.yml @@ -18,45 +18,7 @@ name: "RISC-V Server CI" on: - push: - branches: - - master - - 'release-*' - paths: - - '.github/workflows/riscv64-ci.yml' - - 'pom.xml' - - 'hugegraph-pd/pom.xml' - - 'hugegraph-pd/hg-pd-grpc/**' - - 'hugegraph-pd/hg-pd-common/**' - - 'hugegraph-pd/hg-pd-client/**' - - 'hugegraph-store/pom.xml' - - 'hugegraph-store/hg-store-common/**' - - 'hugegraph-commons/**' - - 'hugegraph-struct/**' - - 'hugegraph-server/pom.xml' - - 'hugegraph-server/hugegraph-core/**' - - 'hugegraph-server/hugegraph-rpc/**' - - 'hugegraph-server/hugegraph-api/**' - - 'hugegraph-server/hugegraph-rocksdb/**' - - 'hugegraph-server/hugegraph-dist/**' - pull_request: - paths: - - '.github/workflows/riscv64-ci.yml' - - 'pom.xml' - - 'hugegraph-pd/pom.xml' - - 'hugegraph-pd/hg-pd-grpc/**' - - 'hugegraph-pd/hg-pd-common/**' - - 'hugegraph-pd/hg-pd-client/**' - - 'hugegraph-store/pom.xml' - - 'hugegraph-store/hg-store-common/**' - - 'hugegraph-commons/**' - - 'hugegraph-struct/**' - - 'hugegraph-server/pom.xml' - - 'hugegraph-server/hugegraph-core/**' - - 'hugegraph-server/hugegraph-rpc/**' - - 'hugegraph-server/hugegraph-api/**' - - 'hugegraph-server/hugegraph-rocksdb/**' - - 'hugegraph-server/hugegraph-dist/**' + workflow_call: permissions: contents: read diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index 586e36da49..0d6c54b51c 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -203,3 +203,8 @@ jobs: if [ -f "$SERVER_DIR/bin/pid" ]; then $TRAVIS_DIR/stop-server.sh $SERVER_DIR || true fi + + build-server-riscv64: + uses: ./.github/workflows/riscv64-ci.yml + permissions: + contents: read From bd69efb8a9b87142998d43682fbd67bcc948de30 Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Thu, 23 Jul 2026 16:00:01 +0800 Subject: [PATCH 07/10] fix(ci): reap RISC-V server processes --- .github/workflows/riscv64-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/riscv64-ci.yml b/.github/workflows/riscv64-ci.yml index 62caa84015..9f8ca12057 100644 --- a/.github/workflows/riscv64-ci.yml +++ b/.github/workflows/riscv64-ci.yml @@ -51,7 +51,7 @@ jobs: - name: Start isolated RISC-V environment run: | docker run --privileged --rm "$BINFMT_IMAGE" --install riscv64 - docker run --detach --platform linux/riscv64 \ + docker run --detach --init --platform linux/riscv64 \ --name "$RISCV64_CONTAINER" "$RISCV64_BASE_IMAGE" sleep infinity test "$(docker exec "$RISCV64_CONTAINER" uname -m)" = riscv64 From fff97cf2be5ea168cb3df1a15a9e971f4a90f1a5 Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Thu, 23 Jul 2026 17:35:13 +0800 Subject: [PATCH 08/10] refactor(server): preserve default reactor layout --- hugegraph-server/README.md | 4 ++-- pom.xml | 33 ++++----------------------------- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/hugegraph-server/README.md b/hugegraph-server/README.md index fe9be5eeab..74d09e7458 100644 --- a/hugegraph-server/README.md +++ b/hugegraph-server/README.md @@ -52,8 +52,8 @@ install the build and runtime dependencies: ```bash sudo apt-get update -sudo apt-get install -y maven protobuf-compiler \ - protobuf-compiler-grpc-java-plugin libatomic1 libstdc++6 libgcc-s1 curl jq +sudo apt-get install -y ca-certificates curl jq libatomic1 libgcc-s1 libstdc++6 \ + lsof maven procps protobuf-compiler protobuf-compiler-grpc-java-plugin ``` After selecting Dragonwell as `JAVA_HOME`, build and verify the RocksDB-only distribution: diff --git a/pom.xml b/pom.xml index 5b8952110c..045a24ad56 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,11 @@ hugegraph-server + hugegraph-pd + hugegraph-store hugegraph-commons + install-dist + hugegraph-cluster-test hugegraph-struct @@ -318,35 +322,6 @@ - - all-modules - - - !rocksdb-only - - - - hugegraph-pd - hugegraph-store - install-dist - hugegraph-cluster-test - - - - rocksdb-only - - - rocksdb-only - - - - - hugegraph-pd/hg-pd-grpc - hugegraph-pd/hg-pd-common - hugegraph-pd/hg-pd-client - hugegraph-store/hg-store-common - - apache-release From 1c30c1c5d6537e644b801aa74f833340f7aa6e9e Mon Sep 17 00:00:00 2001 From: "guanxiao.233" Date: Fri, 24 Jul 2026 11:54:35 +0800 Subject: [PATCH 09/10] fix(server): cover RISC-V store dumper --- .../src/assembly/static/bin/dump-store.sh | 12 ++++++++---- .../assembly/travis/run-native-runtime-smoke-test.sh | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/dump-store.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/dump-store.sh index 425ad9f157..14b6ac1f79 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/dump-store.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/dump-store.sh @@ -30,16 +30,20 @@ TOP="$(cd $BIN/../ && pwd)" CONF=$TOP/conf LIB=$TOP/lib +. "${BIN}"/util.sh + +configure_riscv64_libatomic || exit 1 + if [ -n "$JAVA_HOME" ]; then JAVA="$JAVA_HOME"/bin/java else JAVA=java fi -conf=$1 if [ $# -eq 0 ]; then - conf=$CONF/hugegraph.properties + set -- "$CONF/graphs/hugegraph.properties" fi +conf=$1 cd $TOP @@ -47,5 +51,5 @@ echo "Dumping HugeGraph Store($conf)..." dump_store_ext_jar_path=$LIB/hugegraph-dist-*.jar for i in $LIB/*.jar; do dump_store_ext_jar_path=$dump_store_ext_jar_path:$i; export dump_store_ext_jar_path; done -exec $JAVA -cp dump_store_ext_jar_path \ -org.apache.hugegraph.cmd.StoreDumper $conf $2 $3 $4 +exec "$JAVA" -cp "$dump_store_ext_jar_path" \ +org.apache.hugegraph.cmd.StoreDumper "$@" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh index b4faf7785f..7cf09e30ee 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-native-runtime-smoke-test.sh @@ -30,6 +30,7 @@ EXPECTED_JAVA_MAJOR=${EXPECTED_JAVA_MAJOR:-11} SERVER_START_ATTEMPTED=false SERVER_STARTUP_TIMEOUT=${SERVER_STARTUP_TIMEOUT:-300} SERVER_START_COMMAND_TIMEOUT=$((SERVER_STARTUP_TIMEOUT + 30)) +STORE_DUMP_TIMEOUT=${STORE_DUMP_TIMEOUT:-120} WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-native-runtime-smoke.XXXXXX") RUN_ID="$(date +%s)_$$" @@ -66,6 +67,13 @@ start_server grep -q '^server-e2e-smoke-create-ok$' "$WORK_DIR/create.log" "$SERVER_DIR/bin/stop-hugegraph.sh" -m false +timeout --foreground --kill-after=15s "${STORE_DUMP_TIMEOUT}s" \ + "$SERVER_DIR/bin/dump-store.sh" | tee "$WORK_DIR/store-dump.log" +grep -q 'Dump table VERTEX (offset 0 limit 20):' "$WORK_DIR/store-dump.log" +grep -Fq "riscv-smoke-v1-$RUN_ID" "$WORK_DIR/store-dump.log" +grep -Fq "riscv-smoke-v2-$RUN_ID" "$WORK_DIR/store-dump.log" +echo "store-dump-smoke-ok" + start_server "$TRAVIS_DIR/run-server-e2e-smoke-test.sh" "$SERVER_URL" verify "$RUN_ID" | \ tee "$WORK_DIR/verify.log" From 87ec3519c589607854757ab59162e270a9c9e08e Mon Sep 17 00:00:00 2001 From: Sean Date: Fri, 24 Jul 2026 20:37:48 +0800 Subject: [PATCH 10/10] fix(server): clarify RISC-V glibc validation --- hugegraph-server/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hugegraph-server/README.md b/hugegraph-server/README.md index 74d09e7458..ef6c9f111d 100644 --- a/hugegraph-server/README.md +++ b/hugegraph-server/README.md @@ -33,9 +33,9 @@ See [docker/README.md](../docker/README.md) for the full setup guide. ## RISC-V Development and Testing -The RISC-V validation target is 64-bit `linux/riscv64` LP64D with glibc 2.30 or newer, -HugeGraph Server, and the embedded RocksDB backend. PD, Store, HStore, other backends, -musl/Alpine, and 32-bit RISC-V are out of scope. +The end-to-end RISC-V CI validation currently runs on 64-bit `linux/riscv64` LP64D with +Ubuntu 24.04 and glibc 2.39. It covers HugeGraph Server and the embedded RocksDB backend. +PD, Store, HStore, other backends, musl/Alpine, and 32-bit RISC-V are out of scope. The dedicated [RISC-V Server CI](../.github/workflows/riscv64-ci.yml) runs a RocksDB-only native build and runtime smoke test in an isolated QEMU environment. It uses the @@ -43,6 +43,10 @@ checksum-pinned Alibaba Dragonwell 11 Extended Server VM and installs `libatomic packaged RocksDB JNI library. QEMU is for correctness testing and is not a performance benchmark. +The packaged `rocksdbjni:8.10.2` RISC-V ELF references glibc symbols through +`GLIBC_2.30`. This is an inferred minimum for that JNI artifact only, not a validated +compatibility floor for the complete HugeGraph, Dragonwell, and system-library runtime. + The repository Dockerfile and published HugeGraph image do not include RISC-V support. Image publication requires separate multi-architecture design and validation.