Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down
48 changes: 48 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions scripts/bisect-forc/README.md
Original file line number Diff line number Diff line change
@@ -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` will be run as:

```
> forc <SECONDARGUMENT> --path <FIRSTARGUMENT>
```

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.
162 changes: 162 additions & 0 deletions scripts/bisect-forc/bisect-forc.sh
Original file line number Diff line number Diff line change
@@ -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
26 changes: 26 additions & 0 deletions scripts/compare-gas-usage/extract-gas-usage.sh
Original file line number Diff line number Diff line change
@@ -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
34 changes: 34 additions & 0 deletions scripts/compare-gas-usage/generate-diff.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/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 <before>.csv <after>.csv [MD|CSV]`.

if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 <before>.csv <after>.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
14 changes: 13 additions & 1 deletion test/src/e2e_vm_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:?}");
}
Expand Down Expand Up @@ -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)];
}
Expand Down
6 changes: 6 additions & 0 deletions test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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 {
Expand Down
Loading