diff --git a/.github/workflows/test_with_trezor-user-env.yml b/.github/workflows/test_with_trezor-user-env.yml index 86ac45a8e..734a45780 100644 --- a/.github/workflows/test_with_trezor-user-env.yml +++ b/.github/workflows/test_with_trezor-user-env.yml @@ -18,17 +18,17 @@ jobs: strategy: matrix: node-version: [12.x, 14.x, 16.x] - services: - trezor-user-env: - image: "ghcr.io/trezor/trezor-user-env:latest" - ports: - - 9001:9001 - - 21326:21326 - - 21325:21326 - env: - SDL_VIDEODRIVER: "dummy" - USE_TX_CACHE: true - USE_WS_CACHE: true + # services: + # trezor-user-env: + # image: "ghcr.io/trezor/trezor-user-env:latest" + # ports: + # - 9001:9001 + # - 21326:21326 + # - 21325:21326 + # env: + # SDL_VIDEODRIVER: "dummy" + # USE_TX_CACHE: true + # USE_WS_CACHE: true steps: - uses: actions/checkout@v2 with: @@ -40,23 +40,24 @@ jobs: cache: yarn cache-dependency-path: "**/yarn.lock" - run: yarn install + - run: "./docker/docker-connect-test.sh node -p ${{ inputs.test-pattern }} -i ${{ inputs.methods }}" # Use `-d` to disable Docker, since it's started under `trezor-user-env` - - run: ./tests/run.sh -d -s 'yarn test:integration ${{ inputs.test-pattern }}' -i '${{ inputs.methods }}' + # - run: ./tests/run.sh -d -s 'yarn test:integration ${{ inputs.test-pattern }}' -i '${{ inputs.methods }}' test-karma: name: Test Karma runs-on: ubuntu-latest - services: - trezor-user-env: - image: "ghcr.io/trezor/trezor-user-env:latest" - ports: - - 9001:9001 - - 21326:21326 - - 21325:21326 - env: - SDL_VIDEODRIVER: "dummy" - USE_TX_CACHE: true - USE_WS_CACHE: true + # services: + # trezor-user-env: + # image: "ghcr.io/trezor/trezor-user-env:latest" + # ports: + # - 9001:9001 + # - 21326:21326 + # - 21325:21326 + # env: + # SDL_VIDEODRIVER: "dummy" + # USE_TX_CACHE: true + # USE_WS_CACHE: true steps: - uses: actions/checkout@v2 with: @@ -74,7 +75,9 @@ jobs: with: name: build-artifact path: build + # - run: sudo apt-get install xvfb + - run: "./docker/docker-connect-test.sh web -p ${{ inputs.test-pattern }} -i ${{ inputs.methods }}" # xvfb is required to run karma - - run: sudo apt-get install xvfb + # - run: sudo apt-get install xvfb # Use `-d` to disable Docker, since it's started under `trezor-user-env` - - run: xvfb-run --auto-servernum ./tests/run.sh -d -s 'yarn test:karma:production ${{ inputs.test-pattern }}' -i '${{ inputs.methods }}' + # - run: xvfb-run --auto-servernum ./tests/run.sh -d -s 'yarn test:karma:production ${{ inputs.test-pattern }}' -i '${{ inputs.methods }}' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5749d0e13..1d92b5a40 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -151,138 +151,138 @@ publish beta release to npm: # Test -.jobs: - parallel: - matrix: - - TESTS_INCLUDED_METHODS: "applySettings,applyFlags,getFeatures" - - TESTS_INCLUDED_METHODS: "signTransaction" - - TESTS_INCLUDED_METHODS: "getAccountInfo,getAddress,getPublicKey,signMessage,verifyMessage,composeTransaction" - - TESTS_INCLUDED_METHODS: "stellarGetAddress,stellarSignTransaction" - - TESTS_INCLUDED_METHODS: "cardanoGetAddress,cardanoGetNativeScriptHash,cardanoGetPublicKey,cardanoSignTransaction" - - TESTS_INCLUDED_METHODS: "eosGetPublicKey,eosSignTransaction" - - TESTS_INCLUDED_METHODS: "ethereumGetAddress,ethereumGetPublicKey,ethereumSignMessage,ethereumSignTransaction,ethereumVerifyMessage,ethereumSignTypedData" - - TESTS_INCLUDED_METHODS: "nemGetAddress,nemSignTransaction" - - TESTS_INCLUDED_METHODS: "rippleGetAddress,rippleSignTransaction" - - TESTS_INCLUDED_METHODS: "tezosGetAddress,tezosGetPublicKey" - - TESTS_INCLUDED_METHODS: "binanceSignTransaction" - -.jobs-t1: - parallel: - matrix: - - TESTS_INCLUDED_METHODS: "applySettings,applyFlags,getFeatures" - - TESTS_INCLUDED_METHODS: "signTransaction" - - TESTS_INCLUDED_METHODS: "getAccountInfo,getAddress,getPublicKey,signMessage,verifyMessage,composeTransaction" - - TESTS_INCLUDED_METHODS: "ethereumGetAddress,ethereumGetPublicKey,ethereumSignMessage,ethereumSignTransaction,ethereumVerifyMessage,ethereumSignTypedData" +# .jobs: +# parallel: +# matrix: +# - TESTS_INCLUDED_METHODS: "applySettings,applyFlags,getFeatures" +# - TESTS_INCLUDED_METHODS: "signTransaction" +# - TESTS_INCLUDED_METHODS: "getAccountInfo,getAddress,getPublicKey,signMessage,verifyMessage,composeTransaction" +# - TESTS_INCLUDED_METHODS: "stellarGetAddress,stellarSignTransaction" +# - TESTS_INCLUDED_METHODS: "cardanoGetAddress,cardanoGetNativeScriptHash,cardanoGetPublicKey,cardanoSignTransaction" +# - TESTS_INCLUDED_METHODS: "eosGetPublicKey,eosSignTransaction" +# - TESTS_INCLUDED_METHODS: "ethereumGetAddress,ethereumGetPublicKey,ethereumSignMessage,ethereumSignTransaction,ethereumVerifyMessage,ethereumSignTypedData" +# - TESTS_INCLUDED_METHODS: "nemGetAddress,nemSignTransaction" +# - TESTS_INCLUDED_METHODS: "rippleGetAddress,rippleSignTransaction" +# - TESTS_INCLUDED_METHODS: "tezosGetAddress,tezosGetPublicKey" +# - TESTS_INCLUDED_METHODS: "binanceSignTransaction" -.jobs-api: - parallel: - matrix: - - TEST_PATTERN: "init" +# .jobs-t1: +# parallel: +# matrix: +# - TESTS_INCLUDED_METHODS: "applySettings,applyFlags,getFeatures" +# - TESTS_INCLUDED_METHODS: "signTransaction" +# - TESTS_INCLUDED_METHODS: "getAccountInfo,getAddress,getPublicKey,signMessage,verifyMessage,composeTransaction" +# - TESTS_INCLUDED_METHODS: "ethereumGetAddress,ethereumGetPublicKey,ethereumSignMessage,ethereumSignTransaction,ethereumVerifyMessage,ethereumSignTypedData" -.test: - extends: .jobs - image: ghcr.io/trezor/trezor-user-env - dependencies: - - "setup environment" - variables: - SDL_VIDEODRIVER: "dummy" - TESTS_USE_TX_CACHE: "false" - TESTS_USE_WS_CACHE: "false" - before_script: - - nix-shell --run "yarn" - script: - - "echo Firmware version: $TESTS_FIRMWARE" - - /trezor-user-env/run-nix.sh & - - nix-shell --run "yarn test:integration ${TEST_PATTERN} --coverage true" - after_script: - - cp /trezor-user-env/logs/debugging.log trezor-user-env-debugging.log - - cp /trezor-user-env/logs/emulator_bridge.log tenv-emulator-bridge-debugging.log - artifacts: - paths: - - trezor-user-env-debugging.log - - tenv-emulator-bridge-debugging.log - expire_in: 1 week - when: always +# .jobs-api: +# parallel: +# matrix: +# - TEST_PATTERN: "init" -TT latest: - extends: .test - stage: test +# .test: +# extends: .jobs +# image: ghcr.io/trezor/trezor-user-env +# dependencies: +# - "setup environment" +# variables: +# SDL_VIDEODRIVER: "dummy" +# TESTS_USE_TX_CACHE: "false" +# TESTS_USE_WS_CACHE: "false" +# before_script: +# - nix-shell --run "yarn" +# script: +# - "echo Firmware version: $TESTS_FIRMWARE" +# - /trezor-user-env/run-nix.sh & +# - nix-shell --run "yarn test:integration ${TEST_PATTERN} --coverage true" +# after_script: +# - cp /trezor-user-env/logs/debugging.log trezor-user-env-debugging.log +# - cp /trezor-user-env/logs/emulator_bridge.log tenv-emulator-bridge-debugging.log +# artifacts: +# paths: +# - trezor-user-env-debugging.log +# - tenv-emulator-bridge-debugging.log +# expire_in: 1 week +# when: always -API: - extends: .test - stage: test - parallel: !reference [.jobs-api,parallel] +# TT latest: +# extends: .test +# stage: test -.test-nightly: - extends: .test - stage: test extended - only: - - schedules - variables: - TESTS_USE_TX_CACHE: "true" - TESTS_USE_WS_CACHE: "true" - # todo: resolve tests flakiness and remove retry option - retry: 2 - -.test-manual: - extends: .test - stage: test extended - when: manual - # out of stages order, needs makes jobs available along with "base tests" - needs: ["setup environment", "verify", "build"] +# API: +# extends: .test +# stage: test +# parallel: !reference [.jobs-api,parallel] -TT master: - extends: .test-nightly - variables: - TESTS_FIRMWARE: "2-master" +# .test-nightly: +# extends: .test +# stage: test extended +# only: +# - schedules +# variables: +# TESTS_USE_TX_CACHE: "true" +# TESTS_USE_WS_CACHE: "true" +# # todo: resolve tests flakiness and remove retry option +# retry: 2 -TT master: - extends: .test-manual - variables: - TESTS_FIRMWARE: "2-master" +# .test-manual: +# extends: .test +# stage: test extended +# when: manual +# # out of stages order, needs makes jobs available along with "base tests" +# needs: ["setup environment", "verify", "build"] -TT 2.2.0: - extends: .test-nightly - # todo: remove delay. according to my observation, the higher number of jobs running concurrently, the higher chance of test failing. are we sure jobs are isolated from each other - when: delayed - start_in: 5 minutes - variables: - TESTS_FIRMWARE: "2.2.0" +# TT master: +# extends: .test-nightly +# variables: +# TESTS_FIRMWARE: "2-master" -TT 2.2.0: - extends: .test-manual - variables: - TESTS_FIRMWARE: "2.2.0" +# TT master: +# extends: .test-manual +# variables: +# TESTS_FIRMWARE: "2-master" -T1 latest: - extends: .test-nightly - # todo: remove delay. according to my observation, the higher number of jobs running concurrently, the higher chance of test failing. are we sure jobs are isolated from each other - when: delayed - start_in: 10 minutes - variables: - TESTS_FIRMWARE: "1-latest" - parallel: !reference [.jobs-t1,parallel] +# TT 2.2.0: +# extends: .test-nightly +# # todo: remove delay. according to my observation, the higher number of jobs running concurrently, the higher chance of test failing. are we sure jobs are isolated from each other +# when: delayed +# start_in: 5 minutes +# variables: +# TESTS_FIRMWARE: "2.2.0" -T1 latest: - extends: .test-manual - variables: - TESTS_FIRMWARE: "1-latest" - parallel: !reference [.jobs-t1,parallel] - -T1 master: - extends: .test-nightly - # todo: remove delay. according to my observation, the higher number of jobs running concurrently, the higher chance of test failing. are we sure jobs are isolated from each other - when: delayed - start_in: 15 minutes - variables: - TESTS_FIRMWARE: "1-master" - parallel: !reference [.jobs-t1,parallel] +# TT 2.2.0: +# extends: .test-manual +# variables: +# TESTS_FIRMWARE: "2.2.0" -T1 master: - extends: .test-manual - variables: - TESTS_FIRMWARE: "1-master" - parallel: !reference [.jobs-t1,parallel] +# T1 latest: +# extends: .test-nightly +# # todo: remove delay. according to my observation, the higher number of jobs running concurrently, the higher chance of test failing. are we sure jobs are isolated from each other +# when: delayed +# start_in: 10 minutes +# variables: +# TESTS_FIRMWARE: "1-latest" +# parallel: !reference [.jobs-t1,parallel] + +# T1 latest: +# extends: .test-manual +# variables: +# TESTS_FIRMWARE: "1-latest" +# parallel: !reference [.jobs-t1,parallel] + +# T1 master: +# extends: .test-nightly +# # todo: remove delay. according to my observation, the higher number of jobs running concurrently, the higher chance of test failing. are we sure jobs are isolated from each other +# when: delayed +# start_in: 15 minutes +# variables: +# TESTS_FIRMWARE: "1-master" +# parallel: !reference [.jobs-t1,parallel] + +# T1 master: +# extends: .test-manual +# variables: +# TESTS_FIRMWARE: "1-master" +# parallel: !reference [.jobs-t1,parallel] # Examples node: @@ -299,3 +299,68 @@ node: - /trezor-user-env/run-nix.sh & - sleep 10 - nix-shell --run "yarn babel-node ./examples/node/index.js" + +.connect: + stage: test + variables: + COMPOSE_PROJECT_NAME: $CI_JOB_ID + COMPOSE_FILE: ./docker/docker-compose.connect-test.yml + TESTS_INCLUDED_METHODS: $TESTS_INCLUDED_METHODS + TESTS_EXCLUDED_METHODS: $TESTS_EXCLUDED_METHODS + TESTS_PATTERN: $TESTS_PATTERN + TESTS_SCRIPT: yarn workspace @trezor/integration-tests test:connect:${TESTS_ENVIRONMENT} + TESTS_FIRMWARE: $TESTS_FIRMWARE + TESTS_USE_TX_CACHE: $TESTS_MOCK_BACKENDS + TESTS_USE_WS_CACHE: $TESTS_MOCK_BACKENDS + before_script: + - docker-compose down + - docker network prune -f + script: + - git submodule update --init --recursive + - yarn install --pure-lockfile --cache-folder .yarn --prefer-offline + - yarn build + - docker-compose pull + - docker-compose up -d trezor-user-env-unix + - docker-compose run test-run + after_script: + - docker-compose down + - docker network prune -f + parallel: + matrix: + - TESTS_ENVIRONMENT: ["node", "web"] + TESTS_PATTERN: "init" + TESTS_FIRMWARE: ["2-latest", "2.2.0"] + # todo: + # TESTS_NODE_VERSION: ["12", "14", "16"] + - TESTS_ENVIRONMENT: ["node", "web"] + TESTS_PATTERN: "methods" + TESTS_FIRMWARE: ["2-latest", "2.2.0"] + # todo: + # TESTS_NODE_VERSION: ["12", "14", "16"] + TESTS_INCLUDED_METHODS: [ + "applySettings,applyFlags,getFeatures", + "signTransaction", + "getAccountInfo,getAddress,getPublicKey,signMessage,verifyMessage,composeTransaction", + "stellarGetAddress,stellarSignTransaction", + "cardanoGetAddress,cardanoGetNativeScriptHash,cardanoGetPublicKey,cardanoSignTransaction", + "eosGetPublicKey,eosSignTransaction", + "ethereumGetAddress,ethereumGetPublicKey,ethereumSignMessage,ethereumSignTransaction,ethereumVerifyMessage,ethereumSignTypedData", + # "nemGetAddress,nemSignTransaction", + "rippleGetAddress,rippleSignTransaction", + "tezosGetAddress,tezosGetPublicKey", + "binanceSignTransaction", + ] + TESTS_MOCK_BACKENDS: "false" + +connect: + extends: .connect + # only: + # refs: + # - schedules # only nightly jobs, this is too heavy for develop branches at the moment + +connect manual: + extends: .connect + except: + refs: + - schedules + when: manual diff --git a/docker/docker-compose.connect-test.yml b/docker/docker-compose.connect-test.yml new file mode 100644 index 000000000..4a2eeb27a --- /dev/null +++ b/docker/docker-compose.connect-test.yml @@ -0,0 +1,24 @@ +version: "3" +services: + trezor-user-env-unix: + image: ghcr.io/trezor/trezor-user-env + environment: + - SDL_VIDEODRIVER=dummy + - XDG_RUNTIME_DIR=/var/tmp + network_mode: bridge + + test-run: + image: registry.gitlab.com/satoshilabs/trezor/trezor-suite/base:latest + environment: + - TESTS_FIRMWARE=$TESTS_FIRMWARE + - TESTS_INCLUDED_METHODS=$TESTS_INCLUDED_METHODS + - TESTS_EXCLUDED_METHODS=$TESTS_EXCLUDED_METHODS + - TESTS_USE_TX_CACHE=false + - TESTS_USE_WS_CACHE=false + depends_on: + - trezor-user-env-unix + network_mode: service:trezor-user-env-unix + working_dir: /connect + command: bash -c "docker/wait-for-env.sh && $TESTS_SCRIPT $TESTS_PATTERN" + volumes: + - ../:/connect diff --git a/docker/docker-connect-test.sh b/docker/docker-connect-test.sh new file mode 100755 index 000000000..ebca312cd --- /dev/null +++ b/docker/docker-connect-test.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash + +# This script runs @trezor/connect tests. +# It spins up trezor-user-env and sets required evironment variables. + +set -euo pipefail + +# Running standalone instance of trezor-user-env +# docker run -it -e SDL_VIDEODRIVER="dummy" -p "9001:9001" -p "21326:21326" -p "21325:21326" registry.gitlab.com/satoshilabs/trezor/trezor-user-env/trezor-user-env + +# Tweaking trezor-user-env locally +# docker run -it -e SDL_VIDEODRIVER="dummy" -p "9001:9001" -p "21326:21326" -p "21325:21326" registry.gitlab.com/satoshilabs/trezor/trezor-user-env/trezor-user-env nix-shell +# do your changes using `vi` and run: +# [nix-shell:/trezor-user-env]# ./run.sh + +# Ports +# 9001 - websocket server, communication test case > user-env (setup etc...) +# 21326 - trezord proxy. beacuse of trezord CORS check +# 21325 - original trezord port redirected to trezor-user-env proxy + +ENVIRONEMT=$1 + +if [[ "$ENVIRONEMT" != "web" && "$ENVIRONEMT" != "node" ]]; + then + echo "either 'web' or 'node' must be specified as the first argument" + exit 1 +fi + +show_usage() { + echo "Usage: run [OPTIONS] [ARGS]" + echo "" + echo "Options:" + echo " -c Disable backend cache. default: enabled" + echo " -d Disable docker. Useful when running own instance of trezor-user-env. default: enabled" + echo " -D PATH Set path to docker executable. Can be replaced with `podman`. default: docker" + echo " -e All methods except excluded, example: applySettings,signTransaction" + echo " -f Use specific firmware version, example: 2.1.4, 1.8.0 default: 2-master" + echo " -i Included methods only, example: applySettings,signTransaction" + echo " -s actual test script. default: 'yarn test:integration'" +} + +# default options +FIRMWARE="" +INCLUDED_METHODS="" +EXCLUDED_METHODS="" +DOCKER=true +DOCKER_PATH="docker" +USE_TX_CACHE=true +USE_WS_CACHE=true +PATTERN="" + +# user options +OPTIND=2 +while getopts ":p:i:e:f:D:hdc" opt; do + case $opt in + d) + DOCKER=false + ;; + D) + DOCKER_PATH="$OPTARG" + ;; + c) + USE_TX_CACHE=false + USE_WS_CACHE=false + ;; + f) + FIRMWARE=$OPTARG + ;; + i) + INCLUDED_METHODS=$OPTARG + ;; + e) + EXCLUDED_METHODS=$OPTARG + ;; + p) + PATTERN=$OPTARG + ;; + h) # Script usage + show_usage + exit 0 + ;; + \?) + echo "invalid option $OPTARG" + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +if [[ $ENVIRONEMT == "node" ]]; + then + SCRIPT="yarn test:node" + else + SCRIPT="yarn test:web" +fi + +# export essential process.env variables +export TESTS_FIRMWARE=$FIRMWARE +export TESTS_INCLUDED_METHODS=$INCLUDED_METHODS +export TESTS_EXCLUDED_METHODS=$EXCLUDED_METHODS +export TESTS_USE_TX_CACHE=$USE_TX_CACHE +export TESTS_USE_WS_CACHE=$USE_WS_CACHE +export TESTS_PATTERN=$PATTERN +export TESTS_SCRIPT=$SCRIPT + +runDocker() { + docker-compose -f ./docker/docker-compose.connect-test.yml up --abort-on-container-exit +} + + +run() { + echo "Testing env: ${ENVIRONEMT}. Using: ${SCRIPT} ${PATTERN}" + echo " Firmware: ${FIRMWARE}" + echo " Included methods: ${INCLUDED_METHODS}" + echo " Excluded methods: ${EXCLUDED_METHODS}" + echo " TxCache: ${USE_TX_CACHE}" + echo " WsCache: ${USE_WS_CACHE}" + + if [ $DOCKER = true ]; then + runDocker + else + ./docker/wait-for-env.sh + $SCRIPT + fi + +} + +run + diff --git a/docker/wait-for-env.sh b/docker/wait-for-env.sh new file mode 100755 index 000000000..41175071e --- /dev/null +++ b/docker/wait-for-env.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +echo "Waiting for trezor-user-env to load up..." +counter=0 +max_attempts=60 + # there is no official support for websockets in curl + # trezor-user-env websocket server will return HTTP/1.1 426 Upgrade Required error with "Upgrade: websocket" header +until (curl -i -s -I http://localhost:9001 | grep 'websocket'); do + if [ ${counter} -eq ${max_attempts} ]; then + echo "trezor-user-env is not running. exiting" + exit 1 + fi + counter=$(($counter+1)) + printf "." + sleep 1 +done + +echo "trezor-user-env loaded up" diff --git a/karma.config.production.js b/karma.config.production.js index ca6c0c133..76382bae4 100644 --- a/karma.config.production.js +++ b/karma.config.production.js @@ -28,7 +28,20 @@ module.exports = config => { useIframe: false, runInParent: true, }, - browsers: ['Chrome'], + browsers: [ + // 'Chrome', + 'ChromeHeadlessNoSandbox', + ], + customLaunchers: { + ChromeHeadlessNoSandbox: { + base: 'ChromeHeadless', + flags: ['--no-sandbox'], + }, + Chrome: { + base: 'Chrome', + flags: ['--no-sandbox'], + }, + }, concurrency: 0, browserNoActivityTimeout: 6000000, colors: true, diff --git a/package.json b/package.json index f4b532c59..03cb333db 100644 --- a/package.json +++ b/package.json @@ -45,8 +45,8 @@ "version:major": "yarn bump major ./package.json ./README.md ./src/js/data/ConnectSettings.js ./src/js/plugins/webextension/trezor-usb-permissions.js", "stats": "webpack --config ./webpack/config.prod.babel.js --json > build/stats.json", "test:unit": "jest --verbose -c jest.config.unit.js", - "test:integration": "jest --verbose -c jest.config.integration.js", - "test:karma:production": "babel-node ./node_modules/.bin/karma start karma.config.production.js", + "test:node": "jest --verbose -c jest.config.integration.js", + "test:web": "babel-node ./node_modules/.bin/karma start karma.config.production.js", "test:health": "babel-node ./scripts/check-extended-dependencies.js", "flow": "flow check .", "typescript": "tsc --project src/ts/types/tsconfig.json", diff --git a/tests/common.setup.js b/tests/common.setup.js index 0d5b7f3ad..8e4bc49be 100644 --- a/tests/common.setup.js +++ b/tests/common.setup.js @@ -16,15 +16,20 @@ const MNEMONICS = { let firmware = process.env.TESTS_FIRMWARE; if (firmware === '1-latest') { - firmware = releases1[0].version.join('.'); + // firmware = releases1[0].version.join('.'); + firmware = releases1[1].version.join('.'); } + if (firmware === '2-latest') { - firmware = releases2[0].version.join('.'); + // firmware = releases2[0].version.join('.'); + firmware = releases2[1].version.join('.'); } if (!firmware) { // fallback to the latest officially release model T firmware - firmware = releases2[0].version.join('.'); + // firmware = releases2[0].version.join('.'); + + firmware = releases2[1].version.join('.'); } const wait = ms =>