diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..0441a3d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,105 @@ +name: Systems test workflow + +on: + workflow_call: + inputs: + # the pre-compiled image to use of quickstart, or the git ref to build + # from source. + # TODO: allow other versions +# SYSTEM_TEST_QUICKSTART_IMAGE: +# required: true +# type: string + # TODO allow building from source + # SYSTEM_TEST_QUICKSTART_GIT_REF: "https://github.com/stellar/quickstart.git#master" + + + # the version of components built in quickstart. only used if quickstart + # is configured above to build from source. + # SYSTEM_TEST_PROTOCOL_VERSION_DEFAULT: 21 + # SYSTEM_TEST_RS_XDR_GIT_REF: v21.0.1 + # SYSTEM_TEST_CORE_IMAGE: + # SYSTEM_TEST_CORE_GIT_REF: https://github.com/stellar/stellar-core.git#v21.0.0rc1 + # SYSTEM_TEST_CORE_COMPILE_CONFIGURE_FLAGS: "--disable-tests" + # SYSTEM_TEST_SOROBAN_RPC_REF: https://github.com/stellar/soroban-rpc.git#v21.0.1 + + # the soroban CLI source code to compile and run from system test + # refers to checked out source of current GitHub ref context or branch + SOROBAN_CLI_REF: + type: string + SOROBAN_CLI_BRANCH: + type: string + default: main + + # TODO: do we still want it? + # sets the version of rust toolchain that will be pre-installed in the + # test runtime environment, tests invoke rustc/cargo +# SYSTEM_TEST_RUST_TOOLCHAIN_VERSION: +# required: true +# type: string +# default: stable + + + # set the version of js-stellar-sdk to use, need to choose one of either + # resolution options, using npm release or a gh ref: + # option #1, set the version of stellar-sdk based on a npm release version + JS_STELLAR_SDK_NPM_VERSION: + type: string + default: 12.2.0 + + # TODO allow other options + # option #2, set the version of stellar-sdk used as a ref to a gh repo if + # a value is set on SYSTEM_TEST_JS_STELLAR_SDK_GH_REPO, it takes + # precedence over any SYSTEM_TEST_JS_STELLAR_SDK_NPM_VERSION + # SYSTEM_TEST_JS_STELLAR_SDK_GH_REPO: + # SYSTEM_TEST_JS_STELLAR_SDK_GH_REF: + + # triggers system test to log out details from quickstart's logs and test steps + # TODO + #VERBOSE_OUTPUT: + # type: boolean + # default: true + + # TODO + # the soroban test cases will compile various contracts from the examples repo + # SOROBAN_EXAMPLES_GIT_HASH: + #type: string + +jobs: + systems-test: + # TODO: allow other runners + runs-on: ubuntu-latest + # TODO: allow other versions + services: + rpc: + image: stellar/quickstart:testing + ports: + - 8000:8000 + env: + ENABLE_LOGS: true + NETWORK: local + ENABLE_SOROBAN_RPC: true + options: >- + --health-cmd "curl --no-progress-meter --fail-with-body -X POST \"http://localhost:8000/rpc\" -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":8675309,\"method\":\"getNetwork\"}' && curl --no-progress-meter \"http://localhost:8000/friendbot\" | grep '\"invalid_field\": \"addr\"'" + --health-interval 10s + --health-timeout 5s + --health-retries 50 + steps: + - uses: actions/checkout@v4 + - uses: stellar/actions/rust-cache@main + - run: sudo apt update && sudo apt install -y libudev-dev libdbus-1-dev + - run: rustup update + - run: cargo install --git https://github.com/stellar/stellar-cli soroban-cli --rev ${{ inputs.SOROBAN_CLI_REF }} + if: ${{ inputs.SOROBAN_CLI_REF != '' }} + - run: cargo install --git https://github.com/stellar/stellar-cli soroban-cli --branch ${{ inputs.SOROBAN_CLI_BRANCH }} + if: ${{ inputs.SOROBAN_CLI_REF == '' }} + - run: go mod download + - run: | + go test -c -o ./bin/dapp_develop_test.bin ./features/dapp_develop/... + cp features/dapp_develop/dapp_develop.feature ./bin + cp features/dapp_develop/soroban_config.exp ./bin + cp invoke.ts ./bin + cp events.ts ./bin + - run: npm install -g ts-node + - run: yarn add "@stellar/stellar-sdk@${{ inputs.JS_STELLAR_SDK_NPM_VERSION }}" --network-concurrency 1 + # TODO: get rid of the script + - run: ./start-ci diff --git a/.github/workflows/systems-test.yml b/.github/workflows/systems-test.yml new file mode 100644 index 0000000..4f028dd --- /dev/null +++ b/.github/workflows/systems-test.yml @@ -0,0 +1,15 @@ +name: Systems test + +on: + push: + branches: [main, release/**] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_protected == 'true' && github.sha || github.ref }} + cancel-in-progress: true + +jobs: + systems-test: + name: System tests + uses: ./.github/workflows/main.yml diff --git a/start-ci b/start-ci new file mode 100755 index 0000000..cb72a47 --- /dev/null +++ b/start-ci @@ -0,0 +1,167 @@ +#! /usr/bin/env bash +set -e +set -o pipefail + +# the versions of software that tests will use +SOROBAN_EXAMPLES_GIT_HASH="main" +SOROBAN_EXAMPLES_REPO_URL="https://github.com/stellar/soroban-examples.git" +DEBUG_MODE= + +# the target network under test +# TODO: support other networks +TARGET_NETWORK_PASSPHRASE="Standalone Network ; February 2017" +TARGET_NETWORK_SECRET_KEY="SC5O7VZUXDJ6JBDSZ74DSERXL7W3Y5LTOAMRF7RQRL3TAGAPS7LUVG3L" +TARGET_NETWORK_PUBLIC_KEY="GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI" +TARGET_NETWORK_RPC_URL="http://localhost:8000/soroban/rpc" +QUICKSTART_LOG_FILE=/var/log/system-test-quickstart.log +LOCAL_CORE=false +ENABLE_SOROBAN_DIAGNOSTIC_EVENTS=--enable-soroban-diagnostic-events + +# example filter for all combos of one scenario outline: ^TestDappDevelop$/^DApp developer compiles, deploys and invokes a contract.*$ +# each row in example data for a scenario outline is postfixed with '#01', '#02', example: +# TestDappDevelop/DApp developer compiles, deploys and invokes a contract#01 +TEST_FILTER="" +VERBOSE_OUTPUT=false +CANCELLED=false +# the relative path to runtime directory on image that feature files will be found at +# these files are aggregated into this directory by Dockerfile +FEATURE_PATH=. + +function print_screen_output() { + echo "$1" +} + +print_screen_output "Starting system test ..." + +trap printout SIGINT +printout() { + echo "Cancelling and exit." + exit 1 +} + +function main() { + process_args "$@" + + if [ ! -z "$TARGET_NETWORK_RPC_URL" ] && [ ! -z "$TARGET_NETWORK" ]; then + echo "Invalid TargetNetwork config, must set TargetNetwork or TargetNetworkRPCURL, aborting test ..." >&2 + exit 1 + fi + + stellar_rpc_status + + print_screen_output " RUST_TOOLCHAIN_VERSION=$(rustc --version 2>/dev/null || echo"n/a" )" + print_screen_output " SOROBAN_CLI_CRATE_VERSION=$(soroban version 2>/dev/null || echo "n/a" )" + print_screen_output " SOROBAN_EXAMPLES_GIT_HASH=$SOROBAN_EXAMPLES_GIT_HASH" + print_screen_output " SOROBAN_EXAMPLES_REPO_URL=$SOROBAN_EXAMPLES_REPO_URL" + print_screen_output " TARGET_NETWORK_PASSPHRASE=$TARGET_NETWORK_PASSPHRASE" + print_screen_output " TARGET_NETWORK_SECRET_KEY=$TARGET_NETWORK_SECRET_KEY" + print_screen_output " TARGET_NETWORK_PUBLIC_KEY=$TARGET_NETWORK_PUBLIC_KEY" + print_screen_output " TARGET_NETWORK_RPC_URL=$TARGET_NETWORK_RPC_URL" + print_screen_output " TEST_FILTER=${TEST_FILTER}" + print_screen_output "Tests can now begin ..." + + cd ./bin + + export SorobanExamplesGitHash=${SOROBAN_EXAMPLES_GIT_HASH} + export SorobanExamplesRepoURL=${SOROBAN_EXAMPLES_REPO_URL} + export TargetNetworkPassPhrase="${TARGET_NETWORK_PASSPHRASE}" + export TargetNetworkSecretKey=${TARGET_NETWORK_SECRET_KEY} + export TargetNetworkPublicKey=${TARGET_NETWORK_PUBLIC_KEY} + export TargetNetworkRPCURL=${TARGET_NETWORK_RPC_URL} + export VerboseOutput=${VERBOSE_OUTPUT} + export LocalCore=${LOCAL_CORE} + export FeaturePath=${FEATURE_PATH} + + for file in ./*; + do + if [ "$CANCELLED" = "true" ]; then + break + fi + + if [[ "$file" =~ ^.*\.bin$ ]]; then + # these bin files were compiled from go feature tests in the Dockerfile during image build + print_screen_output "Running test binary ${file} ... " + ${file} -test.v ${TEST_FILTER} + fi + done +} + +function process_args() { + while [[ -n "$1" ]]; do + ARG="$1" + shift + + case "${ARG}" in + --DebugMode) + DEBUG_MODE="$1" + shift + ;; + --SorobanExamplesGitHash) + SOROBAN_EXAMPLES_GIT_HASH="$1" + shift + ;; + --SorobanExamplesRepoURL) + SOROBAN_EXAMPLES_REPO_URL="$1" + shift + ;; + --TestFilter) + TEST_FILTER="-test.run ""$1""" + shift + ;; + --VerboseOutput) + VERBOSE_OUTPUT="$1" + shift + ;; + --TargetNetwork) + TARGET_NETWORK="$1" + shift + ;; + --TargetNetworkPassphrase) + TARGET_NETWORK_PASSPHRASE="$1" + shift + ;; + --TargetNetworkTestAccountSecret) + TARGET_NETWORK_SECRET_KEY="$1" + shift + ;; + --TargetNetworkTestAccountPublic) + TARGET_NETWORK_PUBLIC_KEY="$1" + shift + ;; + --TargetNetworkRPCURL) + TARGET_NETWORK_RPC_URL="$1" + shift + ;; + *) + esac + done +} + +function stellar_rpc_status () { + print_screen_output "waiting for soroban rpc to report ready state..." + COUNTER=1 + while ! $(curl --silent --location --request POST "$TARGET_NETWORK_RPC_URL" \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "jsonrpc": "2.0", + "id": 10235, + "method": "getHealth" + + }' | jq --exit-status '.result.status == "healthy"' 2>/dev/null | grep -o true || echo false ); + do + if [ $(expr $COUNTER % 12) -eq 0 ]; then + print_screen_output "waited $(expr $COUNTER / 12) minutes for Stellar RPC to report ready state..." + fi + COUNTER=$[$COUNTER +1] + + if [ $COUNTER -gt 900 ]; then + echo "Waited longer than 15 minutes for Stellar RPC, cancelling and exit." + exit 1 + fi + + sleep 5 + done + print_screen_output "Stellar RPC reported ready status, the service can be used by tools/cli now ..." +} + +main "$@"