Skip to content

Commit c81c915

Browse files
committed
scripts/ImportExportTest.sh: Add generic script for import export.
1 parent 53fe56b commit c81c915

File tree

2 files changed

+268
-2
lines changed

2 files changed

+268
-2
lines changed

scripts/ImportExportTest.sh

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
# Bash script to test the ast-import option of the compiler by
6+
# first exporting a .sol file to JSON, then loading it into the compiler
7+
# and exporting it again. The second JSON should be identical to the first
8+
READLINK=readlink
9+
if [[ "$OSTYPE" == "darwin"* ]]; then
10+
READLINK=greadlink
11+
fi
12+
IMPORT_TEST_TYPE=${1}
13+
REPO_ROOT=$(${READLINK} -f "$(dirname "$0")"/..)
14+
SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}
15+
SOLC=${SOLIDITY_BUILD_DIR}/solc/solc
16+
SPLITSOURCES=${REPO_ROOT}/scripts/splitSources.py
17+
18+
SYNTAXTESTS_DIR="${REPO_ROOT}/test/libsolidity/syntaxTests"
19+
SEMANTICTESTS_DIR="${REPO_ROOT}/test/libsolidity/semanticTests"
20+
ASTJSONTESTS_DIR="${REPO_ROOT}/test/libsolidity/ASTJSON"
21+
22+
# DEV_DIR="${REPO_ROOT}/../tmp/contracts/"
23+
# NSOURCES="$(find $DEV_DIR -type f | wc -l)" #TODO use find command
24+
25+
FAILED=0
26+
UNCOMPILABLE=0
27+
TESTED=0
28+
29+
if [[ "$(find . -maxdepth 0 -type d -empty)" == "" ]]; then
30+
echo "Test directory not empty. Skipping!"
31+
exit 1
32+
fi
33+
34+
# function tests whether exporting and importing again leaves the JSON ast unchanged
35+
# Results are recorded by adding to FAILED or UNCOMPILABLE.
36+
# Also, in case of a mismatch a diff and the respective ASTs are printed
37+
# Expected parameters:
38+
# $1 name of the file to be exported and imported
39+
# $2 any files needed to do so that might be in parent directories
40+
function testImportExportEquivalence {
41+
local nth_input_file="$1"
42+
IFS=" " read -r -a all_input_files <<< "$2"
43+
44+
if $SOLC --bin "$nth_input_file" "${all_input_files[@]}" > /dev/null 2>&1
45+
then
46+
! [[ -e stderr.txt ]] || { echo "stderr.txt already exists. Refusing to overwrite."; exit 1; }
47+
48+
if [ "${IMPORT_TEST_TYPE}" == "ast" ]
49+
then
50+
# save exported json as expected result (silently)
51+
$SOLC --combined-json ast --pretty-json "$nth_input_file" "${all_input_files[@]}" > expected.json 2> /dev/null
52+
# import it, and export it again as obtained result (silently)
53+
if ! $SOLC --import-ast --combined-json ast --pretty-json expected.json > obtained.json 2> stderr.txt
54+
then
55+
# For investigating, use exit 1 here so the script stops at the
56+
# first failing test
57+
# exit 1
58+
FAILED=$((FAILED + 1))
59+
echo -e "ERROR: AST reimport failed for input file $nth_input_file"
60+
echo
61+
echo "Compiler stderr:"
62+
cat ./stderr.txt
63+
echo
64+
echo "Compiler stdout:"
65+
cat ./obtained.json
66+
return 1
67+
fi
68+
set +e
69+
DIFF="$(diff expected.json obtained.json)"
70+
set +e
71+
if [ "$DIFF" != "" ]
72+
then
73+
if [ "$DIFFVIEW" == "" ]
74+
then
75+
echo -e "ERROR: JSONS differ for $1: \n $DIFF \n"
76+
echo "Expected:"
77+
cat ./expected.json
78+
echo "Obtained:"
79+
cat ./obtained.json
80+
else
81+
# Use user supplied diff view binary
82+
$DIFFVIEW expected.json obtained.json
83+
fi
84+
FAILED=$((FAILED + 1))
85+
return 2
86+
fi
87+
TESTED=$((TESTED + 1))
88+
rm expected.json obtained.json
89+
rm -f stderr.txt
90+
elif [ "${IMPORT_TEST_TYPE}" == "evm-assembly" ]
91+
then
92+
local types=( "asm" "bin" "bin-runtime" "opcodes" "srcmap" "srcmap-runtime" )
93+
local _TESTED=1
94+
if ! $SOLC --combined-json bin,bin-runtime,opcodes,asm,srcmap,srcmap-runtime --pretty-json "$nth_input_file" "${all_input_files[@]}" > expected.json 2> expected.error
95+
then
96+
printf "\n"
97+
echo "$nth_input_file"
98+
cat expected.error
99+
UNCOMPILABLE=$((UNCOMPILABLE + 1))
100+
return 0
101+
else
102+
for contract in $(jq '.contracts | keys | .[]' expected.json 2> /dev/null)
103+
do
104+
for type in "${types[@]}"
105+
do
106+
jq --raw-output ".contracts.${contract}.\"${type}\"" expected.json > "expected.${type}"
107+
done
108+
109+
assembly=$(cat expected.asm)
110+
if [ "$assembly" != "" ] && [ "$assembly" != "null" ]
111+
then
112+
cp expected.asm /tmp/test.asm
113+
if ! $SOLC --combined-json bin,bin-runtime,opcodes,asm,srcmap,srcmap-runtime --pretty-json --import-asm-json expected.asm > obtained.json 2> obtained.error
114+
then
115+
printf "\n"
116+
echo "$nth_input_file"
117+
cat obtained.error
118+
UNCOMPILABLE=$((UNCOMPILABLE + 1))
119+
return 0
120+
else
121+
for type in "${types[@]}"
122+
do
123+
for obtained_contract in $(jq '.contracts | keys | .[]' obtained.json 2> /dev/null)
124+
do
125+
jq --raw-output ".contracts.${obtained_contract}.\"${type}\"" obtained.json > "obtained.${type}"
126+
set +e
127+
DIFF="$(diff "expected.${type}" "obtained.${type}")"
128+
set -e
129+
if [ "$DIFF" != "" ]
130+
then
131+
if [ "$DIFFVIEW" == "" ]
132+
then
133+
echo -e "ERROR: JSONS differ for $1: \n $DIFF \n"
134+
echo "Expected:"
135+
cat "expected.${type}"
136+
echo "Obtained:"
137+
cat "obtained.${type}"
138+
else
139+
# Use user supplied diff view binary
140+
$DIFFVIEW expected.json obtained.json
141+
fi
142+
_TESTED=
143+
FAILED=$((FAILED + 1))
144+
return 0
145+
fi
146+
done
147+
done
148+
149+
rm obtained.json
150+
rm -f obtained.error
151+
for type in "${types[@]}"
152+
do
153+
rm "obtained.${type}"
154+
done
155+
fi
156+
157+
for type in "${types[@]}"
158+
do
159+
rm "expected.${type}"
160+
done
161+
fi
162+
done
163+
rm expected.json
164+
fi
165+
if [ -n "${_TESTED}" ]
166+
then
167+
TESTED=$((TESTED + 1))
168+
fi
169+
else
170+
echo "unknown import test type. aborting."
171+
exit 1
172+
fi
173+
else
174+
UNCOMPILABLE=$((UNCOMPILABLE + 1))
175+
fi
176+
}
177+
178+
WORKINGDIR=$PWD
179+
NSOURCES=0
180+
181+
# for solfile in $(find $DEV_DIR -name *.sol)
182+
# boost_filesystem_bug specifically tests a local fix for a boost::filesystem
183+
# bug. Since the test involves a malformed path, there is no point in running
184+
# AST tests on it. See https://github.com/boostorg/filesystem/issues/176
185+
if [ "${IMPORT_TEST_TYPE}" == "ast" ]
186+
then
187+
IMPORT_TEST_FILES=$(find "${SYNTAXTESTS_DIR}" "${ASTJSONTESTS_DIR}" -name "*.sol" -and -not -name "boost_filesystem_bug.sol")
188+
elif [ "${IMPORT_TEST_TYPE}" == "evm-assembly" ]
189+
then
190+
IMPORT_TEST_FILES=$(find "${SYNTAXTESTS_DIR}" "${SEMANTICTESTS_DIR}" -name "*.sol" -and -not -name "boost_filesystem_bug.sol")
191+
else
192+
echo "unknown import test type. aborting. please specify $0 [ast|evm-assembly]."
193+
exit 1
194+
fi
195+
196+
NSOURCES="$(echo "$IMPORT_TEST_FILES" | wc -l)"
197+
echo "Looking at $NSOURCES .sol files..."
198+
199+
for solfile in ${IMPORT_TEST_FILES}
200+
do
201+
echo -n "."
202+
# create a temporary sub-directory
203+
FILETMP=$(mktemp -d)
204+
cd "$FILETMP"
205+
206+
set +e
207+
OUTPUT=$("$SPLITSOURCES" "$solfile")
208+
SPLITSOURCES_RC=$?
209+
set -e
210+
if [ ${SPLITSOURCES_RC} == 0 ]
211+
then
212+
# echo $OUTPUT
213+
NSOURCES=$((NSOURCES - 1))
214+
for i in $OUTPUT;
215+
do
216+
testImportExportEquivalence "$i" "$OUTPUT"
217+
NSOURCES=$((NSOURCES + 1))
218+
done
219+
elif [ ${SPLITSOURCES_RC} == 1 ]
220+
then
221+
testImportExportEquivalence "$solfile"
222+
elif [ ${SPLITSOURCES_RC} == 2 ]
223+
then
224+
# The script will exit with return code 2, if an UnicodeDecodeError occurred.
225+
# This is the case if e.g. some tests are using invalid utf-8 sequences. We will ignore
226+
# these errors, but print the actual output of the script.
227+
echo -e "\n${OUTPUT}\n"
228+
testImportExportEquivalence "$solfile"
229+
else
230+
# All other return codes will be treated as critical errors. The script will exit.
231+
echo -e "\nGot unexpected return code ${SPLITSOURCES_RC} from ${SPLITSOURCES}. Aborting."
232+
echo -e "\n${OUTPUT}\n"
233+
234+
cd "$WORKINGDIR"
235+
# Delete temporary files
236+
rm -rf "$FILETMP"
237+
238+
exit 1
239+
fi
240+
241+
cd "$WORKINGDIR"
242+
# Delete temporary files
243+
rm -rf "$FILETMP"
244+
done
245+
246+
echo ""
247+
248+
if [ "$FAILED" = 0 ]
249+
then
250+
echo "SUCCESS: $TESTED tests passed, $FAILED failed, $UNCOMPILABLE could not be compiled ($NSOURCES sources total)."
251+
else
252+
echo "FAILURE: Out of $NSOURCES sources, $FAILED failed, ($UNCOMPILABLE could not be compiled)."
253+
exit 1
254+
fi

test/cmdlineTests.sh

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,11 +645,23 @@ SOLTMPDIR=$(mktemp -d)
645645
)
646646
rm -r "$SOLTMPDIR"
647647

648-
printTask "Testing AST import..."
648+
printTask "Testing AST import/export..."
649649
SOLTMPDIR=$(mktemp -d)
650650
(
651651
cd "$SOLTMPDIR"
652-
if ! "$REPO_ROOT/scripts/ASTImportTest.sh"
652+
if ! "$REPO_ROOT/scripts/ImportExportTest.sh" ast
653+
then
654+
rm -r "$SOLTMPDIR"
655+
fail
656+
fi
657+
)
658+
rm -r "$SOLTMPDIR"
659+
660+
printTask "Testing EVM Assembly JSON import/export..."
661+
SOLTMPDIR=$(mktemp -d)
662+
(
663+
cd "$SOLTMPDIR"
664+
if ! "$REPO_ROOT/scripts/ImportExportTest.sh" evm-assembly
653665
then
654666
rm -r "$SOLTMPDIR"
655667
fail

0 commit comments

Comments
 (0)