diff --git a/.github/workflows/helm-charts.yaml b/.github/workflows/helm-charts.yaml index 7f71396e..7a3a4e87 100644 --- a/.github/workflows/helm-charts.yaml +++ b/.github/workflows/helm-charts.yaml @@ -18,7 +18,8 @@ name: Lint and Test Charts on: pull_request jobs: - lint-test: + lint-install-test: + name: Lint and Install Charts runs-on: ubuntu-latest steps: - name: Harden Runner diff --git a/.github/workflows/smoke-test.yaml b/.github/workflows/smoke-test.yaml new file mode 100644 index 00000000..e2935a07 --- /dev/null +++ b/.github/workflows/smoke-test.yaml @@ -0,0 +1,93 @@ +## +# Copyright (C) 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: "Smoke Test" +on: + push: + branches: + - main + - release/* + pull_request: + branches: + - "*" + +defaults: + run: + shell: bash + +env: + GRADLE_EXEC: ./gradlew + +jobs: + smoke-test: + name: "Smoke Tests" + runs-on: block-node-linux-medium + steps: + - name: Harden Runner + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + with: + egress-policy: audit + + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + fetch-depth: 0 + + - name: Expand Shallow Clone for Spotless + run: | + if [ -f .git/shallow ]; then + git fetch --unshallow --no-recurse-submodules + else + echo "Repository is not shallow, no need to unshallow." + fi + + - name: Set up JDK 21 + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + with: + distribution: 'temurin' + java-version: '21' + + - name: Install grpcurl + run: | + curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.7/grpcurl_1.8.7_linux_x86_64.tar.gz -o grpcurl.tar.gz + sudo tar -xzf grpcurl.tar.gz -C /usr/local/bin grpcurl + rm grpcurl.tar.gz + + + - name: Cache Gradle packages + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Build application + run: ${{ env.GRADLE_EXEC }} build + + - name: Run application in background, capture logs in app.log + run: | + ${{ env.GRADLE_EXEC }} run 2> server/src/test/resources/app.log < /dev/null & + echo "Application started with PID $APP_PID" + sleep 10 + + - name: Print App Logs + run: cat server/src/test/resources/app.log + + - name: Smoke Test + working-directory: server/src/test/resources/ + run: ./smoke-test.sh app.log diff --git a/server/src/test/resources/get-block.sh b/server/src/test/resources/get-block.sh new file mode 100755 index 00000000..c441d1ae --- /dev/null +++ b/server/src/test/resources/get-block.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +usage_error() { + echo "Usage: $0 " + exit 1 +} + +# An integer is expected as the first parameter +if [ "$#" -lt 1 ] || ! [[ "$1" =~ ^[0-9]+$ ]]; then + usage_error +fi + +# If the script reaches here, the parameters are valid +echo "Param is: $1" + +# Use environment variables or default values +GRPC_SERVER=${GRPC_SERVER:-"localhost:8080"} +GRPC_METHOD=${GRPC_METHOD:-"BlockStreamGrpcService/singleBlock"} +PATH_TO_PROTO=${PATH_TO_PROTO:-"../../../../protos/src/main/protobuf/blockstream.proto"} +PROTO_IMPORT_PATH=${PROTO_IMPORT_PATH:-"../../../../protos/src/main/protobuf"} + +echo "Requesting block $1..." + +# Response block messages from the gRPC server are printed to stdout. +echo "{\"block_number\": $1}" | grpcurl -plaintext -import-path $PROTO_IMPORT_PATH -proto $PATH_TO_PROTO -d @ $GRPC_SERVER $GRPC_METHOD diff --git a/server/src/test/resources/smoke-test.sh b/server/src/test/resources/smoke-test.sh new file mode 100755 index 00000000..efad6d9c --- /dev/null +++ b/server/src/test/resources/smoke-test.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# Variable to track whether shutdown has been called +SHUTDOWN_CALLED=0 + +# Function to shut down the background processes +shutdown() { + if [[ $SHUTDOWN_CALLED -eq 1 ]]; then + return + fi + SHUTDOWN_CALLED=1 + + echo "Shutting down background processes..." + + if [[ -n "$PRODUCER_PID" ]]; then + if kill -0 $PRODUCER_PID 2>/dev/null; then + kill $PRODUCER_PID + wait $PRODUCER_PID 2>/dev/null + echo "Producer process $PRODUCER_PID terminated." + else + echo "Error: Producer process $PRODUCER_PID has already terminated." + echo "Producer logs:" + cat producer.log + exit 1 + fi + fi + + if [[ -n "$CONSUMER_PID" ]]; then + if kill -0 $CONSUMER_PID 2>/dev/null; then + kill $CONSUMER_PID + wait $CONSUMER_PID 2>/dev/null + echo "Consumer process $CONSUMER_PID terminated." + else + echo "Error: Consumer process $CONSUMER_PID has already terminated." + echo "Consumer logs:" + cat consumer.log + exit 1 + fi + fi +} + +# Trap any exit signal to ensure everything is cleaned up +trap "shutdown; exit 1" ERR SIGINT SIGTERM + +# 1. Verify that the logs have the startup pattern (only if log file is provided) +LOG_FILE=$1 +STARTUP_PATTERN="Block Node Server started at port" + +if [[ -n "$LOG_FILE" ]]; then + if grep -q "$STARTUP_PATTERN" "$LOG_FILE"; then + echo "Startup pattern found in logs." + else + echo "Startup pattern not found in logs." + exit 1 + fi +else + echo "No log file provided, skipping startup pattern check." +fi + +# 2. Start the consumer script with parameters 1 1000 and save logs to consumer.log +./consumer.sh 1 1000 > consumer.log 2>&1 & +CONSUMER_PID=$! +echo "Started consumer with PID $CONSUMER_PID, logging to consumer.log" + +# 3. Start the producer script with parameter 1 and save logs to producer.log +./producer.sh 1 > producer.log 2>&1 & +PRODUCER_PID=$! +echo "Started producer with PID $PRODUCER_PID, logging to producer.log" + +# Sleep time after starting the consumer +sleep 5 # Adjust sleep time as needed + +# 4. Run the get-block script with parameter 1 and save logs to get-block.log +if ! ./get-block.sh 1 > get-block.log 2>&1; then + echo "get-block.sh failed." + echo "get-block logs:" + cat get-block.log + shutdown + exit 1 +fi +echo "get-block.sh executed successfully." + +# 5. Call the endpoints /health/liveness and /health/readiness +SERVER_URL="http://localhost:8080" +LIVENESS_ENDPOINT="/healthz/liveness" +READINESS_ENDPOINT="/healthz/readiness" + +if ! curl -f $SERVER_URL$LIVENESS_ENDPOINT; then + echo "$LIVENESS_ENDPOINT failed." + shutdown + exit 1 +fi +echo "$LIVENESS_ENDPOINT endpoint is healthy." + +if ! curl -f $SERVER_URL$READINESS_ENDPOINT; then + echo "$READINESS_ENDPOINT endpoint failed." + shutdown + exit 1 +fi +echo "$READINESS_ENDPOINT endpoint is ready." + +# 6. Shut everything down +shutdown + +# 7. Return success +echo "Smoke test completed successfully." +exit 0