diff --git a/.github/testcases-env b/.github/testcases-env new file mode 100644 index 0000000..b272199 --- /dev/null +++ b/.github/testcases-env @@ -0,0 +1,74 @@ +# Basenet settings +LOCAL_DOMAIN=neofs.devenv +IPV4_PREFIX=192.168.130 +CA_CERTS_TRUSTED_STORE=${PWD}/vendor/certs + +# Bastion image +BASTION_VERSION=10 +BASTION_IMAGE=debian + +# Flag to enable metabase resync on start +RESYNC_METABASE=false + +# NeoGo privnet +#CHAIN_PATH="/path/to/devenv.dump.gz" +CHAIN_URL="https://github.com/nspcc-dev/neofs-contract/releases/download/v0.17.0/devenv_mainchain.gz" + +#NEOGO +NEOGO_VERSION=0.102.0 +NEOGO_IMAGE=nspccdev/neo-go +NEO_GO_PLATFORM=linux-amd64 +NEO_GO_URL=https://github.com/nspcc-dev/neo-go/releases/download/v${NEOGO_VERSION}/neo-go-${NEO_GO_PLATFORM} + +# NeoFS InnerRing nodes +IR_VERSION=0.38.1 +IR_IMAGE=nspccdev/neofs-ir + +# NeoFS Storage nodes +NODE_VERSION=0.38.1 +NODE_IMAGE=nspccdev/neofs-storage +NODE_PLATFORM=amd64 + +# NATS Server +NATS_VERSION=2.7.2 +NATS_IMAGE=nats + +# HTTP Gate +HTTP_GW_VERSION=_TAG_ +HTTP_GW_IMAGE=nspccdev/neofs-http-gw + +# REST Gate +REST_GW_VERSION=0.5.0 +REST_GW_IMAGE=nspccdev/neofs-rest-gw + +# S3 Gate +S3_GW_VERSION=0.28.2 +S3_GW_IMAGE=nspccdev/neofs-s3-gw +S3_GW_PLATFORM=linux-amd64 +S3_GW_HOST=s3.neofs.devenv +S3_GW_PORT=8080 +S3_GW_TLS=True + +# Coredns +COREDNS_VERSION=v016 +COREDNS_IMAGE=nspccdev/coredns + +# NeoFS LOCODE database +LOCODE_DB_URL=https://github.com/nspcc-dev/neofs-locode-db/releases/download/v0.3.0/locode_db.gz + +# NeoFS CLI binary +NEOFS_CLI_URL=https://github.com/nspcc-dev/neofs-node/releases/download/v${NODE_VERSION}/neofs-cli-${NODE_PLATFORM}.tar.gz + +# NeoFS adm binary +NEOFS_ADM_URL=https://github.com/nspcc-dev/neofs-node/releases/download/v${NODE_VERSION}/neofs-adm-${NODE_PLATFORM}.tar.gz + +# Compiled NeoFS Smart Contracts +NEOFS_CONTRACTS_VERSION=v0.17.0 +NEOFS_CONTRACTS_URL=https://github.com/nspcc-dev/neofs-contract/releases/download/${NEOFS_CONTRACTS_VERSION}/neofs-contract-${NEOFS_CONTRACTS_VERSION}.tar.gz + +# Control service addresses used for healthchecks +NEOFS_IR_CONTROL_GRPC_ENDPOINT=127.0.0.1:16512 +NEOFS_STORAGE_CONTROL_GRPC_ENDPOINT_1=s01.${LOCAL_DOMAIN}:8081 +NEOFS_STORAGE_CONTROL_GRPC_ENDPOINT_2=s02.${LOCAL_DOMAIN}:8081 +NEOFS_STORAGE_CONTROL_GRPC_ENDPOINT_3=s03.${LOCAL_DOMAIN}:8081 +NEOFS_STORAGE_CONTROL_GRPC_ENDPOINT_4=s04.${LOCAL_DOMAIN}:8081 diff --git a/.github/workflows/system-tests.yml b/.github/workflows/system-tests.yml new file mode 100644 index 0000000..3ea8c52 --- /dev/null +++ b/.github/workflows/system-tests.yml @@ -0,0 +1,321 @@ +name: Run automated system tests + +on: + push: + branches: + - master + pull_request: + branches: + - master + - support/** + types: [opened, synchronize] + paths-ignore: + - '**/*.md' + release: + types: + - published + workflow_dispatch: + inputs: + neofs-http-gw_ref: + description: 'neofs-http-gw ref. Default ref - latest master. Examples: v0.27.0, 8fdcc6d7e798e6511be8806b81894622e72d7fdc, branch_name' + required: false + default: '' + +permissions: write-all + +jobs: + run_system_tests: + runs-on: ubuntu-latest + timeout-minutes: 500 + steps: + - name: Get the current date + id: date + run: echo "::set-output name=timestamp::$(date +%s)" + + - name: Set RUN_ID + env: + TIMESTAMP: ${{ steps.date.outputs.timestamp }} + run: echo "RUN_ID=${{ github.run_number }}-$TIMESTAMP" >> $GITHUB_ENV + + - name: Checkout neofs-testcases repository + uses: actions/checkout@v3 + with: + repository: nspcc-dev/neofs-testcases + ref: master + path: neofs-testcases + + - name: Checkout neofs-http-gw repository + uses: actions/checkout@v3 + with: + repository: nspcc-dev/neofs-http-gw + ref: master + path: neofs-http-gw + + - name: Checkout neofs-dev-env repository + uses: actions/checkout@v3 + with: + repository: nspcc-dev/neofs-dev-env + ref: master + path: neofs-dev-env + + - name: Download latest stable neofs-s3-authmate for uploading reports to NeoFS + uses: dsaltares/fetch-gh-release-asset@1.1.1 + with: + repo: 'nspcc-dev/neofs-s3-gw' + version: 'tags/v0.28.2' + file: 'neofs-s3-authmate-linux-amd64' + target: 'neofs-dev-env/vendor/neofs-s3-authmate' + + - name: Download latest stable neofs-cli for uploading reports to NeoFS + uses: dsaltares/fetch-gh-release-asset@1.1.1 + with: + repo: 'nspcc-dev/neofs-node' + version: 'tags/v0.38.1' + file: 'neofs-cli-amd64' + target: 'neofs-dev-env/vendor/neofs-cli' + + - name: Chmod latest stable binaries + run: | + sudo chmod a+x neofs-cli + sudo chmod a+x neofs-s3-authmate + echo "$(pwd)" >> $GITHUB_PATH + working-directory: neofs-dev-env/vendor + +################################################################# + - name: Set up Go + uses: actions/setup-go@v4 + with: + cache: true + go-version: '1.20' + - run: go version + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10.11' + - run: python --version + +# Hashlib uses OpenSSL for ripemd160 and apparently OpenSSL disabled some older crypto algos around version 3.0 +# in November 2021. All the functions are still there but require manual enabling. +# See https://github.com/openssl/openssl/issues/16994 +# But we use ripemd160 for tests. +# For ripemd160 to be supported, we need the openssl configuration file to contain the following lines: +# openssl_conf = openssl_init +# +# [openssl_init] +# providers = provider_sect +# +# [provider_sect] +# default = default_sect +# legacy = legacy_sect +# +# [default_sect] +# activate = 1 +# +# [legacy_sect] +# activate = 1 + - name: Fix OpenSSL ripemd160 + run: | + sudo python ./tools/src/openssl_config_fix.py + working-directory: neofs-testcases + +################################################################ + - name: Get TAG for docker images + run: | + echo "CURRENT_TAG=$( make version | sed 's/^v//' )" >> $GITHUB_ENV + working-directory: neofs-http-gw + + - name: Build neofs-http-gw docker image + run: | + make image + working-directory: neofs-http-gw + + - name: Add NeoFS HTTP-gw TAGs to env config + run: | + sed -i -e 's/HTTP_GW_VERSION=_TAG_/HTTP_GW_VERSION=${{ env.CURRENT_TAG }}/' .github/testcases-env + working-directory: neofs-http-gw + + - name: Copy testcases-env file to .env for neofs-dev-env + run: | + cp .github/testcases-env ${GITHUB_WORKSPACE}/neofs-dev-env/.env + working-directory: neofs-http-gw + +################################################################ + + - name: Prepare hosts + timeout-minutes: 5 + run: | + make get + sudo ./bin/update_hosts.sh + sudo chmod a+w vendor/hosts + sudo chmod -R a+x vendor + working-directory: neofs-dev-env + + - name: Add pytest-timeout to requirements + run: | + echo "pytest-timeout==2.1.0" >> requirements.txt + working-directory: neofs-testcases + + - name: Prepare venv + timeout-minutes: 30 + run: | + make venv.local-pytest + working-directory: neofs-testcases + + - name: Prepare Dev-Env to run tests + id: prepare_test_env + timeout-minutes: 30 + run: | + make prepare-test-env + working-directory: neofs-dev-env + +################################################################ + - name: Log environment + run: | + echo "Check free space" + df -h + echo "==========================================" + + echo "Check /etc/hosts" + cat /etc/hosts + echo "==========================================" + + echo "Check docker images" + docker images + echo "==========================================" + + echo "Check docker ps" + docker ps + echo "==========================================" + + echo "Check neo-go version" + neo-go --version + echo "==========================================" + + echo "Check neofs-s3-authmate version" + neofs-s3-authmate --version + echo "==========================================" + + echo "Check neofs-adm version" + neofs-adm --version + echo "==========================================" + + echo "Check neofs-cli version" + neofs-cli --version + echo "==========================================" + + echo "Check vendor dir" + ls -lah "${GITHUB_WORKSPACE}/neofs-dev-env/vendor" + echo "==========================================" + + working-directory: neofs-dev-env + +################################################################ + - name: Run all tests + timeout-minutes: 120 + run: | + source venv.local-pytest/bin/activate + pytest --show-capture=no --alluredir=${GITHUB_WORKSPACE}/allure-results pytest_tests/testsuites/services/http_gate + working-directory: neofs-testcases + +################################################################ + - name: Generate Allure report + timeout-minutes: 60 + uses: simple-elf/allure-report-action@v1.6 + if: always() + id: allure-report + with: + keep_reports: 100000 + allure_results: allure-results + allure_report: allure-report + allure_history: allure-history + + - name: Create wallet + if: always() + env: + TEST_RESULTS_WALLET: ${{ secrets.TEST_RESULTS_WALLET }} + run: | + echo "$TEST_RESULTS_WALLET" | base64 -d > wallet.json + working-directory: neofs-testcases + + - name: Define expiration + if: always() + env: + TEST_RESULTS_NEOFS_NETWORK_DOMAIN: ${{ vars.TEST_RESULTS_NEOFS_NETWORK_DOMAIN }} + MASTER_EXPIRATION_PERIOD: ${{ vars.MASTER_EXPIRATION_PERIOD }} + PR_EXPIRATION_PERIOD: ${{ vars.PR_EXPIRATION_PERIOD }} + MANUAL_RUN_EXPIRATION_PERIOD: ${{ vars.MANUAL_RUN_EXPIRATION_PERIOD }} + OTHER_EXPIRATION_PERIOD: ${{ vars.OTHER_EXPIRATION_PERIOD }} + run: | + CURRENT_EPOCH=$(neofs-cli netmap epoch --rpc-endpoint st1.$TEST_RESULTS_NEOFS_NETWORK_DOMAIN:8080) + if [[ "${{ github.event_name }}" == "push" ]]; then + EXP_EPOCH=$((MASTER_EXPIRATION_PERIOD + CURRENT_EPOCH)) + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + EXP_EPOCH=$((PR_EXPIRATION_PERIOD + CURRENT_EPOCH)) + elif [[ "${{ github.event_name }}" == "release" ]]; then + EXP_EPOCH=0 # For test reports from releases - no expiration period + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + EXP_EPOCH=$((MANUAL_RUN_EXPIRATION_PERIOD + CURRENT_EPOCH)) + else + EXP_EPOCH=$((OTHER_EXPIRATION_PERIOD + CURRENT_EPOCH)) + fi + echo "EXP_EPOCH=$EXP_EPOCH" >> $GITHUB_ENV + working-directory: neofs-testcases + + - name: Put allure report to NeoFS + id: put_report + if: always() && steps.prepare_test_env.outcome == 'success' + env: + TEST_RESULTS_PASSWORD: ${{ secrets.TEST_RESULTS_PASSWORD }} + TEST_RESULTS_NEOFS_NETWORK_DOMAIN: ${{ vars.TEST_RESULTS_NEOFS_NETWORK_DOMAIN }} + TEST_RESULTS_CID: ${{ vars.TEST_RESULTS_CID }} + run: | + sudo chmod -R a+rw ${GITHUB_WORKSPACE}/allure-report + source venv.local-pytest/bin/activate && python ./tools/src/process-allure-reports.py \ + --expire-at $EXP_EPOCH --neofs_domain $TEST_RESULTS_NEOFS_NETWORK_DOMAIN --run_id $RUN_ID \ + --cid $TEST_RESULTS_CID --allure_report ${GITHUB_WORKSPACE}/allure-report --wallet wallet.json + working-directory: neofs-testcases + + - name: Post the link to the report + id: post_report_link + timeout-minutes: 60 + if: always() && steps.put_report.outcome == 'success' + env: + TEST_RESULTS_HTTP_GATE: ${{ vars.TEST_RESULTS_HTTP_GATE }} + TEST_RESULTS_CID: ${{ vars.TEST_RESULTS_CID }} + uses: Sibz/github-status-action@v1 + with: + authToken: ${{secrets.GITHUB_TOKEN}} + context: 'Test report' + state: 'success' + sha: ${{github.event.pull_request.head.sha || github.sha}} + target_url: https://${{ env.TEST_RESULTS_HTTP_GATE }}/${{ env.TEST_RESULTS_CID }}/${{ env.RUN_ID }}/index.html + + - name: Post only docker logs + id: post_dockers_logs + if: always() && ( steps.prepare_test_env.outcome != 'success' || steps.put_report.outcome != 'success' ) + env: + TEST_RESULTS_PASSWORD: ${{ secrets.TEST_RESULTS_PASSWORD }} + TEST_RESULTS_NEOFS_NETWORK_DOMAIN: ${{ vars.TEST_RESULTS_NEOFS_NETWORK_DOMAIN }} + TEST_RESULTS_CID: ${{ vars.TEST_RESULTS_CID }} + run: | + source venv.local-pytest/bin/activate && python ./tools/src/zip_dev_env_logs.py + NEOFS_CLI_PASSWORD=$TEST_RESULTS_PASSWORD neofs-cli --rpc-endpoint st1.$TEST_RESULTS_NEOFS_NETWORK_DOMAIN:8080 \ + --wallet wallet.json object put --file containers_logs.zip --cid $TEST_RESULTS_CID --timeout 1200s \ + --expire-at $EXP_EPOCH \ + --attributes FilePath=$RUN_ID/data/containers_logs.zip,RunNumber=$RUN_ID,ContentType=application/zip + working-directory: neofs-testcases + + - name: Post the link to the docker logs + timeout-minutes: 60 + if: always() && ( steps.post_dockers_logs.outcome == 'success' ) + env: + TEST_RESULTS_HTTP_GATE: ${{ vars.TEST_RESULTS_HTTP_GATE }} + TEST_RESULTS_CID: ${{ vars.TEST_RESULTS_CID }} + uses: Sibz/github-status-action@v1 + with: + authToken: ${{secrets.GITHUB_TOKEN}} + context: 'Docker logs' + state: 'success' + sha: ${{github.event.pull_request.head.sha || github.sha}} + target_url: https://${{ env.TEST_RESULTS_HTTP_GATE }}/${{ env.TEST_RESULTS_CID }}/${{ env.RUN_ID }}/data/containers_logs.zip