blob: b88c22a169fd20fa3a51eca684befb246121c152 [file] [log] [blame]
Lev Walkincb523912017-09-30 19:33:23 -07001#!/bin/sh
2
3#
4# Create an ASN.1 source code project for each line in each of the
5# bundles/*.txt files, compile and run that it can be encoded, decoded,
6# and fuzzed (if fuzzing is available).
7#
8
9set -e
10
Lev Walkincb523912017-09-30 19:33:23 -070011usage() {
12 echo "Usage:"
13 echo " $0 -h"
Lev Walkin93f372b2017-10-03 16:39:38 -070014 echo " $0 [--dirty] -t \"<ASN.1 text defining type T, in string form>\""
15 echo " $0 [--dirty] bundles/<bundle-name.txt> [<line>]"
Lev Walkin8cec5232017-10-03 15:05:54 -070016 echo "Where options are:"
Lev Walkin43292722017-10-05 00:33:32 -070017 echo " -h Show this help screen"
18 echo " -e <syntax> Verify a given encoding explicitly (default is ALL)"
19 echo " --asn1c <flag> Add this flag to asn1c"
20 echo " --dirty Reuse compile results from the previous run(s)"
21 echo " -t <ASN.1> Run this particular typel"
Lev Walkincb523912017-09-30 19:33:23 -070022 echo "Examples:"
23 echo " $0 -t UTF8String"
24 echo " $0 -t \"T ::= INTEGER (0..1)\""
25 echo " $0 bundles/01-INTEGER-bundle.txt 3"
26 exit 1
27}
28
Lev Walkind3cce462017-10-01 13:43:36 -070029RNDTEMP=.tmp.random
30
31srcdir="${srcdir:-.}"
32abs_top_srcdir="${abs_top_srcdir:-$(pwd)/../../}"
33abs_top_builddir="${abs_top_builddir:-$(pwd)/../../}"
34
Lev Walkincb523912017-09-30 19:33:23 -070035tests_succeeded=0
36tests_failed=0
Lev Walkind3cce462017-10-01 13:43:36 -070037stop_after_failed=1 # We stop after 3 failures.
Lev Walkin8cec5232017-10-03 15:05:54 -070038need_clean_before_bundle=1 # Clean before testing a bundle file
39need_clean_before_test=1 # Before each line in a bundle file
Lev Walkin68619bf2017-10-03 18:40:36 -070040encodings="" # Default is to verify all supported ASN.1 transfer syntaxes
41parallelism=4
Lev Walkin43292722017-10-05 00:33:32 -070042asn1c_flags=""
Lev Walkin8cec5232017-10-03 15:05:54 -070043
44make_clean_before_bundle() {
Lev Walkin945958e2017-10-05 01:09:23 -070045 test "${need_clean_before_bundle}" = "1" && rm -rf ${RNDTEMP}
Lev Walkin8cec5232017-10-03 15:05:54 -070046}
47
48make_clean_before_test() {
Lev Walkin945958e2017-10-05 01:09:23 -070049 test "${need_clean_before_test}" = "1" && rm -rf ${RNDTEMP}
Lev Walkin8cec5232017-10-03 15:05:54 -070050}
Lev Walkincb523912017-09-30 19:33:23 -070051
52# Get all the type-bearding lines in file and process them individually
53verify_asn_types_in_file() {
54 local filename="$1"
55 local need_line="$2"
56 test "x$filename" != "x" || usage
Lev Walkin8cec5232017-10-03 15:05:54 -070057
58 make_clean_before_bundle
59
Lev Walkincb523912017-09-30 19:33:23 -070060 echo "Open [$filename]"
61 local line=0
Lev Walkind28b45f2017-10-05 22:09:19 -070062 while read -r asn; do
Lev Walkincb523912017-09-30 19:33:23 -070063 line=$((line+1))
64 if echo "$asn" | sed -e 's/--.*//;' | grep -vqi "[A-Z]"; then
65 # Ignore lines consisting of just comments.
66 continue;
67 fi
Lev Walkind28b45f2017-10-05 22:09:19 -070068 if [ "x$need_line" != "x" ] && [ "$need_line" != "$line" ]; then
Lev Walkincb523912017-09-30 19:33:23 -070069 # We need a different line.
70 continue;
71 fi
72 verify_asn_type "$asn" "in $filename $line"
Lev Walkind3cce462017-10-01 13:43:36 -070073 if [ "${tests_failed}" = "${stop_after_failed}" ]; then
74 echo "STOP after ${tests_failed} failures, OK ${tests_succeeded}"
75 exit 1
76 fi
Lev Walkincb523912017-09-30 19:33:23 -070077 done < "$filename"
78}
79
80verify_asn_type() {
81 local asn="$1"
82 shift
83 local where="$*"
84 test "x$asn" != "x" || usage
Lev Walkin8cec5232017-10-03 15:05:54 -070085
Lev Walkincb523912017-09-30 19:33:23 -070086 if echo "$asn" | grep -qv "::="; then
87 asn="T ::= $asn"
88 fi
89 echo "Testing [$asn] ${where}"
90
Lev Walkind3cce462017-10-01 13:43:36 -070091 mkdir -p ${RNDTEMP}
Lev Walkin791d3b72017-10-02 16:24:28 -070092 if (set -e && cd ${RNDTEMP} && compile_and_test "$asn" "${where}"); then
Lev Walkincb523912017-09-30 19:33:23 -070093 echo "OK [$asn] ${where}"
94 tests_succeeded=$((tests_succeeded+1))
95 else
96 tests_failed=$((tests_failed+1))
97 echo "FAIL [$asn] ${where}"
98 fi
99}
100
Lev Walkin43292722017-10-05 00:33:32 -0700101# compile_and_test "<text>" "<where found>" [<asn.1 flags>]
Lev Walkincb523912017-09-30 19:33:23 -0700102compile_and_test() {
Lev Walkin43292722017-10-05 00:33:32 -0700103 if [ "x${asn1c_flags}" != "x" ]; then
104 if ! compile_and_test_with "$@" ${asn1c_flags} ; then
105 return 1
106 fi
107 else
108 if ! compile_and_test_with "$@" ; then
109 echo "Can't compile and test narrow"
110 return 1
111 fi
Lev Walkincb523912017-09-30 19:33:23 -0700112
Lev Walkin43292722017-10-05 00:33:32 -0700113 if ! compile_and_test_with "$@" "-fwide-types"; then
114 echo "Can't compile and test wide"
115 return 2
116 fi
117 fi
118
119 return 0
120}
121
122compile_and_test_with() {
123 local asn="$1"
124 local where="$2"
125 shift 2
126
127 make_clean_before_test
128
129 if ! asn_compile "$asn" "$where" "$@"; then
Lev Walkincb523912017-09-30 19:33:23 -0700130 echo "Cannot compile ASN.1 $asn"
131 return 1
132 fi
133
134 rm -f random-test-driver.o
135 rm -f random-test-driver
Lev Walkin68619bf2017-10-03 18:40:36 -0700136 if ! make -j${parallelism}; then
Lev Walkind3cce462017-10-01 13:43:36 -0700137 echo "Cannot compile C for $asn in ${RNDTEMP}"
Lev Walkincb523912017-09-30 19:33:23 -0700138 return 2
139 fi
140
Lev Walkin791d3b72017-10-02 16:24:28 -0700141 # Maximum size of the random data
142 local rmax=$(echo "$asn" | sed -Ee '/RMAX/!d;s/.*RMAX=([0-9]+).*/\1/')
143 if [ "0${rmax}" -lt 1 ]; then rmax=128; fi
144
Lev Walkincb523912017-09-30 19:33:23 -0700145 echo "Checking random data encode-decode"
Lev Walkind28b45f2017-10-05 22:09:19 -0700146 local round_trip_check_cmd="${ASAN_ENV_FLAGS} ./random-test-driver -s ${rmax} ${encodings} -c"
147 if ! eval "$round_trip_check_cmd"; then
Lev Walkincec390d2017-10-03 16:36:17 -0700148 if [ "x$CC" = "x" ]; then CCSTR=""; else CCSTR="CC=${CC} "; fi
Lev Walkind3cce462017-10-01 13:43:36 -0700149 echo "RETRY:"
Lev Walkin68619bf2017-10-03 18:40:36 -0700150 echo "(cd ${RNDTEMP} && ${CCSTR}CFLAGS=\"${LIBFUZZER_CFLAGS} ${CFLAGS}\" make && ${ASAN_ENV_FLAGS} ./random-test-driver -s ${rmax} ${encodings} -c)"
Lev Walkincb523912017-09-30 19:33:23 -0700151 return 3
152 fi
153
Lev Walkind3cce462017-10-01 13:43:36 -0700154 echo "Generating new random data"
155 rm -rf random-data
156 cmd="${ASAN_ENV_FLAGS} UBSAN_OPTIONS=print_stacktrace=1"
Lev Walkind28b45f2017-10-05 22:09:19 -0700157 cmd="${cmd} ./random-test-driver -s ${rmax} ${encodings} -g random-data"
Lev Walkind3cce462017-10-01 13:43:36 -0700158 if ! eval "$cmd" ; then
159 echo "RETRY:"
160 echo "(cd ${RNDTEMP} && $cmd)"
161 return 4
162 fi
163
Lev Walkin233d14d2017-10-02 01:09:01 -0700164 # Do a LibFuzzer based testing
165 local fuzz_time=10
166 local fuzz_cmd="${ASAN_ENV_FLAGS} UBSAN_OPTIONS=print_stacktrace=1"
Lev Walkind28b45f2017-10-05 22:09:19 -0700167 fuzz_cmd="${fuzz_cmd} ./random-test-driver"
168 fuzz_cmd="${fuzz_cmd} -timeout=3 -max_total_time=${fuzz_time} -max_len=128"
Lev Walkin233d14d2017-10-02 01:09:01 -0700169
170 if ! grep -q "^fuzz:" Makefile ; then
171 local fuzz_targets=$(echo random-data/* | sed -e 's/random-data./fuzz-/g')
Lev Walkind28b45f2017-10-05 22:09:19 -0700172 {
173 echo "fuzz: $fuzz_targets"
174 echo "fuzz-%: random-data/% random-test-driver"
175 echo " ASN1_DATA_DIR=\$< ${fuzz_cmd} \$<"
176 } >> Makefile
Lev Walkin233d14d2017-10-02 01:09:01 -0700177 fi
178
Lev Walkincb523912017-09-30 19:33:23 -0700179 # If LIBFUZZER_CFLAGS are properly defined, do the fuzz test as well
180 if echo "${LIBFUZZER_CFLAGS}" | grep -qi "[a-z]"; then
Lev Walkincb523912017-09-30 19:33:23 -0700181
182 echo "Recompiling for fuzzing..."
183 rm -f random-test-driver.o
184 rm -f random-test-driver
Lev Walkin68619bf2017-10-03 18:40:36 -0700185 CFLAGS="${LIBFUZZER_CFLAGS} ${CFLAGS}" make -j${parallelism}
Lev Walkincb523912017-09-30 19:33:23 -0700186
Lev Walkind28b45f2017-10-05 22:09:19 -0700187 echo "Fuzzing will take a multiple of $fuzz_time seconds..."
Lev Walkin68619bf2017-10-03 18:40:36 -0700188 if ! make -j${parallelism} fuzz ; then
Lev Walkin233d14d2017-10-02 01:09:01 -0700189 echo "RETRY:"
190 echo "(cd ${RNDTEMP} && CC=${CC} CFLAGS=\"${LIBFUZZER_CFLAGS} ${CFLAGS}\" make fuzz)"
191 return 5
192 fi
Lev Walkincb523912017-09-30 19:33:23 -0700193 fi
194
Lev Walkina5b02882017-10-01 22:48:44 -0700195 return 0
Lev Walkincb523912017-09-30 19:33:23 -0700196}
197
Lev Walkincb523912017-09-30 19:33:23 -0700198asn_compile() {
199 local asn="$1"
Lev Walkin43292722017-10-05 00:33:32 -0700200 local where="$2"
201 shift 2
Lev Walkind3cce462017-10-01 13:43:36 -0700202
Lev Walkin5d947a82017-10-03 01:04:03 -0700203 # Create "INTEGER (1..2)" from "T ::= INTEGER (1..2) -- RMAX=5"
Lev Walkin791d3b72017-10-02 16:24:28 -0700204 local short_asn=$(echo "$asn" | sed -e 's/ *--.*//;s/RMAX=[^ ]* //;')
Lev Walkind3cce462017-10-01 13:43:36 -0700205 if [ $(echo "$short_asn" | grep -c "::=") = 1 ]; then
206 short_asn=$(echo "$short_asn" | sed -e 's/.*::= *//')
207 fi
208
Lev Walkincb523912017-09-30 19:33:23 -0700209 test ! -f Makefile.am # Protection from accidental clobbering
210 echo "Test DEFINITIONS ::= BEGIN $asn" > test.asn1
Lev Walkin43292722017-10-05 00:33:32 -0700211 echo "-- ${where}" >> test.asn1
Lev Walkincb523912017-09-30 19:33:23 -0700212 echo "END" >> test.asn1
Lev Walkind28b45f2017-10-05 22:09:19 -0700213 if ! "${abs_top_builddir}/asn1c/asn1c" -S "${abs_top_srcdir}/skeletons" \
Lev Walkin43292722017-10-05 00:33:32 -0700214 -gen-OER -gen-PER "$@" test.asn1
Lev Walkina5b02882017-10-01 22:48:44 -0700215 then
216 return 1
217 fi
Lev Walkincb523912017-09-30 19:33:23 -0700218 rm -f converter-example.c
219 ln -sf ../random-test-driver.c || cp ../random-test-driver.c .
Lev Walkind3cce462017-10-01 13:43:36 -0700220 echo "CFLAGS+= -DASN1_TEXT='$short_asn'" > Makefile
Lev Walkincb523912017-09-30 19:33:23 -0700221 sed -e 's/converter-example/random-test-driver/' \
Lev Walkind3cce462017-10-01 13:43:36 -0700222 < Makefile.am.example >> Makefile
Lev Walkincb523912017-09-30 19:33:23 -0700223 echo "Makefile.am.example -> Makefile"
224}
225
226# Command line parsing
Lev Walkin68619bf2017-10-03 18:40:36 -0700227while :; do
228 case "$1" in
229 -h) usage ;;
Lev Walkind28b45f2017-10-05 22:09:19 -0700230 --asn1c) asn1c_flags="${asn1c_flags} $2"; shift 2; continue ;;
Lev Walkin68619bf2017-10-03 18:40:36 -0700231 --dirty)
232 need_clean_before_bundle=0
233 need_clean_before_test=0
234 shift
235 continue
236 ;;
Lev Walkind28b45f2017-10-05 22:09:19 -0700237 -e) encodings="${encodings} -e $2"; shift 2; continue;;
Lev Walkin68619bf2017-10-03 18:40:36 -0700238 -j) parallelism="$1"; shift 2; continue;;
239 -t)
240 parallelism=1 # Better for debuggability
241 verify_asn_type "$2" || exit 1 ;;
242 "")
243 for bundle in $(echo bundles/*txt | sort -nr); do
244 verify_asn_types_in_file "$bundle"
245 done
246 ;;
247 *)
248 verify_asn_types_in_file "$@"
249 ;;
250 esac
251 break
252done
Lev Walkincb523912017-09-30 19:33:23 -0700253
Lev Walkind28b45f2017-10-05 22:09:19 -0700254if [ "$tests_succeeded" != "0" ] && [ "$tests_failed" = "0" ]; then
Lev Walkincb523912017-09-30 19:33:23 -0700255 echo "OK $tests_succeeded tests"
256else
257 echo "FAILED $tests_failed tests, OK $tests_succeeded tests"
258 exit 1
259fi