summaryrefslogtreecommitdiffstats
path: root/test-many-klibcs
blob: 8bb810239cf447ab4c7bab1e8e4acc1fceb9c6db (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
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
#!/bin/bash -eu

build() {
    echo "I: Using $("$gnuarch-gcc" --version | head -1)"
    echo "I: Using $("$gnuarch-ld" --version | head -1)"

    mkdir -p "build/$gnuarch"
    echo "I: Generating kernel UAPI headers for ARCH=$kernelarch"
    make -C ../linux "ARCH=$kernelarch" \
	 "INSTALL_HDR_PATH=$PWD/build/$gnuarch/linux" headers_install \
    || return
    echo "I: Building with ARCH=$arch CROSS_COMPILE=$gnuarch- $makeflags"
    make -C "build/$gnuarch" -f "$PWD/../klibc/Makefile" -j"$nproc" \
	 "ARCH=$arch" "CROSS_COMPILE=$gnuarch-" "KBUILD_SRC=$PWD/../klibc" \
	 $makeflags all test \
    || return
}

do_install() {
    # Set up a tmpfs in case the current filesystem is mounted nodev
    mkdir -p install
    if mountpoint install >/dev/null; then
	find install -xdev -mindepth 1 -delete || return
    else
	sudo mount -t tmpfs tmpfs install || return
    fi

    # Install klibc itself
    make -C "build/$gnuarch" -f "$PWD/../klibc/Makefile" \
	 "ARCH=$arch" "CROSS_COMPILE=$gnuarch-" "KBUILD_SRC=$PWD/../klibc" \
	 $makeflags INSTALLROOT="$PWD/install" install \
    || return

    # Install shared-library tests
    mkdir install/tests
    cp "build/$gnuarch/usr/klibc/tests"/*.shared install/tests/ || return

    # Some tests need these
    mkdir -p install/dev
    sudo mknod -m 666 install/dev/null c 1 3
    sudo mknod -m 666 install/dev/zero c 1 5
    mkdir -p install/etc
    head -1 /etc/passwd > install/etc/passwd

    # Install statically-linked QEMU inside
    case "$arch" in
	i386 | x86_64)
	    ;;
	*)
	    mkdir -p install/bin
	    install "$(command -v "qemu-$qemuarch-static")" install/bin/ \
	    || return
	    ;;
    esac
}

clean() {
    echo "I: Cleaning"
    (cd ../klibc && git clean -d -f -x)
}

run_built() {
    # XXX We assume build architecture is x86_64
    case "$arch" in
	i386 | x86_64)
	    "$@"
	    ;;
	*)
	    "qemu-$qemuarch-static" -- "$@"
	    ;;
    esac
}

run_installed() {
    local useropt

    useropt="--userspec=$(id -un):$(id -gn)"

    # XXX We assume build architecture is x86_64
    case "$arch" in
	i386 | x86_64)
	    sudo chroot "$useropt" -- install "$@"
	    ;;
	*)
	    sudo ${QEMU_CPU:+QEMU_CPU=$QEMU_CPU} chroot "$useropt" -- install "/bin/qemu-$qemuarch-static" -- \
		 "$@"
	    ;;
    esac
}

run_test_program() {
    local flavour="$1"
    local progname="$2"
    shift 2
    local logname="test-$gnuarch-$flavour-$progname.log"
    local err=0

    case "$flavour" in
	static)
	    run_built "build/$gnuarch/usr/klibc/tests/$progname" > "$logname" \
	    || err=$?
	    ;;
	shared)
	    run_installed /tests/"$progname".shared > "$logname" \
	    || err=$?
	    ;;
    esac

    if [ "$err" -eq 0 ]; then
	if grep -qw ERROR "$logname"; then
	    echo "E: $progname: Error found in output"
	    return 1
	fi
	while [ $# -ge 1 ]; do
	    if ! grep -qF -- "$1" "$logname"; then
		echo "E: $progname: Expected text '$1' not found in output"
		return 1
	    fi
	    shift
	done
	echo "I: $progname: pass"
    else
	echo "E: $progname: fail"
	return 1
    fi
}

run_shell_static() {
    local command="$1"

    if run_built "build/$gnuarch/usr/dash/static/sh" -c "$command"; then
	echo "I: shell '$command': pass"
    else
	echo "E: shell '$command': fail"
	return 1
    fi
}

run_shell_shared() {
    local command="$1"

    if run_installed /usr/lib/klibc/bin/sh -c "$command"; then
	echo "I: shell '$command': pass"
    else
	echo "E: shell '$command': fail"
	return 1
    fi
}

run_tests_flavour() {
    local flavour="$1"
    local err=0

    run_test_program "$flavour" microhello || err=1
    run_test_program "$flavour" minihello || err=1
    run_test_program "$flavour" hello || err=1
    run_test_program "$flavour" environ 'Verifying envp == environ... ok' \
	|| err=1
    run_test_program "$flavour" fcntl || err=1
    run_test_program "$flavour" malloctest || err=1
    run_test_program "$flavour" malloctest2 || err=1
    run_test_program "$flavour" opentest "Line 1 = $(head -1 /etc/passwd)" \
	|| err=1
    run_test_program "$flavour" pipetest || err=1
    run_test_program "$flavour" select || err=1
    run_test_program "$flavour" setjmptest \
	"calling longjmp with 256... setjmp returned 256" || err=1
    run_test_program "$flavour" sigint "Signal received OK" || err=1
    run_test_program "$flavour" socket || err=1
    run_test_program "$flavour" sscanf || err=1
    run_test_program "$flavour" stdio "Hello, World!" \
        "Hello again - and some more - and some more" || err=1
    run_test_program "$flavour" strlcpycat || err=1
    run_test_program "$flavour" vfork || err=1

    return $err
}

run_tests() {
    local err=0

    run_tests_flavour static || err=1
    run_shell_static "exit" || err=1
    run_shell_static "build/$gnuarch/usr/utils/static/true; exit" || err=1

    run_tests_flavour shared || err=1
    run_shell_shared "exit" || err=1
    run_shell_shared "/usr/lib/klibc/bin/true; exit" || err=1

    return $err
}

process() {
    arch="$1"
    kernelarch="$2"
    gnuarch="$3"
    qemuarch="$4"
    makeflags="${5:-}"

    case "$qemuarch" in
	*:*)
	    export QEMU_CPU="${qemuarch#*:}"
	    qemuarch="${qemuarch%:*}"
	    ;;
	*)
	    unset QEMU_CPU
	    ;;
    esac

    echo "I: Architecture $arch/$gnuarch: begin"
    if clean && build && do_install && run_tests; then
	echo "I: Architecture $arch/$gnuarch: pass"
    else
	echo "E: Architecture $arch/$gnuarch: fail"
    fi
    clean || true
}

echo "I: $0 started at $(date)"
echo "I: Using klibc $(GIT_DIR=../klibc/.git git describe)"
echo "I: Using Linux $(make -C ../linux -s kernelversion)"

nproc="$(nproc || echo 1)"
echo "I: Using concurrency of $nproc"

process alpha   alpha   alpha-linux-gnu         alpha
# arm OABI is no longer supported in Debian.
#process arm     arm     arm-linux-gnu           arm
process arm     arm     arm-linux-gnueabi       arm     "CONFIG_AEABI=y"
process arm     arm     arm-linux-gnueabihf     arm     "CONFIG_AEABI=y CPU_ARCH=armv7-a CPU_TUNE=cortex-a8 CONFIG_KLIBC_THUMB=y"
process arm64   arm64   aarch64-linux-gnu       aarch64
# cris is not supported in Debian.
#process cris    cris    cris-linux-gnu          cris
process i386    x86     i686-linux-gnu          i386
# ia64 cross-compiler is currently missing in Debian, as is QEMU support.
#process ia64    ia64    ia64-linux-gnu          ???
process m68k    m68k    m68k-linux-gnu          m68k
process mips    mips    mips-linux-gnu          mips
process mips    mips    mipsel-linux-gnu        mipsel
# Big-endian mips64 is not supported in Debian.
#process mips64  mips    mips64-linux-gnuabi64   mips64
process mips64  mips    mips64el-linux-gnuabi64 mips64el
process parisc  parisc  hppa-linux-gnu          hppa
process ppc     powerpc powerpc-linux-gnu       ppc
process ppc64   powerpc powerpc64-linux-gnu     ppc64
process ppc64   powerpc powerpc64le-linux-gnu   ppc64le
process riscv64 riscv   riscv64-linux-gnu       riscv64
# 32-bit s390 is no longer supported in Debian.
#process s390    s390    s390-linux-gnu          s390
process s390x   s390    s390x-linux-gnu         s390x
process sh      sh      sh4-linux-gnu           sh4
# 32-bit sparc is no longer supported in Debian.
#process sparc   sparc   sparc-linux-gnu         sparc
process sparc64 sparc   sparc64-linux-gnu       sparc64
process x86_64  x86     x86_64-linux-gnu        x86_64

echo "I: $0 finished at $(date)"