diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000000..8226afb6b6 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +external-sources=true diff --git a/e2e/tests-dfx/assetscanister.bash b/e2e/tests-dfx/assetscanister.bash index 63826e3cdc..08dc13b9b1 100644 --- a/e2e/tests-dfx/assetscanister.bash +++ b/e2e/tests-dfx/assetscanister.bash @@ -38,7 +38,7 @@ delete_batch() { } check_permission_failure() { - assert_contains "$1" + assert_contains "$1" "$output" } @test "commit_batch is atomic" { @@ -51,9 +51,9 @@ check_permission_failure() { SET_ASSET_CONTENT="variant { SetAssetContent = record { key=\"/abd.txt\"; content_encoding = \"identity\"; chunk_ids=vec { $CHUNK_ID } } }" OPERATIONS="vec { $CREATE_ASSET ; $SET_ASSET_CONTENT }" assert_command_fail dfx canister call e2e_project_frontend commit_batch "(record { batch_id=$BATCH_ID; operations = $OPERATIONS })" - assert_contains "asset not found" + assert_contains "asset not found" "$output" assert_command dfx canister call e2e_project_frontend list '(record {})' - assert_not_contains "/abc.txt" + assert_not_contains "/abc.txt" "$output" } @test "batch id persists through upgrade" { @@ -78,7 +78,7 @@ check_permission_failure() { echo "new file content" > 'src/e2e_project_frontend/assets/new_file.txt' assert_command_fail dfx deploy --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" } @test "deploy --by-proposal extravaganza" { @@ -135,36 +135,36 @@ check_permission_failure() { dfx identity get-principal --identity prepare dfx canister call e2e_project_frontend list_permitted '(record { permission = variant { Commit }; })' assert_command dfx deploy e2e_project_frontend --by-proposal --identity prepare - assert_contains "Proposed commit of batch 2 with evidence 164fcc4d933ff9992ab6ab909a4bf350010fa0f4a3e1e247bfc679d3f45254e1. Either commit it by proposal, or delete it." + assert_contains "Proposed commit of batch 2 with evidence 164fcc4d933ff9992ab6ab909a4bf350010fa0f4a3e1e247bfc679d3f45254e1. Either commit it by proposal, or delete it." "$output" assert_command_fail dfx deploy e2e_project_frontend --by-proposal --identity prepare - assert_contains "Batch 2 is already proposed. Delete or execute it to propose another." + assert_contains "Batch 2 is already proposed. Delete or execute it to propose another." "$output" assert_command dfx deploy e2e_project_frontend --compute-evidence --identity anonymous # shellcheck disable=SC2154 - assert_eq "164fcc4d933ff9992ab6ab909a4bf350010fa0f4a3e1e247bfc679d3f45254e1" "$stdout" + assert_eq "164fcc4d933ff9992ab6ab909a4bf350010fa0f4a3e1e247bfc679d3f45254e1" ID=$(dfx canister id e2e_project_frontend) PORT=$(get_webserver_port) assert_command_fail curl --fail -vv http://localhost:"$PORT"/new_file.txt?canisterId="$ID" - assert_contains "The requested URL returned error: 404" + assert_contains "The requested URL returned error: 404" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/to-be-deleted.txt?canisterId="$ID" assert_command curl --fail -vv --output encoded-compressed-1.gz -H "Accept-Encoding: gzip" http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_match "content-encoding: gzip" + assert_match "content-encoding: gzip" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/update-my-properties.txt?canisterId="$ID" - assert_not_contains "x-extra-header: x-extra-value" + assert_not_contains "x-extra-header: x-extra-value" "$output" wrong_commit_args='(record { batch_id = 2; evidence = blob "\31\e0\bf\26\2c\ab\cb\bb\eb\65\a9\54\4b\a2\3c\7c\af\88\42\3f\e0\3f\68\14\8d\31\b2\e4\ca\50\cd\b1" } )' assert_command_fail dfx canister call e2e_project_frontend commit_proposed_batch "$wrong_commit_args" --identity commit - assert_match "batch computed evidence .* does not match presented evidence" + assert_match "batch computed evidence .* does not match presented evidence" "$output" commit_args='(record { batch_id = 2; evidence = blob "\16\4f\cc\4d\93\3f\f9\99\2a\b6\ab\90\9a\4b\f3\50\01\0f\a0\f4\a3\e1\e2\47\bf\c6\79\d3\f4\52\54\e1" } )' assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$commit_args" --identity commit - assert_contains "commit proposed batch 2 with evidence 164f" + assert_contains "commit proposed batch 2 with evidence 164f" "$output" assert_command dfx canister call e2e_project_frontend commit_proposed_batch "$commit_args" --identity commit assert_eq "()" @@ -172,19 +172,19 @@ check_permission_failure() { assert_command curl --fail -vv http://localhost:"$PORT"/new_file.txt?canisterId="$ID" # shellcheck disable=SC2154 assert_match "200 OK" "$stderr" - assert_match "new file content" + assert_match "new file content" "$output" # show the DeleteAsset operation was applied assert_command_fail curl --fail -vv http://localhost:"$PORT"/to-be-deleted.txt?canisterId="$ID" # show the UnsetAssetContent was applied (gzip content encoding was removed) assert_command curl --fail -vv -H "Accept-Encoding: gzip" http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_not_contains "content-encoding" - assert_eq "will not compress" "$stdout" + assert_not_contains "content-encoding" "$output" + assert_eq "will not compress" assert_command curl --fail -vv http://localhost:"$PORT"/update-my-properties.txt?canisterId="$ID" - assert_contains "x-extra-header: x-extra-value" - assert_contains "cache-control: max-age=888" + assert_contains "x-extra-header: x-extra-value" "$output" + assert_contains "cache-control: max-age=888" "$output" } @test "deploy --by-proposal lots of small assets should not overflow message limits" { @@ -213,7 +213,7 @@ check_permission_failure() { done assert_command dfx deploy e2e_project_frontend --by-proposal --identity prepare - assert_match "Proposed commit of batch 2 with evidence [0-9a-z]*. Either commit it by proposal, or delete it." + assert_match "Proposed commit of batch 2 with evidence [0-9a-z]*. Either commit it by proposal, or delete it." "$output" } @test "deploy --by-proposal all assets" { @@ -244,21 +244,21 @@ check_permission_failure() { dfx identity get-principal --identity prepare dfx canister call e2e_project_frontend list_permitted '(record { permission = variant { Commit }; })' assert_command dfx deploy e2e_project_frontend --by-proposal --identity prepare - assert_contains "Proposed commit of batch 2 with evidence 9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b. Either commit it by proposal, or delete it." + assert_contains "Proposed commit of batch 2 with evidence 9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b. Either commit it by proposal, or delete it." "$output" assert_command dfx deploy e2e_project_frontend --compute-evidence --identity anonymous # shellcheck disable=SC2154 - assert_eq "9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b" "$stdout" + assert_eq "9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b" ID=$(dfx canister id e2e_project_frontend) PORT=$(get_webserver_port) assert_command_fail curl --fail -vv http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID" - assert_contains "The requested URL returned error: 404" + assert_contains "The requested URL returned error: 404" "$output" commit_args='(record { batch_id = 2; evidence = blob "\9b\72\ee\e7\f0\d7\af\2a\9b\41\23\3c\34\1b\1c\aa\0c\90\5e\f9\14\05\f5\f5\13\ff\b5\8f\68\af\ee\5b" } )' assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$commit_args" --identity commit - assert_contains "commit proposed batch 2 with evidence 9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b" + assert_contains "commit proposed batch 2 with evidence 9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b" "$output" assert_command dfx canister call e2e_project_frontend commit_proposed_batch "$commit_args" --identity commit assert_eq "()" @@ -267,7 +267,7 @@ check_permission_failure() { assert_command curl --fail -vv http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID" # shellcheck disable=SC2154 assert_match "200 OK" "$stderr" - assert_match "This is a sample asset!" + assert_match "This is a sample asset!" "$output" } @test "validation methods" { @@ -283,21 +283,21 @@ check_permission_failure() { PREPARE_PRINCIPAL=$(dfx identity get-principal --identity prepare) assert_command dfx canister call e2e_project_frontend validate_grant_permission "(record { to_principal=principal \"$PREPARE_PRINCIPAL\"; permission = variant { Prepare }; })" - assert_contains 'Ok = "grant Prepare permission to principal '"$PREPARE_PRINCIPAL"'"' + assert_contains 'Ok = "grant Prepare permission to principal '"$PREPARE_PRINCIPAL"'"' "$output" assert_command dfx canister call e2e_project_frontend validate_grant_permission "(record { to_principal=principal \"$PREPARE_PRINCIPAL\"; permission = variant { Prepare }; })" --identity prepare - assert_contains 'Ok = "grant Prepare permission to principal '"$PREPARE_PRINCIPAL"'"' + assert_contains 'Ok = "grant Prepare permission to principal '"$PREPARE_PRINCIPAL"'"' "$output" assert_command dfx canister call e2e_project_frontend validate_revoke_permission "(record { of_principal=principal \"$PREPARE_PRINCIPAL\"; permission = variant { Commit }; })" - assert_contains 'Ok = "revoke Commit permission from principal '"$PREPARE_PRINCIPAL"'"' + assert_contains 'Ok = "revoke Commit permission from principal '"$PREPARE_PRINCIPAL"'"' "$output" assert_command dfx canister call e2e_project_frontend validate_take_ownership "()" - assert_contains 'Ok = "revoke all permissions, then gives the caller Commit permissions"' + assert_contains 'Ok = "revoke all permissions, then gives the caller Commit permissions"' "$output" FE_CANISTER_ID="$(dfx canister id e2e_project_frontend)" rm .dfx/local/canister_ids.json assert_command_fail dfx canister call "$FE_CANISTER_ID" validate_revoke_permission "(record { of_principal=principal \"$PREPARE_PRINCIPAL\"; permission = variant { FlyBeFree }; })" - assert_contains "FlyBeFree not found" + assert_contains "FlyBeFree not found" "$output" } @test "access control - fine-grained" { @@ -374,11 +374,11 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend create_batch '(record { })' --identity commit assert_command dfx canister call e2e_project_frontend create_batch '(record { })' --identity prepare assert_command_fail dfx canister call e2e_project_frontend create_batch '(record { })' --identity manage-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_batch '(record { })' --identity no-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_batch '(record { })' --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # create chunk BATCH_ID="$(create_batch)" @@ -389,11 +389,11 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend create_chunk "$args" --identity commit assert_command dfx canister call e2e_project_frontend create_chunk "$args" --identity prepare assert_command_fail dfx canister call e2e_project_frontend create_chunk "$args" --identity manage-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_chunk "$args" --identity no-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_chunk "$args" --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # create_asset args='(record { key="/a.txt"; content_type="text/plain" })' @@ -402,13 +402,13 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend delete_asset "$delete_args" assert_command dfx canister call e2e_project_frontend create_asset "$args" --identity commit assert_command_fail dfx canister call e2e_project_frontend create_asset "$args" --identity prepare - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_asset "$args" --identity manage-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_asset "$args" --identity no-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend create_asset "$args" --identity anonymous - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" # commit_batch BATCH_ID="$(create_batch)" @@ -418,13 +418,13 @@ check_permission_failure() { args="(record { batch_id=$BATCH_ID; operations=vec{} })" assert_command dfx canister call e2e_project_frontend commit_batch "$args" --identity commit assert_command_fail dfx canister call e2e_project_frontend commit_batch "$args" --identity prepare - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_batch "$args" --identity manage-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_batch "$args" --identity no-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_batch "$args" --identity anonymous - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" # propose_commit_batch BATCH_ID="$(create_batch)" @@ -443,11 +443,11 @@ check_permission_failure() { delete_batch "$BATCH_ID" assert_command_fail dfx canister call e2e_project_frontend propose_commit_batch "$args" --identity manage-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend propose_commit_batch "$args" --identity no-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend propose_commit_batch "$args" --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # delete_batch @@ -464,11 +464,11 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend delete_batch "$args" --identity prepare assert_command_fail dfx canister call e2e_project_frontend delete_batch "$args" --identity manage-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend delete_batch "$args" --identity no-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend delete_batch "$args" --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # compute_evidence @@ -495,11 +495,11 @@ check_permission_failure() { assert_command_fail dfx canister call e2e_project_frontend compute_evidence "$args" --identity manage-permissions assert_command_fail dfx canister call e2e_project_frontend delete_batch "$args" --identity manage-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend compute_evidence "$args" --identity no-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend compute_evidence "$args" --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # commit_proposed_batch @@ -522,13 +522,13 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend commit_proposed_batch "$args" --identity commit assert_command_fail dfx canister call e2e_project_frontend commit_proposed_batch "$args" --identity prepare - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_proposed_batch "$args" --identity manage-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_proposed_batch "$args" --identity no-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_proposed_batch "$args" --identity anonymous - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" # get_configuration() args="()" @@ -536,24 +536,24 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend get_configuration "$args" --identity prepare assert_command_fail dfx canister call e2e_project_frontend get_configuration "$args" --identity manage-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend get_configuration "$args" --identity no-permissions - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend get_configuration "$args" --identity anonymous - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # configure() args="(record { })" assert_command dfx canister call e2e_project_frontend configure "$args" --identity commit assert_command_fail dfx canister call e2e_project_frontend configure "$args" --identity prepare - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend configure "$args" --identity manage-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend configure "$args" --identity no-permissions - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command_fail dfx canister call e2e_project_frontend configure "$args" --identity anonymous - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" # validate_configure() args="(record { })" @@ -571,7 +571,7 @@ check_permission_failure() { assert_command dfx canister call e2e_project_frontend compute_evidence "$args" args="(record { batch_id=$BATCH_ID; evidence=$EVIDENCE_BLOB })" assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$args" - assert_contains "commit proposed batch $BATCH_ID with evidence" + assert_contains "commit proposed batch $BATCH_ID with evidence" "$output" assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$args" --identity commit assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$args" --identity prepare assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$args" --identity manage-permissions @@ -585,23 +585,23 @@ check_permission_failure() { # controller w/o permissions can revoke assert_command dfx canister call e2e_project_frontend revoke_permission "(record { of_principal=principal \"$COMMIT_PRINCIPAL\"; permission = variant { Commit }; })" --identity non-permissioned-controller assert_command_fail dfx canister call e2e_project_frontend create_batch '(record { })' --identity commit - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" assert_command_fail dfx canister call e2e_project_frontend commit_batch "(record { batch_id=7; operations=vec{} })" --identity commit - assert_contains "Caller does not have Commit permission" + assert_contains "Caller does not have Commit permission" "$output" assert_command dfx canister call e2e_project_frontend create_batch '(record { })' --identity prepare # principal with only ManagePermissions can revoke assert_command dfx canister call e2e_project_frontend revoke_permission "(record { of_principal=principal \"$PREPARE_PRINCIPAL\"; permission = variant { Prepare }; })" --identity manage-permissions assert_command_fail dfx canister call e2e_project_frontend create_batch '(record { })' --identity prepare - assert_contains "Caller does not have Prepare permission" + assert_contains "Caller does not have Prepare permission" "$output" # can revoke your own permissions even without ManagePermissions assert_command dfx canister call e2e_project_frontend grant_permission "(record { to_principal=principal \"$COMMIT_PRINCIPAL\"; permission = variant { Commit }; })" --identity manage-permissions assert_command dfx canister call e2e_project_frontend list_permitted '(record { permission = variant { Commit }; })' - assert_contains "$COMMIT_PRINCIPAL" + assert_contains "$COMMIT_PRINCIPAL" "$output" assert_command dfx canister call e2e_project_frontend revoke_permission "(record { of_principal=principal \"$COMMIT_PRINCIPAL\"; permission = variant { Commit }; })" --identity commit assert_command dfx canister call e2e_project_frontend list_permitted '(record { permission = variant { Commit }; })' - assert_not_contains "$COMMIT_PRINCIPAL" + assert_not_contains "$COMMIT_PRINCIPAL" "$output" } @@ -666,7 +666,7 @@ check_permission_failure() { # deployer is automatically authorized assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_contains "$CONTROLLER_PRINCIPAL" + assert_contains "$CONTROLLER_PRINCIPAL" "$output" # non-controller is not allowed to deauthorize principals assert_command dfx identity use stranger @@ -676,7 +676,7 @@ check_permission_failure() { assert_command dfx identity use controller assert_command dfx canister call e2e_project_frontend deauthorize "(principal \"$CONTROLLER_PRINCIPAL\")" assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_not_contains "$CONTROLLER_PRINCIPAL" + assert_not_contains "$CONTROLLER_PRINCIPAL" "$output" # while not authorized, dfx deploy fails, even as controller echo "new file content" > 'src/e2e_project_frontend/assets/new_file.txt' @@ -685,7 +685,7 @@ check_permission_failure() { # canister controllers may always authorize principals, even if they're not authorized themselves assert_command dfx canister call e2e_project_frontend authorize "(principal \"$STRANGER_PRINCIPAL\")" assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_contains "$STRANGER_PRINCIPAL" + assert_contains "$STRANGER_PRINCIPAL" "$output" # authorized principals, that are not controllers, cannot authorize other principals assert_command dfx canister call e2e_project_frontend authorize "(principal \"$AUTHORIZED_PRINCIPAL\")" --identity controller @@ -694,30 +694,30 @@ check_permission_failure() { check_permission_failure "Caller does not have ManagePermissions permission and is not a controller." assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_not_contains "$BACKDOOR_PRINCIPAL" + assert_not_contains "$BACKDOOR_PRINCIPAL" "$output" # authorized principals, that are not controllers, cannot deauthorize others assert_command dfx canister call e2e_project_frontend authorize "(principal \"$BACKDOOR_PRINCIPAL\")" --identity controller assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_contains "$BACKDOOR_PRINCIPAL" + assert_contains "$BACKDOOR_PRINCIPAL" "$output" assert_command_fail dfx canister call e2e_project_frontend deauthorize "(principal \"$BACKDOOR_PRINCIPAL\")" --identity authorized check_permission_failure "Caller is not a controller" assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_contains "$BACKDOOR_PRINCIPAL" + assert_contains "$BACKDOOR_PRINCIPAL" "$output" # authorized principals, that are not controllers, can deauthorize themselves assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_contains "$AUTHORIZED_PRINCIPAL" + assert_contains "$AUTHORIZED_PRINCIPAL" "$output" assert_command dfx canister call e2e_project_frontend deauthorize "(principal \"$AUTHORIZED_PRINCIPAL\")" --identity authorized assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_not_contains "$AUTHORIZED_PRINCIPAL" + assert_not_contains "$AUTHORIZED_PRINCIPAL" "$output" # canister controller may always deauthorize, even if they're not authorized themselves assert_command dfx canister call e2e_project_frontend deauthorize "(principal \"$STRANGER_PRINCIPAL\")" assert_command dfx canister call e2e_project_frontend list_authorized '()' - assert_not_contains "$STRANGER_PRINCIPAL" + assert_not_contains "$STRANGER_PRINCIPAL" "$output" # after authorizing, deploy works again, even for non-controller assert_command dfx canister call e2e_project_frontend authorize "(principal \"$STRANGER_PRINCIPAL\")" @@ -740,14 +740,14 @@ check_permission_failure() { # decode as expected - %c3%a6 is the utf-8 encoding of the ae symbol assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%c3%a6";headers=vec{};method="GET";body=vec{}})' - assert_match "filename is an ae symbol" # candid looks like blob "filename is \c3\a6\0a" + assert_match "filename is an ae symbol" "$output" # candid looks like blob "filename is \c3\a6\0a" assert_command curl --fail -vv http://localhost:"$PORT"/%c3%a6?canisterId="$ID" - assert_match "filename is an ae symbol" + assert_match "filename is an ae symbol" "$output" # fails with because %e6 is not valid utf-8 percent encoding assert_command_fail curl --fail -vv http://localhost:"$PORT"/%e6?canisterId="$ID" - assert_contains "503 Service Unavailable" + assert_contains "503 Service Unavailable" "$output" } @test "http_request percent-decodes urls" { @@ -768,20 +768,20 @@ check_permission_failure() { # 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_match "contents of file with space in filename" "$output" 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_match "contents of file with plus in filename" "$output" 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_match "contents of file with plus in filename" "$output" assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/has%25percent.txt";headers=vec{};method="GET";body=vec{}})' - assert_match "contents of file with percent in filename" + assert_match "contents of file with percent in filename" "$output" assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%c3%a6";headers=vec{};method="GET";body=vec{}})' - assert_match "filename is an ae symbol" # candid looks like blob "filename is \c3\a6\0a" + assert_match "filename is an ae symbol" "$output" # candid looks like blob "filename is \c3\a6\0a" assert_command dfx canister call --query e2e_project_frontend http_request '(record{url="/%25";headers=vec{};method="GET";body=vec{}})' - assert_match "filename is percent" + assert_match "filename is percent" "$output" # 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" + assert_match "filename contains question mark" "$output" # 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 @@ -805,27 +805,27 @@ check_permission_failure() { 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_match "contents of file with space in filename" "$output" 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_match "contents of file with plus in filename" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/has%25percent.txt?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "contents of file with percent in filename" + assert_match "contents of file with percent in filename" "$output" assert_command_fail curl --fail -vv http://localhost:"$PORT"/%e6?canisterId="$ID" # fails because %e6 is not valid utf-8 percent encoding - assert_contains "503 Service Unavailable" + assert_contains "503 Service Unavailable" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/%25?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "filename is percent symbol" + assert_match "filename is percent symbol" "$output" 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_match "filename contains question mark" "$output" 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 @@ -849,17 +849,17 @@ check_permission_failure() { PORT=$(get_webserver_port) assert_command curl -v --output not-compressed http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_not_match "content-encoding:" + assert_not_match "content-encoding:" "$output" 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" + assert_match "content-encoding: gzip" "$output" 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" + assert_match "content-encoding: gzip" "$output" gunzip encoded-compressed-2.gz diff encoded-compressed-2 src/e2e_project_frontend/assets/notreally.js } @@ -884,17 +884,17 @@ check_permission_failure() { PORT=$(get_webserver_port) assert_command curl -v --output not-compressed http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_not_match "content-encoding:" + assert_not_match "content-encoding:" "$output" diff not-compressed src/e2e_project_frontend/assets/notreally.js assert_command curl -v --output encoded-compressed-1.br -H "Accept-Encoding: br" http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_match "content-encoding: br" + assert_match "content-encoding: br" "$output" brotli --decompress encoded-compressed-1.br 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.br -H "Accept-Encoding: br, deflate, gzip" http://localhost:"$PORT"/notreally.js?canisterId="$ID" - assert_match "content-encoding: br" + assert_match "content-encoding: br" "$output" brotli --decompress encoded-compressed-2.br diff encoded-compressed-2 src/e2e_project_frontend/assets/notreally.js } @@ -907,14 +907,14 @@ check_permission_failure() { dfx_start assert_command dfx deploy -v - assert_match '/asset1.bin 1/1' - assert_match '/asset2.bin 1/1' + assert_match '/asset1.bin 1/1' "$output" + assert_match '/asset2.bin 1/1' "$output" dd if=/dev/urandom of=src/e2e_project_frontend/assets/asset2.bin bs=400000 count=1 assert_command dfx deploy -v - assert_match '/asset1.bin.*is already installed' - assert_match '/asset2.bin 1/1' + assert_match '/asset1.bin.*is already installed' "$output" + assert_match '/asset2.bin 1/1' "$output" } @test "unsets asset encodings that are removed from project" { @@ -944,13 +944,13 @@ check_permission_failure() { assert_command dfx canister call --query e2e_project_frontend get_chunk '(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 get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0})' - assert_match 'sha256 required' + assert_match 'sha256 required' "$output" 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 blob "XWV" })' - assert_match 'sha256 mismatch' + assert_match 'sha256 mismatch' "$output" 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_match 'sha256 mismatch' "$output" } @@ -964,11 +964,11 @@ check_permission_failure() { assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl # shellcheck disable=SC2154 - assert_eq '(blob "\b8\01\20\80\0a\77\31\32\20\00\78\79\0a\4b\4c\0b\0a\6a\6b")' "$stdout" + assert_eq '(blob "\b8\01\20\80\0a\77\31\32\20\00\78\79\0a\4b\4c\0b\0a\6a\6b")' assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl # shellcheck disable=SC2154 - assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' "$stdout" + 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 '()' @@ -977,15 +977,15 @@ check_permission_failure() { assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl # shellcheck disable=SC2154 - assert_eq '(blob "XWV")' "$stdout" + assert_eq '(blob "XWV")' assert_command dfx canister call --query e2e_project_frontend retrieve '("AA")' --output idl # shellcheck disable=SC2154 - assert_eq '(blob "hello, world!")' "$stdout" + assert_eq '(blob "hello, world!")' assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl # shellcheck disable=SC2154 - assert_eq '(blob "XWV")' "$stdout" + assert_eq '(blob "XWV")' assert_command_fail dfx canister call --query e2e_project_frontend retrieve '("C")' } @@ -1023,17 +1023,17 @@ CHERRIES" "$stdout" # 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_match 'Asset too large.' "$output" 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_match 'total_length = 6_000_051' "$output" + assert_match 'content_type = "application/octet-stream"' "$output" + assert_match 'content_encoding = "identity"' "$output" 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_contains "sha256 mismatch" "$output" 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"})' @@ -1078,36 +1078,36 @@ CHERRIES" "$stdout" # Initial deploy should sync all 150 assets assert_command dfx deploy -v - assert_match 'test001.txt.*1/1' - assert_match 'test100.txt.*1/1' - assert_match 'test150.txt.*1/1' + assert_match 'test001.txt.*1/1' "$output" + assert_match 'test100.txt.*1/1' "$output" + assert_match 'test150.txt.*1/1' "$output" # Verify all assets were uploaded by checking a few across the range assert_command dfx canister call --query e2e_project_frontend get '(record{key="/test001.txt";accept_encodings=vec{"identity"}})' - assert_match "test content 1" + assert_match "test content 1" "$output" assert_command dfx canister call --query e2e_project_frontend get '(record{key="/test100.txt";accept_encodings=vec{"identity"}})' - assert_match "test content 100" + assert_match "test content 100" "$output" assert_command dfx canister call --query e2e_project_frontend get '(record{key="/test150.txt";accept_encodings=vec{"identity"}})' - assert_match "test content 150" + assert_match "test content 150" "$output" # Modify only one asset echo "modified content 075" > "src/e2e_project_frontend/assets/test075.txt" # Redeploy - should only sync the modified asset assert_command dfx deploy -v - assert_match 'test075.txt.*1/1' - assert_match 'test001.txt.*is already installed' - assert_match 'test150.txt.*is already installed' + assert_match 'test075.txt.*1/1' "$output" + assert_match 'test001.txt.*is already installed' "$output" + assert_match 'test150.txt.*is already installed' "$output" # Verify the modified asset was updated assert_command dfx canister call --query e2e_project_frontend get '(record{key="/test075.txt";accept_encodings=vec{"identity"}})' - assert_match "modified content 075" + assert_match "modified content 075" "$output" # Verify other assets remain unchanged assert_command dfx canister call --query e2e_project_frontend get '(record{key="/test074.txt";accept_encodings=vec{"identity"}})' - assert_match "test content 74" + assert_match "test content 74" "$output" assert_command dfx canister call --query e2e_project_frontend get '(record{key="/test076.txt";accept_encodings=vec{"identity"}})' - assert_match "test content 76" + assert_match "test content 76" "$output" } @test "identifies content type" { @@ -1368,17 +1368,17 @@ EOF PORT=$(get_webserver_port) assert_command curl --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "cache-control: max-age=2000" + assert_match "cache-control: max-age=2000" "$output" 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_match "cache-control: max-age=2000" "$output" + assert_match "x-header: x-value" "$output" assert_command curl -vv "http://localhost:$PORT/.ignored-by-default.txt?canisterId=$ID" - assert_match "404 Not Found" + assert_match "404 Not Found" "$output" assert_command curl -vv "http://localhost:$PORT/.well-known/.hidden/ignored.txt?canisterId=$ID" - assert_match "404 Not Found" + assert_match "404 Not Found" "$output" assert_command curl -vv "http://localhost:$PORT/.well-known/.another-hidden/ignored.txt?canisterId=$ID" - assert_match "404 Not Found" + assert_match "404 Not Found" "$output" } @test "asset configuration via .ic-assets.json5 - overwriting default headers" { @@ -1429,10 +1429,10 @@ EOF echo '[]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_contains "This project does not define a security policy for any assets." + assert_contains "This project does not define a security policy for any assets." "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_not_match "content-security-policy" - assert_not_match "permissions-policy" + assert_not_match "content-security-policy" "$output" + assert_not_match "permissions-policy" "$output" # No security policy defined, warning disabled for one asset echo '[ @@ -1443,13 +1443,13 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_contains "This project does not define a security policy for some assets." - assert_contains "Assets without any security policy:" - assert_contains "- /thing2.json" - assert_not_contains "- /thing.json" + assert_contains "This project does not define a security policy for some assets." "$output" + assert_contains "Assets without any security policy:" "$output" + assert_contains "- /thing2.json" "$output" + assert_not_contains "- /thing.json" "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_not_match "content-security-policy" - assert_not_match "permissions-policy" + assert_not_match "content-security-policy" "$output" + assert_not_match "permissions-policy" "$output" # No security policy defined, warning disabled for all assets echo '[ @@ -1460,10 +1460,10 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_not_contains "This project does not define a security policy for any assets." + assert_not_contains "This project does not define a security policy for any assets." "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_not_match "content-security-policy" - assert_not_match "permissions-policy" + assert_not_match "content-security-policy" "$output" + assert_not_match "permissions-policy" "$output" # Security policy "disabled" defined for all assets, which disables the warning echo '[ @@ -1474,11 +1474,11 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_not_contains "This project does not define a security policy for any assets." - assert_not_contains "This project uses the default security policy for all assets." + assert_not_contains "This project does not define a security policy for any assets." "$output" + assert_not_contains "This project uses the default security policy for all assets." "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_not_match "content-security-policy" - assert_not_match "permissions-policy" + assert_not_match "content-security-policy" "$output" + assert_not_match "permissions-policy" "$output" # Security policy "standard" defined for all assets, warning not disabled echo '[ @@ -1489,11 +1489,11 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_contains "This project uses the default security policy for all assets." - assert_not_contains "Unhardened assets:" + assert_contains "This project uses the default security policy for all assets." "$output" + assert_not_contains "Unhardened assets:" "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "content-security-policy" - assert_match "permissions-policy" + assert_match "content-security-policy" "$output" + assert_match "permissions-policy" "$output" # Security policy "standard" defined for all assets, warning disabled for one asset echo '[ @@ -1508,13 +1508,13 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_contains "This project uses the default security policy for some assets." - assert_contains "Unhardened assets:" - assert_contains "- /thing2.json" - assert_not_contains "- /thing.json" + assert_contains "This project uses the default security policy for some assets." "$output" + assert_contains "Unhardened assets:" "$output" + assert_contains "- /thing2.json" "$output" + assert_not_contains "- /thing.json" "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "content-security-policy" - assert_match "permissions-policy" + assert_match "content-security-policy" "$output" + assert_match "permissions-policy" "$output" # Security policy "standard" defined for all assets, warning disabled for all assets echo '[ @@ -1526,10 +1526,10 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_not_contains "This project uses the default security policy for all assets." + assert_not_contains "This project uses the default security policy for all assets." "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "content-security-policy" - assert_match "permissions-policy" + assert_match "content-security-policy" "$output" + assert_match "permissions-policy" "$output" # Security policy "hardened" defined for all assets but no custom headers results in an error echo '[ @@ -1540,7 +1540,7 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command_fail dfx deploy - assert_contains "does not actually configure any custom improvements over the standard policy" + assert_contains "does not actually configure any custom improvements over the standard policy" "$output" # Security policy "hardened" defined for all assets, with overwriting default security headers echo '[ @@ -1554,11 +1554,11 @@ EOF ]' > src/e2e_project_frontend/assets/.ic-assets.json5 assert_command dfx deploy - assert_not_contains "This project does not define a security policy for any assets." - assert_not_contains "This project uses the default security policy for all assets." + assert_not_contains "This project does not define a security policy for any assets." "$output" + assert_not_contains "This project uses the default security policy for all assets." "$output" assert_command curl --fail --head "http://localhost:$PORT/thing.json?canisterId=$ID" - assert_match "content-security-policy: overwritten" - assert_match "permissions-policy" + assert_match "content-security-policy: overwritten" "$output" + assert_match "permissions-policy" "$output" } @test "asset configuration via .ic-assets.json5 - overwriting default encodings" { @@ -1586,13 +1586,13 @@ EOF # favicon.ico is not available in gzip format by default but was configured to be assert_command curl -vv -H "Accept-Encoding: gzip" "http://localhost:$PORT/favicon.ico?canisterId=$ID" - assert_match "content-encoding: gzip" + assert_match "content-encoding: gzip" "$output" # index.html is available in gzip format by default but was configured not to be # The asset canister would serve the gzip encoding if it was available, but can't. # Therefore it falls back to the identity encoding, meaning there is no `content-encoding` header present assert_command curl -vv -H "Accept-Encoding: gzip" "http://localhost:$PORT/index.html?canisterId=$ID" - assert_not_match "content-encoding" + assert_not_match "content-encoding" "$output" } @test "aliasing rules: to .html or /index.html" { @@ -1608,17 +1608,17 @@ EOF # 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_match "test alias file" "$output" 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_match "test alias file" "$output" 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_match "test index file" "$output" 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_match "test alias file" "$output" 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_match "test alias file" "$output" 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" + assert_match "test index file" "$output" ID=$(dfx canister id e2e_project_frontend) PORT=$(get_webserver_port) @@ -1626,16 +1626,16 @@ EOF 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_match "test alias file" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "test alias file" + assert_match "test alias file" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "test index file" + assert_match "test index file" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/index_test/index?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "test index file" + assert_match "test index file" "$output" # toggle aliasing on and off using `set_asset_properties` # this doesn't work, see https://dfinity.atlassian.net/browse/SDK-1246 @@ -1687,7 +1687,7 @@ EOF # However, due to returning the wrong certificate, it fails with Err(InvalidResponseHashes) # see https://dfinity.atlassian.net/browse/SDK-1246 - assert_contains "503 Service Unavailable" + assert_contains "503 Service Unavailable" "$output" assert_command dfx canister call e2e_project_frontend set_asset_properties '( record { key="/test_alias_file.html"; is_aliased=opt(opt(true)) })' @@ -1696,25 +1696,25 @@ EOF # redirect survives upgrade assert_command dfx deploy --upgrade-unchanged -v - assert_match "is already installed" + assert_match "is already installed" "$output" 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_match "test alias file" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "test alias file" + assert_match "test alias file" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "test index file" + assert_match "test index file" "$output" 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_match "test alias file" "$output" 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_match "test alias file" "$output" 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" + assert_match "test index file" "$output" # disabling redirect works echo "DISABLING NOW" @@ -1729,23 +1729,23 @@ EOF 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_match "test alias file" "$output" assert_command_fail curl --fail -vv http://localhost:"$PORT"/test_alias_file?canisterId="$ID" # again see # see https://dfinity.atlassian.net/browse/SDK-1246, this should be 404 # assert_match "404 Not Found" "$stderr" - assert_contains "503 Service Unavailable" + assert_contains "503 Service Unavailable" "$output" assert_command curl --fail -vv http://localhost:"$PORT"/index_test?canisterId="$ID" assert_match "200 OK" "$stderr" - assert_match "test index file" + assert_match "test index file" "$output" 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_match "test alias file" "$output" 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_match "key not found" "$output" 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" + assert_match "test index file" "$output" # disabled redirect survives canister upgrade echo "UPGRADE" @@ -1754,19 +1754,19 @@ EOF 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_match "test alias file" "$output" 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_match "test index file" "$output" 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_match "test alias file" "$output" 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_match "key not found" "$output" 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" + assert_match "test index file" "$output" # } @@ -1812,14 +1812,14 @@ EOF ]' > src/e2e_project_frontend/assets/somedir/.ic-assets.json5 assert_command dfx deploy - assert_match 'WARNING: 1 unmatched configuration in .*/src/e2e_project_frontend/assets/.ic-assets.json config file:' + assert_match 'WARNING: 1 unmatched configuration in .*/src/e2e_project_frontend/assets/.ic-assets.json config file:' "$output" assert_contains 'WARNING: { "match": "nevermatchme", "cache": { "max_age": 2000 } -}' - assert_match 'WARNING: 4 unmatched configurations in .*/src/e2e_project_frontend/assets/somedir/.ic-assets.json config file:' +}' "$output" + assert_match 'WARNING: 4 unmatched configurations in .*/src/e2e_project_frontend/assets/somedir/.ic-assets.json config file:' "$output" assert_contains 'WARNING: { "match": "nevermatchme", "headers": {}, @@ -1836,7 +1836,7 @@ WARNING: { "x-header": "x-value" }, "ignore": false -}' +}' "$output" # splitting this up into two checks, because the order is different on macos vs ubuntu assert_contains 'WARNING: { "match": "/thanks-for-not-stripping-forward-slash", @@ -1844,7 +1844,7 @@ WARNING: { "x-header": "x-value" }, "ignore": false -}' +}' "$output" } @test "asset configuration via .ic-assets.json5 - get and set asset properties" { @@ -1874,18 +1874,18 @@ WARNING: { allow_raw_access = opt true; max_age = opt (2_000 : nat64); }, -)' +)' "$output" # 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" + assert_match "Caller does not have Commit permission" "$output" 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" + assert_match "Caller does not have Commit permission" "$output" # 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_contains '()' "$output" assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' assert_contains '( record { @@ -1894,11 +1894,11 @@ WARNING: { allow_raw_access = opt true; max_age = opt (5 : nat64); }, -)' +)' "$output" # 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_contains '()' "$output" assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' assert_contains '( record { @@ -1907,11 +1907,11 @@ WARNING: { allow_raw_access = opt true; max_age = opt (5 : nat64); }, -)' +)' "$output" # 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_contains '()' "$output" assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' assert_contains '( record { @@ -1920,11 +1920,11 @@ WARNING: { allow_raw_access = opt true; max_age = opt (5 : nat64); }, -)' +)' "$output" # 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_contains '()' "$output" assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' assert_contains '( record { @@ -1933,11 +1933,11 @@ WARNING: { allow_raw_access = opt true; max_age = opt (5 : nat64); }, -)' +)' "$output" # 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_contains '()' "$output" assert_command dfx canister call e2e_project_frontend get_asset_properties '("/somedir/upload-me.txt")' assert_contains '( record { @@ -1946,7 +1946,7 @@ WARNING: { allow_raw_access = null; max_age = null; }, -)' +)' "$output" } @test "asset configuration via .ic-assets.json5 - pretty printing when deploying" { @@ -1969,7 +1969,7 @@ WARNING: { ]' > src/e2e_project_frontend/assets/somedir/.ic-assets.json5 assert_command dfx deploy -v - assert_match '/somedir/upload-me.txt 1/1 \(8 bytes\) sha [0-9a-z]* \(with cache and 1 header\)' + assert_match '/somedir/upload-me.txt 1/1 \(8 bytes\) sha [0-9a-z]* \(with cache and 1 header\)' "$output" } @test "asset configuration via .ic-assets.json5 - respects weird characters" { @@ -2065,20 +2065,20 @@ EOF assert_command dfx canister call e2e_project_frontend configure '(record { max_batches= opt opt 1 })' EXTRA_BATCH=$(create_batch) assert_command_fail dfx deploy - assert_contains "batch limit exceeded" + assert_contains "batch limit exceeded" "$output" assert_command dfx canister call e2e_project_frontend delete_batch "(record { batch_id=$EXTRA_BATCH })" assert_command dfx canister call e2e_project_frontend configure '(record { max_batches= opt null })' assert_command dfx canister call e2e_project_frontend configure '(record { max_bytes= opt opt 5499 })' assert_command_fail dfx deploy - assert_contains "byte limit exceeded" + assert_contains "byte limit exceeded" "$output" assert_command dfx canister call e2e_project_frontend delete_batch "(record { batch_id=3 })" assert_command dfx canister call e2e_project_frontend configure '(record { max_bytes= opt null })' assert_command dfx canister call e2e_project_frontend configure '(record { max_chunks=opt opt 2 })' assert_command_fail dfx deploy - assert_contains "chunk limit exceeded" + assert_contains "chunk limit exceeded" "$output" assert_command dfx canister call e2e_project_frontend delete_batch "(record { batch_id=4 })" assert_command dfx canister call e2e_project_frontend configure '(record { max_chunks=opt opt 3; max_bytes = opt opt 5500 })' @@ -2172,7 +2172,7 @@ EOF # Request HTML file and verify ic_env cookie is set assert_command curl -v "http://$ID.localhost:$PORT/index.html" - assert_match "set-cookie: $IC_ENV_COOKIE_REGEX" + assert_match "set-cookie: $IC_ENV_COOKIE_REGEX" "$output" } @test "ic_env cookie contains PUBLIC_ environment variables" { @@ -2198,7 +2198,7 @@ EOF # Request HTML file and verify cookie contains PUBLIC_ variables assert_command curl -v "http://$ID.localhost:$PORT/index.html" - assert_match "set-cookie: $IC_ENV_COOKIE_REGEX" + assert_match "set-cookie: $IC_ENV_COOKIE_REGEX" "$output" } @test "ic_env cookie is not set for non-html files" { @@ -2246,7 +2246,7 @@ EOF IC_ENV_COOKIE_REGEX_1="ic_env=ic%5Froot%5Fkey%3D[0-9a-fA-F]+%26PUBLIC%5FTEST1%3Dvalue1; SameSite=Lax" assert_command curl -v "http://$ID.localhost:$PORT/app.html" - assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_1" + assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_1" "$output" # Redeploy with no PUBLIC_ prefixed (case sensitive!) environment variables set_canister_environment_variables "$ID" public_TEST1=value1 TEST2=value2 @@ -2255,7 +2255,7 @@ EOF IC_ENV_COOKIE_REGEX_2="ic_env=ic%5Froot%5Fkey%3D[0-9a-fA-F]+; SameSite=Lax" assert_command curl -v "http://$ID.localhost:$PORT/app.html" - assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_2" + assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_2" "$output" } @test "ic_env cookie updates on redeploy with new environment variables" { @@ -2280,7 +2280,7 @@ EOF IC_ENV_COOKIE_REGEX_1="ic_env=ic%5Froot%5Fkey%3D[0-9a-fA-F]+%26PUBLIC%5FTEST1%3Dvalue1; SameSite=Lax" assert_command curl -v "http://$ID.localhost:$PORT/app.html" - assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_1" + assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_1" "$output" # Redeploy with additional PUBLIC_ variable set_canister_environment_variables "$ID" PUBLIC_TEST1=value1 PUBLIC_TEST2=value2 @@ -2289,7 +2289,7 @@ EOF IC_ENV_COOKIE_REGEX_2="ic_env=ic%5Froot%5Fkey%3D[0-9a-fA-F]+%26PUBLIC%5FTEST1%3Dvalue1%26PUBLIC%5FTEST2%3Dvalue2; SameSite=Lax" assert_command curl -v "http://$ID.localhost:$PORT/app.html" - assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_2" + assert_match "set-cookie: $IC_ENV_COOKIE_REGEX_2" "$output" } @test "local state hash matches canister state hash" { diff --git a/e2e/tests-dfx/base.bash b/e2e/tests-dfx/base.bash index 5903d4244f..7483a26d61 100644 --- a/e2e/tests-dfx/base.bash +++ b/e2e/tests-dfx/base.bash @@ -36,5 +36,5 @@ teardown() { dfx_start dfx canister create --all assert_command_fail dfx build - assert_match 'import error \[M0010\], package "base" not defined' + assert_match 'import error \[M0010\], package "base" not defined' "$output" } diff --git a/e2e/tests-dfx/basic-project.bash b/e2e/tests-dfx/basic-project.bash index 1131673b79..9a1b5d5920 100644 --- a/e2e/tests-dfx/basic-project.bash +++ b/e2e/tests-dfx/basic-project.bash @@ -79,8 +79,8 @@ teardown() { assert_eq "4449444c00017d02" assert_command_fail dfx canister call --query hello_backend inc - assert_match "inc is an update method, not a query method." - assert_match "Run the command without '--query'." + assert_match "inc is an update method, not a query method." "$output" + assert_match "Run the command without '--query'." "$output" dfx canister call hello_backend inc @@ -151,7 +151,7 @@ teardown() { 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_contains "canister_inspect_message explicitly refused message" "$output" } @test "inspect message - rust" { @@ -165,5 +165,5 @@ teardown() { assert_command dfx canister call hello_backend always_accepted assert_command_fail dfx canister call hello_backend always_rejected - assert_contains "Canister rejected the message" + assert_contains "Canister rejected the message" "$output" } diff --git a/e2e/tests-dfx/bitcoin.bash b/e2e/tests-dfx/bitcoin.bash index 12011229f1..e27e037f42 100644 --- a/e2e/tests-dfx/bitcoin.bash +++ b/e2e/tests-dfx/bitcoin.bash @@ -92,7 +92,7 @@ set_local_network_bitcoin_enabled() { address = "bcrt1qu58aj62urda83c00eylc6w34yl2s6e5rkzqet7"; } )' - assert_contains "tip_height = 0 : nat32;" + assert_contains "tip_height = 0 : nat32;" "$output" # bitcoin_get_current_fee_percentiles assert_command dfx canister call --with-cycles 100000000 --wallet default aaaaa-aa --candid bitcoin.did bitcoin_get_current_fee_percentiles '(record { network = variant { regtest } })' @@ -101,5 +101,5 @@ set_local_network_bitcoin_enabled() { # It's hard to test this without a real transaction, but we can at least check that the call fails. # The error message indicates that the argument is in correct format, only the inner transaction is malformed. assert_command_fail dfx canister call --with-cycles 5020000000 --wallet default aaaaa-aa --candid bitcoin.did bitcoin_send_transaction '(record { transaction = vec {0:nat8}; network = variant { regtest } })' - assert_contains "send_transaction failed: MalformedTransaction" + assert_contains "send_transaction failed: MalformedTransaction" "$output" } diff --git a/e2e/tests-dfx/build.bash b/e2e/tests-dfx/build.bash index bf2bd499b0..8852a801ae 100644 --- a/e2e/tests-dfx/build.bash +++ b/e2e/tests-dfx/build.bash @@ -70,30 +70,30 @@ teardown() { 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_contains "Canister 'e2e_project' defines its wasm field as a URL, and has a build step." "$output" } @test "build uses default build args" { install_asset default_args assert_command_fail dfx build --check - assert_match "unknown option" - assert_match "compacting-gcX" + assert_match "unknown option" "$output" + assert_match "compacting-gcX" "$output" } @test "build uses canister build args" { install_asset canister_args assert_command_fail dfx build --check - assert_match "unknown option" - assert_match "compacting-gcY" - assert_not_match "compacting-gcX" + assert_match "unknown option" "$output" + assert_match "compacting-gcY" "$output" + assert_not_match "compacting-gcX" "$output" } @test "empty canister build args don't shadow default" { install_asset empty_canister_args assert_command_fail dfx build --check - assert_match '"--error-detail" "5"' - assert_match "unknown option" - assert_match "compacting-gcX" + assert_match '"--error-detail" "5"' "$output" + assert_match "unknown option" "$output" + assert_match "compacting-gcX" "$output" } @test "build fails on invalid motoko" { @@ -101,13 +101,13 @@ teardown() { dfx_start dfx canister create --all assert_command_fail dfx build - assert_match "syntax error" + assert_match "syntax error" "$output" } @test "build --check fails on build error when there are no canister ids" { install_asset invalid assert_command_fail dfx build --check - assert_match "syntax error" + assert_match "syntax error" "$output" } @test "build --check fails on build error when there are canister ids" { @@ -115,7 +115,7 @@ teardown() { dfx canister create --all install_asset invalid assert_command_fail dfx build --check - assert_match "syntax error" + assert_match "syntax error" "$output" } @test "build supports relative imports" { @@ -150,8 +150,8 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build - assert_contains "Building canister 'e2e_project_backend'" - assert_contains "Finished building canisters." + assert_contains "Building canister 'e2e_project_backend'" "$output" + assert_contains "Finished building canisters." "$output" } @test "build succeeds if enable optimize" { @@ -168,11 +168,11 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build custom -vvv - assert_not_match "Shrinking Wasm" + assert_not_match "Shrinking Wasm" "$output" jq '.canisters.custom.shrink=true' dfx.json | sponge dfx.json assert_command dfx build custom -vvv - assert_match "Shrinking Wasm" + assert_match "Shrinking Wasm" "$output" } @test "build custom canister default no optimize" { @@ -182,11 +182,11 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build custom -vvv - assert_not_match "Optimizing" + assert_not_match "Optimizing" "$output" jq '.canisters.custom.optimize="size"' dfx.json | sponge dfx.json assert_command dfx build custom -vvv - assert_match "Optimizing Wasm at level" + assert_match "Optimizing Wasm at level" "$output" } @test "build succeeds if enable gzip" { @@ -222,7 +222,7 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build - assert_match "warning \[M0145\], this pattern of type" + assert_match "warning \[M0145\], this pattern of type" "$output" } @test "build fails on unknown imports" { @@ -230,7 +230,7 @@ teardown() { dfx_start dfx canister create --all assert_command_fail dfx build - assert_match 'import error \[M0011\], canister alias "random" not defined' + assert_match 'import error \[M0011\], canister alias "random" not defined' "$output" } @test "build fails if canister type is not supported" { @@ -239,7 +239,7 @@ teardown() { jq '.canisters.e2e_project_backend.type="unknown_canister_type"' dfx.json | sponge dfx.json assert_command_fail dfx build # shellcheck disable=SC2016 - assert_match "canister 'e2e_project_backend' has unknown type 'unknown_canister_type' and there is no installed extension by that name which could define it" + assert_match "canister 'e2e_project_backend' has unknown type 'unknown_canister_type' and there is no installed extension by that name which could define it" "$output" # If canister type is invalid, `dfx stop` fails jq '.canisters.e2e_project_backend.type="motoko"' dfx.json | sponge dfx.json @@ -372,5 +372,5 @@ teardown() { assert_command dfx build --check # the module contains table64 which is not supported by ic_wasm::optimize # optimization failure doesn't fail the build, but a warning is issued - assert_contains "WARNING: Failed to optimize the Wasm module:" + assert_contains "WARNING: Failed to optimize the Wasm module:" "$output" } diff --git a/e2e/tests-dfx/build_granular.bash b/e2e/tests-dfx/build_granular.bash index 1b8d971250..74dba9fc49 100644 --- a/e2e/tests-dfx/build_granular.bash +++ b/e2e/tests-dfx/build_granular.bash @@ -47,7 +47,7 @@ teardown() { 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 "The canister must be built before install. Please run \`dfx build\`." + assert_match "The canister must be built before install. Please run \`dfx build\`." "$output" } @@ -61,18 +61,18 @@ teardown() { 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'." + assert_match "Cannot find canister id. Please issue 'dfx canister create e2e_project_frontend'." "$output" 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 # shellcheck disable=SC2154 - assert_eq '(blob "\b8\01\20\80\0a\77\31\32\20\00\78\79\0a\4b\4c\0b\0a\6a\6b")' "$stdout" + assert_eq '(blob "\b8\01\20\80\0a\77\31\32\20\00\78\79\0a\4b\4c\0b\0a\6a\6b")' assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl # shellcheck disable=SC2154 - assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' "$stdout" + assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' } @test "cyclic dependencies are detected" { @@ -80,7 +80,7 @@ teardown() { dfx_start dfx canister create --all assert_command_fail dfx build canister_e - assert_match "Circular canister dependencies: canister_e -> canister_d -> canister_e" + assert_match "Circular canister dependencies: canister_e -> canister_d -> canister_e" "$output" } @test "multiple non-cyclic dependency paths to the same canister are ok" { diff --git a/e2e/tests-dfx/build_rust.bash b/e2e/tests-dfx/build_rust.bash index 6df5a8cb18..1f55325061 100644 --- a/e2e/tests-dfx/build_rust.bash +++ b/e2e/tests-dfx/build_rust.bash @@ -21,7 +21,7 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build - assert_match "Cannot check for vulnerabilities in rust canisters because cargo-audit is not installed." + assert_match "Cannot check for vulnerabilities in rust canisters because cargo-audit is not installed." "$output" } @test "build with vulnerabilities in rust dependencies emits a warning" { @@ -33,8 +33,8 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build - assert_match "Audit found vulnerabilities" + assert_match "Audit found vulnerabilities" "$output" jq '.canisters.hello.skip_cargo_audit=true' dfx.json | sponge dfx.json assert_command dfx build - assert_not_match "Audit found vulnerabilities" + assert_not_match "Audit found vulnerabilities" "$output" } diff --git a/e2e/tests-dfx/call.bash b/e2e/tests-dfx/call.bash index 1b5ae42019..62c30210cf 100644 --- a/e2e/tests-dfx/call.bash +++ b/e2e/tests-dfx/call.bash @@ -102,7 +102,7 @@ teardown() { # if no candid method known, then no field names assert_command dfx canister call "$CANISTER_ID" make_struct2 '("A", "B")' # shellcheck disable=SC2154 - assert_eq '(record { 99 = "A"; 100 = "B" })' "$stdout" + assert_eq '(record { 99 = "A"; 100 = "B" })' # if passing the candid file, field names available assert_command dfx canister call --candid full.did "$CANISTER_ID" make_struct2 '("A", "B")' @@ -249,6 +249,7 @@ teardown() { assert_match '("Hello, you!")' } +# shellcheck disable=SC2030 @test "inter-canister calls" { dfx_new_rust inter install_asset inter @@ -299,6 +300,7 @@ teardown() { assert_match '(8 : nat)' } +# shellcheck disable=SC2031 function impersonate_sender() { IDENTITY_PRINCIPAL="${1}" @@ -311,57 +313,57 @@ function impersonate_sender() { # updating settings now fails because the default identity does not control the canister anymore assert_command_fail dfx canister update-settings hello_backend --freezing-threshold 0 --confirm-very-short-freezing-threshold - assert_contains "The principal you are using to call a management function is not part of the controllers." + assert_contains "The principal you are using to call a management function is not part of the controllers." "$output" # updating settings succeeds when impersonating the management canister as the sender assert_command dfx canister update-settings hello_backend --freezing-threshold 0 --confirm-very-short-freezing-threshold --impersonate "${IDENTITY_PRINCIPAL}" # canister status fails because the default identity does not control the canister anymore assert_command_fail dfx canister status hello_backend - assert_contains "The principal you are using to call a management function is not part of the controllers." + assert_contains "The principal you are using to call a management function is not part of the controllers." "$output" # canister status succeeds when impersonating the management canister as the sender assert_command dfx canister status hello_backend --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "Controllers: ${IDENTITY_PRINCIPAL}" - assert_contains "Freezing threshold: 0" + assert_contains "Controllers: ${IDENTITY_PRINCIPAL}" "$output" + assert_contains "Freezing threshold: 0" "$output" # freeze the canister assert_command dfx canister update-settings hello_backend --freezing-threshold 9223372036854775808 --confirm-very-long-freezing-threshold --impersonate "${IDENTITY_PRINCIPAL}" # test management canister call submission failure assert_command_fail dfx canister status hello_backend --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "Failed to submit management canister call: Canister $CANISTER_ID is out of cycles" + assert_contains "Failed to submit management canister call: Canister $CANISTER_ID is out of cycles" "$output" # test update call submission failure assert_command_fail dfx canister call aaaaa-aa canister_status "(record { canister_id=principal\"$CANISTER_ID\" })" --update --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "Failed to submit canister call: Canister $CANISTER_ID is out of cycles" + assert_contains "Failed to submit canister call: Canister $CANISTER_ID is out of cycles" "$output" # test async call submission failure assert_command_fail dfx canister call aaaaa-aa canister_status "(record { canister_id=principal\"$CANISTER_ID\" })" --async --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "Failed to submit canister call: Canister $CANISTER_ID is out of cycles" + assert_contains "Failed to submit canister call: Canister $CANISTER_ID is out of cycles" "$output" # unfreeze the canister assert_command dfx canister update-settings hello_backend --freezing-threshold 0 --confirm-very-short-freezing-threshold --impersonate "${IDENTITY_PRINCIPAL}" # test update call failure assert_command_fail dfx canister call aaaaa-aa delete_canister "(record { canister_id=principal\"$CANISTER_ID\" })" --update --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "Canister call failed: Canister $CANISTER_ID must be stopped before it is deleted." + assert_contains "Canister call failed: Canister $CANISTER_ID must be stopped before it is deleted." "$output" # test update call assert_command dfx canister call aaaaa-aa start_canister "(record { canister_id=principal\"$CANISTER_ID\" })" --update --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "()" + assert_contains "()" "$output" # test async call assert_command dfx canister call aaaaa-aa canister_status "(record { canister_id=principal\"$CANISTER_ID\" })" --async --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "Request ID:" + assert_contains "Request ID:" "$output" # test query call failure assert_command_fail dfx canister call aaaaa-aa fetch_canister_logs "(record { canister_id=principal\"$CANISTER_ID\" })" --query --impersonate "$CANISTER_ID" - assert_contains "Failed to perform query call: Caller $CANISTER_ID is not allowed to access canister logs (IC0406)" + assert_contains "Failed to perform query call: Caller $CANISTER_ID is not allowed to access canister logs (IC0406)" "$output" # test query call assert_command dfx canister call aaaaa-aa fetch_canister_logs "(record { canister_id=principal\"$CANISTER_ID\" })" --query --impersonate "${IDENTITY_PRINCIPAL}" - assert_contains "(record { 1_754_302_831 = vec {} })" + assert_contains "(record { 1_754_302_831 = vec {} })" "$output" } @test "impersonate management canister as sender" { diff --git a/e2e/tests-dfx/canister_extra.bash b/e2e/tests-dfx/canister_extra.bash index 0d596d4d4b..65a1eddf89 100755 --- a/e2e/tests-dfx/canister_extra.bash +++ b/e2e/tests-dfx/canister_extra.bash @@ -21,31 +21,31 @@ teardown() { dfx deploy assert_command dfx canister call hello_backend inc_read - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" dfx canister stop hello_backend assert_command dfx canister snapshot create hello_backend - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot=${BASH_REMATCH[1]} dfx canister start hello_backend assert_command dfx canister call hello_backend inc_read - assert_contains '(2 : nat)' + assert_contains '(2 : nat)' "$output" dfx canister stop hello_backend assert_command dfx canister snapshot load hello_backend "$snapshot" dfx canister start hello_backend assert_command dfx canister call hello_backend read - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" assert_command dfx canister snapshot list hello_backend assert_match "^${snapshot}:" assert_command dfx canister snapshot delete hello_backend "$snapshot" assert_command dfx canister snapshot list hello_backend - assert_contains 'No snapshots found in canister hello_backend' + assert_contains 'No snapshots found in canister hello_backend' "$output" assert_command_fail dfx canister snapshot create hello_backend - assert_contains 'Canister hello_backend is running and snapshots should not be taken of running canisters' + assert_contains 'Canister hello_backend is running and snapshots should not be taken of running canisters' "$output" } @test "canister snapshots download and upload" { @@ -54,34 +54,34 @@ teardown() { dfx deploy assert_command dfx canister call hello_backend inc_read - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" # Create the first snapshot. dfx canister stop hello_backend assert_command dfx canister snapshot create hello_backend - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot=${BASH_REMATCH[1]} dfx canister start hello_backend assert_command dfx canister call hello_backend inc_read - assert_contains '(2 : nat)' + assert_contains '(2 : nat)' "$output" # Download the first snapshot. OUTPUT_DIR="output" mkdir -p "$OUTPUT_DIR" assert_command dfx canister snapshot download hello_backend "$snapshot" --dir "$OUTPUT_DIR" - assert_contains "saved to '$OUTPUT_DIR'" + assert_contains "saved to '$OUTPUT_DIR'" "$output" # Replace the first snapshot. dfx canister stop hello_backend assert_command dfx canister snapshot create hello_backend --replace "$snapshot" - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot=${BASH_REMATCH[1]} dfx canister start hello_backend assert_command dfx canister call hello_backend inc_read - assert_contains '(3 : nat)' + assert_contains '(3 : nat)' "$output" # Load and verify the replaced snapshot. dfx canister stop hello_backend @@ -89,15 +89,15 @@ teardown() { dfx canister start hello_backend assert_command dfx canister call hello_backend read - assert_contains '(2 : nat)' + assert_contains '(2 : nat)' "$output" # Upload to create a new snapshot. assert_command dfx canister snapshot upload hello_backend --dir "$OUTPUT_DIR" - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot_1=${BASH_REMATCH[1]} assert_command dfx canister snapshot list hello_backend - assert_contains "${snapshot_1}" + assert_contains "${snapshot_1}" "$output" # Load and verify the uploaded snapshot. dfx canister stop hello_backend @@ -105,7 +105,7 @@ teardown() { dfx canister start hello_backend assert_command dfx canister call hello_backend read - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" } @test "canister snapshots download and upload via toxiproxy with high latency" { @@ -121,12 +121,12 @@ teardown() { dfx deploy --no-wallet --network "http://127.0.0.1:$proxy_port" assert_command dfx canister call hello_backend inc_read --network "http://127.0.0.1:$proxy_port" - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" # Create a snapshot to download. dfx canister stop hello_backend --network "http://127.0.0.1:$proxy_port" assert_command dfx canister snapshot create hello_backend --network "http://127.0.0.1:$proxy_port" - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot=${BASH_REMATCH[1]} # Add latency to the proxy. @@ -136,16 +136,16 @@ teardown() { OUTPUT_DIR="output" mkdir -p "$OUTPUT_DIR" assert_command dfx canister snapshot download hello_backend "$snapshot" --dir "$OUTPUT_DIR" --network "http://127.0.0.1:$proxy_port" - assert_contains "saved to '$OUTPUT_DIR'" + assert_contains "saved to '$OUTPUT_DIR'" "$output" # Start the canister again. dfx canister start hello_backend --network "http://127.0.0.1:$proxy_port" assert_command dfx canister call hello_backend inc_read --network "http://127.0.0.1:$proxy_port" - assert_contains '(2 : nat)' + assert_contains '(2 : nat)' "$output" # Upload the snapshot to create a new snapshot. assert_command dfx canister snapshot upload hello_backend --dir "$OUTPUT_DIR" --network "http://127.0.0.1:$proxy_port" - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot_1=${BASH_REMATCH[1]} # Stop the canister and load the new snapshot. @@ -155,7 +155,7 @@ teardown() { # Start the canister again and verify the loaded snapshot. dfx canister start hello_backend --network "http://127.0.0.1:$proxy_port" assert_command dfx canister call hello_backend read --network "http://127.0.0.1:$proxy_port" - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" toxiproxy_delete_proxy proxy_high_latency } @@ -173,12 +173,12 @@ teardown() { dfx deploy --no-wallet --network "http://127.0.0.1:$proxy_port" assert_command dfx canister call hello_backend inc_read --network "http://127.0.0.1:$proxy_port" - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" # Create a snapshot to download. dfx canister stop hello_backend --network "http://127.0.0.1:$proxy_port" assert_command dfx canister snapshot create hello_backend --network "http://127.0.0.1:$proxy_port" - assert_match 'Snapshot ID: ([0-9a-f]+)' + assert_match 'Snapshot ID: ([0-9a-f]+)' "$output" snapshot=${BASH_REMATCH[1]} # Add a 1MB limit_data toxic to force the snapshot download to fail. @@ -198,12 +198,12 @@ teardown() { # Resume the download through the proxy. assert_command dfx -v canister snapshot download hello_backend "$snapshot" --dir "$OUTPUT_DIR" -r --network "http://127.0.0.1:$proxy_port" - assert_contains "saved to '$OUTPUT_DIR'" + assert_contains "saved to '$OUTPUT_DIR'" "$output" # Start the canister again. dfx canister start hello_backend --network "http://127.0.0.1:$proxy_port" assert_command dfx canister call hello_backend inc_read --network "http://127.0.0.1:$proxy_port" - assert_contains '(2 : nat)' + assert_contains '(2 : nat)' "$output" # Add a 1MB limit_data toxic to force the snapshot upload to fail. toxiproxy_add_limit_data limit_upload 1000000 proxy_network_drop -u @@ -230,7 +230,7 @@ teardown() { # Resume the upload through the proxy. assert_command dfx canister snapshot upload hello_backend --dir "$OUTPUT_DIR" -r "$snapshot_1" --network "http://127.0.0.1:$proxy_port" - assert_contains "$snapshot_1" + assert_contains "$snapshot_1" "$output" # Stop the canister and load the new snapshot. dfx canister stop hello_backend --network "http://127.0.0.1:$proxy_port" @@ -239,7 +239,7 @@ teardown() { # Start the canister again and verify the loaded snapshot. dfx canister start hello_backend --network "http://127.0.0.1:$proxy_port" assert_command dfx canister call hello_backend read --network "http://127.0.0.1:$proxy_port" - assert_contains '(1 : nat)' + assert_contains '(1 : nat)' "$output" toxiproxy_delete_proxy proxy_network_drop } diff --git a/e2e/tests-dfx/canister_migration.bash b/e2e/tests-dfx/canister_migration.bash index 080d694595..063e41e9e5 100755 --- a/e2e/tests-dfx/canister_migration.bash +++ b/e2e/tests-dfx/canister_migration.bash @@ -34,7 +34,7 @@ teardown() { # The migration will take a few minutes to complete. assert_command dfx canister migrate-id migrated --replace replaced --yes - assert_contains "Migration succeeded" + assert_contains "Migration succeeded" "$output" assert_command dfx canister status migrated assert_command_fail dfx canister status replaced diff --git a/e2e/tests-dfx/certificate.bash b/e2e/tests-dfx/certificate.bash index 949cf41026..ed6e817135 100644 --- a/e2e/tests-dfx/certificate.bash +++ b/e2e/tests-dfx/certificate.bash @@ -66,7 +66,7 @@ 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_match 'Certificate verification failed.' "$output" } @test "mitm attack - query: attack succeeds because there is no certificate to verify" { diff --git a/e2e/tests-dfx/core.bash b/e2e/tests-dfx/core.bash index 114e47bdfb..f6130a7973 100644 --- a/e2e/tests-dfx/core.bash +++ b/e2e/tests-dfx/core.bash @@ -33,5 +33,5 @@ teardown() { dfx_start dfx canister create --all assert_command_fail dfx build - assert_match 'import error \[M0010\], package "core" not defined' + assert_match 'import error \[M0010\], package "core" not defined' "$output" } diff --git a/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index 1b5b70e1d1..fc5c590faf 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -19,15 +19,15 @@ teardown() { dfx_start assert_command_fail dfx canister create e2e_project_backend --reserved-cycles-limit 470000 - assert_contains "Cannot create a canister using a wallet if the reserved_cycles_limit is set. Please create with --no-wallet or use dfx canister update-settings instead." + assert_contains "Cannot create a canister using a wallet if the reserved_cycles_limit is set. Please create with --no-wallet or use dfx canister update-settings instead." "$output" assert_command dfx canister create e2e_project_frontend --no-wallet assert_command dfx canister status e2e_project_frontend - assert_contains "Reserved cycles limit: 5_000_000_000_000 Cycles" + assert_contains "Reserved cycles limit: 5_000_000_000_000 Cycles" "$output" assert_command dfx canister create e2e_project_backend --reserved-cycles-limit 470000 --no-wallet assert_command dfx canister status e2e_project_backend - assert_contains "Reserved cycles limit: 470_000 Cycles" + assert_contains "Reserved cycles limit: 470_000 Cycles" "$output" } @test "create succeeds on default project" { @@ -46,13 +46,13 @@ teardown() { 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 "The specified canister ID nojwb-ieaaa-aaaaa-aaaaa-cai is out of range. Hint: A mainnet canister ID is normally valid here." + assert_match "The specified canister ID nojwb-ieaaa-aaaaa-aaaaa-cai is out of range. Hint: A mainnet canister ID is normally valid here." "$output" } @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 '" + assert_match "error: the argument '--all' cannot be used with '--specified-id '" "$output" } @test "create succeeds when specify canister ID in dfx.json" { @@ -67,12 +67,12 @@ teardown() { dfx_start jq '.canisters.e2e_project_backend.specified_id="n5n4y-3aaaa-aaaaa-p777q-cai"' dfx.json | sponge dfx.json assert_command dfx canister create e2e_project_backend --specified-id n2m2m-wyaaa-aaaaa-p777a-cai - assert_contains "WARNING: Canister 'e2e_project_backend' has a specified ID in dfx.json: n5n4y-3aaaa-aaaaa-p777q-cai," - assert_contains "which is different from the one specified in the command line: n2m2m-wyaaa-aaaaa-p777a-cai." - assert_contains "The command line value will be used." + assert_contains "WARNING: Canister 'e2e_project_backend' has a specified ID in dfx.json: n5n4y-3aaaa-aaaaa-p777q-cai," "$output" + assert_contains "which is different from the one specified in the command line: n2m2m-wyaaa-aaaaa-p777a-cai." "$output" + assert_contains "The command line value will be used." "$output" assert_command dfx canister id e2e_project_backend - assert_match n2m2m-wyaaa-aaaaa-p777a-cai + assert_match n2m2m-wyaaa-aaaaa-p777a-cai "$output" } @test "create generates the canister_ids.json" { @@ -103,14 +103,14 @@ teardown() { @test "build fails without create" { dfx_start assert_command_fail dfx build - assert_match "Cannot find canister id." + assert_match "Cannot find canister id." "$output" } @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'" + assert_match "Cannot find canister id. Please issue 'dfx canister create e2e_project_frontend'" "$output" } @test "create succeeds with network parameter" { @@ -121,7 +121,7 @@ teardown() { @test "create fails with incorrect network" { dfx_start assert_command_fail dfx canister create --all --network nosuch - assert_match "Network not found" + assert_match "Network not found" "$output" } @test "create succeeds when requested network is configured" { @@ -144,14 +144,14 @@ teardown() { 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'" + assert_match "Did not find any providers for network 'actuallylocal'" "$output" } @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_contains "error sending request for url (http://not-real.nowhere.test./api/v2/status)" + assert_contains "error sending request for url (http://not-real.nowhere.test./api/v2/status)" "$output" } @test "create accepts --controller named parameter, with controller by identity name" { @@ -274,8 +274,8 @@ teardown() { 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_match "The wallet canister must be upgraded: The installed wallet does not support multiple controllers." "$output" + assert_match "To upgrade, run dfx wallet upgrade" "$output" use_wallet_wasm 0.8.2 assert_command dfx wallet upgrade --identity alice diff --git a/e2e/tests-dfx/cycles-ledger.bash b/e2e/tests-dfx/cycles-ledger.bash index b6c356d2a2..71ebd6b8b5 100644 --- a/e2e/tests-dfx/cycles-ledger.bash +++ b/e2e/tests-dfx/cycles-ledger.bash @@ -25,7 +25,7 @@ current_time_nanoseconds() { dfx_start assert_command_fail dfx cycles balance - assert_contains "Cycles ledger with canister ID 'um5iw-rqaaa-aaaaq-qaaba-cai' is not installed." + assert_contains "Cycles ledger with canister ID 'um5iw-rqaaa-aaaaq-qaaba-cai' is not installed." "$output" } @test "convert icp to cycles & balance" { @@ -37,7 +37,7 @@ current_time_nanoseconds() { # Test failed to convert ICP to cycles without enough ICP. assert_command_fail dfx cycles convert --amount 12.5 --identity alice - assert_contains "Insufficient ICP balance to finish the transfer transaction." + assert_contains "Insufficient ICP balance to finish the transfer transaction." "$output" assert_command dfx --identity anonymous ledger transfer --memo 1234 --amount 100 "$(dfx ledger account-id --of-principal "$ALICE")" assert_command dfx --identity anonymous ledger transfer --memo 1234 --amount 100 "$(dfx ledger account-id --of-principal "$ALICE" --subaccount "$ALICE_SUBACCT1")" @@ -52,7 +52,7 @@ current_time_nanoseconds() { # base case assert_command dfx cycles convert --amount 12.5 - assert_contains "Account was topped up with 44_000_000_000_000 cycles!" + assert_contains "Account was topped up with 44_000_000_000_000 cycles!" "$output" assert_command dfx ledger balance assert_eq "87.49990000 ICP" assert_command dfx cycles balance --precise @@ -60,7 +60,7 @@ current_time_nanoseconds() { # to-subaccount and from-subaccount assert_command dfx cycles convert --amount 10 --from-subaccount "$ALICE_SUBACCT1" --to-subaccount "$ALICE_SUBACCT2" - assert_contains "Account was topped up with 35_200_000_000_000 cycles!" + assert_contains "Account was topped up with 35_200_000_000_000 cycles!" "$output" assert_command dfx ledger balance --subaccount "$ALICE_SUBACCT1" assert_eq "89.99990000 ICP" assert_command dfx cycles balance --precise --subaccount "$ALICE_SUBACCT2" @@ -69,7 +69,7 @@ current_time_nanoseconds() { # deduplication t=$(current_time_nanoseconds) assert_command dfx cycles convert --amount 10 --created-at-time "$t" - assert_contains "Transfer sent at block height" + assert_contains "Transfer sent at block height" "$output" assert_command dfx cycles balance --precise assert_eq "79199800000000 cycles." # same created-at-time: dupe @@ -77,7 +77,7 @@ current_time_nanoseconds() { # shellcheck disable=SC2154 assert_contains "transaction is a duplicate of another transaction in block" "$stderr" # shellcheck disable=SC2154 - assert_contains "Transfer sent at block height" + assert_contains "Transfer sent at block height" "$output" # Check balances @@ -283,11 +283,11 @@ current_time_nanoseconds() { t=$(current_time_nanoseconds) assert_command dfx cycles approve "$BOB" 2000000000 --created-at-time "$t" --memo 123 --identity alice - assert_contains "Approval sent at block index" + assert_contains "Approval sent at block index" "$output" assert_command dfx cycles approve "$BOB" 2000000000 --created-at-time "$t" --memo 123 --identity alice - assert_contains "Approval is a duplicate of block" + assert_contains "Approval is a duplicate of block" "$output" assert_command dfx cycles transfer "$BOB" 100000 --from "$ALICE" --identity bob - assert_contains "Transfer sent at block index" + assert_contains "Transfer sent at block index" "$output" assert_command dfx cycles balance --precise --identity alice assert_eq "35199699900000 cycles." @@ -303,9 +303,9 @@ current_time_nanoseconds() { t=$(current_time_nanoseconds) assert_command dfx cycles transfer "$BOB" 100000 --from "$ALICE" --to-subaccount "$BOB_SUBACCT1" --created-at-time "$t" --identity bob - assert_contains "Transfer sent at block index" + assert_contains "Transfer sent at block index" "$output" assert_command dfx cycles transfer "$BOB" 100000 --from "$ALICE" --to-subaccount "$BOB_SUBACCT1" --created-at-time "$t" --identity bob - assert_contains "Transfer is a duplicate of block index" + assert_contains "Transfer is a duplicate of block index" "$output" assert_command dfx cycles balance --precise --identity alice assert_eq "35199599800000 cycles." @@ -320,9 +320,9 @@ current_time_nanoseconds() { assert_eq "100000 cycles." assert_command dfx cycles approve "$BOB" 200000000000 --from-subaccount "$ALICE_SUBACCT1" --identity alice - assert_contains "Approval sent at block index" + assert_contains "Approval sent at block index" "$output" assert_command dfx cycles transfer "$BOB" 700000 --from "$ALICE" --from-subaccount "$ALICE_SUBACCT1" --identity bob - assert_contains "Transfer sent at block index" + assert_contains "Transfer sent at block index" "$output" assert_command dfx cycles balance --precise --identity alice --subaccount "$ALICE_SUBACCT1" assert_eq "35199699300000 cycles." @@ -334,9 +334,9 @@ current_time_nanoseconds() { assert_eq "35199900000000 cycles." assert_command dfx cycles approve "$BOB" 200000000000 --spender-subaccount "$BOB_SUBACCT1" --from-subaccount "$ALICE_SUBACCT2" --identity alice - assert_contains "Approval sent at block index" + assert_contains "Approval sent at block index" "$output" assert_command dfx cycles transfer "$BOB" 300000 --from "$ALICE" --from-subaccount "$ALICE_SUBACCT2" --spender-subaccount "$BOB_SUBACCT1" --identity bob - assert_contains "Transfer sent at block index" + assert_contains "Transfer sent at block index" "$output" assert_command dfx cycles balance --precise --identity alice --subaccount "$ALICE_SUBACCT2" assert_eq "35199699700000 cycles." @@ -350,7 +350,7 @@ current_time_nanoseconds() { BOB=$(dfx identity get-principal --identity bob) assert_command_fail dfx cycles top-up "$BOB" 600000 --identity alice - assert_contains "Invalid receiver: $BOB. Make sure the receiver is a canister." + assert_contains "Invalid receiver: $BOB. Make sure the receiver is a canister." "$output" } @test "top-up and deposit-cycles" { @@ -383,81 +383,81 @@ current_time_nanoseconds() { assert_command dfx cycles balance --precise --identity bob assert_eq "35199900000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 2_999" # 2_999x10^9 + assert_contains "Balance: 2_999" "$output" # 2_999x10^9 assert_command dfx cycles top-up e2e_project_backend 1000000000 --identity bob assert_command dfx cycles balance --precise --identity bob assert_eq "35198800000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_000" # 3_000x10^9 + assert_contains "Balance: 3_000" "$output" # 3_000x10^9 assert_command dfx canister deposit-cycles 1000000000 e2e_project_backend --identity bob assert_command dfx cycles balance --precise --identity bob assert_eq "35197700000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_001" # 3_001x10^9 + assert_contains "Balance: 3_001" "$output" # 3_001x10^9 # subaccount to canister assert_command dfx cycles balance --precise --identity bob --subaccount "$BOB_SUBACCT1" assert_eq "35199900000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_001" # 3_001x10^9 + assert_contains "Balance: 3_001" "$output" # 3_001x10^9 assert_command dfx cycles top-up e2e_project_backend 1000000000 --identity bob --from-subaccount "$BOB_SUBACCT1" assert_command dfx cycles balance --precise --identity bob --subaccount "$BOB_SUBACCT1" assert_eq "35198800000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_002" # 3_002x10^9 + assert_contains "Balance: 3_002" "$output" # 3_002x10^9 assert_command dfx canister deposit-cycles 1000000000 e2e_project_backend --identity bob --from-subaccount "$BOB_SUBACCT1" assert_command dfx cycles balance --precise --identity bob --subaccount "$BOB_SUBACCT1" assert_eq "35197700000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_003" # 3_003x10^9 + assert_contains "Balance: 3_003" "$output" # 3_003x10^9 # subaccount to canister - by canister id assert_command dfx cycles balance --precise --identity bob --subaccount "$BOB_SUBACCT2" assert_eq "35199900000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_003" # 3_003x10^9 + assert_contains "Balance: 3_003" "$output" # 3_003x10^9 assert_command dfx cycles top-up "$(dfx canister id e2e_project_backend)" 1000000000 --identity bob --from-subaccount "$BOB_SUBACCT2" assert_command dfx cycles balance --precise --identity bob --subaccount "$BOB_SUBACCT2" assert_eq "35198800000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_004" # 3_004x10^9 + assert_contains "Balance: 3_004" "$output" # 3_004x10^9 assert_command dfx canister deposit-cycles 1000000000 "$(dfx canister id e2e_project_backend)" --identity bob --from-subaccount "$BOB_SUBACCT2" assert_command dfx cycles balance --precise --identity bob --subaccount "$BOB_SUBACCT2" assert_eq "35197700000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_005" # 3_005x10^9 + assert_contains "Balance: 3_005" "$output" # 3_005x10^9 # deduplication t=$(current_time_nanoseconds) assert_command dfx cycles balance --precise --identity bob assert_eq "35197700000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_005" # 3_005x10^9 + assert_contains "Balance: 3_005" "$output" # 3_005x10^9 assert_command dfx canister deposit-cycles 1000000000 e2e_project_backend --identity bob --created-at-time "$t" assert_command dfx cycles balance --precise --identity bob assert_eq "35196600000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_006" # 3_006x10^9 + assert_contains "Balance: 3_006" "$output" # 3_006x10^9 assert_command dfx canister deposit-cycles 1000000000 e2e_project_backend --identity bob --created-at-time "$t" assert_command dfx cycles balance --precise --identity bob assert_eq "35196600000000 cycles." assert_command dfx canister status e2e_project_backend - assert_contains "Balance: 3_006" # 3_006x10^9 + assert_contains "Balance: 3_006" "$output" # 3_006x10^9 # deposit-cycles --all skips remote canisters jq '.canisters.remote.remote.id.local="rdmx6-jaaaa-aaaaa-aaadq-cai"' dfx.json | sponge dfx.json assert_command dfx canister deposit-cycles 1000000000 --all --identity bob - assert_contains "Skipping canister 'remote' because it is remote for network 'local'" - assert_contains "Depositing 1000000000 cycles onto e2e_project_backend" - assert_not_contains "Depositing 1000000000 cycles onto remote" + assert_contains "Skipping canister 'remote' because it is remote for network 'local'" "$output" + assert_contains "Depositing 1000000000 cycles onto e2e_project_backend" "$output" + assert_not_contains "Depositing 1000000000 cycles onto remote" "$output" } @test "top-up deduplication" { @@ -523,7 +523,7 @@ current_time_nanoseconds() { dfx_new canister_creation_failed assert_command_fail dfx canister create canister_creation_failed_backend --with-cycles 1T --identity alice - assert_contains "Insufficient cycles balance to create the canister." + assert_contains "Insufficient cycles balance to create the canister." "$output" # shellcheck disable=SC2103 cd .. @@ -550,7 +550,7 @@ current_time_nanoseconds() { rm .dfx/local/canister_ids.json assert_command dfx canister create e2e_project_backend --with-cycles 1T --created-at-time "$t" assert_command dfx canister id e2e_project_backend - assert_contains "$E2E_PROJECT_BACKEND_CANISTER_ID" + assert_contains "$E2E_PROJECT_BACKEND_CANISTER_ID" "$output" assert_command dfx cycles balance --precise assert_eq "34199800000000 cycles." dfx canister stop e2e_project_backend @@ -560,7 +560,7 @@ current_time_nanoseconds() { assert_command dfx canister id e2e_project_backend assert_command dfx cycles balance --subaccount "$ALICE_SUBACCT1" --precise assert_eq "34199800000000 cycles." - + # reset deployment status rm -r .dfx @@ -576,12 +576,12 @@ current_time_nanoseconds() { rm .dfx/local/canister_ids.json assert_command dfx deploy e2e_project_backend --with-cycles 2T --created-at-time "$t" -vv assert_command dfx canister id e2e_project_backend - assert_contains "$E2E_PROJECT_BACKEND_CANISTER_ID" + assert_contains "$E2E_PROJECT_BACKEND_CANISTER_ID" "$output" assert_command dfx cycles balance --precise assert_eq "32199700000000 cycles." dfx canister stop e2e_project_backend dfx canister delete e2e_project_backend --no-withdrawal - + assert_command dfx deploy e2e_project_backend --with-cycles 2T --from-subaccount "$ALICE_SUBACCT1" assert_command dfx canister id e2e_project_backend assert_command dfx cycles balance --subaccount "$ALICE_SUBACCT1" --precise @@ -610,7 +610,7 @@ current_time_nanoseconds() { # delete by name assert_command dfx canister stop --all assert_command dfx canister delete e2e_project_backend - assert_contains "Successfully withdrew" + assert_contains "Successfully withdrew" "$output" # delete by id assert_command dfx canister create --all @@ -618,7 +618,7 @@ current_time_nanoseconds() { rm .dfx/local/canister_ids.json assert_command dfx canister stop "${CANISTER_ID}" assert_command dfx canister delete "${CANISTER_ID}" - assert_contains "Successfully withdrew" + assert_contains "Successfully withdrew" "$output" } @test "redeem-faucet-coupon redeems into the cycles ledger" { @@ -639,15 +639,15 @@ current_time_nanoseconds() { assert_eq "0.000 TC (trillion cycles)." assert_command dfx cycles redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'valid-coupon' - assert_match "Redeemed coupon 'valid-coupon'" + assert_match "Redeemed coupon 'valid-coupon'" "$output" assert_command dfx cycles redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'another-valid-coupon' - assert_match "Redeemed coupon 'another-valid-coupon'" + assert_match "Redeemed coupon 'another-valid-coupon'" "$output" assert_command dfx cycles balance assert_eq "20.000 TC (trillion cycles)." # with subaccount assert_command dfx cycles redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'another-valid-coupon' --to-subaccount "$SUBACCOUNT" - assert_match "Redeemed coupon 'another-valid-coupon'" + assert_match "Redeemed coupon 'another-valid-coupon'" "$output" assert_command dfx cycles balance --subaccount "$SUBACCOUNT" assert_eq "10.000 TC (trillion cycles)." } @@ -671,11 +671,11 @@ current_time_nanoseconds() { # use --subnet SUBNET_ID="5kdm2-62fc6-fwnja-hutkz-ycsnm-4z33i-woh43-4cenu-ev7mi-gii6t-4ae" # a random, valid principal assert_command_fail dfx canister create e2e_project_backend --subnet "$SUBNET_ID" - assert_contains "Subnet $SUBNET_ID does not exist" - + assert_contains "Subnet $SUBNET_ID does not exist" "$output" + # use --subnet-type assert_command_fail dfx canister create e2e_project_backend --subnet-type custom_subnet_type - assert_contains "Provided subnet type custom_subnet_type does not exist" + assert_contains "Provided subnet type custom_subnet_type does not exist" "$output" } @test "automatically choose subnet" { @@ -726,13 +726,13 @@ current_time_nanoseconds() { assert_command dfx canister create e2e_project_backend ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET1" + assert_contains "$SUBNET1" "$output" stop_and_delete e2e_project_backend assert_command dfx deploy e2e_project_backend ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET1" + assert_contains "$SUBNET1" "$output" stop_and_delete e2e_project_backend # multiple other canisters already exist - all on same subnet @@ -743,13 +743,13 @@ current_time_nanoseconds() { assert_command dfx canister create e2e_project_backend ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET1" + assert_contains "$SUBNET1" "$output" stop_and_delete e2e_project_backend assert_command dfx deploy e2e_project_backend ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET1" + assert_contains "$SUBNET1" "$output" stop_and_delete e2e_project_backend # multiple other canisters already exist - not all on same subnet @@ -757,22 +757,22 @@ current_time_nanoseconds() { assert_command dfx canister create two --subnet "$SUBNET2" assert_command_fail dfx canister create e2e_project_backend - assert_contains "Cannot automatically decide which subnet to target." + assert_contains "Cannot automatically decide which subnet to target." "$output" assert_command_fail dfx deploy e2e_project_backend - assert_contains "Cannot automatically decide which subnet to target." - + assert_contains "Cannot automatically decide which subnet to target." "$output" + # still can create if a subnet is specified assert_command dfx canister create e2e_project_backend --subnet "$SUBNET2" ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET2" + assert_contains "$SUBNET2" "$output" stop_and_delete e2e_project_backend assert_command dfx deploy e2e_project_backend --subnet "$SUBNET2" ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET2" + assert_contains "$SUBNET2" "$output" stop_and_delete e2e_project_backend # remote canister exists on different subnet @@ -783,12 +783,12 @@ current_time_nanoseconds() { assert_command dfx canister create e2e_project_backend ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET1" + assert_contains "$SUBNET1" "$output" stop_and_delete e2e_project_backend assert_command dfx deploy e2e_project_backend ID="$(dfx canister id e2e_project_backend)" assert_command dfx canister call "$REGISTRY" get_subnet_for_canister --query "(record { \"principal\" = opt principal \"$ID\" })" - assert_contains "$SUBNET1" + assert_contains "$SUBNET1" "$output" stop_and_delete e2e_project_backend } diff --git a/e2e/tests-dfx/delete.bash b/e2e/tests-dfx/delete.bash index 5aa7b3e610..5115f6c0fd 100755 --- a/e2e/tests-dfx/delete.bash +++ b/e2e/tests-dfx/delete.bash @@ -21,9 +21,9 @@ teardown() { dfx canister stop e2e_project_backend assert_command dfx canister delete "$id" assert_command_fail dfx canister info e2e_project_backend - assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." + assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." "$output" assert_command_fail dfx canister status "$id" - assert_contains "Canister $id not found" + assert_contains "Canister $id not found" "$output" assert_command dfx deploy } @@ -34,9 +34,9 @@ teardown() { 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_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." "$output" assert_command_fail dfx canister status "$id" - assert_contains "Canister $id not found" + assert_contains "Canister $id not found" "$output" } @test "delete requires confirmation if the canister is not stopped" { @@ -47,7 +47,7 @@ teardown() { 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_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." "$output" assert_command_fail dfx canister status "$id" - assert_contains "Canister $id not found" + assert_contains "Canister $id not found" "$output" } diff --git a/e2e/tests-dfx/deploy.bash b/e2e/tests-dfx/deploy.bash index 50cedd6e71..cd140a5cd5 100644 --- a/e2e/tests-dfx/deploy.bash +++ b/e2e/tests-dfx/deploy.bash @@ -20,12 +20,12 @@ teardown() { cat dfx.json jq '.canisters.hello_backend.initialization_values.reserved_cycles_limit=860000' dfx.json | sponge dfx.json assert_command_fail dfx deploy - assert_contains "Cannot create a canister using a wallet if the reserved_cycles_limit is set. Please create with --no-wallet or use dfx canister update-settings instead." + assert_contains "Cannot create a canister using a wallet if the reserved_cycles_limit is set. Please create with --no-wallet or use dfx canister update-settings instead." "$output" assert_command dfx deploy --no-wallet assert_command dfx canister status hello_backend - assert_contains "Reserved cycles limit: 860_000 Cycles" + assert_contains "Reserved cycles limit: 860_000 Cycles" "$output" } @test "deploy --upgrade-unchanged upgrades even if the .wasm did not change" { @@ -33,10 +33,10 @@ teardown() { assert_command dfx deploy assert_command dfx deploy - assert_match "Module hash.*is already installed" + assert_match "Module hash.*is already installed" "$output" assert_command dfx deploy --upgrade-unchanged --wasm-memory-persistence replace - assert_not_match "Module hash.*is already installed" + assert_not_match "Module hash.*is already installed" "$output" } @test "deploy without --no-wallet sets wallet and self as the controllers" { @@ -66,20 +66,20 @@ teardown() { ( cd src assert_command dfx deploy - assert_match "Installed code for" + assert_match "Installed code for" "$output" ) assert_command dfx canister call hello_backend greet '("Banzai")' assert_eq '("Hello, Banzai!")' assert_command dfx deploy - assert_not_match "Installed code for" - assert_match "is already installed" + assert_not_match "Installed code for" "$output" + assert_match "is already installed" "$output" } @test "deploying multiple canisters with arguments fails" { assert_command_fail dfx deploy --argument hello - assert_contains "The init argument can only be set when deploying a single canister." + assert_contains "The init argument can only be set when deploying a single canister." "$output" } @test "deploy one canister with an argument" { @@ -115,14 +115,14 @@ teardown() { jq '.canisters.dependency.init_arg="(\"dfx\")"' dfx.json | sponge dfx.json assert_command dfx deploy dependency assert_command dfx canister call dependency greet - assert_match "Hello, dfx!" + assert_match "Hello, dfx!" "$output" assert_command dfx deploy dependency --mode reinstall --yes --argument '("icp")' - assert_contains "Canister 'dependency' has init_arg/init_arg_file in dfx.json: (\"dfx\")," - assert_contains "which is different from the one specified in the command line: (\"icp\")." - assert_contains "The command line value will be used." + assert_contains "Canister 'dependency' has init_arg/init_arg_file in dfx.json: (\"dfx\")," "$output" + assert_contains "which is different from the one specified in the command line: (\"icp\")." "$output" + assert_contains "The command line value will be used." "$output" assert_command dfx canister call dependency greet - assert_match "Hello, icp!" + assert_match "Hello, icp!" "$output" } @test "reinstalling a single Motoko canister with imported dependency works" { @@ -144,7 +144,7 @@ teardown() { assert_command_fail dfx deploy --specified-id n5n4y-3aaaa-aaaaa-p777q-cai assert_match \ "error: the following required arguments were not provided: - " + " "$output" } @test "deploy succeeds when specify canister ID in dfx.json" { @@ -170,21 +170,21 @@ teardown() { dfx_start jq '.canisters.hello_backend.specified_id="n5n4y-3aaaa-aaaaa-p777q-cai"' dfx.json | sponge dfx.json assert_command dfx deploy hello_backend --specified-id n2m2m-wyaaa-aaaaa-p777a-cai - assert_contains "WARNING: Canister 'hello_backend' has a specified ID in dfx.json: n5n4y-3aaaa-aaaaa-p777q-cai," - assert_contains "which is different from the one specified in the command line: n2m2m-wyaaa-aaaaa-p777a-cai." - assert_contains "The command line value will be used." + assert_contains "WARNING: Canister 'hello_backend' has a specified ID in dfx.json: n5n4y-3aaaa-aaaaa-p777q-cai," "$output" + assert_contains "which is different from the one specified in the command line: n2m2m-wyaaa-aaaaa-p777a-cai." "$output" + assert_contains "The command line value will be used." "$output" assert_command dfx canister id hello_backend - assert_match n2m2m-wyaaa-aaaaa-p777a-cai + assert_match n2m2m-wyaaa-aaaaa-p777a-cai "$output" } @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 "Created a wallet canister" + assert_not_contains "Created a wallet canister" "$output" assert_command dfx identity get-wallet - assert_contains "Created a wallet canister" + assert_contains "Created a wallet canister" "$output" } @test "can deploy gzip wasm" { @@ -201,8 +201,8 @@ teardown() { dfx_start assert_command dfx deploy frontend_id=$(dfx canister id hello_frontend) - assert_match "http://127.0.0.1.+${frontend_id}" - assert_match "${frontend_id}.localhost" + assert_match "http://127.0.0.1.+${frontend_id}" "$output" + assert_match "${frontend_id}.localhost" "$output" } @test "prints the frontend url if 'frontend' section is not present in dfx.json" { @@ -211,8 +211,8 @@ teardown() { dfx_start assert_command dfx deploy frontend_id=$(dfx canister id hello_frontend) - assert_match "http://127.0.0.1.+${frontend_id}" - assert_match "${frontend_id}.localhost" + assert_match "http://127.0.0.1.+${frontend_id}" "$output" + assert_match "${frontend_id}.localhost" "$output" } @test "prints the frontend url if the frontend section has been removed after initial deployment" { @@ -220,12 +220,12 @@ teardown() { dfx_start assert_command dfx deploy frontend_id=$(dfx canister id hello_frontend) - assert_match "http://127.0.0.1.+${frontend_id}" - assert_match "${frontend_id}.localhost" + assert_match "http://127.0.0.1.+${frontend_id}" "$output" + assert_match "${frontend_id}.localhost" "$output" jq 'del(.canisters.hello_frontend.frontend)' dfx.json | sponge dfx.json assert_command dfx deploy - assert_match "http://127.0.0.1.+${frontend_id}" - assert_match "${frontend_id}.localhost" + assert_match "http://127.0.0.1.+${frontend_id}" "$output" + assert_match "${frontend_id}.localhost" "$output" } @test "subnet targetting" { @@ -276,9 +276,9 @@ teardown() { assert_command dfx deploy --mode upgrade --skip-pre-upgrade assert_command_fail dfx deploy --mode install --skip-pre-upgrade - assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." + assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." "$output" assert_command_fail dfx deploy --mode reinstall --wasm-memory-persistence keep - assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." + assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." "$output" } @test "can deploy a hyphenated project" { diff --git a/e2e/tests-dfx/deps.bash b/e2e/tests-dfx/deps.bash index bad6e57f92..96ad03fca3 100644 --- a/e2e/tests-dfx/deps.bash +++ b/e2e/tests-dfx/deps.bash @@ -61,13 +61,13 @@ setup_onchain() { 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://httpbin.org/status/404" "$output" + assert_eq "http://httpbin.org/status/404" assert_command jq -r '.pullable.dependencies | length' c_dfx.json - assert_eq 1 "$output" + assert_eq 1 assert_command jq -r '.pullable.dependencies | first' c_dfx.json - assert_eq "$CANISTER_ID_A" "$output" + assert_eq "$CANISTER_ID_A" assert_command jq -r '.pullable.init_guide' c_dfx.json - assert_eq "An optional natural number, e.g. \"(opt 20)\"." "$output" + assert_eq "An optional natural number, e.g. \"(opt 20)\"." } @test "dfx deps pull can resolve dependencies from on-chain canister metadata" { @@ -99,17 +99,17 @@ setup_onchain() { 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:" # Then canister IDs will be listed, but order doesn't matter - assert_occurs 1 "Fetching dependencies of canister $CANISTER_ID_A..." # common dependency onchain_a is pulled only once +Found 3 dependencies:" "$output" # Then canister IDs will be listed, but order doesn't matter + assert_occurs 1 "Fetching dependencies of canister $CANISTER_ID_A..." "$output" # 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://httpbin.org/status/404." +Failed to download from url: http://httpbin.org/status/404." "$output" assert_contains "Pulling canister $CANISTER_ID_B... ERROR: Failed to pull canister $CANISTER_ID_B. -Failed to download from url: http://httpbin.org/status/404." +Failed to download from url: http://httpbin.org/status/404." "$output" assert_contains "Pulling canister $CANISTER_ID_C... ERROR: Failed to pull canister $CANISTER_ID_C. -Failed to download from url: http://httpbin.org/status/404." +Failed to download from url: http://httpbin.org/status/404." "$output" # 3. sad path: if the canister is not present on-chain cd ../onchain @@ -119,7 +119,7 @@ Failed to download from url: http://httpbin.org/status/404." cd ../app assert_command_fail dfx deps pull --network local - assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." + assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." "$output" cd ../onchain dfx canister stop a @@ -127,7 +127,7 @@ Failed to download from url: http://httpbin.org/status/404." cd ../app assert_command_fail dfx deps pull --network local - assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." + assert_contains "Failed to get dependencies of canister $CANISTER_ID_A." "$output" } @test "dfx deps pull can download wasm and candids to shared cache and generate pulled.json" { @@ -164,15 +164,15 @@ Failed to download from url: http://httpbin.org/status/404." 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_eq "A natural number, e.g. 10." assert_command jq -r '.canisters."'"$CANISTER_ID_B"'".name' pulled.json - assert_eq "dep_b" "$output" + assert_eq "dep_b" assert_command jq -r '.canisters."'"$CANISTER_ID_C"'".name' pulled.json - assert_eq "dep_c" "$output" + assert_eq "dep_c" cd ../ assert_command dfx deps pull --network local -vvv - assert_contains "The canister wasm was found in the cache." # cache hit + assert_contains "The canister wasm was found in the cache." "$output" # cache hit # hash mismatch is ok # the expected hash is written to pulled.json wasm_hash field @@ -185,7 +185,7 @@ Failed to download from url: http://httpbin.org/status/404." cd ../app assert_command dfx deps pull --network local - assert_not_contains "WARN" + assert_not_match "WARNING: Canister [^ ]+ specified" "$output" assert_command jq -r '.canisters."'"$CANISTER_ID_A"'".wasm_hash' deps/pulled.json assert_match "$WASM_HASH_A" "$output" assert_command jq -r '.canisters."'"$CANISTER_ID_A"'".wasm_hash_download' deps/pulled.json @@ -196,8 +196,8 @@ Failed to download from url: http://httpbin.org/status/404." 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:" + assert_contains "Failed to pull canister $CANISTER_ID_A." "$output" + assert_contains "Failed to download from url:" "$output" } @test "dfx deps pull works when wasm_hash or wasm_hash_url specified" { @@ -250,9 +250,9 @@ Failed to download from url: http://httpbin.org/status/404." 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_contains "Canister $CANISTER_ID_B specified a custom hash via url:" - assert_contains "Canister $CANISTER_ID_C specified a custom hash via url:" + assert_contains "Canister $CANISTER_ID_A specified a custom hash:" "$output" + assert_contains "Canister $CANISTER_ID_B specified a custom hash via url:" "$output" + assert_contains "Canister $CANISTER_ID_C specified a custom hash via url:" "$output" # warning: specified both `wasm_hash` and `wasm_hash_url`. Providers should avoid this. PULLED_DIR="$DFX_CACHE_ROOT/.cache/dfinity/pulled/" @@ -264,7 +264,7 @@ Failed to download from url: http://httpbin.org/status/404." cd ../app assert_command dfx deps pull --network local -vvv - assert_contains "WARNING: Canister $CANISTER_ID_C specified both \`wasm_hash\` and \`wasm_hash_url\`. \`wasm_hash\` will be used." + assert_contains "WARNING: Canister $CANISTER_ID_C specified both \`wasm_hash\` and \`wasm_hash_url\`. \`wasm_hash\` will be used." "$output" # hash mismatch is ok rm -r "${PULLED_DIR:?}/" @@ -273,7 +273,7 @@ Failed to download from url: http://httpbin.org/status/404." cd ../app assert_command dfx deps pull --network local -vvv - assert_contains "Canister $CANISTER_ID_A specified a custom hash:" + assert_contains "Canister $CANISTER_ID_A specified a custom hash:" "$output" } @test "dfx deps init works" { @@ -292,9 +292,9 @@ Failed to download from url: http://httpbin.org/status/404." dfx_stop assert_command dfx deps init - assert_contains "Canister $CANISTER_ID_C (dep_c) set init argument with \"(null)\"." + assert_contains "Canister $CANISTER_ID_C (dep_c) set init argument with \"(null)\"." "$output" assert_contains "WARNING: The following canister(s) require an init argument. Please run \`dfx deps init \` to set them individually: -$CANISTER_ID_A" +$CANISTER_ID_A" "$output" assert_command dfx deps init "$CANISTER_ID_A" --argument 11 @@ -313,11 +313,11 @@ $CANISTER_ID_A" # 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" + assert_eq "4449444c00017103616263" # Canister A has been set, set again without --argument will prompt a info message assert_command dfx deps init "$CANISTER_ID_A" - assert_contains "Canister $CANISTER_ID_A already set init argument." + assert_contains "Canister $CANISTER_ID_A already set init argument." "$output" # error cases rm deps/init.json @@ -325,19 +325,19 @@ $CANISTER_ID_A" assert_command_fail dfx deps init "$CANISTER_ID_A" assert_contains "Canister $CANISTER_ID_A requires an init argument. The following info might be helpful: init_guide => A natural number, e.g. 10. -candid:args => (nat)" +candid:args => (nat)" "$output" ## 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" + assert_contains "Invalid data: Unable to serialize Candid values: type mismatch: \"abc\" cannot be of type nat" "$output" ## 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\`" + assert_contains "Canister $CANISTER_ID_B (dep_b) takes no init argument. Please rerun without \`--argument\`" "$output" ## canister ID not in pulled.json assert_command_fail dfx deps init aaaaa-aa - assert_contains "Could not find aaaaa-aa in pulled.json" + assert_contains "Could not find aaaaa-aa in pulled.json" "$output" } @test "dfx deps init can handle init_arg in pullable metadata" { @@ -397,7 +397,7 @@ candid:args => (nat)" Please try to set an init argument with \`--argument\` option. The following info might be helpful: init_guide => A natural number, e.g. 10. -candid:args => (nat)" +candid:args => (nat)" "$output" # Consumer set correct init_arg assert_command dfx deps init "$CANISTER_ID_A" --argument 10 @@ -428,19 +428,19 @@ candid:args => (nat)" # deploy all assert_command dfx deps deploy assert_contains "Creating canister: $CANISTER_ID_A -Installing canister: $CANISTER_ID_A" +Installing canister: $CANISTER_ID_A" "$output" assert_contains "Creating canister: $CANISTER_ID_B (dep_b) -Installing canister: $CANISTER_ID_B (dep_b)" +Installing canister: $CANISTER_ID_B (dep_b)" "$output" assert_contains "Creating canister: $CANISTER_ID_C (dep_c) -Installing canister: $CANISTER_ID_C (dep_c)" +Installing canister: $CANISTER_ID_C (dep_c)" "$output" # 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 + assert_contains "Installing canister: $CANISTER_ID_B (dep_b)" "$output" # 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" + assert_contains "Installing canister: $CANISTER_ID_A" "$output" # deployed pull dependencies can be stopped and deleted assert_command dfx canister stop dep_b --identity anonymous @@ -453,22 +453,22 @@ Installing canister: $CANISTER_ID_C (dep_c)" ## 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" + assert_contains "Failed to install canister $CANISTER_ID_A" "$output" ## canister ID not in pulled.json assert_command_fail dfx deps deploy aaaaa-aa - assert_contains "Could not find aaaaa-aa in pulled.json" + assert_contains "Could not find aaaaa-aa in pulled.json" "$output" ## 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\`." + assert_contains "Failed to read init.json. Please run \`dfx deps init\`." "$output" ## 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\`." + assert_contains "Failed to create and install canister $CANISTER_ID_A" "$output" + assert_contains "Failed to find $CANISTER_ID_A entry in init.json. Please run \`dfx deps init $CANISTER_ID_A\`." "$output" } @test "dfx deps init/deploy works when hash mismatch" { @@ -515,25 +515,25 @@ Installing canister: $CANISTER_ID_C (dep_c)" ## 1.1. missing pull dependency in pulled.json jq 'del(.canisters."'"$CANISTER_ID_B"'")' deps/pulled.json.bak > deps/pulled.json assert_command_fail dfx deps init - assert_contains "Failed to find dep_b:$CANISTER_ID_B in pulled.json." - assert_contains "Please rerun \`dfx deps pull\`." + assert_contains "Failed to find dep_b:$CANISTER_ID_B in pulled.json." "$output" + assert_contains "Please rerun \`dfx deps pull\`." "$output" assert_command_fail dfx deps deploy - assert_contains "Failed to find dep_b:$CANISTER_ID_B in pulled.json." - assert_contains "Please rerun \`dfx deps pull\`." + assert_contains "Failed to find dep_b:$CANISTER_ID_B in pulled.json." "$output" + assert_contains "Please rerun \`dfx deps pull\`." "$output" ## 1.2. name mismatch in pulled.json and dfx.json jq '.canisters."'"$CANISTER_ID_B"'".name="not_dep_b"' deps/pulled.json.bak > deps/pulled.json assert_command_fail dfx deps init - assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it has name \"not_dep_b\" in pulled.json." + assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it has name \"not_dep_b\" in pulled.json." "$output" assert_command_fail dfx deps deploy - assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it has name \"not_dep_b\" in pulled.json." + assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it has name \"not_dep_b\" in pulled.json." "$output" ## 1.3. no name in pulled.json jq 'del(.canisters."'"$CANISTER_ID_B"'".name)' deps/pulled.json.bak > deps/pulled.json assert_command_fail dfx deps init - assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it doesn't have name in pulled.json." + assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it doesn't have name in pulled.json." "$output" assert_command_fail dfx deps deploy - assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it doesn't have name in pulled.json." + assert_contains "$CANISTER_ID_B is \"dep_b\" in dfx.json, but it doesn't have name in pulled.json." "$output" cp deps/pulled.json.bak deps/pulled.json @@ -543,30 +543,30 @@ Installing canister: $CANISTER_ID_C (dep_c)" WASM_PATH_A="$DFX_CACHE_ROOT/.cache/dfinity/pulled/$CANISTER_ID_A/canister.wasm" mv "$WASM_PATH_A" "$WASM_PATH_A.bak" assert_command_fail dfx deps init - assert_contains "failed to read from $WASM_PATH_A" + assert_contains "failed to read from $WASM_PATH_A" "$output" assert_command_fail dfx deps deploy - assert_contains "failed to read from $WASM_PATH_A" + assert_contains "failed to read from $WASM_PATH_A" "$output" mv "$WASM_PATH_A.bak" "$WASM_PATH_A" ## 2.2. wasm_hash_download is not valid hex string jq '.canisters."'"$CANISTER_ID_B"'".wasm_hash_download="xyz"' deps/pulled.json.bak > deps/pulled.json assert_command_fail dfx deps init - assert_contains "In pulled.json, the \`wasm_hash_download\` field of $CANISTER_ID_B is invalid." + assert_contains "In pulled.json, the \`wasm_hash_download\` field of $CANISTER_ID_B is invalid." "$output" assert_command_fail dfx deps deploy - assert_contains "In pulled.json, the \`wasm_hash_download\` field of $CANISTER_ID_B is invalid." + assert_contains "In pulled.json, the \`wasm_hash_download\` field of $CANISTER_ID_B is invalid." "$output" ## 2.3. hash mismatch jq '.canisters."'"$CANISTER_ID_A"'".wasm_hash_download="0123456789abcdef"' deps/pulled.json.bak > deps/pulled.json assert_command_fail dfx deps init - assert_contains "The wasm of $CANISTER_ID_A in pulled cache has different hash than in pulled.json:" - assert_contains "The pulled cache is at \"$WASM_PATH_A\". Its hash is:" - assert_contains "The hash (wasm_hash_download) in pulled.json is:" - assert_contains "The pulled cache may be modified manually or the same canister was pulled in different projects." + assert_contains "The wasm of $CANISTER_ID_A in pulled cache has different hash than in pulled.json:" "$output" + assert_contains "The pulled cache is at \"$WASM_PATH_A\". Its hash is:" "$output" + assert_contains "The hash (wasm_hash_download) in pulled.json is:" "$output" + assert_contains "The pulled cache may be modified manually or the same canister was pulled in different projects." "$output" assert_command_fail dfx deps deploy - assert_contains "The wasm of $CANISTER_ID_A in pulled cache has different hash than in pulled.json:" - assert_contains "The pulled cache is at \"$WASM_PATH_A\". Its hash is:" - assert_contains "The hash (wasm_hash_download) in pulled.json is:" - assert_contains "The pulled cache may be modified manually or the same canister was pulled in different projects." + assert_contains "The wasm of $CANISTER_ID_A in pulled cache has different hash than in pulled.json:" "$output" + assert_contains "The pulled cache is at \"$WASM_PATH_A\". Its hash is:" "$output" + assert_contains "The hash (wasm_hash_download) in pulled.json is:" "$output" + assert_contains "The pulled cache may be modified manually or the same canister was pulled in different projects." "$output" } @test "dfx deps pulled dependencies work with app canister" { @@ -586,18 +586,18 @@ Installing canister: $CANISTER_ID_C (dep_c)" dfx_start --clean 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_contains "dep_b is a pull dependency. Please deploy it using \`dfx deps deploy dep_b\`" "$output" 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_contains "There are pull dependencies defined in dfx.json. Please deploy them using \`dfx deps deploy\`." "$output" 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_contains "Canister $CANISTER_ID_B not found" "$output" assert_command dfx deps init assert_command dfx deps init "$CANISTER_ID_A" --argument 11 @@ -605,13 +605,13 @@ Installing canister: $CANISTER_ID_C (dep_c)" assert_command dfx deps deploy assert_command dfx canister call app get_b - assert_eq "(2 : nat)" "$output" + assert_eq "(2 : nat)" assert_command dfx canister call app get_c - assert_eq "(33 : nat)" "$output" # corresponding to --argument "(opt 33)" above + assert_eq "(33 : nat)" # corresponding to --argument "(opt 33)" above assert_command dfx canister call app get_b_times_a - assert_eq "(22 : nat)" "$output" # 2 * 11 + assert_eq "(22 : nat)" # 2 * 11 assert_command dfx canister call app get_c_times_a - assert_eq "(363 : nat)" "$output" # 33 * 11 + assert_eq "(363 : nat)" # 33 * 11 # start a clean local replica dfx canister stop app @@ -624,15 +624,15 @@ Installing canister: $CANISTER_ID_C (dep_c)" # 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." - assert_contains "You can still choose other network by setting \`--network\`" + assert_contains "Pull canisters upon which the project depends. This command connects to the \"ic\" mainnet by default." "$output" + assert_contains "You can still choose other network by setting \`--network\`" "$output" assert_command dfx deps pull - assert_contains "There are no pull dependencies defined in dfx.json" + assert_contains "There are no pull dependencies defined in dfx.json" "$output" assert_command dfx deps init - assert_contains "There are no pull dependencies defined in dfx.json" + assert_contains "There are no pull dependencies defined in dfx.json" "$output" assert_command dfx deps deploy - assert_contains "There are no pull dependencies defined in dfx.json" + assert_contains "There are no pull dependencies defined in dfx.json" "$output" assert_directory_not_exists "deps" } @@ -666,12 +666,12 @@ Installing canister: $CANISTER_ID_C (dep_c)" dfx_start assert_command dfx deps pull --network local - assert_contains "Using facade dependencies for canister ryjl3-tyaaa-aaaaa-aaaba-cai." + assert_contains "Using facade dependencies for canister ryjl3-tyaaa-aaaaa-aaaba-cai." "$output" dfx identity new --storage-mode plaintext minter assert_command_fail dfx deps init icp_ledger assert_contains "1. Create a 'minter' identity: dfx identity new minter -2. Run the following multi-line command:" +2. Run the following multi-line command:" "$output" assert_command dfx deps init ryjl3-tyaaa-aaaaa-aaaba-cai --argument "(variant { Init = record { @@ -715,12 +715,12 @@ Installing canister: $CANISTER_ID_C (dep_c)" dfx_start assert_command dfx deps pull --network local - assert_contains "Using facade dependencies for canister mxzaz-hqaaa-aaaar-qaada-cai." + assert_contains "Using facade dependencies for canister mxzaz-hqaaa-aaaar-qaada-cai." "$output" dfx identity new --storage-mode plaintext minter assert_command_fail dfx deps init ckbtc_ledger assert_contains "1. Create a 'minter' identity: dfx identity new minter -2. Run the following multi-line command:" +2. Run the following multi-line command:" "$output" assert_command dfx deps init mxzaz-hqaaa-aaaar-qaada-cai --argument "(variant { Init = record { @@ -774,12 +774,12 @@ Installing canister: $CANISTER_ID_C (dep_c)" dfx_start assert_command dfx deps pull --network local - assert_contains "Using facade dependencies for canister ss2fx-dyaaa-aaaar-qacoq-cai." + assert_contains "Using facade dependencies for canister ss2fx-dyaaa-aaaar-qacoq-cai." "$output" dfx identity new --storage-mode plaintext minter assert_command_fail dfx deps init cketh_ledger assert_contains "1. Create a 'minter' identity: dfx identity new minter -2. Run the following multi-line command:" +2. Run the following multi-line command:" "$output" assert_command dfx deps init ss2fx-dyaaa-aaaar-qacoq-cai --argument "(variant { Init = record { diff --git a/e2e/tests-dfx/describe_local_network.bash b/e2e/tests-dfx/describe_local_network.bash index acb5e18925..26e8c21426 100644 --- a/e2e/tests-dfx/describe_local_network.bash +++ b/e2e/tests-dfx/describe_local_network.bash @@ -17,7 +17,7 @@ teardown() { 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\)" "$output" } @test "dfx start with a nonstandard subnet type" { @@ -26,20 +26,20 @@ teardown() { 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\)" "$output" } @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_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\)" "$output" + assert_match "nodes: \[192.168.0.1:18000\] \(default: \[127.0.0.1:18444\]\)" "$output" } @test "dfx start enabling bitcoin" { 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\)" "$output" } @test "dfx start in a project without a network definition" { @@ -50,22 +50,22 @@ teardown() { # 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 configuration for the local shared network" + assert_match "There is no project-specific network 'local' defined in .*/some-project/dfx.json." "$output" + assert_match "Using the default configuration for the local shared network" "$output" - 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" + assert_match "Local server configuration:" "$output" + assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:4943\)" "$output" + assert_match "bitcoin: disabled" "$output" + assert_match "canister http: enabled" "$output" + assert_match "subnet type: Application" "$output" + assert_match "scope: shared" "$output" } @test "dfx start outside of a project with default configuration" { 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 configuration for the local shared network" + assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." "$output" + assert_match "Using the default configuration for the local shared network" "$output" } @test "dfx start outside of a project with a shared configuration file" { @@ -73,8 +73,8 @@ teardown() { 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 configuration for the local shared network" + assert_match "There is no project-specific network 'local' because there is no project \(no dfx.json\)." "$output" + assert_match "Using the default configuration for the local shared network" "$output" } @@ -84,8 +84,8 @@ teardown() { 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\)." "$output" + assert_match "Using shared network 'local' defined in $DFX_CONFIG_ROOT/.config/dfx/networks.json" "$output" } @test "dfx start describes default project-specific network" { @@ -94,13 +94,13 @@ teardown() { 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" + assert_match "Local server configuration:" "$output" + assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:8000\)" "$output" + assert_match "bitcoin: disabled" "$output" + assert_match "canister http: enabled" "$output" + assert_match "subnet type: Application" "$output" + assert_match "data directory: .*/working-dir/.dfx/network/local" "$output" + assert_match "scope: project" "$output" } @test "dfx start describes default shared network" { @@ -110,17 +110,17 @@ teardown() { 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:" "$output" + assert_match "bind address: 127.0.0.1:0 \(default: 127.0.0.1:4943\)" "$output" + assert_match "bitcoin: disabled" "$output" + assert_match "canister http: enabled" "$output" + assert_match "subnet type: Application" "$output" if [ "$(uname)" == "Darwin" ]; then - assert_match "data directory: .*/home-dir/Library/Application Support/org.dfinity.dfx/network/local" + assert_match "data directory: .*/home-dir/Library/Application Support/org.dfinity.dfx/network/local" "$output" elif [ "$(uname)" == "Linux" ]; then - assert_match "data directory: .*/home-dir/.local/share/dfx/network/local" + assert_match "data directory: .*/home-dir/.local/share/dfx/network/local" "$output" fi - assert_match "scope: shared" + assert_match "scope: shared" "$output" } \ No newline at end of file diff --git a/e2e/tests-dfx/dfx_install.bash b/e2e/tests-dfx/dfx_install.bash index 498ba65c36..ace73783eb 100644 --- a/e2e/tests-dfx/dfx_install.bash +++ b/e2e/tests-dfx/dfx_install.bash @@ -55,7 +55,7 @@ teardown() { for file in "$(dfx cache show)"/base/*.mo; do assert_command_fail test -x "$file" assert_command_fail "$file" - assert_contains "Permission denied" + assert_contains "Permission denied" "$output" done } @@ -64,7 +64,7 @@ teardown() { for file in "$(dfx cache show)"/core/*.mo; do assert_command_fail test -x "$file" assert_command_fail "$file" - assert_contains "Permission denied" + assert_contains "Permission denied" "$output" done } diff --git a/e2e/tests-dfx/dotenv.bash b/e2e/tests-dfx/dotenv.bash index 7322cea76c..58e4ca627b 100644 --- a/e2e/tests-dfx/dotenv.bash +++ b/e2e/tests-dfx/dotenv.bash @@ -43,13 +43,13 @@ teardown() { mkdir ../outside assert_command_fail dfx deploy --output-env-file nonexistent/.env - assert_contains "failed to canonicalize output_env_file" - assert_contains "working-dir/e2e_project/nonexistent" - assert_contains "No such file or directory" + assert_contains "failed to canonicalize output_env_file" "$output" + assert_contains "working-dir/e2e_project/nonexistent" "$output" + assert_contains "No such file or directory" "$output" assert_command_fail dfx deploy --output-env-file /etc/passwd - assert_contains "The output_env_file must be a relative path, but is /etc/passwd" + assert_contains "The output_env_file must be a relative path, but is /etc/passwd" "$output" assert_command_fail dfx deploy --output-env-file ../outside/.env - assert_match "The output_env_file must be within the project root, but is .*/working-dir/e2e_project/../outside/.env" + assert_match "The output_env_file must be within the project root, but is .*/working-dir/e2e_project/../outside/.env" "$output" } @test "build writes all environment variables to .env" { diff --git a/e2e/tests-dfx/error_context.bash b/e2e/tests-dfx/error_context.bash index 19211ef9ae..d480152f8a 100644 --- a/e2e/tests-dfx/error_context.bash +++ b/e2e/tests-dfx/error_context.bash @@ -25,31 +25,31 @@ teardown() { echo "invalid json" >"$WALLETS_JSON" assert_command_fail dfx identity get-wallet - assert_match "failed to parse contents of .*/network/local/[0-9a-f]+/wallets.json as json" - assert_match "expected value at line 1 column 1" + assert_match "failed to parse contents of .*/network/local/[0-9a-f]+/wallets.json as json" "$output" + assert_match "expected value at line 1 column 1" "$output" assert_command_fail dfx wallet upgrade - assert_match "failed to parse contents of .*/network/local/[0-9a-f]+/wallets.json as json" - assert_match "expected value at line 1 column 1" + assert_match "failed to parse contents of .*/network/local/[0-9a-f]+/wallets.json as json" "$output" + assert_match "expected value at line 1 column 1" "$output" echo '{ "identities": {} }' >"$WALLETS_JSON" # maybe you were sudo when you made it chmod u=w,go= "$WALLETS_JSON" assert_command_fail dfx identity get-wallet - assert_match "failed to read .*/network/local/[0-9a-f]+/wallets.json" - assert_match "Permission denied" + assert_match "failed to read .*/network/local/[0-9a-f]+/wallets.json" "$output" + assert_match "Permission denied" "$output" assert_command_fail dfx wallet upgrade - assert_match "failed to read .*/network/local/[0-9a-f]+/wallets.json" - assert_match "Permission denied" + assert_match "failed to read .*/network/local/[0-9a-f]+/wallets.json" "$output" + assert_match "Permission denied" "$output" # can't write it? chmod u=r,go= "$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/[0-9a-f]+/wallets.json" - assert_match "Permission denied" + assert_match "failed to write to .*/local/[0-9a-f]+/wallets.json" "$output" + assert_match "Permission denied" "$output" } @test "address already in use" { @@ -64,13 +64,13 @@ teardown() { assert_command_fail dfx start --host "$address" # What was the purpose of the address - assert_match "frontend address" + assert_match "frontend address" "$output" # What was the address we were looking for - assert_match "$address" + assert_match "$address" "$output" # The underlying cause - assert_match "Address already in use" + assert_match "Address already in use" "$output" # 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" @@ -81,13 +81,13 @@ teardown() { assert_command_fail dfx deploy # The bare minimum is to mention the file - assert_match "dfx.json" + assert_match "dfx.json" "$output" # It's nice to mention the full path to the file - assert_match "$(pwd)/dfx.json" + assert_match "$(pwd)/dfx.json" "$output" # The underlying cause - assert_match "expected value at line 1 column 1" + assert_match "expected value at line 1 column 1" "$output" } @test "packtool missing" { @@ -101,9 +101,9 @@ teardown() { 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"' + assert_match '"not-a-valid-packtool" "and" "some" "parameters"' "$output" # expect to see the underlying cause - assert_match "No such file or directory" + assert_match "No such file or directory" "$output" } @test "moc missing" { @@ -117,13 +117,13 @@ teardown() { assert_command_fail dfx build m_o_c_missing # expect to see the name of the binary - assert_match "moc" + assert_match "moc" "$output" # expect to see the full path of the binary - assert_contains "$(dfx cache show)/moc" + assert_contains "$(dfx cache show)/moc" "$output" # expect to see the underlying cause - assert_match "No such file or directory" + assert_match "No such file or directory" "$output" } @test "npm is not installed" { @@ -140,11 +140,11 @@ teardown() { PATH="$helpers_path" assert_command_fail "$dfx_path" deploy npm_missing # expect to see the npm command line - assert_match 'npm run build' + assert_match 'npm run build' "$output" # expect to see the name of the canister - assert_match "npm_missing" + assert_match "npm_missing" "$output" # expect to see the underlying cause - assert_match "(Is it installed?)" + assert_match "(Is it installed?)" "$output" } @test "missing asset source directory" { @@ -155,11 +155,11 @@ teardown() { assert_command_fail dfx deploy asset_bad_source_path # expect to see the bad path - assert_match "src/does/not/exist" + assert_match "src/does/not/exist" "$output" # expect to see the name of the canister - assert_match "asset_bad_source_path" + assert_match "asset_bad_source_path" "$output" # expect to see the underlying cause - assert_match "No such file or directory" + assert_match "No such file or directory" "$output" } @test "custom bad build step" { @@ -170,17 +170,17 @@ teardown() { 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" + assert_match "not-the-name-of-an-executable-that-exists" "$output" # expect to see the name of the canister - assert_match "custom_bad_build_step" + assert_match "custom_bad_build_step" "$output" # expect to see the underlying cause - assert_match "The custom tool failed" + assert_match "The custom tool failed" "$output" } @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 " + assert_match "expected one of " "$output" } @test "HTTP 403 has a full diagnosis" { @@ -198,8 +198,8 @@ teardown() { # 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 + assert_match "not part of the controllers" "$output" # this is part of the error explanation + assert_match "'dfx canister update-settings --add-controller \(--network ic\)'" "$output" # this is part of the solution } @test "bad wallet canisters get diagnosed" { @@ -209,16 +209,16 @@ teardown() { id=$(dfx canister id hello_backend) dfx identity set-wallet "$id" --force assert_command_fail dfx wallet balance - assert_contains "it did not contain a function that dfx was looking for" - assert_contains "dfx identity set-wallet --identity " + assert_contains "it did not contain a function that dfx was looking for" "$output" + assert_contains "dfx identity set-wallet --identity " "$output" } @test "Local replica not running has nice error messages" { dfx_new assert_command_fail dfx ping local - assert_contains "You are trying to connect to the local replica but dfx cannot connect to it." + assert_contains "You are trying to connect to the local replica but dfx cannot connect to it." "$output" assert_command_fail dfx deploy - assert_contains "You are trying to connect to the local replica but dfx cannot connect to it." + assert_contains "You are trying to connect to the local replica but dfx cannot connect to it." "$output" assert_command_fail dfx canister call um5iw-rqaaa-aaaaq-qaaba-cai some_method - assert_contains "You are trying to connect to the local replica but dfx cannot connect to it." + assert_contains "You are trying to connect to the local replica but dfx cannot connect to it." "$output" } diff --git a/e2e/tests-dfx/extension.bash b/e2e/tests-dfx/extension.bash index 77c5a4851b..399a02826e 100644 --- a/e2e/tests-dfx/extension.bash +++ b/e2e/tests-dfx/extension.bash @@ -347,28 +347,30 @@ EOF assert_eq "java,kotlin" } +# shellcheck disable=SC2030 @test "extension install with an empty cache does not create a corrupt cache" { dfx cache delete dfx extension install nns --version 0.2.1 dfx_start } +# shellcheck disable=SC2031 install_extension_from_dfx_extensions_repo() { EXTENSION=$1 assert_command_fail dfx snsx assert_command dfx extension list - assert_match 'No extensions installed' + assert_match 'No extensions installed' "$output" assert_command dfx extension install "$EXTENSION" --install-as snsx --version 0.4.7 - assert_contains "Extension 'sns' version 0.4.7 installed successfully, and is available as 'snsx'" + assert_contains "Extension 'sns' version 0.4.7 installed successfully, and is available as 'snsx'" "$output" assert_command dfx extension list - assert_match 'snsx' + assert_match 'snsx' "$output" assert_command dfx --help - assert_match 'snsx.*Initialize, deploy and interact with an SNS' + assert_match 'snsx.*Initialize, deploy and interact with an SNS' "$output" assert_command dfx snsx --help @@ -377,7 +379,7 @@ install_extension_from_dfx_extensions_repo() { # assert_match 'Successfully uninstalled extension' assert_command dfx extension list - assert_match 'No extensions installed' + assert_match 'No extensions installed' "$output" } @test "install extension by name from official catalog" { @@ -721,7 +723,7 @@ EOF @test "manually create extension" { assert_command dfx extension list - assert_match 'No extensions installed' + assert_match 'No extensions installed' "$output" CACHE_DIR=$(dfx cache show) mkdir -p "$CACHE_DIR"/extensions/test_extension @@ -731,46 +733,46 @@ echo testoutput' > "$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.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" "$output" assert_command_fail dfx extension run test_extension - assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" "$output" assert_command_fail dfx test_extension - assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" "$output" assert_command_fail dfx --help - assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" "$output" assert_command_fail dfx test_extension --help - assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" + assert_match "Error.*Failed to load extension manifest.*failed to read JSON file.*failed to read .*extensions/test_extension/extension.json.*No such file or directory" "$output" echo "{}" > "$CACHE_DIR"/extensions/test_extension/extension.json assert_command_fail dfx extension list - assert_contains "Failed to load extension manifest" - assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json" - assert_match "missing field .* at line .* column .*" + assert_contains "Failed to load extension manifest" "$output" + assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json" "$output" + assert_match "missing field .* at line .* column .*" "$output" assert_command_fail dfx extension run test_extension - assert_contains "Failed to load extension manifest" - assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" - assert_match "missing field .* at line .* column .*" + assert_contains "Failed to load extension manifest" "$output" + assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" "$output" + assert_match "missing field .* at line .* column .*" "$output" assert_command_fail dfx test_extension - assert_contains "Failed to load extension manifest" - assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" - assert_match "missing field .* at line .* column .*" + assert_contains "Failed to load extension manifest" "$output" + assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" "$output" + assert_match "missing field .* at line .* column .*" "$output" assert_command_fail dfx --help - assert_contains "Failed to load extension manifest" - assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" - assert_match "missing field .* at line .* column .*" + assert_contains "Failed to load extension manifest" "$output" + assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" "$output" + assert_match "missing field .* at line .* column .*" "$output" assert_command_fail dfx test_extension --help - assert_contains "Failed to load extension manifest" - assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" - assert_match "missing field .* at line .* column .*" + assert_contains "Failed to load extension manifest" "$output" + assert_match "failed to parse contents of .*extensions/test_extension/extension.json as json.*" "$output" + assert_match "missing field .* at line .* column .*" "$output" echo '{ "name": "test_extension", @@ -783,26 +785,26 @@ echo testoutput' > "$CACHE_DIR"/extensions/test_extension/test_extension }' > "$CACHE_DIR"/extensions/test_extension/extension.json assert_command dfx --help - assert_match "test_extension.*Test extension for e2e purposes." + assert_match "test_extension.*Test extension for e2e purposes." "$output" assert_command dfx test_extension --help - assert_match "Test extension for e2e purposes..*Usage: dfx test_extension" + assert_match "Test extension for e2e purposes..*Usage: dfx test_extension" "$output" assert_command dfx extension list - assert_match "test_extension" + assert_match "test_extension" "$output" assert_command dfx extension run test_extension - assert_match "testoutput" + assert_match "testoutput" "$output" assert_command dfx test_extension - assert_match "testoutput" + assert_match "testoutput" "$output" 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_match 'No extensions installed' "$output" } diff --git a/e2e/tests-dfx/fabricate_cycles.bash b/e2e/tests-dfx/fabricate_cycles.bash index 6d811adb03..2e00fcf5ec 100644 --- a/e2e/tests-dfx/fabricate_cycles.bash +++ b/e2e/tests-dfx/fabricate_cycles.bash @@ -21,9 +21,9 @@ teardown() { # default amount is 10 trillion cycles, which results in an amount like 13_899_071_239_420 assert_command dfx ledger fabricate-cycles --canister "$(dfx canister id hello_backend)" # bash does not accept \d, use [0-9] instead - assert_match 'updated balance: [0-9]{2}(_[0-9]{3}){4} cycles' + assert_match 'updated balance: [0-9]{2}(_[0-9]{3}){4} cycles' "$output" assert_command dfx ledger fabricate-cycles --all - assert_match 'updated balance: [0-9]{2}(_[0-9]{3}){4} cycles' + assert_match 'updated balance: [0-9]{2}(_[0-9]{3}){4} cycles' "$output" } @test "ledger fabricate-cycles works with specific amount" { @@ -32,9 +32,9 @@ teardown() { dfx deploy # adding 100 trillion cycles, which results in an amount like 103_899_071_239_420 assert_command dfx ledger fabricate-cycles --canister "$(dfx canister id hello_backend)" --cycles 100000000000000 - assert_match 'updated balance: [0-9]{3}(_[0-9]{3}){4} cycles' + assert_match 'updated balance: [0-9]{3}(_[0-9]{3}){4} cycles' "$output" assert_command dfx ledger fabricate-cycles --canister hello_backend --t 100 - assert_match 'updated balance: [0-9]{3}(_[0-9]{3}){4} cycles' + assert_match 'updated balance: [0-9]{3}(_[0-9]{3}){4} cycles' "$output" } @test "ledger fabricate-cycles fails on real IC" { @@ -42,9 +42,9 @@ teardown() { # without DFX_WARNING, the command would fail with different error (Failed to create AgentEnvironment...) export DFX_WARNING=-mainnet_plaintext_identity assert_command_fail dfx ledger fabricate-cycles --all --network ic - assert_match "Cannot run this on the real IC." + assert_match "Cannot run this on the real IC." "$output" assert_command_fail dfx ledger fabricate-cycles --all --ic - assert_match "Cannot run this on the real IC." + assert_match "Cannot run this on the real IC." "$output" } @test "ledger fabricate-cycles fails with wrong option combinations" { diff --git a/e2e/tests-dfx/frontend.bash b/e2e/tests-dfx/frontend.bash index d0f8e4884d..e52eba2740 100644 --- a/e2e/tests-dfx/frontend.bash +++ b/e2e/tests-dfx/frontend.bash @@ -22,15 +22,15 @@ teardown() { 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 "http://127.0.0.1:$PORT/\?canisterId=$ASSETS_ID" + assert_match "e2e_project_backend: http://127.0.0.1:$PORT/\?canisterId=$CANDID_UI_ID&id=$APP_ID" "$output" + assert_match "http://127.0.0.1:$PORT/\?canisterId=$ASSETS_ID" "$output" # 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/" + assert_match "e2e_project_backend: http://$CANDID_UI_ID.localhost:$PORT/\?id=$APP_ID" "$output" + assert_match "e2e_project_frontend: http://$ASSETS_ID.localhost:$PORT/" "$output" } @test "dfx start serves a frontend with static assets" { @@ -85,9 +85,9 @@ teardown() { 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_match "< x-key: x-value" "$output" assert_command curl -vv http://localhost:"$PORT"/favicon.ico?canisterId="$ID" - assert_match "< x-key: x-value" + assert_match "< x-key: x-value" "$output" } @test "dfx uses a custom build command if one is provided" { diff --git a/e2e/tests-dfx/id.bash b/e2e/tests-dfx/id.bash index 444289aa3b..bd9f165239 100644 --- a/e2e/tests-dfx/id.bash +++ b/e2e/tests-dfx/id.bash @@ -102,8 +102,8 @@ teardown() { assert_command dfx canister --network ic set-id hello_backend $CANISTER_ID assert_command dfx canister id hello_backend --network ic - assert_contains $CANISTER_ID + assert_contains $CANISTER_ID "$output" assert_command_fail dfx canister id hello_backend --network local - assert_contains "Cannot find canister id" + assert_contains "Cannot find canister id" "$output" } diff --git a/e2e/tests-dfx/identity.bash b/e2e/tests-dfx/identity.bash index dc9af2c237..cb2fc76055 100644 --- a/e2e/tests-dfx/identity.bash +++ b/e2e/tests-dfx/identity.bash @@ -16,22 +16,22 @@ teardown() { @test "identity new: name validation" { assert_command_fail dfx identity new iden%tity --storage-mode plaintext - assert_match "Invalid identity name" + assert_match "Invalid identity name" "$output" assert_command_fail dfx identity new 'iden tity' --storage-mode plaintext - assert_match "Invalid identity name" + assert_match "Invalid identity name" "$output" assert_command_fail dfx identity new "iden\$tity" --storage-mode plaintext - assert_match "Invalid identity name" + assert_match "Invalid identity name" "$output" assert_command_fail dfx identity new iden\\tity --storage-mode plaintext - assert_match "Invalid identity name" + assert_match "Invalid identity name" "$output" assert_command_fail dfx identity new 'iden\ttity' --storage-mode plaintext - assert_match "Invalid identity name" + assert_match "Invalid identity name" "$output" assert_command_fail dfx identity new iden/tity --storage-mode plaintext - assert_match "Invalid identity name" + assert_match "Invalid identity name" "$output" assert_command dfx identity new i_den.ti-ty --storage-mode plaintext @@ -156,7 +156,7 @@ teardown() { assert_eq '()' assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' # shellcheck disable=SC2154 - assert_eq '(blob "XWV")' "$stdout" + assert_eq '(blob "XWV")' } @test "after renaming an identity, the renamed identity is still initializer" { @@ -183,7 +183,7 @@ teardown() { assert_eq '()' assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' # shellcheck disable=SC2154 - assert_eq '(blob "hello")' "$stdout" + assert_eq '(blob "hello")' } @test "using an unencrypted identity on mainnet provokes a hard error which can be suppressed" { diff --git a/e2e/tests-dfx/identity_command.bash b/e2e/tests-dfx/identity_command.bash index 154637846a..38ffbb53a7 100644 --- a/e2e/tests-dfx/identity_command.bash +++ b/e2e/tests-dfx/identity_command.bash @@ -102,7 +102,7 @@ frank' @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_match "Identity already exists" "$output" } @test "identity new: --force re-creates an identity" { @@ -133,12 +133,12 @@ frank' @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_match "Key id must contain only hex digits" "$output" } @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_match "Key id must consist of an even number of hex digits" "$output" } @test "identity new: key is compatible with openssl" { @@ -204,9 +204,9 @@ default' 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_match "identity 'alice' on network 'ic' has wallet $WALLET" "$output" assert_command dfx identity remove alice --drop-wallets - assert_match "identity 'alice' on network 'ic' has wallet $WALLET" + assert_match "identity 'alice' on network 'ic' has wallet $WALLET" "$output" } @test "identity remove: cannot remove the non-default active identity" { @@ -226,7 +226,7 @@ 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" + assert_match "Cannot delete the default identity" "$output" } @@ -342,7 +342,7 @@ default' @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_match "Cannot create an anonymous identity" "$output" } @test "identity rename: can rename an HSM-backed identity" { @@ -412,14 +412,14 @@ 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_eq 'default' 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_eq 'default' assert_command dfx identity new charlie assert_command dfx identity whoami assert_eq 'default' @@ -432,7 +432,7 @@ default' @test "dfx identity whoami --identity (name): shows the overriding identity" { assert_command dfx identity whoami - assert_eq 'default' "$stdout" + assert_eq 'default' assert_command dfx identity new charlie assert_command dfx identity new alice assert_command dfx identity whoami --identity charlie @@ -443,7 +443,7 @@ default' @test "dfx (command) --identity does not persistently change the selected identity" { assert_command dfx identity whoami - assert_eq 'default' "$stdout" + assert_eq 'default' assert_command dfx identity new charlie assert_command dfx identity new alice assert_command dfx identity use charlie @@ -469,7 +469,7 @@ default' assert_command dfx identity whoami - assert_match "migrating key from" + assert_match "migrating key from" "$output" assert_eq "$(cat "$DFX_CONFIG_ROOT"/.config/dfx/identity/default/identity.pem)" "$ORIGINAL_KEY" } @@ -491,9 +491,9 @@ default' PRINCIPAL_1="$(dfx identity get-principal)" assert_command_fail dfx identity import alice identity2.pem - assert_match "Identity already exists." + assert_match "Identity already exists." "$output" assert_command dfx identity import --force alice identity2.pem - assert_match 'Imported identity: "alice".' + assert_match 'Imported identity: "alice".' "$output" PRINCIPAL_2="$(dfx identity get-principal)" assert_neq "$PRINCIPAL_1" "$PRINCIPAL_2" diff --git a/e2e/tests-dfx/info.bash b/e2e/tests-dfx/info.bash index 044fee6336..f9677f3946 100644 --- a/e2e/tests-dfx/info.bash +++ b/e2e/tests-dfx/info.bash @@ -28,10 +28,10 @@ teardown() { @test "displays the replica port" { assert_command_fail dfx info pocketic-config-port - assert_contains "No PocketIC port found" + assert_contains "No PocketIC port found" "$output" dfx_start assert_command_fail dfx info replica-port - assert_contains "Error: The 'native' replica (--replica) is no longer supported. If you intended to get the API port, use \`--webserver-port\`." + assert_contains "Error: The 'native' replica (--replica) is no longer supported. If you intended to get the API port, use \`--webserver-port\`." "$output" assert_command dfx info pocketic-config-port assert_eq "$(get_pocketic_port)" } @@ -63,15 +63,15 @@ teardown() { @test "displays Candid UI URL" { assert_command dfx info candid-ui-url --ic # shellcheck disable=SC2154 - assert_eq "https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/" "$stdout" + assert_eq "https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/" # Before deployment the UI canister does not exist yet assert_command_fail dfx info candid-ui-url - assert_contains "Candid UI not installed on network local." + assert_contains "Candid UI not installed on network local." "$output" dfx_start assert_command dfx deploy e2e_project_backend - assert_command dfx info candid-ui-url + assert_command dfx info candid-ui-url assert_eq "http://127.0.0.1:$(dfx info webserver-port)/?canisterId=$(dfx canister id __Candid_UI)" } @@ -121,5 +121,5 @@ teardown() { expected_id=$(cat <(crc32 <(base64 -d <<<"$expected_id64") | xxd -r -p) <(base64 -d <<<"$expected_id64") | base32 \ | tr -d = | tr '[:upper:]' '[:lower:]' | fold -w5 | paste -sd- -) assert_command dfx info default-effective-canister-id - assert_eq "$stdout" "$expected_id" + assert_eq "$expected_id" } diff --git a/e2e/tests-dfx/install.bash b/e2e/tests-dfx/install.bash index fa102c6606..c830f31ade 100644 --- a/e2e/tests-dfx/install.bash +++ b/e2e/tests-dfx/install.bash @@ -22,17 +22,17 @@ teardown() { assert_command dfx canister install --all assert_command dfx canister install --all --mode upgrade - assert_match "Module hash.*is already installed" + assert_match "Module hash.*is already installed" "$output" assert_command dfx canister install --all --mode upgrade --upgrade-unchanged --wasm-memory-persistence replace - assert_not_match "Module hash.*is already installed" + assert_not_match "Module hash.*is already installed" "$output" } @test "install fails if no argument is provided" { dfx_start assert_command_fail dfx canister install - assert_match "required arguments were not provided" - assert_match "--all" + assert_match "required arguments were not provided" "$output" + assert_match "--all" "$output" } @test "install succeeds when --all is provided" { @@ -42,7 +42,7 @@ teardown() { assert_command dfx canister install --all - assert_match "Installed code for canister e2e_project_backend" + assert_match "Installed code for canister e2e_project_backend" "$output" } @test "install succeeds with network name" { @@ -52,7 +52,7 @@ teardown() { assert_command dfx canister install --all --network local - assert_match "Installed code for canister e2e_project_backend" + assert_match "Installed code for canister e2e_project_backend" "$output" } @test "install fails with network name that is not in dfx.json" { @@ -62,7 +62,7 @@ teardown() { assert_command_fail dfx canister install --all --network nosuch - assert_match "Network not found.*nosuch" + assert_match "Network not found.*nosuch" "$output" } @test "install succeeds with arbitrary wasm" { @@ -285,14 +285,14 @@ teardown() { @test "installing multiple canisters with arguments fails" { assert_command_fail dfx canister install --all --argument '()' - assert_contains "error: the argument '--all' cannot be used with '--argument '" + assert_contains "error: the argument '--all' cannot be used with '--argument '" "$output" } @test "remind to build before install" { dfx_start dfx canister create --all assert_command_fail dfx canister install e2e_project_backend - assert_contains "The canister must be built before install. Please run \`dfx build\`." + assert_contains "The canister must be built before install. Please run \`dfx build\`." "$output" } @test "install succeeds if init_arg is defined in dfx.json" { @@ -304,14 +304,14 @@ teardown() { dfx build dependency assert_command dfx canister install dependency assert_command dfx canister call dependency greet - assert_match "Hello, dfx!" + assert_match "Hello, dfx!" "$output" assert_command dfx canister install dependency --mode reinstall --yes --argument '("icp")' - assert_contains "Canister 'dependency' has init_arg/init_arg_file in dfx.json: (\"dfx\")," - assert_contains "which is different from the one specified in the command line: (\"icp\")." - assert_contains "The command line value will be used." + assert_contains "Canister 'dependency' has init_arg/init_arg_file in dfx.json: (\"dfx\")," "$output" + assert_contains "which is different from the one specified in the command line: (\"icp\")." "$output" + assert_contains "The command line value will be used." "$output" assert_command dfx canister call dependency greet - assert_match "Hello, icp!" + assert_match "Hello, icp!" "$output" } @test "install succeeds if init_arg_file is defined in dfx.json" { @@ -342,7 +342,7 @@ teardown() { dfx build dependency assert_command_fail dfx canister install dependency assert_contains "At most one of the fields 'init_arg' and 'init_arg_file' should be defined in \`dfx.json\`. -Please remove one of them or leave both undefined." +Please remove one of them or leave both undefined." "$output" } @test "install succeeds when specify canister id and wasm, in dir without dfx.json" { @@ -386,9 +386,9 @@ Please remove one of them or leave both undefined." assert_command dfx canister install e2e_project_backend --mode upgrade --skip-pre-upgrade --wasm-memory-persistence keep assert_command_fail dfx canister install e2e_project_backend --mode install --skip-pre-upgrade - assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." + assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." "$output" assert_command_fail dfx canister install e2e_project_backend --mode reinstall --wasm-memory-persistence keep - assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." + assert_contains "--skip-pre-upgrade and --wasm-memory-persistence can only be used with mode 'upgrade' or 'auto'." "$output" } @test "Candid UI" { diff --git a/e2e/tests-dfx/ledger.bash b/e2e/tests-dfx/ledger.bash index 1b5c8a71d5..698c93857d 100644 --- a/e2e/tests-dfx/ledger.bash +++ b/e2e/tests-dfx/ledger.bash @@ -68,7 +68,7 @@ current_time_nanoseconds() { assert_eq "1000000.00000000 ICP" assert_command dfx ledger transfer --amount 100 --memo 1 "$BOB_ACCOUNT_ID" - assert_contains "Transfer sent at block height" + assert_contains "Transfer sent at block height" "$output" # The sender(alice) paid transaction fee which is 0.0001 ICP assert_command dfx ledger balance @@ -82,7 +82,7 @@ current_time_nanoseconds() { assert_eq "1000100.00000000 ICP" assert_command dfx ledger transfer --icp 100 --e8s 1 --memo 2 "$ALICE_ACCOUNT_ID" - assert_contains "Transfer sent at block height" + assert_contains "Transfer sent at block height" "$output" # The sender(bob) paid transaction fee which is 0.0001 ICP # 10100 - 100 - 0.0001 - 0.00000001 = 9999.99989999 @@ -96,7 +96,7 @@ current_time_nanoseconds() { # shellcheck disable=SC2154 block_height=$(echo "$stdout" | sed '1q' | sed 's/Transfer sent at block height //') # shellcheck disable=SC2154 - assert_eq "Transfer sent at block height $block_height" "$stdout" + assert_eq "Transfer sent at block height $block_height" assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time $((t+1)) "$ALICE_ACCOUNT_ID" # shellcheck disable=SC2154 @@ -106,8 +106,8 @@ current_time_nanoseconds() { assert_command dfx ledger transfer --icp 1 --memo 1 --created-at-time "$t" "$ALICE_ACCOUNT_ID" # shellcheck disable=SC2154 - assert_eq "transaction is a duplicate of another transaction in block $block_height" "$stderr" - assert_eq "Transfer sent at block height $block_height" "$stdout" + assert_contains "transaction is a duplicate of another transaction in block $block_height" "$stderr" + assert_eq "Transfer sent at block height $block_height" assert_command dfx ledger transfer --icp 1 --memo 2 --created-at-time "$t" "$ALICE_ACCOUNT_ID" # shellcheck disable=SC2154 @@ -132,7 +132,7 @@ current_time_nanoseconds() { # Test transfer and balance. assert_command dfx ledger transfer --amount 50 --to-principal "$DAVID" --memo 1 # to david - assert_contains "Transfer sent at block index" + assert_contains "Transfer sent at block index" "$output" # The owner(alice) transferred 50 ICP to david and paid transaction fee which is 0.0001 ICP. assert_command dfx ledger balance @@ -140,12 +140,12 @@ current_time_nanoseconds() { # The receiver(david) received 50 ICP. assert_command dfx ledger balance --of-principal "$DAVID" - assert_match "50.00000000 ICP" + assert_match "50.00000000 ICP" "$output" # Test approve, transfer-from and allowance. assert_command dfx ledger approve "$BOB" --amount 100 # to bob - assert_contains "Approval sent at block index" + assert_contains "Approval sent at block index" "$output" # The approver(alice) paid approving fee which is 0.0001 ICP. assert_command dfx ledger balance @@ -153,15 +153,15 @@ current_time_nanoseconds() { # The spender(bob) have 100 ICP allowance from the approver(alice). assert_command dfx ledger allowance --spender "$BOB" - assert_match "Allowance 100.00000000 ICP" + assert_match "Allowance 100.00000000 ICP" "$output" dfx identity use bob assert_command dfx ledger balance - assert_match "1000000.00000000 ICP" + assert_match "1000000.00000000 ICP" "$output" assert_command dfx ledger transfer-from --from "$ALICE" --amount 50 "$DAVID" # to david - assert_contains "Transfer sent at block index" + assert_contains "Transfer sent at block index" "$output" # The spender(bob) transferred 50 ICP to david from the approver(alice). # And the approver(alice) paid transaction fee which is 0.0001 ICP @@ -170,15 +170,15 @@ current_time_nanoseconds() { # The spender(bob) remains 49.99990000 ICP allowance from the approver(alice). assert_command dfx ledger allowance --owner "$ALICE" --spender "$BOB" - assert_match "Allowance 49.99990000 ICP" + assert_match "Allowance 49.99990000 ICP" "$output" # The spender(bob) balance is unchanged. assert_command dfx ledger balance --of-principal "$BOB" - assert_match "1000000.00000000 ICP" + assert_match "1000000.00000000 ICP" "$output" # The receiver(david) received 50 ICP. assert_command dfx ledger balance --of-principal "$DAVID" - assert_match "100.00000000 ICP" + assert_match "100.00000000 ICP" "$output" } @test "ledger subaccounts" { @@ -366,5 +366,5 @@ tc_to_num() { dfx_start assert_command_fail dfx ledger balance - assert_contains "ICP Ledger with canister ID 'ryjl3-tyaaa-aaaaa-aaaba-cai' is not installed." + assert_contains "ICP Ledger with canister ID 'ryjl3-tyaaa-aaaaa-aaaba-cai' is not installed." "$output" } diff --git a/e2e/tests-dfx/metadata.bash b/e2e/tests-dfx/metadata.bash index e88f866f19..e2e2c9ed10 100644 --- a/e2e/tests-dfx/metadata.bash +++ b/e2e/tests-dfx/metadata.bash @@ -72,13 +72,13 @@ teardown() { 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" + assert_match "Method new_method is only in the expected type" "$output" 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" + assert_match "int is not a subtype of nat" "$output" echo "adds private candid:service metadata if so configured" @@ -144,7 +144,7 @@ teardown() { assert_command dfx deploy assert_command dfx canister metadata gzipped arbitrary - assert_eq "$output" "arbitrary content" + assert_eq "arbitrary content" } @test "existence of build steps do not control custom canister metadata" { @@ -237,7 +237,7 @@ teardown() { echo "$stdout" > e.json assert_command jq -r '.tech_stack.lib | keys[]' e.json assert_eq "ic-cdk-timers -ic-stable-structures" +ic-stable-structures" "$output" # f defines all 5 categories assert_command dfx deploy f @@ -270,12 +270,12 @@ ic-stable-structures" # i defines a value_command that fails assert_command_fail dfx deploy i - assert_contains "Failed to run the value_command: language->rust->version." + assert_contains "Failed to run the value_command: language->rust->version." "$output" # j defines a value_command that returns a non-valid string echo -e "\xc3\x28" > invalid_utf8.txt assert_command_fail dfx deploy j - assert_contains "The value_command didn't return a valid UTF-8 string: language->rust->version." + assert_contains "The value_command didn't return a valid UTF-8 string: language->rust->version." "$output" # TODO: remove this when we have motoko extension # k is a motoko canister which doesn't define tech_stack diff --git a/e2e/tests-dfx/mode_reinstall.bash b/e2e/tests-dfx/mode_reinstall.bash index 65949b93d5..bb873ac75e 100644 --- a/e2e/tests-dfx/mode_reinstall.bash +++ b/e2e/tests-dfx/mode_reinstall.bash @@ -18,7 +18,7 @@ teardown() { 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." "$output" } @test "install --mode=reinstall fails if no canister is provided" { @@ -28,7 +28,7 @@ teardown() { assert_command_fail dfx canister install --mode=reinstall assert_match \ "error: the following required arguments were not provided: - --all" + --all" "$output" } @test "reinstall succeeds when a canister name is provided" { @@ -40,8 +40,8 @@ teardown() { echo yes | ( assert_command dfx canister install --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalled code for canister hello_backend" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_backend" "$output" ) } @@ -52,11 +52,11 @@ teardown() { 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" "$output" - assert_not_match "Installed code for canister" - assert_contains "Refusing to install canister without approval" - assert_contains "User declined consent" + assert_not_match "Installed code for canister" "$output" + assert_contains "Refusing to install canister without approval" "$output" + assert_contains "User declined consent" "$output" ) } @@ -64,7 +64,7 @@ teardown() { 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." "$output" } @test "deploy --mode=reinstall succeeds when a canister name is provided" { @@ -76,8 +76,8 @@ teardown() { echo yes | ( assert_command dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalled code for canister hello_backend" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_backend" "$output" ) } @@ -88,11 +88,11 @@ teardown() { 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" "$output" - assert_not_match "Installed code for canister" - assert_contains "Refusing to install canister without approval" - assert_contains "User declined consent" + assert_not_match "Installed code for canister" "$output" + assert_contains "Refusing to install canister without approval" "$output" + assert_contains "User declined consent" "$output" ) } @@ -120,10 +120,10 @@ teardown() { 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 "Reinstalled code for canister hello_frontend," + assert_match "You are about to reinstall the hello_frontend canister." "$output" + assert_not_match "You are about to reinstall the hello_backend canister." "$output" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_frontend," "$output" ) # the hello_backend canister should not have been upgraded (which would reset the non-stable var) @@ -140,25 +140,25 @@ teardown() { echo yes | ( assert_command dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalled code for canister hello_backend" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_backend" "$output" ) echo y | ( assert_command dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalled code for canister hello_backend" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_backend" "$output" ) echo YES | ( assert_command dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalled code for canister hello_backend" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_backend" "$output" ) echo YeS | ( assert_command dfx deploy --mode=reinstall hello_backend - assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" - assert_match "Reinstalled code for canister hello_backend" + assert_match "YOU WILL LOSE ALL DATA IN THE CANISTER" "$output" + assert_match "Reinstalled code for canister hello_backend" "$output" ) } diff --git a/e2e/tests-dfx/network.bash b/e2e/tests-dfx/network.bash index 7e152ca027..fe291b8a6f 100644 --- a/e2e/tests-dfx/network.bash +++ b/e2e/tests-dfx/network.bash @@ -26,7 +26,7 @@ teardown() { # 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" + assert_contains "Cannot find canister id" "$output" } @test "equivalent: --network ic and --ic" { @@ -100,16 +100,16 @@ teardown() { dfx identity get-wallet assert_command_fail dfx diagnose --network ic - assert_contains "The test_id identity is not stored securely." - assert_contains "in mainnet-facing commands" - assert_contains "you can suppress this warning" + assert_contains "The test_id identity is not stored securely." "$output" + assert_contains "in mainnet-facing commands" "$output" + assert_contains "you can suppress this warning" "$output" assert_command_fail dfx diagnose --ic - assert_contains "The test_id identity is not stored securely." - assert_contains "in mainnet-facing commands" - assert_contains "you can suppress this warning" + assert_contains "The test_id identity is not stored securely." "$output" + assert_contains "in mainnet-facing commands" "$output" + assert_contains "you can suppress this warning" "$output" assert_command dfx diagnose - assert_not_contains "identity is not stored securely" + assert_not_contains "identity is not stored securely" "$output" assert_eq "No problems found" } diff --git a/e2e/tests-dfx/new.bash b/e2e/tests-dfx/new.bash index 2011f78e7a..8ec113e66d 100644 --- a/e2e/tests-dfx/new.bash +++ b/e2e/tests-dfx/new.bash @@ -45,10 +45,10 @@ teardown() { @test "dfx new --type shows possible values" { assert_command_fail dfx new --type bad_type - assert_match "\[possible values.*motoko.*\]" - assert_match "\[possible values.*rust.*\]" - assert_match "\[possible values.*kybra.*\]" - assert_match "\[possible values.*azle.*\]" + assert_match "\[possible values.*motoko.*\]" "$output" + assert_match "\[possible values.*rust.*\]" "$output" + assert_match "\[possible values.*kybra.*\]" "$output" + assert_match "\[possible values.*azle.*\]" "$output" } @test "dfx new readmes contain appropriate links" { @@ -155,28 +155,28 @@ EOF # neither node nor npm are installed (no binaries) PATH="/usr/bin:/bin:$DFX_ONLY_DIR" \ assert_command dfx new e2e_project1 --type motoko --frontend sveltekit - assert_contains "Node could not be found. Skipping installing the frontend example code." - assert_contains "npm could not be found. Skipping installing the frontend example code." - assert_contains "You can bypass this check by using the --frontend flag." + assert_contains "Node could not be found. Skipping installing the frontend example code." "$output" + assert_contains "npm could not be found. Skipping installing the frontend example code." "$output" + assert_contains "You can bypass this check by using the --frontend flag." "$output" # node is installable, but not installed PATH="/usr/bin:/bin:$DFX_ONLY_DIR:$NODE_INSTALLABLE_DIR" \ assert_command dfx new e2e_project2 --type motoko --frontend sveltekit - assert_contains "Node could not be found. Skipping installing the frontend example code." - assert_contains "npm could not be found. Skipping installing the frontend example code." - assert_contains "You can bypass this check by using the --frontend flag." + assert_contains "Node could not be found. Skipping installing the frontend example code." "$output" + assert_contains "npm could not be found. Skipping installing the frontend example code." "$output" + assert_contains "You can bypass this check by using the --frontend flag." "$output" # node is installed, but there is no npm binary PATH="/usr/bin:/bin:$DFX_ONLY_DIR:$NODE_ONLY_DIR" \ assert_command dfx new e2e_project3 --type motoko --frontend sveltekit - assert_not_contains "Node could not be found" - assert_contains "npm could not be found. Skipping installing the frontend example code." - assert_contains "You can bypass this check by using the --frontend flag." + assert_not_contains "Node could not be found" "$output" + assert_contains "npm could not be found. Skipping installing the frontend example code." "$output" + assert_contains "You can bypass this check by using the --frontend flag." "$output" # node is installed; npm is not, but a stub reports that it is installable PATH="/usr/bin:/bin:$DFX_ONLY_DIR:$NODE_ONLY_DIR:$NPM_INSTALLABLE_DIR" \ assert_command dfx new e2e_project4 --type motoko --frontend sveltekit - assert_not_contains "Node could not be found" - assert_contains "npm could not be found. Skipping installing the frontend example code." - assert_contains "You can bypass this check by using the --frontend flag." + assert_not_contains "Node could not be found" "$output" + assert_contains "npm could not be found. Skipping installing the frontend example code." "$output" + assert_contains "You can bypass this check by using the --frontend flag." "$output" } diff --git a/e2e/tests-dfx/packtool.bash b/e2e/tests-dfx/packtool.bash index 60b8276f18..20ac8fb3e3 100644 --- a/e2e/tests-dfx/packtool.bash +++ b/e2e/tests-dfx/packtool.bash @@ -20,7 +20,7 @@ teardown() { dfx_start dfx canister create --all assert_command_fail dfx build - assert_match 'import error \[M0010\], package "(rate|describe)" not defined' + assert_match 'import error \[M0010\], package "(rate|describe)" not defined' "$output" } @test "build succeeds if packtool is configured" { @@ -76,9 +76,9 @@ teardown() { 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\)' + assert_match 'Failed to invoke the package tool' "$output" + assert_match 'no-such-command.*that.*command.*cannot.*be.*invoked' "$output" + assert_match 'No such file or directory \(os error 2\)' "$output" } @test "failure in execution reports the command line and exit code" { @@ -88,7 +88,7 @@ teardown() { 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' + assert_match 'The command.*failed' "$output" + assert_match 'sh.*command-that-fails.bash' "$output" + assert_match 'exit (code|status): 3' "$output" } diff --git a/e2e/tests-dfx/playground.bash b/e2e/tests-dfx/playground.bash index 6484b47849..681f509708 100644 --- a/e2e/tests-dfx/playground.bash +++ b/e2e/tests-dfx/playground.bash @@ -54,13 +54,13 @@ setup_playground() { assert_command dfx deploy --playground assert_command dfx canister --playground call hello_backend greet '("player")' - assert_match "Hello, player!" + assert_match "Hello, player!" "$output" CANISTER=$(dfx canister --playground id hello_backend) assert_command_fail dfx canister --playground stop hello_backend - assert_match "Canisters borrowed from a playground cannot be stopped." + assert_match "Canisters borrowed from a playground cannot be stopped." "$output" assert_command_fail dfx canister stop "${CANISTER}" - assert_match "The principal you are using to call a management function is not part of the controllers." + assert_match "The principal you are using to call a management function is not part of the controllers." "$output" if [ "$(uname)" == "Darwin" ]; then sed -i '' 's/Hello/Goodbye/g' src/hello_backend/main.mo @@ -70,7 +70,7 @@ setup_playground() { assert_command dfx deploy --playground assert_command dfx canister --playground call hello_backend greet '("player")' - assert_match "Goodbye, player!" + assert_match "Goodbye, player!" "$output" assert_command dfx canister --playground delete hello_backend assert_command_fail dfx canister --playground info hello_backend @@ -94,14 +94,14 @@ setup_playground() { @test "Handle timeout correctly" { assert_command dfx canister create hello_backend --playground -vv - assert_match "Reserved canister 'hello_backend'" + assert_match "Reserved canister 'hello_backend'" "$output" assert_command dfx canister create hello_backend --playground -vv - assert_match "hello_backend canister was already created" + assert_match "hello_backend canister was already created" "$output" sleep 10 jq '.playground.playground.timeout_seconds=5' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" assert_command dfx canister create hello_backend --playground -vv - assert_match "Canister 'hello_backend' has timed out." - assert_match "Reserved canister 'hello_backend'" + assert_match "Canister 'hello_backend' has timed out." "$output" + assert_match "Reserved canister 'hello_backend'" "$output" } # This is important for whitelisting wasm hashes in the playground. diff --git a/e2e/tests-dfx/project_local_network.bash b/e2e/tests-dfx/project_local_network.bash index ee80fcde44..df98ca5f03 100644 --- a/e2e/tests-dfx/project_local_network.bash +++ b/e2e/tests-dfx/project_local_network.bash @@ -159,7 +159,7 @@ teardown() { # 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)" + assert_match "$(jq -r .hello_backend.actuallylocal <.dfx/actuallylocal/canister_ids.json)" "$output" } @@ -171,11 +171,11 @@ teardown() { mv .dfx/network/local/pid .dfx/pid assert_command_fail dfx start - assert_match 'dfx is already running' + assert_match 'dfx is already running' "$output" assert_command dfx stop assert_file_not_exists .dfx/pid - assert_not_match "Nothing to do" + assert_not_match "Nothing to do" "$output" assert_command dfx stop - assert_match "Nothing to do" + assert_match "Nothing to do" "$output" } diff --git a/e2e/tests-dfx/remote.bash b/e2e/tests-dfx/remote.bash index 105a35e53f..270fb125ef 100644 --- a/e2e/tests-dfx/remote.bash +++ b/e2e/tests-dfx/remote.bash @@ -82,15 +82,15 @@ teardown() { # 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_match 'not a query method' "$output" 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' + assert_match 'not a query method' "$output" # 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_match 'not a query method' "$output" 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' + assert_match 'not a query method' "$output" } @test "canister create fails for a remote canister" { @@ -112,7 +112,7 @@ teardown() { 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_match "Canister 'remote' is a remote canister on network 'actuallylocal', and cannot be created from here." "$output" } @test "canister install fails for a remote canister" { @@ -134,7 +134,7 @@ teardown() { 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_match "Canister 'remote' is a remote canister on network 'actuallylocal', and cannot be installed from here." "$output" } @test "all commands with --all skip remote canisters" { @@ -175,7 +175,7 @@ teardown() { assert_command dfx canister create --all --network actuallylocal assert_command dfx build --network actuallylocal -vv - assert_match "Not building canister 'remote'" + assert_match "Not building canister 'remote'" "$output" assert_command dfx canister install --all --network actuallylocal assert_command dfx canister call basic read_remote --network actuallylocal @@ -202,30 +202,30 @@ teardown() { assert_eq "null" assert_command dfx ledger fabricate-cycles --all --t 100 --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" assert_command dfx canister status --all --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" assert_command dfx canister update-settings --log-visibility public --all --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" assert_command dfx canister stop --all --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" assert_command dfx canister start --all --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" # have to stop to uninstall assert_command dfx canister stop --all --network actuallylocal assert_command dfx canister uninstall-code --all --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" assert_command dfx build --all --network actuallylocal assert_command dfx canister delete --all --network actuallylocal - assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" + assert_contains "Skipping canister 'remote' because it is remote for network 'actuallylocal'" "$output" # Assert frontend declarations are actually created dfx generate @@ -310,7 +310,7 @@ teardown() { assert_eq '("mock")' assert_command dfx deploy --network actuallylocal -vv - assert_match "Not building canister 'remote'" + assert_match "Not building canister 'remote'" "$output" assert_command dfx canister call basic read_remote --network actuallylocal assert_eq '("this is data in the remote canister")' diff --git a/e2e/tests-dfx/remote_generate_binding.bash b/e2e/tests-dfx/remote_generate_binding.bash index d29c16fe70..c44469e410 100644 --- a/e2e/tests-dfx/remote_generate_binding.bash +++ b/e2e/tests-dfx/remote_generate_binding.bash @@ -103,7 +103,7 @@ teardown() { # should not overwrite without --overwrite assert_command dfx remote generate-binding remote-motoko - assert_match 'already exists' + assert_match 'already exists' "$output" assert_eq "to_overwrite" "$(cat remote.mo)" # should overwrite with --overwrite diff --git a/e2e/tests-dfx/request_status.bash b/e2e/tests-dfx/request_status.bash index 0a5cfb7197..b050170e82 100644 --- a/e2e/tests-dfx/request_status.bash +++ b/e2e/tests-dfx/request_status.bash @@ -44,7 +44,7 @@ teardown() { REQUEST_ID="$stdout" assert_command_fail dfx canister request-status "$REQUEST_ID" "$(dfx canister id hello_backend)" --identity anonymous - assert_contains "The user tries to access Request ID not signed by the caller" + assert_contains "The user tries to access Request ID not signed by the caller" "$output" assert_command dfx canister request-status "$REQUEST_ID" "$(dfx canister id hello_backend)" assert_eq '("Hello, Bob!")' diff --git a/e2e/tests-dfx/rust.bash b/e2e/tests-dfx/rust.bash index 29f3f627fe..ea4dc1ec41 100644 --- a/e2e/tests-dfx/rust.bash +++ b/e2e/tests-dfx/rust.bash @@ -19,10 +19,10 @@ teardown() { dfx_start dfx canister create --all assert_command dfx build hello_backend -vvv - assert_match "Shrinking Wasm" + assert_match "Shrinking Wasm" "$output" assert_command dfx canister install hello_backend assert_command dfx canister call hello_backend greet dfinity - assert_match '("Hello, dfinity!")' + assert_match '("Hello, dfinity!")' "$output" # dfx sets the candid:service metadata dfx canister metadata hello_backend candid:service >installed.did diff --git a/e2e/tests-dfx/shared_local_network.bash b/e2e/tests-dfx/shared_local_network.bash index c1a82364a7..64a2fcfd7a 100644 --- a/e2e/tests-dfx/shared_local_network.bash +++ b/e2e/tests-dfx/shared_local_network.bash @@ -109,7 +109,7 @@ teardown() { ( cd hello assert_command_fail dfx diagnose - assert_match "No wallet found; nothing to do" + assert_match "No wallet found; nothing to do" "$output" ) } diff --git a/e2e/tests-dfx/sign_send.bash b/e2e/tests-dfx/sign_send.bash index 5a828eb052..724dc07b2b 100644 --- a/e2e/tests-dfx/sign_send.bash +++ b/e2e/tests-dfx/sign_send.bash @@ -20,24 +20,25 @@ teardown() { dfx deploy assert_command dfx canister sign --query hello_backend read - assert_eq "Query message generated at [message.json]" + assert_contains "Query message generated at [message.json]" "$output" 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." + # shellcheck disable=SC2154 + assert_contains "Error: Can only check request_status on update calls." "$stderr" 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_contains "Error: [message.json] already exists, please specify a different output file name." "$stderr" assert_command dfx canister sign --update hello_backend inc --file message-inc.json - assert_eq "Update and request_status message generated at [message-inc.json]" + assert_contains "Update and request_status message generated at [message-inc.json]" "$output" sleep 10 echo y | assert_command dfx canister send message-inc.json assert_command dfx canister send message-inc.json --status - assert_match "Response:" + assert_match "Response:" "$output" } @test "sign outside of a dfx project" { @@ -47,7 +48,7 @@ teardown() { # suppress the error export DFX_WARNING=-mainnet_plaintext_identity assert_command dfx canister sign --query rwlgt-iiaaa-aaaaa-aaaaa-cai read --network ic - assert_match "Query message generated at \[message.json\]" + assert_contains "Query message generated at [message.json]" "$output" } @test "sign subcommand accepts argument from a file" { @@ -58,10 +59,10 @@ teardown() { 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_contains "Query message generated at [message.json]" "$output" 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_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]" "$output" rm "$TMP_NAME_FILE" } @@ -74,10 +75,10 @@ teardown() { 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_contains "Query message generated at [message.json]" "$output" assert_command jq -rc .arg message.json - assert_match "[68,73,68,76,0,1,113,5,115,116,100,105,110]" + assert_match "[68,73,68,76,0,1,113,5,115,116,100,105,110]" "$output" rm "$TMP_NAME_FILE" } diff --git a/e2e/tests-dfx/start.bash b/e2e/tests-dfx/start.bash index f56da51aa3..37e385edd5 100644 --- a/e2e/tests-dfx/start.bash +++ b/e2e/tests-dfx/start.bash @@ -79,7 +79,7 @@ teardown() { @test "start and stop outside project" { assert_command dfx_start - assert_contains "Replica API running in the background" + assert_contains "Replica API running in the background" "$output" mkdir subdir cd subdir || exit 1 @@ -88,13 +88,13 @@ teardown() { CANISTER_ID="$(dfx canister id e2e_project_backend)" cd .. assert_command dfx canister status "$CANISTER_ID" - assert_contains "Status: Running" + assert_contains "Status: Running" "$output" assert_command dfx canister stop "$CANISTER_ID" assert_command dfx canister status "$CANISTER_ID" - assert_contains "Status: Stopped" + assert_contains "Status: Stopped" "$output" assert_command dfx canister start "$CANISTER_ID" assert_command dfx canister status "$CANISTER_ID" - assert_contains "Status: Running" + assert_contains "Status: Running" "$output" } @test "uninstall-code outside of a project" { @@ -107,11 +107,11 @@ teardown() { CANISTER_ID="$(dfx canister id e2e_project_backend)" cd .. assert_command dfx canister status "$CANISTER_ID" - assert_contains "Module hash: 0x" + assert_contains "Module hash: 0x" "$output" assert_command dfx canister uninstall-code "$CANISTER_ID" - assert_contains "Uninstalling code for canister $CANISTER_ID" + assert_contains "Uninstalling code for canister $CANISTER_ID" "$output" assert_command dfx canister status "$CANISTER_ID" - assert_contains "Module hash: None" + assert_contains "Module hash: None" "$output" } @test "pocket-ic proxy domain configuration in string form" { @@ -216,7 +216,7 @@ teardown() { jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json assert_command dfx start --background -v - assert_match "subnet type: Application" + assert_match "subnet type: Application" "$output" } @test "dfx starts pocketic with subnet type verifiedapplication - project defaults" { @@ -225,7 +225,7 @@ teardown() { jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json assert_command dfx start --background -v - assert_match "subnet type: VerifiedApplication" + assert_match "subnet type: VerifiedApplication" "$output" } @test "dfx starts pocketic with subnet type system - project defaults" { @@ -234,7 +234,7 @@ teardown() { jq '.defaults.replica.log_level="info"' dfx.json | sponge dfx.json assert_command dfx start --background -v - assert_match "subnet type: System" + assert_match "subnet type: System" "$output" } @test "dfx starts pocketic with subnet type application - local network" { @@ -243,7 +243,7 @@ teardown() { jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json assert_command dfx start --background -v - assert_match "subnet type: Application" + assert_match "subnet type: Application" "$output" } @test "dfx starts pocketic with subnet type verifiedapplication - local network" { @@ -252,7 +252,7 @@ teardown() { jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json assert_command dfx start --background -v - assert_match "subnet type: VerifiedApplication" + assert_match "subnet type: VerifiedApplication" "$output" } @test "dfx starts pocketic with subnet type system - local network" { @@ -261,7 +261,7 @@ teardown() { jq '.networks.local.replica.log_level="info"' dfx.json | sponge dfx.json assert_command dfx start --background -v - assert_match "subnet type: System" + assert_match "subnet type: System" "$output" } @@ -270,7 +270,7 @@ teardown() { jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" assert_command dfx start --background -v - assert_match "subnet type: Application" + assert_match "subnet type: Application" "$output" } @test "dfx starts pocketic with subnet type verifiedapplication - shared network" { @@ -278,7 +278,7 @@ teardown() { jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" assert_command dfx start --background -v - assert_match "subnet type: VerifiedApplication" + assert_match "subnet type: VerifiedApplication" "$output" } @test "dfx starts pocketic with subnet type system - shared network" { @@ -286,7 +286,7 @@ teardown() { jq '.local.replica.log_level="info"' "$E2E_NETWORKS_JSON" | sponge "$E2E_NETWORKS_JSON" assert_command dfx start --background -v - assert_match "subnet type: System" + assert_match "subnet type: System" "$output" } @test "dfx start detects if dfx is already running - shared network" { @@ -294,7 +294,7 @@ teardown() { dfx_start assert_command_fail dfx start - assert_match "dfx is already running" + assert_match "dfx is already running" "$output" } @test "dfx start for shared network warns about default settings specified in dfx.json that do not apply" { @@ -306,31 +306,31 @@ teardown() { 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_contains "$IGNORED_MESSAGE" "$output" + assert_match "$APPLY_SETTINGS_MESSAGE" "$output" + assert_contains '"bitcoin": {' "$output" + assert_not_contains '"replica"' "$output" + assert_not_contains '"canister_http"' "$output" 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_contains "$IGNORED_MESSAGE" "$output" + assert_match "$APPLY_SETTINGS_MESSAGE" "$output" + assert_not_contains '"bitcoin"' "$output" + assert_contains '"replica": {' "$output" + assert_not_contains '"canister_http"' "$output" 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_contains "$IGNORED_MESSAGE" "$output" + assert_match "$APPLY_SETTINGS_MESSAGE" "$output" + assert_not_contains '"bitcoin"' "$output" + assert_not_contains '"replica"' "$output" + assert_contains '"canister_http": {' "$output" assert_command dfx stop jq 'del(.defaults)' dfx.json | sponge dfx.json @@ -338,11 +338,11 @@ teardown() { 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_contains "$IGNORED_MESSAGE" "$output" + assert_match "$APPLY_SETTINGS_MESSAGE" "$output" + assert_contains '"bitcoin": {' "$output" + assert_contains '"replica": {' "$output" + assert_contains '"canister_http": {' "$output" assert_command dfx stop } @@ -352,12 +352,12 @@ teardown() { define_project_network assert_command dfx start --background --verbose - assert_match "log level: Warning" + assert_match "log level: Warning" "$output" 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" + assert_match "log level: Critical" "$output" } @test "dfx starts pocketic with correct log level - local network" { @@ -366,12 +366,12 @@ teardown() { define_project_network assert_command dfx start --background --verbose - assert_match "log level: Warning" + assert_match "log level: Warning" "$output" 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" + assert_match "log level: Critical" "$output" } @test "dfx starts pocketic with correct log level - shared network" { @@ -380,12 +380,12 @@ teardown() { 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_match "log level: Warning" "$output" 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" + assert_match "log level: Critical" "$output" } @test "debug print statements work with default log level" { @@ -396,7 +396,7 @@ teardown() { assert_command dfx canister call e2e_project hello sleep 2 run tail -2 stderr.txt - assert_match "Hello, World! from DFINITY" + assert_match "Hello, World! from DFINITY" "$output" } # Disabled: each test has multiple dfx start/stop cycles, each taking ~1 min, diff --git a/e2e/tests-dfx/upgrade_check.bash b/e2e/tests-dfx/upgrade_check.bash index 9b5068f460..67d7cab804 100644 --- a/e2e/tests-dfx/upgrade_check.bash +++ b/e2e/tests-dfx/upgrade_check.bash @@ -33,7 +33,7 @@ teardown() { jq '.canisters.hello_backend.main="v2_bad.mo"' dfx.json | sponge dfx.json echo yes | ( assert_command_fail dfx deploy - assert_match "Stable interface compatibility check issued an ERROR" + assert_match "Stable interface compatibility check issued an ERROR" "$output" ) } @@ -57,10 +57,10 @@ teardown() { 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_match "Candid interface compatibility check failed" "$output" ) assert_command dfx canister call hello_backend read2 '()' - assert_match "(1 : int)" + assert_match "(1 : int)" "$output" } @test "warning for using special opt rule" { @@ -71,10 +71,10 @@ teardown() { jq '.canisters.hello_backend.main="v4_bad.mo"' dfx.json | sponge dfx.json echo yes | ( assert_command dfx deploy - assert_match "Candid interface compatibility check failed" + assert_match "Candid interface compatibility check failed" "$output" ) assert_command dfx canister call hello_backend f '()' - assert_match "(opt \"\")" + assert_match "(opt \"\")" "$output" } @test "error when dropping stable variable" { @@ -85,6 +85,6 @@ teardown() { jq '.canisters.hello_backend.main="v5.mo"' dfx.json | sponge dfx.json echo yes | ( assert_command_fail dfx deploy - assert_match "Stable interface compatibility check issued an ERROR" + assert_match "Stable interface compatibility check issued an ERROR" "$output" ) } diff --git a/e2e/tests-dfx/usage.bash b/e2e/tests-dfx/usage.bash index 0ece968beb..b95b91c06d 100644 --- a/e2e/tests-dfx/usage.bash +++ b/e2e/tests-dfx/usage.bash @@ -29,7 +29,7 @@ teardown() { @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_match "Cannot find dfx configuration file in the current working directory. Did you forget to create one?" "$output" dfx new t --no-frontend cd t @@ -70,5 +70,5 @@ teardown() { dfx canister call e2e_project hello sleep 2 run tail -2 stderr.txt - assert_match "Hello, World! from DFINITY" + assert_match "Hello, World! from DFINITY" "$output" } diff --git a/e2e/tests-dfx/wallet.bash b/e2e/tests-dfx/wallet.bash index 5a073aa943..4801010f6a 100644 --- a/e2e/tests-dfx/wallet.bash +++ b/e2e/tests-dfx/wallet.bash @@ -15,16 +15,16 @@ teardown() { @test "error reporting for --wallet parameter" { dfx_start assert_command_fail dfx canister call hello_backend greet '' --with-cycles 100 --wallet "abc-def" - assert_contains "Failed to read principal from id 'abc-def', and did not find a wallet for that identity" - assert_contains "Text must be in valid Base32 encoding" + assert_contains "Failed to read principal from id 'abc-def', and did not find a wallet for that identity" "$output" + assert_contains "Text must be in valid Base32 encoding" "$output" assert_command_fail dfx canister call hello_backend greet '' --with-cycles 100 --wallet "alice" - assert_contains "Failed to read principal from id 'alice', and did not find a wallet for that identity" + assert_contains "Failed to read principal from id 'alice', and did not find a wallet for that identity" "$output" echo "{}" > "$(shared_wallets_json)" assert_command_fail dfx canister call hello_backend greet '' --with-cycles 100 --wallet broken - assert_contains "Failed to read principal from id 'broken' (Text must be in valid Base32 encoding.), and failed to load the wallet for that identity" - assert_contains "missing field \`identities\`" + assert_contains "Failed to read principal from id 'broken' (Text must be in valid Base32 encoding.), and failed to load the wallet for that identity" "$output" + assert_contains "missing field \`identities\`" "$output" } @@ -34,7 +34,7 @@ teardown() { dfx_new assert_command dfx deploy assert_command dfx canister deposit-cycles 47 e2e_project_backend - assert_contains "Deposited 47 cycles" + assert_contains "Deposited 47 cycles" "$output" } @test "deposit cycles outside a project" { @@ -47,7 +47,7 @@ teardown() { CANISTER_ID="$(dfx canister id e2e_project_backend)" cd .. assert_command dfx canister deposit-cycles 42 "$CANISTER_ID" - assert_contains "Deposited 42 cycles" + assert_contains "Deposited 42 cycles" "$output" } @test "DFX_WALLET_WASM environment variable overrides wallet module wasm at installation" { @@ -59,20 +59,20 @@ teardown() { 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" + assert_match "Using wasm at path: .*/wallet/0.7.0/wallet.wasm" "$output" 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" + assert_match "Using wasm at path: .*/wallet/0.7.2/wallet.wasm" "$output" 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_match "Module hash: 0xa609400f2576d1d6df72ce868b359fd08e1d68e58454ef17db2361d2f1c242a1" "$output" assert_command dfx canister info "$BOB_WALLET" --identity bob - assert_match "Module hash: 0x1404b28b1c66491689b59e184a9de3c2be0dbdd75d952f29113b516742b7f898" + assert_match "Module hash: 0x1404b28b1c66491689b59e184a9de3c2be0dbdd75d952f29113b516742b7f898" "$output" } @test "DFX_WALLET_WASM environment variable overrides wallet module wasm for upgrade" { @@ -110,9 +110,9 @@ teardown() { 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_not_match "Setting wallet for identity" "$output" assert_command dfx identity set-wallet --force "${ID}" --network actuallylocal - assert_match "Setting wallet for identity 'default' on network 'actuallylocal' to id '$ID'" + assert_match "Setting wallet for identity 'default' on network 'actuallylocal' to id '$ID'" "$output" assert_command jq -r .identities.default.actuallylocal <"$DFX_CONFIG_ROOT"/.config/dfx/identity/default/wallets.json assert_eq "$ID" } @@ -142,7 +142,7 @@ teardown() { # 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." + assert_match "The wallet canister \"${ID_TWO}\"\ already exists for user \"default\" on \"actuallylocal\" network." "$output" } @test "wallet create wallet" { @@ -186,7 +186,7 @@ teardown() { 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)})" # shellcheck disable=SC2154 - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7e\01" } })' "$stdout" # True in DIDL. + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7e\01" } })' # True in DIDL. } @test "forward user call through wallet: deploy" { @@ -203,7 +203,7 @@ teardown() { 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)})" # shellcheck disable=SC2154 - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7e\01" } })' "$stdout" # True in DIDL. + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7e\01" } })' # True in DIDL. } @test "a 64-bit wallet can still be called in the 128-bit context" { @@ -239,7 +239,7 @@ teardown() { dfx_start 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." + assert_match "There is no wallet defined for identity 'default' on network 'local'. Nothing to do." "$output" } @test "creates new wallet if backend changes" { @@ -256,7 +256,7 @@ teardown() { @test "must run dfx start before accessing wallet on shared local network" { assert_command_fail dfx wallet upgrade - assert_contains "cannot use a wallet before dfx start" + assert_contains "cannot use a wallet before dfx start" "$output" } @test "redeem-faucet-coupon can set a new wallet and top up an existing one" { @@ -277,25 +277,25 @@ teardown() { # assert: no wallet configured export DFX_DISABLE_AUTO_WALLET=1 assert_command_fail dfx wallet balance - assert_match "No wallet configured" + assert_match "No wallet configured" "$output" assert_command dfx wallet redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'valid-coupon' --yes - assert_match "Redeemed coupon valid-coupon for a new wallet" - assert_match "New wallet set." + assert_match "Redeemed coupon valid-coupon for a new wallet" "$output" + assert_match "New wallet set." "$output" # 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\." + assert_match "99\.|100\." "$output" unset DFX_DISABLE_AUTO_WALLET assert_command dfx wallet redeem-faucet-coupon --faucet "$(dfx canister id faucet)" 'another-valid-coupon' --yes - assert_match "Redeemed coupon code another-valid-coupon for 10.000 TC" + assert_match "Redeemed coupon code another-valid-coupon for 10.000 TC" "$output" 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\." + assert_match "109\.|110\." "$output" } diff --git a/e2e/tests-dfx/wasm_memory_persistence.bash b/e2e/tests-dfx/wasm_memory_persistence.bash index 50aa71b05e..cce75a7e22 100644 --- a/e2e/tests-dfx/wasm_memory_persistence.bash +++ b/e2e/tests-dfx/wasm_memory_persistence.bash @@ -51,7 +51,7 @@ teardown() { dfx deploy jq '.canisters.test.wasm="classical-actor.wasm"' dfx.json | sponge dfx.json assert_command_fail dfx deploy - assert_match "The \`wasm_memory_persistence: opt Keep\` upgrade option requires that the new canister module supports enhanced orthogonal persistence." + assert_match "The \`wasm_memory_persistence: opt Keep\` upgrade option requires that the new canister module supports enhanced orthogonal persistence." "$output" } @test "re-install Motoko enhanced orthogonal persistence with classical persistence" { diff --git a/e2e/tests-icx-asset/icx-asset.bash b/e2e/tests-icx-asset/icx-asset.bash index 0915fe3ee6..5c86768654 100644 --- a/e2e/tests-icx-asset/icx-asset.bash +++ b/e2e/tests-icx-asset/icx-asset.bash @@ -58,9 +58,9 @@ icx_asset_upload() { icx_asset_list - assert_match "sample-asset.txt.*text/plain.*identity" - assert_match "notreally.js.*text/javascript.*gzip" - assert_match "notreally.js.*text/javascript.*identity" + assert_match "sample-asset.txt.*text/plain.*identity" "$output" + assert_match "notreally.js.*text/javascript.*gzip" "$output" + assert_match "notreally.js.*text/javascript.*identity" "$output" } @test "lists all assets when more than 100" { @@ -73,14 +73,14 @@ icx_asset_upload() { icx_asset_list # Verify we get assets from the first page - assert_match "test001.txt.*text/plain.*identity" - assert_match "test050.txt.*text/plain.*identity" - assert_match "test100.txt.*text/plain.*identity" - + assert_match "test001.txt.*text/plain.*identity" "$output" + assert_match "test050.txt.*text/plain.*identity" "$output" + assert_match "test100.txt.*text/plain.*identity" "$output" + # Verify we get assets from the second page (beyond first 100) - assert_match "test101.txt.*text/plain.*identity" - assert_match "test125.txt.*text/plain.*identity" - assert_match "test150.txt.*text/plain.*identity" + assert_match "test101.txt.*text/plain.*identity" "$output" + assert_match "test125.txt.*text/plain.*identity" "$output" + assert_match "test150.txt.*text/plain.*identity" "$output" # Count total number of test*.txt assets listed # shellcheck disable=SC2154 @@ -195,7 +195,7 @@ icx_asset_upload() { 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_match "Asset with key '/duplicate' defined at .*/e2e_project/multiple/b/duplicate and .*/e2e_project/multiple/a/duplicate" "$output" } @test "ignores filenames and directories starting with a dot" { @@ -233,17 +233,17 @@ icx_asset_upload() { icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" "$output" + assert_match " /b.txt.*text/plain.*identity" "$output" echo "ccc" >c.txt icx_asset_upload c.txt 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" "$output" + assert_match " /b.txt.*text/plain.*identity" "$output" + assert_match " /c.txt.*text/plain.*identity" "$output" } @test "deletes asset if necessary in order to change content type" { @@ -254,8 +254,8 @@ icx_asset_upload() { 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" "$output" + assert_match " /sample-asset.txt.*application/pdf.*arbitrary" "$output" echo "just some text" >sample-asset.txt @@ -264,8 +264,8 @@ icx_asset_upload() { 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" "$output" + assert_not_match " /sample-asset.txt.*application/pdf.*arbitrary" "$output" } @test "uploads multiple files" { @@ -278,8 +278,8 @@ icx_asset_upload() { 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" "$output" + assert_match " /b.txt.*text/plain.*identity" "$output" } @@ -291,8 +291,8 @@ icx_asset_upload() { 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" "$output" + assert_match " /b.txt.*text/plain.*identity" "$output" } @test "uploads a file by name" { @@ -302,7 +302,7 @@ icx_asset_upload() { icx_asset_list - assert_match " /uploaded.txt.*text/plain.*identity" + assert_match " /uploaded.txt.*text/plain.*identity" "$output" } @test "can override asset name" { @@ -312,7 +312,7 @@ icx_asset_upload() { icx_asset_list - assert_match " /abcd.txt.*text/plain.*identity" + assert_match " /abcd.txt.*text/plain.*identity" "$output" } @test "uploads a directory by name" { @@ -324,8 +324,8 @@ icx_asset_upload() { 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" "$output" + assert_match " /some_dir/b.txt.*text/plain.*identity" "$output" } @test "uploads a directory by name as root" { @@ -337,6 +337,6 @@ icx_asset_upload() { icx_asset_list - assert_match " /a.txt.*text/plain.*identity" - assert_match " /b.txt.*text/plain.*identity" + assert_match " /a.txt.*text/plain.*identity" "$output" + assert_match " /b.txt.*text/plain.*identity" "$output" } diff --git a/e2e/tests-replica/deploy.bash b/e2e/tests-replica/deploy.bash index 5ad367176c..f9e351a6de 100644 --- a/e2e/tests-replica/deploy.bash +++ b/e2e/tests-replica/deploy.bash @@ -27,8 +27,8 @@ teardown() { dfx_start install_asset greet assert_command dfx deploy hello_backend - assert_match 'Deploying: hello_backend' - assert_not_match 'hello_frontend' + assert_match 'Deploying: hello_backend' "$output" + assert_not_match 'hello_frontend' "$output" } @test "deploy a canister with dependencies" { @@ -36,21 +36,21 @@ teardown() { dfx_start install_asset greet assert_command dfx deploy hello_frontend - assert_match 'Deploying: hello_backend hello_frontend' + assert_match 'Deploying: hello_backend hello_frontend' "$output" } @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' + assert_match 'Deploying: canister_a canister_f canister_g canister_h' "$output" } @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' + assert_match 'canister_d -> canister_e -> canister_d' "$output" } @test "deploy with InstallMode::Install on an empty canister" { @@ -60,7 +60,7 @@ teardown() { assert_command dfx canister create --all assert_command dfx deploy - assert_match 'Installed code for canister' + assert_match 'Installed code for canister' "$output" } @test "dfx deploy supports arguments" { @@ -72,7 +72,7 @@ teardown() { assert_command dfx deploy hello_backend --argument '("World")' assert_command dfx canister call hello_backend greet - assert_match 'Hello, World' + assert_match 'Hello, World' "$output" } @test "dfx deploy with InstallMode::Install on first invocation, InstallMode::Upgrade on second" { @@ -85,13 +85,13 @@ teardown() { # Therefore, there is no "attempting (install|upgrade)" message. assert_command dfx deploy hello_backend - assert_match 'Installed code for canister' + assert_match 'Installed code for canister' "$output" assert_command dfx canister call hello_backend greet '("First")' assert_eq '("Hello, First!")' assert_command dfx deploy hello_backend --upgrade-unchanged - assert_match 'Upgraded code for canister' + assert_match 'Upgraded code for canister' "$output" assert_command dfx canister call hello_backend greet '("Second")' assert_eq '("Hello, Second!")' @@ -105,27 +105,27 @@ teardown() { dfx build dfx canister install hello_backend assert_command dfx canister status hello_backend - assert_match "Status: Running." + assert_match "Status: Running." "$output" # Stop assert_command dfx canister stop hello_backend assert_command dfx canister status hello_backend - assert_match "Status: Stopped." + assert_match "Status: Stopped." "$output" assert_command_fail dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' - assert_match "is stopped" + assert_match "is stopped" "$output" # Start assert_command dfx canister start hello_backend assert_command dfx canister status hello_backend - assert_match "Status: Running." + assert_match "Status: Running." "$output" # Call assert_command dfx canister call "$(dfx canister id hello_backend)" greet '("Names are difficult")' - assert_match '("Hello, Names are difficult!")' + assert_match '("Hello, Names are difficult!")' "$output" # Id assert_command dfx canister id hello_backend - assert_match "$(jq -r .hello_backend.local < .dfx/local/canister_ids.json)" + assert_match "$(jq -r .hello_backend.local < .dfx/local/canister_ids.json)" "$output" x="$(dfx canister id hello_backend)" local old_id="$x" @@ -134,10 +134,10 @@ teardown() { 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'." + assert_match "Cannot find canister id. Please issue 'dfx canister create hello_backend'." "$output" # Create again assert_command dfx canister create hello_backend assert_command dfx canister id hello_backend - assert_neq "$old_id" + assert_neq "$old_id" "$output" } diff --git a/e2e/utils/_.bash b/e2e/utils/_.bash index 95e3371d71..4a676bfa1f 100644 --- a/e2e/utils/_.bash +++ b/e2e/utils/_.bash @@ -195,7 +195,8 @@ dfx_set_wallet() { export WALLET_CANISTER_ID WALLET_CANISTER_ID=$(dfx identity get-wallet) assert_command dfx identity set-wallet "${WALLET_CANISTER_ID}" --force --network "${network}" - assert_match 'Wallet set successfully.' + # shellcheck disable=SC2154 + assert_match 'Wallet set successfully.' "$output" } shared_wallets_json() { diff --git a/e2e/utils/assertions.bash b/e2e/utils/assertions.bash index eb627337fe..5162421dc6 100644 --- a/e2e/utils/assertions.bash +++ b/e2e/utils/assertions.bash @@ -58,11 +58,11 @@ assert_command_fail() { # Arguments: # $1 - The regex to use to match. # $2 - The string to match against (output). By default it will use -# $output. +# $stdout. assert_match() { regex="$1" if [[ $# -lt 2 ]]; then - text="$output" + text="$stdout" else text="$2" fi @@ -80,7 +80,7 @@ assert_match() { assert_contains() { search_for="$1" if [[ $# -lt 2 ]]; then - search_in="$output" + search_in="$stdout" else search_in="$2" fi @@ -98,7 +98,7 @@ assert_contains() { assert_not_contains() { search_for="$1" if [[ $# -lt 2 ]]; then - search_in="$output" + search_in="$stdout" else search_in="$2" fi @@ -113,11 +113,11 @@ assert_not_contains() { # Arguments: # $1 - The regex to use to match. # $2 - The string to match against (output). By default it will use -# $output. +# $stdout. assert_not_match() { regex="$1" if [[ $# -lt 2 ]]; then - text="$output" + text="$stdout" else text="$2" fi @@ -132,12 +132,12 @@ assert_not_match() { # Arguments: # $1 - Expected number of occurrence. # $2 - The string to search for. -# $3 - The string to search in. By default it will use $output. +# $3 - The string to search in. By default it will use $stdout. assert_occurs() { expect="$1" search_for="$2" if [[ $# -lt 3 ]]; then - search_in="$output" + search_in="$stdout" else search_in="$3" fi @@ -164,7 +164,7 @@ assert_occurs() { assert_eq() { expected="$1" if [[ $# -lt 2 ]]; then - actual="$output" + actual="$stdout" else actual="$2" fi @@ -183,7 +183,7 @@ assert_eq() { assert_neq() { expected="$1" if [[ $# -lt 2 ]]; then - actual="$output" + actual="$stdout" else actual="$2" fi diff --git a/src/dfx/src/commands/canister/snapshot.rs b/src/dfx/src/commands/canister/snapshot.rs index f7d3f258c3..68c3c16b1d 100644 --- a/src/dfx/src/commands/canister/snapshot.rs +++ b/src/dfx/src/commands/canister/snapshot.rs @@ -227,8 +227,7 @@ async fn create( ) .await .with_context(|| format!("Failed to take snapshot of canister {canister}"))?; - info!( - env.get_logger(), + println!( "Created a new snapshot of canister {canister}. Snapshot ID: {}", SnapshotId(id.id) ); @@ -307,7 +306,7 @@ async fn list(env: &dyn Environment, canister: String, call_sender: &CallSender) .unwrap() )) }); - info!(env.get_logger(), "{snapshots}"); + println!("{snapshots}"); } Ok(()) } diff --git a/src/dfx/src/lib/warning.rs b/src/dfx/src/lib/warning.rs index fa7b4e3d03..6d5841808d 100644 --- a/src/dfx/src/lib/warning.rs +++ b/src/dfx/src/lib/warning.rs @@ -1,10 +1,12 @@ pub enum DfxWarning { MainnetPlainTextIdentity, + Deprecation, } pub fn is_warning_disabled(warning: DfxWarning) -> bool { let warning = match warning { DfxWarning::MainnetPlainTextIdentity => "mainnet_plaintext_identity", + DfxWarning::Deprecation => "deprecation", }; // By default, warnings are all enabled. let env_warnings = std::env::var("DFX_WARNING").unwrap_or_else(|_| "".to_string()); diff --git a/src/dfx/src/main.rs b/src/dfx/src/main.rs index 69bd20bbf3..cb9b19745a 100644 --- a/src/dfx/src/main.rs +++ b/src/dfx/src/main.rs @@ -6,8 +6,9 @@ use crate::lib::error::DfxResult; use crate::lib::logger::{LoggingMode, create_root_logger}; use crate::lib::project::templates::builtin_templates; use crate::lib::telemetry::Telemetry; +use crate::lib::warning::{DfxWarning, is_warning_disabled}; use anyhow::Error; -use clap::{ArgAction, CommandFactory, Parser}; +use clap::{ArgAction, CommandFactory, FromArgMatches, Parser}; use dfx_core::config::model::dfinity::ToolConfig; use dfx_core::config::project_templates; use dfx_core::extension::installed::InstalledExtensionManifests; @@ -130,6 +131,17 @@ fn print_error_and_diagnosis(log_level: Option, err: Error, error_diagnosis } } +const DEPRECATION_NOTICE: &str = "WARNING: dfx is deprecated, use icp-cli https://cli.internetcomputer.org. LLM skills can be found at https://skills.internetcomputer.org/llms.txt"; + +fn add_deprecation_notices(cmd: &mut clap::Command) { + *cmd = cmd.clone().before_help(DEPRECATION_NOTICE); + for subcmd in cmd.get_subcommands_mut() { + if subcmd.get_name() != "extension" { + add_deprecation_notices(subcmd); + } + } +} + fn get_args_altered_for_extension_run( installed: &InstalledExtensionManifests, ) -> DfxResult> { @@ -168,7 +180,14 @@ fn inner_main(log_level: &mut Option) -> DfxResult { Telemetry::set_platform(); Telemetry::set_week(); - let cli_opts = CliOpts::parse_from(args); + let cli_opts = { + let mut cmd = CliOpts::command(); + if !is_warning_disabled(DfxWarning::Deprecation) { + add_deprecation_notices(&mut cmd); + } + let matches = cmd.get_matches_from(&args); + CliOpts::from_arg_matches(&matches).unwrap_or_else(|e| e.exit()) + }; if matches!( cli_opts.command, @@ -193,6 +212,13 @@ fn inner_main(log_level: &mut Option) -> DfxResult { env.get_logger(), "Trace mode enabled. Lots of logs coming up." ); + + if !matches!(cli_opts.command, commands::DfxCommand::Extension(_)) + && !is_warning_disabled(DfxWarning::Deprecation) + { + eprintln!("{DEPRECATION_NOTICE}"); + } + commands::exec(&env, cli_opts.command) }