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
44 changes: 33 additions & 11 deletions contest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ test_dir=$(dirname $file)
build_dir="$root_dir/build"
base=$(basename "$file" .json)
src="$test_dir/$base.solc"
hull="$build_dir/output1.hull"
hexfile="$build_dir/$base.hex"
yulfile="$build_dir/$base.yul"

create=true
# Allow overriding testrunner location (useful for Nix builds)
Expand Down Expand Up @@ -87,16 +84,41 @@ suite=$(echo $presuite | tr -d '"')
echo "Compiling to Hull..."
# Allow overriding sol-core command (useful for Nix builds)
: ${SOLCORE_CMD:="cabal run exe:sol-core --"}
if ! $SOLCORE_CMD -f "$src"; then
mkdir -p "$build_dir"
work_root="$build_dir/.contest-work"
mkdir -p "$work_root"
work_dir="$(mktemp -d "$work_root/run.XXXXXX")"
work_marker="$work_dir/.owned-by-contest"
touch "$work_marker"
hull="$work_dir/output1.hull"
yulfile="$work_dir/output.yul"
hexfile="$work_dir/output.hex"
runner_input="$work_dir/runner-input.json"
runner_output="$work_dir/runner-output.json"

cleanup_work_dir() {
if [[ -z "${work_dir:-}" ]]; then
return
fi

if [[ "$work_dir" != "$work_root"/run.* || ! -f "$work_marker" ]]; then
echo "Error: refusing to clean unverified contest work directory '$work_dir'" >&2
return 1
fi

rm -rf -- "$work_dir"
}

trap cleanup_work_dir EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM

if ! $SOLCORE_CMD -f "$src" -o "$work_dir"; then
echo "Error: sol-core compilation failed"
exit 1
fi

mkdir -p "$build_dir"
if ls ./output*.hull 1> /dev/null 2>&1; then
mv ./output*.hull "$build_dir"/
fi

if [[ ! -f "$hull" ]]; then
echo "Error: sol-core did not produce output1.hull"
exit 1
Expand All @@ -122,6 +144,6 @@ fi

echo "Hex output: $hexfile"

jq ".$suite.bytecode |= \"$(cat $hexfile)\" " $file > $build_dir/$suite.json
jq ".$suite.bytecode |= \"$(cat $hexfile)\" " $file > "$runner_input"

"$testrunner_exe" "$evmone" "$build_dir/$suite.json" "$build_dir/$suite-output.json"
"$testrunner_exe" "$evmone" "$runner_input" "$runner_output"
2 changes: 2 additions & 0 deletions run_contests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -euo pipefail
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$root_dir"

bash ./scripts/test_contest_concurrency.sh

bash ./contest.sh test/examples/dispatch/basic.json
bash ./contest.sh test/examples/dispatch/assembly.json
bash ./contest.sh test/examples/dispatch/neg.json
Expand Down
208 changes: 208 additions & 0 deletions scripts/test_contest_concurrency.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#!/usr/bin/env bash

set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
tmp_parent="${TMPDIR:-/tmp}"
tmp_parent="${tmp_parent%/}"
test_root="$(mktemp -d "$tmp_parent/solcore-contest-concurrency.XXXXXX")"
test_marker="$test_root/.owned-by-contest-concurrency-test"
touch "$test_marker"

cleanup_test_root() {
if [[ "$test_root" != "$tmp_parent"/solcore-contest-concurrency.* || ! -f "$test_marker" ]]; then
echo "Error: refusing to clean unverified test directory '$test_root'" >&2
return 1
fi

rm -rf -- "$test_root"
}

trap cleanup_test_root EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM

mkdir -p \
"$test_root/cases/alpha" \
"$test_root/cases/beta" \
"$test_root/fake-bin" \
"$test_root/state"
cp "$repo_root/contest.sh" "$test_root/contest.sh"
chmod +x "$test_root/contest.sh"

printf '%s\n' alpha > "$test_root/cases/alpha/shared.solc"
printf '%s\n' '{"shared": {}}' > "$test_root/cases/alpha/shared.json"
printf '%s\n' beta > "$test_root/cases/beta/shared.solc"
printf '%s\n' '{"shared": {}}' > "$test_root/cases/beta/shared.json"
printf '%s\n' user-owned-sentinel > "$test_root/output1.hull"
touch "$test_root/libevmone.so"

# Nix sandboxes do not provide /usr/bin/env, so use the active Bash path.
printf '#!%s\n\n' "$BASH" > "$test_root/fake-bin/tool"
cat >> "$test_root/fake-bin/tool" <<'EOF'
set -euo pipefail

tool="$(basename "$0")"

case "$tool" in
sol-core)
src=
output_dir=
while [[ $# -gt 0 ]]; do
case "$1" in
-f)
src="$2"
shift 2
;;
-o)
output_dir="$2"
shift 2
;;
*)
shift
;;
esac
done

case_name="$FAKE_CASE"
[[ "$(<"$src")" == "$case_name" ]]
printf '%s\n' "$case_name" > "$output_dir/output1.hull"
printf '%s\n' "$output_dir" > "$FAKE_STATE/$case_name.work-dir"
touch "$FAKE_STATE/compiler-$case_name.ready"

