]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/units/testsuite-17.11.sh
Merge pull request #26944 from aafeijoo-suse/systemd-network-generator-initrd-fix
[thirdparty/systemd.git] / test / units / testsuite-17.11.sh
CommitLineData
45183cdd
DL
1#!/usr/bin/env bash
2# SPDX-License-Identifier: LGPL-2.1-or-later
3set -ex
4set -o pipefail
5
6# Test for udevadm verify.
7
197f695a
DL
8# shellcheck source=test/units/assert.sh
9. "$(dirname "$0")"/assert.sh
10
99f24451 11cleanup() {
f99deb1e
YW
12 cd /
13 rm -rf "${workdir}"
14 workdir=
99f24451
DL
15}
16
17workdir="$(mktemp -d)"
18trap cleanup EXIT
19cd "${workdir}"
20
7b4cae90
YW
21cat >"${workdir}/default_output_1_success" <<EOF
22
231 udev rules files have been checked.
24 Success: 1
25 Fail: 0
26EOF
27cat >"${workdir}/default_output_1_fail" <<EOF
28
291 udev rules files have been checked.
30 Success: 0
31 Fail: 1
32EOF
33
197f695a
DL
34test_number=0
35rules=
36exp=
37err=
7b4cae90 38out=
197f695a 39next_test_number() {
f99deb1e 40 : $((++test_number))
197f695a 41
f99deb1e
YW
42 local num_str
43 num_str=$(printf %05d "${test_number}")
197f695a 44
f99deb1e
YW
45 rules="sample-${num_str}.rules"
46 exp="sample-${num_str}.exp"
47 err="sample-${num_str}.err"
7b4cae90
YW
48 exo="sample-${num_str}.exo"
49 out="sample-${num_str}.out"
197f695a
DL
50}
51
52assert_0() {
7b4cae90
YW
53 udevadm verify "$@" >"${out}"
54 if [ -f "${rules}" ]; then
55 diff -u "${workdir}/default_output_1_success" "${out}"
56 fi
57
f99deb1e 58 next_test_number
197f695a
DL
59}
60
61assert_1() {
7b4cae90
YW
62 set +e
63 udevadm verify "$@" >"${out}" 2>"${err}"
64 assert_eq "$?" 1
65 set -e
66
f99deb1e 67 if [ -f "${exp}" ]; then
7b4cae90
YW
68 diff -u "${exp}" "${err}"
69 fi
70
71 if [ -f "${exo}" ]; then
72 diff -u "${exo}" "${out}"
f99deb1e 73 fi
7b4cae90 74
f99deb1e 75 next_test_number
197f695a
DL
76}
77
7b4cae90
YW
78# initialize variables
79next_test_number
80
197f695a
DL
81assert_0 -h
82assert_0 --help
83assert_0 -V
84assert_0 --version
85assert_0 /dev/null
45183cdd 86
45183cdd 87# unrecognized option '--unknown'
197f695a 88assert_1 --unknown
45183cdd 89# option requires an argument -- 'N'
197f695a 90assert_1 -N
45183cdd 91# --resolve-names= takes "early" or "never"
197f695a 92assert_1 -N now
45183cdd 93# option '--resolve-names' requires an argument
197f695a 94assert_1 --resolve-names
45183cdd 95# --resolve-names= takes "early" or "never"
197f695a 96assert_1 --resolve-names=now
45183cdd 97# Failed to parse rules file .: Is a directory
7b4cae90 98cp "${workdir}/default_output_1_fail" "${exo}"
197f695a 99assert_1 .
139203e1
DL
100# Failed to parse rules file ./nosuchfile: No such file or directory
101assert_1 ./nosuchfile
45183cdd 102# Failed to parse rules file .: Is a directory
7b4cae90
YW
103cat >"${exo}" <<EOF
104
1053 udev rules files have been checked.
106 Success: 2
107 Fail: 1
108EOF
197f695a 109assert_1 /dev/null . /dev/null
45183cdd 110
c8f39ddc
DL
111rules_dir='etc/udev/rules.d'
112mkdir -p "${rules_dir}"
113# No rules files found in $PWD
114assert_1 --root="${workdir}"
115
116touch "${rules_dir}/empty.rules"
117assert_0 --root="${workdir}"
118
119# Combination of --root= and FILEs is not supported.
120assert_1 --root="${workdir}" /dev/null
121# No rules files found in nosuchdir
122assert_1 --root=nosuchdir
123
124cd "${rules_dir}"
125
45183cdd 126# UDEV_LINE_SIZE 16384
197f695a
DL
127printf '%16383s\n' ' ' >"${rules}"
128assert_0 "${rules}"
129
130# Failed to parse rules file ${rules}: No buffer space available
131printf '%16384s\n' ' ' >"${rules}"
132echo "Failed to parse rules file ${rules}: No buffer space available" >"${exp}"
7b4cae90 133cp "${workdir}/default_output_1_fail" "${exo}"
197f695a
DL
134assert_1 "${rules}"
135
3ec58d0c 136{
d656c496 137 printf 'RUN+="/bin/true",%8174s\\\n' ' '
f99deb1e
YW
138 printf 'RUN+="/bin/false"%8174s\\\n' ' '
139 echo
3ec58d0c 140} >"${rules}"
197f695a
DL
141assert_0 "${rules}"
142
143printf 'RUN+="/bin/true"%8176s\\\n #\n' ' ' ' ' >"${rules}"
144echo >>"${rules}"
145cat >"${exp}" <<EOF
146${rules}:5 Line is too long, ignored
147${rules}: udev rules check failed
b27e5e2a 148EOF
7b4cae90 149cp "${workdir}/default_output_1_fail" "${exo}"
197f695a 150assert_1 "${rules}"
b27e5e2a 151
197f695a
DL
152printf '\\\n' >"${rules}"
153cat >"${exp}" <<EOF
154${rules}:1 Unexpected EOF after line continuation, line ignored
155${rules}: udev rules check failed
45183cdd 156EOF
7b4cae90 157cp "${workdir}/default_output_1_fail" "${exo}"
197f695a 158assert_1 "${rules}"
45183cdd
DL
159
160test_syntax_error() {
f99deb1e 161 local rule msg
197f695a 162
f99deb1e
YW
163 rule="$1"; shift
164 msg="$1"; shift
165
166 printf '%s\n' "${rule}" >"${rules}"
167 cat >"${exp}" <<EOF
197f695a
DL
168${rules}:1 ${msg}
169${rules}: udev rules check failed
170EOF
7b4cae90 171 cp "${workdir}/default_output_1_fail" "${exo}"
f99deb1e 172 assert_1 "${rules}"
45183cdd
DL
173}
174
175test_syntax_error '=' 'Invalid key/value pair, ignoring.'
176test_syntax_error 'ACTION{a}=="b"' 'Invalid attribute for ACTION.'
177test_syntax_error 'ACTION:="b"' 'Invalid operator for ACTION.'
ebb00082 178test_syntax_error 'ACTION=="b"' 'The line has no effect, ignoring.'
45183cdd
DL
179test_syntax_error 'DEVPATH{a}=="b"' 'Invalid attribute for DEVPATH.'
180test_syntax_error 'DEVPATH:="b"' 'Invalid operator for DEVPATH.'
181test_syntax_error 'KERNEL{a}=="b"' 'Invalid attribute for KERNEL.'
182test_syntax_error 'KERNEL:="b"' 'Invalid operator for KERNEL.'
183test_syntax_error 'KERNELS{a}=="b"' 'Invalid attribute for KERNELS.'
184test_syntax_error 'KERNELS:="b"' 'Invalid operator for KERNELS.'
185test_syntax_error 'SYMLINK{a}=="b"' 'Invalid attribute for SYMLINK.'
186test_syntax_error 'SYMLINK:="%?"' 'Invalid value "%?" for SYMLINK (char 1: invalid substitution type), ignoring.'
187test_syntax_error 'NAME{a}=="b"' 'Invalid attribute for NAME.'
188test_syntax_error 'NAME-="b"' 'Invalid operator for NAME.'
189test_syntax_error 'NAME+="a"' "NAME key takes '==', '!=', '=', or ':=' operator, assuming '='."
190test_syntax_error 'NAME:=""' 'Ignoring NAME="", as udev will not delete any network interfaces.'
191test_syntax_error 'NAME="%k"' 'Ignoring NAME="%k", as it will take no effect.'
192test_syntax_error 'ENV=="b"' 'Invalid attribute for ENV.'
193test_syntax_error 'ENV{a}-="b"' 'Invalid operator for ENV.'
194test_syntax_error 'ENV{a}:="b"' "ENV key takes '==', '!=', '=', or '+=' operator, assuming '='."
195test_syntax_error 'ENV{ACTION}="b"' "Invalid ENV attribute. 'ACTION' cannot be set."
196test_syntax_error 'CONST=="b"' 'Invalid attribute for CONST.'
197test_syntax_error 'CONST{a}=="b"' 'Invalid attribute for CONST.'
198test_syntax_error 'CONST{arch}="b"' 'Invalid operator for CONST.'
199test_syntax_error 'TAG{a}=="b"' 'Invalid attribute for TAG.'
200test_syntax_error 'TAG:="a"' "TAG key takes '==', '!=', '=', or '+=' operator, assuming '='."
201test_syntax_error 'TAG="%?"' 'Invalid value "%?" for TAG (char 1: invalid substitution type), ignoring.'
202test_syntax_error 'TAGS{a}=="b"' 'Invalid attribute for TAGS.'
203test_syntax_error 'TAGS:="a"' 'Invalid operator for TAGS.'
204test_syntax_error 'SUBSYSTEM{a}=="b"' 'Invalid attribute for SUBSYSTEM.'
205test_syntax_error 'SUBSYSTEM:="b"' 'Invalid operator for SUBSYSTEM.'
d656c496 206test_syntax_error 'SUBSYSTEM=="bus", NAME="b"' '"bus" must be specified as "subsystem".'
45183cdd
DL
207test_syntax_error 'SUBSYSTEMS{a}=="b"' 'Invalid attribute for SUBSYSTEMS.'
208test_syntax_error 'SUBSYSTEMS:="b"' 'Invalid operator for SUBSYSTEMS.'
209test_syntax_error 'DRIVER{a}=="b"' 'Invalid attribute for DRIVER.'
210test_syntax_error 'DRIVER:="b"' 'Invalid operator for DRIVER.'
211test_syntax_error 'DRIVERS{a}=="b"' 'Invalid attribute for DRIVERS.'
212test_syntax_error 'DRIVERS:="b"' 'Invalid operator for DRIVERS.'
213test_syntax_error 'ATTR="b"' 'Invalid attribute for ATTR.'
214test_syntax_error 'ATTR{%}="b"' 'Invalid attribute "%" for ATTR (char 1: invalid substitution type), ignoring.'
215test_syntax_error 'ATTR{a}-="b"' 'Invalid operator for ATTR.'
216test_syntax_error 'ATTR{a}+="b"' "ATTR key takes '==', '!=', or '=' operator, assuming '='."
217test_syntax_error 'ATTR{a}="%?"' 'Invalid value "%?" for ATTR (char 1: invalid substitution type), ignoring.'
218test_syntax_error 'SYSCTL=""' 'Invalid attribute for SYSCTL.'
219test_syntax_error 'SYSCTL{%}="b"' 'Invalid attribute "%" for SYSCTL (char 1: invalid substitution type), ignoring.'
220test_syntax_error 'SYSCTL{a}-="b"' 'Invalid operator for SYSCTL.'
221test_syntax_error 'SYSCTL{a}+="b"' "SYSCTL key takes '==', '!=', or '=' operator, assuming '='."
222test_syntax_error 'SYSCTL{a}="%?"' 'Invalid value "%?" for SYSCTL (char 1: invalid substitution type), ignoring.'
223test_syntax_error 'ATTRS=""' 'Invalid attribute for ATTRS.'
d656c496 224test_syntax_error 'ATTRS{%}=="b", NAME="b"' 'Invalid attribute "%" for ATTRS (char 1: invalid substitution type), ignoring.'
45183cdd 225test_syntax_error 'ATTRS{a}-="b"' 'Invalid operator for ATTRS.'
d656c496
DL
226test_syntax_error 'ATTRS{device/}!="a", NAME="b"' "'device' link may not be available in future kernels."
227test_syntax_error 'ATTRS{../}!="a", NAME="b"' 'Direct reference to parent sysfs directory, may break in future kernels.'
45183cdd 228test_syntax_error 'TEST{a}=="b"' "Failed to parse mode 'a': Invalid argument"
d656c496 229test_syntax_error 'TEST{0}=="%", NAME="b"' 'Invalid value "%" for TEST (char 1: invalid substitution type), ignoring.'
45183cdd
DL
230test_syntax_error 'TEST{0644}="b"' 'Invalid operator for TEST.'
231test_syntax_error 'PROGRAM{a}=="b"' 'Invalid attribute for PROGRAM.'
232test_syntax_error 'PROGRAM-="b"' 'Invalid operator for PROGRAM.'
d656c496 233test_syntax_error 'PROGRAM=="%", NAME="b"' 'Invalid value "%" for PROGRAM (char 1: invalid substitution type), ignoring.'
45183cdd
DL
234test_syntax_error 'IMPORT="b"' 'Invalid attribute for IMPORT.'
235test_syntax_error 'IMPORT{a}="b"' 'Invalid attribute for IMPORT.'
236test_syntax_error 'IMPORT{a}-="b"' 'Invalid operator for IMPORT.'
d656c496 237test_syntax_error 'IMPORT{file}=="%", NAME="b"' 'Invalid value "%" for IMPORT (char 1: invalid substitution type), ignoring.'
45183cdd
DL
238test_syntax_error 'IMPORT{builtin}!="foo"' 'Unknown builtin command: foo'
239test_syntax_error 'RESULT{a}=="b"' 'Invalid attribute for RESULT.'
240test_syntax_error 'RESULT:="b"' 'Invalid operator for RESULT.'
241test_syntax_error 'OPTIONS{a}="b"' 'Invalid attribute for OPTIONS.'
242test_syntax_error 'OPTIONS-="b"' 'Invalid operator for OPTIONS.'
243test_syntax_error 'OPTIONS!="b"' 'Invalid operator for OPTIONS.'
244test_syntax_error 'OPTIONS+="link_priority=a"' "Failed to parse link priority 'a': Invalid argument"
245test_syntax_error 'OPTIONS:="log_level=a"' "Failed to parse log level 'a': Invalid argument"
d656c496 246test_syntax_error 'OPTIONS="a", NAME="b"' "Invalid value for OPTIONS key, ignoring: 'a'"
45183cdd
DL
247test_syntax_error 'OWNER{a}="b"' 'Invalid attribute for OWNER.'
248test_syntax_error 'OWNER-="b"' 'Invalid operator for OWNER.'
249test_syntax_error 'OWNER!="b"' 'Invalid operator for OWNER.'
250test_syntax_error 'OWNER+="0"' "OWNER key takes '=' or ':=' operator, assuming '='."
0b1ee3e3 251test_syntax_error 'OWNER=":nosuchuser:"' "Unknown user ':nosuchuser:', ignoring"
45183cdd
DL
252test_syntax_error 'GROUP{a}="b"' 'Invalid attribute for GROUP.'
253test_syntax_error 'GROUP-="b"' 'Invalid operator for GROUP.'
254test_syntax_error 'GROUP!="b"' 'Invalid operator for GROUP.'
255test_syntax_error 'GROUP+="0"' "GROUP key takes '=' or ':=' operator, assuming '='."
0b1ee3e3 256test_syntax_error 'GROUP=":nosuchgroup:"' "Unknown group ':nosuchgroup:', ignoring"
45183cdd
DL
257test_syntax_error 'MODE{a}="b"' 'Invalid attribute for MODE.'
258test_syntax_error 'MODE-="b"' 'Invalid operator for MODE.'
259test_syntax_error 'MODE!="b"' 'Invalid operator for MODE.'
260test_syntax_error 'MODE+="0"' "MODE key takes '=' or ':=' operator, assuming '='."
261test_syntax_error 'MODE="%"' 'Invalid value "%" for MODE (char 1: invalid substitution type), ignoring.'
262test_syntax_error 'SECLABEL="b"' 'Invalid attribute for SECLABEL.'
263test_syntax_error 'SECLABEL{a}="%"' 'Invalid value "%" for SECLABEL (char 1: invalid substitution type), ignoring.'
264test_syntax_error 'SECLABEL{a}!="b"' 'Invalid operator for SECLABEL.'
265test_syntax_error 'SECLABEL{a}-="b"' 'Invalid operator for SECLABEL.'
266test_syntax_error 'SECLABEL{a}:="b"' "SECLABEL key takes '=' or '+=' operator, assuming '='."
267test_syntax_error 'RUN=="b"' 'Invalid operator for RUN.'
268test_syntax_error 'RUN-="b"' 'Invalid operator for RUN.'
269test_syntax_error 'RUN="%"' 'Invalid value "%" for RUN (char 1: invalid substitution type), ignoring.'
270test_syntax_error 'RUN{builtin}+="foo"' "Unknown builtin command 'foo', ignoring"
271test_syntax_error 'GOTO{a}="b"' 'Invalid attribute for GOTO.'
272test_syntax_error 'GOTO=="b"' 'Invalid operator for GOTO.'
d656c496
DL
273test_syntax_error 'NAME="a", GOTO="b"' 'GOTO="b" has no matching label, ignoring'
274test_syntax_error 'GOTO="a", GOTO="b"
45183cdd
DL
275LABEL="a"' 'Contains multiple GOTO keys, ignoring GOTO="b".'
276test_syntax_error 'LABEL{a}="b"' 'Invalid attribute for LABEL.'
277test_syntax_error 'LABEL=="b"' 'Invalid operator for LABEL.'
5040401b 278test_syntax_error 'LABEL="b"' 'LABEL="b" is unused.'
45183cdd 279test_syntax_error 'a="b"' "Invalid key 'a'"
ebb00082
DL
280test_syntax_error 'KERNEL=="", KERNEL=="?*", NAME="a"' 'conflicting match expressions, the line has no effect'
281test_syntax_error 'KERNEL=="abc", KERNEL!="abc", NAME="b"' 'conflicting match expressions, the line has no effect'
282test_syntax_error 'KERNEL=="|a|b", KERNEL!="b|a|", NAME="c"' 'conflicting match expressions, the line has no effect'
283test_syntax_error 'KERNEL=="a|b", KERNEL=="c|d|e", NAME="f"' 'conflicting match expressions, the line has no effect'
3ec58d0c 284# shellcheck disable=SC2016
d656c496 285test_syntax_error 'ENV{DISKSEQ}=="?*", ENV{DEVTYPE}!="partition", ENV{DISKSEQ}!="?*", ENV{ID_IGNORE_DISKSEQ}!="1", SYMLINK+="disk/by-diskseq/$env{DISKSEQ}"' \
ebb00082
DL
286 'conflicting match expressions, the line has no effect'
287test_syntax_error 'ACTION=="a*", ACTION=="bc*", NAME="d"' 'conflicting match expressions, the line has no effect'
288test_syntax_error 'ACTION=="a*|bc*", ACTION=="d*|ef*", NAME="g"' 'conflicting match expressions, the line has no effect'
3ec58d0c 289test_syntax_error 'KERNEL!="", KERNEL=="?*", NAME="a"' 'duplicate expressions'
5004aa84 290test_syntax_error 'KERNEL=="|a|b", KERNEL=="b|a|", NAME="c"' 'duplicate expressions'
3ec58d0c 291# shellcheck disable=SC2016
d656c496 292test_syntax_error 'ENV{DISKSEQ}=="?*", ENV{DEVTYPE}!="partition", ENV{DISKSEQ}=="?*", ENV{ID_IGNORE_DISKSEQ}!="1", SYMLINK+="disk/by-diskseq/$env{DISKSEQ}"' \
f99deb1e 293 'duplicate expressions'
acc1954a
DL
294test_syntax_error ',ACTION=="a", NAME="b"' 'Stray leading comma.'
295test_syntax_error ' ,ACTION=="a", NAME="b"' 'Stray leading comma.'
296test_syntax_error ', ACTION=="a", NAME="b"' 'Stray leading comma.'
297test_syntax_error 'ACTION=="a", NAME="b",' 'Stray trailing comma.'
298test_syntax_error 'ACTION=="a", NAME="b", ' 'Stray trailing comma.'
299test_syntax_error 'ACTION=="a" NAME="b"' 'A comma between tokens is expected.'
300test_syntax_error 'ACTION=="a",, NAME="b"' 'More than one comma between tokens.'
301test_syntax_error 'ACTION=="a" , NAME="b"' 'Stray whitespace before comma.'
302test_syntax_error 'ACTION=="a",NAME="b"' 'Whitespace after comma is expected.'
56df2f6f
DL
303test_syntax_error 'RESULT=="a", PROGRAM="b"' 'Reordering RESULT check after PROGRAM assignment.'
304test_syntax_error 'RESULT=="a*", PROGRAM="b", RESULT=="*c", PROGRAM="d"' \
305 'Reordering RESULT check after PROGRAM assignment.'
45183cdd 306
5004aa84
DL
307cat >"${rules}" <<'EOF'
308KERNEL=="a|b", KERNEL=="a|c", NAME="d"
309KERNEL=="a|b", KERNEL!="a|c", NAME="d"
f0a16c9a
DL
310KERNEL!="a", KERNEL!="b", NAME="c"
311KERNEL=="|a", KERNEL=="|b", NAME="c"
860e2a11
DL
312KERNEL=="*", KERNEL=="a*", NAME="b"
313KERNEL=="a*", KERNEL=="c*|ab*", NAME="d"
56df2f6f 314PROGRAM="a", RESULT=="b"
5004aa84
DL
315EOF
316assert_0 "${rules}"
317
197f695a
DL
318echo 'GOTO="a"' >"${rules}"
319cat >"${exp}" <<EOF
320${rules}:1 GOTO="a" has no matching label, ignoring
ebb00082 321${rules}:1 The line has no effect any more, dropping.
197f695a 322${rules}: udev rules check failed
45183cdd 323EOF
7b4cae90 324cp "${workdir}/default_output_1_fail" "${exo}"
197f695a 325assert_1 "${rules}"
45183cdd 326
197f695a 327cat >"${rules}" <<'EOF'
5040401b
DL
328GOTO="a"
329LABEL="a"
330EOF
197f695a 331assert_0 "${rules}"
5040401b 332
197f695a 333cat >"${rules}" <<'EOF'
5040401b
DL
334GOTO="b"
335LABEL="b"
336LABEL="b"
337EOF
197f695a
DL
338cat >"${exp}" <<EOF
339${rules}:3 LABEL="b" is unused.
340${rules}: udev rules check failed
5040401b 341EOF
7b4cae90 342cp "${workdir}/default_output_1_fail" "${exo}"
197f695a 343assert_1 "${rules}"
5040401b 344
b2f7bb76
DL
345cat >"${rules}" <<'EOF'
346GOTO="a"
347LABEL="a", LABEL="b"
348EOF
349cat >"${exp}" <<EOF
350${rules}:2 Contains multiple LABEL keys, ignoring LABEL="a".
351${rules}:1 GOTO="a" has no matching label, ignoring
ebb00082 352${rules}:1 The line has no effect any more, dropping.
b2f7bb76
DL
353${rules}:2 LABEL="b" is unused.
354${rules}: udev rules check failed
355EOF
7b4cae90 356cp "${workdir}/default_output_1_fail" "${exo}"
b2f7bb76
DL
357assert_1 "${rules}"
358
3ec58d0c
DL
359cat >"${rules}" <<'EOF'
360KERNEL!="", KERNEL=="?*", KERNEL=="", NAME="a"
361EOF
362cat >"${exp}" <<EOF
363${rules}:1 duplicate expressions
ebb00082 364${rules}:1 conflicting match expressions, the line has no effect
3ec58d0c
DL
365${rules}: udev rules check failed
366EOF
7b4cae90 367cp "${workdir}/default_output_1_fail" "${exo}"
3ec58d0c
DL
368assert_1 "${rules}"
369
acc1954a
DL
370cat >"${rules}" <<'EOF'
371ACTION=="a"NAME="b"
372EOF
373cat >"${exp}" <<EOF
374${rules}:1 A comma between tokens is expected.
375${rules}:1 Whitespace between tokens is expected.
376${rules}: udev rules check failed
377EOF
378cp "${workdir}/default_output_1_fail" "${exo}"
379assert_1 "${rules}"
380
381cat >"${rules}" <<'EOF'
382ACTION=="a" ,NAME="b"
383EOF
384cat >"${exp}" <<EOF
385${rules}:1 Stray whitespace before comma.
386${rules}:1 Whitespace after comma is expected.
387${rules}: udev rules check failed
388EOF
389cp "${workdir}/default_output_1_fail" "${exo}"
390assert_1 "${rules}"
391
c8f39ddc
DL
392# udevadm verify --root
393sed "s|sample-[0-9]*.rules|${workdir}/${rules_dir}/&|" sample-*.exp >"${workdir}/${exp}"
394cd -
395assert_1 --root="${workdir}"
396
45183cdd 397exit 0