xref: /aosp_15_r20/external/fsverity-utils/scripts/run-tests.sh (revision b13c0e4024008a1f948ee8189745cb3371f4ac04)
1*b13c0e40SEric Biggers#!/bin/bash
2*b13c0e40SEric Biggers# SPDX-License-Identifier: MIT
3*b13c0e40SEric Biggers# Copyright 2020 Google LLC
4*b13c0e40SEric Biggers#
5*b13c0e40SEric Biggers# Use of this source code is governed by an MIT-style
6*b13c0e40SEric Biggers# license that can be found in the LICENSE file or at
7*b13c0e40SEric Biggers# https://opensource.org/licenses/MIT.
8*b13c0e40SEric Biggers#
9*b13c0e40SEric Biggers#
10*b13c0e40SEric Biggers# Test script for fsverity-utils.  Runs 'make check' in lots of configurations,
11*b13c0e40SEric Biggers# runs static analysis, and does a few other tests.
12*b13c0e40SEric Biggers#
13*b13c0e40SEric Biggers# Note: for more test coverage, in addition to running this script, also build
14*b13c0e40SEric Biggers# fsverity-utils into a kvm-xfstests test appliance and run
15*b13c0e40SEric Biggers# 'kvm-xfstests -c ext4,f2fs -g verity'
16*b13c0e40SEric Biggers
17*b13c0e40SEric Biggersset -e -u -o pipefail
18*b13c0e40SEric Biggerscd "$(dirname "$0")/.."
19*b13c0e40SEric Biggers
20*b13c0e40SEric Biggerslog()
21*b13c0e40SEric Biggers{
22*b13c0e40SEric Biggers	echo "[$(date)] $*" 1>&2
23*b13c0e40SEric Biggers}
24*b13c0e40SEric Biggers
25*b13c0e40SEric Biggersfail()
26*b13c0e40SEric Biggers{
27*b13c0e40SEric Biggers	echo "FAIL: $*" 1>&2
28*b13c0e40SEric Biggers	exit 1
29*b13c0e40SEric Biggers}
30*b13c0e40SEric Biggers
31*b13c0e40SEric BiggersTMPDIR=$(mktemp -d -t libfsverity_test.XXXXXXXXX)
32*b13c0e40SEric Biggerstrap 'rm -r "$TMPDIR"' EXIT
33*b13c0e40SEric Biggers
34*b13c0e40SEric Biggers# Both stdout and stderr go to log file.
35*b13c0e40SEric Biggers# Only stderr goes to terminal.
36*b13c0e40SEric Biggersecho "Starting fsverity-utils tests.  See run-tests.log for full output."
37*b13c0e40SEric Biggersrm -f run-tests.log
38*b13c0e40SEric Biggersexec >> run-tests.log
39*b13c0e40SEric Biggersexec 2> >(tee -ia run-tests.log 1>&2)
40*b13c0e40SEric Biggers
41*b13c0e40SEric BiggersMAKE="make -j$(getconf _NPROCESSORS_ONLN)"
42*b13c0e40SEric Biggers
43*b13c0e40SEric BiggersTEST_FUNCS=()
44*b13c0e40SEric Biggers
45*b13c0e40SEric Biggersstatic_linking_test()
46*b13c0e40SEric Biggers{
47*b13c0e40SEric Biggers	log "Build and test with statically linking"
48*b13c0e40SEric Biggers	$MAKE CFLAGS="-Werror"
49*b13c0e40SEric Biggers	if ldd fsverity | grep libfsverity.so; then
50*b13c0e40SEric Biggers		fail "fsverity binary should be statically linked to libfsverity by default"
51*b13c0e40SEric Biggers	fi
52*b13c0e40SEric Biggers	./fsverity --version
53*b13c0e40SEric Biggers
54*b13c0e40SEric Biggers	log "Check that all global symbols are prefixed with \"libfsverity_\""
55*b13c0e40SEric Biggers	if nm libfsverity.a | grep ' T ' | grep -v " libfsverity_"; then
56*b13c0e40SEric Biggers		fail "Some global symbols are not prefixed with \"libfsverity_\""
57*b13c0e40SEric Biggers	fi
58*b13c0e40SEric Biggers}
59*b13c0e40SEric BiggersTEST_FUNCS+=(static_linking_test)
60*b13c0e40SEric Biggers
61*b13c0e40SEric Biggersdynamic_linking_test()
62*b13c0e40SEric Biggers{
63*b13c0e40SEric Biggers	log "Build and test with dynamic linking"
64*b13c0e40SEric Biggers	$MAKE CFLAGS="-Werror" USE_SHARED_LIB=1 check
65*b13c0e40SEric Biggers	if ! ldd fsverity | grep libfsverity.so; then
66*b13c0e40SEric Biggers		fail "fsverity binary should be dynamically linked to libfsverity when USE_SHARED_LIB=1"
67*b13c0e40SEric Biggers	fi
68*b13c0e40SEric Biggers
69*b13c0e40SEric Biggers	log "Check that all exported symbols are prefixed with \"libfsverity_\""
70*b13c0e40SEric Biggers	if nm libfsverity.so | grep ' T ' | grep -v " libfsverity_"; then
71*b13c0e40SEric Biggers		fail "Some exported symbols are not prefixed with \"libfsverity_\""
72*b13c0e40SEric Biggers	fi
73*b13c0e40SEric Biggers}
74*b13c0e40SEric BiggersTEST_FUNCS+=(dynamic_linking_test)
75*b13c0e40SEric Biggers
76*b13c0e40SEric Biggerscplusplus_test()
77*b13c0e40SEric Biggers{
78*b13c0e40SEric Biggers	$MAKE CFLAGS="-Werror" libfsverity.so
79*b13c0e40SEric Biggers	log "Test using libfsverity from C++ program"
80*b13c0e40SEric Biggers	cat > "$TMPDIR/test.cc" <<EOF
81*b13c0e40SEric Biggers#include <libfsverity.h>
82*b13c0e40SEric Biggers#include <iostream>
83*b13c0e40SEric Biggersint main()
84*b13c0e40SEric Biggers{
85*b13c0e40SEric Biggers	std::cout << libfsverity_get_digest_size(FS_VERITY_HASH_ALG_SHA256) << std::endl;
86*b13c0e40SEric Biggers}
87*b13c0e40SEric BiggersEOF
88*b13c0e40SEric Biggers	c++ -Wall -Werror "$TMPDIR/test.cc" -Iinclude -L. -lfsverity -o "$TMPDIR/test"
89*b13c0e40SEric Biggers	[ "$(LD_LIBRARY_PATH=. "$TMPDIR/test")" = "32" ]
90*b13c0e40SEric Biggers	rm "${TMPDIR:?}"/*
91*b13c0e40SEric Biggers}
92*b13c0e40SEric BiggersTEST_FUNCS+=(cplusplus_test)
93*b13c0e40SEric Biggers
94*b13c0e40SEric Biggersuntracked_files_test()
95*b13c0e40SEric Biggers{
96*b13c0e40SEric Biggers	log "Check that build doesn't produce untracked files"
97*b13c0e40SEric Biggers	$MAKE CFLAGS="-Werror" all test_programs
98*b13c0e40SEric Biggers	if git status --short | grep -q '^??'; then
99*b13c0e40SEric Biggers		git status
100*b13c0e40SEric Biggers		fail "Build produced untracked files (check 'git status').  Missing gitignore entry?"
101*b13c0e40SEric Biggers	fi
102*b13c0e40SEric Biggers}
103*b13c0e40SEric BiggersTEST_FUNCS+=(untracked_files_test)
104*b13c0e40SEric Biggers
105*b13c0e40SEric Biggersuninstall_test()
106*b13c0e40SEric Biggers{
107*b13c0e40SEric Biggers	log "Test that 'make uninstall' uninstalls all files"
108*b13c0e40SEric Biggers	make DESTDIR="$TMPDIR" install
109*b13c0e40SEric Biggers	if [ "$(find "$TMPDIR" -type f -o -type l | wc -l)" = 0 ]; then
110*b13c0e40SEric Biggers		fail "'make install' didn't install any files"
111*b13c0e40SEric Biggers	fi
112*b13c0e40SEric Biggers	make DESTDIR="$TMPDIR" uninstall
113*b13c0e40SEric Biggers	if [ "$(find "$TMPDIR" -type f -o -type l | wc -l)" != 0 ]; then
114*b13c0e40SEric Biggers		fail "'make uninstall' didn't uninstall all files"
115*b13c0e40SEric Biggers	fi
116*b13c0e40SEric Biggers	rm -r "${TMPDIR:?}"/*
117*b13c0e40SEric Biggers}
118*b13c0e40SEric BiggersTEST_FUNCS+=(uninstall_test)
119*b13c0e40SEric Biggers
120*b13c0e40SEric Biggersdash_test()
121*b13c0e40SEric Biggers{
122*b13c0e40SEric Biggers	log "Build, install, and uninstall with dash"
123*b13c0e40SEric Biggers	make clean SHELL=/bin/dash
124*b13c0e40SEric Biggers	make DESTDIR="$TMPDIR" SHELL=/bin/dash install
125*b13c0e40SEric Biggers	make DESTDIR="$TMPDIR" SHELL=/bin/dash uninstall
126*b13c0e40SEric Biggers}
127*b13c0e40SEric BiggersTEST_FUNCS+=(dash_test)
128*b13c0e40SEric Biggers
129*b13c0e40SEric Biggerslicense_test()
130*b13c0e40SEric Biggers{
131*b13c0e40SEric Biggers	log "Check that all files have license and copyright info"
132*b13c0e40SEric Biggers	list="$TMPDIR/filelist"
133*b13c0e40SEric Biggers	filter_license_info() {
134*b13c0e40SEric Biggers		# files to exclude from license and copyright info checks
135*b13c0e40SEric Biggers		grep -E -v '(\.gitignore|LICENSE|.*\.md|testdata|fsverity_uapi\.h|libfsverity\.pc\.in)'
136*b13c0e40SEric Biggers	}
137*b13c0e40SEric Biggers	git grep -L 'SPDX-License-Identifier: MIT' \
138*b13c0e40SEric Biggers		| filter_license_info > "$list" || true
139*b13c0e40SEric Biggers	if [ -s "$list" ]; then
140*b13c0e40SEric Biggers		fail "The following files are missing an appropriate SPDX license identifier: $(<"$list")"
141*b13c0e40SEric Biggers	fi
142*b13c0e40SEric Biggers	# For now some people still prefer a free-form license statement, not just SPDX.
143*b13c0e40SEric Biggers	git grep -L 'Use of this source code is governed by an MIT-style' \
144*b13c0e40SEric Biggers		| filter_license_info > "$list" || true
145*b13c0e40SEric Biggers	if [ -s "$list" ]; then
146*b13c0e40SEric Biggers		fail "The following files are missing an appropriate license statement: $(<"$list")"
147*b13c0e40SEric Biggers	fi
148*b13c0e40SEric Biggers	git grep -L '\<Copyright\>' | filter_license_info > "$list" || true
149*b13c0e40SEric Biggers	if [ -s "$list" ]; then
150*b13c0e40SEric Biggers		fail "The following files are missing a copyright statement: $(<"$list")"
151*b13c0e40SEric Biggers	fi
152*b13c0e40SEric Biggers	rm "$list"
153*b13c0e40SEric Biggers}
154*b13c0e40SEric BiggersTEST_FUNCS+=(license_test)
155*b13c0e40SEric Biggers
156*b13c0e40SEric Biggersgcc_test()
157*b13c0e40SEric Biggers{
158*b13c0e40SEric Biggers	log "Build and test with gcc (-O2)"
159*b13c0e40SEric Biggers	$MAKE CC=gcc CFLAGS="-O2 -Werror" check
160*b13c0e40SEric Biggers
161*b13c0e40SEric Biggers	log "Build and test with gcc (-O3)"
162*b13c0e40SEric Biggers	$MAKE CC=gcc CFLAGS="-O3 -Werror" check
163*b13c0e40SEric Biggers}
164*b13c0e40SEric BiggersTEST_FUNCS+=(gcc_test)
165*b13c0e40SEric Biggers
166*b13c0e40SEric Biggersclang_test()
167*b13c0e40SEric Biggers{
168*b13c0e40SEric Biggers	log "Build and test with clang (-O2)"
169*b13c0e40SEric Biggers	$MAKE CC=clang CFLAGS="-O2 -Werror" check
170*b13c0e40SEric Biggers
171*b13c0e40SEric Biggers	log "Build and test with clang (-O3)"
172*b13c0e40SEric Biggers	$MAKE CC=clang CFLAGS="-O3 -Werror" check
173*b13c0e40SEric Biggers}
174*b13c0e40SEric BiggersTEST_FUNCS+=(clang_test)
175*b13c0e40SEric Biggers
176*b13c0e40SEric Biggers32bit_test()
177*b13c0e40SEric Biggers{
178*b13c0e40SEric Biggers	log "Build and test with gcc (32-bit)"
179*b13c0e40SEric Biggers	$MAKE CC=gcc CFLAGS="-O2 -Werror -m32" check
180*b13c0e40SEric Biggers}
181*b13c0e40SEric BiggersTEST_FUNCS+=(32bit_test)
182*b13c0e40SEric Biggers
183*b13c0e40SEric Biggerssanitizers_test()
184*b13c0e40SEric Biggers{
185*b13c0e40SEric Biggers	log "Build and test with clang + UBSAN"
186*b13c0e40SEric Biggers	$MAKE CC=clang \
187*b13c0e40SEric Biggers		CFLAGS="-O2 -Werror -fsanitize=undefined -fno-sanitize-recover=undefined" \
188*b13c0e40SEric Biggers		check
189*b13c0e40SEric Biggers
190*b13c0e40SEric Biggers	log "Build and test with clang + ASAN"
191*b13c0e40SEric Biggers	$MAKE CC=clang \
192*b13c0e40SEric Biggers		CFLAGS="-O2 -Werror -fsanitize=address -fno-sanitize-recover=address" \
193*b13c0e40SEric Biggers		check
194*b13c0e40SEric Biggers
195*b13c0e40SEric Biggers	log "Build and test with clang + unsigned integer overflow sanitizer"
196*b13c0e40SEric Biggers	$MAKE CC=clang \
197*b13c0e40SEric Biggers		CFLAGS="-O2 -Werror -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow" \
198*b13c0e40SEric Biggers		check
199*b13c0e40SEric Biggers
200*b13c0e40SEric Biggers	log "Build and test with clang + CFI"
201*b13c0e40SEric Biggers	$MAKE CC=clang CFLAGS="-O2 -Werror -fsanitize=cfi -flto -fvisibility=hidden" \
202*b13c0e40SEric Biggers		AR=llvm-ar check
203*b13c0e40SEric Biggers}
204*b13c0e40SEric BiggersTEST_FUNCS+=(sanitizers_test)
205*b13c0e40SEric Biggers
206*b13c0e40SEric Biggersvalgrind_test()
207*b13c0e40SEric Biggers{
208*b13c0e40SEric Biggers	log "Build and test with valgrind"
209*b13c0e40SEric Biggers	$MAKE TEST_WRAPPER_PROG="valgrind --quiet --error-exitcode=100 --leak-check=full --errors-for-leak-kinds=all" \
210*b13c0e40SEric Biggers		CFLAGS="-O2 -Werror" check
211*b13c0e40SEric Biggers}
212*b13c0e40SEric BiggersTEST_FUNCS+=(valgrind_test)
213*b13c0e40SEric Biggers
214*b13c0e40SEric Biggersboringssl_test()
215*b13c0e40SEric Biggers{
216*b13c0e40SEric Biggers	log "Build and test using BoringSSL instead of OpenSSL"
217*b13c0e40SEric Biggers	log "-> Building BoringSSL"
218*b13c0e40SEric Biggers	$MAKE boringssl
219*b13c0e40SEric Biggers	log "-> Building fsverity-utils linked to BoringSSL"
220*b13c0e40SEric Biggers	$MAKE CFLAGS="-O2 -Werror" LDFLAGS="-Lboringssl/build/crypto" \
221*b13c0e40SEric Biggers		CPPFLAGS="-Iboringssl/include" LDLIBS="-lcrypto -lpthread" check
222*b13c0e40SEric Biggers}
223*b13c0e40SEric BiggersTEST_FUNCS+=(boringssl_test)
224*b13c0e40SEric Biggers
225*b13c0e40SEric Biggersopenssl1_test()
226*b13c0e40SEric Biggers{
227*b13c0e40SEric Biggers	log "Build and test using OpenSSL 1.0"
228*b13c0e40SEric Biggers	$MAKE CFLAGS="-O2 -Werror" LDFLAGS="-L/usr/lib/openssl-1.0" \
229*b13c0e40SEric Biggers		CPPFLAGS="-I/usr/include/openssl-1.0" check
230*b13c0e40SEric Biggers}
231*b13c0e40SEric BiggersTEST_FUNCS+=(openssl1_test)
232*b13c0e40SEric Biggers
233*b13c0e40SEric Biggersopenssl3_test()
234*b13c0e40SEric Biggers{
235*b13c0e40SEric Biggers	log "Build and test using OpenSSL 3.0"
236*b13c0e40SEric Biggers	OSSL3=$HOME/src/openssl/inst/usr/local
237*b13c0e40SEric Biggers	LD_LIBRARY_PATH="$OSSL3/lib64" $MAKE CFLAGS="-O2 -Werror" \
238*b13c0e40SEric Biggers		LDFLAGS="-L$OSSL3/lib64" CPPFLAGS="-I$OSSL3/include" check
239*b13c0e40SEric Biggers}
240*b13c0e40SEric BiggersTEST_FUNCS+=(openssl3_test)
241*b13c0e40SEric Biggers
242*b13c0e40SEric Biggersunsigned_char_test()
243*b13c0e40SEric Biggers{
244*b13c0e40SEric Biggers	log "Build and test using -funsigned-char"
245*b13c0e40SEric Biggers	$MAKE CFLAGS="-O2 -Werror -funsigned-char" check
246*b13c0e40SEric Biggers}
247*b13c0e40SEric BiggersTEST_FUNCS+=(unsigned_char_test)
248*b13c0e40SEric Biggers
249*b13c0e40SEric Biggerssigned_char_test()
250*b13c0e40SEric Biggers{
251*b13c0e40SEric Biggers	log "Build and test using -fsigned-char"
252*b13c0e40SEric Biggers	$MAKE CFLAGS="-O2 -Werror -fsigned-char" check
253*b13c0e40SEric Biggers}
254*b13c0e40SEric BiggersTEST_FUNCS+=(signed_char_test)
255*b13c0e40SEric Biggers
256*b13c0e40SEric Biggerswindows_build_test()
257*b13c0e40SEric Biggers{
258*b13c0e40SEric Biggers	log "Cross-compile for Windows (32-bit)"
259*b13c0e40SEric Biggers	$MAKE CC=i686-w64-mingw32-gcc CFLAGS="-O2 -Werror"
260*b13c0e40SEric Biggers
261*b13c0e40SEric Biggers	log "Cross-compile for Windows (64-bit)"
262*b13c0e40SEric Biggers	$MAKE CC=x86_64-w64-mingw32-gcc CFLAGS="-O2 -Werror"
263*b13c0e40SEric Biggers}
264*b13c0e40SEric BiggersTEST_FUNCS+=(windows_build_test)
265*b13c0e40SEric Biggers
266*b13c0e40SEric Biggerssparse_test()
267*b13c0e40SEric Biggers{
268*b13c0e40SEric Biggers	log "Run sparse"
269*b13c0e40SEric Biggers	./scripts/run-sparse.sh
270*b13c0e40SEric Biggers}
271*b13c0e40SEric BiggersTEST_FUNCS+=(sparse_test)
272*b13c0e40SEric Biggers
273*b13c0e40SEric Biggersclang_analyzer_test()
274*b13c0e40SEric Biggers{
275*b13c0e40SEric Biggers	log "Run clang static analyzer"
276*b13c0e40SEric Biggers	scan-build --status-bugs make CFLAGS="-O2 -Werror" all test_programs
277*b13c0e40SEric Biggers}
278*b13c0e40SEric BiggersTEST_FUNCS+=(clang_analyzer_test)
279*b13c0e40SEric Biggers
280*b13c0e40SEric Biggersshellcheck_test()
281*b13c0e40SEric Biggers{
282*b13c0e40SEric Biggers	log "Run shellcheck"
283*b13c0e40SEric Biggers	shellcheck scripts/*.sh 1>&2
284*b13c0e40SEric Biggers}
285*b13c0e40SEric BiggersTEST_FUNCS+=(shellcheck_test)
286*b13c0e40SEric Biggers
287*b13c0e40SEric Biggerstest_exists()
288*b13c0e40SEric Biggers{
289*b13c0e40SEric Biggers	local tst=$1
290*b13c0e40SEric Biggers	local func
291*b13c0e40SEric Biggers	for func in "${TEST_FUNCS[@]}"; do
292*b13c0e40SEric Biggers		if [ "${tst}_test" = "$func" ]; then
293*b13c0e40SEric Biggers			return 0
294*b13c0e40SEric Biggers		fi
295*b13c0e40SEric Biggers	done
296*b13c0e40SEric Biggers	return 1
297*b13c0e40SEric Biggers}
298*b13c0e40SEric Biggers
299*b13c0e40SEric Biggersif [[ $# == 0 ]]; then
300*b13c0e40SEric Biggers	for func in "${TEST_FUNCS[@]}"; do
301*b13c0e40SEric Biggers		eval "$func"
302*b13c0e40SEric Biggers	done
303*b13c0e40SEric Biggerselse
304*b13c0e40SEric Biggers	for tst; do
305*b13c0e40SEric Biggers		if ! test_exists "$tst"; then
306*b13c0e40SEric Biggers			echo 1>&2 "Unknown test: $tst"
307*b13c0e40SEric Biggers			exit 2
308*b13c0e40SEric Biggers		fi
309*b13c0e40SEric Biggers	done
310*b13c0e40SEric Biggers	for tst; do
311*b13c0e40SEric Biggers		eval "${tst}_test"
312*b13c0e40SEric Biggers	done
313*b13c0e40SEric Biggersfi
314*b13c0e40SEric Biggers
315*b13c0e40SEric Biggerslog "All tests passed!"
316