• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /bin/sh
2#
3# Copyright (c) 2018-2019 Gavin D. Howard and contributors.
4#
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10# * Redistributions of source code must retain the above copyright notice, this
11#   list of conditions and the following disclaimer.
12#
13# * Redistributions in binary form must reproduce the above copyright notice,
14#   this list of conditions and the following disclaimer in the documentation
15#   and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30usage() {
31	printf 'usage: %s [run_tests] [generate_tests] [test_with_clang] [test_with_gcc] \n' "$script"
32	printf '          [run_sanitizers] [run_valgrind] [run_64_bit] [run_gen_script]\n'
33	exit 1
34}
35
36header() {
37
38	_header_msg="$1"
39	shift
40
41	printf '\n'
42	printf '*******************\n'
43	printf "$_header_msg"
44	printf '\n'
45	printf '*******************\n'
46	printf '\n'
47}
48
49do_make() {
50	make -j4 "$@"
51}
52
53configure() {
54
55	_configure_CFLAGS="$1"
56	shift
57
58	_configure_CC="$1"
59	shift
60
61	_configure_configure_flags="-f $1"
62	shift
63
64	_configure_GEN_HOST="$1"
65	shift
66
67	_configure_LONG_BIT="$1"
68	shift
69
70	if [ "$gen_tests" -eq 0 ]; then
71		_configure_configure_flags="-G $_configure_configure_flags"
72	fi
73
74	if [ "$_configure_CC" = "clang" ]; then
75		_configure_CFLAGS="$clang_flags $_configure_CFLAGS"
76	elif [ "$_configure_CC" = "gcc" ]; then
77		_configure_CFLAGS="$gcc_flags $_configure_CFLAGS"
78	fi
79
80	_configure_header=$(printf 'Running ./configure.sh %s ...' "$_configure_configure_flags")
81	_configure_header=$(printf "$_configure_header\n    CC=\"%s\"\n" "$_configure_CC")
82	_configure_header=$(printf "$_configure_header\n    CFLAGS=\"%s\"\n" "$_configure_CFLAGS")
83	_configure_header=$(printf "$_configure_header\n    LONG_BIT=%s" "$_configure_LONG_BIT")
84	_configure_header=$(printf "$_configure_header\n    GEN_HOST=%s" "$_configure_GEN_HOST")
85
86	header "$_configure_header"
87	CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \
88		LONG_BIT="$_configure_LONG_BIT" ./configure.sh $_configure_configure_flags > /dev/null
89
90}
91
92build() {
93
94	_build_CFLAGS="$1"
95	shift
96
97	_build_CC="$1"
98	shift
99
100	_build_configure_flags="$1"
101	shift
102
103	_build_GEN_HOST="$1"
104	shift
105
106	_build_LONG_BIT="$1"
107	shift
108
109	configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT"
110
111	_build_header=$(printf 'Building...\n    CC=%s' "$_build_CC")
112	_build_header=$(printf "$_build_header\n    CFLAGS=\"%s\"" "$_build_CFLAGS")
113	_build_header=$(printf "$_build_header\n    LONG_BIT=%s" "$_build_LONG_BIT")
114	_build_header=$(printf "$_build_header\n    GEN_HOST=%s" "$_build_GEN_HOST")
115
116	header "$_build_header"
117
118	do_make > /dev/null 2> "$scriptdir/.test.txt"
119
120	if [ -s "$scriptdir/.test.txt" ]; then
121		printf '%s generated warning(s):\n' "$_build_CC"
122		printf '\n'
123		cat "$scriptdir/.test.txt"
124		exit 1
125	fi
126}
127
128runtest() {
129
130	header "Running tests"
131
132	if [ "$#" -gt 0 ]; then
133		do_make "$@"
134	else
135		do_make test
136	fi
137}
138
139runconfigtests() {
140
141	_runconfigtests_CFLAGS="$1"
142	shift
143
144	_runconfigtests_CC="$1"
145	shift
146
147	_runconfigtests_configure_flags="$1"
148	shift
149
150	_runconfigtests_GEN_HOST="$1"
151	shift
152
153	_runconfigtests_LONG_BIT="$1"
154	shift
155
156	_runconfigtests_run_tests="$1"
157	shift
158
159	if [ "$_runconfigtests_run_tests" -ne 0 ]; then
160		_runconfigtests_header=$(printf 'Running tests with configure flags')
161	else
162		_runconfigtests_header=$(printf 'Building with configure flags')
163	fi
164
165	_runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags")
166	_runconfigtests_header=$(printf "$_runconfigtests_header\n    CC=%s\n" "$_runconfigseries_CC")
167	_runconfigtests_header=$(printf "$_runconfigtests_header\n    CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS")
168	_runconfigtests_header=$(printf "$_runconfigtests_header\n    LONG_BIT=%s" "$_runconfigtests_LONG_BIT")
169	_runconfigtests_header=$(printf "$_runconfigtests_header\n    GEN_HOST=%s" "$_runconfigtests_GEN_HOST")
170
171	header "$_runconfigtests_header"
172
173	build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \
174		"$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \
175		"$_runconfigtests_LONG_BIT"
176
177	if [ "$_runconfigtests_run_tests" -ne 0 ]; then
178		runtest
179	fi
180
181	do_make clean
182
183	build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \
184		"$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \
185		"$_runconfigtests_LONG_BIT"
186
187	if [ "$_runconfigtests_run_tests" -ne 0 ]; then
188		runtest
189	fi
190
191	do_make clean
192
193	build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \
194		"$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \
195		"$_runconfigtests_LONG_BIT"
196
197	if [ "$_runconfigtests_run_tests" -ne 0 ]; then
198		runtest
199	fi
200
201	do_make clean
202}
203
204runconfigseries() {
205
206	_runconfigseries_CFLAGS="$1"
207	shift
208
209	_runconfigseries_CC="$1"
210	shift
211
212	_runconfigseries_configure_flags="$1"
213	shift
214
215	_runconfigseries_run_tests="$1"
216	shift
217
218	if [ "$run_64_bit" -ne 0 ]; then
219
220		runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
221			"$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests"
222
223		if [ "$run_gen_script" -ne 0 ]; then
224			runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
225				"$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests"
226		fi
227
228	fi
229
230	runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
231		"$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests"
232
233	if [ "$run_gen_script" -ne 0 ]; then
234		runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
235			"$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests"
236	fi
237}
238
239runtestseries() {
240
241	_runtestseries_CFLAGS="$1"
242	shift
243
244	_runtestseries_CC="$1"
245	shift
246
247	_runtestseries_configure_flags="$1"
248	shift
249
250	_runtestseries_run_tests="$1"
251	shift
252
253	_runtestseries_flags="E H N P S EH EN EP ES HN HP HS NP NS PS EHN EHP EHS
254		ENP ENS EPS HNP HNS HPS NPS EHNP EHNS EHPS ENPS HNPS EHNPS"
255
256	runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \
257		"$_runtestseries_configure_flags" "$_runtestseries_run_tests"
258
259	for f in $_runtestseries_flags; do
260		runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \
261			"$_runtestseries_configure_flags -$f" "$_runtestseries_run_tests"
262	done
263}
264
265runtests() {
266
267	_runtests_CFLAGS="$1"
268	shift
269
270	_runtests_CC="$1"
271	shift
272
273	_runtests_configure_flags="$1"
274	shift
275
276	_runtests_run_tests="$1"
277	shift
278
279	runtestseries "$_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests"
280}
281
282karatsuba() {
283
284	header "Running Karatsuba tests"
285	do_make karatsuba_test
286}
287
288vg() {
289
290	header "Running valgrind"
291
292	if [ "$run_64_bit" -ne 0 ]; then
293		_vg_bits=64
294	else
295		_vg_bits=32
296	fi
297
298	build "$debug" "gcc" "-O0 -g" "1" "$_vg_bits"
299	runtest valgrind
300
301	do_make clean_config
302
303	build "$debug" "gcc" "-O0 -gb" "1" "$_vg_bits"
304	runtest valgrind
305
306	do_make clean_config
307
308	build "$debug" "gcc" "-O0 -gd" "1" "$_vg_bits"
309	runtest valgrind
310
311	do_make clean_config
312}
313
314debug() {
315
316	_debug_CC="$1"
317	shift
318
319	_debug_run_tests="$1"
320	shift
321
322	runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests"
323
324	if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
325		runtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests"
326	fi
327}
328
329release() {
330
331	_release_CC="$1"
332	shift
333
334	_release_run_tests="$1"
335	shift
336
337	runtests "$release" "$_release_CC" "-O3" "$_release_run_tests"
338}
339
340reldebug() {
341
342	_reldebug_CC="$1"
343	shift
344
345	_reldebug_run_tests="$1"
346	shift
347
348	runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
349
350	if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
351		runtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
352		runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
353	fi
354}
355
356minsize() {
357
358	_minsize_CC="$1"
359	shift
360
361	_minsize_run_tests="$1"
362	shift
363
364	runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests"
365}
366
367build_set() {
368
369	_build_set_CC="$1"
370	shift
371
372	_build_set_run_tests="$1"
373	shift
374
375	debug "$_build_set_CC" "$_build_set_run_tests"
376	release "$_build_set_CC" "$_build_set_run_tests"
377	reldebug "$_build_set_CC" "$_build_set_run_tests"
378	minsize "$_build_set_CC" "$_build_set_run_tests"
379}
380
381clang_flags="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral"
382clang_flags="$clang_flags -Wno-cast-align -Wno-missing-noreturn -Wno-disabled-macro-expansion"
383clang_flags="$clang_flags -Wno-unreachable-code -Wno-unreachable-code-return"
384gcc_flags="-Wno-maybe-uninitialized"
385
386cflags="-Wall -Wextra -Werror -pedantic -std=c99 -Wno-conditional-uninitialized"
387
388debug="$cflags -fno-omit-frame-pointer"
389release="$cflags -DNDEBUG"
390
391set -e
392
393script="$0"
394scriptdir=$(dirname "$script")
395
396if [ "$#" -gt 0 ]; then
397	run_tests="$1"
398	shift
399else
400	run_tests=1
401fi
402
403if [ "$#" -gt 0 ]; then
404	gen_tests="$1"
405	shift
406else
407	gen_tests=1
408fi
409
410if [ "$#" -gt 0 ]; then
411	test_with_clang="$1"
412	shift
413else
414	test_with_clang=1
415fi
416
417if [ "$#" -gt 0 ]; then
418	test_with_gcc="$1"
419	shift
420else
421	test_with_gcc=1
422fi
423
424if [ "$#" -gt 0 ]; then
425	run_sanitizers="$1"
426	shift
427else
428	run_sanitizers=1
429fi
430
431if [ "$#" -gt 0 ]; then
432	run_valgrind="$1"
433	shift
434else
435	run_valgrind=1
436fi
437
438if [ "$#" -gt 0 ]; then
439	run_64_bit="$1"
440	shift
441else
442	run_64_bit=1
443fi
444
445if [ "$#" -gt 0 ]; then
446	run_gen_script="$1"
447	shift
448else
449	run_gen_script=0
450fi
451
452if [ "$run_64_bit" -ne 0 ]; then
453	bits=64
454else
455	bits=32
456fi
457
458cd "$scriptdir"
459
460if [ "$test_with_clang" -ne 0 ]; then
461	defcc="clang"
462elif [ "$test_with_gcc" -ne 0 ]; then
463	defcc="gcc"
464else
465	defcc="c99"
466fi
467
468build "$debug" "$defcc" "-g" "1" "$bits"
469
470header "Running math library under --standard"
471
472printf 'quit\n' | bin/bc -ls
473
474version=$(make version)
475
476do_make clean_tests
477
478if [ "$test_with_clang" -ne 0 ]; then
479	build_set "clang" "$run_tests"
480fi
481
482if [ "$test_with_gcc" -ne 0 ]; then
483	build_set "gcc" "$run_tests"
484fi
485
486if [ "$run_tests" -ne 0 ]; then
487
488	build "$release" "$defcc" "-O3" "1" "$bits"
489
490	karatsuba
491
492	if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then
493		vg
494	fi
495
496	printf '\n'
497	printf 'Tests successful.\n'
498
499	set +e
500
501	command -v afl-gcc > /dev/null 2>&1
502	err="$?"
503
504	set -e
505
506	if [ "$err" -eq 0 ]; then
507
508		header "Configuring for afl-gcc..."
509
510		configure "$debug" "afl-gcc" "-HNPS -gO3" "1" "$bits"
511
512		printf '\n'
513		printf 'Run make\n'
514		printf '\n'
515		printf 'Then run %s/tests/randmath.py and the fuzzer.\n' "$scriptdir"
516		printf '\n'
517		printf 'Then run ASan on the fuzzer test cases with the following build:\n'
518		printf '\n'
519		printf '    CFLAGS="-fsanitize=address -fno-omit-frame-pointer" ./configure.sh -gO3 -HNPS\n'
520		printf '    make\n'
521		printf '\n'
522		printf 'Then run the GitHub release script as follows:\n'
523		printf '\n'
524		printf '    <github_release> %s .travis.yml codecov.yml release.sh \\\n' "$version"
525		printf '    RELEASE.md tests/afl.py tests/randmath.py tests/bc/scripts/timeconst.bc\n'
526
527	fi
528
529fi
530