summaryrefslogtreecommitdiff
path: root/test.bash
blob: d126a9ef194e97f05eb97b4d746eaf0267177406 (plain)
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
#!/bin/bash
#
# test.bash runs the gocryptfs test suite against $TMPDIR,
# or, if unset, /var/tmp.

set -eu

VERBOSE=0
for i in "$@" ; do
	if [[ $i == "-v" ]] ; then
		VERBOSE=1
		set -x
		break
	fi
done

if [[ -z ${TMPDIR:-} ]]; then
	TMPDIR=/var/tmp
	export TMPDIR
else
	echo "Using TMPDIR=$TMPDIR"
fi

cd "$(dirname "$0")"
export GO111MODULE=on
MYNAME=$(basename "$0")
TESTDIR=$TMPDIR/gocryptfs-test-parent-$UID
mkdir -p "$TESTDIR"
LOCKFILE=$TESTDIR/$MYNAME.lock

unmount_leftovers() {
	RET=0
	for i in $(mount | grep "$TESTDIR" | cut -f3 -d" "); do
		echo "Warning: unmounting leftover filesystem: $i"
		tests/fuse-unmount.bash "$i"
		RET=1
	done
	return $RET
}

(
# Prevent multiple parallel test.bash instances as this causes
# all kinds of mayhem
if ! command -v flock > /dev/null ; then
	echo "flock is not available, skipping"
elif ! flock -n 200 ; then
	echo "Could not acquire lock on $LOCKFILE - already running?"
	exit 1
fi

# Clean up dangling filesystems and don't exit if we found some
unmount_leftovers || true

./build-without-openssl.bash || {
	echo "$MYNAME: build-without-openssl.bash failed"
	exit 1
}
# Don't build with openssl if we were passed "-tags without_openssl"
if [[ "$*" != *without_openssl* ]] ; then
	./build.bash
fi

if ! go tool | grep vet > /dev/null ; then
	echo "'go tool vet' not available - skipping"
elif [[ -d vendor ]] ; then
	echo "vendor directory exists, skipping 'go tool vet'"
else
	go vet ./...
fi

if command -v shellcheck > /dev/null ; then
	# SC2002 = useless cat. Does no harm, disable the check.
	shellcheck -x -e SC2002 ./*.bash
else
	echo "shellcheck not installed - skipping"
fi

echo -n "Testing on TMPDIR=$TMPDIR, filesystem: "
findmnt --noheadings --target "$TESTDIR" --output FSTYPE,OPTIONS || true

EXTRA_ARGS=""
if [[ $VERBOSE -eq 1 ]]; then
	# Disabling parallelism disables per-package output buffering, hence enabling
	# live streaming of result output. And seeing where things hang.
	EXTRA_ARGS="-p 1"
fi

#                         We don't want all the subprocesses
#                              holding the lock file open
#                                       vvvvv
# shellcheck disable=SC2086
go test -count 1 $EXTRA_ARGS ./... "$@" 200>&-
#       ^^^^^^^^
#   Disable result caching

# Clean up dangling filesystems but do exit with an error if we found one
unmount_leftovers || { echo "Error: the tests left mounted filesystems behind" ; exit 1 ; }

# The tests cannot to this themselves as they are run in parallel.
# Don't descend into possibly still mounted example filesystems.
if [[ $OSTYPE == *linux* ]] ; then
	rm -Rf --one-file-system "$TESTDIR"
else
	# MacOS "rm" does not understand "--one-file-system"
	rm -Rf "$TESTDIR"
fi

if find internal -type f -name \*.go -print0 | xargs -0 grep "panic("; then
	echo "$MYNAME: Please use log.Panic instead of naked panic!"
	exit 1
fi

# Both syscall.Setreuid etc (since 2020, https://github.com/golang/go/commit/d1b1145cace8b968307f9311ff611e4bb810710c)
# and unix.Setreuid etc (since 2022, https://github.com/golang/sys/commit/d0df966e6959f00dc1c74363e537872647352d51)
# affect the whole process, not only the current thread, which is what we do NOT want.
if find . -type f -name \*.go -print0 | xargs -0 grep -v -E '^//' |
	grep -E '(syscall|unix).(Setegid|Seteuid|Setgroups|Setgid|Setregid|Setreuid|Setresgid|Setresuid|Setuid)\(' ; then
	echo "$MYNAME: This affects the whole process. Please use the syscallcompat wrappers instead."
	exit 1
fi

if find . -type f -name \*.go -print0 | xargs -0 grep '\.Creat('; then
	# MacOS does not have syscall.Creat(). Creat() is equivalent to Open(..., O_CREAT|O_WRONLY|O_TRUNC, ...),
	# but usually you want O_EXCL instead of O_TRUNC because it is safer, so that's what we suggest
	# instead.
	echo "$MYNAME: Please use Open(..., O_CREAT|O_WRONLY|O_EXCL, ...) instead of Creat()! https://github.com/rfjakob/gocryptfs/issues/623"
	exit 1
fi

) 200> "$LOCKFILE"