]>
Commit | Line | Data |
---|---|---|
a71f1b49 | 1 | #!/bin/bash |
a3f73298 | 2 | |
43c16bfa | 3 | [ -z "$USE_NETWORK" ] && USE_NETWORK="network-legacy" |
a3f73298 | 4 | |
c864f893 | 5 | # shellcheck disable=SC2034 |
a3f73298 | 6 | TEST_DESCRIPTION="root filesystem on NFS with multiple nics with $USE_NETWORK" |
a71f1b49 PS |
7 | |
8 | KVERSION=${KVERSION-$(uname -r)} | |
9 | ||
10 | # Uncomment this to debug failures | |
8b2afb08 | 11 | #DEBUGFAIL="loglevel=7 rd.shell rd.break" |
67ab4f77 | 12 | #SERIAL="tcp:127.0.0.1:9999" |
a71f1b49 PS |
13 | |
14 | run_server() { | |
15 | # Start server first | |
16 | echo "MULTINIC TEST SETUP: Starting DHCP/NFS server" | |
17 | ||
b80ee080 HH |
18 | declare -a disk_args=() |
19 | # shellcheck disable=SC2034 | |
20 | declare -i disk_index=0 | |
21 | qemu_add_drive_args disk_index disk_args "$TESTDIR"/server.img root | |
22 | ||
c864f893 | 23 | "$testdir"/run-qemu \ |
b80ee080 | 24 | "${disk_args[@]}" \ |
9288d21b HH |
25 | -net socket,listen=127.0.0.1:12350 \ |
26 | -net nic,macaddr=52:54:01:12:34:56,model=e1000 \ | |
c864f893 | 27 | -serial "${SERIAL:-"file:$TESTDIR/server.log"}" \ |
9f6b4e53 | 28 | -device i6300esb -watchdog-action poweroff \ |
b2cf61d9 | 29 | -append "panic=1 oops=panic softlockup_panic=1 systemd.crash_reboot root=LABEL=dracut rootfstype=ext3 rw console=ttyS0,115200n81 selinux=0" \ |
9288d21b HH |
30 | -initrd "$TESTDIR"/initramfs.server \ |
31 | -pidfile "$TESTDIR"/server.pid -daemonize || return 1 | |
ca8f1c1b | 32 | |
4bd0ab61 | 33 | chmod 644 -- "$TESTDIR"/server.pid || return 1 |
a71f1b49 PS |
34 | |
35 | # Cleanup the terminal if we have one | |
36 | tty -s && stty sane | |
37 | ||
3aae122c | 38 | if ! [[ $SERIAL ]]; then |
9a52c3fd | 39 | while :; do |
3aae122c | 40 | grep Serving "$TESTDIR"/server.log && break |
a3f73298 | 41 | echo "Waiting for the server to startup" |
0f62da04 | 42 | tail "$TESTDIR"/server.log |
3aae122c HH |
43 | sleep 1 |
44 | done | |
45 | else | |
46 | echo Sleeping 10 seconds to give the server a head start | |
47 | sleep 10 | |
48 | fi | |
a71f1b49 PS |
49 | } |
50 | ||
51 | client_test() { | |
52 | local test_name="$1" | |
53 | local mac1="$2" | |
54 | local mac2="$3" | |
55 | local mac3="$4" | |
56 | local cmdline="$5" | |
57 | local check="$6" | |
58 | ||
59 | echo "CLIENT TEST START: $test_name" | |
60 | ||
b80ee080 HH |
61 | dd if=/dev/zero of="$TESTDIR"/marker.img bs=1MiB count=1 |
62 | declare -a disk_args=() | |
63 | # shellcheck disable=SC2034 | |
64 | declare -i disk_index=0 | |
65 | qemu_add_drive_args disk_index disk_args "$TESTDIR"/marker.img marker | |
462d9b92 | 66 | cmdline="$cmdline rd.net.timeout.dhcp=30" |
8b2afb08 | 67 | |
b80ee080 HH |
68 | # Invoke KVM and/or QEMU to actually create the target filesystem. |
69 | "$testdir"/run-qemu \ | |
70 | "${disk_args[@]}" \ | |
9a52c3fd | 71 | -net socket,connect=127.0.0.1:12350 \ |
c864f893 HH |
72 | -net nic,macaddr=52:54:00:12:34:"$mac1",model=e1000 \ |
73 | -net nic,macaddr=52:54:00:12:34:"$mac2",model=e1000 \ | |
74 | -net nic,macaddr=52:54:00:12:34:"$mac3",model=e1000 \ | |
9a52c3fd HH |
75 | -netdev hubport,id=n1,hubid=1 \ |
76 | -netdev hubport,id=n2,hubid=2 \ | |
77 | -device e1000,netdev=n1,mac=52:54:00:12:34:98 \ | |
78 | -device e1000,netdev=n2,mac=52:54:00:12:34:99 \ | |
9f6b4e53 | 79 | -device i6300esb -watchdog-action poweroff \ |
b2cf61d9 | 80 | -append "quiet panic=1 oops=panic softlockup_panic=1 systemd.crash_reboot rd.shell=0 $cmdline $DEBUGFAIL rd.retry=5 ro console=ttyS0,115200n81 selinux=0 init=/sbin/init rd.debug systemd.log_target=console" \ |
b80ee080 | 81 | -initrd "$TESTDIR"/initramfs.testing || return 1 |
9a52c3fd HH |
82 | |
83 | { | |
c864f893 HH |
84 | read -r OK |
85 | read -r IFACES | |
b80ee080 | 86 | } < "$TESTDIR"/marker.img |
84bc1929 | 87 | |
75d758e8 | 88 | if [[ $OK != "OK" ]]; then |
d6862983 HH |
89 | echo "CLIENT TEST END: $test_name [FAILED - BAD EXIT]" |
90 | return 1 | |
a71f1b49 PS |
91 | fi |
92 | ||
84bc1929 HH |
93 | for i in $check; do |
94 | if [[ " $IFACES " != *\ $i\ * ]]; then | |
95 | echo "$i not in '$IFACES'" | |
96 | echo "CLIENT TEST END: $test_name [FAILED - BAD IF]" | |
97 | return 1 | |
98 | fi | |
99 | done | |
a71f1b49 | 100 | |
84bc1929 HH |
101 | for i in $IFACES; do |
102 | if [[ " $check " != *\ $i\ * ]]; then | |
103 | echo "$i in '$IFACES', but should not be" | |
d6862983 HH |
104 | echo "CLIENT TEST END: $test_name [FAILED - BAD IF]" |
105 | return 1 | |
106 | fi | |
a71f1b49 PS |
107 | done |
108 | ||
109 | echo "CLIENT TEST END: $test_name [OK]" | |
110 | return 0 | |
111 | } | |
112 | ||
a71f1b49 PS |
113 | test_run() { |
114 | if ! run_server; then | |
d6862983 HH |
115 | echo "Failed to start server" 1>&2 |
116 | return 1 | |
a71f1b49 | 117 | fi |
24a78b26 HH |
118 | test_client |
119 | ret=$? | |
120 | kill_server | |
121 | return $ret | |
6c980807 | 122 | } |
a71f1b49 | 123 | |
6c980807 | 124 | test_client() { |
a71f1b49 PS |
125 | # Mac Numbering Scheme |
126 | # ...:00-02 receive IP adresses all others don't | |
127 | # ...:02 receives a dhcp root-path | |
128 | ||
129 | # PXE Style BOOTIF= | |
e0641277 | 130 | client_test "MULTINIC root=nfs BOOTIF=" \ |
9a52c3fd HH |
131 | 00 01 02 \ |
132 | "root=nfs:192.168.50.1:/nfs/client BOOTIF=52-54-00-12-34-00" \ | |
b80ee080 | 133 | "enp0s1" || return 1 |
a71f1b49 | 134 | |
b80ee080 | 135 | client_test "MULTINIC root=nfs BOOTIF= ip=enp0s3:dhcp" \ |
9a52c3fd | 136 | 00 01 02 \ |
b80ee080 HH |
137 | "root=nfs:192.168.50.1:/nfs/client BOOTIF=52-54-00-12-34-00 ip=enp0s2:dhcp" \ |
138 | "enp0s1 enp0s2" || return 1 | |
84bc1929 | 139 | |
a71f1b49 PS |
140 | # PXE Style BOOTIF= with dhcp root-path |
141 | client_test "MULTINIC root=dhcp BOOTIF=" \ | |
9a52c3fd HH |
142 | 00 01 02 \ |
143 | "root=dhcp BOOTIF=52-54-00-12-34-02" \ | |
b80ee080 | 144 | "enp0s3" || return 1 |
a71f1b49 PS |
145 | |
146 | # Multinic case, where only one nic works | |
147 | client_test "MULTINIC root=nfs ip=dhcp" \ | |
9a52c3fd HH |
148 | FF 00 FE \ |
149 | "root=nfs:192.168.50.1:/nfs/client ip=dhcp" \ | |
b80ee080 | 150 | "enp0s2" || return 1 |
a71f1b49 PS |
151 | |
152 | # Require two interfaces | |
b80ee080 | 153 | client_test "MULTINIC root=nfs ip=enp0s2:dhcp ip=enp0s3:dhcp bootdev=enp0s2" \ |
9a52c3fd | 154 | 00 01 02 \ |
b80ee080 HH |
155 | "root=nfs:192.168.50.1:/nfs/client ip=enp0s2:dhcp ip=enp0s3:dhcp bootdev=enp0s2" \ |
156 | "enp0s2 enp0s3" || return 1 | |
a71f1b49 PS |
157 | |
158 | # Require three interfaces with dhcp root-path | |
b80ee080 | 159 | client_test "MULTINIC root=dhcp ip=enp0s1:dhcp ip=enp0s2:dhcp ip=enp0s3:dhcp bootdev=enp0s3" \ |
9a52c3fd | 160 | 00 01 02 \ |
b80ee080 HH |
161 | "root=dhcp ip=enp0s1:dhcp ip=enp0s2:dhcp ip=enp0s3:dhcp bootdev=enp0s3" \ |
162 | "enp0s1 enp0s2 enp0s3" || return 1 | |
8f4c0660 | 163 | |
24a78b26 | 164 | client_test "MULTINIC bonding" \ |
9a52c3fd | 165 | 00 01 02 \ |
b80ee080 | 166 | "root=nfs:192.168.50.1:/nfs/client ip=bond0:dhcp bond=bond0:enp0s1,enp0s2,enp0s3:mode=balance-rr" \ |
9a52c3fd | 167 | "bond0" || return 1 |
24a78b26 | 168 | |
a3f73298 | 169 | # bridge, where only one interface is actually connected |
24a78b26 | 170 | client_test "MULTINIC bridging" \ |
9a52c3fd | 171 | 00 01 02 \ |
b80ee080 | 172 | "root=nfs:192.168.50.1:/nfs/client ip=bridge0:dhcp bridge=bridge0:enp0s1,enp0s5,enp0s6" \ |
9a52c3fd | 173 | "bridge0" || return 1 |
8f4c0660 | 174 | return 0 |
a71f1b49 PS |
175 | } |
176 | ||
177 | test_setup() { | |
8b2afb08 HH |
178 | export kernel=$KVERSION |
179 | export srcmods="/lib/modules/$kernel/" | |
180 | rm -rf -- "$TESTDIR"/overlay | |
3eca0cc8 | 181 | ( |
c864f893 HH |
182 | mkdir -p "$TESTDIR"/overlay/source |
183 | # shellcheck disable=SC2030 | |
0f62da04 | 184 | export initdir=$TESTDIR/overlay/source |
c864f893 HH |
185 | # shellcheck disable=SC1090 |
186 | . "$basedir"/dracut-init.sh | |
0f62da04 | 187 | |
d6862983 | 188 | ( |
c864f893 | 189 | cd "$initdir" || exit |
8b2afb08 HH |
190 | mkdir -p dev sys proc run etc var/run tmp var/lib/{dhcpd,rpcbind} |
191 | mkdir -p var/lib/nfs/{v4recovery,rpc_pipefs} | |
192 | chmod 777 var/lib/rpcbind var/lib/nfs | |
d6862983 HH |
193 | ) |
194 | ||
af119460 | 195 | inst_multiple sh ls shutdown poweroff stty cat ps ln ip \ |
9a52c3fd HH |
196 | dmesg mkdir cp ping exportfs \ |
197 | modprobe rpc.nfsd rpc.mountd showmount tcpdump \ | |
8b2afb08 | 198 | sleep mount chmod rm |
96d22bd7 | 199 | for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do |
8b2afb08 HH |
200 | if [ -f "${_terminfodir}"/l/linux ]; then |
201 | inst_multiple -o "${_terminfodir}"/l/linux | |
202 | break | |
203 | fi | |
d6862983 | 204 | done |
9a52c3fd HH |
205 | type -P portmap > /dev/null && inst_multiple portmap |
206 | type -P rpcbind > /dev/null && inst_multiple rpcbind | |
af119460 | 207 | [ -f /etc/netconfig ] && inst_multiple /etc/netconfig |
9a52c3fd | 208 | type -P dhcpd > /dev/null && inst_multiple dhcpd |
d6862983 | 209 | [ -x /usr/sbin/dhcpd3 ] && inst /usr/sbin/dhcpd3 /usr/sbin/dhcpd |
ec897491 | 210 | instmods nfsd sunrpc ipv6 lockd af_packet |
d6862983 | 211 | inst ./server-init.sh /sbin/init |
8b2afb08 | 212 | inst_simple /etc/os-release |
d6862983 HH |
213 | inst ./hosts /etc/hosts |
214 | inst ./exports /etc/exports | |
215 | inst ./dhcpd.conf /etc/dhcpd.conf | |
8b2afb08 HH |
216 | inst_multiple -o {,/usr}/etc/nsswitch.conf {,/usr}/etc/rpc \ |
217 | {,/usr}/etc/protocols {,/usr}/etc/services | |
7299c14e | 218 | inst_multiple -o rpc.idmapd /etc/idmapd.conf |
d6862983 HH |
219 | |
220 | inst_libdir_file 'libnfsidmap_nsswitch.so*' | |
221 | inst_libdir_file 'libnfsidmap/*.so*' | |
222 | inst_libdir_file 'libnfsidmap*.so*' | |
c5ef4b63 | 223 | |
8b2afb08 HH |
224 | _nsslibs=$( |
225 | cat "$dracutsysrootdir"/{,usr/}etc/nsswitch.conf 2> /dev/null \ | |
226 | | sed -e '/^#/d' -e 's/^.*://' -e 's/\[NOTFOUND=return\]//' \ | |
227 | | tr -s '[:space:]' '\n' | sort -u | tr -s '[:space:]' '|' | |
228 | ) | |
3eca0cc8 HH |
229 | _nsslibs=${_nsslibs#|} |
230 | _nsslibs=${_nsslibs%|} | |
167a320e | 231 | inst_libdir_file -n "$_nsslibs" 'libnss_*.so*' |
c5ef4b63 | 232 | |
d6862983 HH |
233 | inst /etc/passwd /etc/passwd |
234 | inst /etc/group /etc/group | |
3eca0cc8 | 235 | |
8b2afb08 | 236 | cp -a /etc/ld.so.conf* "$initdir"/etc |
7ecb36ae | 237 | ldconfig -r "$initdir" |
67ab4f77 | 238 | dracut_kernel_post |
3eca0cc8 | 239 | ) |
a71f1b49 PS |
240 | |
241 | # Make client root inside server root | |
a71f1b49 | 242 | ( |
c864f893 HH |
243 | # shellcheck disable=SC2030 |
244 | # shellcheck disable=SC2031 | |
0f62da04 | 245 | export initdir=$TESTDIR/overlay/source/nfs/client |
c864f893 HH |
246 | # shellcheck disable=SC1090 |
247 | . "$basedir"/dracut-init.sh | |
8b2afb08 | 248 | |
06853123 | 249 | ( |
c864f893 | 250 | cd "$initdir" || exit |
8b2afb08 | 251 | mkdir -p dev sys proc etc run root usr var/lib/nfs/rpc_pipefs |
06853123 | 252 | ) |
8b2afb08 HH |
253 | |
254 | inst_multiple sh shutdown poweroff stty cat ps ln ip dd \ | |
255 | mount dmesg mkdir cp ping grep setsid ls vi less cat sync | |
96d22bd7 | 256 | for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do |
8b2afb08 HH |
257 | if [ -f "${_terminfodir}"/l/linux ]; then |
258 | inst_multiple -o "${_terminfodir}"/l/linux | |
259 | break | |
260 | fi | |
d6862983 | 261 | done |
c864f893 HH |
262 | |
263 | inst_simple "${basedir}/modules.d/99base/dracut-lib.sh" "/lib/dracut-lib.sh" | |
c08bc810 | 264 | inst_simple "${basedir}/modules.d/99base/dracut-dev-lib.sh" "/lib/dracut-dev-lib.sh" |
c864f893 HH |
265 | inst_binary "${basedir}/dracut-util" "/usr/bin/dracut-util" |
266 | ln -s dracut-util "${initdir}/usr/bin/dracut-getarg" | |
267 | ln -s dracut-util "${initdir}/usr/bin/dracut-getargs" | |
268 | ||
d6862983 | 269 | inst ./client-init.sh /sbin/init |
8b2afb08 HH |
270 | inst_simple /etc/os-release |
271 | inst_multiple -o {,/usr}/etc/nsswitch.conf | |
d6862983 HH |
272 | inst /etc/passwd /etc/passwd |
273 | inst /etc/group /etc/group | |
274 | ||
d6862983 HH |
275 | inst_libdir_file 'libnfsidmap_nsswitch.so*' |
276 | inst_libdir_file 'libnfsidmap/*.so*' | |
277 | inst_libdir_file 'libnfsidmap*.so*' | |
3eca0cc8 | 278 | |
8b2afb08 HH |
279 | _nsslibs=$( |
280 | cat "$dracutsysrootdir"/{,usr/}etc/nsswitch.conf 2> /dev/null \ | |
281 | | sed -e '/^#/d' -e 's/^.*://' -e 's/\[NOTFOUND=return\]//' \ | |
282 | | tr -s '[:space:]' '\n' | sort -u | tr -s '[:space:]' '|' | |
283 | ) | |
3eca0cc8 HH |
284 | _nsslibs=${_nsslibs#|} |
285 | _nsslibs=${_nsslibs%|} | |
167a320e | 286 | inst_libdir_file -n "$_nsslibs" 'libnss_*.so*' |
a71f1b49 | 287 | |
8b2afb08 | 288 | cp -a /etc/ld.so.conf* "$initdir"/etc |
4bd0ab61 | 289 | ldconfig -r "$initdir" |
3eca0cc8 HH |
290 | ) |
291 | ||
0f62da04 HH |
292 | # second, install the files needed to make the root filesystem |
293 | ( | |
c864f893 HH |
294 | # shellcheck disable=SC2030 |
295 | # shellcheck disable=SC2031 | |
0f62da04 | 296 | export initdir=$TESTDIR/overlay |
c864f893 HH |
297 | # shellcheck disable=SC1090 |
298 | . "$basedir"/dracut-init.sh | |
0f62da04 HH |
299 | inst_multiple sfdisk mkfs.ext3 poweroff cp umount sync dd |
300 | inst_hook initqueue 01 ./create-root.sh | |
301 | inst_hook initqueue/finished 01 ./finished-false.sh | |
0f62da04 HH |
302 | ) |
303 | ||
304 | # create an initramfs that will create the target root filesystem. | |
305 | # We do it this way so that we do not risk trashing the host mdraid | |
306 | # devices, volume groups, encrypted partitions, etc. | |
c864f893 | 307 | "$basedir"/dracut.sh -l -i "$TESTDIR"/overlay / \ |
1573bb81 | 308 | -m "bash rootfs-block kernel-modules qemu" \ |
9a52c3fd HH |
309 | -d "piix ide-gd_mod ata_piix ext3 sd_mod" \ |
310 | --nomdadmconf \ | |
311 | --no-hostonly-cmdline -N \ | |
c864f893 | 312 | -f "$TESTDIR"/initramfs.makeroot "$KVERSION" || return 1 |
8b2afb08 | 313 | rm -rf -- "$TESTDIR"/overlay |
b80ee080 HH |
314 | |
315 | dd if=/dev/zero of="$TESTDIR"/server.img bs=1MiB count=120 | |
316 | dd if=/dev/zero of="$TESTDIR"/marker.img bs=1MiB count=1 | |
317 | declare -a disk_args=() | |
318 | # shellcheck disable=SC2034 | |
319 | declare -i disk_index=0 | |
320 | qemu_add_drive_args disk_index disk_args "$TESTDIR"/marker.img marker | |
321 | qemu_add_drive_args disk_index disk_args "$TESTDIR"/server.img root | |
0f62da04 HH |
322 | |
323 | # Invoke KVM and/or QEMU to actually create the target filesystem. | |
c864f893 | 324 | "$testdir"/run-qemu \ |
b80ee080 | 325 | "${disk_args[@]}" \ |
0f62da04 | 326 | -append "root=/dev/dracut/root rw rootfstype=ext3 quiet console=ttyS0,115200n81 selinux=0" \ |
c864f893 | 327 | -initrd "$TESTDIR"/initramfs.makeroot || return 1 |
b80ee080 | 328 | grep -U --binary-files=binary -F -m 1 -q dracut-root-block-created "$TESTDIR"/marker.img || return 1 |
a71f1b49 PS |
329 | |
330 | # Make an overlay with needed tools for the test harness | |
331 | ( | |
c864f893 | 332 | # shellcheck disable=SC2031 |
8b2afb08 | 333 | # shellcheck disable=SC2030 |
b093aa2d | 334 | export initdir="$TESTDIR"/overlay |
8b2afb08 | 335 | mkdir -p "$TESTDIR"/overlay |
c864f893 | 336 | # shellcheck disable=SC1090 |
777f2db0 | 337 | . "$basedir"/dracut-init.sh |
af119460 | 338 | inst_multiple poweroff shutdown |
4e882b80 | 339 | inst_hook shutdown-emergency 000 ./hard-off.sh |
781f1971 | 340 | inst_hook emergency 000 ./hard-off.sh |
8b2afb08 HH |
341 | inst_simple ./client.link /etc/systemd/network/01-client.link |
342 | ||
343 | inst_binary awk | |
344 | inst_hook pre-pivot 85 "$basedir/modules.d/45ifcfg/write-ifcfg.sh" | |
a71f1b49 | 345 | ) |
8b2afb08 HH |
346 | # Make client's dracut image |
347 | "$basedir"/dracut.sh -l -i "$TESTDIR"/overlay / \ | |
1586621b | 348 | -o "ifcfg plymouth" \ |
8b2afb08 HH |
349 | -a "debug watchdog ${USE_NETWORK}" \ |
350 | --no-hostonly-cmdline -N \ | |
351 | -f "$TESTDIR"/initramfs.testing "$KVERSION" || return 1 | |
a71f1b49 | 352 | |
8b2afb08 HH |
353 | ( |
354 | # shellcheck disable=SC2031 | |
355 | export initdir="$TESTDIR"/overlay | |
356 | # shellcheck disable=SC1090 | |
357 | . "$basedir"/dracut-init.sh | |
358 | rm "$initdir"/etc/systemd/network/01-client.link | |
359 | inst_simple ./server.link /etc/systemd/network/01-server.link | |
360 | inst_hook pre-mount 99 ./wait-if-server.sh | |
361 | ) | |
a71f1b49 | 362 | # Make server's dracut image |
8b2afb08 | 363 | "$basedir"/dracut.sh -l -i "$TESTDIR"/overlay / \ |
1573bb81 | 364 | -m "dash rootfs-block debug kernel-modules watchdog qemu network network-legacy" \ |
a8986425 | 365 | -d "af_packet piix ide-gd_mod ata_piix ext3 sd_mod nfsv2 nfsv3 nfsv4 nfs_acl nfs_layout_nfsv41_files nfsd e1000 i6300esb ib700wdt" \ |
e3e1f406 | 366 | --no-hostonly-cmdline -N \ |
b093aa2d | 367 | -f "$TESTDIR"/initramfs.server "$KVERSION" || return 1 |
a71f1b49 | 368 | |
a71f1b49 PS |
369 | } |
370 | ||
6c980807 | 371 | kill_server() { |
b093aa2d | 372 | if [[ -s "$TESTDIR"/server.pid ]]; then |
c864f893 | 373 | kill -TERM -- "$(cat "$TESTDIR"/server.pid)" |
b093aa2d | 374 | rm -f -- "$TESTDIR"/server.pid |
a71f1b49 | 375 | fi |
6c980807 HH |
376 | } |
377 | ||
378 | test_cleanup() { | |
0be1785a | 379 | kill_server |
a71f1b49 PS |
380 | } |
381 | ||
c864f893 | 382 | # shellcheck disable=SC1090 |
b093aa2d | 383 | . "$testdir"/test-functions |