forked from angr/angr-dev
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathangr-test
executable file
·306 lines (262 loc) · 8.55 KB
/
angr-test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#!/bin/bash
#
# Angr testing script
# This is a fork of the internal angr testing script which is slaved to our infrastructure, so it's not actually maintained
# Lives in /usr/local/bin/angr-test
#
if [[ -z $VIRTUAL_ENV ]]; then
echo "This script must be run from within the Angr virtualenv"
exit 1
fi
# Set up global variables
export PERSIST_DATA=/home/angr/.persist
export PATH=$VIRTUAL_ENV/bin:$PATH
declare -A RESULTS=()
SCRIPTNAME=$(which $0)
if (git status >/dev/null 2>/dev/null); then
export IN_GIT_REPO=1
export COMMIT=$(git rev-parse --short HEAD)
export BRANCH=$(git branch --list -rv | grep $COMMIT | grep origin | head -n 1 | cut -c 10- | grep -o '^[^ ]*')
export CURRENT_REPO_PATH=$(git rev-parse --show-toplevel)
cd $CURRENT_REPO_PATH
export CURRENT_REPO_NAME=$(dirname */__init__.py | grep -v test)
cd $OLDPWD
if [[ -f $CURRENT_REPO_PATH/$CURRENT_REPO_NAME/__init__.py ]]; then
export WELL_FORMED_REPO=0
else
export WELL_FORMED_REPO=
fi
if git remote -v | grep angr-doc\\.git >/dev/null; then
export WELL_FORMED_REPO=0
export CURRENT_REPO_NAME="angr-doc"
fi
if (git status 2>&1 | grep 'On branch' >/dev/null); then
export USE_COMMIT_HASH=
else
export USE_COMMIT_HASH=0
fi
else
export IN_GIT_REPO=0
fi
# Define functions
main () {
update_self "$@"
if [[ -z $1 ]]; then
usage
exit 1
elif [[ $1 == "sync" ]]; then
synchronize $2
exit 0
elif [[ $1 == "lint" ]]; then
lint # this command might cause the program to terminate
exit 0
else
perform_tests "$@" # this command will cause the program to terminate
echo "This statement should not be reached"
exit 1
fi
}
update_self () {
cd /home/angr/angr-dev
git pull >/dev/null 2>/dev/null
if ! diff angr-test $SCRIPTNAME >/dev/null; then
echo 'Updating sync script!'
cd $OLDPWD
sudo cp /home/angr/angr-dev/angr-test $SCRIPTNAME && exec $SCRIPTNAME "$@"
fi
cd $OLDPWD
}
usage () {
cat <<EOF
Angr test script
Usage: $0 [ sync | lint | <repo1> <repo2> ... ]
This program assumes angr-dev is in /home/angr/angr-dev
and that the rest of the angr repositories are in /home/angr/angr/*.
Sync command:
Must be run from within a repository. Will attempt to syncronize
the rest of the angr repositories to the current commit hash, then
the current branch name, then to master. Will rebuild repositories
that need rebuilding.
"angr-test sync hard" will discard your local branches in favor of the
remote ones.
Lint command:
Must be run from within a repository in which the files to be linted
are inside a folder that contains an __init__.py file. Test folders are
not linted. Will lint with command:
pylint /home/angr/angr/\$REPO/\$REPO
The current best-linting status of the master branch will be kept in
$PERSIST_DATA. Tests will fail if they perform worse than this
benchmark.
Test commands:
If run from within a repository, will produce coverage data for the
repoitory it is run within. Will test any repository \$REPO specified
on the command line with the following command:
nosetests -v --with-timer /home/angr/angr/\$REPO/tests/test_*.py
After all the tests are run, a summary will be printed and the program
will exit with status zero if all the test commands exited with status
zero, else with status one.
EOF
}
assert_wellformed () {
if [[ -z $WELL_FORMED_REPO ]]; then
echo "$1 command can only be run within an angr repo"
exit 1
fi
}
synchronize () {
assert_wellformed sync
echo "Syncing with branch $BRANCH..."
echo "Cache contents:"
#ls -alhR $PERSIST_DATA
cd /home/angr/angr
for REPO in vex pyvex cle claripy simuvex angr ana cooldict binaries archinfo ../angr-doc; do
if [[ ! -d $REPO ]]; then
continue
fi
cd $REPO
if (!(git status >/dev/null 2>/dev/null)); then
cd $OLDPWD
continue
fi
if (!(git diff --quiet)); then
if [[ $1 == "hard" ]]; then
git reset --hard HEAD
else
echo "NOT syncing repository $REPO with changes on the working tree"
cd $OLDPWD
continue
fi
fi
echo -e "\e[33;1m**** Syncing ${REPO}...\e[0m"
git fetch origin
git remote prune origin
if [[ $1 == "hard" ]]; then
git rev-parse HEAD | xargs git checkout >/dev/null 2>/dev/null
git branch | grep -v '*' | xargs git branch -D
fi
{ test $USE_COMMIT_HASH && git checkout -f $COMMIT; } || { git checkout -f $BRANCH; } || { git checkout -f master; } || \
{ echo 'Unable to check out any branch!' && exit 1; }
if [[ $1 != "hard" ]]; then
git pull
fi
echo -e "\e[33;1m**** $REPO on commit $(git rev-parse --short HEAD)\e[0m"
if [ "$REPO" == "pyvex" ]; then
{ rm -rf build && python setup.py build; } || \
{ echo 'Unable to build Pyvex!' && exit 1; }
fi
if [ "$REPO" == "vex" ]; then
{ make; } || { echo 'Unable to build VEX!' && exit 1; }
fi
if [ -f requirements.txt ]; then
echo "Installing requirements.txt..."
{ pip install -r requirements.txt >/dev/null; } || { echo 'Unable to install requirements!' && exit 1; }
fi
echo -e "\e[32;1m**** $REPO synchronized!\e[0m"
cd ..
done
}
lint() {
assert_wellformed lint
if [ -d $PERSIST_DATA ]; then
mkdir -p $PERSIST_DATA/lint-migration
fi
TEMP_RAW=$(mktemp)
TEMP_PROCESSED=$(mktemp)
header $CURRENT_REPO_NAME "Linting"
pylint $CURRENT_REPO_PATH/$CURRENT_REPO_NAME | tee $TEMP_RAW
grep '\*\*\*\*\*\*\*\*\*\*\*\*\*' $TEMP_RAW | cut -f 3 -d ' ' | sort > $TEMP_PROCESSED
BASELINE=$PERSIST_DATA/lint-migration/$CURRENT_REPO_NAME
if [ -f $BASELINE ]; then
if diff $BASELINE $TEMP_PROCESSED | grep '>' >/dev/null; then
echo -e "\e[33;1m======== LINTING FAILED =========\e[0m"
echo Files that failed to lint:
diff $BASELINE $TEMP_PROCESSED | grep '>'
rm -f $TEMP_RAW $TEMP_PROCESSED
exit 1
else
echo -e "\e[32;1m======== Linting passed! =========\e[0m"
fi
else
echo "No lint migration data available, no test performed with lint data"
fi
if [[ $BRANCH == "master" ]]; then
if [ -d $PERSIST_DATA ]; then
echo "Updating lint migration data!"
mv $TEMP_PROCESSED $BASELINE
fi
fi
rm -f $TEMP_RAW $TEMP_PROCESSED
}
header () {
WHAT=$1
TYPE=$2
cat <<EOF
==========================================================
Running $TYPE for $WHAT
==========================================================
EOF
}
perform_tests () {
# First clear all the old pyc files - they can mess things up
find $(realpath /home/angr/angr) -name '*.pyc' -print0 | xargs -0 rm 2>/dev/null
cd /home/angr
while [[ -n $1 ]]; do
if [[ $1 == 'docs' ]]; then
test_docs
shift
else
perform_test $1
shift
fi
done
print_summary
appropriate_exit
}
test_docs () {
cd /home/angr/angr-doc
header angr-doc Tests
nosetests -v --nologcapture --with-timer test.py
RESULTS["docs"]=$?
}
perform_test () {
WHAT=$1
shift
shift
LOGFILE=$(mktemp)
header $WHAT "Tests"
nosetests -v --nologcapture --with-timer $(coverage_command $WHAT) /home/angr/angr/$WHAT/tests/test_*.py 2>&1 | tee $LOGFILE
RESULTS[$WHAT]=${PIPESTATUS[0]}
grep TOTAL $LOGFILE | awk '{ print "TOTAL: "$4; }'
rm $LOGFILE
}
coverage_command() {
if [ -n "$WELL_FORMED_REPO" -a "$1" == "$CURRENT_REPO_NAME" ]; then
echo "--with-coverage --cover-package=$CURRENT_REPO_NAME --cover-erase"
fi
}
print_summary () {
echo
echo " Results "
echo " ====================================="
for WHAT in ${!RESULTS[*]}; do
RESULT=${RESULTS[$WHAT]}
if [ -z "$RESULT" ]; then
MSG="didn't run"
elif [ $RESULT -ne 0 ]; then
MSG='FAILURE'
else
MSG='SUCCESS'
fi
printf ' %-30s%s\n' $WHAT $MSG
done
echo
}
appropriate_exit() {
SUM=0
for what in ${!RESULTS[*]}
do
SUM=$(($SUM + ${RESULTS[$what]}))
done
exit $SUM
}
main "$@"