diff --git a/.github/workflows/e2e-linux-lite.yml b/.github/workflows/e2e-linux-lite.yml new file mode 100644 index 00000000000..96a2c906797 --- /dev/null +++ b/.github/workflows/e2e-linux-lite.yml @@ -0,0 +1,67 @@ +name: E2E Linux --light + +on: + schedule: + - cron: "0 22 * * *" + workflow_dispatch: + inputs: + network: + description: 'Network' + required: true + default: 'testnet' + pr: + description: 'PR number or "master"' + default: 'master' + +defaults: + run: + working-directory: ./test/e2e + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.1 + bundler-cache: true + + - name: Install dependencies + run: bundle install + + - name: ๐Ÿ•’ Get Date/Time + id: date-time + shell: bash + run: | + echo "::set-output name=value::$(rake datetime)" + + - name: โš™๏ธ Setup (get latest bins and configs and decode fixtures) + run: rake setup[$NETWORK,$PR] + + - name: ๐Ÿ” Display versions + run: rake display_versions + + - name: ๐Ÿš€ Start wallet --light + run: rake start_wallet_light[$NETWORK] + + - name: ๐Ÿงช Run all tests + run: rake spec SPEC_OPTS="-t light" + + - name: ๐Ÿ Stop wallet --light + run: rake stop_wallet_light[$NETWORK] + + - name: ๐Ÿ“Ž Upload logs + uses: actions/upload-artifact@v2 + if: always() + with: + name: ${{ runner.os }}-logs + path: test/e2e/state/logs + + env: + TESTS_E2E_FIXTURES: ${{ secrets.TESTS_E2E_FIXTURES }} + NETWORK: ${{ github.event.inputs.network || 'testnet' }} + PR: ${{ github.event.inputs.pr || '' }} diff --git a/.github/workflows/e2e-macos-lite.yml b/.github/workflows/e2e-macos-lite.yml new file mode 100644 index 00000000000..7f3f87e4925 --- /dev/null +++ b/.github/workflows/e2e-macos-lite.yml @@ -0,0 +1,70 @@ +name: E2E MacOS --light + +on: + schedule: + - cron: "0 22 * * *" + workflow_dispatch: + inputs: + network: + description: 'Network' + required: true + default: 'testnet' + pr: + description: 'PR number or "master"' + default: 'master' + +defaults: + run: + working-directory: ./test/e2e + +jobs: + test: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.1 + bundler-cache: true + + - name: Install dependencies + run: bundle install + + - name: Prepare MacOS + run: brew install screen + + - name: ๐Ÿ•’ Get Date/Time + id: date-time + shell: bash + run: | + echo "::set-output name=value::$(rake datetime)" + + - name: โš™๏ธ Setup (get latest bins and configs and decode fixtures) + run: rake setup[$NETWORK,$PR] + + - name: ๐Ÿ” Display versions + run: rake display_versions + + - name: ๐Ÿš€ Start wallet --light + run: rake start_wallet_light[$NETWORK] + + - name: ๐Ÿงช Run all tests + run: rake spec SPEC_OPTS="-t light" + + - name: ๐Ÿ Stop wallet --light + run: rake stop_wallet_light[$NETWORK] + + - name: ๐Ÿ“Ž Upload logs + uses: actions/upload-artifact@v2 + if: always() + with: + name: ${{ runner.os }}-logs + path: test/e2e/state/logs + + env: + TESTS_E2E_FIXTURES: ${{ secrets.TESTS_E2E_FIXTURES }} + NETWORK: ${{ github.event.inputs.network || 'testnet' }} + PR: ${{ github.event.inputs.pr || '' }} diff --git a/.github/workflows/e2e-windows-lite.yml b/.github/workflows/e2e-windows-lite.yml new file mode 100644 index 00000000000..c7b67e800bb --- /dev/null +++ b/.github/workflows/e2e-windows-lite.yml @@ -0,0 +1,73 @@ +name: E2E Windows --light + +on: + schedule: + - cron: "0 22 * * *" + workflow_dispatch: + inputs: + network: + description: 'Network' + required: true + default: 'testnet' + pr: + description: 'PR number or "master"' + default: 'master' + +defaults: + run: + working-directory: ./test/e2e + +jobs: + test: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.1 + bundler-cache: true + + - name: Install dependencies + run: bundle install + + - name: Prepare Windows + run: | + choco install wget + choco install unzip + choco install nssm + + - name: ๐Ÿ•’ Get Date/Time + id: date-time + shell: bash + run: | + echo "::set-output name=value::$(rake datetime)" + + - name: โš™๏ธ Setup (get latest bins and configs and decode fixtures) + run: rake setup[%NETWORK%,%PR%] + + - name: ๐Ÿ” Display versions + run: rake display_versions + + - name: ๐Ÿš€ Start wallet --light + run: rake start_wallet_light[%NETWORK%] + + - name: ๐Ÿงช Run all tests + run: rake spec SPEC_OPTS="-t light" + + - name: ๐Ÿ Stop wallet --light + run: rake stop_wallet_light[%NETWORK%] + + - name: ๐Ÿ“Ž Upload logs + uses: actions/upload-artifact@v2 + if: always() + with: + name: ${{ runner.os }}-logs + path: test/e2e/state/logs + + env: + NETWORK: ${{ github.event.inputs.network || 'testnet' }} + TESTS_E2E_FIXTURES: ${{ secrets.TESTS_E2E_FIXTURES }} + PR: ${{ github.event.inputs.pr || 'master' }} diff --git a/test/e2e/.gitignore b/test/e2e/.gitignore index 3245f5ef2a1..a0aaf2fd0c6 100644 --- a/test/e2e/.gitignore +++ b/test/e2e/.gitignore @@ -4,6 +4,7 @@ # secrets /fixtures/fixture_wallets.json +/fixtures/blockfrost.api.key # local environment variables /.envrc-local diff --git a/test/e2e/.rake_tasks~ b/test/e2e/.rake_tasks~ index e2ecfc2f4e6..08cedc850b6 100644 --- a/test/e2e/.rake_tasks~ +++ b/test/e2e/.rake_tasks~ @@ -2,8 +2,8 @@ clean_bins clean_logs datetime display_versions -fixture_wallets_decode -fixture_wallets_encode +secrets_decode +secrets_encode fixture_wallets_template get_docker_logs get_latest_bins @@ -13,4 +13,6 @@ spec setup start_node_and_wallet stop_node_and_wallet +start_wallet_light +stop_wallet_light wait_until_node_synced diff --git a/test/e2e/README.md b/test/e2e/README.md index b5200d3d58e..aca60a92cb5 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -1,13 +1,10 @@ - - - - - - # E2E testing -[![E2E Docker](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-docker.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-docker.yml) [![E2E Linux](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-linux.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-linux.yml) [![E2E MacOS](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-macos.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-macos.yml) [![E2E Windows](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-windows.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-windows.yml) - -[![Docker-compose Linux](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_linux.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_linux.yml) [![Docker-compose MacOS](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_macos.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_macos.yml) +| | | +|--|--| +|**Full mode** |[![E2E Docker](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-docker.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-docker.yml) [![E2E Linux](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-linux.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-linux.yml) [![E2E MacOS](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-macos.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-macos.yml) [![E2E Windows](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-windows.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-windows.yml) | +|**Light mode** | [![E2E Linux --light](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-linux-lite.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-linux-lite.yml) [![E2E MacOS --light](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-macos-lite.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-macos-lite.yml) [![E2E Windows --light](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-windows-lite.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/e2e-windows-lite.yml) | +|**Docker compose** | [![Docker-compose Linux](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_linux.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_linux.yml) [![Docker-compose MacOS](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_macos.yml/badge.svg)](https://github.com/input-output-hk/cardano-wallet/actions/workflows/docker_macos.yml) +| E2E functional tests of cardano-wallet are running nightly on [cardano testnet](https://testnets.cardano.org/en/cardano/overview/). Running tests against public testnet allows to exercise cardano-wallet on environment close to production (mainnet) utilizing and integrating maximally all components of the Cardano ecosystem like Stake pools, SMASH, metadata token server etc. @@ -22,11 +19,13 @@ In order to run tests one needs to [have ruby](https://www.ruby-lang.org/en/docu cd test/e2e bundle install ``` -2. Decrypt `fixture_wallets.json.gpg` containing mnemonics of testnet fixture wallets using `$TESTS_E2E_FIXTURES` secret. +2. Decrypt secret files using `$TESTS_E2E_FIXTURES` secret: + - `fixture_wallets.json.gpg` containing mnemonics of testnet fixture wallets + - `blockfrost.api.key.gpg` containing Blockfrost API key for `testnet` ```bash export TESTS_E2E_FIXTURES=******* -rake fixture_wallets_decode +rake secrets_decode ``` > :information_source: **_TESTS_E2E_FIXTURES_** secret is defined on https://github.com/input-output-hk/cardano-wallet/settings/secrets and also used by GH actions. Note that this step is also executed on very first test run. > @@ -38,7 +37,7 @@ $ rake run_on[testnet] This master task is performing also all the necessary configuration steps (i.e. getting latest testnet configs and wallet/node binaries from [Hydra](https://hydra.iohk.io/jobset/Cardano/cardano-wallet#tabs-jobs), starting everything up). All steps can also be executed as separate tasks , i.e.: ```bash -$ rake fixture_wallets_decode +$ rake secrets_decode $ rake get_latest_bins $ rake get_latest_configs[testnet] $ rake start_node_and_wallet[testnet] @@ -79,9 +78,21 @@ One can also run tests against `cardano-wallet` and `cardano-node` which are spe ```bash $ TESTS_E2E_BINDIR="" rake run_on[testnet] ``` - Running tests as such skips downloading latest binaries from Hydra. +#### Running tests against wallet started in `--light` mode + +One can also run some tests against wallet started in `--light` mode. Similar rake workflow can be applied except there is no need to start `cardano-node` and wait for it to be synced with the network: +```bash +$ rake secrets_decode +$ rake get_latest_bins +$ rake get_latest_configs[testnet] +$ rake start_wallet_light[testnet] +$ rake spec SPEC_OPTS="-t light" +$ rake stop_wallet_light[testnet] +``` +All tests that are suitable for `--light` mode are tagged with `:light` tag. + ### Test artifacts By default following locations are used for different artifacts used by the tests: diff --git a/test/e2e/Rakefile b/test/e2e/Rakefile index a17a0da1880..6a9d3cef03f 100644 --- a/test/e2e/Rakefile +++ b/test/e2e/Rakefile @@ -16,6 +16,7 @@ WALLET_DB = absolute_path ENV['TESTS_WALLET_DB'] BINS = absolute_path ENV['TESTS_E2E_BINDIR'] FIXTURES_FILE = absolute_path ENV['TESTS_E2E_FIXTURES_FILE'] +BLOCKFROST_FILE = absolute_path ENV['TESTS_E2E_BLOCKFROST_FILE'] FIXTURES_SECRET = absolute_path ENV['TESTS_E2E_FIXTURES'] TOKEN_METADATA = ENV['TESTS_E2E_TOKEN_METADATA'] @@ -26,22 +27,32 @@ ENV['PATH'] = "#{BINS}#{path_separator}#{ENV['PATH']}" task :default => :spec -task :fixture_wallets_encode do - desc "Encode fixture wallets from #{FIXTURES_FILE} using $TESTS_E2E_FIXTURES phrase" - puts "\n >> Encoding #{FIXTURES_FILE}..." +task :secrets_encode do + desc "Encode secrets using $TESTS_E2E_FIXTURES phrase" + puts "\n >> Encoding #{FIXTURES_FILE}..." puts `gpg --pinentry-mode loopback --passphrase=#{FIXTURES_SECRET} --symmetric --output=#{FIXTURES_FILE}.gpg #{FIXTURES_FILE}` + + puts "\n >> Encoding #{BLOCKFROST_FILE}..." + puts `gpg --pinentry-mode loopback --passphrase=#{FIXTURES_SECRET} --symmetric --output=#{BLOCKFROST_FILE}.gpg #{BLOCKFROST_FILE}` + end -task :fixture_wallets_decode do - desc "Decode fixture wallets from #{FIXTURES_FILE}.gpg using $TESTS_E2E_FIXTURES phrase" - encoded_file = "#{FIXTURES_FILE}.gpg" - decoded_file = FIXTURES_FILE - if File.exists?(decoded_file) - puts "\n >> Skipping decoding #{encoded_file}... #{decoded_file} already exists!" +task :secrets_decode do + desc "Decode secrets using $TESTS_E2E_FIXTURES phrase" + + if File.exists?(FIXTURES_FILE) + puts "\n >> Skipping decoding #{FIXTURES_FILE}.gpg... #{FIXTURES_FILE} already exists!" else puts "\n >> Decoding #{FIXTURES_FILE}.gpg..." - puts `gpg --pinentry-mode loopback --yes --passphrase=#{FIXTURES_SECRET} --output #{decoded_file} --decrypt #{encoded_file}` + puts `gpg --pinentry-mode loopback --yes --passphrase=#{FIXTURES_SECRET} --output #{FIXTURES_FILE} --decrypt #{FIXTURES_FILE}.gpg` + end + + if File.exists?(BLOCKFROST_FILE) + puts "\n >> Skipping decoding #{BLOCKFROST_FILE}.gpg... #{BLOCKFROST_FILE} already exists!" + else + puts "\n >> Decoding #{BLOCKFROST_FILE}.gpg..." + puts `gpg --pinentry-mode loopback --yes --passphrase=#{FIXTURES_SECRET} --output #{BLOCKFROST_FILE} --decrypt #{BLOCKFROST_FILE}.gpg` end end @@ -181,19 +192,6 @@ task :start_node_and_wallet, [:env] do |task, args| end end -task :display_versions do - puts "\n >> cardano-node and cardano-wallet versions:" - - bin_dir = BINS == '' ? BINS : "#{BINS}/" - if is_win? - cmd "#{bin_dir}cardano-wallet.exe version", true - cmd "#{bin_dir}cardano-node.exe version", true - else - cmd "#{bin_dir}cardano-wallet version", true - cmd "#{bin_dir}cardano-node version", true - end -end - task :stop_node_and_wallet, [:env] do |task, args| puts "\n >> Stopping cardano-node and cardano-wallet" @@ -210,6 +208,66 @@ task :stop_node_and_wallet, [:env] do |task, args| end +task :start_wallet_light, [:env] do |task, args| + puts "\n >> Setting up cardano-wallet-light" + + bin_dir = BINS == '' ? BINS : "#{BINS}/" + config_dir = File.join(CONFIGS, args[:env]) + log_dir = File.join(LOGS, args[:env]) + wallet_db_dir = File.join(WALLET_DB, args[:env]) + cd = Dir.pwd + mk_dir(STATE) + mk_dir(log_dir) + + if is_win? + # create cardano-wallet.bat file + wallet_cmd = "#{bin_dir}cardano-wallet.exe serve --port #{WALLET_PORT} --light --blockfrost-token-file #{BLOCKFROST_FILE} --testnet #{config_dir}/genesis-byron.json --database #{wallet_db_dir} --token-metadata-server #{TOKEN_METADATA}" + File.open("cardano-wallet.bat", "w") do |f| + f.write(wallet_cmd) + end + + install_wallet = "nssm install cardano-wallet-light #{cd}/cardano-wallet.bat" + log_stdout_wallet = "nssm set cardano-wallet-light AppStdout #{log_dir}/wallet.log" + log_stderr_wallet = "nssm set cardano-wallet-light AppStderr #{log_dir}/wallet.log" + start_wallet = "nssm start cardano-wallet-light" + + cmd install_wallet + cmd log_stdout_wallet + cmd log_stderr_wallet + cmd start_wallet + else + start_wallet = "#{bin_dir}cardano-wallet serve --port #{WALLET_PORT} --light --blockfrost-token-file #{BLOCKFROST_FILE} --testnet #{config_dir}/genesis-byron.json --database #{wallet_db_dir} --token-metadata-server #{TOKEN_METADATA}" + + cmd "screen -dmS WALLET_#{args[:env]}_light -L -Logfile #{log_dir}/wallet.log #{start_wallet}" + cmd "screen -ls", true + end +end + +task :stop_wallet_light, [:env] do |task, args| + puts "\n >> Stopping cardano-wallet-light" + + if is_win? + cmd "nssm stop cardano-wallet-light" + cmd "nssm remove cardano-wallet-light confirm" + else + cmd "screen -XS WALLET_#{args[:env]}_light quit" + end + +end + +task :display_versions do + puts "\n >> cardano-node and cardano-wallet versions:" + + bin_dir = BINS == '' ? BINS : "#{BINS}/" + if is_win? + cmd "#{bin_dir}cardano-wallet.exe version", true + cmd "#{bin_dir}cardano-node.exe version", true + else + cmd "#{bin_dir}cardano-wallet version", true + cmd "#{bin_dir}cardano-node version", true + end +end + task :get_latest_bins, [:pr] do |task, args| puts "\n >> Getting latest node and wallet binaries from Hydra into #{BINS}" @@ -296,7 +354,7 @@ task :setup, [:env, :pr, :skip_configs] do |task, args| Rake::Task[:get_latest_bins].invoke(pr) end Rake::Task[:get_latest_configs].invoke(env) unless skip_configs - Rake::Task[:fixture_wallets_decode].invoke + Rake::Task[:secrets_decode].invoke end task :run_on, [:env, :sync_strategy, :skip_configs, :pr] do |task, args| diff --git a/test/e2e/env.rb b/test/e2e/env.rb index 4b5ce4d0c21..d17155ff0ee 100644 --- a/test/e2e/env.rb +++ b/test/e2e/env.rb @@ -1,7 +1,8 @@ ## -# fixture wallets with mnemonics +# secrets ๐Ÿคซ ENV['TESTS_E2E_FIXTURES'] ||= "this_is_wrong_secret" ENV['TESTS_E2E_FIXTURES_FILE'] ||= "./fixtures/fixture_wallets.json" +ENV['TESTS_E2E_BLOCKFROST_FILE'] ||= "./fixtures/blockfrost.api.key" ## # Wallet/node databases, logs and configs will be stored here diff --git a/test/e2e/fixtures/blockfrost.api.key.gpg b/test/e2e/fixtures/blockfrost.api.key.gpg new file mode 100644 index 00000000000..3cddc2b3949 Binary files /dev/null and b/test/e2e/fixtures/blockfrost.api.key.gpg differ diff --git a/test/e2e/spec/e2e_spec.rb b/test/e2e/spec/e2e_spec.rb index e4b64f73d50..15ef0178201 100644 --- a/test/e2e/spec/e2e_spec.rb +++ b/test/e2e/spec/e2e_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe "Cardano Wallet E2E tests", :e2e => true do +RSpec.describe "Cardano Wallet E2E tests", :e2e do before(:all) do # shelley wallets diff --git a/test/e2e/spec/misc_spec.rb b/test/e2e/spec/misc_spec.rb index d95d623f3da..32fabef9b31 100644 --- a/test/e2e/spec/misc_spec.rb +++ b/test/e2e/spec/misc_spec.rb @@ -7,7 +7,7 @@ expect(res).to be_correct_and_respond 200 end - it "Can check network clock offset" do + it "Can check network clock offset", :light do res = NETWORK.clock expect(res).to be_correct_and_respond 200 end @@ -34,7 +34,7 @@ end end - describe CardanoWallet::Misc::Utils do + describe CardanoWallet::Misc::Utils, :light do describe "SMASH health" do it "SMASH health - unreachable" do @@ -276,7 +276,7 @@ end end - describe CardanoWallet::Misc::Settings do + describe CardanoWallet::Misc::Settings, :light do after(:all) do SETTINGS.update({ :pool_metadata_source => "none" })