From 7ec9a7a91b092f036b8eae2ef6da975284b2f680 Mon Sep 17 00:00:00 2001 From: Eric Swanson Date: Tue, 26 Sep 2023 09:25:28 -0700 Subject: [PATCH] refactor: standardize indentation for e2e test scripts --- e2e/tests-dfx/assetscanister.bash | 1402 ++++++++++---------- e2e/tests-dfx/base.bash | 38 +- e2e/tests-dfx/basic-project.bash | 206 +-- e2e/tests-dfx/bitcoin.bash | 336 ++--- e2e/tests-dfx/bootstrap.bash | 38 +- e2e/tests-dfx/build.bash | 232 ++-- e2e/tests-dfx/build_granular.bash | 124 +- e2e/tests-dfx/build_rust.bash | 8 +- e2e/tests-dfx/call.bash | 174 +-- e2e/tests-dfx/candid_ui.bash | 20 +- e2e/tests-dfx/canister_http.bash | 400 +++--- e2e/tests-dfx/certificate.bash | 118 +- e2e/tests-dfx/certified_info.bash | 36 +- e2e/tests-dfx/create.bash | 320 ++--- e2e/tests-dfx/delete.bash | 48 +- e2e/tests-dfx/deploy.bash | 168 +-- e2e/tests-dfx/deps.bash | 704 +++++----- e2e/tests-dfx/describe_local_network.bash | 142 +- e2e/tests-dfx/dfx_install.bash | 76 +- e2e/tests-dfx/dotenv.bash | 128 +- e2e/tests-dfx/ed25519.bash | 32 +- e2e/tests-dfx/error_context.bash | 212 +-- e2e/tests-dfx/error_diagnosis.bash | 74 +- e2e/tests-dfx/extension.bash | 216 +-- e2e/tests-dfx/fabricate_cycles.bash | 64 +- e2e/tests-dfx/frontend.bash | 130 +- e2e/tests-dfx/generate.bash | 188 +-- e2e/tests-dfx/id.bash | 140 +- e2e/tests-dfx/identity.bash | 278 ++-- e2e/tests-dfx/identity_command.bash | 640 ++++----- e2e/tests-dfx/identity_encryption.bash | 40 +- e2e/tests-dfx/info.bash | 40 +- e2e/tests-dfx/install.bash | 226 ++-- e2e/tests-dfx/inter.bash | 96 +- e2e/tests-dfx/leak.bash | 24 +- e2e/tests-dfx/ledger.bash | 412 +++--- e2e/tests-dfx/metadata.bash | 246 ++-- e2e/tests-dfx/migrate.bash | 42 +- e2e/tests-dfx/mode_reinstall.bash | 202 +-- e2e/tests-dfx/network.bash | 128 +- e2e/tests-dfx/new.bash | 70 +- e2e/tests-dfx/packtool.bash | 88 +- e2e/tests-dfx/ping.bash | 84 +- e2e/tests-dfx/playground.bash | 18 +- e2e/tests-dfx/print.bash | 26 +- e2e/tests-dfx/project_local_network.bash | 214 +-- e2e/tests-dfx/provider.bash | 34 +- e2e/tests-dfx/remote.bash | 494 +++---- e2e/tests-dfx/remote_generate_binding.bash | 124 +- e2e/tests-dfx/request_status.bash | 26 +- e2e/tests-dfx/rust.bash | 78 +- e2e/tests-dfx/schema.bash | 18 +- e2e/tests-dfx/shared_local_network.bash | 186 +-- e2e/tests-dfx/sign_send.bash | 92 +- e2e/tests-dfx/signals.bash | 28 +- e2e/tests-dfx/start.bash | 538 ++++---- e2e/tests-dfx/subcommands.bash | 22 +- e2e/tests-dfx/update_settings.bash | 788 +++++------ e2e/tests-dfx/upgrade.bash | 74 +- e2e/tests-dfx/upgrade_check.bash | 70 +- e2e/tests-dfx/usage.bash | 30 +- e2e/tests-dfx/usage_env.bash | 64 +- e2e/tests-dfx/wallet.bash | 338 ++--- e2e/tests-icx-asset/icx-asset.bash | 304 ++--- e2e/tests-replica/deploy.bash | 110 +- e2e/tests-replica/lifecycle.bash | 90 +- 66 files changed, 6078 insertions(+), 6078 deletions(-) diff --git a/e2e/tests-dfx/assetscanister.bash b/e2e/tests-dfx/assetscanister.bash index 10152e960f..d37ac80e67 100644 --- a/e2e/tests-dfx/assetscanister.bash +++ b/e2e/tests-dfx/assetscanister.bash @@ -3,42 +3,42 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } create_batch() { - reg="batch_id = ([0-9]*) : nat" - assert_command dfx canister call e2e_project_frontend create_batch '(record { })' - # shellcheck disable=SC2154 - [[ "$stdout" =~ $reg ]] - BATCH_ID="${BASH_REMATCH[1]}" - echo "$BATCH_ID" + reg="batch_id = ([0-9]*) : nat" + assert_command dfx canister call e2e_project_frontend create_batch '(record { })' + # shellcheck disable=SC2154 + [[ "$stdout" =~ $reg ]] + BATCH_ID="${BASH_REMATCH[1]}" + echo "$BATCH_ID" } create_chunk() { - batch_id="$1" - reg="chunk_id = ([0-9]*) : nat" - assert_command dfx canister call e2e_project_frontend create_chunk "(record { batch_id = $batch_id; content = vec {} })" - # shellcheck disable=SC2154 - [[ "$stdout" =~ $reg ]] - CHUNK_ID="${BASH_REMATCH[1]}" - echo "$CHUNK_ID" + batch_id="$1" + reg="chunk_id = ([0-9]*) : nat" + assert_command dfx canister call e2e_project_frontend create_chunk "(record { batch_id = $batch_id; content = vec {} })" + # shellcheck disable=SC2154 + [[ "$stdout" =~ $reg ]] + CHUNK_ID="${BASH_REMATCH[1]}" + echo "$CHUNK_ID" } delete_batch() { - assert_command dfx canister call e2e_project_frontend delete_batch "(record { batch_id=$1; })" + assert_command dfx canister call e2e_project_frontend delete_batch "(record { batch_id=$1; })" } check_permission_failure() { - assert_contains "$1" + assert_contains "$1" } @test "commit_batch is atomic" { @@ -695,713 +695,713 @@ check_permission_failure() { } @test "http_request percent-decodes urls" { - install_asset assetscanister - - dfx_start - - echo "contents of file with space in filename" >'src/e2e_project_frontend/assets/filename with space.txt' - echo "contents of file with plus in filename" >'src/e2e_project_frontend/assets/has+plus.txt' - echo "contents of file with percent in filename" >'src/e2e_project_frontend/assets/has%percent.txt' - echo "filename is an ae symbol" >'src/e2e_project_frontend/assets/æ' - echo "filename is percent symbol" >'src/e2e_project_frontend/assets/%' - echo "filename contains question mark" >'src/e2e_project_frontend/assets/filename?withqmark.txt' - dd if=/dev/urandom of='src/e2e_project_frontend/assets/large with spaces.bin' bs=2500000 count=1 - - - dfx deploy - - # decode as expected - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/filename%20with%20space.txt";headers=vec{};method="GET";body=vec{}})' - assert_match "contents of file with space in filename" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%2bplus.txt";headers=vec{};method="GET";body=vec{}})' - assert_match "contents of file with plus in filename" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%2Bplus.txt";headers=vec{};method="GET";body=vec{}})' - assert_match "contents of file with plus in filename" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%%percent.txt";headers=vec{};method="GET";body=vec{}})' - assert_match "contents of file with percent in filename" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%e6";headers=vec{};method="GET";body=vec{}})' - assert_match "filename is an ae symbol" # candid looks like blob "filename is \c3\a6\0a" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%%";headers=vec{};method="GET";body=vec{}})' - assert_match "filename is percent" - # this test ensures url decoding happens after removing the query string - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/filename%3fwithqmark.txt";headers=vec{};method="GET";body=vec{}})' - assert_match "filename contains question mark" - - # these error conditions can't be tested with curl, because something responds first with Bad Request. - # THESE TESTS WERE REMOVED BECAUSE THE RUST CANISTER DOES NOT SUPPORT REJECTING MESSAGES - # TODO: Reenable those tests. - # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%";headers=vec{};method="GET";body=vec{}})' - # assert_match "error decoding url: % must be followed by '%' or two hex digits" - # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%z";headers=vec{};method="GET";body=vec{}})' - # assert_match "error decoding url: % must be followed by two hex digits, but only one was found" - # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%zz";headers=vec{};method="GET";body=vec{}})' - # assert_match "error decoding url: neither character after % is a hex digit" - # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%e";headers=vec{};method="GET";body=vec{}})' - # assert_match "error decoding url: % must be followed by two hex digits, but only one was found" - # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%g6";headers=vec{};method="GET";body=vec{}})' - # assert_match "error decoding url: first character after % is not a hex digit" - # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%ch";headers=vec{};method="GET";body=vec{}})' - # assert_match "error decoding url: second character after % is not a hex digit" - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - - assert_command curl --fail -vv http://localhost:"$PORT"/filename%20with%20space.txt?canisterId="$ID" - # shellcheck disable=SC2154 - assert_match "200 OK" "$stderr" - assert_match "contents of file with space in filename" - - assert_command curl --fail -vv http://localhost:"$PORT"/has%2bplus.txt?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "contents of file with plus in filename" - - assert_command curl --fail -vv http://localhost:"$PORT"/has%%percent.txt?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "contents of file with percent in filename" - - assert_command curl --fail -vv http://localhost:"$PORT"/%e6?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "filename is an ae symbol" - - assert_command curl --fail -vv http://localhost:"$PORT"/%%?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "filename is percent symbol" - - assert_command curl --fail -vv http://localhost:"$PORT"/filename%3fwithqmark.txt?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "filename contains question mark" - - assert_command curl --fail -vv --output lws-curl-output.bin "http://localhost:$PORT/large%20with%20spaces.bin?canisterId=$ID" - diff 'src/e2e_project_frontend/assets/large with spaces.bin' lws-curl-output.bin - - # curl now reports "curl: (3) URL using bad/illegal format or missing URL" so we cannot verify behavior - # assert_command_fail curl --fail -vv --path-as-is http://localhost:"$PORT"/'filename with space'.txt?canisterId="$ID" - # assert_match "400 Bad Request" "$stderr" + install_asset assetscanister + + dfx_start + + echo "contents of file with space in filename" >'src/e2e_project_frontend/assets/filename with space.txt' + echo "contents of file with plus in filename" >'src/e2e_project_frontend/assets/has+plus.txt' + echo "contents of file with percent in filename" >'src/e2e_project_frontend/assets/has%percent.txt' + echo "filename is an ae symbol" >'src/e2e_project_frontend/assets/æ' + echo "filename is percent symbol" >'src/e2e_project_frontend/assets/%' + echo "filename contains question mark" >'src/e2e_project_frontend/assets/filename?withqmark.txt' + dd if=/dev/urandom of='src/e2e_project_frontend/assets/large with spaces.bin' bs=2500000 count=1 + + + dfx deploy + + # decode as expected + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/filename%20with%20space.txt";headers=vec{};method="GET";body=vec{}})' + assert_match "contents of file with space in filename" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%2bplus.txt";headers=vec{};method="GET";body=vec{}})' + assert_match "contents of file with plus in filename" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%2Bplus.txt";headers=vec{};method="GET";body=vec{}})' + assert_match "contents of file with plus in filename" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%%percent.txt";headers=vec{};method="GET";body=vec{}})' + assert_match "contents of file with percent in filename" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%e6";headers=vec{};method="GET";body=vec{}})' + assert_match "filename is an ae symbol" # candid looks like blob "filename is \c3\a6\0a" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%%";headers=vec{};method="GET";body=vec{}})' + assert_match "filename is percent" + # this test ensures url decoding happens after removing the query string + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/filename%3fwithqmark.txt";headers=vec{};method="GET";body=vec{}})' + assert_match "filename contains question mark" + + # these error conditions can't be tested with curl, because something responds first with Bad Request. + # THESE TESTS WERE REMOVED BECAUSE THE RUST CANISTER DOES NOT SUPPORT REJECTING MESSAGES + # TODO: Reenable those tests. + # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%";headers=vec{};method="GET";body=vec{}})' + # assert_match "error decoding url: % must be followed by '%' or two hex digits" + # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%z";headers=vec{};method="GET";body=vec{}})' + # assert_match "error decoding url: % must be followed by two hex digits, but only one was found" + # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%zz";headers=vec{};method="GET";body=vec{}})' + # assert_match "error decoding url: neither character after % is a hex digit" + # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%e";headers=vec{};method="GET";body=vec{}})' + # assert_match "error decoding url: % must be followed by two hex digits, but only one was found" + # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%g6";headers=vec{};method="GET";body=vec{}})' + # assert_match "error decoding url: first character after % is not a hex digit" + # assert_command_fail dfx canister call --query e2e_project_frontend http_request '(record{url="/%ch";headers=vec{};method="GET";body=vec{}})' + # assert_match "error decoding url: second character after % is not a hex digit" + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + + assert_command curl --fail -vv http://localhost:"$PORT"/filename%20with%20space.txt?canisterId="$ID" + # shellcheck disable=SC2154 + assert_match "200 OK" "$stderr" + assert_match "contents of file with space in filename" + + assert_command curl --fail -vv http://localhost:"$PORT"/has%2bplus.txt?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "contents of file with plus in filename" + + assert_command curl --fail -vv http://localhost:"$PORT"/has%%percent.txt?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "contents of file with percent in filename" + + assert_command curl --fail -vv http://localhost:"$PORT"/%e6?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "filename is an ae symbol" + + assert_command curl --fail -vv http://localhost:"$PORT"/%%?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "filename is percent symbol" + + assert_command curl --fail -vv http://localhost:"$PORT"/filename%3fwithqmark.txt?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "filename contains question mark" + + assert_command curl --fail -vv --output lws-curl-output.bin "http://localhost:$PORT/large%20with%20spaces.bin?canisterId=$ID" + diff 'src/e2e_project_frontend/assets/large with spaces.bin' lws-curl-output.bin + + # curl now reports "curl: (3) URL using bad/illegal format or missing URL" so we cannot verify behavior + # assert_command_fail curl --fail -vv --path-as-is http://localhost:"$PORT"/'filename with space'.txt?canisterId="$ID" + # assert_match "400 Bad Request" "$stderr" } @test "generates gzipped content encoding for .js files" { - install_asset assetscanister - for i in $(seq 1 400); do - echo "some easily duplicate text $i" >>src/e2e_project_frontend/assets/notreally.js - done - - dfx_start - assert_command dfx deploy - dfx canister call --query e2e_project_frontend list '(record{})' - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - - assert_command curl -v --output not-compressed http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_not_match "content-encoding:" - diff not-compressed src/e2e_project_frontend/assets/notreally.js - - assert_command curl -v --output encoded-compressed-1.gz -H "Accept-Encoding: gzip" http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_match "content-encoding: gzip" - gunzip encoded-compressed-1.gz - diff encoded-compressed-1 src/e2e_project_frontend/assets/notreally.js - - # should split up accept-encoding lines with more than one encoding - assert_command curl -v --output encoded-compressed-2.gz -H "Accept-Encoding: gzip, deflate, br" http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_match "content-encoding: gzip" - gunzip encoded-compressed-2.gz - diff encoded-compressed-2 src/e2e_project_frontend/assets/notreally.js + install_asset assetscanister + for i in $(seq 1 400); do + echo "some easily duplicate text $i" >>src/e2e_project_frontend/assets/notreally.js + done + + dfx_start + assert_command dfx deploy + dfx canister call --query e2e_project_frontend list '(record{})' + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + + assert_command curl -v --output not-compressed http://localhost:"$PORT"/notreally.js?canisterId="$ID" + assert_not_match "content-encoding:" + diff not-compressed src/e2e_project_frontend/assets/notreally.js + + assert_command curl -v --output encoded-compressed-1.gz -H "Accept-Encoding: gzip" http://localhost:"$PORT"/notreally.js?canisterId="$ID" + assert_match "content-encoding: gzip" + gunzip encoded-compressed-1.gz + diff encoded-compressed-1 src/e2e_project_frontend/assets/notreally.js + + # should split up accept-encoding lines with more than one encoding + assert_command curl -v --output encoded-compressed-2.gz -H "Accept-Encoding: gzip, deflate, br" http://localhost:"$PORT"/notreally.js?canisterId="$ID" + assert_match "content-encoding: gzip" + gunzip encoded-compressed-2.gz + diff encoded-compressed-2 src/e2e_project_frontend/assets/notreally.js } @test "leaves in place files that were already installed" { - install_asset assetscanister - dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset1.bin bs=400000 count=1 - dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset2.bin bs=400000 count=1 + install_asset assetscanister + dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset1.bin bs=400000 count=1 + dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset2.bin bs=400000 count=1 - dfx_start - assert_command dfx deploy + dfx_start + assert_command dfx deploy - assert_match '/asset1.bin 1/1' - assert_match '/asset2.bin 1/1' + assert_match '/asset1.bin 1/1' + assert_match '/asset2.bin 1/1' - dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset2.bin bs=400000 count=1 + dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset2.bin bs=400000 count=1 - assert_command dfx deploy - assert_match '/asset1.bin.*is already installed' - assert_match '/asset2.bin 1/1' + assert_command dfx deploy + assert_match '/asset1.bin.*is already installed' + assert_match '/asset2.bin 1/1' } @test "unsets asset encodings that are removed from project" { - install_asset assetscanister + install_asset assetscanister - dfx_start - dfx deploy + dfx_start + dfx deploy - assert_command dfx canister call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="text/plain"; content_encoding="arbitrary"; content=blob "content encoded in another way!"})' + assert_command dfx canister call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="text/plain"; content_encoding="arbitrary"; content=blob "content encoded in another way!"})' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' - dfx deploy + dfx deploy - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' - assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' + assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' } @test "verifies sha256" { - install_asset assetscanister + install_asset assetscanister - dfx_start - dfx deploy + dfx_start + dfx deploy - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/text-with-newlines.txt";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/text-with-newlines.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 243; 191; 114; 177; 83; 18; 144; 121; 131; 38; 109; 183; 89; 244; 120; 136; 53; 187; 14; 74; 8; 112; 86; 100; 115; 8; 179; 155; 69; 78; 95; 160; }})' - assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0})' - assert_match 'sha256 required' - assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 88; 87; 86; }})' - assert_match 'sha256 mismatch' + assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 243; 191; 114; 177; 83; 18; 144; 121; 131; 38; 109; 183; 89; 244; 120; 136; 53; 187; 14; 74; 8; 112; 86; 100; 115; 8; 179; 155; 69; 78; 95; 160; }})' + assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0})' + assert_match 'sha256 required' + assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 88; 87; 86; }})' + assert_match 'sha256 mismatch' - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 243; 191; 114; 177; 83; 18; 144; 121; 131; 38; 109; 183; 89; 244; 120; 136; 53; 187; 14; 74; 8; 112; 86; 100; 115; 8; 179; 155; 69; 78; 95; 160; }})' - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt blob "\f3\bf\72\b1\53\12\90\79\83\26\6d\b7\59\f4\78\88\35\bb\0e\4a\08\70\56\64\73\08\b3\9b\45\4e\5f\a0"})' - assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 88; 87; 86; }})' - assert_match 'sha256 mismatch' + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 243; 191; 114; 177; 83; 18; 144; 121; 131; 38; 109; 183; 89; 244; 120; 136; 53; 187; 14; 74; 8; 112; 86; 100; 115; 8; 179; 155; 69; 78; 95; 160; }})' + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt blob "\f3\bf\72\b1\53\12\90\79\83\26\6d\b7\59\f4\78\88\35\bb\0e\4a\08\70\56\64\73\08\b3\9b\45\4e\5f\a0"})' + assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 88; 87; 86; }})' + assert_match 'sha256 mismatch' } @test "can store and retrieve assets by key" { - install_asset assetscanister + install_asset assetscanister - dfx_start - dfx canister create --all - dfx build - dfx canister install e2e_project_frontend + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project_frontend - assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl - assert_eq '(blob "\b8\01 \80\0aw12 \00xy\0aKL\0b\0ajk")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl + assert_eq '(blob "\b8\01 \80\0aw12 \00xy\0aKL\0b\0ajk")' - assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl - assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl + assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' - assert_command dfx canister call --update e2e_project_frontend store '(record{key="AA"; content_type="text/plain"; content_encoding="identity"; content=blob "hello, world!"})' - assert_eq '()' - assert_command dfx canister call --update e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' - assert_eq '()' + assert_command dfx canister call --update e2e_project_frontend store '(record{key="AA"; content_type="text/plain"; content_encoding="identity"; content=blob "hello, world!"})' + assert_eq '()' + assert_command dfx canister call --update e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' + assert_eq '()' - assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl - assert_eq '(blob "XWV")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl + assert_eq '(blob "XWV")' - assert_command dfx canister call --query e2e_project_frontend retrieve '("AA")' --output idl - assert_eq '(blob "hello, world!")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("AA")' --output idl + assert_eq '(blob "hello, world!")' - assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl - assert_eq '(blob "XWV")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl + assert_eq '(blob "XWV")' - assert_command_fail dfx canister call --query e2e_project_frontend retrieve '("C")' + assert_command_fail dfx canister call --query e2e_project_frontend retrieve '("C")' } @test "asset canister supports http requests" { - install_asset assetscanister - - dfx_start - dfx canister create --all - dfx build - dfx canister install e2e_project_frontend - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - assert_command curl http://localhost:"$PORT"/text-with-newlines.txt?canisterId="$ID" - # shellcheck disable=SC2154 - assert_eq "cherries + install_asset assetscanister + + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project_frontend + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + assert_command curl http://localhost:"$PORT"/text-with-newlines.txt?canisterId="$ID" + # shellcheck disable=SC2154 + assert_eq "cherries it's cherry season CHERRIES" "$stdout" } @test 'can store arbitrarily large files' { - install_asset assetscanister + install_asset assetscanister - # make a big file with deterministic contents (a fixed hash) - for a in $(seq 1 20); do - echo "$a" >>src/e2e_project_frontend/assets/large-asset.bin - dd if=/dev/zero bs=300000 count=1 >> src/e2e_project_frontend/assets/large-asset.bin - done + # make a big file with deterministic contents (a fixed hash) + for a in $(seq 1 20); do + echo "$a" >>src/e2e_project_frontend/assets/large-asset.bin + dd if=/dev/zero bs=300000 count=1 >> src/e2e_project_frontend/assets/large-asset.bin + done - dfx_start - dfx canister create --all - dfx build - dfx canister install e2e_project_frontend + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project_frontend - # retrieve() refuses to serve just part of an asset - assert_command_fail dfx canister call --query e2e_project_frontend retrieve '("/large-asset.bin")' - assert_match 'Asset too large.' + # retrieve() refuses to serve just part of an asset + assert_command_fail dfx canister call --query e2e_project_frontend retrieve '("/large-asset.bin")' + assert_match 'Asset too large.' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/large-asset.bin";accept_encodings=vec{"identity"}})' - assert_match 'total_length = 6_000_051' - assert_match 'content_type = "application/octet-stream"' - assert_match 'content_encoding = "identity"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/large-asset.bin";accept_encodings=vec{"identity"}})' + assert_match 'total_length = 6_000_051' + assert_match 'content_type = "application/octet-stream"' + assert_match 'content_encoding = "identity"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/large-asset.bin";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/large-asset.bin";accept_encodings=vec{"identity"}})' - assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=2;sha256=opt blob "\4f\a1\0f\f7\41\9f\0e\18\81\44\8f\d5\6e\2c\6a\a1\89\a8\f5\21\92\d4\87\f5\9b\4b\a2\3c\52\eb\e5\b7"})' - assert_contains "sha256 mismatch" + assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=2;sha256=opt blob "\4f\a1\0f\f7\41\9f\0e\18\81\44\8f\d5\6e\2c\6a\a1\89\a8\f5\21\92\d4\87\f5\9b\4b\a2\3c\52\eb\e5\b7"})' + assert_contains "sha256 mismatch" - assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=2;sha256=opt blob "\4f\a1\0f\f7\41\9c\0e\18\81\44\8f\d5\6e\2c\6a\a1\89\a8\f5\21\92\d4\87\f5\9b\4b\a2\3c\52\eb\e5\b7"})' + assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=2;sha256=opt blob "\4f\a1\0f\f7\41\9c\0e\18\81\44\8f\d5\6e\2c\6a\a1\89\a8\f5\21\92\d4\87\f5\9b\4b\a2\3c\52\eb\e5\b7"})' - assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=3;sha256=opt blob "\4f\a1\0f\f7\41\9c\0e\18\81\44\8f\d5\6e\2c\6a\a1\89\a8\f5\21\92\d4\87\f5\9b\4b\a2\3c\52\eb\e5\b7"})' - assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=4})' + assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=3;sha256=opt blob "\4f\a1\0f\f7\41\9c\0e\18\81\44\8f\d5\6e\2c\6a\a1\89\a8\f5\21\92\d4\87\f5\9b\4b\a2\3c\52\eb\e5\b7"})' + assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=4})' - PORT=$(get_webserver_port) - CANISTER_ID=$(dfx canister id e2e_project_frontend) - curl -v --output curl-output.bin "http://localhost:$PORT/large-asset.bin?canisterId=$CANISTER_ID" - diff src/e2e_project_frontend/assets/large-asset.bin curl-output.bin + PORT=$(get_webserver_port) + CANISTER_ID=$(dfx canister id e2e_project_frontend) + curl -v --output curl-output.bin "http://localhost:$PORT/large-asset.bin?canisterId=$CANISTER_ID" + diff src/e2e_project_frontend/assets/large-asset.bin curl-output.bin } @test "list() return assets" { - install_asset assetscanister - - dfx_start - dfx canister create --all - dfx build - dfx canister install e2e_project_frontend - - assert_command dfx canister call --query e2e_project_frontend list '(record{})' - assert_match '"/binary/noise.txt"' - assert_match 'length = 19' - assert_match '"/text-with-newlines.txt"' - assert_match 'length = 36' - assert_match '"/sample-asset.txt"' - assert_match 'length = 24' + install_asset assetscanister + + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project_frontend + + assert_command dfx canister call --query e2e_project_frontend list '(record{})' + assert_match '"/binary/noise.txt"' + assert_match 'length = 19' + assert_match '"/text-with-newlines.txt"' + assert_match 'length = 36' + assert_match '"/sample-asset.txt"' + assert_match 'length = 24' } @test "identifies content type" { - install_asset assetscanister - - dfx_start - dfx canister create --all - - touch src/e2e_project_frontend/assets/index.html - touch src/e2e_project_frontend/assets/logo.png - touch src/e2e_project_frontend/assets/index.js - touch src/e2e_project_frontend/assets/main.css - touch src/e2e_project_frontend/assets/index.js.map - touch src/e2e_project_frontend/assets/index.js.LICENSE.txt - touch src/e2e_project_frontend/assets/index.js.LICENSE - - dfx build - dfx canister install e2e_project_frontend - - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.html";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "text/html"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/logo.png";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "image/png"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "application/javascript"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "text/plain"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/main.css";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "text/css"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js.map";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "text/plain"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js.LICENSE.txt";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "text/plain"' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js.LICENSE";accept_encodings=vec{"identity"}})' - assert_match 'content_type = "application/octet-stream"' + install_asset assetscanister + + dfx_start + dfx canister create --all + + touch src/e2e_project_frontend/assets/index.html + touch src/e2e_project_frontend/assets/logo.png + touch src/e2e_project_frontend/assets/index.js + touch src/e2e_project_frontend/assets/main.css + touch src/e2e_project_frontend/assets/index.js.map + touch src/e2e_project_frontend/assets/index.js.LICENSE.txt + touch src/e2e_project_frontend/assets/index.js.LICENSE + + dfx build + dfx canister install e2e_project_frontend + + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.html";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "text/html"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/logo.png";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "image/png"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "application/javascript"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "text/plain"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/main.css";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "text/css"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js.map";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "text/plain"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js.LICENSE.txt";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "text/plain"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/index.js.LICENSE";accept_encodings=vec{"identity"}})' + assert_match 'content_type = "application/octet-stream"' } @test "deletes assets that are removed from project" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - touch src/e2e_project_frontend/assets/will-delete-this.txt - dfx deploy + touch src/e2e_project_frontend/assets/will-delete-this.txt + dfx deploy - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend list '(record{})' - assert_match '"/will-delete-this.txt"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend list '(record{})' + assert_match '"/will-delete-this.txt"' - rm src/e2e_project_frontend/assets/will-delete-this.txt - dfx deploy + rm src/e2e_project_frontend/assets/will-delete-this.txt + dfx deploy - assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend list '(record{})' - assert_not_match '"/will-delete-this.txt"' + assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend list '(record{})' + assert_not_match '"/will-delete-this.txt"' } @test "asset configuration via .ic-assets.json5" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - touch src/e2e_project_frontend/assets/ignored.txt - touch src/e2e_project_frontend/assets/index.html - touch src/e2e_project_frontend/assets/.hidden.txt + touch src/e2e_project_frontend/assets/ignored.txt + touch src/e2e_project_frontend/assets/index.html + touch src/e2e_project_frontend/assets/.hidden.txt - mkdir src/e2e_project_frontend/assets/.well-known - touch src/e2e_project_frontend/assets/.well-known/thing.json - touch src/e2e_project_frontend/assets/.well-known/file.txt + mkdir src/e2e_project_frontend/assets/.well-known + touch src/e2e_project_frontend/assets/.well-known/thing.json + touch src/e2e_project_frontend/assets/.well-known/file.txt - echo '[ - { - "match": "ignored.txt", - "ignore": true - }, - { - "match": "*", - "cache": { - "max_age": 500 - }, - "headers": { - "x-header": "x-value" - } - }, - { - "match": ".*", - "ignore": false, - "cache": { - "max_age": 888 - }, - "headers": { - "x-extra-header": "x-extra-value" - } + echo '[ + { + "match": "ignored.txt", + "ignore": true + }, + { + "match": "*", + "cache": { + "max_age": 500 }, - { - "match": "ignored.txt", - "ignore": true + "headers": { + "x-header": "x-value" } - ]' > src/e2e_project_frontend/assets/.ic-assets.json5 - echo '[ - { - "match": "*", - "headers": { - "x-well-known-header": "x-well-known-value" - } - }, - { - "match": "*.json", - "cache": { - "max_age": 1000 - } + }, + { + "match": ".*", + "ignore": false, + "cache": { + "max_age": 888 }, - { - "match": "file.txt", - "headers": null + "headers": { + "x-extra-header": "x-extra-value" } - ]' > src/e2e_project_frontend/assets/.well-known/.ic-assets.json5 - - dfx deploy - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - - assert_command curl --head "http://localhost:$PORT/.well-known/thing.json?canisterId=$ID" - assert_match "x-extra-header: x-extra-value" - assert_match "x-header: x-value" - assert_match "x-well-known-header: x-well-known-value" - assert_match "cache-control: max-age=1000" - - assert_command curl --head "http://localhost:$PORT/.well-known/file.txt?canisterId=$ID" - assert_match "cache-control: max-age=888" - assert_not_match "x-well-known-header: x-well-known-value" - assert_not_match "x-header: x-value" - assert_not_match "x-extra-header: x-extra-value" - - assert_command curl --head "http://localhost:$PORT/index.html?canisterId=$ID" - assert_match "cache-control: max-age=500" - assert_match "x-header: x-value" - assert_not_match "x-extra-header: x-extra-value" - - assert_command curl --head "http://localhost:$PORT/.hidden.txt?canisterId=$ID" - assert_match "cache-control: max-age=888" - assert_match "x-header: x-value" - assert_match "x-extra-header: x-extra-value" - - # assert_command curl -vv "http://localhost:$PORT/ignored.txt?canisterId=$ID" - # assert_match "404 Not Found" - # from logs: - # Staging contents of new and changed assets: - # /sample-asset.txt 1/1 (24 bytes) - # /text-with-newlines.txt 1/1 (36 bytes) - # /.well-known/file.txt 1/1 (0 bytes) - # /index.html 1/1 (0 bytes) - # /.hidden.txt 1/1 (0 bytes) - # /binary/noise.txt 1/1 (19 bytes) - # /.well-known/thing.json 1/1 (0 bytes) + }, + { + "match": "ignored.txt", + "ignore": true + } + ]' > src/e2e_project_frontend/assets/.ic-assets.json5 + echo '[ + { + "match": "*", + "headers": { + "x-well-known-header": "x-well-known-value" + } + }, + { + "match": "*.json", + "cache": { + "max_age": 1000 + } + }, + { + "match": "file.txt", + "headers": null + } + ]' > src/e2e_project_frontend/assets/.well-known/.ic-assets.json5 + + dfx deploy + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + + assert_command curl --head "http://localhost:$PORT/.well-known/thing.json?canisterId=$ID" + assert_match "x-extra-header: x-extra-value" + assert_match "x-header: x-value" + assert_match "x-well-known-header: x-well-known-value" + assert_match "cache-control: max-age=1000" + + assert_command curl --head "http://localhost:$PORT/.well-known/file.txt?canisterId=$ID" + assert_match "cache-control: max-age=888" + assert_not_match "x-well-known-header: x-well-known-value" + assert_not_match "x-header: x-value" + assert_not_match "x-extra-header: x-extra-value" + + assert_command curl --head "http://localhost:$PORT/index.html?canisterId=$ID" + assert_match "cache-control: max-age=500" + assert_match "x-header: x-value" + assert_not_match "x-extra-header: x-extra-value" + + assert_command curl --head "http://localhost:$PORT/.hidden.txt?canisterId=$ID" + assert_match "cache-control: max-age=888" + assert_match "x-header: x-value" + assert_match "x-extra-header: x-extra-value" + + # assert_command curl -vv "http://localhost:$PORT/ignored.txt?canisterId=$ID" + # assert_match "404 Not Found" + # from logs: + # Staging contents of new and changed assets: + # /sample-asset.txt 1/1 (24 bytes) + # /text-with-newlines.txt 1/1 (36 bytes) + # /.well-known/file.txt 1/1 (0 bytes) + # /index.html 1/1 (0 bytes) + # /.hidden.txt 1/1 (0 bytes) + # /binary/noise.txt 1/1 (19 bytes) + # /.well-known/thing.json 1/1 (0 bytes) } @test "asset configuration via .ic-assets.json5 - nested dot directories" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - touch src/e2e_project_frontend/assets/thing.json - touch src/e2e_project_frontend/assets/.ignored-by-defualt.txt + touch src/e2e_project_frontend/assets/thing.json + touch src/e2e_project_frontend/assets/.ignored-by-defualt.txt - mkdir src/e2e_project_frontend/assets/.well-known - touch src/e2e_project_frontend/assets/.well-known/thing.json + mkdir src/e2e_project_frontend/assets/.well-known + touch src/e2e_project_frontend/assets/.well-known/thing.json - mkdir src/e2e_project_frontend/assets/.well-known/.hidden - touch src/e2e_project_frontend/assets/.well-known/.hidden/ignored.txt + mkdir src/e2e_project_frontend/assets/.well-known/.hidden + touch src/e2e_project_frontend/assets/.well-known/.hidden/ignored.txt - mkdir src/e2e_project_frontend/assets/.well-known/.another-hidden - touch src/e2e_project_frontend/assets/.well-known/.another-hidden/ignored.txt + mkdir src/e2e_project_frontend/assets/.well-known/.another-hidden + touch src/e2e_project_frontend/assets/.well-known/.another-hidden/ignored.txt - echo '[ - { - "match": ".well-known", - "ignore": false - }, - { - "match": "**/*", - "cache": { "max_age": 2000 } - } + echo '[ + { + "match": ".well-known", + "ignore": false + }, + { + "match": "**/*", + "cache": { "max_age": 2000 } + } ]' > src/e2e_project_frontend/assets/.ic-assets.json5 echo '[ - { - "match": "*", - "headers": { - "x-header": "x-value" - } - }, - { - "match": ".hidden", - "ignore": true - } - ]' > src/e2e_project_frontend/assets/.well-known/.ic-assets.json5 - echo '[ - { - "match": "*", - "ignore": false + { + "match": "*", + "headers": { + "x-header": "x-value" } + }, + { + "match": ".hidden", + "ignore": true + } + ]' > src/e2e_project_frontend/assets/.well-known/.ic-assets.json5 + echo '[ + { + "match": "*", + "ignore": false + } ]' > src/e2e_project_frontend/assets/.well-known/.hidden/.ic-assets.json5 echo '[ - { - "match": "*", - "ignore": false - } - ]' > src/e2e_project_frontend/assets/.well-known/.another-hidden/.ic-assets.json5 + { + "match": "*", + "ignore": false + } + ]' > src/e2e_project_frontend/assets/.well-known/.another-hidden/.ic-assets.json5 - dfx deploy + dfx deploy - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) - assert_command curl --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "cache-control: max-age=2000" - assert_command curl --head "http://localhost:$PORT/.well-known/thing.json?canisterId=$ID" - assert_match "cache-control: max-age=2000" - assert_match "x-header: x-value" + assert_command curl --head "http://localhost:$PORT/thing.json?canisterId=$ID" + assert_match "cache-control: max-age=2000" + assert_command curl --head "http://localhost:$PORT/.well-known/thing.json?canisterId=$ID" + assert_match "cache-control: max-age=2000" + assert_match "x-header: x-value" - assert_command curl -vv "http://localhost:$PORT/.ignored-by-defualt.txt?canisterId=$ID" - assert_match "404 Not Found" - assert_command curl -vv "http://localhost:$PORT/.well-known/.hidden/ignored.txt?canisterId=$ID" - assert_match "404 Not Found" - assert_command curl -vv "http://localhost:$PORT/.well-known/.another-hidden/ignored.txt?canisterId=$ID" - assert_match "404 Not Found" + assert_command curl -vv "http://localhost:$PORT/.ignored-by-defualt.txt?canisterId=$ID" + assert_match "404 Not Found" + assert_command curl -vv "http://localhost:$PORT/.well-known/.hidden/ignored.txt?canisterId=$ID" + assert_match "404 Not Found" + assert_command curl -vv "http://localhost:$PORT/.well-known/.another-hidden/ignored.txt?canisterId=$ID" + assert_match "404 Not Found" } @test "asset configuration via .ic-assets.json5 - overwriting default headers" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - touch src/e2e_project_frontend/assets/thing.json + touch src/e2e_project_frontend/assets/thing.json - echo '[ - { - "match": "thing.json", - "cache": { "max_age": 2000 }, - "headers": { - "Content-Encoding": "my-encoding", - "Content-Type": "x-type", - "Cache-Control": "custom", - "etag": "my-etag" - } + echo '[ + { + "match": "thing.json", + "cache": { "max_age": 2000 }, + "headers": { + "Content-Encoding": "my-encoding", + "Content-Type": "x-type", + "Cache-Control": "custom", + "etag": "my-etag" } - ]' > src/e2e_project_frontend/assets/.ic-assets.json5 + } + ]' > src/e2e_project_frontend/assets/.ic-assets.json5 - dfx deploy + dfx deploy - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) - assert_command curl --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "cache-control: custom" - assert_match "content-encoding: my-encoding" - assert_match "content-type: x-type" - assert_not_match "etag: my-etag" - assert_match "etag: \"[a-z0-9]{64}\"" + assert_command curl --head "http://localhost:$PORT/thing.json?canisterId=$ID" + assert_match "cache-control: custom" + assert_match "content-encoding: my-encoding" + assert_match "content-type: x-type" + assert_not_match "etag: my-etag" + assert_match "etag: \"[a-z0-9]{64}\"" } @test "aliasing rules: to .html or /index.html" { - echo "test alias file" >'src/e2e_project_frontend/assets/test_alias_file.html' - mkdir 'src/e2e_project_frontend/assets/index_test' - echo "test index file" >'src/e2e_project_frontend/assets/index_test/index.html' - - TEST_ALIAS_SHA256="blob \"\67\fb\58\e3\ea\45\56\10\5d\d5\a4\08\0e\8d\38\6e\0c\5f\9b\f5\f5\05\dd\0f\4a\2b\d8\65\ec\27\c6\06\"" - TEST_INDEX_SHA256="blob \"\2c\0c\c1\2a\96\c6\79\8c\34\be\fd\8f\6f\df\ba\2f\39\57\8e\15\c0\f8\69\2f\54\da\df\06\ee\98\08\f5\"" - - dfx_start - dfx deploy - - # decode as expected - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/test_alias_file.html";headers=vec{};method="GET";body=vec{}})' - assert_match "test alias file" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/test_alias_file";headers=vec{};method="GET";body=vec{}})' - assert_match "test alias file" - assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/index_test";headers=vec{};method="GET";body=vec{}})' - assert_match "test index file" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "test alias file" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "test alias file" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" - assert_match "test index file" - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" - # shellcheck disable=SC2154 - assert_match "200 OK" "$stderr" - assert_match "test alias file" - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test alias file" - assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test index file" - assert_command curl --fail -vv http://localhost:"$PORT"/index_test/index?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test index file" - - # toggle aliasing on and off using `set_asset_properties` - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/test_alias_file.html"; is_aliased=opt(opt(false)) })' - assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" - assert_match "404" "$stderr" - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/test_alias_file.html"; is_aliased=opt(opt(true)) })' - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" - assert_match "200 OK" "$stderr" - - # redirect survives upgrade - assert_command dfx deploy --upgrade-unchanged - assert_match "is already installed" - - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" - # shellcheck disable=SC2154 - assert_match "200 OK" "$stderr" - assert_match "test alias file" - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test alias file" - assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test index file" - - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "test alias file" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "test alias file" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" - assert_match "test index file" - - # disabling redirect works - echo "DISABLING NOW" - echo '[ - { - "match": "test_alias_file.html", - "enable_aliasing": false - } - ]' > src/e2e_project_frontend/assets/.ic-assets.json5 - dfx deploy e2e_project_frontend - - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" - # shellcheck disable=SC2154 - assert_match "200 OK" "$stderr" - assert_match "test alias file" - assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" - assert_match "404 Not Found" "$stderr" - assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test index file" - - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "test alias file" - assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "key not found" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" - assert_match "test index file" - - # disabled redirect survives canister upgrade - echo "UPGRADE" - assert_command dfx deploy --upgrade-unchanged - - assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" - # shellcheck disable=SC2154 - assert_match "200 OK" "$stderr" - assert_match "test alias file" - assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" - assert_match "404 Not Found" "$stderr" - assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" - assert_match "200 OK" "$stderr" - assert_match "test index file" - - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "test alias file" - assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" - assert_match "key not found" - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" - assert_match "test index file" - - # + echo "test alias file" >'src/e2e_project_frontend/assets/test_alias_file.html' + mkdir 'src/e2e_project_frontend/assets/index_test' + echo "test index file" >'src/e2e_project_frontend/assets/index_test/index.html' + + TEST_ALIAS_SHA256="blob \"\67\fb\58\e3\ea\45\56\10\5d\d5\a4\08\0e\8d\38\6e\0c\5f\9b\f5\f5\05\dd\0f\4a\2b\d8\65\ec\27\c6\06\"" + TEST_INDEX_SHA256="blob \"\2c\0c\c1\2a\96\c6\79\8c\34\be\fd\8f\6f\df\ba\2f\39\57\8e\15\c0\f8\69\2f\54\da\df\06\ee\98\08\f5\"" + + dfx_start + dfx deploy + + # decode as expected + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/test_alias_file.html";headers=vec{};method="GET";body=vec{}})' + assert_match "test alias file" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/test_alias_file";headers=vec{};method="GET";body=vec{}})' + assert_match "test alias file" + assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/index_test";headers=vec{};method="GET";body=vec{}})' + assert_match "test index file" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "test alias file" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "test alias file" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" + assert_match "test index file" + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" + # shellcheck disable=SC2154 + assert_match "200 OK" "$stderr" + assert_match "test alias file" + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test alias file" + assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test index file" + assert_command curl --fail -vv http://localhost:"$PORT"/index_test/index?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test index file" + + # toggle aliasing on and off using `set_asset_properties` + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/test_alias_file.html"; is_aliased=opt(opt(false)) })' + assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" + assert_match "404" "$stderr" + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/test_alias_file.html"; is_aliased=opt(opt(true)) })' + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" + assert_match "200 OK" "$stderr" + + # redirect survives upgrade + assert_command dfx deploy --upgrade-unchanged + assert_match "is already installed" + + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" + # shellcheck disable=SC2154 + assert_match "200 OK" "$stderr" + assert_match "test alias file" + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test alias file" + assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test index file" + + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "test alias file" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "test alias file" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" + assert_match "test index file" + + # disabling redirect works + echo "DISABLING NOW" + echo '[ + { + "match": "test_alias_file.html", + "enable_aliasing": false + } + ]' > src/e2e_project_frontend/assets/.ic-assets.json5 + dfx deploy e2e_project_frontend + + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" + # shellcheck disable=SC2154 + assert_match "200 OK" "$stderr" + assert_match "test alias file" + assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" + assert_match "404 Not Found" "$stderr" + assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test index file" + + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "test alias file" + assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "key not found" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" + assert_match "test index file" + + # disabled redirect survives canister upgrade + echo "UPGRADE" + assert_command dfx deploy --upgrade-unchanged + + assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file.html?canisterId="$ID" + # shellcheck disable=SC2154 + assert_match "200 OK" "$stderr" + assert_match "test alias file" + assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" + assert_match "404 Not Found" "$stderr" + assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" + assert_match "200 OK" "$stderr" + assert_match "test index file" + + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file.html\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "test alias file" + assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/test_alias_file\";content_encoding=\"identity\";index=0;sha256=opt $TEST_ALIAS_SHA256})" + assert_match "key not found" + assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback "(record{key=\"/index_test\";content_encoding=\"identity\";index=0;sha256=opt $TEST_INDEX_SHA256})" + assert_match "test index file" + + # } @test "asset configuration via .ic-assets.json5 - detect unused config" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - mkdir src/e2e_project_frontend/assets/somedir - touch src/e2e_project_frontend/assets/somedir/upload-me.txt - echo '[ - { - "match": "nevermatchme", - "cache": { "max_age": 2000 } - } - ]' > src/e2e_project_frontend/assets/.ic-assets.json5 - echo '[ - { - "match": "upload-me.txt", - "headers": { "key": "value" } - }, - { - "match": "nevermatchme", - "headers": {}, - "ignore": false - }, - { - "match": "nevermatchmetoo", - "headers": null, - "ignore": false - }, - { - "match": "non-matcher", - "headers": {"x-header": "x-value"}, - "ignore": false - }, - { - "match": "/thanks-for-not-stripping-forward-slash", - "headers": {"x-header": "x-value"}, - "ignore": false - } - ]' > src/e2e_project_frontend/assets/somedir/.ic-assets.json5 + mkdir src/e2e_project_frontend/assets/somedir + touch src/e2e_project_frontend/assets/somedir/upload-me.txt + echo '[ + { + "match": "nevermatchme", + "cache": { "max_age": 2000 } + } + ]' > src/e2e_project_frontend/assets/.ic-assets.json5 + echo '[ + { + "match": "upload-me.txt", + "headers": { "key": "value" } + }, + { + "match": "nevermatchme", + "headers": {}, + "ignore": false + }, + { + "match": "nevermatchmetoo", + "headers": null, + "ignore": false + }, + { + "match": "non-matcher", + "headers": {"x-header": "x-value"}, + "ignore": false + }, + { + "match": "/thanks-for-not-stripping-forward-slash", + "headers": {"x-header": "x-value"}, + "ignore": false + } + ]' > src/e2e_project_frontend/assets/somedir/.ic-assets.json5 - assert_command dfx deploy - assert_match 'WARN: 1 unmatched configuration in .*/src/e2e_project_frontend/assets/.ic-assets.json config file:' - assert_contains 'WARN: { + assert_command dfx deploy + assert_match 'WARN: 1 unmatched configuration in .*/src/e2e_project_frontend/assets/.ic-assets.json config file:' + assert_contains 'WARN: { "match": "nevermatchme", "cache": { "max_age": 2000 }, "allow_raw_access": true }' - assert_match 'WARN: 4 unmatched configurations in .*/src/e2e_project_frontend/assets/somedir/.ic-assets.json config file:' - assert_contains 'WARN: { + assert_match 'WARN: 4 unmatched configurations in .*/src/e2e_project_frontend/assets/somedir/.ic-assets.json config file:' + assert_contains 'WARN: { "match": "nevermatchme", "headers": {}, "ignore": false, @@ -1421,8 +1421,8 @@ WARN: { "ignore": false, "allow_raw_access": true }' - # splitting this up into two checks, because the order is different on macos vs ubuntu - assert_contains 'WARN: { + # splitting this up into two checks, because the order is different on macos vs ubuntu + assert_contains 'WARN: { "match": "/thanks-for-not-stripping-forward-slash", "headers": { "x-header": "x-value" @@ -1433,26 +1433,26 @@ WARN: { } @test "asset configuration via .ic-assets.json5 - get and set asset properties" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - mkdir src/e2e_project_frontend/assets/somedir - touch src/e2e_project_frontend/assets/somedir/upload-me.txt - echo '[ - { - "match": "**/*", - "cache": { "max_age": 2000 }, - "headers": { "x-key": "x-value" }, - "enable_aliasing": true - } - ]' > src/e2e_project_frontend/assets/.ic-assets.json5 + mkdir src/e2e_project_frontend/assets/somedir + touch src/e2e_project_frontend/assets/somedir/upload-me.txt + echo '[ + { + "match": "**/*", + "cache": { "max_age": 2000 }, + "headers": { "x-key": "x-value" }, + "enable_aliasing": true + } + ]' > src/e2e_project_frontend/assets/.ic-assets.json5 - dfx deploy + dfx deploy - # read properties - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' - assert_contains '( + # read properties + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' + assert_contains '( record { headers = opt vec { record { "x-key"; "x-value" } }; is_aliased = opt true; @@ -1461,18 +1461,18 @@ WARN: { }, )' - # access required to update - assert_command_fail dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; max_age=opt(opt(5:nat64)) })' --identity anonymous - assert_match "Caller does not have Commit permission" - dfx identity new other --storage-mode plaintext - assert_command_fail dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; max_age=opt(opt(5:nat64)) })' --identity other - assert_match "Caller does not have Commit permission" - - # set max_age property and read it back - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; max_age=opt(opt(5:nat64)) })' - assert_contains '()' - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' - assert_contains '( + # access required to update + assert_command_fail dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; max_age=opt(opt(5:nat64)) })' --identity anonymous + assert_match "Caller does not have Commit permission" + dfx identity new other --storage-mode plaintext + assert_command_fail dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; max_age=opt(opt(5:nat64)) })' --identity other + assert_match "Caller does not have Commit permission" + + # set max_age property and read it back + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; max_age=opt(opt(5:nat64)) })' + assert_contains '()' + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' + assert_contains '( record { headers = opt vec { record { "x-key"; "x-value" } }; is_aliased = opt true; @@ -1481,11 +1481,11 @@ WARN: { }, )' - # set headers property and read it back - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; headers=opt(opt(vec{record {"new-key"; "new-value"}}))})' - assert_contains '()' - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' - assert_contains '( + # set headers property and read it back + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; headers=opt(opt(vec{record {"new-key"; "new-value"}}))})' + assert_contains '()' + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' + assert_contains '( record { headers = opt vec { record { "new-key"; "new-value" } }; is_aliased = opt true; @@ -1494,11 +1494,11 @@ WARN: { }, )' - # set allow_raw_access property and read it back - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; allow_raw_access=opt(opt(true))})' - assert_contains '()' - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' - assert_contains '( + # set allow_raw_access property and read it back + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; allow_raw_access=opt(opt(true))})' + assert_contains '()' + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' + assert_contains '( record { headers = opt vec { record { "new-key"; "new-value" } }; is_aliased = opt true; @@ -1507,11 +1507,11 @@ WARN: { }, )' - # set is_aliased property and read it back - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; is_aliased=opt(opt(false))})' - assert_contains '()' - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' - assert_contains '( + # set is_aliased property and read it back + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; is_aliased=opt(opt(false))})' + assert_contains '()' + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' + assert_contains '( record { headers = opt vec { record { "new-key"; "new-value" } }; is_aliased = opt false; @@ -1520,11 +1520,11 @@ WARN: { }, )' - # set all properties to None and read them back - assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; headers=opt(null); max_age=opt(null); allow_raw_access=opt(null); is_aliased=opt(null)})' - assert_contains '()' - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' - assert_contains '( + # set all properties to None and read them back + assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/somedir/upload-me.txt"; headers=opt(null); max_age=opt(null); allow_raw_access=opt(null); is_aliased=opt(null)})' + assert_contains '()' + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' + assert_contains '( record { headers = null; is_aliased = null; @@ -1535,53 +1535,53 @@ WARN: { } @test "asset configuration via .ic-assets.json5 - pretty printing when deploying" { - install_asset assetscanister + install_asset assetscanister - dfx_start + dfx_start - mkdir src/e2e_project_frontend/assets/somedir - echo "content" > src/e2e_project_frontend/assets/somedir/upload-me.txt - echo '[ - { - "match": "**/*", - "cache": { "max_age": 2000 }, - "headers": { - "x-header": "x-value" - }, - "enable_aliasing": true + mkdir src/e2e_project_frontend/assets/somedir + echo "content" > src/e2e_project_frontend/assets/somedir/upload-me.txt + echo '[ + { + "match": "**/*", + "cache": { "max_age": 2000 }, + "headers": { + "x-header": "x-value" }, - ]' > src/e2e_project_frontend/assets/somedir/.ic-assets.json5 + "enable_aliasing": true + }, + ]' > src/e2e_project_frontend/assets/somedir/.ic-assets.json5 - assert_command dfx deploy - assert_match '/somedir/upload-me.txt 1/1 \(8 bytes\) sha [0-9a-z]* \(with cache and 1 header\)' + assert_command dfx deploy + assert_match '/somedir/upload-me.txt 1/1 \(8 bytes\) sha [0-9a-z]* \(with cache and 1 header\)' } @test "uses selected canister wasm" { - dfx_start - use_asset_wasm 0.12.1 - assert_command dfx deploy - assert_command dfx canister info e2e_project_frontend - assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 - use_default_asset_wasm - assert_command dfx deploy - assert_command dfx canister info e2e_project_frontend - assert_not_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 + dfx_start + use_asset_wasm 0.12.1 + assert_command dfx deploy + assert_command dfx canister info e2e_project_frontend + assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 + use_default_asset_wasm + assert_command dfx deploy + assert_command dfx canister info e2e_project_frontend + assert_not_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 } @test "api version endpoint" { - install_asset assetscanister - dfx_start - assert_command dfx deploy - assert_command dfx canister call e2e_project_frontend api_version '()' - assert_match '\([0-9]* : nat16\)' + install_asset assetscanister + dfx_start + assert_command dfx deploy + assert_command dfx canister call e2e_project_frontend api_version '()' + assert_match '\([0-9]* : nat16\)' } @test "syncs asset properties when redeploying" { - install_asset assetscanister - dfx_start - assert_command dfx deploy - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/text-with-newlines.txt")' - assert_contains '( + install_asset assetscanister + dfx_start + assert_command dfx deploy + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/text-with-newlines.txt")' + assert_contains '( record { headers = null; is_aliased = null; @@ -1590,20 +1590,20 @@ WARN: { }, )' - echo '[ - { - "match": "**/*", - "cache": { "max_age": 2000 }, - "headers": { - "x-header": "x-value" - }, - "allow_raw_access": true, - "enable_aliasing": false + echo '[ + { + "match": "**/*", + "cache": { "max_age": 2000 }, + "headers": { + "x-header": "x-value" }, - ]' > src/e2e_project_frontend/assets/.ic-assets.json5 - assert_command dfx deploy - assert_command dfx canister call e2e_project_frontend get_asset_properties '("/text-with-newlines.txt")' - assert_contains '( + "allow_raw_access": true, + "enable_aliasing": false + }, + ]' > src/e2e_project_frontend/assets/.ic-assets.json5 + assert_command dfx deploy + assert_command dfx canister call e2e_project_frontend get_asset_properties '("/text-with-newlines.txt")' + assert_contains '( record { headers = opt vec { record { "x-header"; "x-value" } }; is_aliased = opt false; diff --git a/e2e/tests-dfx/base.bash b/e2e/tests-dfx/base.bash index 274a1e607c..5903d4244f 100644 --- a/e2e/tests-dfx/base.bash +++ b/e2e/tests-dfx/base.bash @@ -3,38 +3,38 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "provides base library location by default" { - install_asset base + install_asset base - dfx_start - dfx canister create --all - dfx build - dfx canister install e2e_project_backend + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project_backend - assert_command dfx canister call --query e2e_project_backend is_digit '("5")' - assert_eq '(true)' + assert_command dfx canister call --query e2e_project_backend is_digit '("5")' + assert_eq '(true)' - assert_command dfx canister call --query e2e_project_backend is_digit '("w")' - assert_eq '(false)' + assert_command dfx canister call --query e2e_project_backend is_digit '("w")' + assert_eq '(false)' } @test "does not provide base library if there is a packtool" { - install_asset base - jq '.defaults.build.packtool="echo"' dfx.json | sponge dfx.json + install_asset base + jq '.defaults.build.packtool="echo"' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - assert_command_fail dfx build - assert_match 'import error \[M0010\], package "base" not defined' + dfx_start + dfx canister create --all + assert_command_fail dfx build + assert_match 'import error \[M0010\], package "base" not defined' } diff --git a/e2e/tests-dfx/basic-project.bash b/e2e/tests-dfx/basic-project.bash index f298c29947..6dd4ab76f8 100644 --- a/e2e/tests-dfx/basic-project.bash +++ b/e2e/tests-dfx/basic-project.bash @@ -3,48 +3,48 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "build + install + call + request-status -- greet_mo" { - dfx_new hello - install_asset greet - dfx_start - dfx canister create --all - dfx build - # INSTALL_REQUEST_ID=$(dfx canister install hello_backend --async) - # dfx canister request-status $INSTALL_REQUEST_ID - dfx canister install hello_backend - - assert_command dfx canister call hello_backend greet '("Banzai")' - assert_eq '("Hello, Banzai!")' - - assert_command dfx canister call hello_backend greet --type raw '4449444c00017103e29883' - assert_eq '("Hello, ☃!")' - - assert_command dfx canister call --query hello_backend greet '("Bongalo")' - assert_eq '("Hello, Bongalo!")' - - # Using call --async and request-status. - # Call with user Identity as Sender - assert_command dfx canister call --async hello_backend greet Blueberry - # At this point $output is the request ID. - # shellcheck disable=SC2154 - assert_command dfx canister request-status "$stdout" "$(dfx canister id hello_backend)" - assert_eq '("Hello, Blueberry!")' - - # Call using the wallet's call forwarding - assert_command dfx canister call --async hello_backend greet Blueberry --wallet="$(dfx identity get-wallet)" - # At this point $output is the request ID. - # shellcheck disable=SC2154 - assert_command dfx canister request-status "$stdout" "$(dfx identity get-wallet)" - assert_eq \ + dfx_new hello + install_asset greet + dfx_start + dfx canister create --all + dfx build + # INSTALL_REQUEST_ID=$(dfx canister install hello_backend --async) + # dfx canister request-status $INSTALL_REQUEST_ID + dfx canister install hello_backend + + assert_command dfx canister call hello_backend greet '("Banzai")' + assert_eq '("Hello, Banzai!")' + + assert_command dfx canister call hello_backend greet --type raw '4449444c00017103e29883' + assert_eq '("Hello, ☃!")' + + assert_command dfx canister call --query hello_backend greet '("Bongalo")' + assert_eq '("Hello, Bongalo!")' + + # Using call --async and request-status. + # Call with user Identity as Sender + assert_command dfx canister call --async hello_backend greet Blueberry + # At this point $output is the request ID. + # shellcheck disable=SC2154 + assert_command dfx canister request-status "$stdout" "$(dfx canister id hello_backend)" + assert_eq '("Hello, Blueberry!")' + + # Call using the wallet's call forwarding + assert_command dfx canister call --async hello_backend greet Blueberry --wallet="$(dfx identity get-wallet)" + # At this point $output is the request ID. + # shellcheck disable=SC2154 + assert_command dfx canister request-status "$stdout" "$(dfx identity get-wallet)" + assert_eq \ '( variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01q\11Hello, Blueberry!" } @@ -53,79 +53,79 @@ teardown() { } @test "build + install + call + request-status -- counter_mo" { - dfx_new hello - install_asset counter - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend + dfx_new hello + install_asset counter + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend - assert_command dfx canister call hello_backend read - assert_eq "(0 : nat)" + assert_command dfx canister call hello_backend read + assert_eq "(0 : nat)" - assert_command dfx canister call hello_backend inc - assert_eq "()" + assert_command dfx canister call hello_backend inc + assert_eq "()" - assert_command dfx canister call hello_backend read - assert_eq "(1 : nat)" + assert_command dfx canister call hello_backend read + assert_eq "(1 : nat)" - dfx canister call hello_backend inc - assert_command dfx canister call hello_backend read - assert_eq "(2 : nat)" + dfx canister call hello_backend inc + assert_command dfx canister call hello_backend read + assert_eq "(2 : nat)" - assert_command dfx canister call hello_backend read --output raw - assert_eq "4449444c00017d02" + assert_command dfx canister call hello_backend read --output raw + assert_eq "4449444c00017d02" - assert_command_fail dfx canister call --query hello_backend inc - assert_match "Not a query method." + assert_command_fail dfx canister call --query hello_backend inc + assert_match "Not a query method." - dfx canister call hello_backend inc - assert_command dfx canister call --query hello_backend read - assert_eq "(3 : nat)" + dfx canister call hello_backend inc + assert_command dfx canister call --query hello_backend read + assert_eq "(3 : nat)" - assert_command dfx canister call hello_backend inc --async - assert_command dfx canister request-status "$stdout" "$(dfx canister id hello_backend)" + assert_command dfx canister call hello_backend inc --async + assert_command dfx canister request-status "$stdout" "$(dfx canister id hello_backend)" - # Call write. - assert_command dfx canister call hello_backend write 1337 - assert_eq "()" + # Call write. + assert_command dfx canister call hello_backend write 1337 + assert_eq "()" - # Write has no return value. But we can _call_ read too. - # Call with user Identity as Sender - assert_command dfx canister call hello_backend read --async - assert_command dfx canister request-status "$stdout" "$(dfx canister id hello_backend)" - assert_eq "(1_337 : nat)" + # Write has no return value. But we can _call_ read too. + # Call with user Identity as Sender + assert_command dfx canister call hello_backend read --async + assert_command dfx canister request-status "$stdout" "$(dfx canister id hello_backend)" + assert_eq "(1_337 : nat)" - # Call using the wallet's call forwarding - assert_command dfx canister call hello_backend read --async --wallet="$(dfx identity get-wallet)" - assert_command dfx canister request-status "$stdout" "$(dfx identity get-wallet)" - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01}\b9\0a" } })' + # Call using the wallet's call forwarding + assert_command dfx canister call hello_backend read --async --wallet="$(dfx identity get-wallet)" + assert_command dfx canister request-status "$stdout" "$(dfx identity get-wallet)" + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01}\b9\0a" } })' } @test "build + install + call -- counter_idl_mo" { - dfx_new hello - install_asset counter_idl - dfx_start - dfx canister create --all - dfx build - dfx canister install --all - - assert_command dfx canister call hello_backend inc '(42,false,"testzZ",vec{1;2;3},opt record{head=42; tail=opt record{head=+43; tail=null}}, variant { cons=record{ 42; variant { cons=record{43; variant { nil }} } } })' --output idl - assert_eq "(43 : int, true, \"uftu{[\", vec { 2 : nat; 3 : nat; 4 : nat;}, opt record { head = 43 : int; tail = opt record { head = 44 : int; tail = null;};}, variant { cons = record { 43 : int; variant { cons = record { 44 : int; variant { nil };} };} })" + dfx_new hello + install_asset counter_idl + dfx_start + dfx canister create --all + dfx build + dfx canister install --all + + assert_command dfx canister call hello_backend inc '(42,false,"testzZ",vec{1;2;3},opt record{head=42; tail=opt record{head=+43; tail=null}}, variant { cons=record{ 42; variant { cons=record{43; variant { nil }} } } })' --output idl + assert_eq "(43 : int, true, \"uftu{[\", vec { 2 : nat; 3 : nat; 4 : nat;}, opt record { head = 43 : int; tail = opt record { head = 44 : int; tail = null;};}, variant { cons = record { 43 : int; variant { cons = record { 44 : int; variant { nil };} };} })" } @test "build + install + call -- matrix_multiply_mo" { - dfx_new hello - install_asset matrix_multiply - dfx_start - dfx canister create --all - dfx build - dfx canister install --all - - assert_command dfx canister call hello_backend multiply '(vec{vec{1;2};vec{3;4};vec{5;6}},vec{vec{1;2;3};vec{4;5;6}})' - assert_eq \ + dfx_new hello + install_asset matrix_multiply + dfx_start + dfx canister create --all + dfx build + dfx canister install --all + + assert_command dfx canister call hello_backend multiply '(vec{vec{1;2};vec{3;4};vec{5;6}},vec{vec{1;2;3};vec{4;5;6}})' + assert_eq \ "( vec { vec { 9 : int; 12 : int; 15 : int }; @@ -136,27 +136,27 @@ teardown() { } @test "inspect message - motoko" { - dfx_new hello - install_asset inspect_message - dfx_start - dfx deploy + dfx_new hello + install_asset inspect_message + dfx_start + dfx deploy - assert_command dfx canister call hello_backend always_accepted + assert_command dfx canister call hello_backend always_accepted - assert_command_fail dfx canister call hello_backend always_rejected - assert_contains "canister_inspect_message explicitly refused message" + assert_command_fail dfx canister call hello_backend always_rejected + assert_contains "canister_inspect_message explicitly refused message" } @test "inspect message - rust" { - dfx_new_rust hello + dfx_new_rust hello - install_asset inspect_message_rs + install_asset inspect_message_rs - dfx_start - dfx deploy + dfx_start + dfx deploy - assert_command dfx canister call hello_backend always_accepted + assert_command dfx canister call hello_backend always_accepted - assert_command_fail dfx canister call hello_backend always_rejected - assert_contains "Canister $(dfx canister id hello_backend) rejected the message" + assert_command_fail dfx canister call hello_backend always_rejected + assert_contains "Canister $(dfx canister id hello_backend) rejected the message" } diff --git a/e2e/tests-dfx/bitcoin.bash b/e2e/tests-dfx/bitcoin.bash index c8fb8385c0..72d81f48c1 100644 --- a/e2e/tests-dfx/bitcoin.bash +++ b/e2e/tests-dfx/bitcoin.bash @@ -5,259 +5,259 @@ load ../utils/_ BITCOIN_CANISTER_ID="g4xu7-jiaaa-aaaan-aaaaq-cai" setup() { - standard_setup + standard_setup - bitcoind -regtest -daemonwait + bitcoind -regtest -daemonwait } teardown() { - bitcoin-cli -regtest stop + bitcoin-cli -regtest stop - dfx_stop - # stop_dfx_replica - # stop_dfx_bootstrap - standard_teardown + dfx_stop + # stop_dfx_replica + # stop_dfx_bootstrap + standard_teardown } set_project_default_bitcoin_enabled() { - jq '.defaults.bitcoin.enabled=true' dfx.json | sponge dfx.json + jq '.defaults.bitcoin.enabled=true' dfx.json | sponge dfx.json } set_shared_local_network_bitcoin_enabled() { - create_networks_json - jq '.local.bitcoin.enabled=true' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + create_networks_json + jq '.local.bitcoin.enabled=true' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" } set_local_network_bitcoin_enabled() { - jq '.networks.local.bitcoin.enabled=true' dfx.json | sponge dfx.json + jq '.networks.local.bitcoin.enabled=true' dfx.json | sponge dfx.json } @test "noop" { - assert_command bitcoin-cli -regtest createwallet "test" - ADDRESS="$(bitcoin-cli -regtest getnewaddress)" - assert_command bitcoin-cli -regtest generatetoaddress 101 "$ADDRESS" + assert_command bitcoin-cli -regtest createwallet "test" + ADDRESS="$(bitcoin-cli -regtest getnewaddress)" + assert_command bitcoin-cli -regtest generatetoaddress 101 "$ADDRESS" } @test "dfx restarts replica when ic-btc-adapter restarts" { - dfx_new hello - dfx_start --enable-bitcoin - - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' - - REPLICA_PID=$(get_replica_pid) - BTC_ADAPTER_PID=$(get_btc_adapter_pid) - - echo "replica pid is $REPLICA_PID" - echo "ic-btc-adapter pid is $BTC_ADAPTER_PID" - - kill -KILL "$BTC_ADAPTER_PID" - assert_process_exits "$BTC_ADAPTER_PID" 15s - assert_process_exits "$REPLICA_PID" 15s - - timeout 15s sh -c \ - 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ - || (echo "replica did not restart" && ps aux && exit 1) - wait_until_replica_healthy - - # Sometimes initially get an error like: - # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module - # but the condition clears. - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - # even after the above, still sometimes fails with - # IC0515: Certified state is not available yet. Please try again... - sleep 10 - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - - assert_command dfx canister call hello_backend greet '("Omega")' - assert_eq '("Hello, Omega!")' - - ID=$(dfx canister id hello_frontend) - - timeout 15s sh -c \ - "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port\")/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ - || (echo "icx-proxy did not restart" && ps aux && exit 1) - - assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" + dfx_new hello + dfx_start --enable-bitcoin + + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' + + REPLICA_PID=$(get_replica_pid) + BTC_ADAPTER_PID=$(get_btc_adapter_pid) + + echo "replica pid is $REPLICA_PID" + echo "ic-btc-adapter pid is $BTC_ADAPTER_PID" + + kill -KILL "$BTC_ADAPTER_PID" + assert_process_exits "$BTC_ADAPTER_PID" 15s + assert_process_exits "$REPLICA_PID" 15s + + timeout 15s sh -c \ + 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ + || (echo "replica did not restart" && ps aux && exit 1) + wait_until_replica_healthy + + # Sometimes initially get an error like: + # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module + # but the condition clears. + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + # even after the above, still sometimes fails with + # IC0515: Certified state is not available yet. Please try again... + sleep 10 + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + + assert_command dfx canister call hello_backend greet '("Omega")' + assert_eq '("Hello, Omega!")' + + ID=$(dfx canister id hello_frontend) + + timeout 15s sh -c \ + "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port\")/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ + || (echo "icx-proxy did not restart" && ps aux && exit 1) + + assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" } @test "dfx restarts replica when ic-btc-adapter restarts - replica and bootstrap" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - dfx_replica --enable-bitcoin - dfx_bootstrap - - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' - - REPLICA_PID=$(get_replica_pid) - BTC_ADAPTER_PID=$(get_btc_adapter_pid) - - echo "replica pid is $REPLICA_PID" - echo "replica port is $(get_replica_port)" - echo "ic-btc-adapter pid is $BTC_ADAPTER_PID" - - echo "killing btc adapter" - - kill -KILL "$BTC_ADAPTER_PID" - assert_process_exits "$BTC_ADAPTER_PID" 15s - assert_process_exits "$REPLICA_PID" 15s - - timeout 15s sh -x -c \ - "until curl --fail --verbose -o /dev/null http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port\")/api/v2/status; do echo \"waiting for replica to restart on port \$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port\")\"; sleep 1; done" \ - || (echo "replica did not restart" && echo "last replica port was $(get_replica_port)" && ps aux && exit 1) - - # bootstrap doesn't detect the new replica port, so we have to restart it - stop_dfx_bootstrap - dfx_bootstrap - - # Sometimes initially get an error like: - # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module - # but the condition clears. - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - # even after the above, still sometimes fails with - # IC0515: Certified state is not available yet. Please try again... - sleep 10 - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - - assert_command dfx canister call hello_backend greet '("Omega")' - assert_eq '("Hello, Omega!")' + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + dfx_replica --enable-bitcoin + dfx_bootstrap + + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' + + REPLICA_PID=$(get_replica_pid) + BTC_ADAPTER_PID=$(get_btc_adapter_pid) + + echo "replica pid is $REPLICA_PID" + echo "replica port is $(get_replica_port)" + echo "ic-btc-adapter pid is $BTC_ADAPTER_PID" + + echo "killing btc adapter" + + kill -KILL "$BTC_ADAPTER_PID" + assert_process_exits "$BTC_ADAPTER_PID" 15s + assert_process_exits "$REPLICA_PID" 15s + + timeout 15s sh -x -c \ + "until curl --fail --verbose -o /dev/null http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port\")/api/v2/status; do echo \"waiting for replica to restart on port \$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port\")\"; sleep 1; done" \ + || (echo "replica did not restart" && echo "last replica port was $(get_replica_port)" && ps aux && exit 1) + + # bootstrap doesn't detect the new replica port, so we have to restart it + stop_dfx_bootstrap + dfx_bootstrap + + # Sometimes initially get an error like: + # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module + # but the condition clears. + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + # even after the above, still sometimes fails with + # IC0515: Certified state is not available yet. Please try again... + sleep 10 + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + + assert_command dfx canister call hello_backend greet '("Omega")' + assert_eq '("Hello, Omega!")' } @test "dfx start --bitcoin-node implies --enable-bitcoin" { - dfx_new hello - dfx_start "--bitcoin-node" "127.0.0.1:18444" + dfx_new hello + dfx_start "--bitcoin-node" "127.0.0.1:18444" - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" } @test "dfx replica --bitcoin-node implies --enable-bitcoin" { - skip "dfx replica and bootstrap are deprecated" + skip "dfx replica and bootstrap are deprecated" - dfx_new hello - dfx_replica "--bitcoin-node" "127.0.0.1:18444" - dfx_bootstrap + dfx_new hello + dfx_replica "--bitcoin-node" "127.0.0.1:18444" + dfx_bootstrap - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" } @test "dfx start --enable-bitcoin with no other configuration succeeds" { - dfx_new hello + dfx_new hello - dfx_start --enable-bitcoin + dfx_start --enable-bitcoin - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" } @test "dfx start --enable-bitcoin --background waits until bitcoin canister is installed" { - dfx_new hello + dfx_new hello - dfx_start --enable-bitcoin + dfx_start --enable-bitcoin - assert_command dfx canister info "$BITCOIN_CANISTER_ID" - assert_contains "Controllers: 2vxsx-fae" - assert_contains "Module hash: 0x" + assert_command dfx canister info "$BITCOIN_CANISTER_ID" + assert_contains "Controllers: 2vxsx-fae" + assert_contains "Module hash: 0x" } @test "dfx replica --enable-bitcoin with no other configuration succeeds" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello + skip "dfx replica and bootstrap are deprecated" + dfx_new hello - dfx_replica --enable-bitcoin + dfx_replica --enable-bitcoin - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" } @test "can enable bitcoin through default configuration - dfx start" { - dfx_new hello - define_project_network - set_project_default_bitcoin_enabled + dfx_new hello + define_project_network + set_project_default_bitcoin_enabled - dfx_start + dfx_start - assert_file_not_empty .dfx/network/local/ic-btc-adapter-pid + assert_file_not_empty .dfx/network/local/ic-btc-adapter-pid } @test "can enable bitcoin through shared local network - dfx start" { - dfx_new hello - set_shared_local_network_bitcoin_enabled + dfx_new hello + set_shared_local_network_bitcoin_enabled - dfx_start + dfx_start - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" } @test "can enable bitcoin through local network configuration - dfx start" { - dfx_new hello - set_local_network_bitcoin_enabled + dfx_new hello + set_local_network_bitcoin_enabled - dfx_start + dfx_start - assert_file_not_empty .dfx/network/local/ic-btc-adapter-pid + assert_file_not_empty .dfx/network/local/ic-btc-adapter-pid } @test "can enable bitcoin through default configuration - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - define_project_network - set_project_default_bitcoin_enabled + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + define_project_network + set_project_default_bitcoin_enabled - dfx_replica + dfx_replica - assert_file_not_empty .dfx/network/local/ic-btc-adapter-pid + assert_file_not_empty .dfx/network/local/ic-btc-adapter-pid } @test "can enable bitcoin through shared local network - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - set_shared_local_network_bitcoin_enabled + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + set_shared_local_network_bitcoin_enabled - dfx_replica + dfx_replica - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" } @test "dfx start with both bitcoin and canister http enabled" { - dfx_new hello + dfx_new hello - dfx_start --enable-bitcoin --enable-canister-http + dfx_start --enable-bitcoin --enable-canister-http - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' } @test "dfx replica+bootstrap with both bitcoin and canister http enabled" { - skip "dfx replica and bootstrap are deprecated" + skip "dfx replica and bootstrap are deprecated" - dfx_new hello + dfx_new hello - dfx_replica --enable-bitcoin --enable-canister-http - dfx_bootstrap + dfx_replica --enable-bitcoin --enable-canister-http + dfx_bootstrap - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-btc-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' } diff --git a/e2e/tests-dfx/bootstrap.bash b/e2e/tests-dfx/bootstrap.bash index d782394907..00310e1de8 100644 --- a/e2e/tests-dfx/bootstrap.bash +++ b/e2e/tests-dfx/bootstrap.bash @@ -3,38 +3,38 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - # stop_dfx_replica - # stop_dfx_bootstrap + # stop_dfx_replica + # stop_dfx_bootstrap - standard_teardown + standard_teardown } @test "forbid starting webserver with a forwarded port" { - skip "dfx replica and bootstrap are deprecated" + skip "dfx replica and bootstrap are deprecated" - assert_command_fail dfx bootstrap --port 4943 - assert_match "Cannot forward API calls to the same bootstrap server" + assert_command_fail dfx bootstrap --port 4943 + assert_match "Cannot forward API calls to the same bootstrap server" } @test "bootstrap supports http requests" { - skip "dfx replica and bootstrap are deprecated" + skip "dfx replica and bootstrap are deprecated" - dfx_replica - dfx_bootstrap + dfx_replica + dfx_bootstrap - dfx canister create --all - dfx build - dfx canister install hello_frontend + dfx canister create --all + dfx build + dfx canister install hello_frontend - ID=$(dfx canister id hello_frontend) - PORT=$(get_webserver_port) - assert_command curl http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID" --max-time 60 - # shellcheck disable=SC2154 - assert_eq "This is a sample asset!" "$stdout" + ID=$(dfx canister id hello_frontend) + PORT=$(get_webserver_port) + assert_command curl http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID" --max-time 60 + # shellcheck disable=SC2154 + assert_eq "This is a sample asset!" "$stdout" } diff --git a/e2e/tests-dfx/build.bash b/e2e/tests-dfx/build.bash index a3ff9bc835..898e003d0a 100644 --- a/e2e/tests-dfx/build.bash +++ b/e2e/tests-dfx/build.bash @@ -3,165 +3,165 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - stop_webserver - dfx_stop + stop_webserver + dfx_stop - standard_teardown + standard_teardown } @test "can build a custom canister with wasm and/or candid from a url" { - install_asset wasm/identity - mkdir -p www/wasm - mv main.wasm www/wasm/ - mv main.did www/wasm - start_webserver --directory www - dfx_start + install_asset wasm/identity + mkdir -p www/wasm + mv main.wasm www/wasm/ + mv main.did www/wasm + start_webserver --directory www + dfx_start - dfx_new + dfx_new - jq '.canisters={}' dfx.json | sponge dfx.json + jq '.canisters={}' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.candid="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.did"' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.wasm="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.wasm"' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.type="custom"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.candid="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.did"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.wasm="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.wasm"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.type="custom"' dfx.json | sponge dfx.json - dfx deploy + dfx deploy - ID=$(dfx canister id e2e_project) - assert_command dfx canister call e2e_project getCanisterId - assert_match "$ID" + ID=$(dfx canister id e2e_project) + assert_command dfx canister call e2e_project getCanisterId + assert_match "$ID" } @test "report an error if a canister defines both a wasm url and a build step" { - install_asset wasm/identity - mkdir -p www/wasm - mv main.wasm www/wasm/ - mv main.did www/wasm - start_webserver --directory www - dfx_start + install_asset wasm/identity + mkdir -p www/wasm + mv main.wasm www/wasm/ + mv main.did www/wasm + start_webserver --directory www + dfx_start - dfx_new + dfx_new - jq '.canisters={}' dfx.json | sponge dfx.json + jq '.canisters={}' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.candid="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.did"' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.wasm="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.wasm"' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.type="custom"' dfx.json | sponge dfx.json - jq '.canisters.e2e_project.build="echo nope"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.candid="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.did"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.wasm="http://localhost:'"$E2E_WEB_SERVER_PORT"'/wasm/main.wasm"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.type="custom"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project.build="echo nope"' dfx.json | sponge dfx.json - assert_command_fail dfx deploy - assert_contains "Canister 'e2e_project' defines its wasm field as a URL, and has a build step." + assert_command_fail dfx deploy + assert_contains "Canister 'e2e_project' defines its wasm field as a URL, and has a build step." } @test "build uses default build args" { - install_asset default_args - dfx_start - dfx canister create --all - assert_command_fail dfx build --check - assert_match "unknown option" - assert_match "compacting-gcX" + install_asset default_args + dfx_start + dfx canister create --all + assert_command_fail dfx build --check + assert_match "unknown option" + assert_match "compacting-gcX" } @test "build uses canister build args" { - install_asset canister_args - dfx_start - dfx canister create --all - assert_command_fail dfx build --check - assert_match "unknown option" - assert_match "compacting-gcY" - assert_not_match "compacting-gcX" + install_asset canister_args + dfx_start + dfx canister create --all + assert_command_fail dfx build --check + assert_match "unknown option" + assert_match "compacting-gcY" + assert_not_match "compacting-gcX" } @test "empty canister build args don't shadow default" { - install_asset empty_canister_args - dfx_start - dfx canister create --all - assert_command_fail dfx build --check - assert_match '"--error-detail" "5"' - assert_match "unknown option" - assert_match "compacting-gcX" + install_asset empty_canister_args + dfx_start + dfx canister create --all + assert_command_fail dfx build --check + assert_match '"--error-detail" "5"' + assert_match "unknown option" + assert_match "compacting-gcX" } @test "build fails on invalid motoko" { - install_asset invalid - dfx_start - dfx canister create --all - assert_command_fail dfx build - assert_match "syntax error" + install_asset invalid + dfx_start + dfx canister create --all + assert_command_fail dfx build + assert_match "syntax error" } @test "build supports relative imports" { - install_asset import - dfx_start - dfx canister create --all - assert_command dfx build - dfx canister install --all - assert_command dfx canister call e2e_project_backend greet World - assert_match "10World" + install_asset import + dfx_start + dfx canister create --all + assert_command dfx build + dfx canister install --all + assert_command dfx canister call e2e_project_backend greet World + assert_match "10World" } @test "build succeeds on default project" { - dfx_start - dfx canister create --all - assert_command dfx build + dfx_start + dfx canister create --all + assert_command dfx build } @test "build succeeds if enable optimize" { - jq '.canisters.e2e_project_backend.optimize="cycles"' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - assert_command dfx build + jq '.canisters.e2e_project_backend.optimize="cycles"' dfx.json | sponge dfx.json + dfx_start + dfx canister create --all + assert_command dfx build } @test "build custom canister default no shrink" { - install_asset custom_canister - install_asset wasm/identity + install_asset custom_canister + install_asset wasm/identity - dfx_start - dfx canister create --all - assert_command dfx build custom -vvv - assert_not_match "Shrinking WASM" + dfx_start + dfx canister create --all + assert_command dfx build custom -vvv + assert_not_match "Shrinking WASM" - jq '.canisters.custom.shrink=true' dfx.json | sponge dfx.json - assert_command dfx build custom -vvv - assert_match "Shrinking WASM" + jq '.canisters.custom.shrink=true' dfx.json | sponge dfx.json + assert_command dfx build custom -vvv + assert_match "Shrinking WASM" } @test "build custom canister default no optimize" { - install_asset custom_canister - install_asset wasm/identity + install_asset custom_canister + install_asset wasm/identity - dfx_start - dfx canister create --all - assert_command dfx build custom -vvv - assert_not_match "Optimizing" + dfx_start + dfx canister create --all + assert_command dfx build custom -vvv + assert_not_match "Optimizing" - jq '.canisters.custom.optimize="size"' dfx.json | sponge dfx.json - assert_command dfx build custom -vvv - assert_match "Optimizing WASM at level" + jq '.canisters.custom.optimize="size"' dfx.json | sponge dfx.json + assert_command dfx build custom -vvv + assert_match "Optimizing WASM at level" } @test "build succeeds if enable gzip" { - install_asset base - jq '.canisters.e2e_project_backend.gzip=true' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - assert_command dfx build - assert_file_exists .dfx/local/canisters/e2e_project_backend/e2e_project_backend.wasm.gz + install_asset base + jq '.canisters.e2e_project_backend.gzip=true' dfx.json | sponge dfx.json + dfx_start + dfx canister create --all + assert_command dfx build + assert_file_exists .dfx/local/canisters/e2e_project_backend/e2e_project_backend.wasm.gz } @test "build succeeds if specify gzip wasm" { - install_asset gzip - install_asset wasm/identity - dfx_start - dfx canister create --all - assert_command dfx build + install_asset gzip + install_asset wasm/identity + dfx_start + dfx canister create --all + assert_command dfx build } # TODO: Before Tungsten, we need to update this test for code with inter-canister calls. @@ -176,19 +176,19 @@ teardown() { } @test "build outputs warning" { - install_asset warning - dfx_start - dfx canister create --all - assert_command dfx build - assert_match "warning \[M0145\], this pattern of type" + install_asset warning + dfx_start + dfx canister create --all + assert_command dfx build + assert_match "warning \[M0145\], this pattern of type" } @test "build fails on unknown imports" { - install_asset import_error - dfx_start - dfx canister create --all - assert_command_fail dfx build - assert_match 'import error \[M0011\], canister alias "random" not defined' + install_asset import_error + dfx_start + dfx canister create --all + assert_command_fail dfx build + assert_match 'import error \[M0011\], canister alias "random" not defined' } @test "build fails if canister type is not supported" { @@ -260,10 +260,10 @@ teardown() { } @test "build succeeds with URL as network parameter" { - dfx_start - webserver_port=$(get_webserver_port) - dfx canister create --all --network "http://127.0.0.1:$webserver_port" - assert_command dfx build --network "http://127.0.0.1:$webserver_port" + dfx_start + webserver_port=$(get_webserver_port) + dfx canister create --all --network "http://127.0.0.1:$webserver_port" + assert_command dfx build --network "http://127.0.0.1:$webserver_port" } @test "build succeeds when requested network is configured" { diff --git a/e2e/tests-dfx/build_granular.bash b/e2e/tests-dfx/build_granular.bash index 930b7fa5a4..04101028c8 100644 --- a/e2e/tests-dfx/build_granular.bash +++ b/e2e/tests-dfx/build_granular.bash @@ -3,101 +3,101 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "direct dependencies are built" { - dfx_start - dfx canister create --all - #specify build for only assets_canister - dfx build e2e_project_frontend - - #validate direct dependency built and is callable - assert_command dfx canister install e2e_project_backend - assert_command dfx canister call e2e_project_backend greet World + dfx_start + dfx canister create --all + #specify build for only assets_canister + dfx build e2e_project_frontend + + #validate direct dependency built and is callable + assert_command dfx canister install e2e_project_backend + assert_command dfx canister call e2e_project_backend greet World } @test "transitive dependencies are built" { - install_asset transitive_deps_canisters - dfx_start - dfx canister create --all - #install of tertiary dependency canister will fail since its not built - assert_command_fail dfx canister install canister_a - #specify build for primary canister - dfx build canister_c - - #validate tertiary transitive dependency is built and callable - assert_command dfx canister install canister_a - assert_command dfx canister call canister_a greet World - assert_match '("Namaste, World!")' + install_asset transitive_deps_canisters + dfx_start + dfx canister create --all + #install of tertiary dependency canister will fail since its not built + assert_command_fail dfx canister install canister_a + #specify build for primary canister + dfx build canister_c + + #validate tertiary transitive dependency is built and callable + assert_command dfx canister install canister_a + assert_command dfx canister call canister_a greet World + assert_match '("Namaste, World!")' } @test "unspecified dependencies are not built" { - dfx_start - dfx canister create --all - # only build motoko canister - dfx build e2e_project_backend - # validate assets canister wasn't built and can't be installed - assert_command_fail dfx canister install e2e_project_frontend - assert_match "No such file or directory" + dfx_start + dfx canister create --all + # only build motoko canister + dfx build e2e_project_backend + # validate assets canister wasn't built and can't be installed + assert_command_fail dfx canister install e2e_project_frontend + assert_match "No such file or directory" } @test "manual build of specified canisters succeeds" { - install_asset assetscanister + install_asset assetscanister - dfx_start - dfx canister create e2e_project_backend - dfx build e2e_project_backend - assert_command dfx canister install e2e_project_backend - assert_command dfx canister call e2e_project_backend greet World + dfx_start + dfx canister create e2e_project_backend + dfx build e2e_project_backend + assert_command dfx canister install e2e_project_backend + assert_command dfx canister call e2e_project_backend greet World - assert_command_fail dfx canister install e2e_project_frontend - assert_match "Cannot find canister id. Please issue 'dfx canister create e2e_project_frontend'." - dfx canister create e2e_project_frontend - dfx build e2e_project_frontend - dfx canister install e2e_project_frontend + assert_command_fail dfx canister install e2e_project_frontend + assert_match "Cannot find canister id. Please issue 'dfx canister create e2e_project_frontend'." + dfx canister create e2e_project_frontend + dfx build e2e_project_frontend + dfx canister install e2e_project_frontend - assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl - assert_eq '(blob "\b8\01 \80\0aw12 \00xy\0aKL\0b\0ajk")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl + assert_eq '(blob "\b8\01 \80\0aw12 \00xy\0aKL\0b\0ajk")' - assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl - assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' + assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl + assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' } @test "cyclic dependencies are detected" { - install_asset transitive_deps_canisters - dfx_start - dfx canister create --all - assert_command_fail dfx build canister_e - assert_match "Circular canister dependencies: canister_e -> canister_d -> canister_e" + install_asset transitive_deps_canisters + dfx_start + dfx canister create --all + assert_command_fail dfx build canister_e + assert_match "Circular canister dependencies: canister_e -> canister_d -> canister_e" } @test "multiple non-cyclic dependency paths to the same canister are ok" { - install_asset transitive_deps_canisters - dfx_start - dfx canister create --all - assert_command dfx build canister_f + install_asset transitive_deps_canisters + dfx_start + dfx canister create --all + assert_command dfx build canister_f } @test "the all flag builds everything" { - dfx_start - dfx canister create --all - assert_command dfx build --all - assert_command dfx canister install --all + dfx_start + dfx canister create --all + assert_command dfx build --all + assert_command dfx canister install --all } @test "the all flags conflicts with canister name" { - dfx_start - dfx canister create --all - assert_command_fail dfx build e2e_project --all + dfx_start + dfx canister create --all + assert_command_fail dfx build e2e_project --all } diff --git a/e2e/tests-dfx/build_rust.bash b/e2e/tests-dfx/build_rust.bash index 0f30045528..e07a3dc101 100644 --- a/e2e/tests-dfx/build_rust.bash +++ b/e2e/tests-dfx/build_rust.bash @@ -3,15 +3,15 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "build without cargo-audit installed cannot check for vulnerabilities" { diff --git a/e2e/tests-dfx/call.bash b/e2e/tests-dfx/call.bash index d6ba70735f..0b2e54b8df 100644 --- a/e2e/tests-dfx/call.bash +++ b/e2e/tests-dfx/call.bash @@ -3,130 +3,130 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "call --candid " { - install_asset call - cat dfx.json + install_asset call + cat dfx.json - dfx_start - dfx deploy - assert_command dfx canister call hello_backend make_struct '("A", "B")' - assert_eq '(record { c = "A"; d = "B" })' + dfx_start + dfx deploy + assert_command dfx canister call hello_backend make_struct '("A", "B")' + assert_eq '(record { c = "A"; d = "B" })' - CANISTER_ID=$(dfx canister id hello_backend) - rm .dfx/local/canister_ids.json + CANISTER_ID=$(dfx canister id hello_backend) + rm .dfx/local/canister_ids.json - # if no candid file known, then no field names - assert_command dfx canister call "$CANISTER_ID" make_struct '("A", "B")' - assert_eq '(record { 99 = "A"; 100 = "B" })' + # if no candid file known, then no field names + assert_command dfx canister call "$CANISTER_ID" make_struct '("A", "B")' + assert_eq '(record { 99 = "A"; 100 = "B" })' - # if passing the candid file, field names available - assert_command dfx canister call --candid .dfx/local/canisters/hello_backend/hello_backend.did "$CANISTER_ID" make_struct '("A", "B")' - assert_eq '(record { c = "A"; d = "B" })' + # if passing the candid file, field names available + assert_command dfx canister call --candid .dfx/local/canisters/hello_backend/hello_backend.did "$CANISTER_ID" make_struct '("A", "B")' + assert_eq '(record { c = "A"; d = "B" })' } @test "call subcommand accepts canister identifier as canister name" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - assert_command dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' - assert_match '("Hello, Names are difficult!")' + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + assert_command dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' + assert_match '("Hello, Names are difficult!")' } @test "call subcommand accepts argument from a file" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - TMP_NAME_FILE="$(mktemp)" - printf '("Names can be very long")' > "$TMP_NAME_FILE" - assert_command dfx canister call --argument-file "$TMP_NAME_FILE" hello_backend greet - assert_match '("Hello, Names can be very long!")' - rm "$TMP_NAME_FILE" + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + TMP_NAME_FILE="$(mktemp)" + printf '("Names can be very long")' > "$TMP_NAME_FILE" + assert_command dfx canister call --argument-file "$TMP_NAME_FILE" hello_backend greet + assert_match '("Hello, Names can be very long!")' + rm "$TMP_NAME_FILE" } @test "call subcommand accepts argument from stdin" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - TMP_NAME_FILE="$(mktemp)" - printf '("stdin")' > "$TMP_NAME_FILE" - assert_command dfx canister call --argument-file - hello_backend greet < "$TMP_NAME_FILE" - assert_match '("Hello, stdin!")' - rm "$TMP_NAME_FILE" + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + TMP_NAME_FILE="$(mktemp)" + printf '("stdin")' > "$TMP_NAME_FILE" + assert_command dfx canister call --argument-file - hello_backend greet < "$TMP_NAME_FILE" + assert_match '("Hello, stdin!")' + rm "$TMP_NAME_FILE" } @test "call random value (pattern)" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - assert_command dfx canister call hello_backend greet --random '{ value = Some ["\"DFINITY\""] }' - assert_match '("Hello, DFINITY!")' + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + assert_command dfx canister call hello_backend greet --random '{ value = Some ["\"DFINITY\""] }' + assert_match '("Hello, DFINITY!")' } @test "error on empty arguments when the method requires some" { - install_asset greet - dfx_start - dfx deploy - assert_command_fail dfx canister call hello_backend greet + install_asset greet + dfx_start + dfx deploy + assert_command_fail dfx canister call hello_backend greet } @test "call random value (empty)" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - assert_command dfx canister call hello_backend greet --random '' - assert_match '("Hello, .*!")' + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + assert_command dfx canister call hello_backend greet --random '' + assert_match '("Hello, .*!")' } @test "long call" { - install_asset recurse - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - assert_command dfx canister call hello_backend recurse 100 + install_asset recurse + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + assert_command dfx canister call hello_backend recurse 100 } @test "call with cycles" { - dfx_start - dfx deploy - assert_command_fail dfx canister call hello_backend greet '' --with-cycles 100 - assert_command dfx canister call hello_backend greet '' --with-cycles 100 --wallet "$(dfx identity get-wallet)" + dfx_start + dfx deploy + assert_command_fail dfx canister call hello_backend greet '' --with-cycles 100 + assert_command dfx canister call hello_backend greet '' --with-cycles 100 --wallet "$(dfx identity get-wallet)" } @test "call by canister id outside of a project" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - ID="$(dfx canister id hello_backend)" - NETWORK="http://localhost:$(get_webserver_port)" - ( - cd "$E2E_TEMP_DIR" - mkdir "not-a-project-dir" - cd "not-a-project-dir" - assert_command dfx canister call "$ID" greet '("you")' --network "$NETWORK" - assert_match '("Hello, you!")' - ) + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + ID="$(dfx canister id hello_backend)" + NETWORK="http://localhost:$(get_webserver_port)" + ( + cd "$E2E_TEMP_DIR" + mkdir "not-a-project-dir" + cd "not-a-project-dir" + assert_command dfx canister call "$ID" greet '("you")' --network "$NETWORK" + assert_match '("Hello, you!")' + ) } diff --git a/e2e/tests-dfx/candid_ui.bash b/e2e/tests-dfx/candid_ui.bash index 166606dfbb..eb98beb583 100644 --- a/e2e/tests-dfx/candid_ui.bash +++ b/e2e/tests-dfx/candid_ui.bash @@ -3,22 +3,22 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "Candid UI" { - dfx_start - dfx deploy - ID=$(dfx canister id __Candid_UI) - PORT=$(get_webserver_port) - assert_command curl http://localhost:"$PORT"/?canisterId="$ID" - assert_match "Candid UI" + dfx_start + dfx deploy + ID=$(dfx canister id __Candid_UI) + PORT=$(get_webserver_port) + assert_command curl http://localhost:"$PORT"/?canisterId="$ID" + assert_match "Candid UI" } diff --git a/e2e/tests-dfx/canister_http.bash b/e2e/tests-dfx/canister_http.bash index 24e004018a..c80bf4c927 100644 --- a/e2e/tests-dfx/canister_http.bash +++ b/e2e/tests-dfx/canister_http.bash @@ -3,339 +3,339 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop - # stop_dfx_replica - # stop_dfx_bootstrap - standard_teardown + dfx_stop + # stop_dfx_replica + # stop_dfx_bootstrap + standard_teardown } set_project_default_canister_http_enabled() { - jq ".defaults.canister_http.enabled=${1:-true}" dfx.json | sponge dfx.json + jq ".defaults.canister_http.enabled=${1:-true}" dfx.json | sponge dfx.json } set_project_local_network_canister_http_enabled() { - jq ".networks.local.canister_http.enabled=${1:-true}" dfx.json | sponge dfx.json + jq ".networks.local.canister_http.enabled=${1:-true}" dfx.json | sponge dfx.json } set_shared_local_network_canister_http_enabled() { - create_networks_json + create_networks_json - jq ".local.canister_http.enabled=${1:-true}" "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + jq ".local.canister_http.enabled=${1:-true}" "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" } set_shared_local_network_canister_http_empty() { - create_networks_json + create_networks_json - jq '.local.canister_http={}' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + jq '.local.canister_http={}' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" } @test "canister http feature is enabled by default" { - dfx_start + dfx_start - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "canister http feature is enabled by default with empty json element" { - set_shared_local_network_canister_http_empty + set_shared_local_network_canister_http_empty - dfx_start + dfx_start - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "dfx restarts replica when ic-https-outcalls-adapter restarts" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' - REPLICA_PID=$(get_replica_pid) - CANISTER_HTTP_ADAPTER_PID=$(get_canister_http_adapter_pid) + REPLICA_PID=$(get_replica_pid) + CANISTER_HTTP_ADAPTER_PID=$(get_canister_http_adapter_pid) - echo "replica pid is $REPLICA_PID" - echo "ic-https-outcalls-adapter pid is $CANISTER_HTTP_ADAPTER_PID" + echo "replica pid is $REPLICA_PID" + echo "ic-https-outcalls-adapter pid is $CANISTER_HTTP_ADAPTER_PID" - kill -KILL "$CANISTER_HTTP_ADAPTER_PID" - assert_process_exits "$CANISTER_HTTP_ADAPTER_PID" 15s - assert_process_exits "$REPLICA_PID" 15s + kill -KILL "$CANISTER_HTTP_ADAPTER_PID" + assert_process_exits "$CANISTER_HTTP_ADAPTER_PID" 15s + assert_process_exits "$REPLICA_PID" 15s - timeout 15s sh -c \ - 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ - || (echo "replica did not restart" && ps aux && exit 1) - wait_until_replica_healthy + timeout 15s sh -c \ + 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ + || (echo "replica did not restart" && ps aux && exit 1) + wait_until_replica_healthy - # Sometimes initially get an error like: - # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module - # but the condition clears. - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting + # Sometimes initially get an error like: + # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module + # but the condition clears. + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting - # Even so, after that passes, sometimes this happens: - # IC0515: Certified state is not available yet. Please try again... - sleep 10 - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting + # Even so, after that passes, sometimes this happens: + # IC0515: Certified state is not available yet. Please try again... + sleep 10 + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting - assert_command dfx canister call hello_backend greet '("Omega")' - assert_eq '("Hello, Omega!")' + assert_command dfx canister call hello_backend greet '("Omega")' + assert_eq '("Hello, Omega!")' - ID=$(dfx canister id hello_frontend) + ID=$(dfx canister id hello_frontend) - timeout 15s sh -c \ - "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port\")/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ - || (echo "icx-proxy did not restart" && ps aux && exit 1) + timeout 15s sh -c \ + "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port\")/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ + || (echo "icx-proxy did not restart" && ps aux && exit 1) - assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" + assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" } @test "dfx restarts replica when ic-https-outcalls-adapter restarts - replica and bootstrap" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - dfx_replica - dfx_bootstrap - - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' - - REPLICA_PID=$(get_replica_pid) - CANISTER_HTTP_ADAPTER_PID=$(get_canister_http_adapter_pid) - - echo "replica pid is $REPLICA_PID" - echo "replica port is $(get_replica_port)" - echo "ic-https-outcalls-adapter pid is $CANISTER_HTTP_ADAPTER_PID" - - kill -KILL "$CANISTER_HTTP_ADAPTER_PID" - assert_process_exits "$CANISTER_HTTP_ADAPTER_PID" 15s - assert_process_exits "$REPLICA_PID" 15s - - timeout 15s sh -x -c \ - "until curl --fail --verbose -o /dev/null http://localhost:\$(cat '$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port')/api/v2/status; do echo \"waiting for replica to restart on port \$(cat '$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port')\"; sleep 1; done" \ - || (echo "replica did not restart" && echo "last replica port was $(get_replica_port)" && ps aux && exit 1) - - # bootstrap doesn't detect the new replica port, so we have to restart it - stop_dfx_bootstrap - dfx_bootstrap - - # Sometimes initially get an error like: - # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module - # but the condition clears. - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - - # Even so, after that passes, sometimes this happens: - # IC0515: Certified state is not available yet. Please try again... - sleep 10 - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - - assert_command dfx canister call hello_backend greet '("Omega")' - assert_eq '("Hello, Omega!")' + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + dfx_replica + dfx_bootstrap + + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' + + REPLICA_PID=$(get_replica_pid) + CANISTER_HTTP_ADAPTER_PID=$(get_canister_http_adapter_pid) + + echo "replica pid is $REPLICA_PID" + echo "replica port is $(get_replica_port)" + echo "ic-https-outcalls-adapter pid is $CANISTER_HTTP_ADAPTER_PID" + + kill -KILL "$CANISTER_HTTP_ADAPTER_PID" + assert_process_exits "$CANISTER_HTTP_ADAPTER_PID" 15s + assert_process_exits "$REPLICA_PID" 15s + + timeout 15s sh -x -c \ + "until curl --fail --verbose -o /dev/null http://localhost:\$(cat '$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port')/api/v2/status; do echo \"waiting for replica to restart on port \$(cat '$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port')\"; sleep 1; done" \ + || (echo "replica did not restart" && echo "last replica port was $(get_replica_port)" && ps aux && exit 1) + + # bootstrap doesn't detect the new replica port, so we have to restart it + stop_dfx_bootstrap + dfx_bootstrap + + # Sometimes initially get an error like: + # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module + # but the condition clears. + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 1\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + + # Even so, after that passes, sometimes this happens: + # IC0515: Certified state is not available yet. Please try again... + sleep 10 + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait 2\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + + assert_command dfx canister call hello_backend greet '("Omega")' + assert_eq '("Hello, Omega!")' } @test "dfx start --enable-canister-http with no other configuration succeeds" { - dfx_new hello + dfx_new hello - dfx_start --enable-canister-http + dfx_start --enable-canister-http - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "dfx replica --enable-canister-http with no other configuration succeeds" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello + skip "dfx replica and bootstrap are deprecated" + dfx_new hello - dfx_replica --enable-canister-http + dfx_replica --enable-canister-http - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "can enable http through project default configuration - dfx start" { - dfx_new hello - define_project_network - set_project_default_canister_http_enabled + dfx_new hello + define_project_network + set_project_default_canister_http_enabled - dfx_start + dfx_start - assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can disable http through project default configuration - dfx start" { - dfx_new hello - define_project_network - set_project_default_canister_http_enabled false + dfx_new hello + define_project_network + set_project_default_canister_http_enabled false - dfx_start + dfx_start - assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can enable http through project local network - dfx start" { - dfx_new hello - define_project_network - set_project_local_network_canister_http_enabled + dfx_new hello + define_project_network + set_project_local_network_canister_http_enabled - dfx_start + dfx_start - assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can disable http through project local network - dfx start" { - dfx_new hello - define_project_network - set_project_local_network_canister_http_enabled false + dfx_new hello + define_project_network + set_project_local_network_canister_http_enabled false - dfx_start + dfx_start - assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can enable http through shared local network - dfx start" { - dfx_new hello - set_shared_local_network_canister_http_enabled + dfx_new hello + set_shared_local_network_canister_http_enabled - dfx_start + dfx_start - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "can disable http through shared local network - dfx start" { - dfx_new hello - set_shared_local_network_canister_http_enabled false + dfx_new hello + set_shared_local_network_canister_http_enabled false - dfx_start + dfx_start - assert_file_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "can enable http through project default configuration - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - define_project_network - set_project_default_canister_http_enabled + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + define_project_network + set_project_default_canister_http_enabled - dfx_replica + dfx_replica - assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can disable http through project default configuration - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - define_project_network - set_project_default_canister_http_enabled false + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + define_project_network + set_project_default_canister_http_enabled false - dfx_replica + dfx_replica - assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can enable http through project local network - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - define_project_network - set_project_local_network_canister_http_enabled + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + define_project_network + set_project_local_network_canister_http_enabled - dfx_replica + dfx_replica - assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_not_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can disable http through project local network - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - define_project_network - set_project_local_network_canister_http_enabled false + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + define_project_network + set_project_local_network_canister_http_enabled false - dfx_replica + dfx_replica - assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid + assert_file_empty .dfx/network/local/ic-https-outcalls-adapter-pid } @test "can enable http through shared local network - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - set_shared_local_network_canister_http_enabled + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + set_shared_local_network_canister_http_enabled - dfx_replica + dfx_replica - assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_not_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "can disable http through shared local network - dfx replica" { - skip "dfx replica and bootstrap are deprecated" - dfx_new hello - set_shared_local_network_canister_http_enabled false + skip "dfx replica and bootstrap are deprecated" + dfx_new hello + set_shared_local_network_canister_http_enabled false - dfx_replica + dfx_replica - assert_file_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" + assert_file_empty "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/ic-https-outcalls-adapter-pid" } @test "dfx starts http adapter with correct log level - project defaults" { - dfx_new - jq '.defaults.canister_http.log_level="warning"' dfx.json | sponge dfx.json - define_project_network + dfx_new + jq '.defaults.canister_http.log_level="warning"' dfx.json | sponge dfx.json + define_project_network - assert_command dfx start --background --verbose - assert_match "log level: Warning" - assert_command dfx stop + assert_command dfx start --background --verbose + assert_match "log level: Warning" + assert_command dfx stop - jq '.defaults.canister_http.log_level="critical"' dfx.json | sponge dfx.json - assert_command dfx start --background --verbose - assert_match "log level: Critical" + jq '.defaults.canister_http.log_level="critical"' dfx.json | sponge dfx.json + assert_command dfx start --background --verbose + assert_match "log level: Critical" } @test "dfx starts http adapter with correct log level - local network" { - dfx_new - jq '.networks.local.canister_http.log_level="warning"' dfx.json | sponge dfx.json - define_project_network + dfx_new + jq '.networks.local.canister_http.log_level="warning"' dfx.json | sponge dfx.json + define_project_network - assert_command dfx start --background --verbose - assert_match "log level: Warning" - assert_command dfx stop + assert_command dfx start --background --verbose + assert_match "log level: Warning" + assert_command dfx stop - jq '.networks.local.canister_http.log_level="critical"' dfx.json | sponge dfx.json - assert_command dfx start --background --verbose --clean - assert_match "log level: Critical" + jq '.networks.local.canister_http.log_level="critical"' dfx.json | sponge dfx.json + assert_command dfx start --background --verbose --clean + assert_match "log level: Critical" } @test "dfx starts http adapter with correct log level - shared network" { - dfx_new - create_networks_json - jq '.local.canister_http.log_level="warning"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + dfx_new + create_networks_json + jq '.local.canister_http.log_level="warning"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background --verbose - assert_match "log level: Warning" - assert_command dfx stop + assert_command dfx start --background --verbose + assert_match "log level: Warning" + assert_command dfx stop - jq '.local.canister_http.log_level="critical"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background --verbose - assert_match "log level: Critical" + jq '.local.canister_http.log_level="critical"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + assert_command dfx start --background --verbose + assert_match "log level: Critical" } @test "can query a website" { - dfx_start + dfx_start - dfx_new - install_asset canister_http + dfx_new + install_asset canister_http - dfx deploy + dfx deploy - assert_command dfx canister call e2e_project_backend get_url '("www.githubstatus.com:443","https://www.githubstatus.com:443")' - assert_contains "Git Operations" - assert_contains "API Requests" + assert_command dfx canister call e2e_project_backend get_url '("www.githubstatus.com:443","https://www.githubstatus.com:443")' + assert_contains "Git Operations" + assert_contains "API Requests" } diff --git a/e2e/tests-dfx/certificate.bash b/e2e/tests-dfx/certificate.bash index 3c6ba232d5..1fe5d66269 100644 --- a/e2e/tests-dfx/certificate.bash +++ b/e2e/tests-dfx/certificate.bash @@ -3,76 +3,76 @@ load ../utils/_ setup() { - standard_setup - - dfx_new certificate - - install_asset certificate - dfx_start - - dfx deploy - - BACKEND="127.0.0.1:$(get_webserver_port)" - - # In github workflows, at the time of this writing, we get: - # macos-latest: mitmproxy 7.0.4 - # ubuntu-latest: mitmproxy 4.x - if [ "$(mitmdump --version | grep Mitmproxy | cut -d ' ' -f 2 | cut -c 1-2)" = "4." ]; then - MODIFY_BODY_ARG="--replacements" - else - MODIFY_BODY_ARG="--modify-body" + standard_setup + + dfx_new certificate + + install_asset certificate + dfx_start + + dfx deploy + + BACKEND="127.0.0.1:$(get_webserver_port)" + + # In github workflows, at the time of this writing, we get: + # macos-latest: mitmproxy 7.0.4 + # ubuntu-latest: mitmproxy 4.x + if [ "$(mitmdump --version | grep Mitmproxy | cut -d ' ' -f 2 | cut -c 1-2)" = "4." ]; then + MODIFY_BODY_ARG="--replacements" + else + MODIFY_BODY_ARG="--modify-body" + fi + + # Sometimes, something goes wrong with mitmdump's initialization. + # It reports that it is listening, and the `nc` call succeeds, + # but it does not actually respond to requests. + # + # This happens whether using a fixed port or a dynamic port. + # For this reason, we retry initialization until `dfx ping` succeeds. + # + # I have seen this process take as many as 9 iterations to succeed, + # so across a large number of CI runs, it could take even more. + # The overall CI timeout will limit the maximum time taken. + + while true + do + MITM_PORT=$(get_ephemeral_port) + overwrite_webserver_port "$MITM_PORT" + + mitmdump -p "$MITM_PORT" --mode "reverse:http://$BACKEND" "$MODIFY_BODY_ARG" '/~s/Hello,/Hullo,' & + MITMDUMP_PID=$! + + timeout 5 sh -c \ + "until nc -z localhost $MITM_PORT; do echo waiting for mitmdump; sleep 1; done" \ + || (echo "mitmdump did not start on port $MITM_PORT" && exit 1) + + if timeout 10 dfx ping; then + break fi - # Sometimes, something goes wrong with mitmdump's initialization. - # It reports that it is listening, and the `nc` call succeeds, - # but it does not actually respond to requests. - # - # This happens whether using a fixed port or a dynamic port. - # For this reason, we retry initialization until `dfx ping` succeeds. - # - # I have seen this process take as many as 9 iterations to succeed, - # so across a large number of CI runs, it could take even more. - # The overall CI timeout will limit the maximum time taken. - - while true - do - MITM_PORT=$(get_ephemeral_port) - overwrite_webserver_port "$MITM_PORT" - - mitmdump -p "$MITM_PORT" --mode "reverse:http://$BACKEND" "$MODIFY_BODY_ARG" '/~s/Hello,/Hullo,' & - MITMDUMP_PID=$! - - timeout 5 sh -c \ - "until nc -z localhost $MITM_PORT; do echo waiting for mitmdump; sleep 1; done" \ - || (echo "mitmdump did not start on port $MITM_PORT" && exit 1) - - if timeout 10 dfx ping; then - break - fi - - kill -9 $MITMDUMP_PID - done + kill -9 $MITMDUMP_PID + done } teardown() { - # Kill child processes of mitmdump. Otherwise they hang around way too long - pkill -P $MITMDUMP_PID - kill $MITMDUMP_PID + # Kill child processes of mitmdump. Otherwise they hang around way too long + pkill -P $MITMDUMP_PID + kill $MITMDUMP_PID - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "mitm attack - update: attack fails because certificate verification fails" { - assert_command_fail dfx canister call certificate_backend hello_update '("Buckaroo")' - assert_match 'Certificate verification failed.' + assert_command_fail dfx canister call certificate_backend hello_update '("Buckaroo")' + assert_match 'Certificate verification failed.' } @test "mitm attack - query: attack succeeds because there is no certificate to verify" { - # The wallet does not have a query call forward method (currently calls forward from wallet's update method) - # So call with users Identity as sender here - # There may need to be a query version of wallet_call - assert_command dfx canister call certificate_backend hello_query '("Buckaroo")' - assert_eq '("Hullo, Buckaroo!")' + # The wallet does not have a query call forward method (currently calls forward from wallet's update method) + # So call with users Identity as sender here + # There may need to be a query version of wallet_call + assert_command dfx canister call certificate_backend hello_query '("Buckaroo")' + assert_eq '("Hullo, Buckaroo!")' } diff --git a/e2e/tests-dfx/certified_info.bash b/e2e/tests-dfx/certified_info.bash index 718dd20794..0765760081 100644 --- a/e2e/tests-dfx/certified_info.bash +++ b/e2e/tests-dfx/certified_info.bash @@ -3,37 +3,37 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "get certified-info" { - dfx_start - dfx canister create hello_backend - assert_command dfx canister info "$(dfx canister id hello_backend)" - WALLET_ID=$(dfx identity get-wallet) - SELF_ID=$(dfx identity get-principal) - assert_match \ + dfx_start + dfx canister create hello_backend + assert_command dfx canister info "$(dfx canister id hello_backend)" + WALLET_ID=$(dfx identity get-wallet) + SELF_ID=$(dfx identity get-principal) + assert_match \ "Controllers: ($WALLET_ID $SELF_ID|$SELF_ID $WALLET_ID) Module hash: None" - dfx build hello_backend - RESULT="$(openssl dgst -sha256 .dfx/local/canisters/hello_backend/hello_backend.wasm)" - # shellcheck disable=SC2034 - HASH="0x" - HASH+=$(echo "${RESULT}" | cut -d' ' -f 2) + dfx build hello_backend + RESULT="$(openssl dgst -sha256 .dfx/local/canisters/hello_backend/hello_backend.wasm)" + # shellcheck disable=SC2034 + HASH="0x" + HASH+=$(echo "${RESULT}" | cut -d' ' -f 2) - dfx canister install hello_backend - assert_command dfx canister info "$(dfx canister id hello_backend)" - assert_match \ + dfx canister install hello_backend + assert_command dfx canister info "$(dfx canister id hello_backend)" + assert_match \ "Controllers: ($WALLET_ID $SELF_ID|$SELF_ID $WALLET_ID) Module hash: $(HASH)" } diff --git a/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index 28c82adaa7..a7f04b3ed4 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -3,259 +3,259 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "create succeeds on default project" { - dfx_start - assert_command dfx canister create --all + dfx_start + assert_command dfx canister create --all } @test "create succeeds with --specified-id" { - dfx_start - assert_command dfx canister create e2e_project_backend --specified-id n5n4y-3aaaa-aaaaa-p777q-cai - assert_command dfx canister id e2e_project_backend - assert_match n5n4y-3aaaa-aaaaa-p777q-cai + dfx_start + assert_command dfx canister create e2e_project_backend --specified-id n5n4y-3aaaa-aaaaa-p777q-cai + assert_command dfx canister id e2e_project_backend + assert_match n5n4y-3aaaa-aaaaa-p777q-cai } @test "create succeeds when specify large canister ID" { - dfx_start - # hhn2s-5l777-77777-7777q-cai is the canister ID of (u64::MAX / 2) - assert_command dfx canister create e2e_project_backend --specified-id hhn2s-5l777-77777-7777q-cai - assert_command dfx canister id e2e_project_backend - assert_match hhn2s-5l777-77777-7777q-cai + dfx_start + # hhn2s-5l777-77777-7777q-cai is the canister ID of (u64::MAX / 2) + assert_command dfx canister create e2e_project_backend --specified-id hhn2s-5l777-77777-7777q-cai + assert_command dfx canister id e2e_project_backend + assert_match hhn2s-5l777-77777-7777q-cai } @test "create fails when specify out of range canister ID" { - dfx_start - # nojwb-ieaaa-aaaaa-aaaaa-cai is the canister ID of (u64::MAX / 2 + 1) - assert_command_fail dfx canister create e2e_project_backend --specified-id nojwb-ieaaa-aaaaa-aaaaa-cai + dfx_start + # nojwb-ieaaa-aaaaa-aaaaa-cai is the canister ID of (u64::MAX / 2 + 1) + assert_command_fail dfx canister create e2e_project_backend --specified-id nojwb-ieaaa-aaaaa-aaaaa-cai - assert_match "Specified CanisterId nojwb-ieaaa-aaaaa-aaaaa-cai is not hosted by subnet" + assert_match "Specified CanisterId nojwb-ieaaa-aaaaa-aaaaa-cai is not hosted by subnet" } @test "create fails if set both --all and --specified-id" { - dfx_start - assert_command_fail dfx canister create --all --specified-id xbgkv-fyaaa-aaaaa-aaava-cai - assert_match "error: the argument '--all' cannot be used with '--specified-id '" + dfx_start + assert_command_fail dfx canister create --all --specified-id xbgkv-fyaaa-aaaaa-aaava-cai + assert_match "error: the argument '--all' cannot be used with '--specified-id '" } @test "create generates the canister_ids.json" { - dfx_start - assert_command dfx canister create --all - [[ -f .dfx/local/canister_ids.json ]] + dfx_start + assert_command dfx canister create --all + [[ -f .dfx/local/canister_ids.json ]] } @test "create without parameters sets wallet and self as controller" { - dfx_start - PRINCIPAL=$(dfx identity get-principal) - WALLET=$(dfx identity get-wallet) - assert_command dfx canister create --all - assert_command dfx canister info e2e_project_backend - assert_match "Controllers: ($PRINCIPAL $WALLET|$WALLET $PRINCIPAL)" + dfx_start + PRINCIPAL=$(dfx identity get-principal) + WALLET=$(dfx identity get-wallet) + assert_command dfx canister create --all + assert_command dfx canister info e2e_project_backend + assert_match "Controllers: ($PRINCIPAL $WALLET|$WALLET $PRINCIPAL)" } @test "create with --no-wallet sets only self as controller" { - dfx_start - PRINCIPAL=$(dfx identity get-principal) - WALLET=$(dfx identity get-wallet) - assert_command dfx canister create --all --no-wallet - assert_command dfx canister info e2e_project_backend - assert_not_match "Controllers: ($PRINCIPAL $WALLET|$WALLET $PRINCIPAL)" - assert_match "Controllers: $PRINCIPAL" + dfx_start + PRINCIPAL=$(dfx identity get-principal) + WALLET=$(dfx identity get-wallet) + assert_command dfx canister create --all --no-wallet + assert_command dfx canister info e2e_project_backend + assert_not_match "Controllers: ($PRINCIPAL $WALLET|$WALLET $PRINCIPAL)" + assert_match "Controllers: $PRINCIPAL" } @test "build fails without create" { - dfx_start - assert_command_fail dfx build - assert_match "Cannot find canister id." + dfx_start + assert_command_fail dfx build + assert_match "Cannot find canister id." } @test "build fails if all canisters in project are not created" { - dfx_start - assert_command dfx canister create e2e_project_backend - assert_command_fail dfx build - assert_match "Cannot find canister id. Please issue 'dfx canister create e2e_project_frontend'" + dfx_start + assert_command dfx canister create e2e_project_backend + assert_command_fail dfx build + assert_match "Cannot find canister id. Please issue 'dfx canister create e2e_project_frontend'" } @test "create succeeds with network parameter" { - dfx_start - assert_command dfx canister create --all --network local + dfx_start + assert_command dfx canister create --all --network local } @test "create fails with incorrect network" { - dfx_start - assert_command_fail dfx canister create --all --network nosuch - assert_match "Network not found" + dfx_start + assert_command_fail dfx canister create --all --network nosuch + assert_match "Network not found" } @test "create succeeds when requested network is configured" { - dfx_start + dfx_start - setup_actuallylocal_shared_network - assert_command dfx canister create --all --network actuallylocal + setup_actuallylocal_shared_network + assert_command dfx canister create --all --network actuallylocal } @test "create with wallet succeeds when requested network is configured" { - dfx_start - setup_actuallylocal_shared_network + dfx_start + setup_actuallylocal_shared_network - assert_command dfx_set_wallet - assert_command dfx canister create --all --network actuallylocal + assert_command dfx_set_wallet + assert_command dfx canister create --all --network actuallylocal } @test "create fails if selected network exists but has no providers" { - dfx_start + dfx_start - jq '.networks.actuallylocal.providers=[]' dfx.json | sponge dfx.json - assert_command_fail dfx canister create --all --network actuallylocal - assert_match "Did not find any providers for network 'actuallylocal'" + jq '.networks.actuallylocal.providers=[]' dfx.json | sponge dfx.json + assert_command_fail dfx canister create --all --network actuallylocal + assert_match "Did not find any providers for network 'actuallylocal'" } @test "create fails with network parameter when network does not exist" { - dfx_start - jq '.networks.actuallylocal.providers=["http://not-real.nowhere.test."]' dfx.json | sponge dfx.json - assert_command_fail dfx canister create --all --network actuallylocal - assert_match "dns error: failed to lookup address information" + dfx_start + jq '.networks.actuallylocal.providers=["http://not-real.nowhere.test."]' dfx.json | sponge dfx.json + assert_command_fail dfx canister create --all --network actuallylocal + assert_match "dns error: failed to lookup address information" } @test "create accepts --controller named parameter, with controller by identity name" { - dfx_start - dfx identity new --storage-mode plaintext alice - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - - - assert_command dfx canister create --all --controller alice - assert_command dfx canister info e2e_project_backend - assert_match "Controllers: $ALICE_PRINCIPAL" - - assert_command_fail dfx deploy - assert_command dfx deploy --identity alice + dfx_start + dfx identity new --storage-mode plaintext alice + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + + + assert_command dfx canister create --all --controller alice + assert_command dfx canister info e2e_project_backend + assert_match "Controllers: $ALICE_PRINCIPAL" + + assert_command_fail dfx deploy + assert_command dfx deploy --identity alice } @test "create accepts --controller named parameter, with controller by identity principal" { - dfx_start - dfx identity new --storage-mode plaintext alice - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - - assert_command dfx canister create --all --controller "${ALICE_PRINCIPAL}" - assert_command dfx canister info e2e_project_backend - assert_not_match "Controllers: ($ALICE_WALLET $ALICE_PRINCIPAL|$ALICE_PRINCIPAL $ALICE_WALLET)" - assert_match "Controllers: $ALICE_PRINCIPAL" - - assert_command_fail dfx deploy - assert_command dfx deploy --identity alice + dfx_start + dfx identity new --storage-mode plaintext alice + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + + assert_command dfx canister create --all --controller "${ALICE_PRINCIPAL}" + assert_command dfx canister info e2e_project_backend + assert_not_match "Controllers: ($ALICE_WALLET $ALICE_PRINCIPAL|$ALICE_PRINCIPAL $ALICE_WALLET)" + assert_match "Controllers: $ALICE_PRINCIPAL" + + assert_command_fail dfx deploy + assert_command dfx deploy --identity alice } @test "create accepts --controller named parameter, with controller by wallet principal" { - dfx_start - dfx identity new --storage-mode plaintext alice - ALICE_WALLET=$(dfx identity get-wallet --identity alice) + dfx_start + dfx identity new --storage-mode plaintext alice + ALICE_WALLET=$(dfx identity get-wallet --identity alice) - assert_command dfx canister create --all --controller "${ALICE_WALLET}" - assert_command dfx canister info e2e_project_backend - assert_match "Controllers: $ALICE_WALLET" + assert_command dfx canister create --all --controller "${ALICE_WALLET}" + assert_command dfx canister info e2e_project_backend + assert_match "Controllers: $ALICE_WALLET" - assert_command_fail dfx deploy - assert_command_fail dfx deploy --identity alice - assert_command dfx deploy --identity alice --wallet "${ALICE_WALLET}" + assert_command_fail dfx deploy + assert_command_fail dfx deploy --identity alice + assert_command dfx deploy --identity alice --wallet "${ALICE_WALLET}" } @test "create accepts --controller named parameter, with controller by name of selected identity" { - # there is a different code path if the specified controller happens to be - # the currently selected identity. - dfx_start - dfx identity new --storage-mode plaintext alice - dfx identity new --storage-mode plaintext bob - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + # there is a different code path if the specified controller happens to be + # the currently selected identity. + dfx_start + dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext bob + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - dfx identity use bob + dfx identity use bob - assert_command dfx canister create --all --controller bob + assert_command dfx canister create --all --controller bob - dfx identity use alice - assert_command dfx canister info e2e_project_backend - assert_match "Controllers: $BOB_PRINCIPAL" + dfx identity use alice + assert_command dfx canister info e2e_project_backend + assert_match "Controllers: $BOB_PRINCIPAL" - assert_command_fail dfx deploy - assert_command dfx deploy --identity bob + assert_command_fail dfx deploy + assert_command dfx deploy --identity bob } @test "create single controller accepts --controller named parameter, with controller by identity name" { - dfx_start - dfx identity new --storage-mode plaintext alice - dfx identity new --storage-mode plaintext bob - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + dfx_start + dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext bob + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - assert_command dfx canister create --controller alice e2e_project_backend - assert_command dfx canister create --controller bob e2e_project_frontend + assert_command dfx canister create --controller alice e2e_project_backend + assert_command dfx canister create --controller bob e2e_project_frontend - assert_command dfx canister info e2e_project_backend - assert_match "Controllers: $ALICE_PRINCIPAL" + assert_command dfx canister info e2e_project_backend + assert_match "Controllers: $ALICE_PRINCIPAL" - assert_command dfx canister info e2e_project_frontend - assert_match "Controllers: $BOB_PRINCIPAL" + assert_command dfx canister info e2e_project_frontend + assert_match "Controllers: $BOB_PRINCIPAL" - # check this first, because alice will deploy e2e_project in the next step - assert_command_fail dfx deploy e2e_project_backend --identity bob - # this actually deploys e2e_project before failing, because it is a dependency - assert_command_fail dfx deploy e2e_project_frontend --identity alice + # check this first, because alice will deploy e2e_project in the next step + assert_command_fail dfx deploy e2e_project_backend --identity bob + # this actually deploys e2e_project before failing, because it is a dependency + assert_command_fail dfx deploy e2e_project_frontend --identity alice - assert_command dfx deploy e2e_project_backend --identity alice - assert_command dfx deploy e2e_project_frontend --identity bob + assert_command dfx deploy e2e_project_backend --identity alice + assert_command dfx deploy e2e_project_frontend --identity bob } @test "create canister with multiple controllers" { - dfx_start - dfx identity new --storage-mode plaintext alice - dfx identity new --storage-mode plaintext bob - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - # awk step is to avoid trailing space - PRINCIPALS_SORTED=$(echo "$ALICE_PRINCIPAL" "$BOB_PRINCIPAL" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) - - assert_command dfx canister create --all --controller alice --controller bob --identity alice - assert_command dfx canister info e2e_project_backend - assert_match "Controllers: ${PRINCIPALS_SORTED}" - - assert_command dfx deploy --identity alice - assert_command_fail dfx deploy --identity bob - - # The certified assets canister will have added alice as an authorized user, because she was the caller - # at initialization time. Bob has to be added separately. BUT, the canister has to be deployed first - # in order to call the authorize method. - assert_command dfx canister call e2e_project_frontend authorize "(principal \"$BOB_PRINCIPAL\")" --identity alice - - assert_command dfx deploy --identity bob + dfx_start + dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext bob + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + # awk step is to avoid trailing space + PRINCIPALS_SORTED=$(echo "$ALICE_PRINCIPAL" "$BOB_PRINCIPAL" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) + + assert_command dfx canister create --all --controller alice --controller bob --identity alice + assert_command dfx canister info e2e_project_backend + assert_match "Controllers: ${PRINCIPALS_SORTED}" + + assert_command dfx deploy --identity alice + assert_command_fail dfx deploy --identity bob + + # The certified assets canister will have added alice as an authorized user, because she was the caller + # at initialization time. Bob has to be added separately. BUT, the canister has to be deployed first + # in order to call the authorize method. + assert_command dfx canister call e2e_project_frontend authorize "(principal \"$BOB_PRINCIPAL\")" --identity alice + + assert_command dfx deploy --identity bob } @test "reports wallet must be upgraded if attempting to create a canister with multiple controllers through an old wallet" { - use_wallet_wasm 0.7.2 + use_wallet_wasm 0.7.2 - dfx_start - dfx identity new --storage-mode plaintext alice - dfx identity new --storage-mode plaintext bob + dfx_start + dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext bob - assert_command_fail dfx canister create --all --controller alice --controller bob --identity alice - assert_match "The wallet canister must be upgraded: The installed wallet does not support multiple controllers." - assert_match "To upgrade, run dfx wallet upgrade" + assert_command_fail dfx canister create --all --controller alice --controller bob --identity alice + assert_match "The wallet canister must be upgraded: The installed wallet does not support multiple controllers." + assert_match "To upgrade, run dfx wallet upgrade" - use_wallet_wasm 0.8.2 - assert_command dfx wallet upgrade --identity alice - assert_command dfx canister create --all --controller alice --controller bob --identity alice + use_wallet_wasm 0.8.2 + assert_command dfx wallet upgrade --identity alice + assert_command dfx canister create --all --controller alice --controller bob --identity alice } @test "canister-create on mainnet without wallet does not propagate the 404" { - assert_command_fail dfx deploy --network ic --no-wallet - assert_match 'dfx ledger create-canister' + assert_command_fail dfx deploy --network ic --no-wallet + assert_match 'dfx ledger create-canister' } diff --git a/e2e/tests-dfx/delete.bash b/e2e/tests-dfx/delete.bash index c11792fa3c..d87e08bcfd 100755 --- a/e2e/tests-dfx/delete.bash +++ b/e2e/tests-dfx/delete.bash @@ -3,38 +3,38 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop - - standard_teardown + dfx_stop + + standard_teardown } @test "delete can be used to delete a canister" { - dfx_start - dfx deploy e2e_project_backend - id=$(dfx canister id e2e_project_backend) - dfx canister stop e2e_project_backend - assert_command dfx canister delete e2e_project_backend - assert_command_fail dfx canister info e2e_project_backend - assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." - assert_command_fail dfx canister status "$id" - assert_contains "Canister $id not found" + dfx_start + dfx deploy e2e_project_backend + id=$(dfx canister id e2e_project_backend) + dfx canister stop e2e_project_backend + assert_command dfx canister delete e2e_project_backend + assert_command_fail dfx canister info e2e_project_backend + assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." + assert_command_fail dfx canister status "$id" + assert_contains "Canister $id not found" } @test "delete requires confirmation if the canister is not stopped" { - dfx_start - dfx deploy e2e_project_backend - id=$(dfx canister id e2e_project_backend) - assert_command_fail timeout -s9 20s dfx canister delete e2e_project_backend - assert_command dfx canister info e2e_project_backend - assert_command dfx canister delete e2e_project_backend -y - assert_command_fail dfx canister info e2e_project_backend - assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." - assert_command_fail dfx canister status "$id" - assert_contains "Canister $id not found" + dfx_start + dfx deploy e2e_project_backend + id=$(dfx canister id e2e_project_backend) + assert_command_fail timeout -s9 20s dfx canister delete e2e_project_backend + assert_command dfx canister info e2e_project_backend + assert_command dfx canister delete e2e_project_backend -y + assert_command_fail dfx canister info e2e_project_backend + assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." + assert_command_fail dfx canister status "$id" + assert_contains "Canister $id not found" } diff --git a/e2e/tests-dfx/deploy.bash b/e2e/tests-dfx/deploy.bash index b8ac6692f1..88aa5f05fe 100644 --- a/e2e/tests-dfx/deploy.bash +++ b/e2e/tests-dfx/deploy.bash @@ -3,144 +3,144 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "deploy --upgrade-unchanged upgrades even if the .wasm did not change" { - dfx_start - assert_command dfx deploy + dfx_start + assert_command dfx deploy - assert_command dfx deploy - assert_match "Module hash.*is already installed" + assert_command dfx deploy + assert_match "Module hash.*is already installed" - assert_command dfx deploy --upgrade-unchanged - assert_not_match "Module hash.*is already installed" + assert_command dfx deploy --upgrade-unchanged + assert_not_match "Module hash.*is already installed" } @test "deploy without arguments sets wallet and self as the controllers" { - dfx_start - WALLET=$(dfx identity get-wallet) - PRINCIPAL=$(dfx identity get-principal) - assert_command dfx deploy hello_backend - assert_command dfx canister info hello_backend - assert_match "Controllers: ($WALLET $PRINCIPAL|$PRINCIPAL $WALLET)" + dfx_start + WALLET=$(dfx identity get-wallet) + PRINCIPAL=$(dfx identity get-principal) + assert_command dfx deploy hello_backend + assert_command dfx canister info hello_backend + assert_match "Controllers: ($WALLET $PRINCIPAL|$PRINCIPAL $WALLET)" } @test "deploy --no-wallet sets only self as the controller" { - dfx_start - WALLET=$(dfx identity get-wallet) - PRINCIPAL=$(dfx identity get-principal) - assert_command dfx deploy hello_backend --no-wallet - assert_command dfx canister info hello_backend - assert_not_match "Controllers: ($WALLET $PRINCIPAL|$PRINCIPAL $WALLET)" - assert_match "Controllers: $PRINCIPAL" + dfx_start + WALLET=$(dfx identity get-wallet) + PRINCIPAL=$(dfx identity get-principal) + assert_command dfx deploy hello_backend --no-wallet + assert_command dfx canister info hello_backend + assert_not_match "Controllers: ($WALLET $PRINCIPAL|$PRINCIPAL $WALLET)" + assert_match "Controllers: $PRINCIPAL" } @test "deploy from a subdirectory" { - dfx_new hello - dfx_start - install_asset greet + dfx_new hello + dfx_start + install_asset greet - ( - cd src - assert_command dfx deploy - assert_match "Installing code for" - ) + ( + cd src + assert_command dfx deploy + assert_match "Installing code for" + ) - assert_command dfx canister call hello_backend greet '("Banzai")' - assert_eq '("Hello, Banzai!")' + assert_command dfx canister call hello_backend greet '("Banzai")' + assert_eq '("Hello, Banzai!")' - assert_command dfx deploy - assert_not_match "Installing code for" - assert_match "is already installed" + assert_command dfx deploy + assert_not_match "Installing code for" + assert_match "is already installed" } @test "deploying a dependent doesn't require already-installed dependencies to take args" { - install_asset deploy_deps - dfx_start - assert_command dfx deploy dependency --argument '("dfx")' - touch dependency.mo - assert_command dfx deploy dependent - assert_command dfx canister call dependency greet - assert_match "Hello, dfx!" + install_asset deploy_deps + dfx_start + assert_command dfx deploy dependency --argument '("dfx")' + touch dependency.mo + assert_command dfx deploy dependent + assert_command dfx canister call dependency greet + assert_match "Hello, dfx!" } @test "reinstalling a single Motoko canister with imported dependency works" { - install_asset import_canister - dfx_start - assert_command dfx deploy - assert_command dfx deploy importer --mode reinstall --yes + install_asset import_canister + dfx_start + assert_command dfx deploy + assert_command dfx deploy importer --mode reinstall --yes } @test "deploy succeeds with --specified-id" { - dfx_start - assert_command dfx deploy hello_backend --specified-id n5n4y-3aaaa-aaaaa-p777q-cai - assert_command dfx canister id hello_backend - assert_match n5n4y-3aaaa-aaaaa-p777q-cai + dfx_start + assert_command dfx deploy hello_backend --specified-id n5n4y-3aaaa-aaaaa-p777q-cai + assert_command dfx canister id hello_backend + assert_match n5n4y-3aaaa-aaaaa-p777q-cai } @test "deploy fails if --specified-id without canister_name" { - dfx_start - assert_command_fail dfx deploy --specified-id n5n4y-3aaaa-aaaaa-p777q-cai - assert_match \ + dfx_start + assert_command_fail dfx deploy --specified-id n5n4y-3aaaa-aaaaa-p777q-cai + assert_match \ "error: the following required arguments were not provided: " } @test "deploy does not require wallet if all canisters are created" { - dfx_start - dfx canister create --all --no-wallet - assert_command dfx deploy - assert_not_contains "Creating a wallet canister" - assert_command dfx identity get-wallet - assert_contains "Creating a wallet canister" + dfx_start + dfx canister create --all --no-wallet + assert_command dfx deploy + assert_not_contains "Creating a wallet canister" + assert_command dfx identity get-wallet + assert_contains "Creating a wallet canister" } @test "deploying multiple canisters with arguments fails" { - assert_command_fail dfx deploy --argument hello - assert_contains \ + assert_command_fail dfx deploy --argument hello + assert_contains \ "error: the following required arguments were not provided: " } @test "can deploy gzip wasm" { - jq '.canisters.hello_backend.gzip=true' dfx.json | sponge dfx.json - dfx_start - assert_command dfx deploy - BUILD_HASH="0x$(sha256sum .dfx/local/canisters/hello_backend/hello_backend.wasm.gz | cut -d " " -f 1)" - ONCHAIN_HASH="$(dfx canister info hello_backend | tail -n 1 | cut -d " " -f 3)" - assert_eq "$BUILD_HASH" "$ONCHAIN_HASH" + jq '.canisters.hello_backend.gzip=true' dfx.json | sponge dfx.json + dfx_start + assert_command dfx deploy + BUILD_HASH="0x$(sha256sum .dfx/local/canisters/hello_backend/hello_backend.wasm.gz | cut -d " " -f 1)" + ONCHAIN_HASH="$(dfx canister info hello_backend | tail -n 1 | cut -d " " -f 3)" + assert_eq "$BUILD_HASH" "$ONCHAIN_HASH" } @test "prints the frontend url after deploy" { - dfx_new_frontend hello - dfx_start - assert_command dfx deploy - assert_contains "hello_frontend: http://127.0.0.1" + dfx_new_frontend hello + dfx_start + assert_command dfx deploy + assert_contains "hello_frontend: http://127.0.0.1" } @test "prints the frontend url if 'frontend' section is not present in dfx.json" { - dfx_new_frontend hello - jq 'del(.canisters.hello_frontend.frontend)' dfx.json | sponge dfx.json - dfx_start - assert_command dfx deploy - assert_contains "hello_frontend: http://127.0.0.1" + dfx_new_frontend hello + jq 'del(.canisters.hello_frontend.frontend)' dfx.json | sponge dfx.json + dfx_start + assert_command dfx deploy + assert_contains "hello_frontend: http://127.0.0.1" } @test "prints the frontend url if the frontend section has been removed after initial deployment" { - dfx_new_frontend hello - dfx_start - assert_command dfx deploy - assert_contains "hello_frontend: http://127.0.0.1" - jq 'del(.canisters.hello_frontend.frontend)' dfx.json | sponge dfx.json - assert_command dfx deploy - assert_contains "hello_frontend: http://127.0.0.1" + dfx_new_frontend hello + dfx_start + assert_command dfx deploy + assert_contains "hello_frontend: http://127.0.0.1" + jq 'del(.canisters.hello_frontend.frontend)' dfx.json | sponge dfx.json + assert_command dfx deploy + assert_contains "hello_frontend: http://127.0.0.1" } diff --git a/e2e/tests-dfx/deps.bash b/e2e/tests-dfx/deps.bash index e85ca10a9b..540aa1329a 100644 --- a/e2e/tests-dfx/deps.bash +++ b/e2e/tests-dfx/deps.bash @@ -3,13 +3,13 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - stop_webserver - dfx_stop - standard_teardown + stop_webserver + dfx_stop + standard_teardown } CANISTER_ID_A="yofga-2qaaa-aaaaa-aabsq-cai" @@ -17,441 +17,441 @@ CANISTER_ID_B="yhgn4-myaaa-aaaaa-aabta-cai" CANISTER_ID_C="yahli-baaaa-aaaaa-aabtq-cai" setup_onchain() { - install_asset deps + install_asset deps - # start a webserver to host wasm files - mkdir www - start_webserver --directory www + # start a webserver to host wasm files + mkdir www + start_webserver --directory www - cd onchain || exit + cd onchain || exit - jq '.canisters.a.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/a.wasm"'"' dfx.json | sponge dfx.json - jq '.canisters.b.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/b.wasm.gz"'"' dfx.json | sponge dfx.json - jq '.canisters.c.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/c.wasm"'"' dfx.json | sponge dfx.json + jq '.canisters.a.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/a.wasm"'"' dfx.json | sponge dfx.json + jq '.canisters.b.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/b.wasm.gz"'"' dfx.json | sponge dfx.json + jq '.canisters.c.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/c.wasm"'"' dfx.json | sponge dfx.json - dfx canister create a --specified-id "$CANISTER_ID_A" - dfx canister create b --specified-id "$CANISTER_ID_B" - dfx canister create c --specified-id "$CANISTER_ID_C" - dfx build + dfx canister create a --specified-id "$CANISTER_ID_A" + dfx canister create b --specified-id "$CANISTER_ID_B" + dfx canister create c --specified-id "$CANISTER_ID_C" + dfx build - dfx canister install a --argument 1 - dfx canister install b - dfx canister install c --argument 3 + dfx canister install a --argument 1 + dfx canister install b + dfx canister install c --argument 3 - # copy wasm files to web server dir - cp .dfx/local/canisters/a/a.wasm ../www/a.wasm - cp .dfx/local/canisters/b/b.wasm.gz ../www/b.wasm.gz - cp .dfx/local/canisters/c/c.wasm ../www/c.wasm + # copy wasm files to web server dir + cp .dfx/local/canisters/a/a.wasm ../www/a.wasm + cp .dfx/local/canisters/b/b.wasm.gz ../www/b.wasm.gz + cp .dfx/local/canisters/c/c.wasm ../www/c.wasm - cd .. || exit + cd .. || exit } @test "dfx build can write required metadata for pullable" { - dfx_start - - install_asset deps - - cd onchain - assert_command dfx canister create --all - assert_command dfx build - assert_command ic-wasm .dfx/local/canisters/c/c.wasm metadata - assert_match "icp:public candid:service" - assert_match "icp:public dfx" - - ic-wasm .dfx/local/canisters/c/c.wasm metadata dfx > c_dfx.json - assert_command jq -r '.pullable.wasm_url' c_dfx.json - assert_eq "http://example.com/c.wasm" "$output" - assert_command jq -r '.pullable.dependencies | length' c_dfx.json - assert_eq 1 "$output" - assert_command jq -r '.pullable.dependencies | first' c_dfx.json - assert_eq "$CANISTER_ID_A" "$output" - assert_command jq -r '.pullable.init_guide' c_dfx.json - assert_eq "A natural number, e.g. 20." "$output" + dfx_start + + install_asset deps + + cd onchain + assert_command dfx canister create --all + assert_command dfx build + assert_command ic-wasm .dfx/local/canisters/c/c.wasm metadata + assert_match "icp:public candid:service" + assert_match "icp:public dfx" + + ic-wasm .dfx/local/canisters/c/c.wasm metadata dfx > c_dfx.json + assert_command jq -r '.pullable.wasm_url' c_dfx.json + assert_eq "http://example.com/c.wasm" "$output" + assert_command jq -r '.pullable.dependencies | length' c_dfx.json + assert_eq 1 "$output" + assert_command jq -r '.pullable.dependencies | first' c_dfx.json + assert_eq "$CANISTER_ID_A" "$output" + assert_command jq -r '.pullable.init_guide' c_dfx.json + assert_eq "A natural number, e.g. 20." "$output" } @test "dfx deps pull can resolve dependencies from on-chain canister metadata" { - # ic-ref has different behavior than the replica: - # it doesn't differ whether the canister not exist or the metadata not exist - dfx_start + # ic-ref has different behavior than the replica: + # it doesn't differ whether the canister not exist or the metadata not exist + dfx_start - install_asset deps + install_asset deps - # 1. success path - ## 1.1. prepare "onchain" canisters - # a -> [] - # b -> [a] - # c -> [a] - # app -> [a, b] + # 1. success path + ## 1.1. prepare "onchain" canisters + # a -> [] + # b -> [a] + # c -> [a] + # app -> [a, b] - cd onchain + cd onchain - dfx canister create a --specified-id "$CANISTER_ID_A" - dfx canister create b --specified-id "$CANISTER_ID_B" - dfx canister create c --specified-id "$CANISTER_ID_C" + dfx canister create a --specified-id "$CANISTER_ID_A" + dfx canister create b --specified-id "$CANISTER_ID_B" + dfx canister create c --specified-id "$CANISTER_ID_C" - dfx deploy a --argument 1 - dfx deploy b - dfx deploy c --argument 3 + dfx deploy a --argument 1 + dfx deploy b + dfx deploy c --argument 3 - ## 1.2. pull onchain canisters in "app" project - cd ../app + ## 1.2. pull onchain canisters in "app" project + cd ../app - assert_command_fail dfx deps pull --network local # the overall pull fail but succeed to fetch and parse `dfx:deps` recursively - assert_contains "Fetching dependencies of canister $CANISTER_ID_B... + assert_command_fail dfx deps pull --network local # the overall pull fail but succeed to fetch and parse `dfx:deps` recursively + assert_contains "Fetching dependencies of canister $CANISTER_ID_B... Fetching dependencies of canister $CANISTER_ID_C... Fetching dependencies of canister $CANISTER_ID_A... Found 3 dependencies: $CANISTER_ID_A $CANISTER_ID_B $CANISTER_ID_C" - assert_occurs 1 "Fetching dependencies of canister $CANISTER_ID_A..." # common dependency onchain_a is pulled only once - assert_contains "Pulling canister $CANISTER_ID_A... + assert_occurs 1 "Fetching dependencies of canister $CANISTER_ID_A..." # common dependency onchain_a is pulled only once + assert_contains "Pulling canister $CANISTER_ID_A... ERROR: Failed to pull canister $CANISTER_ID_A. Failed to download from url: http://example.com/a.wasm." - assert_contains "Pulling canister $CANISTER_ID_B... + assert_contains "Pulling canister $CANISTER_ID_B... ERROR: Failed to pull canister $CANISTER_ID_B. Failed to download from url: http://example.com/b.wasm.gz." - assert_contains "Pulling canister $CANISTER_ID_C... + assert_contains "Pulling canister $CANISTER_ID_C... ERROR: Failed to pull canister $CANISTER_ID_C. Failed to download from url: http://example.com/c.wasm." - # 3. sad path: if the canister is not present on-chain - cd ../onchain - dfx build c - dfx canister install c --argument 3 --mode=reinstall --yes # reinstall the correct canister c - dfx canister uninstall-code a + # 3. sad path: if the canister is not present on-chain + cd ../onchain + dfx build c + dfx canister install c --argument 3 --mode=reinstall --yes # reinstall the correct canister c + dfx canister uninstall-code a - cd ../app - assert_command_fail dfx deps pull --network local - assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." + cd ../app + assert_command_fail dfx deps pull --network local + assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." - cd ../onchain - dfx canister stop a - dfx canister delete a + cd ../onchain + dfx canister stop a + dfx canister delete a - cd ../app - assert_command_fail dfx deps pull --network local - assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." + cd ../app + assert_command_fail dfx deps pull --network local + assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." } @test "dfx deps pull can download wasm and candids to shared cache and generate pulled.json" { - use_test_specific_cache_root # dfx deps pull will download files to cache - - PULLED_DIR="$DFX_CACHE_ROOT/.cache/dfinity/pulled/" - assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_B/canister.wasm.gz" - assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_A/canister.wasm" - assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_C/canister.wasm" - assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_B/service.did" - assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_A/service.did" - assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_C/service.did" - - # start a "mainnet" replica which host the onchain canisters - dfx_start - - setup_onchain - - # TODO: test gzipped wasm can be pulled when we have "gzip" option in dfx.json (SDK-1102) - - # pull canisters in app project - cd app - assert_file_not_exists "deps/pulled.json" - - assert_command dfx deps pull --network local - assert_file_exists "$PULLED_DIR/$CANISTER_ID_B/canister.wasm.gz" - assert_file_exists "$PULLED_DIR/$CANISTER_ID_A/canister.wasm" - assert_file_exists "$PULLED_DIR/$CANISTER_ID_C/canister.wasm" - assert_file_exists "$PULLED_DIR/$CANISTER_ID_B/service.did" - assert_file_exists "$PULLED_DIR/$CANISTER_ID_A/service.did" - assert_file_exists "$PULLED_DIR/$CANISTER_ID_C/service.did" - - cd deps - assert_file_exists "pulled.json" - assert_file_exists "candid/$CANISTER_ID_B.did" - assert_file_exists "candid/$CANISTER_ID_C.did" - assert_eq 5 "$(jq -r '.canisters | keys' pulled.json | wc -l | tr -d ' ')" # 3 canisters + 2 lines of '[' and ']' - assert_command jq -r '.canisters."'"$CANISTER_ID_A"'".init_guide' pulled.json - assert_eq "A natural number, e.g. 10." "$output" - assert_command jq -r '.canisters."'"$CANISTER_ID_B"'".name' pulled.json - assert_eq "dep_b" "$output" - assert_command jq -r '.canisters."'"$CANISTER_ID_C"'".name' pulled.json - assert_eq "dep_c" "$output" - cd ../ - - assert_command dfx deps pull --network local -vvv - assert_contains "The canister wasm was found in the cache." # cache hit - - # sad path 1: wasm hash doesn't match on chain - rm -r "${PULLED_DIR:?}/" - cd ../onchain - cp .dfx/local/canisters/c/c.wasm ../www/a.wasm - - cd ../app - assert_command_fail dfx deps pull --network local - assert_contains "Failed to pull canister $CANISTER_ID_A." - assert_contains "Hash mismatch." - - # sad path 2: url server doesn't have the file - rm -r "${PULLED_DIR:?}/" - rm ../www/a.wasm - - assert_command_fail dfx deps pull --network local - assert_contains "Failed to pull canister $CANISTER_ID_A." - assert_contains "Failed to download from url:" + use_test_specific_cache_root # dfx deps pull will download files to cache + + PULLED_DIR="$DFX_CACHE_ROOT/.cache/dfinity/pulled/" + assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_B/canister.wasm.gz" + assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_A/canister.wasm" + assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_C/canister.wasm" + assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_B/service.did" + assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_A/service.did" + assert_file_not_exists "$PULLED_DIR/$CANISTER_ID_C/service.did" + + # start a "mainnet" replica which host the onchain canisters + dfx_start + + setup_onchain + + # TODO: test gzipped wasm can be pulled when we have "gzip" option in dfx.json (SDK-1102) + + # pull canisters in app project + cd app + assert_file_not_exists "deps/pulled.json" + + assert_command dfx deps pull --network local + assert_file_exists "$PULLED_DIR/$CANISTER_ID_B/canister.wasm.gz" + assert_file_exists "$PULLED_DIR/$CANISTER_ID_A/canister.wasm" + assert_file_exists "$PULLED_DIR/$CANISTER_ID_C/canister.wasm" + assert_file_exists "$PULLED_DIR/$CANISTER_ID_B/service.did" + assert_file_exists "$PULLED_DIR/$CANISTER_ID_A/service.did" + assert_file_exists "$PULLED_DIR/$CANISTER_ID_C/service.did" + + cd deps + assert_file_exists "pulled.json" + assert_file_exists "candid/$CANISTER_ID_B.did" + assert_file_exists "candid/$CANISTER_ID_C.did" + assert_eq 5 "$(jq -r '.canisters | keys' pulled.json | wc -l | tr -d ' ')" # 3 canisters + 2 lines of '[' and ']' + assert_command jq -r '.canisters."'"$CANISTER_ID_A"'".init_guide' pulled.json + assert_eq "A natural number, e.g. 10." "$output" + assert_command jq -r '.canisters."'"$CANISTER_ID_B"'".name' pulled.json + assert_eq "dep_b" "$output" + assert_command jq -r '.canisters."'"$CANISTER_ID_C"'".name' pulled.json + assert_eq "dep_c" "$output" + cd ../ + + assert_command dfx deps pull --network local -vvv + assert_contains "The canister wasm was found in the cache." # cache hit + + # sad path 1: wasm hash doesn't match on chain + rm -r "${PULLED_DIR:?}/" + cd ../onchain + cp .dfx/local/canisters/c/c.wasm ../www/a.wasm + + cd ../app + assert_command_fail dfx deps pull --network local + assert_contains "Failed to pull canister $CANISTER_ID_A." + assert_contains "Hash mismatch." + + # sad path 2: url server doesn't have the file + rm -r "${PULLED_DIR:?}/" + rm ../www/a.wasm + + assert_command_fail dfx deps pull --network local + assert_contains "Failed to pull canister $CANISTER_ID_A." + assert_contains "Failed to download from url:" } @test "dfx deps pull can check hash when dfx:wasm_hash specified" { - use_test_specific_cache_root # dfx deps pull will download files to cache + use_test_specific_cache_root # dfx deps pull will download files to cache - # start a "mainnet" replica which host the onchain canisters - dfx_start + # start a "mainnet" replica which host the onchain canisters + dfx_start - install_asset deps + install_asset deps - # start a webserver to host wasm files - mkdir www - start_webserver --directory www + # start a webserver to host wasm files + mkdir www + start_webserver --directory www - cd onchain + cd onchain - jq '.canisters.a.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/a.wasm"'"' dfx.json | sponge dfx.json - jq '.canisters.b.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/b.wasm.gz"'"' dfx.json | sponge dfx.json - jq '.canisters.c.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/c.wasm"'"' dfx.json | sponge dfx.json + jq '.canisters.a.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/a.wasm"'"' dfx.json | sponge dfx.json + jq '.canisters.b.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/b.wasm.gz"'"' dfx.json | sponge dfx.json + jq '.canisters.c.pullable.wasm_url="'"http://localhost:$E2E_WEB_SERVER_PORT/c.wasm"'"' dfx.json | sponge dfx.json - dfx canister create a --specified-id "$CANISTER_ID_A" - dfx canister create b --specified-id "$CANISTER_ID_B" - dfx canister create c --specified-id "$CANISTER_ID_C" - dfx build + dfx canister create a --specified-id "$CANISTER_ID_A" + dfx canister create b --specified-id "$CANISTER_ID_B" + dfx canister create c --specified-id "$CANISTER_ID_C" + dfx build - # copy wasm files to web server dir - cp .dfx/local/canisters/a/a.wasm ../www/a.wasm - cp .dfx/local/canisters/b/b.wasm.gz ../www/b.wasm.gz - cp .dfx/local/canisters/c/c.wasm ../www/c.wasm + # copy wasm files to web server dir + cp .dfx/local/canisters/a/a.wasm ../www/a.wasm + cp .dfx/local/canisters/b/b.wasm.gz ../www/b.wasm.gz + cp .dfx/local/canisters/c/c.wasm ../www/c.wasm - CUSTOM_HASH="$(sha256sum .dfx/local/canisters/a/a.wasm | cut -d " " -f 1)" - jq '.canisters.a.pullable.wasm_hash="'"$CUSTOM_HASH"'"' dfx.json | sponge dfx.json - dfx build a # .dfx/local/canisters/a/a.wasm is replaced. The new wasm has wasm_hash defined and will be installed. + CUSTOM_HASH="$(sha256sum .dfx/local/canisters/a/a.wasm | cut -d " " -f 1)" + jq '.canisters.a.pullable.wasm_hash="'"$CUSTOM_HASH"'"' dfx.json | sponge dfx.json + dfx build a # .dfx/local/canisters/a/a.wasm is replaced. The new wasm has wasm_hash defined and will be installed. - # cd ../../../ - dfx canister install a --argument 1 - dfx canister install b - dfx canister install c --argument 3 + # cd ../../../ + dfx canister install a --argument 1 + dfx canister install b + dfx canister install c --argument 3 - # pull canisters in app project - cd ../app - assert_file_not_exists "deps/pulled.json" + # pull canisters in app project + cd ../app + assert_file_not_exists "deps/pulled.json" - assert_command dfx deps pull --network local -vvv - assert_contains "Canister $CANISTER_ID_A specified a custom hash:" + assert_command dfx deps pull --network local -vvv + assert_contains "Canister $CANISTER_ID_A specified a custom hash:" - # error case: hash mismatch - PULLED_DIR="$DFX_CACHE_ROOT/.cache/dfinity/pulled/" - rm -r "${PULLED_DIR:?}/" - cd ../onchain - cp .dfx/local/canisters/a/a.wasm ../www/a.wasm # now the webserver has the onchain version of canister_a which won't match wasm_hash + # error case: hash mismatch + PULLED_DIR="$DFX_CACHE_ROOT/.cache/dfinity/pulled/" + rm -r "${PULLED_DIR:?}/" + cd ../onchain + cp .dfx/local/canisters/a/a.wasm ../www/a.wasm # now the webserver has the onchain version of canister_a which won't match wasm_hash - cd ../app - assert_command_fail dfx deps pull --network local -vvv - assert_contains "Canister $CANISTER_ID_A specified a custom hash:" - assert_contains "Failed to pull canister $CANISTER_ID_A." - assert_contains "Hash mismatch." + cd ../app + assert_command_fail dfx deps pull --network local -vvv + assert_contains "Canister $CANISTER_ID_A specified a custom hash:" + assert_contains "Failed to pull canister $CANISTER_ID_A." + assert_contains "Hash mismatch." } @test "dfx deps init works" { - use_test_specific_cache_root # dfx deps pull will download files to cache + use_test_specific_cache_root # dfx deps pull will download files to cache - # start a "mainnet" replica which host the onchain canisters - dfx_start + # start a "mainnet" replica which host the onchain canisters + dfx_start - setup_onchain + setup_onchain - # pull canisters in app project - cd app - assert_command dfx deps pull --network local + # pull canisters in app project + cd app + assert_command dfx deps pull --network local - # stop the "mainnet" replica - dfx_stop + # stop the "mainnet" replica + dfx_stop - assert_command dfx deps init - assert_contains "The following canister(s) require an init argument. Please run \`dfx deps init \` to set them individually:" - assert_contains "$CANISTER_ID_A" - assert_contains "$CANISTER_ID_C (dep_c)" + assert_command dfx deps init + assert_contains "The following canister(s) require an init argument. Please run \`dfx deps init \` to set them individually:" + assert_contains "$CANISTER_ID_A" + assert_contains "$CANISTER_ID_C (dep_c)" - assert_command dfx deps init "$CANISTER_ID_A" --argument 11 - assert_command dfx deps init dep_c --argument 33 + assert_command dfx deps init "$CANISTER_ID_A" --argument 11 + assert_command dfx deps init dep_c --argument 33 - # The argument is the hex string of '("abc")' which doesn't type check - # However, passing raw argument will bypass the type check so following command succeed - assert_command dfx deps init "$CANISTER_ID_A" --argument "4449444c00017103616263" --argument-type raw - assert_command jq -r '.canisters."'"$CANISTER_ID_A"'".arg_raw' deps/init.json - assert_eq "4449444c00017103616263" "$output" + # The argument is the hex string of '("abc")' which doesn't type check + # However, passing raw argument will bypass the type check so following command succeed + assert_command dfx deps init "$CANISTER_ID_A" --argument "4449444c00017103616263" --argument-type raw + assert_command jq -r '.canisters."'"$CANISTER_ID_A"'".arg_raw' deps/init.json + assert_eq "4449444c00017103616263" "$output" - # error cases - ## require init arguments but not provide - assert_command_fail dfx deps init "$CANISTER_ID_A" - assert_contains "Canister $CANISTER_ID_A requires an init argument" + # error cases + ## require init arguments but not provide + assert_command_fail dfx deps init "$CANISTER_ID_A" + assert_contains "Canister $CANISTER_ID_A requires an init argument" - ## wrong type - assert_command_fail dfx deps init "$CANISTER_ID_A" --argument '("abc")' - assert_contains "Invalid data: Unable to serialize Candid values: type mismatch: \"abc\" cannot be of type nat" + ## wrong type + assert_command_fail dfx deps init "$CANISTER_ID_A" --argument '("abc")' + assert_contains "Invalid data: Unable to serialize Candid values: type mismatch: \"abc\" cannot be of type nat" - ## require no init argument but provide - assert_command_fail dfx deps init dep_b --argument 1 - assert_contains "Canister $CANISTER_ID_B (dep_b) takes no init argument. Please rerun without \`--argument\`" + ## require no init argument but provide + assert_command_fail dfx deps init dep_b --argument 1 + assert_contains "Canister $CANISTER_ID_B (dep_b) takes no init argument. Please rerun without \`--argument\`" - ## require init arguments but not provide - assert_command_fail dfx deps init dep_c - assert_contains "Canister $CANISTER_ID_C (dep_c) requires an init argument. The following info might be helpful: + ## require init arguments but not provide + assert_command_fail dfx deps init dep_c + assert_contains "Canister $CANISTER_ID_C (dep_c) requires an init argument. The following info might be helpful: init => A natural number, e.g. 20. candid:args => (nat)" - ## canister ID not in pulled.json - assert_command_fail dfx deps init aaaaa-aa - assert_contains "Could not find aaaaa-aa in pulled.json" + ## canister ID not in pulled.json + assert_command_fail dfx deps init aaaaa-aa + assert_contains "Could not find aaaaa-aa in pulled.json" } @test "dfx deps deploy works" { - use_test_specific_cache_root # dfx deps pull will download files to cache - - # start a "mainnet" replica which host the onchain canisters - dfx_start - - setup_onchain - - # pull canisters in app project - cd app - assert_command dfx deps pull --network local - - # delete onchain canisters so that the replica has no canisters as a clean local replica - cd ../onchain - dfx canister stop a - dfx canister delete a - dfx canister stop b - dfx canister delete b - dfx canister stop c - dfx canister delete c - - cd ../app - assert_command dfx deps init # b is set here - assert_command dfx deps init "$CANISTER_ID_A" --argument 11 - assert_command dfx deps init "$CANISTER_ID_C" --argument 33 - - # deploy all - assert_command dfx deps deploy - assert_contains "Creating canister: $CANISTER_ID_A + use_test_specific_cache_root # dfx deps pull will download files to cache + + # start a "mainnet" replica which host the onchain canisters + dfx_start + + setup_onchain + + # pull canisters in app project + cd app + assert_command dfx deps pull --network local + + # delete onchain canisters so that the replica has no canisters as a clean local replica + cd ../onchain + dfx canister stop a + dfx canister delete a + dfx canister stop b + dfx canister delete b + dfx canister stop c + dfx canister delete c + + cd ../app + assert_command dfx deps init # b is set here + assert_command dfx deps init "$CANISTER_ID_A" --argument 11 + assert_command dfx deps init "$CANISTER_ID_C" --argument 33 + + # deploy all + assert_command dfx deps deploy + assert_contains "Creating canister: $CANISTER_ID_A Installing canister: $CANISTER_ID_A" - assert_contains "Creating canister: $CANISTER_ID_B (dep_b) + assert_contains "Creating canister: $CANISTER_ID_B (dep_b) Installing canister: $CANISTER_ID_B (dep_b)" - assert_contains "Creating canister: $CANISTER_ID_C (dep_c) + assert_contains "Creating canister: $CANISTER_ID_C (dep_c) Installing canister: $CANISTER_ID_C (dep_c)" - # by name in dfx.json - assert_command dfx deps deploy dep_b - assert_contains "Installing canister: $CANISTER_ID_B (dep_b)" # dep_p has been created before, so we only see "Installing ..." here - - # by canister id - assert_command dfx deps deploy $CANISTER_ID_A - assert_contains "Installing canister: $CANISTER_ID_A" - - # deployed pull dependencies can be stopped and deleted - assert_command dfx canister stop dep_b --identity anonymous - assert_command dfx canister delete dep_b --identity anonymous - - assert_command dfx canister stop $CANISTER_ID_A --identity anonymous - assert_command dfx canister delete $CANISTER_ID_A --identity anonymous - - # error cases - ## set wrong init argument - assert_command dfx deps init "$CANISTER_ID_A" --argument "4449444c00017103616263" --argument-type raw - assert_command_fail dfx deps deploy - assert_contains "Failed to install canister $CANISTER_ID_A" - - ## canister ID not in pulled.json - assert_command_fail dfx deps deploy aaaaa-aa - assert_contains "Could not find aaaaa-aa in pulled.json" - - ## no init.json - rm deps/init.json - assert_command_fail dfx deps deploy - assert_contains "Failed to read init.json. Please run \`dfx deps init\`." - - ## forgot to set init argument for some dependencies - assert_command dfx deps init # b is set here - assert_command_fail dfx deps deploy "$CANISTER_ID_A" - assert_contains "Failed to create and install canister $CANISTER_ID_A" - assert_contains "Failed to find $CANISTER_ID_A entry in init.json. Please run \`dfx deps init $CANISTER_ID_A\`." + # by name in dfx.json + assert_command dfx deps deploy dep_b + assert_contains "Installing canister: $CANISTER_ID_B (dep_b)" # dep_p has been created before, so we only see "Installing ..." here + + # by canister id + assert_command dfx deps deploy $CANISTER_ID_A + assert_contains "Installing canister: $CANISTER_ID_A" + + # deployed pull dependencies can be stopped and deleted + assert_command dfx canister stop dep_b --identity anonymous + assert_command dfx canister delete dep_b --identity anonymous + + assert_command dfx canister stop $CANISTER_ID_A --identity anonymous + assert_command dfx canister delete $CANISTER_ID_A --identity anonymous + + # error cases + ## set wrong init argument + assert_command dfx deps init "$CANISTER_ID_A" --argument "4449444c00017103616263" --argument-type raw + assert_command_fail dfx deps deploy + assert_contains "Failed to install canister $CANISTER_ID_A" + + ## canister ID not in pulled.json + assert_command_fail dfx deps deploy aaaaa-aa + assert_contains "Could not find aaaaa-aa in pulled.json" + + ## no init.json + rm deps/init.json + assert_command_fail dfx deps deploy + assert_contains "Failed to read init.json. Please run \`dfx deps init\`." + + ## forgot to set init argument for some dependencies + assert_command dfx deps init # b is set here + assert_command_fail dfx deps deploy "$CANISTER_ID_A" + assert_contains "Failed to create and install canister $CANISTER_ID_A" + assert_contains "Failed to find $CANISTER_ID_A entry in init.json. Please run \`dfx deps init $CANISTER_ID_A\`." } @test "dfx deps pulled dependencies work with app canister" { - use_test_specific_cache_root # dfx deps pull will download files to cache - - # start a "mainnet" replica which host the onchain canisters - dfx_start - - setup_onchain - - # pull canisters in app project - cd app - assert_command dfx deps pull --network local - - # delete onchain canisters so that the replica has no canisters as a clean local replica - cd ../onchain - dfx canister stop a - dfx canister delete a - dfx canister stop b - dfx canister delete b - dfx canister stop c - dfx canister delete c - - cd ../app - assert_command_fail dfx canister create dep_b - assert_contains "dep_b is a pull dependency. Please deploy it using \`dfx deps deploy dep_b\`" - assert_command dfx canister create app - - assert_command dfx canister create --all - assert_contains "There are pull dependencies defined in dfx.json. Please deploy them using \`dfx deps deploy\`." - - assert_command dfx build app - assert_command dfx canister install app - - # pulled dependency dep_b hasn't been deployed on local replica - assert_command_fail dfx canister call app get_b - assert_contains "Canister $CANISTER_ID_B not found" - - assert_command dfx deps init - assert_command dfx deps init "$CANISTER_ID_A" --argument 11 - assert_command dfx deps init "$CANISTER_ID_C" --argument 33 - assert_command dfx deps deploy - - assert_command dfx canister call app get_b - assert_eq "(2 : nat)" "$output" - assert_command dfx canister call app get_c - assert_eq "(33 : nat)" "$output" # corresponding to "--argument 33" above - assert_command dfx canister call app get_b_times_a - assert_eq "(22 : nat)" "$output" # 2 * 11 - assert_command dfx canister call app get_c_times_a - assert_eq "(363 : nat)" "$output" # 33 * 11 - - # start a clean local replica - dfx canister stop app - dfx canister delete app - assert_command dfx deploy # only deploy app canister + use_test_specific_cache_root # dfx deps pull will download files to cache + + # start a "mainnet" replica which host the onchain canisters + dfx_start + + setup_onchain + + # pull canisters in app project + cd app + assert_command dfx deps pull --network local + + # delete onchain canisters so that the replica has no canisters as a clean local replica + cd ../onchain + dfx canister stop a + dfx canister delete a + dfx canister stop b + dfx canister delete b + dfx canister stop c + dfx canister delete c + + cd ../app + assert_command_fail dfx canister create dep_b + assert_contains "dep_b is a pull dependency. Please deploy it using \`dfx deps deploy dep_b\`" + assert_command dfx canister create app + + assert_command dfx canister create --all + assert_contains "There are pull dependencies defined in dfx.json. Please deploy them using \`dfx deps deploy\`." + + assert_command dfx build app + assert_command dfx canister install app + + # pulled dependency dep_b hasn't been deployed on local replica + assert_command_fail dfx canister call app get_b + assert_contains "Canister $CANISTER_ID_B not found" + + assert_command dfx deps init + assert_command dfx deps init "$CANISTER_ID_A" --argument 11 + assert_command dfx deps init "$CANISTER_ID_C" --argument 33 + assert_command dfx deps deploy + + assert_command dfx canister call app get_b + assert_eq "(2 : nat)" "$output" + assert_command dfx canister call app get_c + assert_eq "(33 : nat)" "$output" # corresponding to "--argument 33" above + assert_command dfx canister call app get_b_times_a + assert_eq "(22 : nat)" "$output" # 2 * 11 + assert_command dfx canister call app get_c_times_a + assert_eq "(363 : nat)" "$output" # 33 * 11 + + # start a clean local replica + dfx canister stop app + dfx canister delete app + assert_command dfx deploy # only deploy app canister } @test "dfx deps does nothing in a project has no pull dependencies" { - dfx_new empty + dfx_new empty - # verify the help message - assert_command dfx deps pull -h - assert_contains "Pull canisters upon which the project depends. This command connects to the \"ic\" mainnet by default. + # verify the help message + assert_command dfx deps pull -h + assert_contains "Pull canisters upon which the project depends. This command connects to the \"ic\" mainnet by default. You can still choose other network by setting \`--network\`" - assert_command dfx deps pull - assert_contains "There are no pull dependencies defined in dfx.json" - assert_command dfx deps init - assert_contains "There are no pull dependencies defined in dfx.json" - assert_command dfx deps deploy - assert_contains "There are no pull dependencies defined in dfx.json" - - assert_directory_not_exists "deps" + assert_command dfx deps pull + assert_contains "There are no pull dependencies defined in dfx.json" + assert_command dfx deps init + assert_contains "There are no pull dependencies defined in dfx.json" + assert_command dfx deps deploy + assert_contains "There are no pull dependencies defined in dfx.json" + + assert_directory_not_exists "deps" } diff --git a/e2e/tests-dfx/describe_local_network.bash b/e2e/tests-dfx/describe_local_network.bash index 587991dc1a..4e54675441 100644 --- a/e2e/tests-dfx/describe_local_network.bash +++ b/e2e/tests-dfx/describe_local_network.bash @@ -3,124 +3,124 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx start with disabled canister http" { - create_networks_json - echo "{}" | jq '.local.canister_http.enabled=false' >"$E2E_NETWORKS_JSON" - assert_command dfx start --host 127.0.0.1:0 --background --verbose + create_networks_json + echo "{}" | jq '.local.canister_http.enabled=false' >"$E2E_NETWORKS_JSON" + assert_command dfx start --host 127.0.0.1:0 --background --verbose - assert_match "canister http: disabled \(default: enabled\)" + assert_match "canister http: disabled \(default: enabled\)" } @test "dfx start with a nonstandard subnet type" { - create_networks_json - echo "{}" | jq '.local.replica.subnet_type="verifiedapplication"' >"$E2E_NETWORKS_JSON" + create_networks_json + echo "{}" | jq '.local.replica.subnet_type="verifiedapplication"' >"$E2E_NETWORKS_JSON" - assert_command dfx start --host 127.0.0.1:0 --background --verbose + assert_command dfx start --host 127.0.0.1:0 --background --verbose - assert_match "subnet type: VerifiedApplication \(default: Application\)" + assert_match "subnet type: VerifiedApplication \(default: Application\)" } @test "dfx start with nonstandard bitcoin node" { - assert_command dfx start --host 127.0.0.1:0 --background --bitcoin-node 192.168.0.1:18000 --verbose + assert_command dfx start --host 127.0.0.1:0 --background --bitcoin-node 192.168.0.1:18000 --verbose - assert_match "bitcoin: enabled \(default: disabled\)" - assert_match "nodes: \[192.168.0.1:18000\] \(default: \[127.0.0.1:18444\]\)" + assert_match "bitcoin: enabled \(default: disabled\)" + assert_match "nodes: \[192.168.0.1:18000\] \(default: \[127.0.0.1:18444\]\)" } @test "dfx start enabling bitcoin" { - assert_command dfx start --host 127.0.0.1:0 --background --enable-bitcoin --verbose + assert_command dfx start --host 127.0.0.1:0 --background --enable-bitcoin --verbose - assert_match "bitcoin: enabled \(default: disabled\)" + assert_match "bitcoin: enabled \(default: disabled\)" } @test "dfx start in a project without a network definition" { - mkdir some-project - cd some-project - echo "{}" >dfx.json - - # we have to pass 0 for port to avoid conflicts - assert_command dfx start --host 127.0.0.1:0 --background --verbose - - assert_match "There is no project-specific network 'local' defined in .*/some-project/dfx.json." - assert_match "Using the default definition for the 'local' shared network because $DFX_CONFIG_ROOT/.config/dfx/networks.json does not exist." - - assert_match "Local server configuration:" - assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:4943\)" - assert_match "bitcoin: disabled" - assert_match "canister http: enabled" - assert_match "subnet type: Application" - assert_match "scope: shared" + mkdir some-project + cd some-project + echo "{}" >dfx.json + + # we have to pass 0 for port to avoid conflicts + assert_command dfx start --host 127.0.0.1:0 --background --verbose + + assert_match "There is no project-specific network 'local' defined in .*/some-project/dfx.json." + assert_match "Using the default definition for the 'local' shared network because $DFX_CONFIG_ROOT/.config/dfx/networks.json does not exist." + + assert_match "Local server configuration:" + assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:4943\)" + assert_match "bitcoin: disabled" + assert_match "canister http: enabled" + assert_match "subnet type: Application" + assert_match "scope: shared" } @test "dfx start outside of a project with default configuration" { - assert_command dfx start --host 127.0.0.1:0 --background --verbose + assert_command dfx start --host 127.0.0.1:0 --background --verbose - assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." - assert_match "Using the default definition for the 'local' shared network because $DFX_CONFIG_ROOT/.config/dfx/networks.json does not exist." + assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." + assert_match "Using the default definition for the 'local' shared network because $DFX_CONFIG_ROOT/.config/dfx/networks.json does not exist." } @test "dfx start outside of a project with a shared configuration file" { - create_networks_json + create_networks_json - assert_command dfx start --background --verbose + assert_command dfx start --background --verbose - assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." - assert_match "Using the default definition for the 'local' shared network because $DFX_CONFIG_ROOT/.config/dfx/networks.json does not define it." + assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." + assert_match "Using the default definition for the 'local' shared network because $DFX_CONFIG_ROOT/.config/dfx/networks.json does not define it." } @test "dfx start outside of a project with a shared configuration file that defines the local network" { - create_networks_json - echo "{}" | jq '.local.bind="127.0.0.1:0"' >"$E2E_NETWORKS_JSON" + create_networks_json + echo "{}" | jq '.local.bind="127.0.0.1:0"' >"$E2E_NETWORKS_JSON" - assert_command dfx start --background --verbose + assert_command dfx start --background --verbose - assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." - assert_match "Using shared network 'local' defined in $DFX_CONFIG_ROOT/.config/dfx/networks.json" + assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." + assert_match "Using shared network 'local' defined in $DFX_CONFIG_ROOT/.config/dfx/networks.json" } @test "dfx start describes default project-specific network" { - # almost default: use a dynamic port - echo "{}" | jq '.networks.local.bind="127.0.0.1:0"' > dfx.json - - assert_command dfx start --background --verbose - - assert_match "Local server configuration:" - assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:8000\)" - assert_match "bitcoin: disabled" - assert_match "canister http: enabled" - assert_match "subnet type: Application" - assert_match "data directory: .*/working-dir/.dfx/network/local" - assert_match "scope: project" + # almost default: use a dynamic port + echo "{}" | jq '.networks.local.bind="127.0.0.1:0"' > dfx.json + + assert_command dfx start --background --verbose + + assert_match "Local server configuration:" + assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:8000\)" + assert_match "bitcoin: disabled" + assert_match "canister http: enabled" + assert_match "subnet type: Application" + assert_match "data directory: .*/working-dir/.dfx/network/local" + assert_match "scope: project" } @test "dfx start describes default shared network" { - # almost default: use a dynamic port - create_networks_json - echo "{}" | jq '.local.bind="127.0.0.1:0"' >"$E2E_NETWORKS_JSON" + # almost default: use a dynamic port + create_networks_json + echo "{}" | jq '.local.bind="127.0.0.1:0"' >"$E2E_NETWORKS_JSON" - assert_command dfx start --background --verbose + assert_command dfx start --background --verbose - assert_match "Local server configuration:" - assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:4943\)" - assert_match "bitcoin: disabled" - assert_match "canister http: enabled" - assert_match "subnet type: Application" + assert_match "Local server configuration:" + assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:4943\)" + assert_match "bitcoin: disabled" + assert_match "canister http: enabled" + assert_match "subnet type: Application" - if [ "$(uname)" == "Darwin" ]; then - assert_match "data directory: .*/home-dir/Library/Application Support/org.dfinity.dfx/network/local" - elif [ "$(uname)" == "Linux" ]; then - assert_match "data directory: .*/home-dir/.local/share/dfx/network/local" - fi + if [ "$(uname)" == "Darwin" ]; then + assert_match "data directory: .*/home-dir/Library/Application Support/org.dfinity.dfx/network/local" + elif [ "$(uname)" == "Linux" ]; then + assert_match "data directory: .*/home-dir/.local/share/dfx/network/local" + fi - assert_match "scope: shared" + assert_match "scope: shared" } \ No newline at end of file diff --git a/e2e/tests-dfx/dfx_install.bash b/e2e/tests-dfx/dfx_install.bash index 17b1fbab19..60c8f8b1a2 100644 --- a/e2e/tests-dfx/dfx_install.bash +++ b/e2e/tests-dfx/dfx_install.bash @@ -3,78 +3,78 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx cache show does not install the dfx version into the cache" { - use_test_specific_cache_root - test -z "$(ls -A "$DFX_CACHE_ROOT")" + use_test_specific_cache_root + test -z "$(ls -A "$DFX_CACHE_ROOT")" - assert_command dfx cache show + assert_command dfx cache show - # does not populate the cache with this version - test ! -e "$(dfx cache show)" + # does not populate the cache with this version + test ! -e "$(dfx cache show)" - # it does create the empty versions directory though - test -d "$DFX_CACHE_ROOT/.cache/dfinity/versions" - test -z "$(ls -A "$DFX_CACHE_ROOT/.cache/dfinity/versions"``)" + # it does create the empty versions directory though + test -d "$DFX_CACHE_ROOT/.cache/dfinity/versions" + test -z "$(ls -A "$DFX_CACHE_ROOT/.cache/dfinity/versions"``)" } @test "non-forced install populates an empty cache" { - use_test_specific_cache_root - test ! -e "$(dfx cache show)"/dfx + use_test_specific_cache_root + test ! -e "$(dfx cache show)"/dfx - dfx_new + dfx_new - test -f "$(dfx cache show)"/dfx + test -f "$(dfx cache show)"/dfx } @test "forced install populates an empty cache" { - use_test_specific_cache_root + use_test_specific_cache_root - test ! -e "$(dfx cache show)"/dfx + test ! -e "$(dfx cache show)"/dfx - assert_command dfx cache install + assert_command dfx cache install - test -f "$(dfx cache show)"/dfx + test -f "$(dfx cache show)"/dfx } @test "forced install over an install succeeds" { - assert_command dfx cache install - test -f "$(dfx cache show)"/dfx + assert_command dfx cache install + test -f "$(dfx cache show)"/dfx - assert_command dfx cache install + assert_command dfx cache install } @test "Motoko base library files are not executable" { - assert_command dfx cache install - for file in "$(dfx cache show)"/base/*.mo; do - assert_command_fail test -x "$file" - assert_command_fail "$file" - assert_contains "Permission denied" - done + assert_command dfx cache install + for file in "$(dfx cache show)"/base/*.mo; do + assert_command_fail test -x "$file" + assert_command_fail "$file" + assert_contains "Permission denied" + done } @test "forced install overwrites a cached version" { - assert_command dfx cache install - test -f "$(dfx cache show)"/dfx + assert_command dfx cache install + test -f "$(dfx cache show)"/dfx - # add something extra to the cache - echo "garbage" >"$(dfx cache show)"/garbage - test -f "$(dfx cache show)"/garbage + # add something extra to the cache + echo "garbage" >"$(dfx cache show)"/garbage + test -f "$(dfx cache show)"/garbage - assert_command dfx cache install + assert_command dfx cache install - # dfx cache install should have removed it - test ! -e "$(dfx cache show)"/garbage + # dfx cache install should have removed it + test ! -e "$(dfx cache show)"/garbage - # and also installed the cache itself - test -f "$(dfx cache show)"/dfx + # and also installed the cache itself + test -f "$(dfx cache show)"/dfx } diff --git a/e2e/tests-dfx/dotenv.bash b/e2e/tests-dfx/dotenv.bash index 542895bb04..1f6f2ab755 100644 --- a/e2e/tests-dfx/dotenv.bash +++ b/e2e/tests-dfx/dotenv.bash @@ -3,84 +3,84 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop - - standard_teardown + dfx_stop + + standard_teardown } @test "writes environment variables to .env" { - dfx_start - dfx canister create --all - # .env should also include canisters that are not explicit dependencies - jq 'del(.canisters.e2e_project_frontend.dependencies)' dfx.json | sponge dfx.json - backend_canister=$(dfx canister id e2e_project_backend) - frontend_canister=$(dfx canister id e2e_project_frontend) - - assert_command dfx build e2e_project_frontend - - assert_file_exists .env - env=$(< .env) - assert_contains "DFX_NETWORK='local'" "$env" - assert_contains "CANISTER_ID_E2E_PROJECT_BACKEND='$backend_canister'" "$env" - assert_contains "E2E_PROJECT_BACKEND_CANISTER_ID='$backend_canister'" "$env" - assert_contains "CANISTER_ID_E2E_PROJECT_FRONTEND='$frontend_canister'" "$env" - assert_contains "E2E_PROJECT_FRONTEND_CANISTER_ID='$frontend_canister'" "$env" - - setup_actuallylocal_project_network - dfx canister create --all --network actuallylocal - assert_command dfx build --network actuallylocal - assert_contains "DFX_NETWORK='actuallylocal'" "$(< .env)" + dfx_start + dfx canister create --all + # .env should also include canisters that are not explicit dependencies + jq 'del(.canisters.e2e_project_frontend.dependencies)' dfx.json | sponge dfx.json + backend_canister=$(dfx canister id e2e_project_backend) + frontend_canister=$(dfx canister id e2e_project_frontend) + + assert_command dfx build e2e_project_frontend + + assert_file_exists .env + env=$(< .env) + assert_contains "DFX_NETWORK='local'" "$env" + assert_contains "CANISTER_ID_E2E_PROJECT_BACKEND='$backend_canister'" "$env" + assert_contains "E2E_PROJECT_BACKEND_CANISTER_ID='$backend_canister'" "$env" + assert_contains "CANISTER_ID_E2E_PROJECT_FRONTEND='$frontend_canister'" "$env" + assert_contains "E2E_PROJECT_FRONTEND_CANISTER_ID='$frontend_canister'" "$env" + + setup_actuallylocal_project_network + dfx canister create --all --network actuallylocal + assert_command dfx build --network actuallylocal + assert_contains "DFX_NETWORK='actuallylocal'" "$(< .env)" } @test "writes environment variables to selected file" { - dfx_start - dfx canister create --all + dfx_start + dfx canister create --all - assert_command dfx build --output-env-file flag.env - assert_file_exists flag.env - assert_contains "DFX_NETWORK='local'" "$(< flag.env)" + assert_command dfx build --output-env-file flag.env + assert_file_exists flag.env + assert_contains "DFX_NETWORK='local'" "$(< flag.env)" - jq '.output_env_file="json.env"' dfx.json | sponge dfx.json - assert_command dfx build - assert_file_exists json.env - assert_contains "DFX_NETWORK='local'" "$(< json.env)" + jq '.output_env_file="json.env"' dfx.json | sponge dfx.json + assert_command dfx build + assert_file_exists json.env + assert_contains "DFX_NETWORK='local'" "$(< json.env)" - jq 'del(.output_env_file)' dfx.json | sponge dfx.json - assert_command dfx build - assert_file_not_exists .env + jq 'del(.output_env_file)' dfx.json | sponge dfx.json + assert_command dfx build + assert_file_not_exists .env } @test "does not clobber existing .env content" { - dfx_start - dfx canister create --all - echo 'foo=bar' > .env - - assert_command dfx build - assert_file_exists .env - env=$(< .env) - assert_contains "DFX_NETWORK='local'" "$env" - assert_contains "foo=bar" "$env" - - echo 'baz=quux' >> .env - assert_command dfx build - env=$(< .env) - assert_contains "DFX_NETWORK='local'" "$env" - assert_contains "foo=bar" "$env" - assert_contains "baz=quux" "$env" - - # deliberately corrupt the file - head -n 3 .env | sponge .env - echo 'baz=quux' >> .env - assert_command dfx build - env=$(< .env) - assert_contains "# END DFX CANISTER ENVIRONMENT VARIABLES" "$env" - assert_contains "DFX_NETWORK='local'" "$env" - assert_contains "foo=bar" "$env" - assert_contains "baz=quux" "$env" + dfx_start + dfx canister create --all + echo 'foo=bar' > .env + + assert_command dfx build + assert_file_exists .env + env=$(< .env) + assert_contains "DFX_NETWORK='local'" "$env" + assert_contains "foo=bar" "$env" + + echo 'baz=quux' >> .env + assert_command dfx build + env=$(< .env) + assert_contains "DFX_NETWORK='local'" "$env" + assert_contains "foo=bar" "$env" + assert_contains "baz=quux" "$env" + + # deliberately corrupt the file + head -n 3 .env | sponge .env + echo 'baz=quux' >> .env + assert_command dfx build + env=$(< .env) + assert_contains "# END DFX CANISTER ENVIRONMENT VARIABLES" "$env" + assert_contains "DFX_NETWORK='local'" "$env" + assert_contains "foo=bar" "$env" + assert_contains "baz=quux" "$env" } diff --git a/e2e/tests-dfx/ed25519.bash b/e2e/tests-dfx/ed25519.bash index e8de4d8d6c..1e81d06663 100644 --- a/e2e/tests-dfx/ed25519.bash +++ b/e2e/tests-dfx/ed25519.bash @@ -3,27 +3,27 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "can call a canister using an ed25519 identity" { - install_asset ed25519 - assert_command dfx identity import --storage-mode plaintext ed25519 identity.pem - dfx_new # This installs replica and other binaries - dfx identity use ed25519 - install_asset whoami - dfx_start - dfx canister create whoami - dfx build - dfx canister install whoami - assert_command dfx canister call whoami whoami - assert_eq '(principal "2nor3-keehi-duuup-d7jcn-onggn-3atzm-gejtl-5tlzn-k4g6c-nnbf7-7qe")' - assert_command dfx identity get-principal - assert_eq "2nor3-keehi-duuup-d7jcn-onggn-3atzm-gejtl-5tlzn-k4g6c-nnbf7-7qe" + install_asset ed25519 + assert_command dfx identity import --storage-mode plaintext ed25519 identity.pem + dfx_new # This installs replica and other binaries + dfx identity use ed25519 + install_asset whoami + dfx_start + dfx canister create whoami + dfx build + dfx canister install whoami + assert_command dfx canister call whoami whoami + assert_eq '(principal "2nor3-keehi-duuup-d7jcn-onggn-3atzm-gejtl-5tlzn-k4g6c-nnbf7-7qe")' + assert_command dfx identity get-principal + assert_eq "2nor3-keehi-duuup-d7jcn-onggn-3atzm-gejtl-5tlzn-k4g6c-nnbf7-7qe" } diff --git a/e2e/tests-dfx/error_context.bash b/e2e/tests-dfx/error_context.bash index 61ad808525..694e1a8fa4 100644 --- a/e2e/tests-dfx/error_context.bash +++ b/e2e/tests-dfx/error_context.bash @@ -3,181 +3,181 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new - install_asset error_context + dfx_new + install_asset error_context } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "problems reading wallets.json" { - dfx_start + dfx_start - assert_command dfx identity get-wallet + assert_command dfx identity get-wallet - echo "invalid json" >"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + echo "invalid json" >"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" - assert_command_fail dfx identity get-wallet - assert_match "Failed to parse contents of .*/network/local/wallets.json as json" - assert_match "expected value at line 1 column 1" + assert_command_fail dfx identity get-wallet + assert_match "Failed to parse contents of .*/network/local/wallets.json as json" + assert_match "expected value at line 1 column 1" - assert_command_fail dfx wallet upgrade - assert_match "Failed to parse contents of .*/network/local/wallets.json as json" - assert_match "expected value at line 1 column 1" + assert_command_fail dfx wallet upgrade + assert_match "Failed to parse contents of .*/network/local/wallets.json as json" + assert_match "expected value at line 1 column 1" - echo '{ "identities": {} }' >"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + echo '{ "identities": {} }' >"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" - # maybe you were sudo when you made it - chmod u=w,go= "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" - assert_command_fail dfx identity get-wallet - assert_match "Failed to read .*/network/local/wallets.json" - assert_match "Permission denied" + # maybe you were sudo when you made it + chmod u=w,go= "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + assert_command_fail dfx identity get-wallet + assert_match "Failed to read .*/network/local/wallets.json" + assert_match "Permission denied" - assert_command_fail dfx wallet upgrade - assert_match "Failed to read .*/network/local/wallets.json" - assert_match "Permission denied" + assert_command_fail dfx wallet upgrade + assert_match "Failed to read .*/network/local/wallets.json" + assert_match "Permission denied" - # can't write it? - chmod u=r,go= "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" - assert_command dfx identity new --storage-mode plaintext alice - assert_command_fail dfx identity get-wallet --identity alice - assert_match "Failed to write to .*/local/wallets.json" - assert_match "Permission denied" + # can't write it? + chmod u=r,go= "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + assert_command dfx identity new --storage-mode plaintext alice + assert_command_fail dfx identity get-wallet --identity alice + assert_match "Failed to write to .*/local/wallets.json" + assert_match "Permission denied" } @test "address already in use" { - dfx_start + dfx_start - port=$(get_webserver_port) - address="127.0.0.1:$port" + port=$(get_webserver_port) + address="127.0.0.1:$port" - # fool dfx start into thinking dfx isn't running - mv "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/pid" "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/hidden_pid" + # fool dfx start into thinking dfx isn't running + mv "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/pid" "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/hidden_pid" - assert_command_fail dfx start --host "$address" + assert_command_fail dfx start --host "$address" - # What was the purpose of the address - assert_match "frontend address" + # What was the purpose of the address + assert_match "frontend address" - # What was the address we were looking for - assert_match "$address" + # What was the address we were looking for + assert_match "$address" - # The underlying cause - assert_match "Address already in use" + # The underlying cause + assert_match "Address already in use" - # Allow dfx stop to stop dfx in teardown. Otherwise, bats will never exit - mv "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/hidden_pid" "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/pid" + # Allow dfx stop to stop dfx in teardown. Otherwise, bats will never exit + mv "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/hidden_pid" "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/pid" } @test "corrupt dfx.json" { - echo "corrupt" >dfx.json - assert_command_fail dfx deploy + echo "corrupt" >dfx.json + assert_command_fail dfx deploy - # The bare minimum is to mention the file - assert_match "dfx.json" + # The bare minimum is to mention the file + assert_match "dfx.json" - # It's nice to mention the full path to the file - assert_match "$(pwd)/dfx.json" + # It's nice to mention the full path to the file + assert_match "$(pwd)/dfx.json" - # The underlying cause - assert_match "expected value at line 1 column 1" + # The underlying cause + assert_match "expected value at line 1 column 1" } @test "packtool missing" { - dfx_start + dfx_start - assert_command dfx canister create packtool_missing + assert_command dfx canister create packtool_missing - jq '.defaults.build.packtool="not-a-valid-packtool and some parameters"' dfx.json | sponge dfx.json + jq '.defaults.build.packtool="not-a-valid-packtool and some parameters"' dfx.json | sponge dfx.json - assert_command_fail dfx build packtool_missing + assert_command_fail dfx build packtool_missing - # expect to see the name of the packtool and the parameters - assert_match '"not-a-valid-packtool" "and" "some" "parameters"' - # expect to see the underlying cause - assert_match "No such file or directory" + # expect to see the name of the packtool and the parameters + assert_match '"not-a-valid-packtool" "and" "some" "parameters"' + # expect to see the underlying cause + assert_match "No such file or directory" } @test "moc missing" { - use_test_specific_cache_root # Because this test modifies a file in the cache + use_test_specific_cache_root # Because this test modifies a file in the cache - dfx_start + dfx_start - assert_command dfx canister create m_o_c_missing + assert_command dfx canister create m_o_c_missing - rm -f "$(dfx cache show)/moc" - assert_command_fail dfx build m_o_c_missing + rm -f "$(dfx cache show)/moc" + assert_command_fail dfx build m_o_c_missing - # expect to see the name of the binary - assert_match "moc" + # expect to see the name of the binary + assert_match "moc" - # expect to see the full path of the binary - assert_contains "$(dfx cache show)/moc" + # expect to see the full path of the binary + assert_contains "$(dfx cache show)/moc" - # expect to see the underlying cause - assert_match "No such file or directory" + # expect to see the underlying cause + assert_match "No such file or directory" } @test "npm is not installed" { - dfx_start + dfx_start - assert_command dfx canister create npm_missing + assert_command dfx canister create npm_missing - # this is how dfx decides to run `npm run build' - touch package.json + # this is how dfx decides to run `npm run build' + touch package.json - dfx_path="$(which dfx)" - # commands needed by assert_command_fail: - helpers_path="$(which mktemp rm echo | xargs -n 1 dirname | sort | uniq | tr '\n' ':')" - PATH="$helpers_path" assert_command_fail "$dfx_path" deploy npm_missing + dfx_path="$(which dfx)" + # commands needed by assert_command_fail: + helpers_path="$(which mktemp rm echo | xargs -n 1 dirname | sort | uniq | tr '\n' ':')" + PATH="$helpers_path" assert_command_fail "$dfx_path" deploy npm_missing - # expect to see the npm command line - assert_contains 'program: "npm"' - assert_match 'args: \[.*"npm".*"run".*"build".*\]' - # expect to see the name of the canister - assert_match "npm_missing" - # expect to see the underlying cause - assert_match "No such file or directory" + # expect to see the npm command line + assert_contains 'program: "npm"' + assert_match 'args: \[.*"npm".*"run".*"build".*\]' + # expect to see the name of the canister + assert_match "npm_missing" + # expect to see the underlying cause + assert_match "No such file or directory" } @test "missing asset source directory" { - dfx_start + dfx_start - assert_command dfx canister create asset_bad_source_path + assert_command dfx canister create asset_bad_source_path - assert_command_fail dfx deploy asset_bad_source_path + assert_command_fail dfx deploy asset_bad_source_path - # expect to see the bad path - assert_match "src/does/not/exist" - # expect to see the name of the canister - assert_match "asset_bad_source_path" - # expect to see the underlying cause - assert_match "No such file or directory" + # expect to see the bad path + assert_match "src/does/not/exist" + # expect to see the name of the canister + assert_match "asset_bad_source_path" + # expect to see the underlying cause + assert_match "No such file or directory" } @test "custom bad build step" { - dfx_start + dfx_start - assert_command dfx canister create custom_bad_build_step + assert_command dfx canister create custom_bad_build_step - assert_command_fail dfx build custom_bad_build_step + assert_command_fail dfx build custom_bad_build_step - # expect to see what it tried to call - assert_match "not-the-name-of-an-executable-that-exists" - # expect to see the name of the canister - assert_match "custom_bad_build_step" - # expect to see the underlying cause - assert_match "Cannot find command or file" + # expect to see what it tried to call + assert_match "not-the-name-of-an-executable-that-exists" + # expect to see the name of the canister + assert_match "custom_bad_build_step" + # expect to see the underlying cause + assert_match "Cannot find command or file" } @test "invalid optimization level" { - jq '.canisters.bad_optimization_level.optimize="bad_level"' dfx.json | sponge dfx.json - assert_command_fail dfx_start - assert_match "expected one of " + jq '.canisters.bad_optimization_level.optimize="bad_level"' dfx.json | sponge dfx.json + assert_command_fail dfx_start + assert_match "expected one of " } \ No newline at end of file diff --git a/e2e/tests-dfx/error_diagnosis.bash b/e2e/tests-dfx/error_diagnosis.bash index fa774ac1cf..5713607c9a 100644 --- a/e2e/tests-dfx/error_diagnosis.bash +++ b/e2e/tests-dfx/error_diagnosis.bash @@ -3,56 +3,56 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "Duplicate assets in dist/ from src/" { - dfx_new_frontend hello - install_asset greet - dfx_start - assert_command dfx deploy + dfx_new_frontend hello + install_asset greet + dfx_start + assert_command dfx deploy - # simulate previous deploy with CopyPlugin step - cp src/hello_frontend/assets/* dist/hello_frontend/ + # simulate previous deploy with CopyPlugin step + cp src/hello_frontend/assets/* dist/hello_frontend/ - assert_command_fail dfx deploy - assert_contains "Remove the CopyPlugin step from webpack.config.js" - assert_contains "Delete all files from the dist/ directory" + assert_command_fail dfx deploy + assert_contains "Remove the CopyPlugin step from webpack.config.js" + assert_contains "Delete all files from the dist/ directory" } @test "HTTP 403 has a full diagnosis" { - dfx_new hello - install_asset greet - dfx_start - assert_command dfx deploy - - # make sure normal status command works - assert_command dfx canister status hello_backend - - # create a non-controller ID - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity use alice - - # calling canister status with different identity provokes HTTP 403 - assert_command_fail dfx canister status hello_backend - assert_match "not part of the controllers" # this is part of the error explanation - assert_match "'dfx canister update-settings --add-controller \(--network ic\)'" # this is part of the solution + dfx_new hello + install_asset greet + dfx_start + assert_command dfx deploy + + # make sure normal status command works + assert_command dfx canister status hello_backend + + # create a non-controller ID + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity use alice + + # calling canister status with different identity provokes HTTP 403 + assert_command_fail dfx canister status hello_backend + assert_match "not part of the controllers" # this is part of the error explanation + assert_match "'dfx canister update-settings --add-controller \(--network ic\)'" # this is part of the solution } @test "Instruct user to set a wallet" { - dfx_new hello - install_asset greet - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity use alice - - # this will fail because no wallet is configured for alice on network ic - assert_command_fail dfx deploy --network ic - assert_match "requires a configured wallet" # this is part of the error explanation - assert_match "'dfx identity set-wallet --network '" # this is part of the solution + dfx_new hello + install_asset greet + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity use alice + + # this will fail because no wallet is configured for alice on network ic + assert_command_fail dfx deploy --network ic + assert_match "requires a configured wallet" # this is part of the error explanation + assert_match "'dfx identity set-wallet --network '" # this is part of the solution } diff --git a/e2e/tests-dfx/extension.bash b/e2e/tests-dfx/extension.bash index 0d81e3e91b..dd22e5b5b0 100644 --- a/e2e/tests-dfx/extension.bash +++ b/e2e/tests-dfx/extension.bash @@ -3,86 +3,86 @@ load ../utils/_ setup() { - standard_setup - use_test_specific_cache_root + standard_setup + use_test_specific_cache_root } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "install extension from official registry" { - assert_command_fail dfx snsx + assert_command_fail dfx snsx - assert_command dfx extension list - assert_match 'No extensions installed' + assert_command dfx extension list + assert_match 'No extensions installed' - assert_command dfx extension install sns --install-as snsx - # TODO: how to capture spinner message? - # assert_match 'Successfully installed extension' + assert_command dfx extension install sns --install-as snsx + # TODO: how to capture spinner message? + # assert_match 'Successfully installed extension' - assert_command dfx extension list - assert_match 'snsx' + assert_command dfx extension list + assert_match 'snsx' - assert_command dfx --help - assert_match 'snsx.*Toolkit for' + assert_command dfx --help + assert_match 'snsx.*Toolkit for' - assert_command dfx snsx --help + assert_command dfx snsx --help - assert_command dfx extension uninstall snsx - # TODO: how to capture spinner message? - # assert_match 'Successfully uninstalled extension' + assert_command dfx extension uninstall snsx + # TODO: how to capture spinner message? + # assert_match 'Successfully uninstalled extension' - assert_command dfx extension list - assert_match 'No extensions installed' + assert_command dfx extension list + assert_match 'No extensions installed' } @test "manually create extension" { - assert_command dfx extension list - assert_match 'No extensions installed' + assert_command dfx extension list + assert_match 'No extensions installed' - CACHE_DIR=$(dfx cache show) - mkdir -p "$CACHE_DIR"/extensions/test_extension - echo '#!/usr/bin/env bash + CACHE_DIR=$(dfx cache show) + mkdir -p "$CACHE_DIR"/extensions/test_extension + echo '#!/usr/bin/env bash echo testoutput' > "$CACHE_DIR"/extensions/test_extension/test_extension - chmod +x "$CACHE_DIR"/extensions/test_extension/test_extension + chmod +x "$CACHE_DIR"/extensions/test_extension/test_extension - assert_command_fail dfx extension list - assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_command_fail dfx extension list + assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" - assert_command_fail dfx extension run test_extension - assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_command_fail dfx extension run test_extension + assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" - assert_command_fail dfx test_extension - assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_command_fail dfx test_extension + assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" - assert_command_fail dfx --help - assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_command_fail dfx --help + assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" - assert_command_fail dfx test_extension --help - assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_command_fail dfx test_extension --help + assert_match "Error.*Cannot load extension manifest.*Failed to read JSON file.*Failed to read .*extensions/test_extension/extension.json.*No such file or directory" - echo "{}" > "$CACHE_DIR"/extensions/test_extension/extension.json + echo "{}" > "$CACHE_DIR"/extensions/test_extension/extension.json - assert_command_fail dfx extension list - assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" + assert_command_fail dfx extension list + assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" - assert_command_fail dfx extension run test_extension - assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" + assert_command_fail dfx extension run test_extension + assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" - assert_command_fail dfx test_extension - assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" + assert_command_fail dfx test_extension + assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" - assert_command_fail dfx --help - assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" + assert_command_fail dfx --help + assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" - assert_command_fail dfx test_extension --help - assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" + assert_command_fail dfx test_extension --help + assert_match "Error.*Cannot load extension manifest.*Failed to parse contents of .*extensions/test_extension/extension.json as json.* missing field .* at line .* column .*" - echo '{ + echo '{ "name": "test_extension", "version": "0.1.0", "homepage": "https://github.com/dfinity/dfx-extensions", @@ -92,45 +92,45 @@ echo testoutput' > "$CACHE_DIR"/extensions/test_extension/test_extension "keywords": [] }' > "$CACHE_DIR"/extensions/test_extension/extension.json - assert_command dfx --help - assert_match "test_extension.*Test extension for e2e purposes." + assert_command dfx --help + assert_match "test_extension.*Test extension for e2e purposes." - assert_command dfx test_extension --help - assert_match "Test extension for e2e purposes..*Usage: dfx test_extension" + assert_command dfx test_extension --help + assert_match "Test extension for e2e purposes..*Usage: dfx test_extension" - assert_command dfx extension list - assert_match "test_extension" + assert_command dfx extension list + assert_match "test_extension" - assert_command dfx extension run test_extension - assert_match "testoutput" + assert_command dfx extension run test_extension + assert_match "testoutput" - assert_command dfx test_extension - assert_match "testoutput" + assert_command dfx test_extension + assert_match "testoutput" - assert_command dfx extension uninstall test_extension - # TODO: how to capture spinner message? - # assert_match 'Successfully uninstalled extension' + assert_command dfx extension uninstall test_extension + # TODO: how to capture spinner message? + # assert_match 'Successfully uninstalled extension' - assert_command dfx extension list - assert_match 'No extensions installed' + assert_command dfx extension list + assert_match 'No extensions installed' } @test "run with hyphened parameters" { - CACHE_DIR=$(dfx cache show) - mkdir -p "$CACHE_DIR"/extensions/test_extension + CACHE_DIR=$(dfx cache show) + mkdir -p "$CACHE_DIR"/extensions/test_extension - cat > "$CACHE_DIR"/extensions/test_extension/test_extension << "EOF" + cat > "$CACHE_DIR"/extensions/test_extension/test_extension << "EOF" #!/usr/bin/env bash if [ "$2" == "--the-param" ]; then - echo "pamparam the param is $3" + echo "pamparam the param is $3" fi EOF - chmod +x "$CACHE_DIR"/extensions/test_extension/test_extension + chmod +x "$CACHE_DIR"/extensions/test_extension/test_extension - cat > "$CACHE_DIR"/extensions/test_extension/extension.json < "$CACHE_DIR"/extensions/test_extension/extension.json < "$CACHE_DIR"/extensions/test_extension/test_extension << "EOF" + cat > "$CACHE_DIR"/extensions/test_extension/test_extension << "EOF" #!/usr/bin/env bash echo $@ EOF - chmod +x "$CACHE_DIR"/extensions/test_extension/test_extension + chmod +x "$CACHE_DIR"/extensions/test_extension/test_extension - cat > "$CACHE_DIR"/extensions/test_extension/extension.json < "$CACHE_DIR"/extensions/test_extension/extension.json <"$E2E_NETWORKS_JSON" - - assert_command dfx deploy - assert_match "e2e_project_backend: http://$CANDID_UI_ID.localhost:$PORT/\?id=$APP_ID" - assert_match "e2e_project_frontend: http://$ASSETS_ID.localhost:$PORT/" + dfx_start + PORT=$(get_webserver_port) + + assert_command dfx deploy + CANDID_UI_ID=$(dfx canister id __Candid_UI) + APP_ID=$(dfx canister id e2e_project_backend) + ASSETS_ID=$(dfx canister id e2e_project_frontend) + assert_match "e2e_project_backend: http://127.0.0.1:$PORT/\?canisterId=$CANDID_UI_ID&id=$APP_ID" + assert_match "e2e_project_frontend: http://127.0.0.1:$PORT/\?canisterId=$ASSETS_ID" + + # the urls are a little nicer if the bind address is localhost:8000 rather than 127.0.0.1:8000 + jq -n '.local.bind="localhost:'"$PORT"'"' >"$E2E_NETWORKS_JSON" + + assert_command dfx deploy + assert_match "e2e_project_backend: http://$CANDID_UI_ID.localhost:$PORT/\?id=$APP_ID" + assert_match "e2e_project_frontend: http://$ASSETS_ID.localhost:$PORT/" } @test "dfx start serves a frontend with static assets" { - skip "Need a build of @dfinity/agent that works with HTTP Query" - dfx_start - dfx canister create --all - dfx build - dfx canister install --all - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - assert_command curl http://localhost:"$PORT"/?canisterId="$ID" - assert_match "logo.png" + skip "Need a build of @dfinity/agent that works with HTTP Query" + dfx_start + dfx canister create --all + dfx build + dfx canister install --all + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + assert_command curl http://localhost:"$PORT"/?canisterId="$ID" + assert_match "logo.png" } @test "dfx start serves a frontend on a port" { - skip "Need a build of @dfinity/agent that works with HTTP Query" + skip "Need a build of @dfinity/agent that works with HTTP Query" - dfx_start --host 127.0.0.1:12345 + dfx_start --host 127.0.0.1:12345 - jq '.networks.local.bind="127.0.0.1:12345"' dfx.json | sponge dfx.json + jq '.networks.local.bind="127.0.0.1:12345"' dfx.json | sponge dfx.json - dfx canister create --all - dfx build - dfx canister install --all + dfx canister create --all + dfx build + dfx canister install --all - ID=$(dfx canister id e2e_project_frontend) - assert_command curl http://localhost:12345/?canisterId="$ID" - assert_match "" + ID=$(dfx canister id e2e_project_frontend) + assert_command curl http://localhost:12345/?canisterId="$ID" + assert_match "" - assert_command_fail curl http://localhost:8000 - assert_match "Connection refused" + assert_command_fail curl http://localhost:8000 + assert_match "Connection refused" } @test "dfx uses .ic-assets.json file provided in src/__project_name__frontend/src" { - echo '[{"match": "*", "headers": {"x-key": "x-value"}}]' > src/e2e_project_frontend/src/.ic-assets.json - - dfx_start - dfx canister create --all - dfx build - dfx canister install --all - - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) - assert_command curl -vv http://localhost:"$PORT"/?canisterId="$ID" - assert_match "< x-key: x-value" - assert_command curl -vv http://localhost:"$PORT"/index.js?canisterId="$ID" - assert_match "< x-key: x-value" + echo '[{"match": "*", "headers": {"x-key": "x-value"}}]' > src/e2e_project_frontend/src/.ic-assets.json + + dfx_start + dfx canister create --all + dfx build + dfx canister install --all + + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) + assert_command curl -vv http://localhost:"$PORT"/?canisterId="$ID" + assert_match "< x-key: x-value" + assert_command curl -vv http://localhost:"$PORT"/index.js?canisterId="$ID" + assert_match "< x-key: x-value" } @test "dfx uses a custom build command if one is provided" { - jq '.canisters.e2e_project_frontend.source = ["dist/e2e_project_frontend/"]' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_frontend.build = ["npm run custom-build"]' dfx.json | sponge dfx.json - jq '.scripts["custom-build"] = "mkdir -p ./dist/e2e_project_frontend/assets/ && cp -r ./src/e2e_project_frontend/assets/* ./dist/e2e_project_frontend"' package.json | sponge package.json + jq '.canisters.e2e_project_frontend.source = ["dist/e2e_project_frontend/"]' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_frontend.build = ["npm run custom-build"]' dfx.json | sponge dfx.json + jq '.scripts["custom-build"] = "mkdir -p ./dist/e2e_project_frontend/assets/ && cp -r ./src/e2e_project_frontend/assets/* ./dist/e2e_project_frontend"' package.json | sponge package.json - dfx_start - dfx canister create --all - dfx build - dfx canister install --all + dfx_start + dfx canister create --all + dfx build + dfx canister install --all - ID=$(dfx canister id e2e_project_frontend) - PORT=$(get_webserver_port) + ID=$(dfx canister id e2e_project_frontend) + PORT=$(get_webserver_port) - assert_command curl -vv http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID" - assert_match "This is a sample asset!" + assert_command curl -vv http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID" + assert_match "This is a sample asset!" } diff --git a/e2e/tests-dfx/generate.bash b/e2e/tests-dfx/generate.bash index 604fea0c0b..80e571c20d 100755 --- a/e2e/tests-dfx/generate.bash +++ b/e2e/tests-dfx/generate.bash @@ -3,148 +3,148 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx generate creates files" { - dfx_new hello - dfx_start - dfx canister create --all - dfx build - dfx canister install --all - - dfx generate - - assert_file_exists "src/declarations/hello_backend/hello_backend.did" - assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" - assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" - assert_file_exists "src/declarations/hello_backend/index.js" - assert_file_exists "src/declarations/hello_backend/index.d.ts" + dfx_new hello + dfx_start + dfx canister create --all + dfx build + dfx canister install --all + + dfx generate + + assert_file_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_exists "src/declarations/hello_backend/index.js" + assert_file_exists "src/declarations/hello_backend/index.d.ts" } @test "dfx generate creates only JS files" { - dfx_new hello - jq '.canisters.hello_backend.declarations.bindings=["js"]' dfx.json | sponge dfx.json + dfx_new hello + jq '.canisters.hello_backend.declarations.bindings=["js"]' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - dfx build - dfx canister install --all + dfx_start + dfx canister create --all + dfx build + dfx canister install --all - dfx generate + dfx generate - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" - assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.d.ts" - assert_file_exists "src/declarations/hello_backend/index.js" - assert_file_not_exists "src/declarations/hello_backend/index.d.ts" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_exists "src/declarations/hello_backend/index.js" + assert_file_not_exists "src/declarations/hello_backend/index.d.ts" } @test "dfx generate creates only TS files" { - dfx_new hello - jq '.canisters.hello_backend.declarations.bindings=["ts"]' dfx.json | sponge dfx.json + dfx_new hello + jq '.canisters.hello_backend.declarations.bindings=["ts"]' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - dfx build - dfx canister install --all + dfx_start + dfx canister create --all + dfx build + dfx canister install --all - dfx generate + dfx generate - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.js" - assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" - assert_file_not_exists "src/declarations/hello_backend/index.js" - assert_file_exists "src/declarations/hello_backend/index.d.ts" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_not_exists "src/declarations/hello_backend/index.js" + assert_file_exists "src/declarations/hello_backend/index.d.ts" } @test "dfx generate creates only JS & TS files" { - dfx_new hello - jq '.canisters.hello_backend.declarations.bindings=["js", "ts"]' dfx.json | sponge dfx.json + dfx_new hello + jq '.canisters.hello_backend.declarations.bindings=["js", "ts"]' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - dfx build - dfx canister install --all + dfx_start + dfx canister create --all + dfx build + dfx canister install --all - dfx generate + dfx generate - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" - assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" - assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" - assert_file_exists "src/declarations/hello_backend/index.js" - assert_file_exists "src/declarations/hello_backend/index.d.ts" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_exists "src/declarations/hello_backend/index.js" + assert_file_exists "src/declarations/hello_backend/index.d.ts" } @test "dfx generate creates only DID files" { - dfx_new hello - jq '.canisters.hello_backend.declarations.bindings=["did"]' dfx.json | sponge dfx.json + dfx_new hello + jq '.canisters.hello_backend.declarations.bindings=["did"]' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - dfx build - dfx canister install --all + dfx_start + dfx canister create --all + dfx build + dfx canister install --all - dfx generate + dfx generate - assert_file_exists "src/declarations/hello_backend/hello_backend.did" - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.js" - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.d.ts" - assert_file_not_exists "src/declarations/hello_backend/index.js" - assert_file_not_exists "src/declarations/hello_backend/index.d.ts" + assert_file_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_not_exists "src/declarations/hello_backend/index.js" + assert_file_not_exists "src/declarations/hello_backend/index.d.ts" } @test "dfx generate does not create any files" { - dfx_new hello - jq '.canisters.hello_backend.declarations.bindings=[]' dfx.json | sponge dfx.json + dfx_new hello + jq '.canisters.hello_backend.declarations.bindings=[]' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - dfx build - dfx canister install --all + dfx_start + dfx canister create --all + dfx build + dfx canister install --all - dfx generate + dfx generate - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.js" - assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.d.ts" - assert_file_not_exists "src/declarations/hello_backend/index.js" - assert_file_not_exists "src/declarations/hello_backend/index.d.ts" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_not_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_not_exists "src/declarations/hello_backend/index.js" + assert_file_not_exists "src/declarations/hello_backend/index.d.ts" } @test "dfx generate succeeds with an encrypted identity without input" { - dfx_new hello - dfx_start - dfx canister create --all - - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" - assert_command dfx identity use alice - - assert_command timeout 30s dfx generate + dfx_new hello + dfx_start + dfx canister create --all + + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" + assert_command dfx identity use alice + + assert_command timeout 30s dfx generate } @test "dfx generate does not require canister IDs for non-Motoko canisters" { - dfx_new_rust hello - assert_command dfx generate + dfx_new_rust hello + assert_command dfx generate } @test "dfx generate does not require canister IDs for Motoko canisters" { - dfx_new hello - assert_command dfx generate + dfx_new hello + assert_command dfx generate } @test "dfx generate --network is still valid" { - # The option has no effect, but is still accepted to not break existing scripts - dfx_new hello - assert_command dfx generate --network local + # The option has no effect, but is still accepted to not break existing scripts + dfx_new hello + assert_command dfx generate --network local - # Option is not advertised anymore - assert_command dfx generate --help - assert_not_contains "--network" + # Option is not advertised anymore + assert_command dfx generate --help + assert_not_contains "--network" } diff --git a/e2e/tests-dfx/id.bash b/e2e/tests-dfx/id.bash index f019a3996a..9a46066db6 100644 --- a/e2e/tests-dfx/id.bash +++ b/e2e/tests-dfx/id.bash @@ -3,96 +3,96 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "id subcommand prints valid canister identifier" { - install_asset id - dfx_start - dfx canister create --all - dfx build - assert_command dfx canister id e2e_project_backend - assert_match "$(jq -r .e2e_project_backend.local < .dfx/local/canister_ids.json)" + install_asset id + dfx_start + dfx canister create --all + dfx build + assert_command dfx canister id e2e_project_backend + assert_match "$(jq -r .e2e_project_backend.local < .dfx/local/canister_ids.json)" } @test "id subcommand does not display warning about plaintext keys" { - install_asset id - dfx identity get-principal - echo "{}" | jq '.e2e_project_backend.ic = "bd3sg-teaaa-aaaaa-qaaba-cai"' >canister_ids.json - assert_command dfx canister id e2e_project_backend --ic - assert_eq "bd3sg-teaaa-aaaaa-qaaba-cai" + install_asset id + dfx identity get-principal + echo "{}" | jq '.e2e_project_backend.ic = "bd3sg-teaaa-aaaaa-qaaba-cai"' >canister_ids.json + assert_command dfx canister id e2e_project_backend --ic + assert_eq "bd3sg-teaaa-aaaaa-qaaba-cai" } @test "id subcommand works from a subdirectory of the project - ephemeral id" { - install_asset id - dfx_start - dfx canister create --all - ID=$(dfx canister id e2e_project_backend) - echo "canister id is $ID" + install_asset id + dfx_start + dfx canister create --all + ID=$(dfx canister id e2e_project_backend) + echo "canister id is $ID" - ( - cd src - dfx canister id e2e_project_backend - assert_command dfx canister id e2e_project_backend - assert_eq "$ID" - ) + ( + cd src + dfx canister id e2e_project_backend + assert_command dfx canister id e2e_project_backend + assert_eq "$ID" + ) } @test "id subcommand works from a subdirectory of the project - persistent id" { - install_asset id + install_asset id - jq '.networks.local.type="persistent"' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - ID=$(dfx canister id e2e_project_backend) - echo "canister id is $ID" - ( - cd src - dfx canister id e2e_project_backend - assert_command dfx canister id e2e_project_backend - assert_eq "$ID" - ) + jq '.networks.local.type="persistent"' dfx.json | sponge dfx.json + dfx_start + dfx canister create --all + ID=$(dfx canister id e2e_project_backend) + echo "canister id is $ID" + ( + cd src + dfx canister id e2e_project_backend + assert_command dfx canister id e2e_project_backend + assert_eq "$ID" + ) } @test "id subcommand uses default network for remotes only" { - install_asset id - install_shared_asset subnet_type/shared_network_settings/application - # Add a remote canister with a specific ID for one network and a different default for other networks. - jq '.canisters.external_canister = { - "build": "", - "candid": "candid/external_canister.did", - "remote": { - "id": { - "namedremote": "va76m-bqaaa-aaaaa-aaayq-cai", - "__default": "rkp4c-7iaaa-aaaaa-aaaca-cai" - } - }, - "type": "custom", - "wasm": "" - }' dfx.json | sponge dfx.json - # We need to define the networks we are going to use: - jq '.namedremote= {"type": "persistent", "providers": ["http://namedremote"]}' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - jq '.somethingelse= {"type": "persistent", "providers": ["http://somethingelse"]}' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - cat dfx.json - cat "$E2E_NETWORKS_JSON" - # Ok, start: - dfx_start || true - dfx canister create --all - # The local dfx canister ID should not be affected: - assert_command dfx canister id e2e_project_backend - assert_match "$(jq -r .e2e_project_backend.local < .dfx/local/canister_ids.json)" - # Named remotes should be unaffected: - assert_command dfx canister --network namedremote id external_canister - assert_match "va76m-bqaaa-aaaaa-aaayq-cai" - # Other remotes should use the default entry: - assert_command dfx canister --network somethingelse id external_canister - assert_match "rkp4c-7iaaa-aaaaa-aaaca-cai" + install_asset id + install_shared_asset subnet_type/shared_network_settings/application + # Add a remote canister with a specific ID for one network and a different default for other networks. + jq '.canisters.external_canister = { + "build": "", + "candid": "candid/external_canister.did", + "remote": { + "id": { + "namedremote": "va76m-bqaaa-aaaaa-aaayq-cai", + "__default": "rkp4c-7iaaa-aaaaa-aaaca-cai" + } + }, + "type": "custom", + "wasm": "" + }' dfx.json | sponge dfx.json + # We need to define the networks we are going to use: + jq '.namedremote= {"type": "persistent", "providers": ["http://namedremote"]}' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + jq '.somethingelse= {"type": "persistent", "providers": ["http://somethingelse"]}' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + cat dfx.json + cat "$E2E_NETWORKS_JSON" + # Ok, start: + dfx_start || true + dfx canister create --all + # The local dfx canister ID should not be affected: + assert_command dfx canister id e2e_project_backend + assert_match "$(jq -r .e2e_project_backend.local < .dfx/local/canister_ids.json)" + # Named remotes should be unaffected: + assert_command dfx canister --network namedremote id external_canister + assert_match "va76m-bqaaa-aaaaa-aaayq-cai" + # Other remotes should use the default entry: + assert_command dfx canister --network somethingelse id external_canister + assert_match "rkp4c-7iaaa-aaaaa-aaaca-cai" } diff --git a/e2e/tests-dfx/identity.bash b/e2e/tests-dfx/identity.bash index 4946491fa7..a39681152f 100644 --- a/e2e/tests-dfx/identity.bash +++ b/e2e/tests-dfx/identity.bash @@ -3,198 +3,198 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "identity new: name validation" { - assert_command_fail dfx identity new iden%tity --storage-mode plaintext - assert_match "Invalid identity name" + assert_command_fail dfx identity new iden%tity --storage-mode plaintext + assert_match "Invalid identity name" - assert_command_fail dfx identity new 'iden tity' --storage-mode plaintext - assert_match "Invalid identity name" + assert_command_fail dfx identity new 'iden tity' --storage-mode plaintext + assert_match "Invalid identity name" - assert_command_fail dfx identity new "iden\$tity" --storage-mode plaintext - assert_match "Invalid identity name" + assert_command_fail dfx identity new "iden\$tity" --storage-mode plaintext + assert_match "Invalid identity name" - assert_command_fail dfx identity new iden\\tity --storage-mode plaintext - assert_match "Invalid identity name" + assert_command_fail dfx identity new iden\\tity --storage-mode plaintext + assert_match "Invalid identity name" - assert_command_fail dfx identity new 'iden\ttity' --storage-mode plaintext - assert_match "Invalid identity name" + assert_command_fail dfx identity new 'iden\ttity' --storage-mode plaintext + assert_match "Invalid identity name" - assert_command_fail dfx identity new iden/tity --storage-mode plaintext - assert_match "Invalid identity name" + assert_command_fail dfx identity new iden/tity --storage-mode plaintext + assert_match "Invalid identity name" - assert_command dfx identity new i_den.ti-ty --storage-mode plaintext + assert_command dfx identity new i_den.ti-ty --storage-mode plaintext - assert_command dfx identity new i_den@ti-ty --storage-mode plaintext + assert_command dfx identity new i_den@ti-ty --storage-mode plaintext } @test "identity get-principal: the get-principal is the same as sender id" { - install_asset identity - dfx_start - assert_command dfx identity new --storage-mode plaintext jose + install_asset identity + dfx_start + assert_command dfx identity new --storage-mode plaintext jose - PRINCIPAL_ID=$(dfx identity get-principal --identity jose) + PRINCIPAL_ID=$(dfx identity get-principal --identity jose) - dfx canister create e2e_project_backend --identity jose - dfx build e2e_project_backend --identity jose - dfx canister install e2e_project_backend --identity jose + dfx canister create e2e_project_backend --identity jose + dfx build e2e_project_backend --identity jose + dfx canister install e2e_project_backend --identity jose - assert_command dfx canister call e2e_project_backend amInitializer --identity jose + assert_command dfx canister call e2e_project_backend amInitializer --identity jose - SENDER_ID=$(dfx canister call e2e_project_backend fromCall --identity jose) + SENDER_ID=$(dfx canister call e2e_project_backend fromCall --identity jose) - if [ "$PRINCIPAL_ID" -ne "$SENDER_ID" ]; then - echo "IDs did not match: Principal '${PRINCIPAL_ID}' != Sender '${SENDER_ID}'..." | fail - fi + if [ "$PRINCIPAL_ID" -ne "$SENDER_ID" ]; then + echo "IDs did not match: Principal '${PRINCIPAL_ID}' != Sender '${SENDER_ID}'..." | fail + fi } @test "identity get-principal (anonymous): the get-principal is the same as sender id" { - install_asset identity - dfx_start - assert_command dfx identity new --storage-mode plaintext jose + install_asset identity + dfx_start + assert_command dfx identity new --storage-mode plaintext jose - ANONYMOUS_PRINCIPAL_ID="2vxsx-fae" + ANONYMOUS_PRINCIPAL_ID="2vxsx-fae" - PRINCIPAL_ID=$(dfx identity get-principal --identity anonymous) + PRINCIPAL_ID=$(dfx identity get-principal --identity anonymous) - if [ "$PRINCIPAL_ID" -ne "$ANONYMOUS_PRINCIPAL_ID" ]; then - echo "IDs did not match: Principal '${ANONYMOUS_PRINCIPAL_ID}' != Sender '${PRINCIPAL_ID}'..." | fail - fi + if [ "$PRINCIPAL_ID" -ne "$ANONYMOUS_PRINCIPAL_ID" ]; then + echo "IDs did not match: Principal '${ANONYMOUS_PRINCIPAL_ID}' != Sender '${PRINCIPAL_ID}'..." | fail + fi - dfx canister create e2e_project_backend --identity jose - dfx build e2e_project_backend --identity jose - dfx canister install e2e_project_backend --identity jose + dfx canister create e2e_project_backend --identity jose + dfx build e2e_project_backend --identity jose + dfx canister install e2e_project_backend --identity jose - SENDER_ID=$(dfx canister call e2e_project_backend fromCall --identity anonymous) + SENDER_ID=$(dfx canister call e2e_project_backend fromCall --identity anonymous) - if [ "$ANONYMOUS_PRINCIPAL_ID" -ne "$SENDER_ID" ]; then - echo "IDs did not match: Principal '${ANONYMOUS_PRINCIPAL_ID}' != Sender '${SENDER_ID}'..." | fail - fi + if [ "$ANONYMOUS_PRINCIPAL_ID" -ne "$SENDER_ID" ]; then + echo "IDs did not match: Principal '${ANONYMOUS_PRINCIPAL_ID}' != Sender '${SENDER_ID}'..." | fail + fi } @test "calls and query receive the same principal from dfx" { - install_asset identity - dfx_start - dfx canister create --all - assert_command dfx build - assert_command dfx canister install --all - - ID_CALL=$(dfx canister call e2e_project_backend fromCall) - ID_QUERY=$(dfx canister call e2e_project_backend fromQuery) - if [ "$ID_CALL" -ne "$ID_QUERY" ]; then - echo "IDs did not match: call '${ID_CALL}' != query '${ID_QUERY}'..." | fail - fi - - ID=$(dfx canister call e2e_project_backend getCanisterId) - assert_command dfx canister call e2e_project_backend isMyself "$ID" - assert_eq '(true)' - assert_command dfx canister call e2e_project_backend isMyself "$ID_CALL" - assert_eq '(false)' + install_asset identity + dfx_start + dfx canister create --all + assert_command dfx build + assert_command dfx canister install --all + + ID_CALL=$(dfx canister call e2e_project_backend fromCall) + ID_QUERY=$(dfx canister call e2e_project_backend fromQuery) + if [ "$ID_CALL" -ne "$ID_QUERY" ]; then + echo "IDs did not match: call '${ID_CALL}' != query '${ID_QUERY}'..." | fail + fi + + ID=$(dfx canister call e2e_project_backend getCanisterId) + assert_command dfx canister call e2e_project_backend isMyself "$ID" + assert_eq '(true)' + assert_command dfx canister call e2e_project_backend isMyself "$ID_CALL" + assert_eq '(false)' } @test "dfx ping does not create a default identity" { - dfx_start + dfx_start - assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity.json" - assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" + assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity.json" + assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" - assert_command dfx ping + assert_command dfx ping - assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity.json" - assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" + assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity.json" + assert_file_not_exists "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" - # shellcheck disable=SC2154 - assert_not_match 'Creating' "$stderr" - # shellcheck disable=SC2154 - assert_not_match '(default.*identity|identity.*default)' "$stderr" - # shellcheck disable=SC2154 - assert_match "ic_api_version" "$stdout" + # shellcheck disable=SC2154 + assert_not_match 'Creating' "$stderr" + # shellcheck disable=SC2154 + assert_not_match '(default.*identity|identity.*default)' "$stderr" + # shellcheck disable=SC2154 + assert_match "ic_api_version" "$stdout" } @test "dfx canister: creates the default identity on first run" { - install_asset identity - dfx_start - assert_command dfx canister create e2e_project_backend - assert_match 'Creating the "default" identity.' "$stderr" + install_asset identity + dfx_start + assert_command dfx canister create e2e_project_backend + assert_match 'Creating the "default" identity.' "$stderr" } @test "after using a specific identity while creating a canister, that user is the initializer" { - install_asset identity - dfx_start - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - - dfx canister create --all --identity alice - assert_command dfx build --identity alice - assert_command dfx canister install --all --identity alice - - # The user Identity's principal is the initializer - assert_command dfx canister call e2e_project_backend amInitializer --identity alice - assert_eq '(true)' - - assert_command dfx canister call e2e_project_backend amInitializer --identity bob - assert_eq '(false)' - - # these all fail (other identities are not initializer; cannot store assets): - assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity bob - assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity default - assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' - assert_command_fail dfx canister call e2e_project_frontend retrieve '("B")' - - # but alice, the initializer, can store assets: - assert_command dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity alice - assert_eq '()' - assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' - assert_eq '(blob "XWV")' + install_asset identity + dfx_start + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + + dfx canister create --all --identity alice + assert_command dfx build --identity alice + assert_command dfx canister install --all --identity alice + + # The user Identity's principal is the initializer + assert_command dfx canister call e2e_project_backend amInitializer --identity alice + assert_eq '(true)' + + assert_command dfx canister call e2e_project_backend amInitializer --identity bob + assert_eq '(false)' + + # these all fail (other identities are not initializer; cannot store assets): + assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity bob + assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity default + assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' + assert_command_fail dfx canister call e2e_project_frontend retrieve '("B")' + + # but alice, the initializer, can store assets: + assert_command dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity alice + assert_eq '()' + assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' + assert_eq '(blob "XWV")' } @test "after renaming an identity, the renamed identity is still initializer" { - install_asset identity - dfx_start - assert_command dfx identity new --storage-mode plaintext alice - - dfx canister create --all --identity alice - assert_command dfx build --identity alice - assert_command dfx canister install --all --identity alice - assert_command dfx canister call e2e_project_backend amInitializer --identity alice - assert_eq '(true)' - assert_command dfx canister call e2e_project_backend amInitializer - assert_eq '(false)' - - assert_command dfx identity rename alice bob - - assert_command dfx identity whoami - assert_eq 'default' - assert_command dfx canister call e2e_project_backend amInitializer --identity bob - assert_eq '(true)' - - assert_command dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob "hello"})' --identity bob - assert_eq '()' - assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' - assert_eq '(blob "hello")' + install_asset identity + dfx_start + assert_command dfx identity new --storage-mode plaintext alice + + dfx canister create --all --identity alice + assert_command dfx build --identity alice + assert_command dfx canister install --all --identity alice + assert_command dfx canister call e2e_project_backend amInitializer --identity alice + assert_eq '(true)' + assert_command dfx canister call e2e_project_backend amInitializer + assert_eq '(false)' + + assert_command dfx identity rename alice bob + + assert_command dfx identity whoami + assert_eq 'default' + assert_command dfx canister call e2e_project_backend amInitializer --identity bob + assert_eq '(true)' + + assert_command dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob "hello"})' --identity bob + assert_eq '()' + assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' + assert_eq '(blob "hello")' } @test "using an unencrypted identity on mainnet provokes a warning" { - assert_command dfx ledger balance --network ic - assert_match "WARN: The default identity is not stored securely." "$stderr" - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/get_ledger_balance.exp" - dfx identity new bob --storage-mode plaintext - assert_command dfx ledger balance --network ic --identity bob - assert_match "WARN: The bob identity is not stored securely." "$stderr" - - export DFX_WARNING=-mainnet_plaintext_identity - assert_command dfx ledger balance --network ic --identity bob - assert_not_contains "not stored securely" "$stderr" + assert_command dfx ledger balance --network ic + assert_match "WARN: The default identity is not stored securely." "$stderr" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/get_ledger_balance.exp" + dfx identity new bob --storage-mode plaintext + assert_command dfx ledger balance --network ic --identity bob + assert_match "WARN: The bob identity is not stored securely." "$stderr" + + export DFX_WARNING=-mainnet_plaintext_identity + assert_command dfx ledger balance --network ic --identity bob + assert_not_contains "not stored securely" "$stderr" } diff --git a/e2e/tests-dfx/identity_command.bash b/e2e/tests-dfx/identity_command.bash index dd5cea5649..f02119f122 100644 --- a/e2e/tests-dfx/identity_command.bash +++ b/e2e/tests-dfx/identity_command.bash @@ -3,12 +3,12 @@ load ../utils/_ setup() { - standard_setup - export DFX_CI_MOCK_KEYRING_LOCATION="$MOCK_KEYRING_LOCATION" + standard_setup + export DFX_CI_MOCK_KEYRING_LOCATION="$MOCK_KEYRING_LOCATION" } teardown() { - standard_teardown + standard_teardown } ## @@ -16,15 +16,15 @@ teardown() { ## @test "identity get-principal: different identities have different principal ids" { - assert_command dfx identity new jose - assert_command dfx identity new juana + assert_command dfx identity new jose + assert_command dfx identity new juana - PRINCIPAL_ID_JOSE=$(dfx identity get-principal --identity jose) - PRINCIPAL_ID_JUANA=$(dfx identity get-principal --identity juana) + PRINCIPAL_ID_JOSE=$(dfx identity get-principal --identity jose) + PRINCIPAL_ID_JUANA=$(dfx identity get-principal --identity juana) - if [ "$PRINCIPAL_ID_JOSE" -eq "$PRINCIPAL_ID_JUANA" ]; then - echo "IDs should not match: Jose '${PRINCIPAL_ID_JOSE}' == Juana '${PRINCIPAL_ID_JUANA}'..." | fail - fi + if [ "$PRINCIPAL_ID_JOSE" -eq "$PRINCIPAL_ID_JUANA" ]; then + echo "IDs should not match: Jose '${PRINCIPAL_ID_JOSE}' == Juana '${PRINCIPAL_ID_JUANA}'..." | fail + fi } ## @@ -32,21 +32,21 @@ teardown() { ## @test "identity list: shows identities in alpha order" { - assert_command dfx identity new dan - assert_command dfx identity new frank - assert_command dfx identity new alice - assert_command dfx identity new bob - assert_command dfx identity list - assert_match \ + assert_command dfx identity new dan + assert_command dfx identity new frank + assert_command dfx identity new alice + assert_command dfx identity new bob + assert_command dfx identity list + assert_match \ 'alice anonymous bob dan default frank' - assert_command dfx identity new charlie - assert_command dfx identity list - assert_match \ + assert_command dfx identity new charlie + assert_command dfx identity list + assert_match \ 'alice anonymous bob @@ -57,16 +57,16 @@ frank' } @test "identity list: shows the anonymous identity" { - assert_command dfx identity list - # shellcheck disable=SC2154 - assert_match 'anonymous' "$stdout" + assert_command dfx identity list + # shellcheck disable=SC2154 + assert_match 'anonymous' "$stdout" } @test "identity list: shows the default identity" { - assert_command dfx identity list - assert_match 'default' "$stdout" - # shellcheck disable=SC2154 - assert_match 'Creating the "default" identity.' "$stderr" + assert_command dfx identity list + assert_match 'default' "$stdout" + # shellcheck disable=SC2154 + assert_match 'Creating the "default" identity.' "$stderr" } ## @@ -74,76 +74,76 @@ frank' ## @test "identity new: creates a new keyring identity" { - assert_command dfx identity new alice - assert_match 'Created identity: "alice".' "$stderr" - assert_command cat "$MOCK_KEYRING_LOCATION" - assert_match "internet_computer_identity_alice" + assert_command dfx identity new alice + assert_match 'Created identity: "alice".' "$stderr" + assert_command cat "$MOCK_KEYRING_LOCATION" + assert_match "internet_computer_identity_alice" - # does not change the default identity - assert_command dfx identity whoami - assert_eq 'default' + # does not change the default identity + assert_command dfx identity whoami + assert_eq 'default' } @test "identity new --storage-mode plaintext: creates a new identity" { - assert_command dfx identity new alice --storage-mode plaintext - assert_match 'Created identity: "alice".' "$stderr" - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_match "BEGIN EC PRIVATE KEY" + assert_command dfx identity new alice --storage-mode plaintext + assert_match 'Created identity: "alice".' "$stderr" + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_match "BEGIN EC PRIVATE KEY" - # does not change the default identity - assert_command dfx identity whoami - assert_eq 'default' + # does not change the default identity + assert_command dfx identity whoami + assert_eq 'default' } @test "identity new: cannot create an identity called anonymous" { - assert_command_fail dfx identity new anonymous + assert_command_fail dfx identity new anonymous } @test "identity new: cannot create an identity that already exists" { - assert_command dfx identity new bob - assert_command_fail dfx identity new bob - assert_match "Identity already exists" + assert_command dfx identity new bob + assert_command_fail dfx identity new bob + assert_match "Identity already exists" } @test "identity new: --force re-creates an identity" { - assert_command dfx identity new alice - dfx identity use alice - PRINCIPAL_1="$(dfx identity get-principal)" - assert_command dfx identity new --force alice - PRINCIPAL_2="$(dfx identity get-principal)" - assert_neq "$PRINCIPAL_1" "$PRINCIPAL_2" + assert_command dfx identity new alice + dfx identity use alice + PRINCIPAL_1="$(dfx identity get-principal)" + assert_command dfx identity new --force alice + PRINCIPAL_2="$(dfx identity get-principal)" + assert_neq "$PRINCIPAL_1" "$PRINCIPAL_2" } @test "identity new: --force does not switch to created identity" { - # Was a bug: https://dfinity.atlassian.net/browse/SDK-911 - assert_command dfx identity new --force alice - PRINCIPAL_ORIGINAL="$(dfx identity get-principal)" - assert_command dfx identity use alice - PRINCIPAL_ALICE="$(dfx identity get-principal)" - assert_neq "$PRINCIPAL_ORIGINAL" "$PRINCIPAL_ALICE" + # Was a bug: https://dfinity.atlassian.net/browse/SDK-911 + assert_command dfx identity new --force alice + PRINCIPAL_ORIGINAL="$(dfx identity get-principal)" + assert_command dfx identity use alice + PRINCIPAL_ALICE="$(dfx identity get-principal)" + assert_neq "$PRINCIPAL_ORIGINAL" "$PRINCIPAL_ALICE" } @test "identity new: create an HSM-backed identity" { - assert_command dfx identity new --hsm-pkcs11-lib-path /something/else/somewhere.so --hsm-key-id abcd4321 bob - assert_command jq -r .hsm.pkcs11_lib_path "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" - assert_eq "/something/else/somewhere.so" - assert_command jq -r .hsm.key_id "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" - assert_eq "abcd4321" + assert_command dfx identity new --hsm-pkcs11-lib-path /something/else/somewhere.so --hsm-key-id abcd4321 bob + assert_command jq -r .hsm.pkcs11_lib_path "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" + assert_eq "/something/else/somewhere.so" + assert_command jq -r .hsm.key_id "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" + assert_eq "abcd4321" } @test "identity new: key_id must be hex digits" { - assert_command_fail dfx identity new --hsm-pkcs11-lib-path xxx --hsm-key-id abcx bob - assert_match "Key id must contain only hex digits" + assert_command_fail dfx identity new --hsm-pkcs11-lib-path xxx --hsm-key-id abcx bob + assert_match "Key id must contain only hex digits" } @test "identity new: key_id must be an even number of digits" { - assert_command_fail dfx identity new --hsm-pkcs11-lib-path xxx --hsm-key-id fed64 bob - assert_match "Key id must consist of an even number of hex digits" + assert_command_fail dfx identity new --hsm-pkcs11-lib-path xxx --hsm-key-id fed64 bob + assert_match "Key id must consist of an even number of hex digits" } @test "identity new: key is compatible with openssl" { - assert_command dfx identity new --storage-mode plaintext bob - assert_command openssl ec -in "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" + assert_command dfx identity new --storage-mode plaintext bob + assert_command openssl ec -in "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" } ## @@ -151,99 +151,99 @@ frank' ## @test "identity remove: can remove an identity that exists" { - assert_command_fail cat "$MOCK_KEYRING_LOCATION" - assert_command dfx identity new alice + assert_command_fail cat "$MOCK_KEYRING_LOCATION" + assert_command dfx identity new alice - assert_command cat "$MOCK_KEYRING_LOCATION" - assert_match "internet_computer_identity_alice" - assert_command dfx identity list - assert_match \ + assert_command cat "$MOCK_KEYRING_LOCATION" + assert_match "internet_computer_identity_alice" + assert_command dfx identity list + assert_match \ 'alice anonymous default' - assert_command dfx identity remove alice - assert_match 'Removed identity "alice".' "$stderr" - assert_command cat "$MOCK_KEYRING_LOCATION" - assert_not_match "internet_computer_identity_alice" + assert_command dfx identity remove alice + assert_match 'Removed identity "alice".' "$stderr" + assert_command cat "$MOCK_KEYRING_LOCATION" + assert_not_match "internet_computer_identity_alice" - assert_command dfx identity list - assert_match 'default' + assert_command dfx identity list + assert_match 'default' } @test "identity remove --storage-mode plaintext: can remove an identity that exists" { - assert_command_fail head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_command dfx identity new alice --storage-mode plaintext + assert_command_fail head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_command dfx identity new alice --storage-mode plaintext - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_match "BEGIN EC PRIVATE KEY" - assert_command dfx identity list - assert_match \ + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_match "BEGIN EC PRIVATE KEY" + assert_command dfx identity list + assert_match \ 'alice anonymous default' - assert_command dfx identity remove alice - assert_match 'Removed identity "alice".' "$stderr" - assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_command dfx identity remove alice + assert_match 'Removed identity "alice".' "$stderr" + assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_command dfx identity list - assert_match 'default' + assert_command dfx identity list + assert_match 'default' } @test "identity remove: reports an error if no such identity" { - assert_command_fail dfx identity remove charlie + assert_command_fail dfx identity remove charlie } @test "identity remove: only remove identities with configured wallet if --drop-wallets is specified" { - # There's no replica running, and no real wallet. This is just a valid principal. - WALLET="rwlgt-iiaaa-aaaaa-aaaaa-cai" - assert_command dfx identity new alice - assert_command dfx identity use alice - assert_command dfx identity set-wallet --force "$WALLET" --network ic - assert_command dfx identity use default - assert_command_fail dfx identity remove alice - # make sure the configured wallet is displayed - assert_match "identity 'alice' on network 'ic' has wallet $WALLET" - assert_command dfx identity remove alice --drop-wallets - assert_match "identity 'alice' on network 'ic' has wallet $WALLET" + # There's no replica running, and no real wallet. This is just a valid principal. + WALLET="rwlgt-iiaaa-aaaaa-aaaaa-cai" + assert_command dfx identity new alice + assert_command dfx identity use alice + assert_command dfx identity set-wallet --force "$WALLET" --network ic + assert_command dfx identity use default + assert_command_fail dfx identity remove alice + # make sure the configured wallet is displayed + assert_match "identity 'alice' on network 'ic' has wallet $WALLET" + assert_command dfx identity remove alice --drop-wallets + assert_match "identity 'alice' on network 'ic' has wallet $WALLET" } @test "identity remove: cannot remove the non-default active identity" { - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity use alice - assert_command_fail dfx identity remove alice - - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_match "BEGIN EC PRIVATE KEY" - assert_command dfx identity list - assert_match \ + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity use alice + assert_command_fail dfx identity remove alice + + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_match "BEGIN EC PRIVATE KEY" + assert_command dfx identity list + assert_match \ 'alice anonymous default' } @test "identity remove: cannot remove the default identity" { - # a new one will just get created again - assert_command_fail dfx identity remove default - assert_match "Cannot delete the default identity" + # a new one will just get created again + assert_command_fail dfx identity remove default + assert_match "Cannot delete the default identity" } @test "identity remove: cannot remove the anonymous identity" { - assert_command_fail dfx identity remove anonymous + assert_command_fail dfx identity remove anonymous } @test "identity remove: can remove an HSM-backed identity" { - assert_command dfx identity new --hsm-pkcs11-lib-path /something/else/somewhere.so --hsm-key-id abcd4321 bob - assert_command jq -r .hsm.pkcs11_lib_path "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" - assert_eq "/something/else/somewhere.so" - assert_command jq -r .hsm.key_id "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" - assert_eq "abcd4321" - assert_command ls "$DFX_CONFIG_ROOT/.config/dfx/identity/bob" + assert_command dfx identity new --hsm-pkcs11-lib-path /something/else/somewhere.so --hsm-key-id abcd4321 bob + assert_command jq -r .hsm.pkcs11_lib_path "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" + assert_eq "/something/else/somewhere.so" + assert_command jq -r .hsm.key_id "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.json" + assert_eq "abcd4321" + assert_command ls "$DFX_CONFIG_ROOT/.config/dfx/identity/bob" - assert_command dfx identity remove bob - assert_command_fail ls "$DFX_CONFIG_ROOT/.config/dfx/identity/bob" + assert_command dfx identity remove bob + assert_command_fail ls "$DFX_CONFIG_ROOT/.config/dfx/identity/bob" } ## @@ -251,110 +251,110 @@ default' ## @test "identity rename: can rename an identity" { - assert_command dfx identity new alice - assert_command dfx identity list - assert_match \ + assert_command dfx identity new alice + assert_command dfx identity list + assert_match \ 'alice anonymous default' - assert_command cat "$MOCK_KEYRING_LOCATION" - assert_match "internet_computer_identity_alice" - KEY="$(dfx identity export alice)" + assert_command cat "$MOCK_KEYRING_LOCATION" + assert_match "internet_computer_identity_alice" + KEY="$(dfx identity export alice)" - assert_command dfx identity rename alice bob - assert_match 'Renamed identity "alice" to "bob".' "$stderr" + assert_command dfx identity rename alice bob + assert_match 'Renamed identity "alice" to "bob".' "$stderr" - assert_command dfx identity list - assert_match \ + assert_command dfx identity list + assert_match \ 'anonymous bob default' - assert_command cat "$MOCK_KEYRING_LOCATION" - assert_match "internet_computer_identity_bob" - assert_eq "$KEY" "$(dfx identity export bob)" - assert_command cat "$MOCK_KEYRING_LOCATION" - assert_not_match "internet_computer_identity_alice" + assert_command cat "$MOCK_KEYRING_LOCATION" + assert_match "internet_computer_identity_bob" + assert_eq "$KEY" "$(dfx identity export bob)" + assert_command cat "$MOCK_KEYRING_LOCATION" + assert_not_match "internet_computer_identity_alice" } @test "identity rename --storage-mode plaintext: can rename an identity" { - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity list - assert_match \ + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity list + assert_match \ 'alice anonymous default' - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_match "BEGIN EC PRIVATE KEY" - x=$(cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem") - KEY="$x" + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_match "BEGIN EC PRIVATE KEY" + x=$(cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem") + KEY="$x" - assert_command dfx identity rename alice bob - assert_match 'Renamed identity "alice" to "bob".' "$stderr" + assert_command dfx identity rename alice bob + assert_match 'Renamed identity "alice" to "bob".' "$stderr" - assert_command dfx identity list - assert_match \ + assert_command dfx identity list + assert_match \ 'anonymous bob default' - assert_command cat "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" - assert_eq "$KEY" "$(cat "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem")" - assert_match "BEGIN EC PRIVATE KEY" - assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_command cat "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" + assert_eq "$KEY" "$(cat "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem")" + assert_match "BEGIN EC PRIVATE KEY" + assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" } @test "identity rename: can rename the default identity, which also changes the default" { - assert_command dfx identity list - assert_match 'default' - assert_command dfx identity rename default bob - assert_command dfx identity list - assert_match 'bob' - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" - assert_match "BEGIN EC PRIVATE KEY" + assert_command dfx identity list + assert_match 'default' + assert_command dfx identity rename default bob + assert_command dfx identity list + assert_match 'bob' + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" + assert_match "BEGIN EC PRIVATE KEY" - assert_command dfx identity whoami - assert_eq 'bob' + assert_command dfx identity whoami + assert_eq 'bob' } @test "identity rename: can rename the selected identity, which also changes the default" { - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity use alice - assert_command dfx identity list - assert_match \ + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity use alice + assert_command dfx identity list + assert_match \ 'alice anonymous default' - assert_command dfx identity rename alice charlie + assert_command dfx identity rename alice charlie - assert_command dfx identity list - assert_match \ + assert_command dfx identity list + assert_match \ 'anonymous charlie default' - assert_command dfx identity whoami - assert_eq 'charlie' + assert_command dfx identity whoami + assert_eq 'charlie' - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/charlie/identity.pem" - assert_match "BEGIN EC PRIVATE KEY" - assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/charlie/identity.pem" + assert_match "BEGIN EC PRIVATE KEY" + assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" } @test "identity rename: cannot create an anonymous identity via rename" { assert_command dfx identity new alice - assert_command_fail dfx identity rename alice anonymous - assert_match "Cannot create an anonymous identity" + assert_command_fail dfx identity rename alice anonymous + assert_match "Cannot create an anonymous identity" } @test "identity rename: can rename an HSM-backed identity" { - skip "Need to instantiate identity when renaming so skipping until we have an hsm mock" - assert_command dfx identity new --hsm-pkcs11-lib-path /something/else/somewhere.so --hsm-key-id abcd4321 bob - assert_command dfx identity rename bob alice - assert_command_fail ls "$DFX_CONFIG_ROOT/.config/dfx/identity/bob" + skip "Need to instantiate identity when renaming so skipping until we have an hsm mock" + assert_command dfx identity new --hsm-pkcs11-lib-path /something/else/somewhere.so --hsm-key-id abcd4321 bob + assert_command dfx identity rename bob alice + assert_command_fail ls "$DFX_CONFIG_ROOT/.config/dfx/identity/bob" - assert_command jq -r .hsm.pkcs11_lib_path "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.json" - assert_eq "/something/else/somewhere.so" - assert_command jq -r .hsm.key_id "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.json" - assert_eq "abcd4321" + assert_command jq -r .hsm.pkcs11_lib_path "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.json" + assert_eq "/something/else/somewhere.so" + assert_command jq -r .hsm.key_id "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.json" + assert_eq "abcd4321" } ## @@ -362,46 +362,46 @@ default' ## @test "identity use: switches to an existing identity" { - assert_command dfx identity new alice - assert_command dfx identity whoami - assert_eq 'default' - assert_command dfx identity use alice - assert_command dfx identity whoami - assert_eq 'alice' + assert_command dfx identity new alice + assert_command dfx identity whoami + assert_eq 'default' + assert_command dfx identity use alice + assert_command dfx identity whoami + assert_eq 'alice' - ## and back - assert_command dfx identity use default - assert_command dfx identity whoami - assert_eq 'default' + ## and back + assert_command dfx identity use default + assert_command dfx identity whoami + assert_eq 'default' } @test "identity use: cannot use an identity that has not been created yet" { - assert_command_fail dfx identity use alice - assert_command dfx identity whoami - assert_eq 'default' + assert_command_fail dfx identity use alice + assert_command dfx identity whoami + assert_eq 'default' } @test "identity use: can switch to the anonymous identity" { - assert_command dfx identity use anonymous - assert_command dfx identity whoami - assert_eq 'anonymous' - assert_command dfx identity get-principal - assert_eq '2vxsx-fae' + assert_command dfx identity use anonymous + assert_command dfx identity whoami + assert_eq 'anonymous' + assert_command dfx identity get-principal + assert_eq '2vxsx-fae' } @test "identity use: is overridden by env var DFX_IDENTITY" { - assert_command dfx identity new dan - assert_command dfx identity new frank - assert_command dfx identity new alice - assert_command dfx identity use dan - assert_command dfx identity whoami - assert_eq 'dan' - DFX_IDENTITY=frank - export DFX_IDENTITY - assert_command dfx identity whoami - assert_eq 'frank' - assert_command dfx identity whoami --identity alice - assert_eq 'alice' + assert_command dfx identity new dan + assert_command dfx identity new frank + assert_command dfx identity new alice + assert_command dfx identity use dan + assert_command dfx identity whoami + assert_eq 'dan' + DFX_IDENTITY=frank + export DFX_IDENTITY + assert_command dfx identity whoami + assert_eq 'frank' + assert_command dfx identity whoami --identity alice + assert_eq 'alice' } @@ -410,165 +410,165 @@ default' ## @test "identity whoami: creates the default identity on first run" { - # Just an example. All the identity commands do this. - assert_command dfx identity whoami - assert_eq 'default' "$stdout" - assert_match 'Creating the "default" identity.' "$stderr" - assert_match 'Created the "default" identity.' "$stderr" + # Just an example. All the identity commands do this. + assert_command dfx identity whoami + assert_eq 'default' "$stdout" + assert_match 'Creating the "default" identity.' "$stderr" + assert_match 'Created the "default" identity.' "$stderr" } @test "identity whoami: shows the current identity" { - assert_command dfx identity whoami - assert_eq 'default' "$stdout" - assert_command dfx identity new charlie - assert_command dfx identity whoami - assert_eq 'default' - assert_command dfx identity use charlie - assert_command dfx identity whoami - assert_eq 'charlie' + assert_command dfx identity whoami + assert_eq 'default' "$stdout" + assert_command dfx identity new charlie + assert_command dfx identity whoami + assert_eq 'default' + assert_command dfx identity use charlie + assert_command dfx identity whoami + assert_eq 'charlie' } ## dfx (+other commands) --identity @test "dfx identity whoami --identity (name): shows the overriding identity" { - assert_command dfx identity whoami - assert_eq 'default' "$stdout" - assert_command dfx identity new charlie - assert_command dfx identity new alice - assert_command dfx identity whoami --identity charlie - assert_eq 'charlie' - assert_command dfx identity whoami --identity alice - assert_eq 'alice' + assert_command dfx identity whoami + assert_eq 'default' "$stdout" + assert_command dfx identity new charlie + assert_command dfx identity new alice + assert_command dfx identity whoami --identity charlie + assert_eq 'charlie' + assert_command dfx identity whoami --identity alice + assert_eq 'alice' } @test "dfx (command) --identity does not persistently change the selected identity" { - assert_command dfx identity whoami - assert_eq 'default' "$stdout" - assert_command dfx identity new charlie - assert_command dfx identity new alice - assert_command dfx identity use charlie - assert_command dfx identity whoami - assert_eq 'charlie' - assert_command dfx identity whoami --identity alice - assert_eq 'alice' - assert_command dfx identity whoami - assert_eq 'charlie' + assert_command dfx identity whoami + assert_eq 'default' "$stdout" + assert_command dfx identity new charlie + assert_command dfx identity new alice + assert_command dfx identity use charlie + assert_command dfx identity whoami + assert_eq 'charlie' + assert_command dfx identity whoami --identity alice + assert_eq 'alice' + assert_command dfx identity whoami + assert_eq 'charlie' } ## ## Identity key migration ## @test "identity manager copies existing key from $DFX_CONFIG_ROOT/.dfinity/identity/creds.pem" { - assert_command dfx identity whoami - assert_command mkdir -p "$DFX_CONFIG_ROOT/.dfinity/identity" - assert_command mv "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" "$DFX_CONFIG_ROOT/.dfinity/identity/creds.pem" - ORIGINAL_KEY=$(cat "$DFX_CONFIG_ROOT/.dfinity/identity/creds.pem") - assert_command rmdir "$DFX_CONFIG_ROOT/.config/dfx/identity/default" - assert_command rmdir "$DFX_CONFIG_ROOT/.config/dfx/identity" - assert_command rm "$DFX_CONFIG_ROOT/.config/dfx/identity.json" - assert_command rmdir "$DFX_CONFIG_ROOT/.config/dfx" - assert_command rmdir "$DFX_CONFIG_ROOT/.config" + assert_command dfx identity whoami + assert_command mkdir -p "$DFX_CONFIG_ROOT/.dfinity/identity" + assert_command mv "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" "$DFX_CONFIG_ROOT/.dfinity/identity/creds.pem" + ORIGINAL_KEY=$(cat "$DFX_CONFIG_ROOT/.dfinity/identity/creds.pem") + assert_command rmdir "$DFX_CONFIG_ROOT/.config/dfx/identity/default" + assert_command rmdir "$DFX_CONFIG_ROOT/.config/dfx/identity" + assert_command rm "$DFX_CONFIG_ROOT/.config/dfx/identity.json" + assert_command rmdir "$DFX_CONFIG_ROOT/.config/dfx" + assert_command rmdir "$DFX_CONFIG_ROOT/.config" - assert_command dfx identity whoami + assert_command dfx identity whoami - assert_match "migrating key from" - assert_eq "$(cat "$DFX_CONFIG_ROOT"/.config/dfx/identity/default/identity.pem)" "$ORIGINAL_KEY" + assert_match "migrating key from" + assert_eq "$(cat "$DFX_CONFIG_ROOT"/.config/dfx/identity/default/identity.pem)" "$ORIGINAL_KEY" } @test "identity: import" { - openssl ecparam -name secp256k1 -genkey -out identity.pem - assert_command dfx identity import alice identity.pem - assert_match 'Imported identity: "alice".' "$stderr" - assert_command bash -c "dfx identity export alice > alice.pem" - assert_command diff identity.pem alice.pem - assert_eq "" + openssl ecparam -name secp256k1 -genkey -out identity.pem + assert_command dfx identity import alice identity.pem + assert_match 'Imported identity: "alice".' "$stderr" + assert_command bash -c "dfx identity export alice > alice.pem" + assert_command diff identity.pem alice.pem + assert_eq "" } @test "identity: import can only overwrite identity with --force" { - openssl ecparam -name secp256k1 -genkey -out identity.pem - openssl ecparam -name secp256k1 -genkey -out identity2.pem - assert_command dfx identity import alice identity.pem - assert_match 'Imported identity: "alice".' "$stderr" - dfx identity use alice - PRINCIPAL_1="$(dfx identity get-principal)" + openssl ecparam -name secp256k1 -genkey -out identity.pem + openssl ecparam -name secp256k1 -genkey -out identity2.pem + assert_command dfx identity import alice identity.pem + assert_match 'Imported identity: "alice".' "$stderr" + dfx identity use alice + PRINCIPAL_1="$(dfx identity get-principal)" - assert_command_fail dfx identity import alice identity2.pem - assert_match "Identity already exists." - assert_command dfx identity import --force alice identity2.pem - assert_match 'Imported identity: "alice".' - PRINCIPAL_2="$(dfx identity get-principal)" + assert_command_fail dfx identity import alice identity2.pem + assert_match "Identity already exists." + assert_command dfx identity import --force alice identity2.pem + assert_match 'Imported identity: "alice".' + PRINCIPAL_2="$(dfx identity get-principal)" - assert_neq "$PRINCIPAL_1" "$PRINCIPAL_2" + assert_neq "$PRINCIPAL_1" "$PRINCIPAL_2" } @test "identity: import default" { - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity import bob "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_match 'Imported identity: "bob".' "$stderr" - assert_command bash -c "dfx identity export bob > bob.pem" - assert_command diff "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" "bob.pem" - assert_eq "" + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity import bob "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_match 'Imported identity: "bob".' "$stderr" + assert_command bash -c "dfx identity export bob > bob.pem" + assert_command diff "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" "bob.pem" + assert_eq "" } @test "identity: import --storage-mode plaintext" { - assert_command dfx identity new alice --storage-mode plaintext - assert_command dfx identity import bob "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" --storage-mode plaintext - assert_match 'Imported identity: "bob".' "$stderr" - assert_command diff "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" - assert_eq "" + assert_command dfx identity new alice --storage-mode plaintext + assert_command dfx identity import bob "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" --storage-mode plaintext + assert_match 'Imported identity: "bob".' "$stderr" + assert_command diff "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem" + assert_eq "" } @test "identity: cannot import invalid PEM file" { - assert_command dfx identity new alice --storage-mode plaintext - assert_command cp "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" ./alice.pem - # Following 3 lines manipulate the pem file so that it will be invalid - head -n 1 alice.pem > bob.pem - echo -n 1 >> bob.pem - tail -n 3 alice.pem > bob.pem - assert_command_fail dfx identity import bob bob.pem - assert_match 'Failed to validate PEM content' "$stderr" + assert_command dfx identity new alice --storage-mode plaintext + assert_command cp "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" ./alice.pem + # Following 3 lines manipulate the pem file so that it will be invalid + head -n 1 alice.pem > bob.pem + echo -n 1 >> bob.pem + tail -n 3 alice.pem > bob.pem + assert_command_fail dfx identity import bob bob.pem + assert_match 'Failed to validate PEM content' "$stderr" } @test "identity: can import an EC key without an EC PARAMETERS section (as quill generate makes)" { - cat >private-key-no-ec-parameters.pem <private-key-no-ec-parameters.pem <dfx.json # avoid "dfx.json not found, using default." - assert_command dfx ledger account-id --identity private-key-no-ec-parameters - assert_eq "3c00cf85d77b9dbf74a2acec1d9a9e73a3fc65f5048c64800b15f3b2c4c8eb11" + assert_command dfx identity import private-key-no-ec-parameters private-key-no-ec-parameters.pem + assert_command dfx identity get-principal --identity private-key-no-ec-parameters + assert_eq "j4p4p-o5ogq-4gzev-t3kay-hpm5o-xuwpz-yvrpp-47cc4-qyunt-k76yw-qae" + echo "{}" >dfx.json # avoid "dfx.json not found, using default." + assert_command dfx ledger account-id --identity private-key-no-ec-parameters + assert_eq "3c00cf85d77b9dbf74a2acec1d9a9e73a3fc65f5048c64800b15f3b2c4c8eb11" } @test "identity: can export and re-import an identity" { - assert_command dfx identity new alice - dfx identity export alice > export.pem - assert_file_exists export.pem - assert_command dfx identity import bob export.pem + assert_command dfx identity new alice + dfx identity export alice > export.pem + assert_file_exists export.pem + assert_command dfx identity import bob export.pem } @test "identity: can import a seed phrase" { - reg="seed phrase for identity 'alice': ([a-z ]+)" - assert_command dfx identity new alice - [[ $stderr =~ $reg ]] - echo "${BASH_REMATCH[1]}" >seed.txt - principal=$(dfx identity get-principal --identity alice) - assert_command dfx identity import alice2 --seed-file seed.txt --storage-mode plaintext - assert_command dfx identity get-principal --identity alice2 - assert_eq "$principal" - dfx identity export alice2 > export.pem - assert_command openssl asn1parse -in export.pem - assert_match ':secp256k1' + reg="seed phrase for identity 'alice': ([a-z ]+)" + assert_command dfx identity new alice + [[ $stderr =~ $reg ]] + echo "${BASH_REMATCH[1]}" >seed.txt + principal=$(dfx identity get-principal --identity alice) + assert_command dfx identity import alice2 --seed-file seed.txt --storage-mode plaintext + assert_command dfx identity get-principal --identity alice2 + assert_eq "$principal" + dfx identity export alice2 > export.pem + assert_command openssl asn1parse -in export.pem + assert_match ':secp256k1' } @test "identity: consistently imports a known seed phrase" { - echo "display dawn estate night naive stomach receive lock expose boring square boy deposit mistake volume soldier coil rocket match diamond repair opinion action paddle">seed.txt - assert_command dfx identity import alice --seed-file seed.txt --storage-mode plaintext - assert_command dfx identity get-principal --identity alice - assert_eq "qimd7-lqrvx-kdvsm-7zeqn-bgoix-ukjfi-hgmfg-ur2he-odgb2-joms4-nae" + echo "display dawn estate night naive stomach receive lock expose boring square boy deposit mistake volume soldier coil rocket match diamond repair opinion action paddle">seed.txt + assert_command dfx identity import alice --seed-file seed.txt --storage-mode plaintext + assert_command dfx identity get-principal --identity alice + assert_eq "qimd7-lqrvx-kdvsm-7zeqn-bgoix-ukjfi-hgmfg-ur2he-odgb2-joms4-nae" } diff --git a/e2e/tests-dfx/identity_encryption.bash b/e2e/tests-dfx/identity_encryption.bash index 6f545d659f..b986b9a438 100755 --- a/e2e/tests-dfx/identity_encryption.bash +++ b/e2e/tests-dfx/identity_encryption.bash @@ -3,12 +3,12 @@ load ../utils/_ setup() { - standard_setup - export DFX_CI_USE_PROXY_KEYRING="" + standard_setup + export DFX_CI_USE_PROXY_KEYRING="" } teardown() { - standard_teardown + standard_teardown } # @@ -17,18 +17,18 @@ teardown() { # @test "can create and use identity with password" { - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/create_identity_with_password.exp" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/create_identity_with_password.exp" } @test "wrong password is rejected" { - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/wrong_password_rejected.exp" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/init_alice_with_pw.exp" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/wrong_password_rejected.exp" } @test "import and export identity with a password are inverse operations" { - # key generated using `openssl ecparam -genkey -name secp256k1` - cat >import.pem <import.pem <> postinstall.sh - assert_command_fail dfx canister install postinstall_script --mode upgrade - assert_match 'hello-script' + assert_command dfx canister install postinstall_script + assert_match 'hello-script' + + echo 'return 1' >> postinstall.sh + assert_command_fail dfx canister install postinstall_script --mode upgrade + assert_match 'hello-script' } @test "post-install tasks receive environment variables" { - install_asset post_install - dfx_start - echo "echo hello \$CANISTER_ID" >> postinstall.sh + install_asset post_install + dfx_start + echo "echo hello \$CANISTER_ID" >> postinstall.sh - assert_command dfx canister create --all - assert_command dfx build - id=$(dfx canister id postinstall_script) + assert_command dfx canister create --all + assert_command dfx build + id=$(dfx canister id postinstall_script) - assert_command dfx canister install --all - assert_match "hello $id" - assert_command dfx canister install postinstall_script --mode upgrade - assert_match "hello $id" + assert_command dfx canister install --all + assert_match "hello $id" + assert_command dfx canister install postinstall_script --mode upgrade + assert_match "hello $id" - assert_command dfx deploy - assert_match "hello $id" - assert_command dfx deploy postinstall_script - assert_match "hello $id" + assert_command dfx deploy + assert_match "hello $id" + assert_command dfx deploy postinstall_script + assert_match "hello $id" } @test "post-install tasks discover dependencies" { - install_asset post_install - dfx_start - echo "echo hello \$CANISTER_ID_postinstall" >> postinstall.sh + install_asset post_install + dfx_start + echo "echo hello \$CANISTER_ID_postinstall" >> postinstall.sh + + assert_command dfx canister create --all + assert_command dfx build + id=$(dfx canister id postinstall) - assert_command dfx canister create --all - assert_command dfx build - id=$(dfx canister id postinstall) - - assert_command dfx canister install postinstall_script - assert_match "hello $id" + assert_command dfx canister install postinstall_script + assert_match "hello $id" } @test "can install gzip wasm" { - jq '.canisters.e2e_project_backend.gzip=true' dfx.json | sponge dfx.json - dfx_start - dfx canister create --all - assert_command dfx build - assert_command dfx canister install --all - BUILD_HASH="0x$(sha256sum .dfx/local/canisters/e2e_project_backend/e2e_project_backend.wasm.gz | cut -d " " -f 1)" - ONCHAIN_HASH="$(dfx canister info e2e_project_backend | tail -n 1 | cut -d " " -f 3)" - assert_eq "$BUILD_HASH" "$ONCHAIN_HASH" + jq '.canisters.e2e_project_backend.gzip=true' dfx.json | sponge dfx.json + dfx_start + dfx canister create --all + assert_command dfx build + assert_command dfx canister install --all + BUILD_HASH="0x$(sha256sum .dfx/local/canisters/e2e_project_backend/e2e_project_backend.wasm.gz | cut -d " " -f 1)" + ONCHAIN_HASH="$(dfx canister info e2e_project_backend | tail -n 1 | cut -d " " -f 3)" + assert_eq "$BUILD_HASH" "$ONCHAIN_HASH" } @test "--mode=auto selects install or upgrade automatically" { - dfx_start - assert_command dfx canister create e2e_project_backend - assert_command dfx build e2e_project_backend - assert_command dfx canister install e2e_project_backend --mode auto - assert_command dfx canister call e2e_project_backend greet dfx - assert_command dfx canister install e2e_project_backend --mode auto --upgrade-unchanged - assert_command dfx canister call e2e_project_backend greet dfx + dfx_start + assert_command dfx canister create e2e_project_backend + assert_command dfx build e2e_project_backend + assert_command dfx canister install e2e_project_backend --mode auto + assert_command dfx canister call e2e_project_backend greet dfx + assert_command dfx canister install e2e_project_backend --mode auto --upgrade-unchanged + assert_command dfx canister call e2e_project_backend greet dfx } @test "-y skips compat check" { - dfx_start - assert_command dfx canister create e2e_project_backend - assert_command dfx build e2e_project_backend - assert_command dfx canister install e2e_project_backend - assert_command timeout -s9 20s dfx canister install e2e_project_backend --mode reinstall -y # if -y does not work, hangs without stdin + dfx_start + assert_command dfx canister create e2e_project_backend + assert_command dfx build e2e_project_backend + assert_command dfx canister install e2e_project_backend + assert_command timeout -s9 20s dfx canister install e2e_project_backend --mode reinstall -y # if -y does not work, hangs without stdin } @test "--no-asset-upgrade skips asset upgrade" { - dfx_start - use_asset_wasm 0.12.1 - dfx deploy - assert_command dfx canister info e2e_project_frontend - assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 - use_default_asset_wasm - assert_command dfx canister install e2e_project_frontend --mode upgrade --no-asset-upgrade - assert_command dfx canister info e2e_project_frontend - assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 + dfx_start + use_asset_wasm 0.12.1 + dfx deploy + assert_command dfx canister info e2e_project_frontend + assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 + use_default_asset_wasm + assert_command dfx canister install e2e_project_frontend --mode upgrade --no-asset-upgrade + assert_command dfx canister info e2e_project_frontend + assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 } @test "installing multiple canisters with arguments fails" { - assert_command_fail dfx canister install --all --argument hello - assert_contains "error: the argument '--all' cannot be used with '--argument '" + assert_command_fail dfx canister install --all --argument hello + assert_contains "error: the argument '--all' cannot be used with '--argument '" } diff --git a/e2e/tests-dfx/inter.bash b/e2e/tests-dfx/inter.bash index 29934134a6..3c6e1783a5 100644 --- a/e2e/tests-dfx/inter.bash +++ b/e2e/tests-dfx/inter.bash @@ -3,62 +3,62 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop - # stop_dfx_replica - # stop_dfx_bootstrap - standard_teardown + dfx_stop + # stop_dfx_replica + # stop_dfx_bootstrap + standard_teardown } @test "inter-canister calls" { - dfx_new_rust inter - install_asset inter - dfx_start - dfx deploy + dfx_new_rust inter + install_asset inter + dfx_start + dfx deploy - # calling motoko canister from rust canister - assert_command dfx canister call inter_rs read - assert_match '(0 : nat)' - assert_command dfx canister call inter_rs inc - assert_command dfx canister call inter_rs read - assert_match '(1 : nat)' - assert_command dfx canister call inter_rs write '(5)' - assert_command dfx canister call inter_rs read - assert_match '(5 : nat)' + # calling motoko canister from rust canister + assert_command dfx canister call inter_rs read + assert_match '(0 : nat)' + assert_command dfx canister call inter_rs inc + assert_command dfx canister call inter_rs read + assert_match '(1 : nat)' + assert_command dfx canister call inter_rs write '(5)' + assert_command dfx canister call inter_rs read + assert_match '(5 : nat)' - # calling rust canister from motoko canister - assert_command dfx canister call inter_mo write '(0)' - assert_command dfx canister call inter_mo read - assert_match '(0 : nat)' - assert_command dfx canister call inter_mo inc - assert_command dfx canister call inter_mo read - assert_match '(1 : nat)' - assert_command dfx canister call inter_mo write '(6)' - assert_command dfx canister call inter_mo read - assert_match '(6 : nat)' + # calling rust canister from motoko canister + assert_command dfx canister call inter_mo write '(0)' + assert_command dfx canister call inter_mo read + assert_match '(0 : nat)' + assert_command dfx canister call inter_mo inc + assert_command dfx canister call inter_mo read + assert_match '(1 : nat)' + assert_command dfx canister call inter_mo write '(6)' + assert_command dfx canister call inter_mo read + assert_match '(6 : nat)' - # calling rust canister from rust canister, trough motoko canisters - assert_command dfx canister call inter2_rs write '(0)' - assert_command dfx canister call inter2_rs read - assert_match '(0 : nat)' - assert_command dfx canister call inter2_rs inc - assert_command dfx canister call inter2_rs read - assert_match '(1 : nat)' - assert_command dfx canister call inter2_rs write '(7)' - assert_command dfx canister call inter2_rs read - assert_match '(7 : nat)' + # calling rust canister from rust canister, trough motoko canisters + assert_command dfx canister call inter2_rs write '(0)' + assert_command dfx canister call inter2_rs read + assert_match '(0 : nat)' + assert_command dfx canister call inter2_rs inc + assert_command dfx canister call inter2_rs read + assert_match '(1 : nat)' + assert_command dfx canister call inter2_rs write '(7)' + assert_command dfx canister call inter2_rs read + assert_match '(7 : nat)' - # calling motoko canister from motoko canister, trough rust canisters - assert_command dfx canister call inter2_mo write '(0)' - assert_command dfx canister call inter2_mo read - assert_match '(0 : nat)' - assert_command dfx canister call inter2_mo inc - assert_command dfx canister call inter2_mo read - assert_match '(1 : nat)' - assert_command dfx canister call inter2_mo write '(8)' - assert_command dfx canister call inter2_mo read - assert_match '(8 : nat)' + # calling motoko canister from motoko canister, trough rust canisters + assert_command dfx canister call inter2_mo write '(0)' + assert_command dfx canister call inter2_mo read + assert_match '(0 : nat)' + assert_command dfx canister call inter2_mo inc + assert_command dfx canister call inter2_mo read + assert_match '(1 : nat)' + assert_command dfx canister call inter2_mo write '(8)' + assert_command dfx canister call inter2_mo read + assert_match '(8 : nat)' } diff --git a/e2e/tests-dfx/leak.bash b/e2e/tests-dfx/leak.bash index 82a01b516c..5639f8a991 100644 --- a/e2e/tests-dfx/leak.bash +++ b/e2e/tests-dfx/leak.bash @@ -3,24 +3,24 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "repeated install wasm" { - install_asset custom_canister - install_asset wasm/identity - dfx_start - dfx deploy - for _ in {1..50} - do - echo yes | dfx canister install --mode=reinstall custom - done + install_asset custom_canister + install_asset wasm/identity + dfx_start + dfx deploy + for _ in {1..50} + do + echo yes | dfx canister install --mode=reinstall custom + done } diff --git a/e2e/tests-dfx/ledger.bash b/e2e/tests-dfx/ledger.bash index dc225f3085..6c5590fa9c 100644 --- a/e2e/tests-dfx/ledger.bash +++ b/e2e/tests-dfx/ledger.bash @@ -3,246 +3,246 @@ load ../utils/_ setup() { - standard_setup - install_asset ledger - install_shared_asset subnet_type/shared_network_settings/system + standard_setup + install_asset ledger + install_shared_asset subnet_type/shared_network_settings/system - dfx identity import --storage-mode plaintext alice alice.pem - dfx identity import --storage-mode plaintext bob bob.pem + dfx identity import --storage-mode plaintext alice alice.pem + dfx identity import --storage-mode plaintext bob bob.pem - dfx_start_for_nns_install + dfx_start_for_nns_install - dfx extension install nns || true - dfx nns install --ledger-accounts 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 5a94fe181e9d411c58726cb87cbf2d016241b6c350bc3330e4869ca76e54ecbc + dfx extension install nns || true + dfx nns install --ledger-accounts 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 5a94fe181e9d411c58726cb87cbf2d016241b6c350bc3330e4869ca76e54ecbc } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } current_time_nanoseconds() { - echo "$(date +%s)"000000000 + echo "$(date +%s)"000000000 } @test "ledger account-id" { - dfx identity use alice - assert_command dfx ledger account-id - assert_match 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 + dfx identity use alice + assert_command dfx ledger account-id + assert_match 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 - assert_command dfx ledger account-id --of-principal fg7gi-vyaaa-aaaal-qadca-cai - assert_match a014842f64a22e59887162a79c7ca7eb02553250704780ec4d954f12d0ea0b18 + assert_command dfx ledger account-id --of-principal fg7gi-vyaaa-aaaal-qadca-cai + assert_match a014842f64a22e59887162a79c7ca7eb02553250704780ec4d954f12d0ea0b18 - # --of-canister accepts both canister alias and canister principal - assert_command dfx canister create dummy_canister - assert_command dfx ledger account-id --of-canister "$(dfx canister id dummy_canister)" - assert_eq "$(dfx ledger account-id --of-canister dummy_canister)" + # --of-canister accepts both canister alias and canister principal + assert_command dfx canister create dummy_canister + assert_command dfx ledger account-id --of-canister "$(dfx canister id dummy_canister)" + assert_eq "$(dfx ledger account-id --of-canister dummy_canister)" } @test "ledger balance & transfer" { - dfx identity use alice - assert_command dfx ledger account-id - assert_match 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 - - assert_command dfx ledger balance - assert_match "1000000000.00000000 ICP" - - assert_command dfx ledger transfer --amount 100 --memo 1 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 # to bob - assert_match "Transfer sent at block height" - - # The sender(alice) paid transaction fee which is 0.0001 ICP - assert_command dfx ledger balance - assert_match "999999899.99990000 ICP" - - dfx identity use bob - assert_command dfx ledger account-id - assert_match 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 - - assert_command dfx ledger balance - assert_match "1000000100.00000000 ICP" - - assert_command dfx ledger transfer --icp 100 --e8s 1 --memo 2 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 # to alice - assert_match "Transfer sent at block height" - - # The sender(bob) paid transaction fee which is 0.0001 ICP - # 10100 - 100 - 0.0001 - 0.00000001 = 9999.99989999 - assert_command dfx ledger balance - assert_match "999999999.99989999 ICP" - - # Transaction Deduplication - t=$(current_time_nanoseconds) - - assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time "$t" 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 - # shellcheck disable=SC2154 - block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height $block_height" "$stdout" - - assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time $((t+1)) 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Transfer sent at block height $block_height" "$stdout" - - assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time "$t" 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 - # shellcheck disable=SC2154 - assert_match "transaction is a duplicate of another transaction in block $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height $block_height" "$stdout" - - assert_command dfx ledger transfer --icp 1 --memo 2 --created-at-time "$t" 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Transfer sent at block height $block_height" "$stdout" + dfx identity use alice + assert_command dfx ledger account-id + assert_match 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 + + assert_command dfx ledger balance + assert_match "1000000000.00000000 ICP" + + assert_command dfx ledger transfer --amount 100 --memo 1 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 # to bob + assert_match "Transfer sent at block height" + + # The sender(alice) paid transaction fee which is 0.0001 ICP + assert_command dfx ledger balance + assert_match "999999899.99990000 ICP" + + dfx identity use bob + assert_command dfx ledger account-id + assert_match 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 + + assert_command dfx ledger balance + assert_match "1000000100.00000000 ICP" + + assert_command dfx ledger transfer --icp 100 --e8s 1 --memo 2 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 # to alice + assert_match "Transfer sent at block height" + + # The sender(bob) paid transaction fee which is 0.0001 ICP + # 10100 - 100 - 0.0001 - 0.00000001 = 9999.99989999 + assert_command dfx ledger balance + assert_match "999999999.99989999 ICP" + + # Transaction Deduplication + t=$(current_time_nanoseconds) + + assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time "$t" 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 + # shellcheck disable=SC2154 + block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height $block_height" "$stdout" + + assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time $((t+1)) 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Transfer sent at block height $block_height" "$stdout" + + assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time "$t" 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 + # shellcheck disable=SC2154 + assert_match "transaction is a duplicate of another transaction in block $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height $block_height" "$stdout" + + assert_command dfx ledger transfer --icp 1 --memo 2 --created-at-time "$t" 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Transfer sent at block height $block_height" "$stdout" } @test "ledger subaccounts" { - subacct=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f - assert_command dfx ledger account-id --identity bob --subaccount "$subacct" - assert_match 5a94fe181e9d411c58726cb87cbf2d016241b6c350bc3330e4869ca76e54ecbc - - dfx identity use alice - assert_command dfx ledger balance - assert_match "1000000000.00000000 ICP" - assert_command dfx ledger transfer --amount 100 --memo 1 5a94fe181e9d411c58726cb87cbf2d016241b6c350bc3330e4869ca76e54ecbc # to bob+subacct - assert_match "Transfer sent at block height" - assert_command dfx ledger balance - assert_match "999999899.99990000 ICP" - - dfx identity use bob - assert_command dfx ledger balance - assert_match "1000000000.00000000 ICP" - assert_command dfx ledger balance --subaccount "$subacct" - assert_match "1000000100.00000000 ICP" - - assert_command dfx ledger transfer --amount 100 --memo 2 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 --from-subaccount "$subacct" # to alice - assert_match "Transfer sent at block height" - assert_command dfx ledger balance - assert_match "1000000000.00000000 ICP" - assert_command dfx ledger balance --subaccount "$subacct" - assert_match "999999999.99990000 ICP" - assert_command dfx ledger balance --identity alice - assert_match "999999999.99990000 ICP" + subacct=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + assert_command dfx ledger account-id --identity bob --subaccount "$subacct" + assert_match 5a94fe181e9d411c58726cb87cbf2d016241b6c350bc3330e4869ca76e54ecbc + + dfx identity use alice + assert_command dfx ledger balance + assert_match "1000000000.00000000 ICP" + assert_command dfx ledger transfer --amount 100 --memo 1 5a94fe181e9d411c58726cb87cbf2d016241b6c350bc3330e4869ca76e54ecbc # to bob+subacct + assert_match "Transfer sent at block height" + assert_command dfx ledger balance + assert_match "999999899.99990000 ICP" + + dfx identity use bob + assert_command dfx ledger balance + assert_match "1000000000.00000000 ICP" + assert_command dfx ledger balance --subaccount "$subacct" + assert_match "1000000100.00000000 ICP" + + assert_command dfx ledger transfer --amount 100 --memo 2 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 --from-subaccount "$subacct" # to alice + assert_match "Transfer sent at block height" + assert_command dfx ledger balance + assert_match "1000000000.00000000 ICP" + assert_command dfx ledger balance --subaccount "$subacct" + assert_match "999999999.99990000 ICP" + assert_command dfx ledger balance --identity alice + assert_match "999999999.99990000 ICP" } tc_to_num() { - if [[ $1 =~ T ]]; then - echo "${1%%[^0-9]*}000000000000" - else - echo "${1%%[^0-9]*}" - fi + if [[ $1 =~ T ]]; then + echo "${1%%[^0-9]*}000000000000" + else + echo "${1%%[^0-9]*}" + fi } @test "ledger top-up" { - dfx identity use alice - assert_command dfx ledger balance - assert_match "1000000000.00000000 ICP" - - wallet=$(dfx identity get-wallet) - balance=$(tc_to_num "$(dfx wallet balance)") - - assert_command dfx ledger top-up "$wallet" --icp 5 - assert_match "Canister was topped up with 617283500000000 cycles" - balance_now=$(tc_to_num "$(dfx wallet balance)") - - (( balance_now - balance > 600000000000000 )) - - # Transaction Deduplication - t=$(current_time_nanoseconds) - - assert_command dfx ledger top-up "$wallet" --icp 5 --created-at-time "$t" - - # shellcheck disable=SC2154 - block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') - - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Using transfer at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Canister was topped up with" "$stdout" - - assert_command dfx ledger top-up "$wallet" --icp 5 --created-at-time $((t+1)) - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Using transfer at block height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Canister was topped up with" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Transfer sent at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Using transfer at block height $block_height" "$stdout" - - assert_command dfx ledger top-up "$wallet" --icp 5 --created-at-time "$t" - # shellcheck disable=SC2154 - assert_match "transaction is a duplicate of another transaction in block $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Using transfer at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Canister was topped up with" "$stdout" + dfx identity use alice + assert_command dfx ledger balance + assert_match "1000000000.00000000 ICP" + + wallet=$(dfx identity get-wallet) + balance=$(tc_to_num "$(dfx wallet balance)") + + assert_command dfx ledger top-up "$wallet" --icp 5 + assert_match "Canister was topped up with 617283500000000 cycles" + balance_now=$(tc_to_num "$(dfx wallet balance)") + + (( balance_now - balance > 600000000000000 )) + + # Transaction Deduplication + t=$(current_time_nanoseconds) + + assert_command dfx ledger top-up "$wallet" --icp 5 --created-at-time "$t" + + # shellcheck disable=SC2154 + block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') + + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Using transfer at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Canister was topped up with" "$stdout" + + assert_command dfx ledger top-up "$wallet" --icp 5 --created-at-time $((t+1)) + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Using transfer at block height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Canister was topped up with" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Transfer sent at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Using transfer at block height $block_height" "$stdout" + + assert_command dfx ledger top-up "$wallet" --icp 5 --created-at-time "$t" + # shellcheck disable=SC2154 + assert_match "transaction is a duplicate of another transaction in block $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Using transfer at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Canister was topped up with" "$stdout" } @test "ledger create-canister" { - dfx identity use alice - assert_command dfx ledger create-canister --amount=100 --subnet-type "type1" "$(dfx identity get-principal)" - assert_match "Transfer sent at block height" - assert_match "Refunded at block height" - assert_match "with message: Provided subnet type type1 does not exist" - - # Transaction Deduplication - t=$(current_time_nanoseconds) - - assert_command dfx ledger create-canister --amount=100 --created-at-time "$t" "$(dfx identity get-principal)" - # shellcheck disable=SC2154 - block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') - # shellcheck disable=SC2154 - created_canister_id=$(echo "$stdout" | sed '3q;d' | sed 's/Canister created with id: //') - - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Using transfer at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Canister created with id: $created_canister_id" "$stdout" - - assert_command dfx ledger create-canister --amount=100 --created-at-time $((t+1)) "$(dfx identity get-principal)" - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Using transfer at block height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Canister created with id:" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Transfer sent at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Using transfer at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_not_match "Canister created with id: $created_canister_id" "$stdout" - - assert_command dfx ledger create-canister --amount=100 --created-at-time "$t" "$(dfx identity get-principal)" - # shellcheck disable=SC2154 - assert_match "transaction is a duplicate of another transaction in block $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Transfer sent at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Using transfer at block height $block_height" "$stdout" - # shellcheck disable=SC2154 - assert_match "Canister created with id: $created_canister_id" "$stdout" - + dfx identity use alice + assert_command dfx ledger create-canister --amount=100 --subnet-type "type1" "$(dfx identity get-principal)" + assert_match "Transfer sent at block height" + assert_match "Refunded at block height" + assert_match "with message: Provided subnet type type1 does not exist" + + # Transaction Deduplication + t=$(current_time_nanoseconds) + + assert_command dfx ledger create-canister --amount=100 --created-at-time "$t" "$(dfx identity get-principal)" + # shellcheck disable=SC2154 + block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') + # shellcheck disable=SC2154 + created_canister_id=$(echo "$stdout" | sed '3q;d' | sed 's/Canister created with id: //') + + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Using transfer at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Canister created with id: $created_canister_id" "$stdout" + + assert_command dfx ledger create-canister --amount=100 --created-at-time $((t+1)) "$(dfx identity get-principal)" + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Using transfer at block height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Canister created with id:" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Transfer sent at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Using transfer at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_not_match "Canister created with id: $created_canister_id" "$stdout" + + assert_command dfx ledger create-canister --amount=100 --created-at-time "$t" "$(dfx identity get-principal)" + # shellcheck disable=SC2154 + assert_match "transaction is a duplicate of another transaction in block $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Transfer sent at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Using transfer at block height $block_height" "$stdout" + # shellcheck disable=SC2154 + assert_match "Canister created with id: $created_canister_id" "$stdout" + } @test "ledger show-subnet-types" { - install_asset cmc + install_asset cmc - dfx deploy cmc + dfx deploy cmc - CANISTER_ID=$(dfx canister id cmc) + CANISTER_ID=$(dfx canister id cmc) - assert_command dfx ledger show-subnet-types --cycles-minting-canister-id "$CANISTER_ID" - assert_eq '["type1", "type2"]' + assert_command dfx ledger show-subnet-types --cycles-minting-canister-id "$CANISTER_ID" + assert_eq '["type1", "type2"]' } diff --git a/e2e/tests-dfx/metadata.bash b/e2e/tests-dfx/metadata.bash index ddd34841c7..9790de9178 100644 --- a/e2e/tests-dfx/metadata.bash +++ b/e2e/tests-dfx/metadata.bash @@ -3,148 +3,148 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "custom canister metadata rules" { - install_asset metadata/custom - install_asset wasm/identity + install_asset metadata/custom + install_asset wasm/identity - dfx_start - dfx deploy + dfx_start + dfx deploy - echo "leaves existing metadata in a custom canister with no metadata settings" - dfx canister metadata --identity anonymous custom_with_default_metadata candid:service >metadata.txt - diff main.did metadata.txt + echo "leaves existing metadata in a custom canister with no metadata settings" + dfx canister metadata --identity anonymous custom_with_default_metadata candid:service >metadata.txt + diff main.did metadata.txt - echo "adds candid:service public metadata from candid field if a metadata entry exists" - dfx canister metadata --identity anonymous custom_with_standard_candid_service_metadata candid:service >metadata.txt - diff custom_with_standard_candid_service_metadata.did metadata.txt + echo "adds candid:service public metadata from candid field if a metadata entry exists" + dfx canister metadata --identity anonymous custom_with_standard_candid_service_metadata candid:service >metadata.txt + diff custom_with_standard_candid_service_metadata.did metadata.txt - echo "adds candid:service metadata from candid field with private visibility per metadata entry" - assert_command_fail dfx canister metadata --identity anonymous custom_with_private_candid_service_metadata candid:service >metadata.txt - dfx canister metadata custom_with_private_candid_service_metadata candid:service >metadata.txt - diff custom_with_private_candid_service_metadata.did metadata.txt + echo "adds candid:service metadata from candid field with private visibility per metadata entry" + assert_command_fail dfx canister metadata --identity anonymous custom_with_private_candid_service_metadata candid:service >metadata.txt + dfx canister metadata custom_with_private_candid_service_metadata candid:service >metadata.txt + diff custom_with_private_candid_service_metadata.did metadata.txt } @test "rust canister metadata rules" { - rustup default stable - rustup target add wasm32-unknown-unknown + rustup default stable + rustup target add wasm32-unknown-unknown - dfx_new_rust + dfx_new_rust - dfx_start - dfx deploy + dfx_start + dfx deploy - echo "adds public candid:service metadata to a default rust canister" - dfx canister metadata --identity anonymous e2e_project_backend candid:service >metadata.txt - diff src/e2e_project_backend/e2e_project_backend.did metadata.txt + echo "adds public candid:service metadata to a default rust canister" + dfx canister metadata --identity anonymous e2e_project_backend candid:service >metadata.txt + diff src/e2e_project_backend/e2e_project_backend.did metadata.txt - echo "adds private candid:service metadata if so configured" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].visibility="private"' dfx.json | sponge dfx.json - dfx deploy - assert_command_fail dfx canister metadata --identity anonymous e2e_project_backend candid:service - dfx canister metadata e2e_project_backend candid:service >metadata.txt - diff src/e2e_project_backend/e2e_project_backend.did metadata.txt + echo "adds private candid:service metadata if so configured" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].visibility="private"' dfx.json | sponge dfx.json + dfx deploy + assert_command_fail dfx canister metadata --identity anonymous e2e_project_backend candid:service + dfx canister metadata e2e_project_backend candid:service >metadata.txt + diff src/e2e_project_backend/e2e_project_backend.did metadata.txt } @test "motoko canister metadata rules" { - dfx_new - dfx_start - install_asset metadata/motoko - dfx canister create --all - - echo "permits specification of a replacement candid definition, if it is a valid subtype" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - assert_command dfx build - find . -name '*.did' - jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].path="valid_subtype.did"' dfx.json | sponge dfx.json - dfx build - - echo "reports an error if a specified candid:service metadata is not a valid subtype for the canister" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].path="not_subtype_rename.did"' dfx.json | sponge dfx.json - assert_command_fail dfx build - assert_match "Method new_method is only in the expected type" - - echo "reports an error if a specified candid:service metadata is not a valid subtype for the canister" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].path="not_subtype_numbertype.did"' dfx.json | sponge dfx.json - assert_command_fail dfx build - assert_match "int is not a subtype of nat" - - - echo "adds private candid:service metadata if so configured" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].visibility="private"' dfx.json | sponge dfx.json - dfx deploy - assert_command_fail dfx canister metadata --identity anonymous e2e_project_backend candid:service - dfx canister metadata e2e_project_backend candid:service >metadata.txt - diff .dfx/local/canisters/e2e_project_backend/e2e_project_backend.did metadata.txt - - - echo "adds public candid:service metadata to a default motoko canister" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - dfx deploy - dfx canister metadata --identity anonymous e2e_project_backend candid:service >metadata.txt - diff .dfx/local/canisters/e2e_project_backend/e2e_project_backend.did metadata.txt + dfx_new + dfx_start + install_asset metadata/motoko + dfx canister create --all + + echo "permits specification of a replacement candid definition, if it is a valid subtype" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + assert_command dfx build + find . -name '*.did' + jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].path="valid_subtype.did"' dfx.json | sponge dfx.json + dfx build + + echo "reports an error if a specified candid:service metadata is not a valid subtype for the canister" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].path="not_subtype_rename.did"' dfx.json | sponge dfx.json + assert_command_fail dfx build + assert_match "Method new_method is only in the expected type" + + echo "reports an error if a specified candid:service metadata is not a valid subtype for the canister" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].path="not_subtype_numbertype.did"' dfx.json | sponge dfx.json + assert_command_fail dfx build + assert_match "int is not a subtype of nat" + + + echo "adds private candid:service metadata if so configured" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[0].name="candid:service"|.canisters.e2e_project_backend.metadata[0].visibility="private"' dfx.json | sponge dfx.json + dfx deploy + assert_command_fail dfx canister metadata --identity anonymous e2e_project_backend candid:service + dfx canister metadata e2e_project_backend candid:service >metadata.txt + diff .dfx/local/canisters/e2e_project_backend/e2e_project_backend.did metadata.txt + + + echo "adds public candid:service metadata to a default motoko canister" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + dfx deploy + dfx canister metadata --identity anonymous e2e_project_backend candid:service >metadata.txt + diff .dfx/local/canisters/e2e_project_backend/e2e_project_backend.did metadata.txt } @test "adds arbitrary metadata to a motoko canister" { - dfx_new - dfx_start - install_asset metadata/motoko - dfx canister create --all - - echo "adds public arbitrary metadata to a default motoko canister" - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[0].name="arbitrary"|.canisters.e2e_project_backend.metadata[0].path="arbitrary-metadata.txt"' dfx.json | sponge dfx.json - echo "can be anything" >arbitrary-metadata.txt - dfx deploy - dfx canister metadata --identity anonymous e2e_project_backend arbitrary >from-canister.txt - diff arbitrary-metadata.txt from-canister.txt - - # with private visibility - jq '.canisters.e2e_project_backend.metadata[0].visibility="private"' dfx.json | sponge dfx.json - dfx deploy - assert_command_fail dfx canister metadata --identity anonymous e2e_project_backend arbitrary - dfx canister metadata e2e_project_backend arbitrary >from-canister.txt - diff arbitrary-metadata.txt from-canister.txt + dfx_new + dfx_start + install_asset metadata/motoko + dfx canister create --all + + echo "adds public arbitrary metadata to a default motoko canister" + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[0].name="arbitrary"|.canisters.e2e_project_backend.metadata[0].path="arbitrary-metadata.txt"' dfx.json | sponge dfx.json + echo "can be anything" >arbitrary-metadata.txt + dfx deploy + dfx canister metadata --identity anonymous e2e_project_backend arbitrary >from-canister.txt + diff arbitrary-metadata.txt from-canister.txt + + # with private visibility + jq '.canisters.e2e_project_backend.metadata[0].visibility="private"' dfx.json | sponge dfx.json + dfx deploy + assert_command_fail dfx canister metadata --identity anonymous e2e_project_backend arbitrary + dfx canister metadata e2e_project_backend arbitrary >from-canister.txt + diff arbitrary-metadata.txt from-canister.txt } @test "uses the first metadata definition for name and network" { - dfx_new - dfx_start - install_asset metadata/motoko - dfx canister create --all - - jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[0].name="multiple"|.canisters.e2e_project_backend.metadata[0].path="empty-networks-matches-nothing.txt"|.canisters.e2e_project_backend.metadata[0].networks=[]' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[1].name="multiple"|.canisters.e2e_project_backend.metadata[1].path="different-network-no-match.txt"|.canisters.e2e_project_backend.metadata[1].networks=["ic"]' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[2].name="multiple"|.canisters.e2e_project_backend.metadata[2].path="first-match-chosen.txt"' dfx.json | sponge dfx.json - jq '.canisters.e2e_project_backend.metadata[3].name="multiple"|.canisters.e2e_project_backend.metadata[3].path="earlier-match-ignored.txt"' dfx.json | sponge dfx.json - echo "dfx will install this file" >first-match-chosen.txt - dfx deploy - dfx canister metadata --identity anonymous e2e_project_backend multiple >from-canister.txt - diff first-match-chosen.txt from-canister.txt + dfx_new + dfx_start + install_asset metadata/motoko + dfx canister create --all + + jq 'del(.canisters.e2e_project_backend.metadata)' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[0].name="multiple"|.canisters.e2e_project_backend.metadata[0].path="empty-networks-matches-nothing.txt"|.canisters.e2e_project_backend.metadata[0].networks=[]' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[1].name="multiple"|.canisters.e2e_project_backend.metadata[1].path="different-network-no-match.txt"|.canisters.e2e_project_backend.metadata[1].networks=["ic"]' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[2].name="multiple"|.canisters.e2e_project_backend.metadata[2].path="first-match-chosen.txt"' dfx.json | sponge dfx.json + jq '.canisters.e2e_project_backend.metadata[3].name="multiple"|.canisters.e2e_project_backend.metadata[3].path="earlier-match-ignored.txt"' dfx.json | sponge dfx.json + echo "dfx will install this file" >first-match-chosen.txt + dfx deploy + dfx canister metadata --identity anonymous e2e_project_backend multiple >from-canister.txt + diff first-match-chosen.txt from-canister.txt } @test "can add metadata to a compressed canister" { - dfx_start - install_asset gzip - install_asset wasm/identity - jq '.canisters.gzipped.metadata[0].name="arbitrary"|.canisters.gzipped.metadata[0].content="arbitrary content"' dfx.json | sponge dfx.json - - assert_command dfx deploy - assert_command dfx canister metadata gzipped arbitrary - assert_eq "$output" "arbitrary content" + dfx_start + install_asset gzip + install_asset wasm/identity + jq '.canisters.gzipped.metadata[0].name="arbitrary"|.canisters.gzipped.metadata[0].content="arbitrary content"' dfx.json | sponge dfx.json + + assert_command dfx deploy + assert_command dfx canister metadata gzipped arbitrary + assert_eq "$output" "arbitrary content" } @test "existence of build steps do not control custom canister metadata" { @@ -172,22 +172,22 @@ teardown() { } @test "can read canister metadata from replica" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - assert_command dfx deploy + assert_command dfx deploy - dfx canister metadata hello_backend candid:service >metadata.txt - assert_command diff .dfx/local/canisters/hello_backend/hello_backend.did ./metadata.txt + dfx canister metadata hello_backend candid:service >metadata.txt + assert_command diff .dfx/local/canisters/hello_backend/hello_backend.did ./metadata.txt } @test "asset canister provides candid:service metadata" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - assert_command dfx deploy - REPO_ROOT=${BATS_TEST_DIRNAME}/../../ + assert_command dfx deploy + REPO_ROOT=${BATS_TEST_DIRNAME}/../../ - dfx canister metadata hello_frontend candid:service >candid_service_metadata.txt - assert_command diff "$REPO_ROOT/src/distributed/assetstorage.did" ./candid_service_metadata.txt + dfx canister metadata hello_frontend candid:service >candid_service_metadata.txt + assert_command diff "$REPO_ROOT/src/distributed/assetstorage.did" ./candid_service_metadata.txt } diff --git a/e2e/tests-dfx/migrate.bash b/e2e/tests-dfx/migrate.bash index 9ae48eed8a..b2e330d61a 100644 --- a/e2e/tests-dfx/migrate.bash +++ b/e2e/tests-dfx/migrate.bash @@ -3,36 +3,36 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "detects the wallet being outdated" { - use_wallet_wasm 0.7.2 - dfx_start - WALLET=$(dfx identity get-wallet) - use_wallet_wasm 0.10.0 - assert_command dfx diagnose - assert_match "dfx wallet upgrade" - assert_command_fail dfx canister call "$WALLET" wallet_balance128 - assert_command dfx fix - assert_command dfx canister call "$WALLET" wallet_balance128 + use_wallet_wasm 0.7.2 + dfx_start + WALLET=$(dfx identity get-wallet) + use_wallet_wasm 0.10.0 + assert_command dfx diagnose + assert_match "dfx wallet upgrade" + assert_command_fail dfx canister call "$WALLET" wallet_balance128 + assert_command dfx fix + assert_command dfx canister call "$WALLET" wallet_balance128 } @test "detects the wallet being the sole controller" { - dfx_start - dfx canister create e2e_project_backend --controller "$(dfx identity get-wallet)" --no-wallet - dfx build e2e_project_backend - assert_command dfx diagnose - assert_match "dfx canister update-settings" - assert_command_fail dfx canister install e2e_project_backend - assert_command dfx fix - assert_command dfx canister install e2e_project_backend + dfx_start + dfx canister create e2e_project_backend --controller "$(dfx identity get-wallet)" --no-wallet + dfx build e2e_project_backend + assert_command dfx diagnose + assert_match "dfx canister update-settings" + assert_command_fail dfx canister install e2e_project_backend + assert_command dfx fix + assert_command dfx canister install e2e_project_backend } diff --git a/e2e/tests-dfx/mode_reinstall.bash b/e2e/tests-dfx/mode_reinstall.bash index 78a68720b9..a21e4bdd5d 100644 --- a/e2e/tests-dfx/mode_reinstall.bash +++ b/e2e/tests-dfx/mode_reinstall.bash @@ -3,160 +3,160 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "install --mode=reinstall --all fails" { - dfx_start - assert_command_fail dfx canister install --mode=reinstall --all + dfx_start + assert_command_fail dfx canister install --mode=reinstall --all - assert_match "The --mode=reinstall is only valid when specifying a single canister, because reinstallation destroys all data in the canister." + assert_match "The --mode=reinstall is only valid when specifying a single canister, because reinstallation destroys all data in the canister." } @test "install --mode=reinstall fails if no canister is provided" { - # This fails because clap protects against it. + # This fails because clap protects against it. - dfx_start - assert_command_fail dfx canister install --mode=reinstall - assert_match \ + dfx_start + assert_command_fail dfx canister install --mode=reinstall + assert_match \ "error: the following required arguments were not provided: --all" } @test "reinstall succeeds when a canister name is provided" { - dfx_start - dfx deploy + dfx_start + dfx deploy - # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, - # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 - echo yes | ( - assert_command dfx canister install --mode=reinstall hello_backend + # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, + # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 + echo yes | ( + assert_command dfx canister install --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_backend" - ) + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_backend" + ) } @test "install --mode=reinstall refused if not approved" { - dfx_start - dfx deploy + dfx_start + dfx deploy - echo no | ( - assert_command_fail dfx canister install --mode=reinstall hello_backend + echo no | ( + assert_command_fail dfx canister install --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_not_match "Installing code for canister" - assert_match "Refusing to install canister without approval: User declined consent." - ) + assert_not_match "Installing code for canister" + assert_match "Refusing to install canister without approval: User declined consent." + ) } @test "deploy --mode=reinstall fails if no canister name specified" { - dfx_start - assert_command_fail dfx deploy --mode=reinstall + dfx_start + assert_command_fail dfx deploy --mode=reinstall - assert_match "The --mode=reinstall is only valid when deploying a single canister, because reinstallation destroys all data in the canister." + assert_match "The --mode=reinstall is only valid when deploying a single canister, because reinstallation destroys all data in the canister." } @test "deploy --mode=reinstall succeeds when a canister name is provided" { - dfx_start - dfx deploy + dfx_start + dfx deploy - # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, - # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 - echo yes | ( - assert_command dfx deploy --mode=reinstall hello_backend + # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, + # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 + echo yes | ( + assert_command dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_backend" - ) + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_backend" + ) } @test "deploy --mode=reinstall refused if not approved" { - dfx_start - dfx deploy + dfx_start + dfx deploy - echo no | ( - assert_command_fail dfx deploy --mode=reinstall hello_backend + echo no | ( + assert_command_fail dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_not_match "Installing code for canister" - assert_match "Refusing to install canister without approval: User declined consent." - ) + assert_not_match "Installing code for canister" + assert_match "Refusing to install canister without approval: User declined consent." + ) } @test "deploy --mode=reinstall does not reinstall dependencies" { - dfx_start - install_asset counter - dfx deploy + dfx_start + install_asset counter + dfx deploy - assert_command dfx canister call hello_backend read - assert_eq "(0 : nat)" + assert_command dfx canister call hello_backend read + assert_eq "(0 : nat)" - assert_command dfx canister call hello_backend inc - assert_eq "()" + assert_command dfx canister call hello_backend inc + assert_eq "()" - assert_command dfx canister call hello_backend read - assert_eq "(1 : nat)" + assert_command dfx canister call hello_backend read + assert_eq "(1 : nat)" - dfx canister call hello_backend inc - assert_command dfx canister call hello_backend read - assert_eq "(2 : nat)" + dfx canister call hello_backend inc + assert_command dfx canister call hello_backend read + assert_eq "(2 : nat)" - # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, - # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 - echo "yes" | ( - assert_command dfx deploy --mode=reinstall hello_frontend + # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, + # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 + echo "yes" | ( + assert_command dfx deploy --mode=reinstall hello_frontend - assert_match "You are about to reinstall the hello_frontend canister." - assert_not_match "You are about to reinstall the hello_backend canister." - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_frontend," - ) + assert_match "You are about to reinstall the hello_frontend canister." + assert_not_match "You are about to reinstall the hello_backend canister." + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_frontend," + ) - # the hello_backend canister should not have been upgraded (which would reset the non-stable var) - assert_command dfx canister call hello_backend read - assert_eq "(2 : nat)" + # the hello_backend canister should not have been upgraded (which would reset the non-stable var) + assert_command dfx canister call hello_backend read + assert_eq "(2 : nat)" } @test "confirmation dialogue accepts multiple forms of 'yes'" { - dfx_start - dfx deploy - - # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, - # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 - echo yes | ( - assert_command dfx deploy --mode=reinstall hello_backend - - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_backend" - ) - echo y | ( - assert_command dfx deploy --mode=reinstall hello_backend - - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_backend" - ) - echo YES | ( - assert_command dfx deploy --mode=reinstall hello_backend - - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_backend" - ) - echo YeS | ( - assert_command dfx deploy --mode=reinstall hello_backend - - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalling code for canister hello_backend" - ) + dfx_start + dfx deploy + + # if the pipe is alone with assert_command, $stdout, $stderr etc will not be available, + # so all the assert_match calls will fail. http://mywiki.wooledge.org/BashFAQ/024 + echo yes | ( + assert_command dfx deploy --mode=reinstall hello_backend + + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_backend" + ) + echo y | ( + assert_command dfx deploy --mode=reinstall hello_backend + + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_backend" + ) + echo YES | ( + assert_command dfx deploy --mode=reinstall hello_backend + + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_backend" + ) + echo YeS | ( + assert_command dfx deploy --mode=reinstall hello_backend + + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" + assert_match "Reinstalling code for canister hello_backend" + ) } diff --git a/e2e/tests-dfx/network.bash b/e2e/tests-dfx/network.bash index b2a39982db..dcb12ac8da 100644 --- a/e2e/tests-dfx/network.bash +++ b/e2e/tests-dfx/network.bash @@ -3,111 +3,111 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx identity new --storage-mode plaintext test_id - dfx identity use test_id - dfx_new + dfx identity new --storage-mode plaintext test_id + dfx identity use test_id + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "create with wallet stores canister ids for default-persistent networks in canister_ids.json" { - dfx_start - setup_actuallylocal_shared_network - dfx_set_wallet - dfx_set_wallet + dfx_start + setup_actuallylocal_shared_network + dfx_set_wallet + dfx_set_wallet - dfx canister create --all --network actuallylocal + dfx canister create --all --network actuallylocal - # canister creates writes to a spinner (stderr), not stdout - assert_command dfx canister id e2e_project_backend --network actuallylocal - assert_match "$(jq -r .e2e_project_backend.actuallylocal ` - assert_command_fail dfx canister id hello_backend --network playground - assert_contains "Cannot find canister id" + # if network is unknown dfx fails with `Network not found: ` + assert_command_fail dfx canister id hello_backend --network playground + assert_contains "Cannot find canister id" } @test "equivalent: --network ic and --ic" { - dfx_start - dfx identity get-wallet - - assert_command_fail dfx diagnose --network ic - assert_contains "The test_id identity is not stored securely." - assert_contains "use it in mainnet-facing commands" - assert_contains "No wallet found; nothing to do" - - assert_command_fail dfx diagnose --ic - assert_contains "The test_id identity is not stored securely." - assert_contains "use it in mainnet-facing commands" - assert_contains "No wallet found; nothing to do" - - assert_command dfx diagnose - assert_not_contains "identity is not stored securely" - assert_eq "No problems found" + dfx_start + dfx identity get-wallet + + assert_command_fail dfx diagnose --network ic + assert_contains "The test_id identity is not stored securely." + assert_contains "use it in mainnet-facing commands" + assert_contains "No wallet found; nothing to do" + + assert_command_fail dfx diagnose --ic + assert_contains "The test_id identity is not stored securely." + assert_contains "use it in mainnet-facing commands" + assert_contains "No wallet found; nothing to do" + + assert_command dfx diagnose + assert_not_contains "identity is not stored securely" + assert_eq "No problems found" } diff --git a/e2e/tests-dfx/new.bash b/e2e/tests-dfx/new.bash index 731d1dbaf0..6559b2d5b6 100644 --- a/e2e/tests-dfx/new.bash +++ b/e2e/tests-dfx/new.bash @@ -3,57 +3,57 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - standard_teardown + standard_teardown } @test "dfx new - good names" { - dfx new --no-frontend a_good_name_ - dfx new --no-frontend A - dfx new --no-frontend b - dfx new --no-frontend a_ - dfx new --no-frontend a_1 - dfx new --no-frontend a1 - dfx new --no-frontend a1a + dfx new --no-frontend a_good_name_ + dfx new --no-frontend A + dfx new --no-frontend b + dfx new --no-frontend a_ + dfx new --no-frontend a_1 + dfx new --no-frontend a1 + dfx new --no-frontend a1a } @test "dfx new - bad names" { - assert_command_fail dfx new _a_good_name_ - assert_command_fail dfx new __also_good - assert_command_fail dfx new _1 - assert_command_fail dfx new _a - assert_command_fail dfx new 1 - assert_command_fail dfx new 1_ - assert_command_fail dfx new - - assert_command_fail dfx new _ - assert_command_fail dfx new a-b-c - assert_command_fail dfx new '🕹' - assert_command_fail dfx new '不好' - assert_command_fail dfx new 'a:b' + assert_command_fail dfx new _a_good_name_ + assert_command_fail dfx new __also_good + assert_command_fail dfx new _1 + assert_command_fail dfx new _a + assert_command_fail dfx new 1 + assert_command_fail dfx new 1_ + assert_command_fail dfx new - + assert_command_fail dfx new _ + assert_command_fail dfx new a-b-c + assert_command_fail dfx new '🕹' + assert_command_fail dfx new '不好' + assert_command_fail dfx new 'a:b' } @test "dfx new readmes contain appropriate links" { - assert_command dfx new --type rust e2e_rust --no-frontend - assert_command grep "https://docs.rs/ic-cdk" e2e_rust/README.md - assert_command dfx new --type motoko e2e_motoko --no-frontend - assert_command grep "https://internetcomputer.org/docs/current/motoko/main/language-manual" e2e_motoko/README.md + assert_command dfx new --type rust e2e_rust --no-frontend + assert_command grep "https://docs.rs/ic-cdk" e2e_rust/README.md + assert_command dfx new --type motoko e2e_motoko --no-frontend + assert_command grep "https://internetcomputer.org/docs/current/motoko/main/language-manual" e2e_motoko/README.md } @test "dfx new emits projects of the correct type" { - assert_command dfx new --type rust e2e_rust --no-frontend - assert_command jq -r '.canisters.e2e_rust_backend.type' e2e_rust/dfx.json - assert_eq "rust" - assert_command dfx new --type motoko e2e_motoko --no-frontend - assert_command jq -r '.canisters.e2e_motoko_backend.type' e2e_motoko/dfx.json - assert_eq "motoko" + assert_command dfx new --type rust e2e_rust --no-frontend + assert_command jq -r '.canisters.e2e_rust_backend.type' e2e_rust/dfx.json + assert_eq "rust" + assert_command dfx new --type motoko e2e_motoko --no-frontend + assert_command jq -r '.canisters.e2e_motoko_backend.type' e2e_motoko/dfx.json + assert_eq "motoko" } @test "dfx new always emits sample-asset.txt" { - assert_command dfx new e2e_frontend --frontend - assert_file_exists e2e_frontend/src/e2e_frontend_frontend/assets/sample-asset.txt - assert_command dfx new e2e_no_frontend --no-frontend - assert_file_exists e2e_no_frontend/src/e2e_no_frontend_frontend/assets/sample-asset.txt + assert_command dfx new e2e_frontend --frontend + assert_file_exists e2e_frontend/src/e2e_frontend_frontend/assets/sample-asset.txt + assert_command dfx new e2e_no_frontend --no-frontend + assert_file_exists e2e_no_frontend/src/e2e_no_frontend_frontend/assets/sample-asset.txt } diff --git a/e2e/tests-dfx/packtool.bash b/e2e/tests-dfx/packtool.bash index a3109b50a9..8f28b789f7 100644 --- a/e2e/tests-dfx/packtool.bash +++ b/e2e/tests-dfx/packtool.bash @@ -3,73 +3,73 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "build fails if packtool is not configured" { - install_asset packtool + install_asset packtool - dfx_start - dfx canister create --all - assert_command_fail dfx build - assert_match 'import error \[M0010\], package "(rate|describe)" not defined' + dfx_start + dfx canister create --all + assert_command_fail dfx build + assert_match 'import error \[M0010\], package "(rate|describe)" not defined' } @test "build succeeds if packtool is configured" { - install_asset packtool - # shellcheck disable=SC1091 - source configure_packtool.bash + install_asset packtool + # shellcheck disable=SC1091 + source configure_packtool.bash - dfx_start - dfx canister create --all - dfx build + dfx_start + dfx canister create --all + dfx build } @test "project calls dependencies made available by packtool" { - install_asset packtool - # shellcheck disable=SC1091 - source configure_packtool.bash + install_asset packtool + # shellcheck disable=SC1091 + source configure_packtool.bash - dfx_start - dfx canister create --all - dfx build - dfx canister install e2e_project_backend + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project_backend - assert_command dfx canister call e2e_project_backend rate '("rust")' - assert_eq '("rust: So hot right now.")' + assert_command dfx canister call e2e_project_backend rate '("rust")' + assert_eq '("rust: So hot right now.")' - assert_command dfx canister call e2e_project_backend rate '("php")' - assert_eq '("php: No comment.")' + assert_command dfx canister call e2e_project_backend rate '("php")' + assert_eq '("php: No comment.")' } @test "failure to invoke the package tool reports the command line and reason" { - install_asset packtool - jq '.defaults.build.packtool="./no-such-command that command cannot be invoked"' dfx.json | sponge dfx.json - - dfx_start - dfx canister create --all - assert_command_fail dfx build - assert_match 'Failed to invoke the package tool' - assert_match 'no-such-command.*that.*command.*cannot.*be.*invoked' - assert_match 'No such file or directory \(os error 2\)' + install_asset packtool + jq '.defaults.build.packtool="./no-such-command that command cannot be invoked"' dfx.json | sponge dfx.json + + dfx_start + dfx canister create --all + assert_command_fail dfx build + assert_match 'Failed to invoke the package tool' + assert_match 'no-such-command.*that.*command.*cannot.*be.*invoked' + assert_match 'No such file or directory \(os error 2\)' } @test "failure in execution reports the command line and exit code" { - install_asset packtool - jq '.defaults.build.packtool="sh ./command-that-fails.bash"' dfx.json | sponge dfx.json - - dfx_start - dfx canister create --all - assert_command_fail dfx build - assert_match 'The command.*failed' - assert_match 'sh.*command-that-fails.bash' - assert_match 'exit (code|status): 3' + install_asset packtool + jq '.defaults.build.packtool="sh ./command-that-fails.bash"' dfx.json | sponge dfx.json + + dfx_start + dfx canister create --all + assert_command_fail dfx build + assert_match 'The command.*failed' + assert_match 'sh.*command-that-fails.bash' + assert_match 'exit (code|status): 3' } diff --git a/e2e/tests-dfx/ping.bash b/e2e/tests-dfx/ping.bash index 1e18a36914..8b7ecfb1b6 100644 --- a/e2e/tests-dfx/ping.bash +++ b/e2e/tests-dfx/ping.bash @@ -3,86 +3,86 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx ping fails if replica not running" { - assert_command_fail dfx ping + assert_command_fail dfx ping } @test "dfx ping succeeds if replica is running" { - dfx_start - assert_command dfx ping + dfx_start + assert_command dfx ping - assert_match "\"ic_api_version\"" + assert_match "\"ic_api_version\"" } @test "dfx ping succeeds by specific host:post" { - dfx_start - webserver_port=$(get_webserver_port) - assert_command dfx ping http://127.0.0.1:"$webserver_port" + dfx_start + webserver_port=$(get_webserver_port) + assert_command dfx ping http://127.0.0.1:"$webserver_port" - assert_match "\"ic_api_version\"" + assert_match "\"ic_api_version\"" } @test "dfx ping does not require dfx.json" { - dfx_start - webserver_port=$(get_webserver_port) + dfx_start + webserver_port=$(get_webserver_port) - mkdir "$E2E_TEMP_DIR/not-a-project" - ( - cd "$E2E_TEMP_DIR/not-a-project" + mkdir "$E2E_TEMP_DIR/not-a-project" + ( + cd "$E2E_TEMP_DIR/not-a-project" - assert_command dfx ping http://127.0.0.1:"$webserver_port" - assert_match "\"ic_api_version\"" - ) + assert_command dfx ping http://127.0.0.1:"$webserver_port" + assert_match "\"ic_api_version\"" + ) } @test "dfx ping succeeds by network name" { - dfx_start - assert_command dfx ping local + dfx_start + assert_command dfx ping local - assert_match "\"ic_api_version\"" + assert_match "\"ic_api_version\"" } @test "dfx ping succeeds by network name if network bind address is host:port format" { - dfx_start - webserver_port=$(get_webserver_port) - jq '.networks.nnn.bind="127.0.0.1:'"$webserver_port"'"' dfx.json | sponge dfx.json - assert_command dfx ping nnn + dfx_start + webserver_port=$(get_webserver_port) + jq '.networks.nnn.bind="127.0.0.1:'"$webserver_port"'"' dfx.json | sponge dfx.json + assert_command dfx ping nnn - assert_match "\"ic_api_version\"" + assert_match "\"ic_api_version\"" } @test "dfx ping succeeds by arbitrary network name to a nonstandard port" { - dfx_start --host 127.0.0.1:12345 + dfx_start --host 127.0.0.1:12345 - # Make dfx use the port from configuration: - rm "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port" + # Make dfx use the port from configuration: + rm "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port" - jq '.networks.arbitrary.providers=["http://127.0.0.1:12345"]' dfx.json | sponge dfx.json + jq '.networks.arbitrary.providers=["http://127.0.0.1:12345"]' dfx.json | sponge dfx.json - assert_command dfx ping arbitrary - assert_match "\"ic_api_version\"" + assert_command dfx ping arbitrary + assert_match "\"ic_api_version\"" - assert_command_fail dfx ping - # this port won't match the ephemeral port that the replica picked - jq '.networks.arbitrary.providers=["127.0.0.1:22113"]' dfx.json | sponge dfx.json - assert_command_fail dfx ping arbitrary + assert_command_fail dfx ping + # this port won't match the ephemeral port that the replica picked + jq '.networks.arbitrary.providers=["127.0.0.1:22113"]' dfx.json | sponge dfx.json + assert_command_fail dfx ping arbitrary } @test "dfx ping can have a URL for network to ping" { - dfx_start - webserver_port=$(get_webserver_port) - assert_command dfx ping "http://127.0.0.1:$webserver_port" - assert_match "\"ic_api_version\"" + dfx_start + webserver_port=$(get_webserver_port) + assert_command dfx ping "http://127.0.0.1:$webserver_port" + assert_match "\"ic_api_version\"" } diff --git a/e2e/tests-dfx/playground.bash b/e2e/tests-dfx/playground.bash index a2732a4f0c..c90316adb9 100644 --- a/e2e/tests-dfx/playground.bash +++ b/e2e/tests-dfx/playground.bash @@ -3,14 +3,14 @@ load ../utils/_ setup() { - standard_setup - setup_playground - dfx_new hello + standard_setup + setup_playground + dfx_new hello } teardown() { - dfx_stop - standard_teardown + dfx_stop + standard_teardown } setup_playground() { @@ -53,10 +53,10 @@ setup_playground() { assert_match "The principal you are using to call a management function is not part of the controllers." if [ "$(uname)" == "Darwin" ]; then - sed -i '' 's/Hello/Goodbye/g' src/hello_backend/main.mo - elif [ "$(uname)" == "Linux" ]; then - sed -i 's/Hello/Goodbye/g' src/hello_backend/main.mo - fi + sed -i '' 's/Hello/Goodbye/g' src/hello_backend/main.mo + elif [ "$(uname)" == "Linux" ]; then + sed -i 's/Hello/Goodbye/g' src/hello_backend/main.mo + fi assert_command dfx deploy --playground assert_command dfx canister --playground call hello_backend greet '("player")' diff --git a/e2e/tests-dfx/print.bash b/e2e/tests-dfx/print.bash index cef5232c7c..7a1349921a 100644 --- a/e2e/tests-dfx/print.bash +++ b/e2e/tests-dfx/print.bash @@ -3,25 +3,25 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "print_mo" { - install_asset print - dfx_start 2>stderr.txt - dfx canister create --all - dfx build - dfx canister install e2e_project - dfx canister call e2e_project hello - sleep 2 - run tail -2 stderr.txt - assert_match "Hello, World! from DFINITY" + install_asset print + dfx_start 2>stderr.txt + dfx canister create --all + dfx build + dfx canister install e2e_project + dfx canister call e2e_project hello + sleep 2 + run tail -2 stderr.txt + assert_match "Hello, World! from DFINITY" } diff --git a/e2e/tests-dfx/project_local_network.bash b/e2e/tests-dfx/project_local_network.bash index 0f467f27a6..37238ee48e 100644 --- a/e2e/tests-dfx/project_local_network.bash +++ b/e2e/tests-dfx/project_local_network.bash @@ -3,163 +3,163 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx start starts a local network if dfx.json defines one" { - dfx_new hello - cat dfx.json - define_project_network + dfx_new hello + cat dfx.json + define_project_network - dfx_start - dfx deploy + dfx_start + dfx deploy - assert_directory_not_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY" - assert_file_exists .dfx/network/local/pid + assert_directory_not_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY" + assert_file_exists .dfx/network/local/pid } @test "can run more than one project network at the same time" { - mkdir a - cd a - dfx_new hello - install_asset counter - define_project_network - dfx_start - dfx deploy - dfx canister call hello_backend inc - dfx canister call hello_backend inc - - cd ../.. - - mkdir b - cd b - dfx_new hello - install_asset counter - define_project_network - dfx_start - dfx deploy - dfx canister call hello_backend write '(6: nat)' - - cd ../.. - - ( - cd a/hello - assert_command dfx canister call hello_backend read - assert_eq "(2 : nat)" - ) - - ( - cd b/hello - assert_command dfx canister call hello_backend read - assert_eq "(6 : nat)" - ) - - # the above would work even with a shared network. - # So here's the real trick: they will have the same canister ids, because - # each project has its own replica. - HELLO_BACKEND_ID_A="$(cd a/hello ; dfx canister id hello_backend)" - HELLO_BACKEND_ID_B="$(cd b/hello ; dfx canister id hello_backend)" - assert_eq "$HELLO_BACKEND_ID_A" "$HELLO_BACKEND_ID_B" - - (cd a/hello ; dfx stop) - (cd b/hello ; dfx stop) + mkdir a + cd a + dfx_new hello + install_asset counter + define_project_network + dfx_start + dfx deploy + dfx canister call hello_backend inc + dfx canister call hello_backend inc + + cd ../.. + + mkdir b + cd b + dfx_new hello + install_asset counter + define_project_network + dfx_start + dfx deploy + dfx canister call hello_backend write '(6: nat)' + + cd ../.. + + ( + cd a/hello + assert_command dfx canister call hello_backend read + assert_eq "(2 : nat)" + ) + + ( + cd b/hello + assert_command dfx canister call hello_backend read + assert_eq "(6 : nat)" + ) + + # the above would work even with a shared network. + # So here's the real trick: they will have the same canister ids, because + # each project has its own replica. + HELLO_BACKEND_ID_A="$(cd a/hello ; dfx canister id hello_backend)" + HELLO_BACKEND_ID_B="$(cd b/hello ; dfx canister id hello_backend)" + assert_eq "$HELLO_BACKEND_ID_A" "$HELLO_BACKEND_ID_B" + + (cd a/hello ; dfx stop) + (cd b/hello ; dfx stop) } @test "upgrade a wallet in a project-specific network" { - dfx_new hello - define_project_network + dfx_new hello + define_project_network - dfx_start - use_wallet_wasm 0.8.2 + dfx_start + use_wallet_wasm 0.8.2 - dfx identity get-wallet + dfx identity get-wallet - assert_command dfx canister info "$(dfx identity get-wallet)" - assert_match "Module hash: 0x$(wallet_sha 0.8.2)" + assert_command dfx canister info "$(dfx identity get-wallet)" + assert_match "Module hash: 0x$(wallet_sha 0.8.2)" - use_wallet_wasm 0.10.0 + use_wallet_wasm 0.10.0 - dfx wallet upgrade - assert_command dfx canister info "$(dfx identity get-wallet)" - assert_match "Module hash: 0x$(wallet_sha 0.10.0)" + dfx wallet upgrade + assert_command dfx canister info "$(dfx identity get-wallet)" + assert_match "Module hash: 0x$(wallet_sha 0.10.0)" } @test "with a project-specific network, wallet id is stored local to the project" { - dfx_new hello - define_project_network + dfx_new hello + define_project_network - dfx_start + dfx_start - assert_file_not_exists .dfx/local/wallets.json + assert_file_not_exists .dfx/local/wallets.json - WALLET_ID="$(dfx identity get-wallet)" + WALLET_ID="$(dfx identity get-wallet)" - assert_command jq -r .identities.default.local .dfx/local/wallets.json - assert_eq "$WALLET_ID" - assert_file_not_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + assert_command jq -r .identities.default.local .dfx/local/wallets.json + assert_eq "$WALLET_ID" + assert_file_not_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" } @test "with a shared network, wallet id is stored in the shared location" { - dfx_start + dfx_start - assert_file_not_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + assert_file_not_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" - WALLET_ID="$(dfx identity get-wallet)" + WALLET_ID="$(dfx identity get-wallet)" - assert_command jq -r .identities.default.local "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" - assert_eq "$WALLET_ID" - assert_file_not_exists .dfx/local/wallets.json + assert_command jq -r .identities.default.local "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" + assert_eq "$WALLET_ID" + assert_file_not_exists .dfx/local/wallets.json } @test "for project-specific network create stores canister ids for default-ephemeral local networks in .dfx/{network}/canister_ids.json" { - dfx_new hello - define_project_network + dfx_new hello + define_project_network - dfx_start + dfx_start - dfx canister create --all --network local + dfx canister create --all --network local - # canister creates writes to a spinner (stderr), not stdout - assert_command dfx canister id hello_backend --network local - assert_match "$(jq -r .hello_backend.local <.dfx/local/canister_ids.json)" + # canister creates writes to a spinner (stderr), not stdout + assert_command dfx canister id hello_backend --network local + assert_match "$(jq -r .hello_backend.local <.dfx/local/canister_ids.json)" } @test "for project-specific network, create with wallet stores canister ids for configured-ephemeral networks in canister_ids.json" { - dfx_new hello - define_project_network - dfx_start + dfx_new hello + define_project_network + dfx_start - setup_actuallylocal_project_network - jq '.networks.actuallylocal.type="ephemeral"' dfx.json | sponge dfx.json - dfx_set_wallet + setup_actuallylocal_project_network + jq '.networks.actuallylocal.type="ephemeral"' dfx.json | sponge dfx.json + dfx_set_wallet - dfx canister create --all --network actuallylocal + dfx canister create --all --network actuallylocal - # canister creates writes to a spinner (stderr), not stdout - assert_command dfx canister id hello_backend --network actuallylocal - assert_match "$(jq -r .hello_backend.actuallylocal <.dfx/actuallylocal/canister_ids.json)" + # canister creates writes to a spinner (stderr), not stdout + assert_command dfx canister id hello_backend --network actuallylocal + assert_match "$(jq -r .hello_backend.actuallylocal <.dfx/actuallylocal/canister_ids.json)" } @test "dfx start and stop take into account dfx 0.11.x pid files" { - dfx_new hello - define_project_network - dfx_start + dfx_new hello + define_project_network + dfx_start - mv .dfx/network/local/pid .dfx/pid + mv .dfx/network/local/pid .dfx/pid - assert_command_fail dfx start - assert_match 'dfx is already running' + assert_command_fail dfx start + assert_match 'dfx is already running' - assert_command dfx stop - assert_file_not_exists .dfx/pid - assert_not_match "Nothing to do" - assert_command dfx stop - assert_match "Nothing to do" + assert_command dfx stop + assert_file_not_exists .dfx/pid + assert_not_match "Nothing to do" + assert_command dfx stop + assert_match "Nothing to do" } diff --git a/e2e/tests-dfx/provider.bash b/e2e/tests-dfx/provider.bash index d7cfbf7129..ddd37ed625 100644 --- a/e2e/tests-dfx/provider.bash +++ b/e2e/tests-dfx/provider.bash @@ -3,16 +3,16 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - [ -f replica.pid ] && kill -9 "$(cat replica.pid)" - dfx_stop + [ -f replica.pid ] && kill -9 "$(cat replica.pid)" + dfx_stop - standard_teardown + standard_teardown } # This test is around 15 seconds to run. I don't think it should be faster without raising the @@ -23,8 +23,8 @@ teardown() { # Start a replica manually on a specific port. "$(dfx cache show)/replica" --config ' - [http_handler] - write_port_to="port" + [http_handler] + write_port_to="port" ' & echo $! > replica.pid # Use a local file for the replica. sleep 5 # Wait for replica to be available. @@ -48,17 +48,17 @@ teardown() { } @test "network as URL creates the expected name" { - dfx_start - webserver_port=$(get_webserver_port) - dfx canister create --all --network "http://127.0.0.1:$webserver_port" - [ -d ".dfx/http___127_0_0_1_$webserver_port" ] + dfx_start + webserver_port=$(get_webserver_port) + dfx canister create --all --network "http://127.0.0.1:$webserver_port" + [ -d ".dfx/http___127_0_0_1_$webserver_port" ] } @test "network as URL does not create unexpected names" { - dfx_start - webserver_port=$(get_webserver_port) - dfx canister create --all --network "http://127.0.0.1:$webserver_port" - dfx build --all --network "http://127.0.0.1:$webserver_port" - dfx canister install --all --network "http://127.0.0.1:$webserver_port" - assert_eq 1 "$(find .dfx/http* -maxdepth 0 | wc -l | tr -d ' ')" + dfx_start + webserver_port=$(get_webserver_port) + dfx canister create --all --network "http://127.0.0.1:$webserver_port" + dfx build --all --network "http://127.0.0.1:$webserver_port" + dfx canister install --all --network "http://127.0.0.1:$webserver_port" + assert_eq 1 "$(find .dfx/http* -maxdepth 0 | wc -l | tr -d ' ')" } diff --git a/e2e/tests-dfx/remote.bash b/e2e/tests-dfx/remote.bash index cdc4b9f22c..5bd9a08d04 100644 --- a/e2e/tests-dfx/remote.bash +++ b/e2e/tests-dfx/remote.bash @@ -3,318 +3,318 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "canister call and sign" { - install_asset remote/call/actual - dfx_start - setup_actuallylocal_shared_network - - dfx identity new --storage-mode plaintext alice - - assert_command dfx deploy --network actuallylocal --identity alice - assert_command dfx canister call remote write '("initial data in the remote canister")' --identity alice --network actuallylocal - assert_command dfx canister call remote read --identity alice --network actuallylocal - assert_eq '("initial data in the remote canister")' - - REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) - echo "Remote canister id: $REMOTE_CANISTER_ID" - rm canister_ids.json - - install_asset remote/call/mock - jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json - setup_actuallylocal_shared_network - setup_local_shared_network - - # set up: remote method is update, local is query - # call remote method as update to make a change - assert_command dfx deploy --network actuallylocal - assert_command dfx canister call remote which_am_i --network actuallylocal - assert_eq '("actual")' - - cat dfx.json - cat canister_ids.json - - # - # Here the mock doesn't know about the method at all. - # In order for the candid decoder to know the type, dfx must both: - # - look up the canister by (remote) canister id - # - use the remote candid definition - # - assert_command dfx canister call --query "$REMOTE_CANISTER_ID" make_struct '("A query by principal", "B query by principal")' --network actuallylocal - assert_eq '(record { a = "A query by principal"; b = "B query by principal" })' - assert_command dfx canister call "$REMOTE_CANISTER_ID" make_struct '("A default by principal", "B default by principal")' --network actuallylocal - assert_eq '(record { a = "A default by principal"; b = "B default by principal" })' - assert_command dfx canister call --update "$REMOTE_CANISTER_ID" make_struct '("A update by principal", "B update by principal")' --network actuallylocal - assert_eq '(record { a = "A update by principal"; b = "B update by principal" })' - - assert_command dfx canister call --query remote make_struct '("A query by name", "B query by name")' --network actuallylocal - assert_eq '(record { a = "A query by name"; b = "B query by name" })' - assert_command dfx canister call remote make_struct '("A default by name", "B default by name")' --network actuallylocal - assert_eq '(record { a = "A default by name"; b = "B default by name" })' - assert_command dfx canister call --update remote make_struct '("A update by name", "B update by name")' --network actuallylocal - assert_eq '(record { a = "A update by name"; b = "B update by name" })' - - # This also should work when no canister type can be determined / if no info but the bare minimum of remote id and remote candid is given: - jq 'del(.canisters.remote.main)' dfx.json | sponge dfx.json - assert_command dfx canister call --query remote make_struct '("A query by name", "B query by name")' --network actuallylocal - assert_eq '(record { a = "A query by name"; b = "B query by name" })' - - # We can't check this for sign, because dfx canister send outputs something like this: - # To see the content of response, copy-paste the encoded string into cbor.me. - # Response: d9d9f7a2667374617475736[snip]2696e636970616c - - # - # Here: - # - the actual method is an update - # - the mock method is a query - # - in remote candid definition, the method is an update - # We try to call with --query. - # We expect dfx to notice that the method is in fact an update, which it knows from the remote candid definition. - # - assert_command_fail dfx canister call --query "$REMOTE_CANISTER_ID" actual_update_mock_query_remote_candid_update '("call by principal with --query")' --network actuallylocal - assert_match 'not a query method' - assert_command_fail dfx canister call --query remote actual_update_mock_query_remote_candid_update '("call by name with --query")' --network actuallylocal - assert_match 'not a query method' - - # And the same for dfx canister sign: - assert_command_fail dfx canister sign --query "$REMOTE_CANISTER_ID" actual_update_mock_query_remote_candid_update '("call by principal with --query")' --network actuallylocal - assert_match 'not a query method' - assert_command_fail dfx canister sign --query remote actual_update_mock_query_remote_candid_update '("call by name with --query")' --network actuallylocal - assert_match 'not a query method' + install_asset remote/call/actual + dfx_start + setup_actuallylocal_shared_network + + dfx identity new --storage-mode plaintext alice + + assert_command dfx deploy --network actuallylocal --identity alice + assert_command dfx canister call remote write '("initial data in the remote canister")' --identity alice --network actuallylocal + assert_command dfx canister call remote read --identity alice --network actuallylocal + assert_eq '("initial data in the remote canister")' + + REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) + echo "Remote canister id: $REMOTE_CANISTER_ID" + rm canister_ids.json + + install_asset remote/call/mock + jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json + setup_actuallylocal_shared_network + setup_local_shared_network + + # set up: remote method is update, local is query + # call remote method as update to make a change + assert_command dfx deploy --network actuallylocal + assert_command dfx canister call remote which_am_i --network actuallylocal + assert_eq '("actual")' + + cat dfx.json + cat canister_ids.json + + # + # Here the mock doesn't know about the method at all. + # In order for the candid decoder to know the type, dfx must both: + # - look up the canister by (remote) canister id + # - use the remote candid definition + # + assert_command dfx canister call --query "$REMOTE_CANISTER_ID" make_struct '("A query by principal", "B query by principal")' --network actuallylocal + assert_eq '(record { a = "A query by principal"; b = "B query by principal" })' + assert_command dfx canister call "$REMOTE_CANISTER_ID" make_struct '("A default by principal", "B default by principal")' --network actuallylocal + assert_eq '(record { a = "A default by principal"; b = "B default by principal" })' + assert_command dfx canister call --update "$REMOTE_CANISTER_ID" make_struct '("A update by principal", "B update by principal")' --network actuallylocal + assert_eq '(record { a = "A update by principal"; b = "B update by principal" })' + + assert_command dfx canister call --query remote make_struct '("A query by name", "B query by name")' --network actuallylocal + assert_eq '(record { a = "A query by name"; b = "B query by name" })' + assert_command dfx canister call remote make_struct '("A default by name", "B default by name")' --network actuallylocal + assert_eq '(record { a = "A default by name"; b = "B default by name" })' + assert_command dfx canister call --update remote make_struct '("A update by name", "B update by name")' --network actuallylocal + assert_eq '(record { a = "A update by name"; b = "B update by name" })' + + # This also should work when no canister type can be determined / if no info but the bare minimum of remote id and remote candid is given: + jq 'del(.canisters.remote.main)' dfx.json | sponge dfx.json + assert_command dfx canister call --query remote make_struct '("A query by name", "B query by name")' --network actuallylocal + assert_eq '(record { a = "A query by name"; b = "B query by name" })' + + # We can't check this for sign, because dfx canister send outputs something like this: + # To see the content of response, copy-paste the encoded string into cbor.me. + # Response: d9d9f7a2667374617475736[snip]2696e636970616c + + # + # Here: + # - the actual method is an update + # - the mock method is a query + # - in remote candid definition, the method is an update + # We try to call with --query. + # We expect dfx to notice that the method is in fact an update, which it knows from the remote candid definition. + # + assert_command_fail dfx canister call --query "$REMOTE_CANISTER_ID" actual_update_mock_query_remote_candid_update '("call by principal with --query")' --network actuallylocal + assert_match 'not a query method' + assert_command_fail dfx canister call --query remote actual_update_mock_query_remote_candid_update '("call by name with --query")' --network actuallylocal + assert_match 'not a query method' + + # And the same for dfx canister sign: + assert_command_fail dfx canister sign --query "$REMOTE_CANISTER_ID" actual_update_mock_query_remote_candid_update '("call by principal with --query")' --network actuallylocal + assert_match 'not a query method' + assert_command_fail dfx canister sign --query remote actual_update_mock_query_remote_candid_update '("call by name with --query")' --network actuallylocal + assert_match 'not a query method' } @test "canister create fails for a remote canister" { - install_asset remote/actual - dfx_start - setup_actuallylocal_shared_network + install_asset remote/actual + dfx_start + setup_actuallylocal_shared_network - dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext alice - assert_command dfx deploy --network actuallylocal --identity alice + assert_command dfx deploy --network actuallylocal --identity alice - REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) - echo "Remote canister id: $REMOTE_CANISTER_ID" - rm canister_ids.json + REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) + echo "Remote canister id: $REMOTE_CANISTER_ID" + rm canister_ids.json - install_asset remote/basic - setup_actuallylocal_shared_network - setup_local_shared_network - jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json + install_asset remote/basic + setup_actuallylocal_shared_network + setup_local_shared_network + jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json - assert_command_fail dfx canister create remote --network actuallylocal - assert_match "Canister 'remote' is a remote canister on network 'actuallylocal', and cannot be created from here." + assert_command_fail dfx canister create remote --network actuallylocal + assert_match "Canister 'remote' is a remote canister on network 'actuallylocal', and cannot be created from here." } @test "canister install fails for a remote canister" { - install_asset remote/actual - dfx_start - setup_actuallylocal_shared_network + install_asset remote/actual + dfx_start + setup_actuallylocal_shared_network - dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext alice - assert_command dfx deploy --network actuallylocal --identity alice + assert_command dfx deploy --network actuallylocal --identity alice - REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) - echo "Remote canister id: $REMOTE_CANISTER_ID" - rm canister_ids.json + REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) + echo "Remote canister id: $REMOTE_CANISTER_ID" + rm canister_ids.json - install_asset remote/basic - setup_actuallylocal_shared_network - setup_local_shared_network - jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json + install_asset remote/basic + setup_actuallylocal_shared_network + setup_local_shared_network + jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json - assert_command_fail dfx canister install remote --network actuallylocal - assert_match "Canister 'remote' is a remote canister on network 'actuallylocal', and cannot be installed from here." + assert_command_fail dfx canister install remote --network actuallylocal + assert_match "Canister 'remote' is a remote canister on network 'actuallylocal', and cannot be installed from here." } @test "canister create --all, canister install --all skip remote canisters" { - install_asset remote/actual - dfx_start - setup_actuallylocal_shared_network + install_asset remote/actual + dfx_start + setup_actuallylocal_shared_network - # - # Set up the "remote" canister, with a different controller in order to - # demonstrate that we don't try to install/upgrade it as a remote canister. - # - dfx identity new --storage-mode plaintext alice + # + # Set up the "remote" canister, with a different controller in order to + # demonstrate that we don't try to install/upgrade it as a remote canister. + # + dfx identity new --storage-mode plaintext alice - assert_command dfx deploy --network actuallylocal --identity alice - assert_command dfx canister call remote write '("this is data in the remote canister")' --identity alice --network actuallylocal + assert_command dfx deploy --network actuallylocal --identity alice + assert_command dfx canister call remote write '("this is data in the remote canister")' --identity alice --network actuallylocal - assert_command dfx canister call remote read --identity alice --network actuallylocal - assert_eq '("this is data in the remote canister")' + assert_command dfx canister call remote read --identity alice --network actuallylocal + assert_eq '("this is data in the remote canister")' - REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) - echo "Remote canister id: $REMOTE_CANISTER_ID" - rm canister_ids.json + REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) + echo "Remote canister id: $REMOTE_CANISTER_ID" + rm canister_ids.json - install_asset remote/basic - setup_actuallylocal_shared_network - setup_local_shared_network - jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json + install_asset remote/basic + setup_actuallylocal_shared_network + setup_local_shared_network + jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json - # Here we want to make sure that create+build+install works with the common flow - assert_command dfx canister create --all - assert_command dfx build - assert_command dfx canister install --all + # Here we want to make sure that create+build+install works with the common flow + assert_command dfx canister create --all + assert_command dfx build + assert_command dfx canister install --all - assert_command dfx canister call basic read_remote - assert_eq '("")' - assert_command dfx canister call remote which_am_i - assert_eq '("mock")' + assert_command dfx canister call basic read_remote + assert_eq '("")' + assert_command dfx canister call remote which_am_i + assert_eq '("mock")' - assert_command dfx canister create --all --network actuallylocal - assert_command dfx build --network actuallylocal -vv - assert_match "Not building canister 'remote'" - assert_command dfx canister install --all --network actuallylocal + assert_command dfx canister create --all --network actuallylocal + assert_command dfx build --network actuallylocal -vv + assert_match "Not building canister 'remote'" + assert_command dfx canister install --all --network actuallylocal - assert_command dfx canister call basic read_remote --network actuallylocal - assert_eq '("this is data in the remote canister")' + assert_command dfx canister call basic read_remote --network actuallylocal + assert_eq '("this is data in the remote canister")' - # We can change the value by calling the original canister - assert_command dfx canister call "${REMOTE_CANISTER_ID}" write '("altered data (by canister id) in the remote canister")' --network actuallylocal - assert_command dfx canister call basic read_remote --network actuallylocal - assert_eq '("altered data (by canister id) in the remote canister")' + # We can change the value by calling the original canister + assert_command dfx canister call "${REMOTE_CANISTER_ID}" write '("altered data (by canister id) in the remote canister")' --network actuallylocal + assert_command dfx canister call basic read_remote --network actuallylocal + assert_eq '("altered data (by canister id) in the remote canister")' - # We can also call through the canister name - assert_command dfx canister call remote write '("altered data (by canister name) in the remote canister")' --network actuallylocal - assert_command dfx canister call basic read_remote --network actuallylocal - assert_eq '("altered data (by canister name) in the remote canister")' + # We can also call through the canister name + assert_command dfx canister call remote write '("altered data (by canister name) in the remote canister")' --network actuallylocal + assert_command dfx canister call basic read_remote --network actuallylocal + assert_eq '("altered data (by canister name) in the remote canister")' - assert_command dfx canister call remote which_am_i --network actuallylocal - assert_eq '("actual")' + assert_command dfx canister call remote which_am_i --network actuallylocal + assert_eq '("actual")' - assert_command jq .basic.actuallylocal canister_ids.json - assert_eq '"'"$(dfx canister id basic --network actuallylocal)"'"' + assert_command jq .basic.actuallylocal canister_ids.json + assert_eq '"'"$(dfx canister id basic --network actuallylocal)"'"' - assert_command jq .remote canister_ids.json - assert_eq "null" + assert_command jq .remote canister_ids.json + assert_eq "null" - # Assert frontend declarations are actually created - dfx generate - assert_file_exists "src/declarations/remote/remote.did" - assert_file_exists "src/declarations/remote/remote.did.js" - assert_file_exists "src/declarations/remote/remote.did.d.ts" - assert_file_exists "src/declarations/remote/index.js" - assert_file_exists "src/declarations/remote/index.d.ts" + # Assert frontend declarations are actually created + dfx generate + assert_file_exists "src/declarations/remote/remote.did" + assert_file_exists "src/declarations/remote/remote.did.js" + assert_file_exists "src/declarations/remote/remote.did.d.ts" + assert_file_exists "src/declarations/remote/index.js" + assert_file_exists "src/declarations/remote/index.d.ts" } @test "for remote build, checks imports against the candid file rather than the mock" { - # In this test, a canister with a remote ID also has a candid file specified. - # When building for the remote network, we expect to use this candid file, - # and for methods calls that don't match the candid file to fail. - - install_asset remote/actual - dfx_start - setup_actuallylocal_shared_network - - # - # Set up the "remote" canister, with a different controller in order to - # demonstrate that we don't try to install/upgrade it as a remote canister. - # - dfx identity new --storage-mode plaintext alice - - assert_command dfx deploy --network actuallylocal --identity alice - - REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) - echo "Remote canister id: $REMOTE_CANISTER_ID" - rm canister_ids.json - - install_asset remote/extra - jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json - setup_actuallylocal_shared_network - setup_local_shared_network - - # We expect the local network deploy to succeed, because it is built using the candid file from - # the local canister. - assert_command dfx deploy - - # And we can call the extra method, - assert_command dfx canister call extra remote_extra - assert_eq '("extra!")' - - # We expect the remote network deploy to fail, because it is built using the candid file - # specified for the remote canister. That candid file doesn't define the extra method - # that is present in the mock. - assert_command_fail dfx deploy --network actuallylocal + # In this test, a canister with a remote ID also has a candid file specified. + # When building for the remote network, we expect to use this candid file, + # and for methods calls that don't match the candid file to fail. + + install_asset remote/actual + dfx_start + setup_actuallylocal_shared_network + + # + # Set up the "remote" canister, with a different controller in order to + # demonstrate that we don't try to install/upgrade it as a remote canister. + # + dfx identity new --storage-mode plaintext alice + + assert_command dfx deploy --network actuallylocal --identity alice + + REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) + echo "Remote canister id: $REMOTE_CANISTER_ID" + rm canister_ids.json + + install_asset remote/extra + jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json + setup_actuallylocal_shared_network + setup_local_shared_network + + # We expect the local network deploy to succeed, because it is built using the candid file from + # the local canister. + assert_command dfx deploy + + # And we can call the extra method, + assert_command dfx canister call extra remote_extra + assert_eq '("extra!")' + + # We expect the remote network deploy to fail, because it is built using the candid file + # specified for the remote canister. That candid file doesn't define the extra method + # that is present in the mock. + assert_command_fail dfx deploy --network actuallylocal } @test "build + install + call -- remote" { - install_asset remote/actual - dfx_start - setup_actuallylocal_shared_network + install_asset remote/actual + dfx_start + setup_actuallylocal_shared_network - # - # Set up the "remote" canister, with a different controller in order to - # demonstrate that we don't try to install/upgrade it as a remote canister. - # - dfx identity new --storage-mode plaintext alice + # + # Set up the "remote" canister, with a different controller in order to + # demonstrate that we don't try to install/upgrade it as a remote canister. + # + dfx identity new --storage-mode plaintext alice - assert_command dfx deploy --network actuallylocal --identity alice - assert_command dfx canister call remote write '("this is data in the remote canister")' --network actuallylocal --identity alice + assert_command dfx deploy --network actuallylocal --identity alice + assert_command dfx canister call remote write '("this is data in the remote canister")' --network actuallylocal --identity alice - assert_command dfx canister call remote read --network actuallylocal --identity alice - assert_eq '("this is data in the remote canister")' + assert_command dfx canister call remote read --network actuallylocal --identity alice + assert_eq '("this is data in the remote canister")' - REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) - echo "Remote canister id: $REMOTE_CANISTER_ID" - rm canister_ids.json + REMOTE_CANISTER_ID=$(jq -r .remote.actuallylocal canister_ids.json) + echo "Remote canister id: $REMOTE_CANISTER_ID" + rm canister_ids.json - install_asset remote/basic - setup_actuallylocal_shared_network - setup_local_shared_network - jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json + install_asset remote/basic + setup_actuallylocal_shared_network + setup_local_shared_network + jq ".canisters.remote.remote.id.actuallylocal=\"$REMOTE_CANISTER_ID\"" dfx.json | sponge dfx.json - assert_command dfx deploy - assert_command dfx canister call basic read_remote - assert_eq '("")' - assert_command dfx canister call remote which_am_i - assert_eq '("mock")' + assert_command dfx deploy + assert_command dfx canister call basic read_remote + assert_eq '("")' + assert_command dfx canister call remote which_am_i + assert_eq '("mock")' - assert_command dfx deploy --network actuallylocal -vv - assert_match "Not building canister 'remote'" - assert_command dfx canister call basic read_remote --network actuallylocal - assert_eq '("this is data in the remote canister")' + assert_command dfx deploy --network actuallylocal -vv + assert_match "Not building canister 'remote'" + assert_command dfx canister call basic read_remote --network actuallylocal + assert_eq '("this is data in the remote canister")' - # We can change the value by calling the original canister - assert_command dfx canister call "${REMOTE_CANISTER_ID}" write '("data altered by canister id in the remote canister")' --network actuallylocal - assert_command dfx canister call basic read_remote --network actuallylocal - assert_eq '("data altered by canister id in the remote canister")' + # We can change the value by calling the original canister + assert_command dfx canister call "${REMOTE_CANISTER_ID}" write '("data altered by canister id in the remote canister")' --network actuallylocal + assert_command dfx canister call basic read_remote --network actuallylocal + assert_eq '("data altered by canister id in the remote canister")' - # We can also call through the canister name - assert_command dfx canister call remote write '("data altered by canister name in the remote canister")' --network actuallylocal - assert_command dfx canister call basic read_remote --network actuallylocal - assert_eq '("data altered by canister name in the remote canister")' + # We can also call through the canister name + assert_command dfx canister call remote write '("data altered by canister name in the remote canister")' --network actuallylocal + assert_command dfx canister call basic read_remote --network actuallylocal + assert_eq '("data altered by canister name in the remote canister")' - assert_command dfx canister call remote which_am_i --network actuallylocal - assert_eq '("actual")' + assert_command dfx canister call remote which_am_i --network actuallylocal + assert_eq '("actual")' - assert_command jq .basic.actuallylocal canister_ids.json - assert_eq '"'"$(dfx canister id basic --network actuallylocal)"'"' + assert_command jq .basic.actuallylocal canister_ids.json + assert_eq '"'"$(dfx canister id basic --network actuallylocal)"'"' - assert_command jq .remote canister_ids.json - assert_eq "null" + assert_command jq .remote canister_ids.json + assert_eq "null" } @test "build step sets remote cid environment variable correctly" { - install_asset remote/envvar - install_asset wasm/identity # need to have some .did and .wasm files to point our custom canister to - dfx_start - setup_actuallylocal_shared_network + install_asset remote/envvar + install_asset wasm/identity # need to have some .did and .wasm files to point our custom canister to + dfx_start + setup_actuallylocal_shared_network - assert_command dfx deploy --network actuallylocal -vv - assert_match "CANISTER_ID_remote: qoctq-giaaa-aaaaa-aaaea-cai" + assert_command dfx deploy --network actuallylocal -vv + assert_match "CANISTER_ID_remote: qoctq-giaaa-aaaaa-aaaea-cai" } diff --git a/e2e/tests-dfx/remote_generate_binding.bash b/e2e/tests-dfx/remote_generate_binding.bash index f6dff63a3b..d29c16fe70 100644 --- a/e2e/tests-dfx/remote_generate_binding.bash +++ b/e2e/tests-dfx/remote_generate_binding.bash @@ -3,114 +3,114 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - standard_teardown + standard_teardown } @test "remote generate-binding succeeds for --all" { - install_asset remote_generate_binding/basic + install_asset remote_generate_binding/basic - assert_command dfx remote generate-binding --all + assert_command dfx remote generate-binding --all - assert_file_exists remote.mo - assert_file_exists remote.rs - assert_file_exists remote.ts - assert_file_exists remote.js + assert_file_exists remote.mo + assert_file_exists remote.rs + assert_file_exists remote.ts + assert_file_exists remote.js } @test "remote generate-binding --overwrite succeeds for --all" { - install_asset remote_generate_binding/basic - echo "to_overwrite" > remote.mo - echo "to_overwrite" > remote.rs + install_asset remote_generate_binding/basic + echo "to_overwrite" > remote.mo + echo "to_overwrite" > remote.rs - assert_command dfx remote generate-binding --overwrite --all + assert_command dfx remote generate-binding --overwrite --all - # should generate if not present - assert_file_exists remote.js - assert_file_exists remote.ts + # should generate if not present + assert_file_exists remote.js + assert_file_exists remote.ts - # should overwrite if already present - assert_neq "to_overwrite" "$(cat remote.mo)" - assert_neq "to_overwrite" "$(cat remote.rs)" + # should overwrite if already present + assert_neq "to_overwrite" "$(cat remote.mo)" + assert_neq "to_overwrite" "$(cat remote.rs)" } @test "remote generate-binding does not overwrite if file already present" { - install_asset remote_generate_binding/basic - echo "to_overwrite" > remote.mo - echo "to_overwrite" > remote.rs + install_asset remote_generate_binding/basic + echo "to_overwrite" > remote.mo + echo "to_overwrite" > remote.rs - assert_command dfx remote generate-binding --all + assert_command dfx remote generate-binding --all - # should generate if not present - assert_file_exists remote.ts - assert_file_exists remote.js + # should generate if not present + assert_file_exists remote.ts + assert_file_exists remote.js - # should not overwrite if already present - assert_eq "to_overwrite" "$(cat remote.mo)" - assert_eq "to_overwrite" "$(cat remote.rs)" + # should not overwrite if already present + assert_eq "to_overwrite" "$(cat remote.mo)" + assert_eq "to_overwrite" "$(cat remote.rs)" } @test "remote generate-binding succeeds for specific rust canister" { - install_asset remote_generate_binding/basic + install_asset remote_generate_binding/basic - assert_command dfx remote generate-binding remote-rust + assert_command dfx remote generate-binding remote-rust - assert_file_exists remote.rs - assert_file_not_exists remote.mo - assert_file_not_exists remote.ts - assert_file_not_exists remote.js + assert_file_exists remote.rs + assert_file_not_exists remote.mo + assert_file_not_exists remote.ts + assert_file_not_exists remote.js } @test "remote generate-binding succeeds for specific motoko canister" { - install_asset remote_generate_binding/basic + install_asset remote_generate_binding/basic - assert_command dfx remote generate-binding remote-motoko + assert_command dfx remote generate-binding remote-motoko - assert_file_exists remote.mo - assert_file_not_exists remote.rs - assert_file_not_exists remote.ts - assert_file_not_exists remote.js + assert_file_exists remote.mo + assert_file_not_exists remote.rs + assert_file_not_exists remote.ts + assert_file_not_exists remote.js } @test "remote generate-binding succeeds for specific javascript canister" { - install_asset remote_generate_binding/basic + install_asset remote_generate_binding/basic - assert_command dfx remote generate-binding remote-javascript + assert_command dfx remote generate-binding remote-javascript - assert_file_exists remote.js - assert_file_not_exists remote.mo - assert_file_not_exists remote.rs - assert_file_not_exists remote.ts + assert_file_exists remote.js + assert_file_not_exists remote.mo + assert_file_not_exists remote.rs + assert_file_not_exists remote.ts } @test "remote generate-binding succeeds for specific typescript canister" { - install_asset remote_generate_binding/basic + install_asset remote_generate_binding/basic - assert_command dfx remote generate-binding remote-typescript + assert_command dfx remote generate-binding remote-typescript - assert_file_exists remote.ts - assert_file_not_exists remote.mo - assert_file_not_exists remote.rs - assert_file_not_exists remote.js + assert_file_exists remote.ts + assert_file_not_exists remote.mo + assert_file_not_exists remote.rs + assert_file_not_exists remote.js } @test "remote generate-binding --overwrite succeeds for specific canister" { - install_asset remote_generate_binding/basic - echo "to_overwrite" > remote.mo + install_asset remote_generate_binding/basic + echo "to_overwrite" > remote.mo - # should not overwrite without --overwrite - assert_command dfx remote generate-binding remote-motoko - assert_match 'already exists' - assert_eq "to_overwrite" "$(cat remote.mo)" + # should not overwrite without --overwrite + assert_command dfx remote generate-binding remote-motoko + assert_match 'already exists' + assert_eq "to_overwrite" "$(cat remote.mo)" - # should overwrite with --overwrite - assert_command dfx remote generate-binding --overwrite remote-motoko - assert_neq "to_overwrite" "$(cat remote.mo)" + # should overwrite with --overwrite + assert_command dfx remote generate-binding --overwrite remote-motoko + assert_neq "to_overwrite" "$(cat remote.mo)" } @test "remote generate-binding incomplete command rejected" { - assert_command_fail dfx remote generate-binding + assert_command_fail dfx remote generate-binding } diff --git a/e2e/tests-dfx/request_status.bash b/e2e/tests-dfx/request_status.bash index 21246ef8e5..ef918b2c4c 100644 --- a/e2e/tests-dfx/request_status.bash +++ b/e2e/tests-dfx/request_status.bash @@ -3,29 +3,29 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "request-status output raw" { - install_asset greet - dfx_start - dfx canister create --all - dfx build + install_asset greet + dfx_start + dfx canister create --all + dfx build - dfx canister install hello_backend + dfx canister install hello_backend - assert_command dfx canister call --async hello_backend greet Bob + assert_command dfx canister call --async hello_backend greet Bob - # shellcheck disable=SC2154 - assert_command dfx canister request-status --output raw "$stdout" "$(dfx canister id hello_backend)" - assert_eq '4449444c0001710b48656c6c6f2c20426f6221' + # shellcheck disable=SC2154 + assert_command dfx canister request-status --output raw "$stdout" "$(dfx canister id hello_backend)" + assert_eq '4449444c0001710b48656c6c6f2c20426f6221' } diff --git a/e2e/tests-dfx/rust.bash b/e2e/tests-dfx/rust.bash index eea3705196..be545b941c 100644 --- a/e2e/tests-dfx/rust.bash +++ b/e2e/tests-dfx/rust.bash @@ -4,61 +4,61 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "rust starter project can build and call" { - dfx_new_rust hello + dfx_new_rust hello - dfx_start - dfx canister create --all - assert_command dfx build hello_backend -vvv - assert_match "Shrinking WASM" - assert_command dfx canister install hello_backend - assert_command dfx canister call hello_backend greet dfinity - assert_match '("Hello, dfinity!")' + dfx_start + dfx canister create --all + assert_command dfx build hello_backend -vvv + assert_match "Shrinking WASM" + assert_command dfx canister install hello_backend + assert_command dfx canister call hello_backend greet dfinity + assert_match '("Hello, dfinity!")' - # dfx sets the candid:service metadata - dfx canister metadata hello_backend candid:service >installed.did - assert_command diff src/hello_backend/hello_backend.did installed.did + # dfx sets the candid:service metadata + dfx canister metadata hello_backend candid:service >installed.did + assert_command diff src/hello_backend/hello_backend.did installed.did } @test "rust canister can resolve dependencies" { - dfx_new_rust rust_deps - install_asset rust_deps - dfx_start - assert_command dfx deploy - assert_command dfx canister call multiply_deps read - assert_match '(1 : nat)' - assert_command dfx canister call multiply_deps mul '(3)' - assert_match '(9 : nat)' - assert_command dfx canister call rust_deps read - assert_match '(9 : nat)' + dfx_new_rust rust_deps + install_asset rust_deps + dfx_start + assert_command dfx deploy + assert_command dfx canister call multiply_deps read + assert_match '(1 : nat)' + assert_command dfx canister call multiply_deps mul '(3)' + assert_match '(9 : nat)' + assert_command dfx canister call rust_deps read + assert_match '(9 : nat)' } @test "rust canister can have nonstandard target dir location" { - dfx_new_rust - # We used to set CARGO_TARGET_DIR="$(echo -ne '\x81')" - # But since rust 1.69, `cargo metadata` returns - # error: path contains invalid UTF-8 characters - CARGO_TARGET_DIR="custom-target" - export CARGO_TARGET_DIR - dfx_start - assert_command dfx deploy - assert_command dfx canister call e2e_project_backend greet dfinity + dfx_new_rust + # We used to set CARGO_TARGET_DIR="$(echo -ne '\x81')" + # But since rust 1.69, `cargo metadata` returns + # error: path contains invalid UTF-8 characters + CARGO_TARGET_DIR="custom-target" + export CARGO_TARGET_DIR + dfx_start + assert_command dfx deploy + assert_command dfx canister call e2e_project_backend greet dfinity } @test "rust canister fails to build with missing lockfile" { - dfx_new_rust - rm -f ./Cargo.lock - dfx_start - assert_command_fail dfx deploy - cargo update - assert_command dfx deploy + dfx_new_rust + rm -f ./Cargo.lock + dfx_start + assert_command_fail dfx deploy + cargo update + assert_command dfx deploy } diff --git a/e2e/tests-dfx/schema.bash b/e2e/tests-dfx/schema.bash index b3433050ee..3886840934 100644 --- a/e2e/tests-dfx/schema.bash +++ b/e2e/tests-dfx/schema.bash @@ -3,22 +3,22 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop - standard_teardown + dfx_stop + standard_teardown } @test "dfx schema prints valid json" { - assert_command dfx schema --outfile out.json - # make sure out.json contains exactly one json object - assert_command jq type out.json - assert_eq '"object"' + assert_command dfx schema --outfile out.json + # make sure out.json contains exactly one json object + assert_command jq type out.json + assert_eq '"object"' } @test "dfx schema still works with broken dfx.json" { - jq '.broken_key="blahblahblah"' dfx.json | sponge dfx.json - assert_command dfx schema + jq '.broken_key="blahblahblah"' dfx.json | sponge dfx.json + assert_command dfx schema } diff --git a/e2e/tests-dfx/shared_local_network.bash b/e2e/tests-dfx/shared_local_network.bash index 586b38e1f8..c1a82364a7 100644 --- a/e2e/tests-dfx/shared_local_network.bash +++ b/e2e/tests-dfx/shared_local_network.bash @@ -3,135 +3,135 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx start creates no files in the current directory when run from an empty directory" { - dfx_start - assert_command find . - assert_eq "." + dfx_start + assert_command find . + assert_eq "." } @test "dfx start creates only an empty .dfx directory when run from a project" { - dfx_new hello - START_DIR_CONTENTS="$(find .)" - dfx_start - END_DIR_CONTENTS="$(find . | grep -v '^\./\.dfx$')" - assert_eq "$START_DIR_CONTENTS" "$END_DIR_CONTENTS" + dfx_new hello + START_DIR_CONTENTS="$(find .)" + dfx_start + END_DIR_CONTENTS="$(find . | grep -v '^\./\.dfx$')" + assert_eq "$START_DIR_CONTENTS" "$END_DIR_CONTENTS" } @test "project data is cleared after dfx start --clean from outside the project" { - mkdir somewhere - ( - cd somewhere - dfx_start - ) - - ( - dfx_new hello - dfx deploy - dfx canister id hello_backend - ) - - mkdir somewhere_else - ( - cd somewhere_else - dfx_stop - dfx_start --clean - ) - - ( - cd hello - assert_command_fail dfx canister id hello_backend - ) -} - -@test "multiple projects with the same canister names" { + mkdir somewhere + ( + cd somewhere dfx_start + ) - mkdir a - cd a + ( dfx_new hello - install_asset counter dfx deploy - HELLO_BACKEND_A="$(dfx canister id hello_backend)" - dfx canister call hello_backend inc - dfx canister call hello_backend inc - cd ../.. + dfx canister id hello_backend + ) - mkdir b - cd b - dfx_new hello - install_asset counter - dfx deploy - HELLO_BACKEND_B="$(dfx canister id hello_backend)" - dfx canister call hello_backend write '(6: nat)' - cd ../.. + mkdir somewhere_else + ( + cd somewhere_else + dfx_stop + dfx_start --clean + ) - assert_command dfx canister call "$HELLO_BACKEND_A" read + ( + cd hello + assert_command_fail dfx canister id hello_backend + ) +} + +@test "multiple projects with the same canister names" { + dfx_start + + mkdir a + cd a + dfx_new hello + install_asset counter + dfx deploy + HELLO_BACKEND_A="$(dfx canister id hello_backend)" + dfx canister call hello_backend inc + dfx canister call hello_backend inc + cd ../.. + + mkdir b + cd b + dfx_new hello + install_asset counter + dfx deploy + HELLO_BACKEND_B="$(dfx canister id hello_backend)" + dfx canister call hello_backend write '(6: nat)' + cd ../.. + + assert_command dfx canister call "$HELLO_BACKEND_A" read + assert_eq "(2 : nat)" + ( + cd a/hello + assert_command dfx canister call hello_backend read assert_eq "(2 : nat)" - ( - cd a/hello - assert_command dfx canister call hello_backend read - assert_eq "(2 : nat)" - ) + ) - assert_command dfx canister call "$HELLO_BACKEND_B" read + assert_command dfx canister call "$HELLO_BACKEND_B" read + assert_eq "(6 : nat)" + ( + cd b/hello + assert_command dfx canister call hello_backend read assert_eq "(6 : nat)" - ( - cd b/hello - assert_command dfx canister call hello_backend read - assert_eq "(6 : nat)" - ) + ) } @test "wallet config file is reset after start --clean" { - dfx_start - - ( - dfx_new hello - dfx wallet balance - dfx identity get-wallet - assert_command dfx diagnose - assert_eq "No problems found" - ) + dfx_start - dfx_stop - dfx_start --clean - - ( - cd hello - assert_command_fail dfx diagnose - assert_match "No wallet found; nothing to do" - ) + ( + dfx_new hello + dfx wallet balance + dfx identity get-wallet + assert_command dfx diagnose + assert_eq "No problems found" + ) + + dfx_stop + dfx_start --clean + + ( + cd hello + assert_command_fail dfx diagnose + assert_match "No wallet found; nothing to do" + ) } @test "separate projects use the same wallet id for a given identity" { - dfx_start + dfx_start - ( dfx_new a ) - ( dfx_new b ) - WALLET_ID_A="$(cd a ; dfx identity get-wallet)" - WALLET_ID_B="$(cd b ; dfx identity get-wallet)" + ( dfx_new a ) + ( dfx_new b ) + WALLET_ID_A="$(cd a ; dfx identity get-wallet)" + WALLET_ID_B="$(cd b ; dfx identity get-wallet)" - assert_eq "$WALLET_ID_A" "$WALLET_ID_B" + assert_eq "$WALLET_ID_A" "$WALLET_ID_B" } @test "dfx identity rename renames wallet for shared local network" { - dfx_start + dfx_start - dfx identity new alice --storage-mode plaintext - ALICE_WALLET="$(dfx identity get-wallet --identity alice)" + dfx identity new alice --storage-mode plaintext + ALICE_WALLET="$(dfx identity get-wallet --identity alice)" - dfx identity rename alice bob - BOB_WALLET="$(dfx identity get-wallet --identity bob)" + dfx identity rename alice bob + BOB_WALLET="$(dfx identity get-wallet --identity bob)" - assert_eq "$ALICE_WALLET" "$BOB_WALLET" + assert_eq "$ALICE_WALLET" "$BOB_WALLET" } diff --git a/e2e/tests-dfx/sign_send.bash b/e2e/tests-dfx/sign_send.bash index 61b879ed89..a0b848c6fd 100644 --- a/e2e/tests-dfx/sign_send.bash +++ b/e2e/tests-dfx/sign_send.bash @@ -3,81 +3,81 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "sign + send" { - install_asset counter - dfx_start - dfx deploy + install_asset counter + dfx_start + dfx deploy - assert_command dfx canister sign --query hello_backend read - assert_eq "Query message generated at [message.json]" + assert_command dfx canister sign --query hello_backend read + assert_eq "Query message generated at [message.json]" - sleep 10 - echo y | assert_command dfx canister send message.json + sleep 10 + echo y | assert_command dfx canister send message.json - assert_command_fail dfx canister send message.json --status - assert_eq "Error: Can only check request_status on update calls." + assert_command_fail dfx canister send message.json --status + assert_eq "Error: Can only check request_status on update calls." - assert_command_fail dfx canister sign --query hello_backend read - assert_eq "Error: [message.json] already exists, please specify a different output file name." + assert_command_fail dfx canister sign --query hello_backend read + assert_eq "Error: [message.json] already exists, please specify a different output file name." - assert_command dfx canister sign --update hello_backend inc --file message-inc.json - assert_eq "Update message generated at [message-inc.json] + assert_command dfx canister sign --update hello_backend inc --file message-inc.json + assert_eq "Update message generated at [message-inc.json] Signed request_status append to update message in [message-inc.json]" - sleep 10 - echo y | assert_command dfx canister send message-inc.json - assert_command dfx canister send message-inc.json --status - assert_match "To see the content of response, copy-paste the encoded string into cbor.me." + sleep 10 + echo y | assert_command dfx canister send message-inc.json + assert_command dfx canister send message-inc.json --status + assert_match "To see the content of response, copy-paste the encoded string into cbor.me." } @test "sign outside of a dfx project" { - cd "$E2E_TEMP_DIR" - mkdir not-a-project-dir - cd not-a-project-dir + cd "$E2E_TEMP_DIR" + mkdir not-a-project-dir + cd not-a-project-dir - assert_command dfx canister sign --query rwlgt-iiaaa-aaaaa-aaaaa-cai read --network ic - assert_match "Query message generated at \[message.json\]" + assert_command dfx canister sign --query rwlgt-iiaaa-aaaaa-aaaaa-cai read --network ic + assert_match "Query message generated at \[message.json\]" } @test "sign subcommand accepts argument from a file" { - install_asset greet - dfx_start - dfx deploy - TMP_NAME_FILE="$(mktemp)" - printf '("Names can be very long")' > "$TMP_NAME_FILE" + install_asset greet + dfx_start + dfx deploy + TMP_NAME_FILE="$(mktemp)" + printf '("Names can be very long")' > "$TMP_NAME_FILE" - assert_command dfx canister sign --argument-file "$TMP_NAME_FILE" --query hello_backend greet - assert_eq "Query message generated at [message.json]" + assert_command dfx canister sign --argument-file "$TMP_NAME_FILE" --query hello_backend greet + assert_eq "Query message generated at [message.json]" - assert_command jq -rc .arg message.json - assert_match "[68,73,68,76,0,1,113,21,78,97,109,101,115,32,99,97,110,32,98,101,32,118,114,121,32,108,111,110,103]" + assert_command jq -rc .arg message.json + assert_match "[68,73,68,76,0,1,113,21,78,97,109,101,115,32,99,97,110,32,98,101,32,118,114,121,32,108,111,110,103]" - rm "$TMP_NAME_FILE" + rm "$TMP_NAME_FILE" } @test "sign subcommand accepts argument from stdin" { - install_asset greet - dfx_start - dfx deploy - TMP_NAME_FILE="$(mktemp)" - printf '("stdin")' > "$TMP_NAME_FILE" + install_asset greet + dfx_start + dfx deploy + TMP_NAME_FILE="$(mktemp)" + printf '("stdin")' > "$TMP_NAME_FILE" - assert_command dfx canister sign --argument-file - --query hello_backend greet < "$TMP_NAME_FILE" - assert_eq "Query message generated at [message.json]" + assert_command dfx canister sign --argument-file - --query hello_backend greet < "$TMP_NAME_FILE" + assert_eq "Query message generated at [message.json]" - assert_command jq -rc .arg message.json - assert_match "[68,73,68,76,0,1,113,5,115,116,100,105,110]" + assert_command jq -rc .arg message.json + assert_match "[68,73,68,76,0,1,113,5,115,116,100,105,110]" - rm "$TMP_NAME_FILE" + rm "$TMP_NAME_FILE" } diff --git a/e2e/tests-dfx/signals.bash b/e2e/tests-dfx/signals.bash index 83251018a1..daa42a8c4c 100644 --- a/e2e/tests-dfx/signals.bash +++ b/e2e/tests-dfx/signals.bash @@ -3,15 +3,15 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx replica kills the replica upon SIGINT" { @@ -23,18 +23,18 @@ teardown() { } dfx_replica_kills_replica() { - skip "dfx replica and bootstrap are deprecated" - signal=$1 + skip "dfx replica and bootstrap are deprecated" + signal=$1 - dfx_patchelf - dfx replica --port 0 & - DFX_PID=$! + dfx_patchelf + dfx replica --port 0 & + DFX_PID=$! - # wait for replica to start - assert_file_eventually_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port" 15s + # wait for replica to start + assert_file_eventually_exists "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/replica-configuration/replica-1.port" 15s - kill -"$signal" "$DFX_PID" + kill -"$signal" "$DFX_PID" - assert_process_exits $DFX_PID 15s - assert_no_dfx_start_or_replica_processes + assert_process_exits $DFX_PID 15s + assert_no_dfx_start_or_replica_processes } diff --git a/e2e/tests-dfx/start.bash b/e2e/tests-dfx/start.bash index 08c9915797..2ba61ab7b7 100644 --- a/e2e/tests-dfx/start.bash +++ b/e2e/tests-dfx/start.bash @@ -3,372 +3,372 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx restarts the replica" { - dfx_new hello - dfx_start - - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' - - REPLICA_PID=$(get_replica_pid) - - echo "replica pid is $REPLICA_PID" - - kill -KILL "$REPLICA_PID" - assert_process_exits "$REPLICA_PID" 15s - - timeout 15s sh -c \ - 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ - || (echo "replica did not restart" && ps aux && exit 1) - wait_until_replica_healthy - - # Sometimes initially get an error like: - # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module - # but the condition clears. - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - # even after the above, still sometimes fails with - # IC0515: Certified state is not available yet. Please try again... - sleep 10 - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - - assert_command dfx canister call hello_backend greet '("Omega")' - assert_eq '("Hello, Omega!")' + dfx_new hello + dfx_start + + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' + + REPLICA_PID=$(get_replica_pid) + + echo "replica pid is $REPLICA_PID" + + kill -KILL "$REPLICA_PID" + assert_process_exits "$REPLICA_PID" 15s + + timeout 15s sh -c \ + 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ + || (echo "replica did not restart" && ps aux && exit 1) + wait_until_replica_healthy + + # Sometimes initially get an error like: + # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module + # but the condition clears. + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + # even after the above, still sometimes fails with + # IC0515: Certified state is not available yet. Please try again... + sleep 10 + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + + assert_command dfx canister call hello_backend greet '("Omega")' + assert_eq '("Hello, Omega!")' } @test "dfx restarts icx-proxy" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' - ICX_PROXY_PID=$(get_icx_proxy_pid) + ICX_PROXY_PID=$(get_icx_proxy_pid) - echo "icx-proxy pid is $ICX_PROXY_PID" + echo "icx-proxy pid is $ICX_PROXY_PID" - kill -KILL "$ICX_PROXY_PID" - assert_process_exits "$ICX_PROXY_PID" 15s + kill -KILL "$ICX_PROXY_PID" + assert_process_exits "$ICX_PROXY_PID" 15s - ID=$(dfx canister id hello_frontend) + ID=$(dfx canister id hello_frontend) - timeout 15s sh -c \ - "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY\"/webserver-port)/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ - || (echo "icx-proxy did not restart" && ps aux && exit 1) + timeout 15s sh -c \ + "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY\"/webserver-port)/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ + || (echo "icx-proxy did not restart" && ps aux && exit 1) - assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" + assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" } @test "dfx restarts icx-proxy when the replica restarts" { - dfx_new hello - dfx_start - - install_asset greet - assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Alpha")' - assert_eq '("Hello, Alpha!")' - - REPLICA_PID=$(get_replica_pid) - ICX_PROXY_PID=$(get_icx_proxy_pid) - - echo "replica pid is $REPLICA_PID" - echo "icx-proxy pid is $ICX_PROXY_PID" - - kill -KILL "$REPLICA_PID" - assert_process_exits "$REPLICA_PID" 15s - assert_process_exits "$ICX_PROXY_PID" 15s - - timeout 15s sh -c \ - 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ - || (echo "replica did not restart" && ps aux && exit 1) - wait_until_replica_healthy - - # Sometimes initially get an error like: - # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module - # but the condition clears. - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - # even after the above, still sometimes fails with - # IC0515: Certified state is not available yet. Please try again... - sleep 10 - timeout 30s sh -c \ - "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ - || (echo "canister call did not succeed") # but continue, for better error reporting - - assert_command dfx canister call hello_backend greet '("Omega")' - assert_eq '("Hello, Omega!")' - - ID=$(dfx canister id hello_frontend) - - timeout 15s sh -c \ - "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port\")/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ - || (echo "icx-proxy did not restart" && ps aux && exit 1) - - assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" + dfx_new hello + dfx_start + + install_asset greet + assert_command dfx deploy + assert_command dfx canister call hello_backend greet '("Alpha")' + assert_eq '("Hello, Alpha!")' + + REPLICA_PID=$(get_replica_pid) + ICX_PROXY_PID=$(get_icx_proxy_pid) + + echo "replica pid is $REPLICA_PID" + echo "icx-proxy pid is $ICX_PROXY_PID" + + kill -KILL "$REPLICA_PID" + assert_process_exits "$REPLICA_PID" 15s + assert_process_exits "$ICX_PROXY_PID" 15s + + timeout 15s sh -c \ + 'until dfx ping; do echo waiting for replica to restart; sleep 1; done' \ + || (echo "replica did not restart" && ps aux && exit 1) + wait_until_replica_healthy + + # Sometimes initially get an error like: + # IC0304: Attempt to execute a message on canister <>> which contains no Wasm module + # but the condition clears. + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + # even after the above, still sometimes fails with + # IC0515: Certified state is not available yet. Please try again... + sleep 10 + timeout 30s sh -c \ + "until dfx canister call hello_backend greet '(\"wait\")'; do echo waiting for any canister call to succeed; sleep 1; done" \ + || (echo "canister call did not succeed") # but continue, for better error reporting + + assert_command dfx canister call hello_backend greet '("Omega")' + assert_eq '("Hello, Omega!")' + + ID=$(dfx canister id hello_frontend) + + timeout 15s sh -c \ + "until curl --fail http://localhost:\$(cat \"$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/webserver-port\")/sample-asset.txt?canisterId=$ID; do echo waiting for icx-proxy to restart; sleep 1; done" \ + || (echo "icx-proxy did not restart" && ps aux && exit 1) + + assert_command curl --fail http://localhost:"$(get_webserver_port)"/sample-asset.txt?canisterId="$ID" } @test "dfx start honors replica port configuration" { - create_networks_json - replica_port=$(get_ephemeral_port) - jq ".local.replica.port=$replica_port" "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + create_networks_json + replica_port=$(get_ephemeral_port) + jq ".local.replica.port=$replica_port" "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - dfx_start + dfx_start - assert_command dfx info replica-port - assert_eq "$replica_port" + assert_command dfx info replica-port + assert_eq "$replica_port" } @test "dfx starts replica with subnet_type application - project defaults" { - install_asset subnet_type/project_defaults/application - define_project_network - jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json + install_asset subnet_type/project_defaults/application + define_project_network + jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_match "subnet_type: Application" + assert_command dfx start --background + assert_match "subnet_type: Application" } @test "dfx starts replica with subnet_type verifiedapplication - project defaults" { - install_asset subnet_type/project_defaults/verified_application - define_project_network - jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json + install_asset subnet_type/project_defaults/verified_application + define_project_network + jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_match "subnet_type: VerifiedApplication" + assert_command dfx start --background + assert_match "subnet_type: VerifiedApplication" } @test "dfx starts replica with subnet_type system - project defaults" { - install_asset subnet_type/project_defaults/system - define_project_network - jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json + install_asset subnet_type/project_defaults/system + define_project_network + jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_match "subnet_type: System" + assert_command dfx start --background + assert_match "subnet_type: System" } @test "dfx starts replica with subnet_type application - local network" { - install_asset subnet_type/project_network_settings/application - define_project_network - jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json + install_asset subnet_type/project_network_settings/application + define_project_network + jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_match "subnet_type: Application" + assert_command dfx start --background + assert_match "subnet_type: Application" } @test "dfx starts replica with subnet_type verifiedapplication - local network" { - install_asset subnet_type/project_network_settings/verified_application - define_project_network - jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json + install_asset subnet_type/project_network_settings/verified_application + define_project_network + jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_match "subnet_type: VerifiedApplication" + assert_command dfx start --background + assert_match "subnet_type: VerifiedApplication" } @test "dfx starts replica with subnet_type system - local network" { - install_asset subnet_type/project_network_settings/system - define_project_network - jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json + install_asset subnet_type/project_network_settings/system + define_project_network + jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_match "subnet_type: System" + assert_command dfx start --background + assert_match "subnet_type: System" } @test "dfx starts replica with subnet_type application - shared network" { - install_shared_asset subnet_type/shared_network_settings/application - jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + install_shared_asset subnet_type/shared_network_settings/application + jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background - assert_match "subnet_type: Application" + assert_command dfx start --background + assert_match "subnet_type: Application" } @test "dfx starts replica with subnet_type verifiedapplication - shared network" { - install_shared_asset subnet_type/shared_network_settings/verified_application - jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + install_shared_asset subnet_type/shared_network_settings/verified_application + jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background - assert_match "subnet_type: VerifiedApplication" + assert_command dfx start --background + assert_match "subnet_type: VerifiedApplication" } @test "dfx starts replica with subnet_type system - shared network" { - install_shared_asset subnet_type/shared_network_settings/system - jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + install_shared_asset subnet_type/shared_network_settings/system + jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background - assert_match "subnet_type: System" + assert_command dfx start --background + assert_match "subnet_type: System" } @test "dfx start detects if dfx is already running - shared network" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - assert_command_fail dfx start - assert_match "dfx is already running" + assert_command_fail dfx start + assert_match "dfx is already running" } @test "dfx start for shared network warns about default settings specified in dfx.json that do not apply" { - dfx_new hello - - IGNORED_MESSAGE="Ignoring the 'defaults' field in dfx.json because project settings never apply to the shared network." - APPLY_SETTINGS_MESSAGE="To apply these settings to the shared network, define them in .*/config-root/.config/dfx/networks.json like so" - - jq 'del(.defaults)' dfx.json | sponge dfx.json - jq '.defaults.bitcoin.enabled=true' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_contains "$IGNORED_MESSAGE" - assert_match "$APPLY_SETTINGS_MESSAGE" - assert_contains '"bitcoin": {' - assert_not_contains '"replica"' - assert_not_contains '"canister_http"' - assert_command dfx stop - - jq 'del(.defaults)' dfx.json | sponge dfx.json - jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_contains "$IGNORED_MESSAGE" - assert_match "$APPLY_SETTINGS_MESSAGE" - assert_not_contains '"bitcoin"' - assert_contains '"replica": {' - assert_not_contains '"canister_http"' - assert_command dfx stop - - jq 'del(.defaults)' dfx.json | sponge dfx.json - jq '.defaults.canister_http.enabled=false' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_contains "$IGNORED_MESSAGE" - assert_match "$APPLY_SETTINGS_MESSAGE" - assert_not_contains '"bitcoin"' - assert_not_contains '"replica"' - assert_contains '"canister_http": {' - assert_command dfx stop - - jq 'del(.defaults)' dfx.json | sponge dfx.json - jq '.defaults.bitcoin.enabled=true' dfx.json | sponge dfx.json - jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json - jq '.defaults.canister_http.enabled=false' dfx.json | sponge dfx.json - assert_command dfx start --background - assert_contains "$IGNORED_MESSAGE" - assert_match "$APPLY_SETTINGS_MESSAGE" - assert_contains '"bitcoin": {' - assert_contains '"replica": {' - assert_contains '"canister_http": {' - assert_command dfx stop + dfx_new hello + + IGNORED_MESSAGE="Ignoring the 'defaults' field in dfx.json because project settings never apply to the shared network." + APPLY_SETTINGS_MESSAGE="To apply these settings to the shared network, define them in .*/config-root/.config/dfx/networks.json like so" + + jq 'del(.defaults)' dfx.json | sponge dfx.json + jq '.defaults.bitcoin.enabled=true' dfx.json | sponge dfx.json + assert_command dfx start --background + assert_contains "$IGNORED_MESSAGE" + assert_match "$APPLY_SETTINGS_MESSAGE" + assert_contains '"bitcoin": {' + assert_not_contains '"replica"' + assert_not_contains '"canister_http"' + assert_command dfx stop + + jq 'del(.defaults)' dfx.json | sponge dfx.json + jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json + assert_command dfx start --background + assert_contains "$IGNORED_MESSAGE" + assert_match "$APPLY_SETTINGS_MESSAGE" + assert_not_contains '"bitcoin"' + assert_contains '"replica": {' + assert_not_contains '"canister_http"' + assert_command dfx stop + + jq 'del(.defaults)' dfx.json | sponge dfx.json + jq '.defaults.canister_http.enabled=false' dfx.json | sponge dfx.json + assert_command dfx start --background + assert_contains "$IGNORED_MESSAGE" + assert_match "$APPLY_SETTINGS_MESSAGE" + assert_not_contains '"bitcoin"' + assert_not_contains '"replica"' + assert_contains '"canister_http": {' + assert_command dfx stop + + jq 'del(.defaults)' dfx.json | sponge dfx.json + jq '.defaults.bitcoin.enabled=true' dfx.json | sponge dfx.json + jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json + jq '.defaults.canister_http.enabled=false' dfx.json | sponge dfx.json + assert_command dfx start --background + assert_contains "$IGNORED_MESSAGE" + assert_match "$APPLY_SETTINGS_MESSAGE" + assert_contains '"bitcoin": {' + assert_contains '"replica": {' + assert_contains '"canister_http": {' + assert_command dfx stop } @test "dfx starts replica with correct log level - project defaults" { - dfx_new - jq '.defaults.replica.log_level="warning"' dfx.json | sponge dfx.json - define_project_network + dfx_new + jq '.defaults.replica.log_level="warning"' dfx.json | sponge dfx.json + define_project_network - assert_command dfx start --background --verbose - assert_match "log level: Warning" - assert_command dfx stop + assert_command dfx start --background --verbose + assert_match "log level: Warning" + assert_command dfx stop - jq '.defaults.replica.log_level="critical"' dfx.json | sponge dfx.json - assert_command dfx start --background --verbose --clean - assert_match "log level: Critical" + jq '.defaults.replica.log_level="critical"' dfx.json | sponge dfx.json + assert_command dfx start --background --verbose --clean + assert_match "log level: Critical" } @test "dfx starts replica with correct log level - local network" { - dfx_new - jq '.networks.local.replica.log_level="warning"' dfx.json | sponge dfx.json - define_project_network + dfx_new + jq '.networks.local.replica.log_level="warning"' dfx.json | sponge dfx.json + define_project_network - assert_command dfx start --background --verbose - assert_match "log level: Warning" - assert_command dfx stop + assert_command dfx start --background --verbose + assert_match "log level: Warning" + assert_command dfx stop - jq '.networks.local.replica.log_level="critical"' dfx.json | sponge dfx.json - assert_command dfx start --background --verbose --clean - assert_match "log level: Critical" + jq '.networks.local.replica.log_level="critical"' dfx.json | sponge dfx.json + assert_command dfx start --background --verbose --clean + assert_match "log level: Critical" } @test "dfx starts replica with correct log level - shared network" { - dfx_new - create_networks_json - jq '.local.replica.log_level="warning"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + dfx_new + create_networks_json + jq '.local.replica.log_level="warning"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background --verbose - assert_match "log level: Warning" - assert_command dfx stop + assert_command dfx start --background --verbose + assert_match "log level: Warning" + assert_command dfx stop - jq '.local.replica.log_level="critical"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" - assert_command dfx start --background --verbose --clean - assert_match "log level: Critical" + jq '.local.replica.log_level="critical"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" + assert_command dfx start --background --verbose --clean + assert_match "log level: Critical" } @test "debug print statements work with default log level" { - dfx_new - install_asset print - dfx_start 2>stderr.txt - assert_command dfx deploy - assert_command dfx canister call e2e_project hello - sleep 2 - run tail -2 stderr.txt - assert_match "Hello, World! from DFINITY" + dfx_new + install_asset print + dfx_start 2>stderr.txt + assert_command dfx deploy + assert_command dfx canister call e2e_project hello + sleep 2 + run tail -2 stderr.txt + assert_match "Hello, World! from DFINITY" } @test "modifying networks.json requires --clean on restart" { - dfx_start - dfx stop - assert_command dfx_start - dfx stop - jq -n '.local.replica.log_level="warning"' > "$E2E_NETWORKS_JSON" - assert_command_fail dfx_start - assert_contains "The network configuration was changed. Rerun with \`--clean\`." - assert_command dfx_start --force - dfx stop - assert_command dfx_start --clean + dfx_start + dfx stop + assert_command dfx_start + dfx stop + jq -n '.local.replica.log_level="warning"' > "$E2E_NETWORKS_JSON" + assert_command_fail dfx_start + assert_contains "The network configuration was changed. Rerun with \`--clean\`." + assert_command dfx_start --force + dfx stop + assert_command dfx_start --clean } @test "project-local networks require --clean if dfx.json was updated" { - dfx_new - define_project_network - dfx_start - dfx stop - assert_command dfx_start - dfx stop - jq -n '.local.replica.log_level="warning"' > "$E2E_NETWORKS_JSON" - assert_command dfx_start - dfx stop - jq '.networks.local.replica.log_level="warning"' dfx.json | sponge dfx.json - assert_command_fail dfx_start - assert_contains "The network configuration was changed. Rerun with \`--clean\`." - assert_command dfx_start --force - dfx stop - assert_command dfx_start --clean + dfx_new + define_project_network + dfx_start + dfx stop + assert_command dfx_start + dfx stop + jq -n '.local.replica.log_level="warning"' > "$E2E_NETWORKS_JSON" + assert_command dfx_start + dfx stop + jq '.networks.local.replica.log_level="warning"' dfx.json | sponge dfx.json + assert_command_fail dfx_start + assert_contains "The network configuration was changed. Rerun with \`--clean\`." + assert_command dfx_start --force + dfx stop + assert_command dfx_start --clean } @test "flags count as configuration modification and require --clean" { - dfx_start - dfx stop - assert_command_fail dfx_start --enable-bitcoin - assert_contains "The network configuration was changed. Rerun with \`--clean\`." - assert_command dfx_start --enable-bitcoin --clean - dfx stop - assert_command dfx_start --enable-bitcoin - dfx stop - assert_command_fail dfx_start - assert_contains "The network configuration was changed. Rerun with \`--clean\`." - assert_command dfx_start --force + dfx_start + dfx stop + assert_command_fail dfx_start --enable-bitcoin + assert_contains "The network configuration was changed. Rerun with \`--clean\`." + assert_command dfx_start --enable-bitcoin --clean + dfx stop + assert_command dfx_start --enable-bitcoin + dfx stop + assert_command_fail dfx_start + assert_contains "The network configuration was changed. Rerun with \`--clean\`." + assert_command dfx_start --force } @test "dfx start then ctrl-c won't hang and panic but stop actors quickly" { - assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/ctrl_c_right_after_dfx_start.exp" + assert_command "${BATS_TEST_DIRNAME}/../assets/expect_scripts/ctrl_c_right_after_dfx_start.exp" } diff --git a/e2e/tests-dfx/subcommands.bash b/e2e/tests-dfx/subcommands.bash index 92e6f4c65a..9591922c1d 100644 --- a/e2e/tests-dfx/subcommands.bash +++ b/e2e/tests-dfx/subcommands.bash @@ -3,23 +3,23 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new + dfx_new } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "--identity and --network are stil accepted as prefix" { - install_asset whoami - dfx_start - dfx deploy - dfx identity new alice --storage-mode plaintext - assert_command dfx --identity alice canister --network local call whoami whoami - assert_match "$(dfx --identity alice identity get-principal)" - assert_match "$(dfx identity get-principal --identity alice)" + install_asset whoami + dfx_start + dfx deploy + dfx identity new alice --storage-mode plaintext + assert_command dfx --identity alice canister --network local call whoami whoami + assert_match "$(dfx --identity alice identity get-principal)" + assert_match "$(dfx identity get-principal --identity alice)" } diff --git a/e2e/tests-dfx/update_settings.bash b/e2e/tests-dfx/update_settings.bash index ff34082756..8ad100f00b 100644 --- a/e2e/tests-dfx/update_settings.bash +++ b/e2e/tests-dfx/update_settings.bash @@ -3,491 +3,491 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "set freezing threshold" { - dfx_start - assert_command dfx deploy hello_backend + dfx_start + assert_command dfx deploy hello_backend - # trying to set threshold to 1T seconds, which should not work because it's likely a mistake - assert_command_fail dfx canister update-settings hello_backend --freezing-threshold 100000000000 - assert_match "SECONDS" # error message pointing to the error + # trying to set threshold to 1T seconds, which should not work because it's likely a mistake + assert_command_fail dfx canister update-settings hello_backend --freezing-threshold 100000000000 + assert_match "SECONDS" # error message pointing to the error - # with manual override it's ok - assert_command dfx canister update-settings hello_backend --freezing-threshold 100000000000 --confirm-very-long-freezing-threshold + # with manual override it's ok + assert_command dfx canister update-settings hello_backend --freezing-threshold 100000000000 --confirm-very-long-freezing-threshold - # to check if threshold is set correctly we have to un-freeze the canister by adding cycles. Fabricating 100T cycles onto it - assert_command dfx ledger fabricate-cycles --canister hello_backend --t 100 - assert_command dfx canister status hello_backend - assert_match "Freezing threshold: 100_000_000_000" + # to check if threshold is set correctly we have to un-freeze the canister by adding cycles. Fabricating 100T cycles onto it + assert_command dfx ledger fabricate-cycles --canister hello_backend --t 100 + assert_command dfx canister status hello_backend + assert_match "Freezing threshold: 100_000_000_000" } @test "set controller" { - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - - assert_command dfx identity use alice - - dfx_start - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - - dfx canister create hello_backend - dfx build hello_backend - dfx canister install hello_backend - ID=$(dfx canister id hello_backend) - - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller bob --yes - assert_match "Set controller of \"hello_backend\" to: bob" - - # Bob is controller, Alice cannot reinstall - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall - - # Bob can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob - - assert_command dfx identity use bob - # Set controller using canister id and principal - assert_command dfx canister update-settings "$ID" --set-controller "${ALICE_PRINCIPAL}" --yes - assert_match "Set controller of \"${ID}\" to: ${ALICE_PRINCIPAL}" - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall - - # Set controller using combination of name/id and identity/principal - assert_command dfx canister update-settings hello_backend --set-controller "${BOB_PRINCIPAL}" --identity alice --yes - assert_match "Set controller of \"hello_backend\" to: ${BOB_PRINCIPAL}" - - assert_command dfx canister update-settings "${ID}" --set-controller alice --identity bob --yes - assert_match "Set controller of \"${ID}\" to: alice" - - # Set controller using invalid principal/identity fails - assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --yes - assert_match "Identity charlie does not exist" - - # Set controller using invalid canister name/id fails - assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --yes - assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." - - # Fails if no consent is given - echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice - # But works with typing "yes" - echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + + assert_command dfx identity use alice + + dfx_start + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + + dfx canister create hello_backend + dfx build hello_backend + dfx canister install hello_backend + ID=$(dfx canister id hello_backend) + + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller bob --yes + assert_match "Set controller of \"hello_backend\" to: bob" + + # Bob is controller, Alice cannot reinstall + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall + + # Bob can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob + + assert_command dfx identity use bob + # Set controller using canister id and principal + assert_command dfx canister update-settings "$ID" --set-controller "${ALICE_PRINCIPAL}" --yes + assert_match "Set controller of \"${ID}\" to: ${ALICE_PRINCIPAL}" + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall + + # Set controller using combination of name/id and identity/principal + assert_command dfx canister update-settings hello_backend --set-controller "${BOB_PRINCIPAL}" --identity alice --yes + assert_match "Set controller of \"hello_backend\" to: ${BOB_PRINCIPAL}" + + assert_command dfx canister update-settings "${ID}" --set-controller alice --identity bob --yes + assert_match "Set controller of \"${ID}\" to: alice" + + # Set controller using invalid principal/identity fails + assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --yes + assert_match "Identity charlie does not exist" + + # Set controller using invalid canister name/id fails + assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --yes + assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." + + # Fails if no consent is given + echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice + # But works with typing "yes" + echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice } @test "set controller with wallet" { - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob - assert_command dfx identity use alice + assert_command dfx identity use alice - dfx_start - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB_WALLET=$(dfx identity get-wallet --identity bob) + dfx_start + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB_WALLET=$(dfx identity get-wallet --identity bob) - dfx canister create hello_backend --wallet "${ALICE_WALLET}" - dfx build hello_backend - dfx canister install hello_backend --wallet "${ALICE_WALLET}" - ID=$(dfx canister id hello_backend) + dfx canister create hello_backend --wallet "${ALICE_WALLET}" + dfx build hello_backend + dfx canister install hello_backend --wallet "${ALICE_WALLET}" + ID=$(dfx canister id hello_backend) - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" --yes - assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" --yes + assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" - # Bob is controller, Alice cannot reinstall - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${ALICE_WALLET}" + # Bob is controller, Alice cannot reinstall + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${ALICE_WALLET}" - # Bob can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" + # Bob can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" - assert_command dfx identity use bob - # Set controller using canister id and principal - assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --wallet "${BOB_WALLET}" --yes - assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${BOB_WALLET}" + assert_command dfx identity use bob + # Set controller using canister id and principal + assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --wallet "${BOB_WALLET}" --yes + assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${BOB_WALLET}" - # Set controller using combination of name/id and identity/principal - assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" --yes - assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" + # Set controller using combination of name/id and identity/principal + assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" --yes + assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" - assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --identity bob --wallet "${BOB_WALLET}" --yes - assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" + assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --identity bob --wallet "${BOB_WALLET}" --yes + assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" - # Set controller using invalid principal/identity fails - assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --wallet "${ALICE_WALLET}" --yes - assert_match "Identity charlie does not exist" + # Set controller using invalid principal/identity fails + assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --wallet "${ALICE_WALLET}" --yes + assert_match "Identity charlie does not exist" - # Set controller using invalid canister name/id fails - assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --wallet "${ALICE_WALLET}" --yes - assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." + # Set controller using invalid canister name/id fails + assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --wallet "${ALICE_WALLET}" --yes + assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." - # Fails if no consent is given - echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" - # But works with typing "yes" - echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" + # Fails if no consent is given + echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" + # But works with typing "yes" + echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" } @test "set controller with wallet 0.7.2" { - use_wallet_wasm 0.7.2 + use_wallet_wasm 0.7.2 - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob - assert_command dfx identity use alice + assert_command dfx identity use alice - dfx_start - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB_WALLET=$(dfx identity get-wallet --identity bob) + dfx_start + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB_WALLET=$(dfx identity get-wallet --identity bob) - dfx canister create hello_backend --wallet "${ALICE_WALLET}" - dfx build hello_backend - dfx canister install hello_backend --wallet "${ALICE_WALLET}" - ID=$(dfx canister id hello_backend) + dfx canister create hello_backend --wallet "${ALICE_WALLET}" + dfx build hello_backend + dfx canister install hello_backend --wallet "${ALICE_WALLET}" + ID=$(dfx canister id hello_backend) - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" --yes - assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" --yes + assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" - # Bob is controller, Alice cannot reinstall - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${ALICE_WALLET}" + # Bob is controller, Alice cannot reinstall + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${ALICE_WALLET}" - # Bob can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" + # Bob can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" - assert_command dfx identity use bob - # Set controller using canister id and principal - assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --wallet "${BOB_WALLET}" --yes - assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${BOB_WALLET}" + assert_command dfx identity use bob + # Set controller using canister id and principal + assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --wallet "${BOB_WALLET}" --yes + assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall --wallet "${BOB_WALLET}" - # Set controller using combination of name/id and identity/principal - assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" --yes - assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" + # Set controller using combination of name/id and identity/principal + assert_command dfx canister update-settings hello_backend --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" --yes + assert_match "Set controller of \"hello_backend\" to: ${BOB_WALLET}" - assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --identity bob --wallet "${BOB_WALLET}" --yes - assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" + assert_command dfx canister update-settings "${ID}" --set-controller "${ALICE_WALLET}" --identity bob --wallet "${BOB_WALLET}" --yes + assert_match "Set controller of \"${ID}\" to: ${ALICE_WALLET}" - # Set controller using invalid principal/identity fails - assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --yes - assert_match "Identity charlie does not exist" + # Set controller using invalid principal/identity fails + assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --yes + assert_match "Identity charlie does not exist" - # Set controller using invalid canister name/id fails - assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --yes - assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." + # Set controller using invalid canister name/id fails + assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --yes + assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." - # Fails if no consent is given - echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" - # But works with typing "yes" - echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" + # Fails if no consent is given + echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" + # But works with typing "yes" + echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_WALLET}" --identity alice --wallet "${ALICE_WALLET}" } @test "set controller without wallet but using wallet 0.7.2" { - use_wallet_wasm 0.7.2 - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - - assert_command dfx identity use alice - - dfx_start - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - - dfx canister create hello_backend - dfx canister update-settings hello_backend --add-controller "$ALICE_PRINCIPAL" --wallet "$(dfx identity get-wallet)" - dfx build hello_backend - dfx canister install hello_backend - ID=$(dfx canister id hello_backend) - - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller bob --yes - assert_match "Set controller of \"hello_backend\" to: bob" - - # Bob is controller, Alice cannot reinstall - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall - - # Bob can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob - - assert_command dfx identity use bob - # Set controller using canister id and principal - assert_command dfx canister update-settings "$ID" --set-controller "${ALICE_PRINCIPAL}" --yes - assert_match "Set controller of \"${ID}\" to: ${ALICE_PRINCIPAL}" - echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall - - # Set controller using combination of name/id and identity/principal - assert_command dfx canister update-settings hello_backend --set-controller "${BOB_PRINCIPAL}" --identity alice --yes - assert_match "Set controller of \"hello_backend\" to: ${BOB_PRINCIPAL}" - - assert_command dfx canister update-settings "${ID}" --set-controller alice --identity bob --yes - assert_match "Set controller of \"${ID}\" to: alice" - - # Set controller using invalid principal/identity fails - assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --yes - assert_match "Identity charlie does not exist" - - # Set controller using invalid canister name/id fails - assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --yes - assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." - - # Fails if no consent is given - echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice - # But works with typing "yes" - echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice + use_wallet_wasm 0.7.2 + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + + assert_command dfx identity use alice + + dfx_start + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + + dfx canister create hello_backend + dfx canister update-settings hello_backend --add-controller "$ALICE_PRINCIPAL" --wallet "$(dfx identity get-wallet)" + dfx build hello_backend + dfx canister install hello_backend + ID=$(dfx canister id hello_backend) + + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller bob --yes + assert_match "Set controller of \"hello_backend\" to: bob" + + # Bob is controller, Alice cannot reinstall + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall + + # Bob can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob + + assert_command dfx identity use bob + # Set controller using canister id and principal + assert_command dfx canister update-settings "$ID" --set-controller "${ALICE_PRINCIPAL}" --yes + assert_match "Set controller of \"${ID}\" to: ${ALICE_PRINCIPAL}" + echo "yes" | assert_command_fail dfx canister install hello_backend -m reinstall + + # Set controller using combination of name/id and identity/principal + assert_command dfx canister update-settings hello_backend --set-controller "${BOB_PRINCIPAL}" --identity alice --yes + assert_match "Set controller of \"hello_backend\" to: ${BOB_PRINCIPAL}" + + assert_command dfx canister update-settings "${ID}" --set-controller alice --identity bob --yes + assert_match "Set controller of \"${ID}\" to: alice" + + # Set controller using invalid principal/identity fails + assert_command_fail dfx canister update-settings hello_backend --set-controller charlie --identity alice --yes + assert_match "Identity charlie does not exist" + + # Set controller using invalid canister name/id fails + assert_command_fail dfx canister update-settings hello_assets --set-controller bob --identity alice --yes + assert_match "Cannot find canister id. Please issue 'dfx canister create hello_assets'." + + # Fails if no consent is given + echo "no" | assert_command_fail dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice + # But works with typing "yes" + echo "yes" | assert_command dfx canister update-settings "${ID}" --set-controller "${BOB_PRINCIPAL}" --identity alice } @test "set multiple controllers" { - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob - assert_command dfx identity use alice + assert_command dfx identity use alice - dfx_start - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - # awk step is to avoid trailing space - PRINCIPALS_SORTED=$(echo "$ALICE_PRINCIPAL" "$BOB_PRINCIPAL" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) + dfx_start + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + # awk step is to avoid trailing space + PRINCIPALS_SORTED=$(echo "$ALICE_PRINCIPAL" "$BOB_PRINCIPAL" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) - dfx canister create hello_backend - dfx build hello_backend - dfx canister install hello_backend - ID=$(dfx canister id hello_backend) + dfx canister create hello_backend + dfx build hello_backend + dfx canister install hello_backend + ID=$(dfx canister id hello_backend) - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_PRINCIPAL}" --set-controller "${BOB_PRINCIPAL}" - assert_match "Set controllers of \"hello_backend\" to: $PRINCIPALS_SORTED" + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_PRINCIPAL}" --set-controller "${BOB_PRINCIPAL}" + assert_match "Set controllers of \"hello_backend\" to: $PRINCIPALS_SORTED" - # Both can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob + # Both can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob - assert_command dfx canister info hello_backend - assert_match "Controllers: ${PRINCIPALS_SORTED}" + assert_command dfx canister info hello_backend + assert_match "Controllers: ${PRINCIPALS_SORTED}" } @test "set multiple controllers with wallet" { - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob - assert_command dfx identity use alice + assert_command dfx identity use alice - dfx_start - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB_WALLET=$(dfx identity get-wallet --identity bob) - # awk step is to avoid trailing space - WALLETS_SORTED=$(echo "${ALICE_WALLET}" "${BOB_WALLET}" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) + dfx_start + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB_WALLET=$(dfx identity get-wallet --identity bob) + # awk step is to avoid trailing space + WALLETS_SORTED=$(echo "${ALICE_WALLET}" "${BOB_WALLET}" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) - dfx canister create hello_backend - dfx build hello_backend - dfx canister install hello_backend - ID=$(dfx canister id hello_backend) + dfx canister create hello_backend + dfx build hello_backend + dfx canister install hello_backend + ID=$(dfx canister id hello_backend) - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_WALLET}" --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" - assert_match "Set controllers of \"hello_backend\" to: ${WALLETS_SORTED}" + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_WALLET}" --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" + assert_match "Set controllers of \"hello_backend\" to: ${WALLETS_SORTED}" - # Both can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice --wallet "${ALICE_WALLET}" - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" + # Both can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice --wallet "${ALICE_WALLET}" + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" - assert_command dfx canister info hello_backend - assert_match "Controllers: ${WALLETS_SORTED}" + assert_command dfx canister info hello_backend + assert_match "Controllers: ${WALLETS_SORTED}" } @test "set multiple controllers even with wallet 0.7.2" { - use_wallet_wasm 0.7.2 - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - - assert_command dfx identity use alice - - dfx_start - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB_WALLET=$(dfx identity get-wallet --identity bob) - # awk step is to avoid trailing space - WALLETS_SORTED=$(echo "${ALICE_WALLET}" "${BOB_WALLET}" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) - - dfx canister create hello_backend - dfx build hello_backend - dfx canister install hello_backend --wallet "${ALICE_WALLET}" - ID=$(dfx canister id hello_backend) - - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_WALLET}" --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" - assert_match "Set controllers of \"hello_backend\" to: $WALLETS_SORTED" - - # Both can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice --wallet "${ALICE_WALLET}" - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" - - assert_command dfx canister info hello_backend - assert_match "Controllers: ${WALLETS_SORTED}" + use_wallet_wasm 0.7.2 + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + + assert_command dfx identity use alice + + dfx_start + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB_WALLET=$(dfx identity get-wallet --identity bob) + # awk step is to avoid trailing space + WALLETS_SORTED=$(echo "${ALICE_WALLET}" "${BOB_WALLET}" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) + + dfx canister create hello_backend + dfx build hello_backend + dfx canister install hello_backend --wallet "${ALICE_WALLET}" + ID=$(dfx canister id hello_backend) + + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_WALLET}" --set-controller "${BOB_WALLET}" --wallet "${ALICE_WALLET}" + assert_match "Set controllers of \"hello_backend\" to: $WALLETS_SORTED" + + # Both can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice --wallet "${ALICE_WALLET}" + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob --wallet "${BOB_WALLET}" + + assert_command dfx canister info hello_backend + assert_match "Controllers: ${WALLETS_SORTED}" } @test "set multiple controllers without wallet but using wallet 0.7.2" { - use_wallet_wasm 0.7.2 - # Create two identities - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - - assert_command dfx identity use alice - - dfx_start - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - # awk step is to avoid trailing space - PRINCIPALS_SORTED=$(echo "$ALICE_PRINCIPAL" "$BOB_PRINCIPAL" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) - - dfx canister create hello_backend - dfx canister update-settings hello_backend --add-controller "$ALICE_PRINCIPAL" --wallet "$(dfx identity get-wallet)" - dfx build hello_backend - dfx canister install hello_backend - ID=$(dfx canister id hello_backend) - - # Set controller using canister name and identity name - assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_PRINCIPAL}" --set-controller "${BOB_PRINCIPAL}" - assert_match "Set controllers of \"hello_backend\" to: $PRINCIPALS_SORTED" - - # Both can reinstall - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice - echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob - - assert_command dfx canister info hello_backend - assert_match "Controllers: ${PRINCIPALS_SORTED}" + use_wallet_wasm 0.7.2 + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + + assert_command dfx identity use alice + + dfx_start + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + # awk step is to avoid trailing space + PRINCIPALS_SORTED=$(echo "$ALICE_PRINCIPAL" "$BOB_PRINCIPAL" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s",$1,$2}' ) + + dfx canister create hello_backend + dfx canister update-settings hello_backend --add-controller "$ALICE_PRINCIPAL" --wallet "$(dfx identity get-wallet)" + dfx build hello_backend + dfx canister install hello_backend + ID=$(dfx canister id hello_backend) + + # Set controller using canister name and identity name + assert_command dfx canister update-settings hello_backend --set-controller "${ALICE_PRINCIPAL}" --set-controller "${BOB_PRINCIPAL}" + assert_match "Set controllers of \"hello_backend\" to: $PRINCIPALS_SORTED" + + # Both can reinstall + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity alice + echo "yes" | assert_command dfx canister install hello_backend -m reinstall --identity bob + + assert_command dfx canister info hello_backend + assert_match "Controllers: ${PRINCIPALS_SORTED}" } @test "add controller to existing canister" { - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - assert_command dfx identity new --storage-mode plaintext charlie - - dfx identity use alice - dfx_start - - ALICE=$(dfx identity get-principal --identity alice) - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB=$(dfx identity get-principal --identity bob) - CHARLIE=$(dfx identity get-principal --identity charlie) - SORTED=$(echo "$ALICE" "$ALICE_WALLET" "$BOB" "$CHARLIE" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s %s %s",$1,$2,$3,$4}' ) - - dfx canister create hello_backend - dfx build hello_backend - dfx canister install hello_backend - - # make bob a controller - assert_command dfx canister update-settings hello_backend --add-controller bob - # check that bob has the authority to make someone else a controller - assert_command dfx canister update-settings hello_backend --add-controller charlie --identity bob - assert_command dfx canister info hello_backend - assert_match "Controllers: $SORTED" + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + assert_command dfx identity new --storage-mode plaintext charlie + + dfx identity use alice + dfx_start + + ALICE=$(dfx identity get-principal --identity alice) + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB=$(dfx identity get-principal --identity bob) + CHARLIE=$(dfx identity get-principal --identity charlie) + SORTED=$(echo "$ALICE" "$ALICE_WALLET" "$BOB" "$CHARLIE" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s %s %s",$1,$2,$3,$4}' ) + + dfx canister create hello_backend + dfx build hello_backend + dfx canister install hello_backend + + # make bob a controller + assert_command dfx canister update-settings hello_backend --add-controller bob + # check that bob has the authority to make someone else a controller + assert_command dfx canister update-settings hello_backend --add-controller charlie --identity bob + assert_command dfx canister info hello_backend + assert_match "Controllers: $SORTED" } @test "add controller to all canisters" { - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - assert_command dfx identity new --storage-mode plaintext charlie - - dfx identity use alice - dfx_start - - ALICE=$(dfx identity get-principal --identity alice) - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB=$(dfx identity get-principal --identity bob) - CHARLIE=$(dfx identity get-principal --identity charlie) - SORTED=$(echo "$ALICE" "$ALICE_WALLET" "$BOB" "$CHARLIE" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s %s %s",$1,$2,$3,$4}' ) - - dfx canister create --all - dfx build --all - dfx canister install --all - - # make bob a controller - assert_command dfx canister update-settings --all --add-controller bob - # check that bob has the authority to make someone else a controller - assert_command dfx canister update-settings --all --add-controller charlie --identity bob - assert_command dfx canister info hello_backend - assert_match "Controllers: $SORTED" + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + assert_command dfx identity new --storage-mode plaintext charlie + + dfx identity use alice + dfx_start + + ALICE=$(dfx identity get-principal --identity alice) + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB=$(dfx identity get-principal --identity bob) + CHARLIE=$(dfx identity get-principal --identity charlie) + SORTED=$(echo "$ALICE" "$ALICE_WALLET" "$BOB" "$CHARLIE" | tr " " "\n" | sort | tr "\n" " " | awk '{printf "%s %s %s %s",$1,$2,$3,$4}' ) + + dfx canister create --all + dfx build --all + dfx canister install --all + + # make bob a controller + assert_command dfx canister update-settings --all --add-controller bob + # check that bob has the authority to make someone else a controller + assert_command dfx canister update-settings --all --add-controller charlie --identity bob + assert_command dfx canister info hello_backend + assert_match "Controllers: $SORTED" } @test "update settings by canister id, when canister id is not known to the project" { - dfx_start - dfx deploy + dfx_start + dfx deploy - CANISTER_ID=$(dfx canister id hello_backend) + CANISTER_ID=$(dfx canister id hello_backend) - rm .dfx/local/canister_ids.json - jq '.canisters={}' dfx.json | sponge dfx.json + rm .dfx/local/canister_ids.json + jq '.canisters={}' dfx.json | sponge dfx.json - assert_command dfx canister status "$CANISTER_ID" - assert_match 'Memory allocation: 0' - assert_match 'Compute allocation: 0' - assert_match 'Freezing threshold: 2_592_000' + assert_command dfx canister status "$CANISTER_ID" + assert_match 'Memory allocation: 0' + assert_match 'Compute allocation: 0' + assert_match 'Freezing threshold: 2_592_000' - dfx canister update-settings --memory-allocation 2GB "$CANISTER_ID" - assert_command dfx canister status "$CANISTER_ID" - assert_match 'Memory allocation: 2_000_000_000' - assert_match 'Compute allocation: 0' - assert_match 'Freezing threshold: 2_592_000' + dfx canister update-settings --memory-allocation 2GB "$CANISTER_ID" + assert_command dfx canister status "$CANISTER_ID" + assert_match 'Memory allocation: 2_000_000_000' + assert_match 'Compute allocation: 0' + assert_match 'Freezing threshold: 2_592_000' - # This is just checking that update-settings leaves the previous value - # (of memory allocation) alone when setting something else + # This is just checking that update-settings leaves the previous value + # (of memory allocation) alone when setting something else - # Compute allocations are temporarily disabled. - # See https://dfinity.atlassian.net/browse/RUN-314 - # dfx canister update-settings --compute-allocation 1 "$CANISTER_ID" + # Compute allocations are temporarily disabled. + # See https://dfinity.atlassian.net/browse/RUN-314 + # dfx canister update-settings --compute-allocation 1 "$CANISTER_ID" - dfx canister update-settings --freezing-threshold 172 "$CANISTER_ID" - assert_command dfx canister status "$CANISTER_ID" - assert_match 'Memory allocation: 2_000_000_000' - # assert_match 'Compute allocation: 4' - assert_match 'Freezing threshold: 172' + dfx canister update-settings --freezing-threshold 172 "$CANISTER_ID" + assert_command dfx canister status "$CANISTER_ID" + assert_match 'Memory allocation: 2_000_000_000' + # assert_match 'Compute allocation: 4' + assert_match 'Freezing threshold: 172' } @test "remove controller" { - assert_command dfx identity new --storage-mode plaintext alice - assert_command dfx identity new --storage-mode plaintext bob - ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) - BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) - dfx identity use alice - - dfx_start - dfx deploy - WALLET_PRINCIPAL=$(dfx identity get-wallet) - - assert_command dfx canister update-settings hello_backend --add-controller "${BOB_PRINCIPAL}" - assert_command dfx canister info hello_backend - assert_contains "${BOB_PRINCIPAL}" - assert_command dfx canister update-settings hello_backend --remove-controller "${BOB_PRINCIPAL}" - assert_command dfx canister info hello_backend - assert_not_contains "${BOB_PRINCIPAL}" - - # Cannot remove own controller without extra consent - echo "no" | assert_command_fail dfx canister update-settings hello_backend --remove-controller "${ALICE_PRINCIPAL}" - assert_command dfx canister info hello_backend - assert_contains "${ALICE_PRINCIPAL}" - echo "yes" | assert_command dfx canister update-settings hello_backend --remove-controller "${ALICE_PRINCIPAL}" - assert_command dfx canister info hello_backend - assert_not_contains "${ALICE_PRINCIPAL}" - - # Cannot remove wallet controller without extra consent - echo "no" | assert_command_fail dfx canister update-settings hello_backend --remove-controller "${WALLET_PRINCIPAL}" --wallet "${WALLET_PRINCIPAL}" - assert_command dfx canister info hello_backend - assert_contains "${WALLET_PRINCIPAL}" - echo "yes" | assert_command dfx canister update-settings hello_backend --remove-controller "${WALLET_PRINCIPAL}" --wallet "${WALLET_PRINCIPAL}" - assert_command dfx canister info hello_backend - assert_not_contains "${WALLET_PRINCIPAL}" + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + dfx identity use alice + + dfx_start + dfx deploy + WALLET_PRINCIPAL=$(dfx identity get-wallet) + + assert_command dfx canister update-settings hello_backend --add-controller "${BOB_PRINCIPAL}" + assert_command dfx canister info hello_backend + assert_contains "${BOB_PRINCIPAL}" + assert_command dfx canister update-settings hello_backend --remove-controller "${BOB_PRINCIPAL}" + assert_command dfx canister info hello_backend + assert_not_contains "${BOB_PRINCIPAL}" + + # Cannot remove own controller without extra consent + echo "no" | assert_command_fail dfx canister update-settings hello_backend --remove-controller "${ALICE_PRINCIPAL}" + assert_command dfx canister info hello_backend + assert_contains "${ALICE_PRINCIPAL}" + echo "yes" | assert_command dfx canister update-settings hello_backend --remove-controller "${ALICE_PRINCIPAL}" + assert_command dfx canister info hello_backend + assert_not_contains "${ALICE_PRINCIPAL}" + + # Cannot remove wallet controller without extra consent + echo "no" | assert_command_fail dfx canister update-settings hello_backend --remove-controller "${WALLET_PRINCIPAL}" --wallet "${WALLET_PRINCIPAL}" + assert_command dfx canister info hello_backend + assert_contains "${WALLET_PRINCIPAL}" + echo "yes" | assert_command dfx canister update-settings hello_backend --remove-controller "${WALLET_PRINCIPAL}" --wallet "${WALLET_PRINCIPAL}" + assert_command dfx canister info hello_backend + assert_not_contains "${WALLET_PRINCIPAL}" } diff --git a/e2e/tests-dfx/upgrade.bash b/e2e/tests-dfx/upgrade.bash index 4bb884bfa1..02bf5a6d5d 100644 --- a/e2e/tests-dfx/upgrade.bash +++ b/e2e/tests-dfx/upgrade.bash @@ -3,47 +3,47 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - stop_webserver - standard_teardown + stop_webserver + standard_teardown } @test "upgrade succeeds" { - latest_version="0.4.7" - latest_version_dir="downloads/dfx/$latest_version/x86_64-$(uname -s | tr '[:upper:]' '[:lower:]')/" - dfx_archive_file_name="dfx-$latest_version.tar.gz" - mkdir -p "$latest_version_dir" - cp "$(which dfx)" . - version=$(./dfx --version) - tar -czf "$latest_version_dir/$dfx_archive_file_name" dfx - echo '{ - "tags": { - "latest": "0.4.7" - }, - "versions": [ - "0.4.3", - "0.4.4", - "0.4.7" - ] - }' > manifest.json - - start_webserver - - # Override current version to force upgrade - assert_command ./dfx upgrade \ - --current-version 0.4.6 \ - --release-root "http://localhost:$E2E_WEB_SERVER_PORT" - assert_match "Current version: .*" - assert_match "Fetching manifest .*" - assert_match "New version available: .*" - - assert_command ./dfx upgrade \ - --release-root "http://localhost:$E2E_WEB_SERVER_PORT" - assert_match "Already up to date" - - assert_command ./dfx --version - assert_contains "$version" + latest_version="0.4.7" + latest_version_dir="downloads/dfx/$latest_version/x86_64-$(uname -s | tr '[:upper:]' '[:lower:]')/" + dfx_archive_file_name="dfx-$latest_version.tar.gz" + mkdir -p "$latest_version_dir" + cp "$(which dfx)" . + version=$(./dfx --version) + tar -czf "$latest_version_dir/$dfx_archive_file_name" dfx + echo '{ + "tags": { + "latest": "0.4.7" + }, + "versions": [ + "0.4.3", + "0.4.4", + "0.4.7" + ] + }' > manifest.json + + start_webserver + + # Override current version to force upgrade + assert_command ./dfx upgrade \ + --current-version 0.4.6 \ + --release-root "http://localhost:$E2E_WEB_SERVER_PORT" + assert_match "Current version: .*" + assert_match "Fetching manifest .*" + assert_match "New version available: .*" + + assert_command ./dfx upgrade \ + --release-root "http://localhost:$E2E_WEB_SERVER_PORT" + assert_match "Already up to date" + + assert_command ./dfx --version + assert_contains "$version" } diff --git a/e2e/tests-dfx/upgrade_check.bash b/e2e/tests-dfx/upgrade_check.bash index 52641c7f0f..f4d93fc025 100644 --- a/e2e/tests-dfx/upgrade_check.bash +++ b/e2e/tests-dfx/upgrade_check.bash @@ -3,15 +3,15 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "safe upgrade by adding a new stable variable" { @@ -26,41 +26,41 @@ teardown() { } @test "changing stable variable from Int to Nat is not allowed" { - install_asset upgrade - dfx_start - dfx deploy - dfx canister call hello_backend inc '()' - jq '.canisters.hello_backend.main="v2_bad.mo"' dfx.json | sponge dfx.json - echo yes | ( - assert_command dfx deploy - assert_match "Stable interface compatibility check failed" - ) - assert_command dfx canister call hello_backend read '()' - assert_match "(0 : nat)" + install_asset upgrade + dfx_start + dfx deploy + dfx canister call hello_backend inc '()' + jq '.canisters.hello_backend.main="v2_bad.mo"' dfx.json | sponge dfx.json + echo yes | ( + assert_command dfx deploy + assert_match "Stable interface compatibility check failed" + ) + assert_command dfx canister call hello_backend read '()' + assert_match "(0 : nat)" } @test "changing stable variable from Int to Nat with reinstall is allowed" { - install_asset upgrade - dfx_start - dfx deploy - dfx canister call hello_backend inc '()' - jq '.canisters.hello_backend.main="v2_bad.mo"' dfx.json | sponge dfx.json - dfx build - echo yes | dfx canister install hello_backend --mode=reinstall - assert_command dfx canister call hello_backend read '()' - assert_match "(0 : nat)" + install_asset upgrade + dfx_start + dfx deploy + dfx canister call hello_backend inc '()' + jq '.canisters.hello_backend.main="v2_bad.mo"' dfx.json | sponge dfx.json + dfx build + echo yes | dfx canister install hello_backend --mode=reinstall + assert_command dfx canister call hello_backend read '()' + assert_match "(0 : nat)" } @test "warning for changing method name" { - install_asset upgrade - dfx_start - dfx deploy - dfx canister call hello_backend inc '()' - jq '.canisters.hello_backend.main="v3_bad.mo"' dfx.json | sponge dfx.json - echo yes | ( - assert_command dfx deploy - assert_match "Candid interface compatibility check failed" - ) - assert_command dfx canister call hello_backend read2 '()' - assert_match "(1 : int)" + install_asset upgrade + dfx_start + dfx deploy + dfx canister call hello_backend inc '()' + jq '.canisters.hello_backend.main="v3_bad.mo"' dfx.json | sponge dfx.json + echo yes | ( + assert_command dfx deploy + assert_match "Candid interface compatibility check failed" + ) + assert_command dfx canister call hello_backend read2 '()' + assert_match "(1 : int)" } diff --git a/e2e/tests-dfx/usage.bash b/e2e/tests-dfx/usage.bash index bf3246face..96b9f5aada 100644 --- a/e2e/tests-dfx/usage.bash +++ b/e2e/tests-dfx/usage.bash @@ -1,13 +1,13 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "dfx help succeeds" { @@ -19,21 +19,21 @@ teardown() { } @test "using an invalid command fails" { - run dfx blurp - if [[ $status -eq 0 ]]; then - echo "$@" >&2 - exit 1 - fi + run dfx blurp + if [[ $status -eq 0 ]]; then + echo "$@" >&2 + exit 1 + fi } @test "returns the right error if not in a project" { - assert_command_fail dfx build - assert_match "Cannot find dfx configuration file in the current working directory. Did you forget to create one?" + assert_command_fail dfx build + assert_match "Cannot find dfx configuration file in the current working directory. Did you forget to create one?" - dfx new t --no-frontend - cd t - dfx_start - dfx canister create --all - assert_command dfx build + dfx new t --no-frontend + cd t + dfx_start + dfx canister create --all + assert_command dfx build } diff --git a/e2e/tests-dfx/usage_env.bash b/e2e/tests-dfx/usage_env.bash index cd000baf37..7cd19f6af5 100644 --- a/e2e/tests-dfx/usage_env.bash +++ b/e2e/tests-dfx/usage_env.bash @@ -3,47 +3,47 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - standard_teardown + standard_teardown } @test "dfx config root env var stores identity & cache" { - use_test_specific_cache_root # Because this test depends on a clean cache state - - #identity - dfx identity new --storage-mode plaintext alice - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" - assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" - - assert_command_fail head "$HOME/.config/dfx/identity/alice/identity.pem" - assert_command_fail head "$HOME/.config/dfx/identity/default/identity.pem" + use_test_specific_cache_root # Because this test depends on a clean cache state + + #identity + dfx identity new --storage-mode plaintext alice + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem" + assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/default/identity.pem" + + assert_command_fail head "$HOME/.config/dfx/identity/alice/identity.pem" + assert_command_fail head "$HOME/.config/dfx/identity/default/identity.pem" + + #cache + # create a new project to install dfx cache + assert_command_fail ls "$DFX_CACHE_ROOT/.cache/dfinity/versions" + dfx new hello + assert_command ls "$DFX_CACHE_ROOT/.cache/dfinity/versions" + assert_command_fail ls "$HOME/.cache/dfinity/versions" + rm -rf hello + + ( + # use subshell to retain $DFX_CONFIG_ROOT for teardown + # remove configured variable, should use $HOME now + unset DFX_CACHE_ROOT + unset DFX_CONFIG_ROOT + + dfx identity new --storage-mode plaintext bob + assert_command head "$HOME/.config/dfx/identity/bob/identity.pem" + assert_command head "$HOME/.config/dfx/identity/default/identity.pem" #cache # create a new project to install dfx cache - assert_command_fail ls "$DFX_CACHE_ROOT/.cache/dfinity/versions" - dfx new hello - assert_command ls "$DFX_CACHE_ROOT/.cache/dfinity/versions" assert_command_fail ls "$HOME/.cache/dfinity/versions" + dfx new hello + assert_command ls "$HOME/.cache/dfinity/versions" rm -rf hello - - ( - # use subshell to retain $DFX_CONFIG_ROOT for teardown - # remove configured variable, should use $HOME now - unset DFX_CACHE_ROOT - unset DFX_CONFIG_ROOT - - dfx identity new --storage-mode plaintext bob - assert_command head "$HOME/.config/dfx/identity/bob/identity.pem" - assert_command head "$HOME/.config/dfx/identity/default/identity.pem" - - #cache - # create a new project to install dfx cache - assert_command_fail ls "$HOME/.cache/dfinity/versions" - dfx new hello - assert_command ls "$HOME/.cache/dfinity/versions" - rm -rf hello - ) + ) } diff --git a/e2e/tests-dfx/wallet.bash b/e2e/tests-dfx/wallet.bash index e8d71486db..56f9677204 100644 --- a/e2e/tests-dfx/wallet.bash +++ b/e2e/tests-dfx/wallet.bash @@ -3,224 +3,224 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "DFX_WALLET_WASM environment variable overrides wallet module wasm at installation" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - dfx identity new --storage-mode plaintext alice - dfx identity new --storage-mode plaintext bob + dfx identity new --storage-mode plaintext alice + dfx identity new --storage-mode plaintext bob - use_wallet_wasm 0.7.0 - assert_command dfx identity get-wallet --identity alice - assert_match "Using wasm at path: .*/wallet/0.7.0/wallet.wasm" + use_wallet_wasm 0.7.0 + assert_command dfx identity get-wallet --identity alice + assert_match "Using wasm at path: .*/wallet/0.7.0/wallet.wasm" - use_wallet_wasm 0.7.2 - assert_command dfx identity get-wallet --identity bob - assert_match "Using wasm at path: .*/wallet/0.7.2/wallet.wasm" + use_wallet_wasm 0.7.2 + assert_command dfx identity get-wallet --identity bob + assert_match "Using wasm at path: .*/wallet/0.7.2/wallet.wasm" - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - BOB_WALLET=$(dfx identity get-wallet --identity bob) + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + BOB_WALLET=$(dfx identity get-wallet --identity bob) - assert_command dfx canister info "$ALICE_WALLET" --identity alice - assert_match "Module hash: 0xa609400f2576d1d6df72ce868b359fd08e1d68e58454ef17db2361d2f1c242a1" + assert_command dfx canister info "$ALICE_WALLET" --identity alice + assert_match "Module hash: 0xa609400f2576d1d6df72ce868b359fd08e1d68e58454ef17db2361d2f1c242a1" - assert_command dfx canister info "$BOB_WALLET" --identity bob - assert_match "Module hash: 0x1404b28b1c66491689b59e184a9de3c2be0dbdd75d952f29113b516742b7f898" + assert_command dfx canister info "$BOB_WALLET" --identity bob + assert_match "Module hash: 0x1404b28b1c66491689b59e184a9de3c2be0dbdd75d952f29113b516742b7f898" } @test "DFX_WALLET_WASM environment variable overrides wallet module wasm for upgrade" { - dfx_new hello - dfx_start + dfx_new hello + dfx_start - use_wallet_wasm 0.7.0-beta.5 + use_wallet_wasm 0.7.0-beta.5 - assert_command dfx identity get-wallet - WALLET_ID=$(dfx identity get-wallet) + assert_command dfx identity get-wallet + WALLET_ID=$(dfx identity get-wallet) - assert_command dfx canister info "$WALLET_ID" - assert_match "Module hash: 0x3d5b221387875574a9fd75b3165403cf1b301650a602310e9e4229d2f6766dcc" + assert_command dfx canister info "$WALLET_ID" + assert_match "Module hash: 0x3d5b221387875574a9fd75b3165403cf1b301650a602310e9e4229d2f6766dcc" - use_wallet_wasm 0.7.0 - assert_command dfx wallet upgrade + use_wallet_wasm 0.7.0 + assert_command dfx wallet upgrade - assert_command dfx canister info "$WALLET_ID" - assert_match "Module hash: 0xa609400f2576d1d6df72ce868b359fd08e1d68e58454ef17db2361d2f1c242a1" + assert_command dfx canister info "$WALLET_ID" + assert_match "Module hash: 0xa609400f2576d1d6df72ce868b359fd08e1d68e58454ef17db2361d2f1c242a1" } @test "'dfx identity set-wallet --force' bypasses wallet canister verification" { - dfx_new hello - dfx_start - setup_actuallylocal_shared_network - - # get Canister IDs to install the wasm onto - dfx canister create hello_backend --network actuallylocal - ID=$(dfx canister id hello_backend --network actuallylocal) - dfx canister create hello_frontend --network actuallylocal - ID_TWO=$(dfx canister id hello_frontend --network actuallylocal) - - # set controller to user - dfx canister update-settings hello_backend --set-controller "$(dfx identity get-principal)" --network actuallylocal - dfx canister update-settings hello_frontend --set-controller "$(dfx identity get-principal)" --network actuallylocal - - assert_command_fail dfx identity set-wallet "${ID}" --network actuallylocal - assert_not_match "Setting wallet for identity" - assert_command dfx identity set-wallet --force "${ID}" --network actuallylocal - assert_match "Setting wallet for identity 'default' on network 'actuallylocal' to id '$ID'" - assert_command jq -r .identities.default.actuallylocal <"$DFX_CONFIG_ROOT"/.config/dfx/identity/default/wallets.json - assert_eq "$ID" + dfx_new hello + dfx_start + setup_actuallylocal_shared_network + + # get Canister IDs to install the wasm onto + dfx canister create hello_backend --network actuallylocal + ID=$(dfx canister id hello_backend --network actuallylocal) + dfx canister create hello_frontend --network actuallylocal + ID_TWO=$(dfx canister id hello_frontend --network actuallylocal) + + # set controller to user + dfx canister update-settings hello_backend --set-controller "$(dfx identity get-principal)" --network actuallylocal + dfx canister update-settings hello_frontend --set-controller "$(dfx identity get-principal)" --network actuallylocal + + assert_command_fail dfx identity set-wallet "${ID}" --network actuallylocal + assert_not_match "Setting wallet for identity" + assert_command dfx identity set-wallet --force "${ID}" --network actuallylocal + assert_match "Setting wallet for identity 'default' on network 'actuallylocal' to id '$ID'" + assert_command jq -r .identities.default.actuallylocal <"$DFX_CONFIG_ROOT"/.config/dfx/identity/default/wallets.json + assert_eq "$ID" } @test "deploy wallet" { - dfx_new hello - dfx_start - setup_actuallylocal_shared_network - - # get Canister IDs to install the wasm onto - dfx canister create hello_frontend --network actuallylocal - ID=$(dfx canister id hello_frontend --network actuallylocal) - dfx deploy hello_backend --network actuallylocal - ID_TWO=$(dfx canister id hello_backend --network actuallylocal) - - # set controller to user - dfx canister update-settings hello_backend --set-controller "$(dfx identity get-principal)" --network actuallylocal - dfx canister update-settings hello_frontend --set-controller "$(dfx identity get-principal)" --network actuallylocal - - # We're testing on a local network so the create command actually creates a wallet - # Delete this file to force associate wallet created by deploy-wallet to identity - rm "$DFX_CONFIG_ROOT"/.config/dfx/identity/default/wallets.json - - assert_command dfx identity deploy-wallet "${ID}" --network actuallylocal - GET_WALLET_RES=$(dfx identity get-wallet --network actuallylocal) - assert_eq "$ID" "$GET_WALLET_RES" - - # Command should fail on an already-deployed canister - assert_command_fail dfx identity deploy-wallet "${ID_TWO}" --network actuallylocal - assert_match "The wallet canister \"${ID_TWO}\"\ already exists for user \"default\" on \"actuallylocal\" network." + dfx_new hello + dfx_start + setup_actuallylocal_shared_network + + # get Canister IDs to install the wasm onto + dfx canister create hello_frontend --network actuallylocal + ID=$(dfx canister id hello_frontend --network actuallylocal) + dfx deploy hello_backend --network actuallylocal + ID_TWO=$(dfx canister id hello_backend --network actuallylocal) + + # set controller to user + dfx canister update-settings hello_backend --set-controller "$(dfx identity get-principal)" --network actuallylocal + dfx canister update-settings hello_frontend --set-controller "$(dfx identity get-principal)" --network actuallylocal + + # We're testing on a local network so the create command actually creates a wallet + # Delete this file to force associate wallet created by deploy-wallet to identity + rm "$DFX_CONFIG_ROOT"/.config/dfx/identity/default/wallets.json + + assert_command dfx identity deploy-wallet "${ID}" --network actuallylocal + GET_WALLET_RES=$(dfx identity get-wallet --network actuallylocal) + assert_eq "$ID" "$GET_WALLET_RES" + + # Command should fail on an already-deployed canister + assert_command_fail dfx identity deploy-wallet "${ID_TWO}" --network actuallylocal + assert_match "The wallet canister \"${ID_TWO}\"\ already exists for user \"default\" on \"actuallylocal\" network." } @test "wallet create wallet" { - dfx_new - dfx_start - WALLET_ID=$(dfx identity get-wallet) - CREATE_RES=$(dfx canister call "${WALLET_ID}" wallet_create_wallet "(record { cycles = (2000000000000:nat64); settings = record {controller = opt principal \"$(dfx identity get-principal)\";};})") - CHILD_ID=$(echo "${CREATE_RES}" | tr '\n' ' ' | cut -d'"' -f 2) - assert_command dfx canister call "${CHILD_ID}" wallet_balance '()' + dfx_new + dfx_start + WALLET_ID=$(dfx identity get-wallet) + CREATE_RES=$(dfx canister call "${WALLET_ID}" wallet_create_wallet "(record { cycles = (2000000000000:nat64); settings = record {controller = opt principal \"$(dfx identity get-principal)\";};})") + CHILD_ID=$(echo "${CREATE_RES}" | tr '\n' ' ' | cut -d'"' -f 2) + assert_command dfx canister call "${CHILD_ID}" wallet_balance '()' } @test "forward user call through wallet" { - dfx_new - install_asset identity - dfx_start - WALLET=$(dfx identity get-wallet) - assert_command dfx canister create --all --wallet "$WALLET" - assert_command dfx build - assert_command dfx canister install --all --wallet "$WALLET" - - CALL_RES=$(dfx canister call e2e_project_backend fromCall --wallet "$WALLET") - CALLER=$(echo "${CALL_RES}" | cut -d'"' -f 2) - assert_eq "$CALLER" "$WALLET" - - assert_command dfx canister call "$WALLET" wallet_call \ - "(record { canister = principal \"$(dfx canister id e2e_project_backend)\"; method_name = \"amInitializer\"; args = blob \"DIDL\00\00\"; cycles = (0:nat64)})" - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01~\01" } })' # True in DIDL. + dfx_new + install_asset identity + dfx_start + WALLET=$(dfx identity get-wallet) + assert_command dfx canister create --all --wallet "$WALLET" + assert_command dfx build + assert_command dfx canister install --all --wallet "$WALLET" + + CALL_RES=$(dfx canister call e2e_project_backend fromCall --wallet "$WALLET") + CALLER=$(echo "${CALL_RES}" | cut -d'"' -f 2) + assert_eq "$CALLER" "$WALLET" + + assert_command dfx canister call "$WALLET" wallet_call \ + "(record { canister = principal \"$(dfx canister id e2e_project_backend)\"; method_name = \"amInitializer\"; args = blob \"DIDL\00\00\"; cycles = (0:nat64)})" + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01~\01" } })' # True in DIDL. } @test "forward user call through wallet: deploy" { - dfx_new - install_asset identity - dfx_start - WALLET=$(dfx identity get-wallet) - assert_command dfx deploy --wallet "$WALLET" - CALL_RES=$(dfx canister call e2e_project_backend fromCall --wallet "$WALLET") - CALLER=$(echo "${CALL_RES}" | cut -d'"' -f 2) - assert_eq "$CALLER" "$WALLET" - - assert_command dfx canister call e2e_project_backend amInitializer - assert_command dfx canister call "$WALLET" wallet_call \ - "(record { canister = principal \"$(dfx canister id e2e_project_backend)\"; method_name = \"amInitializer\"; args = blob \"DIDL\00\00\"; cycles = (0:nat64)})" - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01~\01" } })' # True in DIDL. + dfx_new + install_asset identity + dfx_start + WALLET=$(dfx identity get-wallet) + assert_command dfx deploy --wallet "$WALLET" + CALL_RES=$(dfx canister call e2e_project_backend fromCall --wallet "$WALLET") + CALLER=$(echo "${CALL_RES}" | cut -d'"' -f 2) + assert_eq "$CALLER" "$WALLET" + + assert_command dfx canister call e2e_project_backend amInitializer + assert_command dfx canister call "$WALLET" wallet_call \ + "(record { canister = principal \"$(dfx canister id e2e_project_backend)\"; method_name = \"amInitializer\"; args = blob \"DIDL\00\00\"; cycles = (0:nat64)})" + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01~\01" } })' # True in DIDL. } @test "a 64-bit wallet can still be called in the 128-bit context" { - use_wallet_wasm 0.8.2 - dfx_new hello - dfx_start - WALLET=$(dfx identity get-wallet) - assert_command dfx wallet balance - assert_command dfx deploy --wallet "$WALLET" - assert_command dfx canister call hello_backend greet '("")' --with-cycles 1 --wallet "$WALLET" - dfx identity new alice --storage-mode plaintext - ALICE_WALLET=$(dfx identity get-wallet --identity alice) - dfx wallet send "$ALICE_WALLET" 1 + use_wallet_wasm 0.8.2 + dfx_new hello + dfx_start + WALLET=$(dfx identity get-wallet) + assert_command dfx wallet balance + assert_command dfx deploy --wallet "$WALLET" + assert_command dfx canister call hello_backend greet '("")' --with-cycles 1 --wallet "$WALLET" + dfx identity new alice --storage-mode plaintext + ALICE_WALLET=$(dfx identity get-wallet --identity alice) + dfx wallet send "$ALICE_WALLET" 1 } @test "dfx canister deposit-cycles succeeds on a canister the caller does not own" { - dfx_new hello - dfx_start - dfx identity new alice --storage-mode plaintext - dfx deploy --no-wallet hello_backend --identity alice - assert_command dfx canister deposit-cycles 1 hello_backend --wallet "$(dfx identity get-wallet)" + dfx_new hello + dfx_start + dfx identity new alice --storage-mode plaintext + dfx deploy --no-wallet hello_backend --identity alice + assert_command dfx canister deposit-cycles 1 hello_backend --wallet "$(dfx identity get-wallet)" } @test "dfx canister deposit-cycles uses default wallet if no wallet is specified" { - dfx_new hello - dfx_start - dfx deploy - assert_command dfx canister deposit-cycles 1 hello_backend + dfx_new hello + dfx_start + dfx deploy + assert_command dfx canister deposit-cycles 1 hello_backend } @test "detects if there is no wallet to upgrade" { - dfx_new hello - assert_command_fail dfx wallet upgrade - assert_match "There is no wallet defined for identity 'default' on network 'local'. Nothing to do." + dfx_new hello + assert_command_fail dfx wallet upgrade + assert_match "There is no wallet defined for identity 'default' on network 'local'. Nothing to do." } @test "redeem-faucet-coupon can set a new wallet and top up an existing one" { - dfx_new hello - dfx_start - install_asset faucet - dfx deploy - dfx ledger fabricate-cycles --canister faucet --t 1000 - - dfx identity new --storage-mode plaintext faucet_testing - dfx identity use faucet_testing - - # prepare wallet to hand out - dfx wallet balance # this creates a new wallet with user faucet_testing as controller - dfx canister call faucet set_wallet_to_hand_out "(principal \"$(dfx identity get-wallet)\")" # register the wallet as the wallet that the faucet will return - rm "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" # forget about the currently configured wallet - - # assert: no wallet configured - export DFX_DISABLE_AUTO_WALLET=1 - assert_command_fail dfx wallet balance - assert_match "command requires a configured wallet" - - assert_command dfx wallet redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'valid-coupon' - assert_match "Redeemed coupon valid-coupon for a new wallet" - assert_match "New wallet set." - - # only succeeds if wallet is correctly set - assert_command dfx wallet balance - # checking only balance before the dot, rest may fluctuate - # balance may be 99.??? TC if cycles accounting is done, or 100.000 TC if not - assert_match "99\.|100\." - - unset DFX_DISABLE_AUTO_WALLET - - assert_command dfx wallet redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'another-valid-coupon' - assert_match "Redeemed coupon code another-valid-coupon for 10.000 TC" - - assert_command dfx wallet balance - # checking only balance before the dot, rest may fluctuate - # balance may be 109.??? TC if cycles accounting is done, or 110.000 TC if not - assert_match "109\.|110\." + dfx_new hello + dfx_start + install_asset faucet + dfx deploy + dfx ledger fabricate-cycles --canister faucet --t 1000 + + dfx identity new --storage-mode plaintext faucet_testing + dfx identity use faucet_testing + + # prepare wallet to hand out + dfx wallet balance # this creates a new wallet with user faucet_testing as controller + dfx canister call faucet set_wallet_to_hand_out "(principal \"$(dfx identity get-wallet)\")" # register the wallet as the wallet that the faucet will return + rm "$E2E_SHARED_LOCAL_NETWORK_DATA_DIRECTORY/wallets.json" # forget about the currently configured wallet + + # assert: no wallet configured + export DFX_DISABLE_AUTO_WALLET=1 + assert_command_fail dfx wallet balance + assert_match "command requires a configured wallet" + + assert_command dfx wallet redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'valid-coupon' + assert_match "Redeemed coupon valid-coupon for a new wallet" + assert_match "New wallet set." + + # only succeeds if wallet is correctly set + assert_command dfx wallet balance + # checking only balance before the dot, rest may fluctuate + # balance may be 99.??? TC if cycles accounting is done, or 100.000 TC if not + assert_match "99\.|100\." + + unset DFX_DISABLE_AUTO_WALLET + + assert_command dfx wallet redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'another-valid-coupon' + assert_match "Redeemed coupon code another-valid-coupon for 10.000 TC" + + assert_command dfx wallet balance + # checking only balance before the dot, rest may fluctuate + # balance may be 109.??? TC if cycles accounting is done, or 110.000 TC if not + assert_match "109\.|110\." } diff --git a/e2e/tests-icx-asset/icx-asset.bash b/e2e/tests-icx-asset/icx-asset.bash index 8c292050bf..786887aea2 100644 --- a/e2e/tests-icx-asset/icx-asset.bash +++ b/e2e/tests-icx-asset/icx-asset.bash @@ -3,24 +3,24 @@ load ../utils/_ setup() { - # when running e2e tests not in GitHub CI (so e.g. locally), build icx-proxy and set environment variable - if [ -z "$ICX_ASSET" ]; then - cargo build -p icx-asset - ICX_ASSET="$(pwd)/target/debug/icx-asset" - fi + # when running e2e tests not in GitHub CI (so e.g. locally), build icx-proxy and set environment variable + if [ -z "$ICX_ASSET" ]; then + cargo build -p icx-asset + ICX_ASSET="$(pwd)/target/debug/icx-asset" + fi - standard_setup + standard_setup - dfx_new_frontend - dfx_start + dfx_new_frontend + dfx_start - assert_command dfx deploy + assert_command dfx deploy } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } icx_asset_sync() { @@ -28,10 +28,10 @@ icx_asset_sync() { REPLICA_ADDRESS="http://localhost:$(get_webserver_port)" CANISTER_ID=$(dfx canister id e2e_project_frontend) if [ -z "$1" ]; then - assert_command "$ICX_ASSET" --pem "$IDENTITY" --replica "$REPLICA_ADDRESS" sync "$CANISTER_ID" src/e2e_project_frontend/assets + assert_command "$ICX_ASSET" --pem "$IDENTITY" --replica "$REPLICA_ADDRESS" sync "$CANISTER_ID" src/e2e_project_frontend/assets else - # shellcheck disable=SC2086 - assert_command "$ICX_ASSET" --pem "$IDENTITY" --replica "$REPLICA_ADDRESS" sync "$CANISTER_ID" $1 $2 + # shellcheck disable=SC2086 + assert_command "$ICX_ASSET" --pem "$IDENTITY" --replica "$REPLICA_ADDRESS" sync "$CANISTER_ID" $1 $2 fi } @@ -51,16 +51,16 @@ icx_asset_upload() { } @test "lists assets" { - for i in $(seq 1 400); do - echo "some easily duplicate text $i" >>src/e2e_project_frontend/assets/notreally.js - done - icx_asset_sync + for i in $(seq 1 400); do + echo "some easily duplicate text $i" >>src/e2e_project_frontend/assets/notreally.js + done + icx_asset_sync - icx_asset_list + icx_asset_list - assert_match "sample-asset.txt.*text/plain.*identity" - assert_match "notreally.js.*application/javascript.*gzip" - assert_match "notreally.js.*application/javascript.*identity" + assert_match "sample-asset.txt.*text/plain.*identity" + assert_match "notreally.js.*application/javascript.*gzip" + assert_match "notreally.js.*application/javascript.*identity" } @test "creates new files" { @@ -72,224 +72,224 @@ icx_asset_upload() { } @test "updates existing files" { - echo -n "an asset that will change" >src/e2e_project_frontend/assets/asset-to-change.txt - assert_command dfx deploy + echo -n "an asset that will change" >src/e2e_project_frontend/assets/asset-to-change.txt + assert_command dfx deploy - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/asset-to-change.txt";accept_encodings=vec{"identity"}})' - # shellcheck disable=SC2154 - assert_match '"an asset that will change"' "$stdout" + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/asset-to-change.txt";accept_encodings=vec{"identity"}})' + # shellcheck disable=SC2154 + assert_match '"an asset that will change"' "$stdout" - echo -n "an asset that has been changed" >src/e2e_project_frontend/assets/asset-to-change.txt + echo -n "an asset that has been changed" >src/e2e_project_frontend/assets/asset-to-change.txt - icx_asset_sync + icx_asset_sync - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/asset-to-change.txt";accept_encodings=vec{"identity"}})' - # shellcheck disable=SC2154 - assert_match '"an asset that has been changed"' "$stdout" + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/asset-to-change.txt";accept_encodings=vec{"identity"}})' + # shellcheck disable=SC2154 + assert_match '"an asset that has been changed"' "$stdout" echo pass } @test "deletes removed files" { - touch src/e2e_project_frontend/assets/will-delete-this.txt - dfx deploy + touch src/e2e_project_frontend/assets/will-delete-this.txt + dfx deploy - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend list '(record{})' - assert_match '"/will-delete-this.txt"' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend list '(record{})' + assert_match '"/will-delete-this.txt"' - rm src/e2e_project_frontend/assets/will-delete-this.txt + rm src/e2e_project_frontend/assets/will-delete-this.txt - icx_asset_sync + icx_asset_sync - assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend list '(record{})' - assert_not_match '"/will-delete-this.txt"' + assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/will-delete-this.txt";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend list '(record{})' + assert_not_match '"/will-delete-this.txt"' } @test "unsets asset encodings that are removed from project" { - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="text/plain"; content_encoding="arbitrary"; content=blob "content encoded in another way!"})' + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="text/plain"; content_encoding="arbitrary"; content=blob "content encoded in another way!"})' - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' - icx_asset_sync + icx_asset_sync - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' - # shellcheck disable=SC2086 - assert_command_fail dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"identity"}})' + # shellcheck disable=SC2086 + assert_command_fail dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/sample-asset.txt";accept_encodings=vec{"arbitrary"}})' } @test "synchronizes multiple directories" { - mkdir -p multiple/a - mkdir -p multiple/b - echo "x_contents" >multiple/a/x - echo "y_contents" >multiple/b/y + mkdir -p multiple/a + mkdir -p multiple/b + echo "x_contents" >multiple/a/x + echo "y_contents" >multiple/b/y - icx_asset_sync multiple/a multiple/b - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/x";accept_encodings=vec{"identity"}})' - assert_match "x_contents" - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/y";accept_encodings=vec{"identity"}})' - assert_match "y_contents" + icx_asset_sync multiple/a multiple/b + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/x";accept_encodings=vec{"identity"}})' + assert_match "x_contents" + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --query e2e_project_frontend get '(record{key="/y";accept_encodings=vec{"identity"}})' + assert_match "y_contents" } @test "reports errors about assets with the same key from multiple sources" { - mkdir -p multiple/a - mkdir -p multiple/b - echo "a_duplicate_contents" >multiple/a/duplicate - echo "b_duplicate_contents" >multiple/b/duplicate + mkdir -p multiple/a + mkdir -p multiple/b + echo "a_duplicate_contents" >multiple/a/duplicate + echo "b_duplicate_contents" >multiple/b/duplicate - assert_command_fail icx_asset_sync multiple/a multiple/b - assert_match "Asset with key '/duplicate' defined at .*/e2e_project/multiple/b/duplicate and .*/e2e_project/multiple/a/duplicate" + assert_command_fail icx_asset_sync multiple/a multiple/b + assert_match "Asset with key '/duplicate' defined at .*/e2e_project/multiple/b/duplicate and .*/e2e_project/multiple/a/duplicate" } @test "ignores filenames and directories starting with a dot" { - touch src/e2e_project_frontend/assets/.not-seen - touch src/e2e_project_frontend/assets/is-seen + touch src/e2e_project_frontend/assets/.not-seen + touch src/e2e_project_frontend/assets/is-seen - mkdir -p src/e2e_project_frontend/assets/.dir-skipped - touch src/e2e_project_frontend/assets/.dir-skipped/also-ignored + mkdir -p src/e2e_project_frontend/assets/.dir-skipped + touch src/e2e_project_frontend/assets/.dir-skipped/also-ignored - mkdir -p src/e2e_project_frontend/assets/dir-not-skipped - touch src/e2e_project_frontend/assets/dir-not-skipped/not-ignored + mkdir -p src/e2e_project_frontend/assets/dir-not-skipped + touch src/e2e_project_frontend/assets/dir-not-skipped/not-ignored - icx_asset_sync + icx_asset_sync - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/is-seen";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend get '(record{key="/dir-not-skipped/not-ignored";accept_encodings=vec{"identity"}})' - assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/.not-seen";accept_encodings=vec{"identity"}})' - assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/.dir-skipped/also-ignored";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/is-seen";accept_encodings=vec{"identity"}})' + assert_command dfx canister call --query e2e_project_frontend get '(record{key="/dir-not-skipped/not-ignored";accept_encodings=vec{"identity"}})' + assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/.not-seen";accept_encodings=vec{"identity"}})' + assert_command_fail dfx canister call --query e2e_project_frontend get '(record{key="/.dir-skipped/also-ignored";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend list '(record{})' + assert_command dfx canister call --query e2e_project_frontend list '(record{})' - assert_match 'is-seen' - assert_match 'not-ignored' + assert_match 'is-seen' + assert_match 'not-ignored' - assert_not_match 'not-seen' - assert_not_match 'also-ignored' + assert_not_match 'not-seen' + assert_not_match 'also-ignored' } @test "does not delete files that are not being uploaded" { - mkdir some_dir - echo "some stuff" >some_dir/a.txt - echo "more things" >some_dir/b.txt + mkdir some_dir + echo "some stuff" >some_dir/a.txt + echo "more things" >some_dir/b.txt - icx_asset_upload /=some_dir + icx_asset_upload /=some_dir - icx_asset_list + icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" + assert_match " /b.txt.*text/plain.*identity" - echo "ccc" >c.txt - icx_asset_upload c.txt + echo "ccc" >c.txt + icx_asset_upload c.txt - icx_asset_list + icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" - assert_match " /c.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" + assert_match " /b.txt.*text/plain.*identity" + assert_match " /c.txt.*text/plain.*identity" } @test "deletes asset if necessary in order to change content type" { - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="application/pdf"; content_encoding="identity"; content=blob "whatever contents!"})' - # shellcheck disable=SC2086 - assert_command dfx canister ${DFX_NO_WALLET:-} call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="application/pdf"; content_encoding="arbitrary"; content=blob "other contents"})' + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="application/pdf"; content_encoding="identity"; content=blob "whatever contents!"})' + # shellcheck disable=SC2086 + assert_command dfx canister ${DFX_NO_WALLET:-} call --update e2e_project_frontend store '(record{key="/sample-asset.txt"; content_type="application/pdf"; content_encoding="arbitrary"; content=blob "other contents"})' - icx_asset_list + icx_asset_list - assert_match " /sample-asset.txt.*application/pdf.*identity" - assert_match " /sample-asset.txt.*application/pdf.*arbitrary" + assert_match " /sample-asset.txt.*application/pdf.*identity" + assert_match " /sample-asset.txt.*application/pdf.*arbitrary" - echo "just some text" >sample-asset.txt + echo "just some text" >sample-asset.txt - # icx-asset upload should delete the asset (and upload its replacement) since the content type is different. - icx_asset_upload sample-asset.txt + # icx-asset upload should delete the asset (and upload its replacement) since the content type is different. + icx_asset_upload sample-asset.txt - icx_asset_list + icx_asset_list - assert_match " /sample-asset.txt.*text/plain.*identity" - assert_not_match " /sample-asset.txt.*application/pdf.*arbitrary" + assert_match " /sample-asset.txt.*text/plain.*identity" + assert_not_match " /sample-asset.txt.*application/pdf.*arbitrary" } @test "uploads multiple files" { - echo "this is the file content" >uploaded.txt - echo "this is the file content ttt" >xyz.txt - mkdir some_dir - echo "some stuff" >some_dir/a.txt - echo "more things" >some_dir/b.txt + echo "this is the file content" >uploaded.txt + echo "this is the file content ttt" >xyz.txt + mkdir some_dir + echo "some stuff" >some_dir/a.txt + echo "more things" >some_dir/b.txt - icx_asset_upload some_dir/*.txt - icx_asset_list + icx_asset_upload some_dir/*.txt + icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" + assert_match " /b.txt.*text/plain.*identity" } @test "uploads multiple files from absolute path" { - mkdir some_dir - echo "some stuff" >some_dir/a.txt - echo "more things" >some_dir/b.txt + mkdir some_dir + echo "some stuff" >some_dir/a.txt + echo "more things" >some_dir/b.txt - icx_asset_upload "$(realpath some_dir/a.txt)" "$(realpath some_dir/b.txt)" - icx_asset_list + icx_asset_upload "$(realpath some_dir/a.txt)" "$(realpath some_dir/b.txt)" + icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" + assert_match " /b.txt.*text/plain.*identity" } @test "uploads a file by name" { - echo "this is the file content" >uploaded.txt + echo "this is the file content" >uploaded.txt - icx_asset_upload uploaded.txt + icx_asset_upload uploaded.txt - icx_asset_list + icx_asset_list - assert_match " /uploaded.txt.*text/plain.*identity" + assert_match " /uploaded.txt.*text/plain.*identity" } @test "can override asset name" { - echo "this is the file content" >uploaded.txt + echo "this is the file content" >uploaded.txt - icx_asset_upload /abcd.txt=uploaded.txt + icx_asset_upload /abcd.txt=uploaded.txt - icx_asset_list + icx_asset_list - assert_match " /abcd.txt.*text/plain.*identity" + assert_match " /abcd.txt.*text/plain.*identity" } @test "uploads a directory by name" { - mkdir some_dir - echo "some stuff" >some_dir/a.txt - echo "more things" >some_dir/b.txt + mkdir some_dir + echo "some stuff" >some_dir/a.txt + echo "more things" >some_dir/b.txt - icx_asset_upload some_dir + icx_asset_upload some_dir - icx_asset_list + icx_asset_list - assert_match " /some_dir/a.txt.*text/plain.*identity" - assert_match " /some_dir/b.txt.*text/plain.*identity" + assert_match " /some_dir/a.txt.*text/plain.*identity" + assert_match " /some_dir/b.txt.*text/plain.*identity" } @test "uploads a directory by name as root" { - mkdir some_dir - echo "some stuff" >some_dir/a.txt - echo "more things" >some_dir/b.txt + mkdir some_dir + echo "some stuff" >some_dir/a.txt + echo "more things" >some_dir/b.txt - icx_asset_upload /=some_dir + icx_asset_upload /=some_dir - icx_asset_list + icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" + assert_match " /b.txt.*text/plain.*identity" } diff --git a/e2e/tests-replica/deploy.bash b/e2e/tests-replica/deploy.bash index 1faa10b72f..8ba88f5cf8 100644 --- a/e2e/tests-replica/deploy.bash +++ b/e2e/tests-replica/deploy.bash @@ -3,96 +3,96 @@ load ../utils/_ setup() { - standard_setup + standard_setup } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "deploy from a fresh project" { - dfx_new hello - dfx_start - install_asset greet - assert_command dfx deploy + dfx_new hello + dfx_start + install_asset greet + assert_command dfx deploy - assert_command dfx canister call hello_backend greet '("Banzai")' - assert_eq '("Hello, Banzai!")' + assert_command dfx canister call hello_backend greet '("Banzai")' + assert_eq '("Hello, Banzai!")' } @test "deploy a canister without dependencies" { - dfx_new hello - dfx_start - install_asset greet - assert_command dfx deploy hello_backend - assert_match 'Deploying: hello_backend' - assert_not_match 'hello_frontend' + dfx_new hello + dfx_start + install_asset greet + assert_command dfx deploy hello_backend + assert_match 'Deploying: hello_backend' + assert_not_match 'hello_frontend' } @test "deploy a canister with dependencies" { - dfx_new hello - dfx_start - install_asset greet - assert_command dfx deploy hello_frontend - assert_match 'Deploying: hello_backend hello_frontend' + dfx_new hello + dfx_start + install_asset greet + assert_command dfx deploy hello_frontend + assert_match 'Deploying: hello_backend hello_frontend' } @test "deploy a canister with non-circular shared dependencies" { - install_asset transitive_deps_canisters - dfx_start - assert_command dfx deploy canister_f - assert_match 'Deploying: canister_a canister_f canister_g canister_h' + install_asset transitive_deps_canisters + dfx_start + assert_command dfx deploy canister_f + assert_match 'Deploying: canister_a canister_f canister_g canister_h' } @test "report an error on attempt to deploy a canister with circular dependencies" { - install_asset transitive_deps_canisters - dfx_start - assert_command_fail dfx deploy canister_d - assert_match 'canister_d -> canister_e -> canister_d' + install_asset transitive_deps_canisters + dfx_start + assert_command_fail dfx deploy canister_d + assert_match 'canister_d -> canister_e -> canister_d' } @test "deploy with InstallMode::Install on an empty canister" { - dfx_new hello - install_asset greet - dfx_start - assert_command dfx canister create --all + dfx_new hello + install_asset greet + dfx_start + assert_command dfx canister create --all - assert_command dfx deploy - assert_match 'Installing code for canister' + assert_command dfx deploy + assert_match 'Installing code for canister' } @test "dfx deploy supports arguments" { - dfx_new hello - install_asset greet_arg - dfx_start - assert_command dfx canister create --all + dfx_new hello + install_asset greet_arg + dfx_start + assert_command dfx canister create --all - assert_command dfx deploy hello_backend --argument '("World")' + assert_command dfx deploy hello_backend --argument '("World")' - assert_command dfx canister call hello_backend greet - assert_match 'Hello, World' + assert_command dfx canister call hello_backend greet + assert_match 'Hello, World' } @test "dfx deploy with InstallMode::Install on first invocation, InstallMode::Upgrade on second" { - dfx_new hello - install_asset greet - dfx_start + dfx_new hello + install_asset greet + dfx_start - # In the normal case, whether for an initial install or a subsequent install, - # dfx deploy does the right thing, so it doesn't need to retry. - # Therefore, there is no "attempting (install|upgrade)" message. + # In the normal case, whether for an initial install or a subsequent install, + # dfx deploy does the right thing, so it doesn't need to retry. + # Therefore, there is no "attempting (install|upgrade)" message. - assert_command dfx deploy hello_backend - assert_match 'Installing code for canister' + assert_command dfx deploy hello_backend + assert_match 'Installing code for canister' - assert_command dfx canister call hello_backend greet '("First")' - assert_eq '("Hello, First!")' + assert_command dfx canister call hello_backend greet '("First")' + assert_eq '("Hello, First!")' - assert_command dfx deploy hello_backend --upgrade-unchanged - assert_match 'Upgrading code for canister' + assert_command dfx deploy hello_backend --upgrade-unchanged + assert_match 'Upgrading code for canister' - assert_command dfx canister call hello_backend greet '("Second")' - assert_eq '("Hello, Second!")' + assert_command dfx canister call hello_backend greet '("Second")' + assert_eq '("Hello, Second!")' } diff --git a/e2e/tests-replica/lifecycle.bash b/e2e/tests-replica/lifecycle.bash index 70e24a5ee2..a675477a76 100644 --- a/e2e/tests-replica/lifecycle.bash +++ b/e2e/tests-replica/lifecycle.bash @@ -3,57 +3,57 @@ load ../utils/_ setup() { - standard_setup + standard_setup - dfx_new hello + dfx_new hello } teardown() { - dfx_stop + dfx_stop - standard_teardown + standard_teardown } @test "test canister lifecycle" { - install_asset greet - dfx_start - dfx canister create --all - dfx build - dfx canister install hello_backend - assert_command dfx canister status hello_backend - assert_match "Status: Running." - - # Stop - assert_command dfx canister stop hello_backend - assert_command dfx canister status hello_backend - assert_match "Status: Stopped." - assert_command_fail dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' - assert_match "is stopped" - - # Start - assert_command dfx canister start hello_backend - assert_command dfx canister status hello_backend - assert_match "Status: Running." - - # Call - assert_command dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' - assert_match '("Hello, Names are difficult!")' - - # Id - assert_command dfx canister id hello_backend - assert_match "$(jq -r .hello_backend.local < .dfx/local/canister_ids.json)" - x="$(dfx canister id hello_backend)" - local old_id="$x" - - # Delete - assert_command_fail dfx canister delete hello_backend - assert_command dfx canister stop hello_backend - assert_command dfx canister delete hello_backend - assert_command_fail dfx canister status hello_backend - assert_match "Cannot find canister id. Please issue 'dfx canister create hello_backend'." - - # Create again - assert_command dfx canister create hello_backend - assert_command dfx canister id hello_backend - assert_neq "$old_id" + install_asset greet + dfx_start + dfx canister create --all + dfx build + dfx canister install hello_backend + assert_command dfx canister status hello_backend + assert_match "Status: Running." + + # Stop + assert_command dfx canister stop hello_backend + assert_command dfx canister status hello_backend + assert_match "Status: Stopped." + assert_command_fail dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' + assert_match "is stopped" + + # Start + assert_command dfx canister start hello_backend + assert_command dfx canister status hello_backend + assert_match "Status: Running." + + # Call + assert_command dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' + assert_match '("Hello, Names are difficult!")' + + # Id + assert_command dfx canister id hello_backend + assert_match "$(jq -r .hello_backend.local < .dfx/local/canister_ids.json)" + x="$(dfx canister id hello_backend)" + local old_id="$x" + + # Delete + assert_command_fail dfx canister delete hello_backend + assert_command dfx canister stop hello_backend + assert_command dfx canister delete hello_backend + assert_command_fail dfx canister status hello_backend + assert_match "Cannot find canister id. Please issue 'dfx canister create hello_backend'." + + # Create again + assert_command dfx canister create hello_backend + assert_command dfx canister id hello_backend + assert_neq "$old_id" }