deadline=$((SECONDS + 10))
until [[ -f "$FAKE_STATE/compiler-alpha.ready" && -f "$FAKE_STATE/compiler-beta.ready" ]]; do
if (( SECONDS >= deadline )); then
echo "Timed out waiting for both fake compilers" >&2
exit 1
fi
sleep 0.01
done
;;
yule)
hull="$1"
shift
output=
while [[ $# -gt 0 ]]; do
case "$1" in
-o)
output="$2"
shift 2
;;
*)
shift
;;
esac
done

case_name="$(<"$hull")"
printf '%s\n' "$output" > "$FAKE_STATE/$case_name.yul-path"
printf '%s\n' "$case_name" > "$output"
;;
solc)
yul=
for arg in "$@"; do
yul="$arg"
done
case_name="$(<"$yul")"
[[ "$case_name" == "$FAKE_CASE" ]]
printf '%s\n' "$yul" > "$FAKE_STATE/$case_name.solc-input"
printf '%s\n' "Binary representation:" "hex-$case_name"
;;
jq)
if [[ "$1" == "keys[0]" ]]; then
printf '%s\n' '"shared"'
else
[[ "$1" == *"hex-$FAKE_CASE"* ]]
printf '{"shared":{"bytecode":"%s","case":"%s"}}\n' \
"hex-$FAKE_CASE" "$FAKE_CASE"
fi
;;
testrunner)
[[ -f "$1" ]]
[[ -f "$2" ]]
command grep -q "\"case\":\"$FAKE_CASE\"" "$2"
printf '%s\n' "$2" > "$FAKE_STATE/$FAKE_CASE.runner-input"
printf '%s\n' "$3" > "$FAKE_STATE/$FAKE_CASE.runner-output"
printf '{"ok":true,"case":"%s"}\n' "$FAKE_CASE" > "$3"
;;
*)
echo "Unexpected fake tool name: $tool" >&2
exit 1
;;
esac
EOF

chmod +x "$test_root/fake-bin/tool"
for tool in sol-core yule solc jq testrunner; do
ln -s tool "$test_root/fake-bin/$tool"
done

run_case() {
local case_name="$1"

PATH="$test_root/fake-bin:$PATH" \
SOLCORE_CMD="$test_root/fake-bin/sol-core" \
YULE_CMD="$test_root/fake-bin/yule" \
testrunner_exe="$test_root/fake-bin/testrunner" \
evmone="$test_root/libevmone.so" \
FAKE_STATE="$test_root/state" \
FAKE_CASE="$case_name" \
bash "$test_root/contest.sh" \
"$test_root/cases/$case_name/shared.json" \
> "$test_root/state/$case_name.log" 2>&1
}

run_case alpha &
alpha_pid=$!
run_case beta &
beta_pid=$!

failed=0
if ! wait "$alpha_pid"; then
command cat "$test_root/state/alpha.log" >&2
failed=1
fi
if ! wait "$beta_pid"; then
command cat "$test_root/state/beta.log" >&2
failed=1
fi
if [[ "$failed" != "0" ]]; then
exit 1
fi

alpha_work_dir="$(<"$test_root/state/alpha.work-dir")"
beta_work_dir="$(<"$test_root/state/beta.work-dir")"
alpha_yul_path="$(<"$test_root/state/alpha.yul-path")"
beta_yul_path="$(<"$test_root/state/beta.yul-path")"
alpha_solc_input="$(<"$test_root/state/alpha.solc-input")"
beta_solc_input="$(<"$test_root/state/beta.solc-input")"
alpha_runner_input="$(<"$test_root/state/alpha.runner-input")"
beta_runner_input="$(<"$test_root/state/beta.runner-input")"
alpha_runner_output="$(<"$test_root/state/alpha.runner-output")"
beta_runner_output="$(<"$test_root/state/beta.runner-output")"

[[ "$alpha_work_dir" == "$test_root/build/.contest-work/run."* ]]
[[ "$beta_work_dir" == "$test_root/build/.contest-work/run."* ]]
[[ "$alpha_work_dir" != "$beta_work_dir" ]]
[[ "$alpha_yul_path" == "$alpha_work_dir/output.yul" ]]
[[ "$beta_yul_path" == "$beta_work_dir/output.yul" ]]
[[ "$alpha_yul_path" != "$beta_yul_path" ]]
[[ "$alpha_solc_input" == "$alpha_yul_path" ]]
[[ "$beta_solc_input" == "$beta_yul_path" ]]
[[ "$alpha_runner_input" == "$alpha_work_dir/runner-input.json" ]]
[[ "$beta_runner_input" == "$beta_work_dir/runner-input.json" ]]
[[ "$alpha_runner_input" != "$beta_runner_input" ]]
[[ "$alpha_runner_output" == "$alpha_work_dir/runner-output.json" ]]
[[ "$beta_runner_output" == "$beta_work_dir/runner-output.json" ]]
[[ "$alpha_runner_output" != "$beta_runner_output" ]]
[[ ! -e "$alpha_work_dir" ]]
[[ ! -e "$beta_work_dir" ]]
[[ "$(<"$test_root/output1.hull")" == "user-owned-sentinel" ]]
[[ ! -e "$test_root/build/shared.yul" ]]
[[ ! -e "$test_root/build/shared.hex" ]]
[[ ! -e "$test_root/build/shared.json" ]]
[[ ! -e "$test_root/build/shared-output.json" ]]

printf '%s\n' "contest concurrency regression passed"
Loading