From 7116df42538064da53288893eeee84163d320f1f Mon Sep 17 00:00:00 2001 From: xunilrj Date: Mon, 1 Sep 2025 08:21:49 -0300 Subject: [PATCH 1/5] first version of the justfile --- test/src/e2e_vm_tests/mod.rs | 14 +++++++++++++- test/src/main.rs | 6 ++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index c3e1ac33ba0..87fd2360a36 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -669,9 +669,18 @@ impl TestContext { result.map(|tested_pkgs| { let mut failed = vec![]; for pkg in tested_pkgs { + if !pkg.tests.is_empty() { + println!(); + } for test in pkg.tests.into_iter() { if verbose { - println!("Test: {} {}", test.name, test.passed()); + //"test incorrect_def_modeling ... ok (17.673µs, 59 gas)" + println!(" test {} ... {} ({:?}, {} gas)", + test.name, + if test.passed() { "ok" } else { "nok" }, + test.duration, + test.gas_used, + ); for log in test.logs.iter() { println!("{log:?}"); } @@ -782,6 +791,9 @@ pub async fn run(filter_config: &FilterConfig, run_config: &RunConfig) -> Result if filter_config.contract_only { tests.retain(|t| t.category == TestCategory::RunsWithContract); } + if filter_config.forc_test_only { + tests.retain(|t| t.category == TestCategory::UnitTestsPass); + } if filter_config.first_only && !tests.is_empty() { tests = vec![tests.remove(0)]; } diff --git a/test/src/main.rs b/test/src/main.rs index 1c6c4ba6282..b08bb59fbb6 100644 --- a/test/src/main.rs +++ b/test/src/main.rs @@ -38,6 +38,10 @@ struct Cli { #[arg(long, visible_alias = "contract")] contract_only: bool, + /// Only run tests that run "forc test" + #[arg(long, visible_alias = "forc-test")] + forc_test_only: bool, + /// Only run the first test #[arg(long, visible_alias = "first")] first_only: bool, @@ -136,6 +140,7 @@ pub struct FilterConfig { pub exclude_std: bool, pub contract_only: bool, pub first_only: bool, + pub forc_test_only: bool, } #[derive(Debug, Clone)] @@ -165,6 +170,7 @@ async fn main() -> Result<()> { abi_only: cli.abi_only, exclude_std: cli.exclude_std, contract_only: cli.contract_only, + forc_test_only: cli.forc_test_only, first_only: cli.first_only, }; let build_target = match cli.build_target { From 051c5860417dea619ab8be0fe52bb5cf0305a16d Mon Sep 17 00:00:00 2001 From: xunilrj Date: Mon, 1 Sep 2025 08:22:16 -0300 Subject: [PATCH 2/5] first version of the justfile --- justfile | 48 ++++++ scripts/bisect-forc/README.md | 17 ++ scripts/bisect-forc/bisect-forc.sh | 162 ++++++++++++++++++ .../compare-gas-usage/extract-gas-usage.sh | 26 +++ scripts/compare-gas-usage/generate-diff.sh | 38 ++++ 5 files changed, 291 insertions(+) create mode 100644 justfile create mode 100644 scripts/bisect-forc/README.md create mode 100755 scripts/bisect-forc/bisect-forc.sh create mode 100755 scripts/compare-gas-usage/extract-gas-usage.sh create mode 100755 scripts/compare-gas-usage/generate-diff.sh diff --git a/justfile b/justfile new file mode 100644 index 00000000000..5322360bd72 --- /dev/null +++ b/justfile @@ -0,0 +1,48 @@ +[group('ci')] +[confirm("Do you want to install cargo-sort, cargo-generate and cargo-udeps from crates.io?")] +install-ci-check: + cargo install cargo-sort + cargo install cargo-generate + cargo install cargo-udeps + +[group('ci')] +ci-check: + bash ./ci_checks.sh + +[group('automation')] +[confirm("Do you want to bump all fuel maintained dependencies?")] +update-fuel-dependencies: + bash ./update_fuel_dependencies.sh + +[group('automation')] +[confirm("Do you want to automatically update contractIds in this repo?")] +update-contract-ids: + bash ./test/update-contract-ids.sh + +[group('benchmark')] +benchmark: + bash ./benchmark.sh + +[group('benchmark')] +benchmark-tests: + bash ./test/bench.sh + +[group('benchmark')] +collect-gas-usage: + cargo r -p test --release -- --verbose --forc-test-only | ./scripts/compare-gas-usage/extract-gas-usage.sh + +[group('build')] +build-prism: + cd ./scripts/prism && ./build.sh + +[group('build')] +build-highlightjs: + cd ./scripts/highlightjs && ./build.sh + +[group('build')] +generate-sway-lib-std: + cd ./sway-lib-std && ./generate.sh + +[group('test')] +test-forc-fmt-check-panic: + cd ./scripts/formatter && ./forc-fmt-check-panic.sh \ No newline at end of file diff --git a/scripts/bisect-forc/README.md b/scripts/bisect-forc/README.md new file mode 100644 index 00000000000..206dd30b013 --- /dev/null +++ b/scripts/bisect-forc/README.md @@ -0,0 +1,17 @@ +`bisect-forc.sh` will automatically run `forc bisect` searching for a different behaviour between two commits. + +The script accepts three arguments: + +``` +bisect-forc.sh sway_project test 30s +``` +1 - First argument is the sway project that will be compiled over and over until a different behavior is found; +2 - The second argument is which forc subcommand will be used. It defaults to `build`. + +So, `forc` wil be run as: + +``` +> forc --path +``` + +3 - The third argument is a sleep that is taken between compilations to avoid notebooks enter into thermal throttle mode, or that weaker machines become unusable. Default to zero. diff --git a/scripts/bisect-forc/bisect-forc.sh b/scripts/bisect-forc/bisect-forc.sh new file mode 100755 index 00000000000..53bed8b70e1 --- /dev/null +++ b/scripts/bisect-forc/bisect-forc.sh @@ -0,0 +1,162 @@ +#! /bin/bash + +PROJ=$1 +SLEEP_BETWEEN=$3 +CACHE="$HOME/.cache/sway-bench" + +NC='\033[0m' +BOLD_GREEN="\033[1;32m" +BOLD_RED='\033[1;31m' +BOLD_WHITE='\033[1;97m' + +# $1 = commit hash +compile_and_cp_to_cache() { + if [ ! -f "$CACHE/$1" ]; then + if [[ -n $SLEEP_BETWEEN ]]; then + sleep "$SLEEP_BETWEEN" + fi + cargo b --release &>> /dev/null + cp target/release/forc "$CACHE/$1" &>> /dev/null + fi +} + +run_cargo() { + if [ "$2" = "" ]; then + bash -c "$CACHE/$CACHENAME build --path $PROJ" &>> /dev/null + echo "$?" + else + bash -c "$CACHE/$CACHENAME $2 --path $PROJ" &>> /dev/null + echo "$?" + fi +} + +INITIAL_COMMIT="$(git show -s --format='%H' HEAD)" +END_COMMIT="" + +echo "Forc command will be:" +if [ "$2" = "" ]; then + echo "> forc build --path $PROJ" +else + echo "> forc $2 --path $PROJ" +fi + +echo "Starting the search at: " +echo -n " " +git log -1 --oneline + +echo -n "Running: " + +CACHENAME="$(git show -s --format='%as-%ct-%H' HEAD)" +compile_and_cp_to_cache "$CACHENAME" +INITIAL_COMPILATION_STATUS=$(run_cargo) + +if [ "$INITIAL_COMPILATION_STATUS" = "0" ]; then + echo -e " ${BOLD_GREEN}Ok${NC}" + echo "" + echo "Searching the newest version which compilation was failing." +else + echo -e " ${BOLD_RED}Failed${NC}" + echo "" + echo "Searching the newest version which compilation was succeeding." +fi + + +for HASH in `git log --format="%H" --tags --no-walk`; do + git checkout "$HASH" &>> /dev/null + git checkout . &>> /dev/null + + git log -1 --oneline + + CACHENAME="$(git show -s --format='%as-%ct-%H' HEAD)" + compile_and_cp_to_cache "$CACHENAME" + LAST_STATUS=$(run_cargo) + if [ "$INITIAL_COMPILATION_STATUS" != "$LAST_STATUS" ]; then + echo -e "^^^^^^^^^ ${BOLD_WHITE}This version result is different!${NC}" + break + fi +done + +END_COMMIT="$(git show -s --format='%H' HEAD)" + +echo "" +echo -e "${BOLD_WHITE}Starting bisect between: ${NC}$INITIAL_COMMIT..$END_COMMIT" + +git checkout $INITIAL_COMMIT &>> /dev/null + +git bisect start &>> /dev/null +git bisect new $INITIAL_COMMIT &>> /dev/null +git bisect old $END_COMMIT &>> /dev/null + +while : +do + #echo "-----------------------" + #git --no-pager bisect visualize --oneline + + git bisect next | grep "is the first new commit" &>> /dev/null + if [ "$LAST_STATUS" = "0" ]; then + FIRST_COMMIT="$(git bisect next 2>&1 | head -n 1 | cut -f1 -d" ")" + git checkout "$FIRST_COMMIT" &>> /dev/null + break + fi + + git bisect next | grep "Bisecting" + if [ "$LAST_STATUS" != "0" ]; then + break + fi + + git checkout . &>> /dev/null + + CACHENAME="$(git show -s --format='%as-%ct-%H' HEAD)" + compile_and_cp_to_cache "$CACHENAME" + LAST_STATUS=$(run_cargo) + if [ "$LAST_STATUS" = "$INITIAL_COMPILATION_STATUS" ]; then + git bisect new &>> /dev/null + else + git bisect old &>> /dev/null + fi +done + +FOUND_COMMIT="$(git show -s --format='%H' HEAD)" + +echo -e "${BOLD_GREEN}Found!${NC} - ${FOUND_COMMIT}" +echo "" + + +# check this commit has the same behaviour +echo -n "checking the found commit has the same behaviour as the initial commit..." + +CACHENAME="$(git show -s --format='%as-%ct-%H' HEAD)" +compile_and_cp_to_cache "$CACHENAME" +LAST_STATUS=$(run_cargo) + +if [ "$INITIAL_COMPILATION_STATUS" != "$LAST_STATUS" ]; then + echo -e " ${BOLD_RED}Unexpected exit code${NC}" + exit 1 +fi + +echo -e " ${BOLD_GREEN}Ok${NC}" + +## check the previous commit has the inverse +echo -n "checking the previous commit has the inverse behaviour as the initial commit..." + +git checkout HEAD~1 &>> /dev/null +PREVIOUS_COMMIT="$(git show -s --format='%H' HEAD)" +CACHENAME="$(git show -s --format='%as-%ct-%H' HEAD)" +compile_and_cp_to_cache "$CACHENAME" +LAST_STATUS=$(run_cargo) + +if [ "$INITIAL_COMPILATION_STATUS" = "$LAST_STATUS" ]; then + echo -e " ${BOLD_RED}Unexpected exit code${NC}" + exit 1 +fi + +echo -e " ${BOLD_GREEN}Ok${NC}" + +echo "" + +git checkout . &>> /dev/null +git bisect reset &>> /dev/null + +git checkout "$FOUND_COMMIT" &>> /dev/null +echo "This is the commit that changed the compiler behavior" +git log -1 --oneline diff --git a/scripts/compare-gas-usage/extract-gas-usage.sh b/scripts/compare-gas-usage/extract-gas-usage.sh new file mode 100755 index 00000000000..8894804fae7 --- /dev/null +++ b/scripts/compare-gas-usage/extract-gas-usage.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# This script extracts full test names and test gas usage from a `forc test` output. +# Usage: `forc test | test_gas_usage.sh`. + +current_suite="" +results=() + +while IFS= read -r line; do + # printf 'Line: %s\n' "$line" + + if [[ $line =~ ^tested\ --\ ([^[:space:]]+) ]]; then + current_suite="${BASH_REMATCH[1]}" + fi + # printf 'Suite: %s\n' "$current_suite" + + if [[ $line =~ ^[[:space:]]*test[[:space:]]([^\ ]+)[[:space:]]\.\.\.[[:space:]].*,[[:space:]]([0-9]+)[[:space:]]gas\) ]]; then + test_name="${BASH_REMATCH[1]}" + # printf 'Test: %s\n' "$test_name" + gas="${BASH_REMATCH[2]}" + # printf 'Gas: %s\n' "$gas" + results+=("${current_suite}::${test_name},${gas}") + fi +done + +printf '%s\n' "${results[@]}" | sort \ No newline at end of file diff --git a/scripts/compare-gas-usage/generate-diff.sh b/scripts/compare-gas-usage/generate-diff.sh new file mode 100755 index 00000000000..d9f458ab94d --- /dev/null +++ b/scripts/compare-gas-usage/generate-diff.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# This script compares test gas usage from two outputs of the `test_gas_usage.sh` script. +# The result of the comparison can be printed either as a Markdown table or a CSV file. +# Usage: `compare_test_gas_usage.sh .csv .csv [MD|CSV]`. + +#!/bin/bash + +#!/bin/bash + +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then + echo "Usage: $0 .csv .csv [MD|CSV]" + exit 1 +fi + +before_file="$1" +after_file="$2" +output_format="${3:-MD}" + +if [ "$output_format" == "CSV" ]; then + echo "Test,Before,After,Percentage" +else + echo "| Test | Before | After | Percentage |" + echo "|------|--------|-------|------------|" +fi + +paste -d, "$before_file" "$after_file" | while IFS=',' read -r test1 before test2 after; do + if [ "$before" != "$after" ]; then + diff=$((before - after)) + percent=$(LC_NUMERIC=C awk -v d="$diff" -v b="$before" 'BEGIN { printf "%.2f", (d / b) * 100 }') + + if [ "$output_format" == "CSV" ]; then + echo "$test1,$before,$after,$percent" + else + echo "| $test1 | $before | $after | $percent% |" + fi + fi +done \ No newline at end of file From 1778c1768cf28c2671df8e99c53d6a09e04b8ee4 Mon Sep 17 00:00:00 2001 From: xunilrj Date: Tue, 2 Sep 2025 09:46:18 -0300 Subject: [PATCH 3/5] update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 23cfb140f9e..081586de877 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,35 @@ Confirm the Sway toolchain built successfully: cargo run --bin forc -- --help ``` +## All other scripts/commands + +For all other scripts and commands use https://github.com/casey/just: + +``` +> just --list +Available recipes: + [automation] + update-contract-ids + update-fuel-dependencies + + [benchmark] + benchmark + benchmark-tests + collect-gas-usage + + [build] + build-highlightjs + build-prism + generate-sway-lib-std + + [ci] + ci-check + install-ci-check + + [test] + test-forc-fmt-check-panic +``` + ## Contributing to Sway We welcome contributions to Sway! From c11b48ad23d163498341eb211750294a229b0aa9 Mon Sep 17 00:00:00 2001 From: xunilrj Date: Tue, 2 Sep 2025 09:48:04 -0300 Subject: [PATCH 4/5] fix typo --- scripts/bisect-forc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bisect-forc/README.md b/scripts/bisect-forc/README.md index 206dd30b013..2e740f44629 100644 --- a/scripts/bisect-forc/README.md +++ b/scripts/bisect-forc/README.md @@ -8,7 +8,7 @@ bisect-forc.sh sway_project test 30s 1 - First argument is the sway project that will be compiled over and over until a different behavior is found; 2 - The second argument is which forc subcommand will be used. It defaults to `build`. -So, `forc` wil be run as: +So, `forc` will be run as: ``` > forc --path From 4326b52b1796d0e204af22dcd8948e26d1f6724f Mon Sep 17 00:00:00 2001 From: xunilrj Date: Wed, 3 Sep 2025 09:05:11 -0300 Subject: [PATCH 5/5] removing unecessary shebangs --- scripts/compare-gas-usage/generate-diff.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/compare-gas-usage/generate-diff.sh b/scripts/compare-gas-usage/generate-diff.sh index d9f458ab94d..61c6c970045 100755 --- a/scripts/compare-gas-usage/generate-diff.sh +++ b/scripts/compare-gas-usage/generate-diff.sh @@ -4,10 +4,6 @@ # The result of the comparison can be printed either as a Markdown table or a CSV file. # Usage: `compare_test_gas_usage.sh .csv .csv [MD|CSV]`. -#!/bin/bash - -#!/bin/bash - if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then echo "Usage: $0 .csv .csv [MD|CSV]" exit 1