Skip to content

ZXC: E2E Test

ZXC: E2E Test #14

Workflow file for this run

##
# Copyright (C) 2023-2024 Hedera Hashgraph, LLC
#
# Licensed 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: "ZXC: E2E Test"
# The purpose of this reusable workflow is to run the e2e tests on every PR and commit.
# This reusable component is called by the following workflows:
# - .github/workflows/flow-pull-request-checks.yaml
# - .github/workflows/flow-build-application.yaml
on:
workflow_dispatch:
inputs:
node-version:
description: "NodeJS Version:"
type: string
required: false
default: "20.19.3"
consensus-node-version:
description: "Consensus Node Version:"
type: string
required: false
default: ""
custom-job-label:
description: "Custom Job Label:"
type: string
required: false
default: "E2E Test"
test-script:
description: "NPM Test Run Script:"
type: string
required: false
default: "test-e2e-standard"
coverage-subdirectory:
description: "Coverage Report Subdirectory:"
type: string
required: false
default: "e2e"
coverage-report-name:
description: "Coverage Report Name:"
type: string
required: false
default: "E2E Tests Coverage Report"
cluster-name:
description: "Cluster Name:"
type: string
required: false
default: "solo-e2e"
workflow_call:
inputs:
node-version:
description: "NodeJS Version:"
type: string
required: false
default: "20.19.3"
consensus-node-version:
description: "Consensus Node Version:"
type: string
required: false
default: ""
custom-job-label:
description: "Custom Job Label:"
type: string
required: false
default: "E2E Test"
test-script:
description: "NPM Test Run Script:"
type: string
required: false
default: "test-e2e-standard"
coverage-subdirectory:
description: "Coverage Report Subdirectory:"
type: string
required: false
default: "e2e"
coverage-report-name:
description: "Coverage Report Name:"
type: string
required: false
default: "E2E Tests Coverage Report"
local-java-build:
description: "Build Local Java Code:"
type: boolean
required: false
default: false
cluster-name:
description: "Cluster Name:"
type: string
required: false
default: "solo-e2e"
defaults:
run:
shell: bash
permissions:
id-token: write
contents: read
actions: read
pull-requests: write
checks: write
statuses: write
env:
#CG_EXEC: export R_UID=$(id -u); CGROUP_LOGLEVEL=DEBUG cgexec -g cpu,memory:user.slice/user-${R_UID}.slice/user@${R_UID}.service/e2e-${{ github.run_id }} --sticky ionice -c 2 -n 2 nice -n 19
CG_EXEC: "ionice -c 2 -n 2 nice -n 19"
SOLO_CLUSTER_DUALITY: ${{ inputs.test-script == 'test-e2e-dual-cluster-full' && 2 || 1 }}
jobs:
e2e-test:
name: ${{ inputs.custom-job-label || 'E2E Test' }}
runs-on: hiero-solo-linux-large
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Checkout Code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Setup Control Groups
# run: |
# echo "::group::Get System Configuration"
# USR_ID="$(id -un)"
# GRP_ID="$(id -gn)"
# E2E_MEM_LIMIT="30064771072"
# AGENT_MEM_LIMIT="2147483648"
# USER_SLICE="user.slice/user-$(id -u).slice"
# USER_SERVICE="${USER_SLICE}/user@$(id -u).service"
# E2E_GROUP_NAME="${USER_SERVICE}/e2e-${{ github.run_id }}"
# AGENT_GROUP_NAME="${USER_SERVICE}/agent-${{ github.run_id }}"
# echo "::endgroup::"
#
# echo "::group::Install Control Group Tools"
# if ! command -v cgcreate >/dev/null 2>&1; then
# sudo apt-get update
# sudo apt-get install -y cgroup-tools
# fi
# echo "::endgroup::"
#
# echo "::group::Create Control Groups"
# sudo cgcreate -g cpu,memory:${USER_SLICE} -a ${USR_ID}:${GRP_ID} -t ${USR_ID}:${GRP_ID}
# sudo cgcreate -g cpu,memory:${USER_SERVICE} -a ${USR_ID}:${GRP_ID} -t ${USR_ID}:${GRP_ID}
# sudo cgcreate -g cpu,memory:${E2E_GROUP_NAME} -a ${USR_ID}:${GRP_ID} -t ${USR_ID}:${GRP_ID}
# sudo cgcreate -g cpu,memory:${AGENT_GROUP_NAME} -a ${USR_ID}:${GRP_ID} -t ${USR_ID}:${GRP_ID}
# echo "::endgroup::"
#
# echo "::group::Set Control Group Limits"
# cgset -r cpu.weight=768 ${E2E_GROUP_NAME}
# cgset -r cpu.weight=500 ${AGENT_GROUP_NAME}
# cgset -r memory.max=${E2E_MEM_LIMIT} ${E2E_GROUP_NAME}
# cgset -r memory.max=${AGENT_MEM_LIMIT} ${AGENT_GROUP_NAME}
# cgset -r memory.swap.max=${E2E_MEM_LIMIT} ${E2E_GROUP_NAME}
# cgset -r memory.swap.max=${AGENT_MEM_LIMIT} ${AGENT_GROUP_NAME}
# echo "::endgroup::"
#
# echo "::group::Move Runner Processes to Control Groups"
# sudo cgclassify --sticky -g cpu,memory:${AGENT_GROUP_NAME} $(pgrep 'Runner.Listener' | tr '\n' ' ')
# sudo cgclassify -g cpu,memory:${AGENT_GROUP_NAME} $(pgrep 'Runner.Worker' | tr '\n' ' ')
# echo "::endgroup::"
- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ inputs.node-version }}
- name: Install wget
run: |
if ! command -v wget >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y wget
fi
- name: Setup Kind
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
with:
install_only: true
node_image: kindest/node:v1.31.4@sha256:2cb39f7295fe7eafee0842b1052a599a4fb0f8bcf3f83d96c7f4864c357c6c30
version: v0.26.0
kubectl_version: v1.31.4
verbosity: 3
wait: 120s
- name: Setup Helm
uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4.3.0
with:
version: "v3.17.1" # helm version
- name: Install Dependencies
id: npm-deps
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
max_attempts: 10
timeout_minutes: 10
command: |
npm ci
- name: Install Task
uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0
with:
version: 3.39.2
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: '1.22.3'
- name: Install grpcurl
run: |
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
- name: Compile Project
run: task build
- name: Pull Kind Docker Image
run: docker image pull kindest/node:v1.31.4@sha256:2cb39f7295fe7eafee0842b1052a599a4fb0f8bcf3f83d96c7f4864c357c6c30
- name: Setup Java
if: ${{ runner.os == 'linux' && inputs.local-java-build && !cancelled() && !failure() }}
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 21.0.1
- name: Setup Gradle
if: ${{ runner.os == 'linux' && inputs.local-java-build && !cancelled() && !failure() }}
uses: gradle/gradle-build-action@ac2d340dc04d9e1113182899e983b5400c17cda1 # v3.5.0
with:
cache-read-only: false
- name: Create Diagnostic Script
env:
WRITE_DIAG_SCRIPT: ${{ github.workspace }}/.github/workflows/script/write_diag_script.sh
run: |
sudo chmod +x "${WRITE_DIAG_SCRIPT}"
${WRITE_DIAG_SCRIPT}
- name: Build Hedera code locally
if: ${{ runner.os == 'linux' && inputs.local-java-build && !cancelled() && !failure() }}
run: |
if [ -z "${{ inputs.consensus-node-version }}" ]; then
export CONSENSUS_NODE_VERSION=$(grep 'TEST_LOCAL_HEDERA_PLATFORM_VERSION' version-test.ts | sed -E "s/.*'([^']+)';/\1/")
else
export CONSENSUS_NODE_VERSION=${{ inputs.consensus-node-version }}
fi
cd ..
git clone https://github.com/hiero-ledger/hiero-consensus-node.git --depth 1 --branch ${CONSENSUS_NODE_VERSION}
cd hiero-consensus-node
ls -ltr
${{ env.CG_EXEC }} ./gradlew assemble --stacktrace --info
cd ../solo
- name: Setup E2E Tests
if: ${{ inputs.test-script != 'test-external-database' && inputs.test-script != 'test-update-markdown' && !cancelled() }}
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
max_attempts: 3
timeout_minutes: 10
command: |
npm link
echo "SOLO_TEST_CLUSTER=${{ inputs.cluster-name }}"
SOLO_TEST_CLUSTER=${{ inputs.cluster-name }} ${{ env.CG_EXEC }} ./test/e2e/dual-cluster/setup-dual-e2e.sh
- name: Build Block code locally
if: ${{ runner.os == 'linux' && (inputs.test-script == 'test-e2e-block-node') && !cancelled() && !failure() }}
run: |
export TEST_LOCAL_BLOCK_NODE_VERSION=$(grep 'TEST_LOCAL_BLOCK_NODE_VERSION' version-test.ts | sed -E "s/.*'([^']+)';/\1/")
cd ..
git clone https://github.com/hiero-ledger/hiero-block-node.git --depth 1 --branch v${TEST_LOCAL_BLOCK_NODE_VERSION}
cd hiero-block-node
./gradlew :block-node-app:createDockerImage
kind get clusters
kind load docker-image block-node-server:${TEST_LOCAL_BLOCK_NODE_VERSION} --name ${{ inputs.cluster-name }}-c1
${{ env.CG_EXEC }} ./gradlew :block-node-app:createDockerImage
cd ../solo
- name: Run E2E Tests
run: |
if [ -z "${{ inputs.consensus-node-version }}" ]; then
export CONSENSUS_NODE_VERSION=$(grep 'TEST_LOCAL_HEDERA_PLATFORM_VERSION' version-test.ts | sed -E "s/.*'([^']+)';/\1/")
else
export CONSENSUS_NODE_VERSION=${{ inputs.consensus-node-version }}
fi
echo SOLO_TEST_CLUSTER=${{ inputs.cluster-name }}-c1 > .env
cat .env
${{ env.CG_EXEC }} task ${{ inputs.test-script }}
- name: Upload E2E Logs to GitHub
if: ${{ inputs.test-script != 'test-external-database' && inputs.test-script != 'test-update-markdown' && !cancelled() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: solo-${{ inputs.test-script }}.log
path: ~/.solo/logs/*
overwrite: true
if-no-files-found: error
- name: Upload E2E Test Report
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: ${{ inputs.test-script != 'test-external-database' && inputs.test-script != 'test-update-markdown' && steps.npm-deps.conclusion == 'success' && !cancelled() }}
with:
name: e2e_test_report_${{ inputs.test-script }}
path: "junit-${{ inputs.coverage-subdirectory }}.xml"
overwrite: true
if-no-files-found: error
- name: Publish E2E Coverage Report
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: ${{ inputs.test-script != 'test-external-database' && inputs.test-script != 'test-update-markdown' && !cancelled() }}
with:
name: ${{ inputs.coverage-report-name }}
path: 'coverage/${{ inputs.coverage-subdirectory }}'