chiark / gitweb /
[PATCH] update Fedora config files and add some more tests
[elogind.git] / test / udev-test.pl
1 #!/usr/bin/perl
2
3 # udev-test
4 #
5 # Provides automated testing of the udev binary.
6 # The whole test is self contained in this file, except the matching sysfs tree.
7 # Simply extend the @tests array, to add a new test variant.
8 #
9 # Every test is driven by its own temporary config file.
10 # This program prepares the environment, creates the config and calls udev.
11 #
12 # udev reads the config, looks at the provided sysfs and
13 # first creates and then removes the device node.
14 # After creation and removal the result is checked against the
15 # expected value and the result is printed.
16 #
17 # happy testing,
18 # Kay Sievers <kay.sievers@vrfy.org>, 2003
19 #
20 # Modified April 9, 2004 by Leann Ogasawara <ogasawara@osdl.org>
21 #  - expanded @tests array to add more symlinks and permissions tests
22 #  - some of the symlinks tests also test lack of node creation
23 #  - added symlink_test() function
24 #  - moved permissions and major_minor tests into their own functions
25
26 use warnings;
27 use strict;
28
29 my $PWD = $ENV{PWD};
30 my $sysfs     = "sys/";
31 my $udev_bin  = "../udev";
32 my $udev_root = "udev-root/"; # !!! directory will be removed !!!
33 my $udev_db   = ".udevdb";
34 my $main_conf = "udev-test.conf";
35 my $conf_tmp  = "udev-test.rules";
36
37 # uncomment following line to run udev with valgrind.
38 # Should make this a runtime option to the script someday...
39 #my $udev_bin  = "valgrind --tool=memcheck --leak-check=yes   ../udev";
40
41 my @tests = (
42         {
43                 desc            => "label test of scsi disc",
44                 subsys          => "block",
45                 devpath         => "/block/sda",
46                 exp_name        => "boot_disk" ,
47                 conf            => <<EOF
48 BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="boot_disk%n"
49 KERNEL="ttyUSB0", NAME="visor"
50 EOF
51         },
52         {
53                 desc            => "label test of scsi partition",
54                 subsys          => "block",
55                 devpath         => "/block/sda/sda1",
56                 exp_name        => "boot_disk1" ,
57                 conf            => <<EOF
58 BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="boot_disk%n"
59 EOF
60         },
61         {
62                 desc            => "label test of pattern match",
63                 subsys          => "block",
64                 devpath         => "/block/sda/sda1",
65                 exp_name        => "boot_disk1" ,
66                 conf            => <<EOF
67 BUS="scsi", SYSFS{vendor}="?IBM-ESXS", NAME="boot_disk%n-1"
68 BUS="scsi", SYSFS{vendor}="IBM-ESXS?", NAME="boot_disk%n-2"
69 BUS="scsi", SYSFS{vendor}="IBM-ES??", NAME="boot_disk%n"
70 BUS="scsi", SYSFS{vendor}="IBM-ESXSS", NAME="boot_disk%n-3"
71 EOF
72         },
73         {
74                 desc            => "label test of multiple sysfs files",
75                 subsys          => "block",
76                 devpath         => "/block/sda/sda1",
77                 exp_name        => "boot_disk1" ,
78                 conf            => <<EOF
79 BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW   !#", NAME="boot_diskX%n"
80 BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW    !#", NAME="boot_disk%n"
81 EOF
82         },
83         {
84                 desc            => "label test of max sysfs files",
85                 subsys          => "block",
86                 devpath         => "/block/sda/sda1",
87                 exp_name        => "boot_disk1" ,
88                 conf            => <<EOF
89 BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW    !#", SYSFS{scsi_level}="4", SYSFS{rev}="B245", SYSFS{type}="2", SYSFS{queue_depth}="32", NAME="boot_diskXX%n"
90 BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW    !#", SYSFS{scsi_level}="4", SYSFS{rev}="B245", SYSFS{type}="0", NAME="boot_disk%n"
91 EOF
92         },
93         {
94                 desc            => "catch device by *",
95                 subsys          => "tty",
96                 devpath         => "/class/tty/ttyUSB0",
97                 exp_name        => "visor/0" ,
98                 conf            => <<EOF
99 KERNEL="ttyUSB*", NAME="visor/%n"
100 EOF
101         },
102         {
103                 desc            => "catch device by * - take 2",
104                 subsys          => "tty",
105                 devpath         => "/class/tty/ttyUSB0",
106                 exp_name        => "visor/0" ,
107                 conf            => <<EOF
108 KERNEL="*USB1", NAME="bad"
109 KERNEL="*USB0", NAME="visor/%n"
110 EOF
111         },
112         {
113                 desc            => "catch device by ?",
114                 subsys          => "tty",
115                 devpath         => "/class/tty/ttyUSB0",
116                 exp_name        => "visor/0" ,
117                 conf            => <<EOF
118 KERNEL="ttyUSB??*", NAME="visor/%n-1"
119 KERNEL="ttyUSB??", NAME="visor/%n-2"
120 KERNEL="ttyUSB?", NAME="visor/%n"
121 EOF
122         },
123         {
124                 desc            => "catch device by character class",
125                 subsys          => "tty",
126                 devpath         => "/class/tty/ttyUSB0",
127                 exp_name        => "visor/0" ,
128                 conf            => <<EOF
129 KERNEL="ttyUSB[A-Z]*", NAME="visor/%n-1"
130 KERNEL="ttyUSB?[0-9]", NAME="visor/%n-2"
131 KERNEL="ttyUSB[0-9]*", NAME="visor/%n"
132 EOF
133         },
134         {
135                 desc            => "replace kernel name",
136                 subsys          => "tty",
137                 devpath         => "/class/tty/ttyUSB0",
138                 exp_name        => "visor" ,
139                 conf            => <<EOF
140 KERNEL="ttyUSB0", NAME="visor"
141 EOF
142         },
143         {
144                 desc            => "Handle comment lines in config file (and replace kernel name)",
145                 subsys          => "tty",
146                 devpath         => "/class/tty/ttyUSB0",
147                 exp_name        => "visor" ,
148                 conf            => <<EOF
149 # this is a comment
150 KERNEL="ttyUSB0", NAME="visor"
151
152 EOF
153         },
154         {
155                 desc            => "Handle comment lines in config file with whitespace (and replace kernel name)",
156                 subsys          => "tty",
157                 devpath         => "/class/tty/ttyUSB0",
158                 exp_name        => "visor" ,
159                 conf            => <<EOF
160  # this is a comment with whitespace before the comment 
161 KERNEL="ttyUSB0", NAME="visor"
162
163 EOF
164         },
165         {
166                 desc            => "Handle whitespace only lines (and replace kernel name)",
167                 subsys          => "tty",
168                 devpath         => "/class/tty/ttyUSB0",
169                 exp_name        => "whitespace" ,
170                 conf            => <<EOF
171
172  
173
174  # this is a comment with whitespace before the comment 
175 KERNEL="ttyUSB0", NAME="whitespace"
176
177  
178
179 EOF
180         },
181         {
182                 desc            => "Handle empty lines in config file (and replace kernel name)",
183                 subsys          => "tty",
184                 devpath         => "/class/tty/ttyUSB0",
185                 exp_name        => "visor" ,
186                 conf            => <<EOF
187
188 KERNEL="ttyUSB0", NAME="visor"
189
190 EOF
191         },
192         {
193                 desc            => "Handle backslashed multi lines in config file (and replace kernel name)",
194                 subsys          => "tty",
195                 devpath         => "/class/tty/ttyUSB0",
196                 exp_name        => "visor" ,
197                 conf            => <<EOF
198 KERNEL="ttyUSB0", \\
199 NAME="visor"
200
201 EOF
202         },
203         {
204                 desc            => "Handle stupid backslashed multi lines in config file (and replace kernel name)",
205                 subsys          => "tty",
206                 devpath         => "/class/tty/ttyUSB0",
207                 exp_name        => "visor" ,
208                 conf            => <<EOF
209
210 #
211 \\
212
213 \\\\
214
215 #\\
216
217 KERNEL="ttyUSB0", \\
218         NAME="visor"
219
220 EOF
221         },
222         {
223                 desc            => "subdirectory handling",
224                 subsys          => "tty",
225                 devpath         => "/class/tty/ttyUSB0",
226                 exp_name        => "sub/direct/ory/visor" ,
227                 conf            => <<EOF
228 KERNEL="ttyUSB0", NAME="sub/direct/ory/visor"
229 EOF
230         },
231         {
232                 desc            => "place on bus of scsi partition",
233                 subsys          => "block",
234                 devpath         => "/block/sda/sda3",
235                 exp_name        => "first_disk3" ,
236                 conf            => <<EOF
237 BUS="scsi", PLACE="0:0:0:0", NAME="first_disk%n"
238 EOF
239         },
240         {
241                 desc            => "test NAME substitution chars",
242                 subsys          => "block",
243                 devpath         => "/block/sda/sda3",
244                 exp_name        => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" ,
245                 conf            => <<EOF
246 BUS="scsi", PLACE="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b"
247 EOF
248         },
249         {
250                 desc            => "test NAME substitution chars (with length limit)",
251                 subsys          => "block",
252                 devpath         => "/block/sda/sda3",
253                 exp_name        => "M8-m3-n3-b0:0-sIBM" ,
254                 conf            => <<EOF
255 BUS="scsi", PLACE="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
256 EOF
257         },
258         {
259                 desc            => "old style SYSFS_ attribute",
260                 subsys          => "block",
261                 devpath         => "/block/sda",
262                 exp_name        => "good" ,
263                 conf            => <<EOF
264 BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="good"
265 EOF
266         },
267         {
268                 desc            => "sustitution of sysfs value (%s{file})",
269                 subsys          => "block",
270                 devpath         => "/block/sda",
271                 exp_name        => "disk-IBM-ESXS-sda" ,
272                 conf            => <<EOF
273 BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="disk-%s{vendor}-%k"
274 KERNEL="ttyUSB0", NAME="visor"
275 EOF
276         },
277         {
278                 desc            => "program result substitution",
279                 subsys          => "block",
280                 devpath         => "/block/sda/sda3",
281                 exp_name        => "special-device-3" ,
282                 conf            => <<EOF
283 BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="-special-*", NAME="%c-1-%n"
284 BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special--*", NAME="%c-2-%n"
285 BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-device-", NAME="%c-3-%n"
286 BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-devic", NAME="%c-4-%n"
287 BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-*", NAME="%c-%n"
288 EOF
289         },
290         {
291                 desc            => "program result substitution (no argument should be subsystem)",
292                 subsys          => "block",
293                 devpath         => "/block/sda/sda3",
294                 exp_name        => "subsys_block" ,
295                 conf            => <<EOF
296 BUS="scsi", PROGRAM="/bin/echo", RESULT="block", NAME="subsys_block"
297 EOF
298         },
299         {
300                 desc            => "program result substitution (newline removal)",
301                 subsys          => "block",
302                 devpath         => "/block/sda/sda3",
303                 exp_name        => "newline_removed" ,
304                 conf            => <<EOF
305 BUS="scsi", PROGRAM="/bin/echo test", RESULT="test", NAME="newline_removed"
306 EOF
307         },
308         {
309                 desc            => "program result substitution",
310                 subsys          => "block",
311                 devpath         => "/block/sda/sda3",
312                 exp_name        => "test-0:0:0:0" ,
313                 conf            => <<EOF
314 BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-0:0*", NAME="%c"
315 EOF
316         },
317         {
318                 desc            => "program with escaped format char (tricky: callout returns format char!)",
319                 subsys          => "block",
320                 devpath         => "/block/sda/sda3",
321                 exp_name        => "escape-3" ,
322                 conf            => <<EOF
323 BUS="scsi", PROGRAM="/bin/echo -n escape-%%n", KERNEL="sda3", NAME="%c"
324 EOF
325         },
326         {
327                 desc            => "program with lots of arguments",
328                 subsys          => "block",
329                 devpath         => "/block/sda/sda3",
330                 exp_name        => "foo9" ,
331                 conf            => <<EOF
332 BUS="scsi", PROGRAM="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL="sda3", NAME="%c{7}"
333 EOF
334         },
335         {
336                 desc            => "program with subshell",
337                 subsys          => "block",
338                 devpath         => "/block/sda/sda3",
339                 exp_name        => "bar9" ,
340                 conf            => <<EOF
341 BUS="scsi", PROGRAM="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed  s/foo9/bar9/'", KERNEL="sda3", NAME="%c{7}"
342 EOF
343         },
344         {
345                 desc            => "program arguments combined with apostrophes",
346                 subsys          => "block",
347                 devpath         => "/block/sda/sda3",
348                 exp_name        => "foo7" ,
349                 conf            => <<EOF
350 BUS="scsi", PROGRAM="/bin/echo -n 'foo3 foo4'   'foo5   foo6   foo7 foo8'", KERNEL="sda3", NAME="%c{5}"
351 EOF
352         },
353         {
354                 desc            => "characters before the %c{N} substitution",
355                 subsys          => "block",
356                 devpath         => "/block/sda/sda3",
357                 exp_name        => "my-foo9" ,
358                 conf            => <<EOF
359 BUS="scsi", PROGRAM="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL="sda3", NAME="my-%c{7}"
360 EOF
361         },
362         {
363                 desc            => "substitute the second to last argument",
364                 subsys          => "block",
365                 devpath         => "/block/sda/sda3",
366                 exp_name        => "my-foo8" ,
367                 conf            => <<EOF
368 BUS="scsi", PROGRAM="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL="sda3", NAME="my-%c{6}"
369 EOF
370         },
371         {
372                 desc            => "invalid program for device with no bus",
373                 subsys          => "tty",
374                 devpath         => "/class/tty/console",
375                 exp_name        => "TTY" ,
376                 conf            => <<EOF
377 BUS="scsi", PROGRAM="/bin/echo -n foo", RESULT="foo", NAME="foo"
378 KERNEL="console", NAME="TTY"
379 EOF
380         },
381         {
382                 desc            => "valid program for device with no bus",
383                 subsys          => "tty",
384                 devpath         => "/class/tty/console",
385                 exp_name        => "foo" ,
386                 conf            => <<EOF
387 PROGRAM="/bin/echo -n foo", RESULT="foo", NAME="foo"
388 KERNEL="console", NAME="TTY"
389 EOF
390         },
391         {
392                 desc            => "invalid label for device with no bus",
393                 subsys          => "tty",
394                 devpath         => "/class/tty/console",
395                 exp_name        => "TTY" ,
396                 conf            => <<EOF
397 BUS="foo", SYSFS{dev}="5:1", NAME="foo"
398 KERNEL="console", NAME="TTY"
399 EOF
400         },
401         {
402                 desc            => "valid label for device with no bus",
403                 subsys          => "tty",
404                 devpath         => "/class/tty/console",
405                 exp_name        => "foo" ,
406                 conf            => <<EOF
407 SYSFS{dev}="5:1", NAME="foo"
408 KERNEL="console", NAME="TTY"
409 EOF
410         },
411         {
412                 desc            => "program and bus type match",
413                 subsys          => "block",
414                 devpath         => "/block/sda",
415                 exp_name        => "scsi-0:0:0:0" ,
416                 conf            => <<EOF
417 BUS="usb", PROGRAM="/bin/echo -n usb-%b", NAME="%c"
418 BUS="scsi", PROGRAM="/bin/echo -n scsi-%b", NAME="%c"
419 BUS="foo", PROGRAM="/bin/echo -n foo-%b", NAME="%c"
420 EOF
421         },
422         {
423                 desc            => "create all possible partitions",
424                 subsys          => "block",
425                 devpath         => "/block/sda",
426                 exp_name        => "boot_disk15" ,
427                 conf            => <<EOF
428 BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME{all_partitions}="boot_disk"
429 EOF
430         },
431         {
432                 desc            => "sysfs parent hierarchy",
433                 subsys          => "tty",
434                 devpath         => "/class/tty/ttyUSB0",
435                 exp_name        => "visor" ,
436                 conf            => <<EOF
437 SYSFS{idProduct}="2008", NAME="visor"
438 EOF
439         },
440         {
441                 desc            => "name test with ! in the name",
442                 subsys          => "block",
443                 devpath         => "/block/rd!c0d0",
444                 exp_name        => "rd/c0d0" ,
445                 conf            => <<EOF
446 BUS="scsi", NAME="%k"
447 KERNEL="ttyUSB0", NAME="visor"
448 EOF
449         },
450         {
451                 desc            => "name test with ! in the name, but no matching rule",
452                 subsys          => "block",
453                 devpath         => "/block/rd!c0d0",
454                 exp_name        => "rd/c0d0" ,
455                 conf            => <<EOF
456 KERNEL="ttyUSB0", NAME="visor"
457 EOF
458         },
459         {
460                 desc            => "name test with ! in the name for a partition",
461                 subsys          => "block",
462                 devpath         => "/block/cciss!c0d0/cciss!c0d0p1",
463                 exp_name        => "cciss/c0d0p1" ,
464                 conf            => <<EOF
465 BUS="scsi", NAME="%k"
466 KERNEL="ttyUSB0", NAME="visor"
467 EOF
468         },
469         {
470                 desc            => "ID rule",
471                 subsys          => "block",
472                 devpath         => "/block/sda",
473                 exp_name        => "scsi-0:0:0:0",
474                 conf            => <<EOF
475 BUS="usb", ID="0:0:0:0", NAME="not-scsi"
476 BUS="scsi", ID="0:0:0:1", NAME="no-match"
477 BUS="scsi", ID=":0", NAME="short-id"
478 BUS="scsi", ID="/0:0:0:0", NAME="no-match"
479 BUS="scsi", ID="0:0:0:0", NAME="scsi-0:0:0:0"
480 EOF
481         },
482         {
483                 desc            => "ID wildcard all",
484                 subsys          => "block",
485                 devpath         => "/block/sda",
486                 exp_name        => "scsi-0:0:0:0",
487                 conf            => <<EOF
488 BUS="scsi", ID="*:1", NAME="no-match"
489 BUS="scsi", ID="*:0:1", NAME="no-match"
490 BUS="scsi", ID="*:0:0:1", NAME="no-match"
491 BUS="scsi", ID="*", NAME="scsi-0:0:0:0"
492 BUS="scsi", ID="0:0:0:0", NAME="bad"
493 EOF
494         },
495         {
496                 desc            => "ID wildcard partial",
497                 subsys          => "block",
498                 devpath         => "/block/sda",
499                 exp_name        => "scsi-0:0:0:0",
500                 conf            => <<EOF
501 BUS="scsi", ID="*:0", NAME="scsi-0:0:0:0"
502 BUS="scsi", ID="0:0:0:0", NAME="bad"
503 EOF
504         },
505         {
506                 desc            => "ID wildcard partial 2",
507                 subsys          => "block",
508                 devpath         => "/block/sda",
509                 exp_name        => "scsi-0:0:0:0",
510                 conf            => <<EOF
511 BUS="scsi", ID="*:0:0:0", NAME="scsi-0:0:0:0"
512 BUS="scsi", ID="0:0:0:0", NAME="bad"
513 EOF
514         },
515         {
516                 desc            => "ignore SYSFS attribute whitespace",
517                 subsys          => "block",
518                 devpath         => "/block/sda",
519                 exp_name        => "ignored",
520                 conf            => <<EOF
521 BUS="scsi", SYSFS{whitespace_test}="WHITE  SPACE", NAME="ignored"
522 EOF
523         },
524         {
525                 desc            => "do not ignore SYSFS attribute whitespace",
526                 subsys          => "block",
527                 devpath         => "/block/sda",
528                 exp_name        => "matched-with-space",
529                 conf            => <<EOF
530 BUS="scsi", SYSFS{whitespace_test}="WHITE  SPACE ", NAME="wrong-to-ignore"
531 BUS="scsi", SYSFS{whitespace_test}="WHITE  SPACE   ", NAME="matched-with-space"
532 EOF
533         },
534         {
535                 desc            => "permissions USER=bad GROUP=name",
536                 subsys          => "tty",
537                 devpath         => "/class/tty/tty33",
538                 exp_name        => "tty33",
539                 exp_perms       => "0:0:0660",
540                 conf            => <<EOF
541 KERNEL="tty33", NAME="tty33", OWNER="bad", GROUP="name"
542 EOF
543         },
544         {
545                 desc            => "permissions OWNER=5000",
546                 subsys          => "block",
547                 devpath         => "/block/sda",
548                 exp_name        => "node",
549                 exp_perms       => "5000::0660",
550                 conf            => <<EOF
551 BUS="scsi", KERNEL="sda", NAME="node", OWNER="5000"
552 EOF
553         },
554         {
555                 desc            => "permissions GROUP=100",
556                 subsys          => "block",
557                 devpath         => "/block/sda",
558                 exp_name        => "node",
559                 exp_perms       => ":100:0660",
560                 conf            => <<EOF
561 BUS="scsi", KERNEL="sda", NAME="node", GROUP="100"
562 EOF
563         },
564         {
565                 desc            => "permissions MODE=0777",
566                 subsys          => "block",
567                 devpath         => "/block/sda",
568                 exp_name        => "node",
569                 exp_perms       => "::0777",
570                 conf            => <<EOF
571 BUS="scsi", KERNEL="sda", NAME="node", MODE="0777"
572 EOF
573         },
574         {
575                 desc            => "permissions OWNER=5000 GROUP=100 MODE=0777",
576                 subsys          => "block",
577                 devpath         => "/block/sda",
578                 exp_name        => "node",
579                 exp_perms       => "5000:100:0777",
580                 conf            => <<EOF
581 BUS="scsi", KERNEL="sda", NAME="node", OWNER="5000", GROUP="100", MODE="0777"
582 EOF
583         },
584         {
585                 desc            => "permissions OWNER to 5000",
586                 subsys          => "tty",
587                 devpath         => "/class/tty/ttyUSB0",
588                 exp_name        => "ttyUSB0",
589                 exp_perms       => "5000::",
590                 conf            => <<EOF
591 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", OWNER="5000"
592 EOF
593         },
594         {
595                 desc            => "permissions GROUP to 100",
596                 subsys          => "tty",
597                 devpath         => "/class/tty/ttyUSB0",
598                 exp_name        => "ttyUSB0",
599                 exp_perms       => ":100:0660",
600                 conf            => <<EOF
601 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", GROUP="100"
602 EOF
603         },
604         {
605                 desc            => "permissions MODE to 0060",
606                 subsys          => "tty",
607                 devpath         => "/class/tty/ttyUSB0",
608                 exp_name        => "ttyUSB0",
609                 exp_perms       => "::0060",
610                 conf            => <<EOF
611 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", MODE="0060"
612 EOF
613         },
614         {
615                 desc            => "permissions OWNER, GROUP, MODE",
616                 subsys          => "tty",
617                 devpath         => "/class/tty/ttyUSB0",
618                 exp_name        => "ttyUSB0",
619                 exp_perms       => "5000:100:0777",
620                 conf            => <<EOF
621 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", OWNER="5000", GROUP="100", MODE="0777"
622 EOF
623         },
624         {
625                 desc            => "permissions only rule",
626                 subsys          => "tty",
627                 devpath         => "/class/tty/ttyUSB0",
628                 exp_name        => "ttyUSB0",
629                 exp_perms       => "5000:100:0777",
630                 conf            => <<EOF
631 KERNEL="ttyUSB[0-9]*", OWNER="5000", GROUP="100", MODE="0777"
632 KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
633 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n"
634 EOF
635         },
636         {
637                 desc            => "multiple permissions only rule",
638                 subsys          => "tty",
639                 devpath         => "/class/tty/ttyUSB0",
640                 exp_name        => "ttyUSB0",
641                 exp_perms       => "3000:4000:0777",
642                 conf            => <<EOF
643 SUBSYSTEM="tty", OWNER="3000"
644 SUBSYSTEM="tty", GROUP="4000"
645 SUBSYSTEM="tty", MODE="0777"
646 KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
647 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n"
648 EOF
649         },
650         {
651                 desc            => "permissions only rule with override at NAME rule",
652                 subsys          => "tty",
653                 devpath         => "/class/tty/ttyUSB0",
654                 exp_name        => "ttyUSB0",
655                 exp_perms       => "3000:8000:0777",
656                 conf            => <<EOF
657 SUBSYSTEM="tty", OWNER="3000"
658 SUBSYSTEM="tty", GROUP="4000"
659 SUBSYSTEM="tty", MODE="0777"
660 KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
661 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", GROUP="8000"
662 EOF
663         },
664         {
665                 desc            => "major/minor number test",
666                 subsys          => "block",
667                 devpath         => "/block/sda",
668                 exp_name        => "node",
669                 exp_majorminor  => "8:0",
670                 conf            => <<EOF
671 BUS="scsi", KERNEL="sda", NAME="node"
672 EOF
673         },
674         {
675                 desc            => "big minor number test",
676                 subsys          => "i2c-dev",
677                 devpath         => "/class/i2c-dev/i2c-300",
678                 exp_name        => "node",
679                 exp_majorminor  => "89:300",
680                 conf            => <<EOF
681 KERNEL="i2c-300", NAME="node"
682 EOF
683         },
684         {
685                 desc            => "big major number test",
686                 subsys          => "i2c-dev",
687                 devpath         => "/class/i2c-dev/i2c-fake1",
688                 exp_name        => "node",
689                 exp_majorminor  => "4095:1",
690                 conf            => <<EOF
691 KERNEL="i2c-fake1", NAME="node"
692 EOF
693         },
694         {
695                 desc            => "big major and big minor number test",
696                 subsys          => "i2c-dev",
697                 devpath         => "/class/i2c-dev/i2c-fake2",
698                 exp_name        => "node",
699                 exp_majorminor  => "4094:89999",
700                 conf            => <<EOF
701 KERNEL="i2c-fake2", NAME="node"
702 EOF
703         },
704         {
705                 desc            => "multiple symlinks with format char",
706                 subsys          => "tty",
707                 devpath         => "/class/tty/ttyUSB0",
708                 exp_name        => "symlink2-ttyUSB0",
709                 exp_target      => "ttyUSB0",
710                 conf            => <<EOF
711 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
712 EOF
713         },
714         {
715                 desc            => "symlink creation (same directory)",
716                 subsys          => "tty",
717                 devpath         => "/class/tty/ttyUSB0",
718                 exp_name        => "visor0",
719                 exp_target      => "ttyUSB0",
720                 conf            => <<EOF
721 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="visor%n"
722 EOF
723         },
724         {
725                 desc            => "symlink creation (relative link forward)",
726                 subsys          => "block",
727                 devpath         => "/block/sda/sda2",
728                 exp_name        => "1/2/symlink" ,
729                 exp_target      => "a/b/node",
730                 conf            => <<EOF
731 BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
732 EOF
733         },
734         {
735                 desc            => "symlink creation (relative link back and forward)",
736                 subsys          => "block",
737                 devpath         => "/block/sda/sda2",
738                 exp_name        => "1/2/c/d/symlink" ,
739                 exp_target      => "../../a/b/node",
740                 conf            => <<EOF
741 BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
742 EOF
743         },
744         {
745                 desc            => "multiple symlinks",
746                 subsys          => "tty",
747                 devpath         => "/class/tty/ttyUSB0",
748                 exp_name        => "second-0" ,
749                 exp_target      => "visor" ,
750                 conf            => <<EOF
751 KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
752 EOF
753         },
754         {
755                 desc            => "symlink only rule",
756                 subsys          => "block",
757                 devpath         => "/block/sda",
758                 exp_name        => "symlink-only2",
759                 exp_target      => "link",
760                 conf            => <<EOF
761 BUS="scsi", KERNEL="sda", SYMLINK="symlink-only1"
762 BUS="scsi", KERNEL="sda", SYMLINK="symlink-only2"
763 BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0"
764 EOF
765         },
766         {
767                 desc            => "symlink name empty",
768                 subsys          => "block",
769                 devpath         => "/block/sda",
770                 exp_name        => "",
771                 exp_target      => "link",
772                 exp_error       => "yes",
773                 conf            => <<EOF
774 BUS="scsi", KERNEL="sda", NAME="link", SYMLINK=""
775 EOF
776         },
777         {
778                 desc            => "symlink name '.'",
779                 subsys          => "block",
780                 devpath         => "/block/sda",
781                 exp_name        => ".",
782                 exp_target      => "link",
783                 exp_error       => "yes",
784                 conf            => <<EOF
785 BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="."
786 EOF
787         },
788         {
789                 desc            => "symlink to empty name",
790                 subsys          => "block",
791                 devpath         => "/block/sda",
792                 exp_name        => "symlink",
793                 exp_target      => "",
794                 exp_error       => "yes",
795                 conf            => <<EOF
796 BUS="scsi", KERNEL="sda", NAME="", SYMLINK="symlink"
797 EOF
798         },
799         {
800                 desc            => "symlink and name empty",
801                 subsys          => "block",
802                 devpath         => "/block/sda",
803                 exp_name        => "",
804                 exp_target      => "",
805                 exp_error       => "yes",
806                 conf            => <<EOF
807 BUS="scsi", KERNEL="sda", NAME="", SYMLINK=""
808 EOF
809         },
810         {
811                 desc            => "symlink node to itself",
812                 subsys          => "tty",
813                 devpath         => "/class/tty/tty0",
814                 exp_name        => "link",
815                 exp_target      => "link",
816                 conf            => <<EOF
817 KERNEL="tty0", NAME="link", SYMLINK="link"
818 EOF
819         },
820         {
821                 desc            => "symlink %n substitution",
822                 subsys          => "tty",
823                 devpath         => "/class/tty/ttyUSB0",
824                 exp_name        => "symlink0",
825                 exp_target      => "ttyUSB0",
826                 conf            => <<EOF
827 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink%n"
828 EOF
829         },
830         {
831                 desc            => "symlink %k substitution",
832                 subsys          => "tty",
833                 devpath         => "/class/tty/ttyUSB0",
834                 exp_name        => "symlink-ttyUSB0",
835                 exp_target      => "ttyUSB0",
836                 conf            => <<EOF
837 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink-%k"
838 EOF
839         },
840         {
841                 desc            => "symlink %M:%m substitution",
842                 subsys          => "tty",
843                 devpath         => "/class/tty/ttyUSB0",
844                 exp_name        => "major-188:0",
845                 exp_target      => "ttyUSB0",
846                 conf            => <<EOF
847 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="major-%M:%m"
848 EOF
849         },
850         {
851                 desc            => "symlink %b substitution",
852                 subsys          => "block",
853                 devpath         => "/block/sda",
854                 exp_name        => "symlink-0:0:0:0",
855                 exp_target      => "node",
856                 conf            => <<EOF
857 BUS="scsi", KERNEL="sda", NAME="node", SYMLINK="symlink-%b"
858 EOF
859         },
860         {
861                 desc            => "symlink %c substitution",
862                 subsys          => "tty",
863                 devpath         => "/class/tty/ttyUSB0",
864                 exp_name        => "test",
865                 exp_target      => "ttyUSB0",
866                 conf            => <<EOF
867 KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo test" NAME="ttyUSB%n", SYMLINK="%c"
868 EOF
869         },
870         {
871                 desc            => "symlink %c{N} substitution",
872                 subsys          => "tty",
873                 devpath         => "/class/tty/ttyUSB0",
874                 exp_name        => "test",
875                 exp_target      => "ttyUSB0",
876                 conf            => <<EOF
877 KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2}"
878 EOF
879         },
880         {
881                 desc            => "symlink %c{N+} substitution",
882                 subsys          => "tty",
883                 devpath         => "/class/tty/ttyUSB0",
884                 exp_name        => "this",
885                 exp_target      => "ttyUSB0",
886                 conf            => <<EOF
887 KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2+}"
888 EOF
889         },
890         {
891                 desc            => "symlink only rule with %c{N+}",
892                 subsys          => "block",
893                 devpath         => "/block/sda",
894                 exp_name        => "test",
895                 exp_target      => "link",
896                 conf            => <<EOF
897 BUS="scsi", KERNEL="sda", PROGRAM="/bin/echo link test this" SYMLINK="%c{2+}"
898 BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0"
899 EOF
900         },
901         {
902                 desc            => "symlink %s{filename} substitution",
903                 subsys          => "tty",
904                 devpath         => "/class/tty/ttyUSB0",
905                 exp_name        => "188:0",
906                 exp_target      => "ttyUSB0",
907                 conf            => <<EOF
908 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%s{dev}"
909 EOF
910         },
911         {
912                 desc            => "symlink %Ns{filename} substitution",
913                 subsys          => "tty",
914                 devpath         => "/class/tty/ttyUSB0",
915                 exp_name        => "188",
916                 exp_target      => "ttyUSB0",
917                 conf            => <<EOF
918 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%3s{dev}"
919 EOF
920         },
921         {
922                 desc            => "symlink with '%' in name",
923                 subsys          => "tty",
924                 devpath         => "/class/tty/ttyUSB0",
925                 exp_name        => "percent%sign",
926                 exp_target      => "ttyUSB0",
927                 conf            => <<EOF
928 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="percent%%sign"
929 EOF
930         },
931         {
932                 desc            => "symlink with '%' in name",
933                 subsys          => "tty",
934                 devpath         => "/class/tty/ttyUSB0",
935                 exp_name        => "%ttyUSB0_name",
936                 exp_target      => "ttyUSB0",
937                 conf            => <<EOF
938 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%%%k_name"
939 EOF
940         },
941         {
942                 desc            => "program result substitution (numbered part of)",
943                 subsys          => "block",
944                 devpath         => "/block/sda/sda3",
945                 exp_name        => "link1",
946                 exp_target      => "node",
947                 conf            => <<EOF
948 BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", RESULT="node *", NAME="%c{1}", SYMLINK="%c{2} %c{3}"
949 EOF
950         },
951         {
952                 desc            => "program result substitution (numbered part of+)",
953                 subsys          => "block",
954                 devpath         => "/block/sda/sda3",
955                 exp_name        => "link4",
956                 exp_target      => "node",
957                 conf            => <<EOF
958 BUS="scsi", PROGRAM="/bin/echo -n node link1 link2 link3 link4", RESULT="node *", NAME="%c{1}", SYMLINK="%c{2+}"
959 EOF
960         },
961         {
962                 desc            => "enumeration char test (single test)",
963                 subsys          => "block",
964                 devpath         => "/block/sda",
965                 exp_name        => "cdrom",
966                 conf            => <<EOF
967 KERNEL="sda", NAME="cdrom%e"
968 EOF
969         },
970         {
971                 desc            => "enumeration char test sequence (1/5 keep)",
972                 subsys          => "block",
973                 devpath         => "/block/sda",
974                 exp_name        => "cdrom",
975                 option          => "keep",
976                 conf            => <<EOF
977 KERNEL="sda", NAME="cdrom%e"
978 EOF
979         },
980         {
981                 desc            => "enumeration char test sequence 2/5 (keep)",
982                 subsys          => "block",
983                 devpath         => "/block/sda/sda1",
984                 exp_name        => "enum",
985                 option          => "keep",
986                 conf            => <<EOF
987 KERNEL="sda1", NAME="enum%e"
988 EOF
989         },
990         {
991                 desc            => "enumeration char test sequence 3/5 (keep)",
992                 subsys          => "block",
993                 devpath         => "/block/sda/sda2",
994                 exp_name        => "cdrom1",
995                 option          => "keep",
996                 conf            => <<EOF
997 KERNEL="sda2", NAME="cdrom%e"
998 EOF
999         },
1000         {
1001                 desc            => "enumeration char test sequence 4/5 (keep)",
1002                 subsys          => "block",
1003                 devpath         => "/block/sda/sda3",
1004                 exp_name        => "enum1",
1005                 option          => "keep",
1006                 conf            => <<EOF
1007 KERNEL="sda3", NAME="enum%e"
1008 EOF
1009         },
1010         {
1011                 desc            => "enumeration char test sequence 5/5 (clean)",
1012                 subsys          => "block",
1013                 devpath         => "/block/sda/sda4",
1014                 exp_name        => "cdrom2",
1015                 option          => "clear",
1016                 conf            => <<EOF
1017 KERNEL="sda4", NAME="cdrom%e"
1018 EOF
1019         },
1020         {
1021                 desc            => "enumeration char test after cleanup (single test)",
1022                 subsys          => "block",
1023                 devpath         => "/block/sda",
1024                 exp_name        => "cdrom",
1025                 conf            => <<EOF
1026 KERNEL="sda", NAME="cdrom%e"
1027 EOF
1028         },
1029         {
1030                 desc            => "ignore remove event test",
1031                 subsys          => "block",
1032                 devpath         => "/block/sda",
1033                 exp_name        => "node",
1034                 exp_error       => "yes",
1035                 conf            => <<EOF
1036 BUS="scsi", KERNEL="sda", NAME{ignore_remove}="node"
1037 EOF
1038         },
1039         {
1040                 desc            => "ignore remove event test (with all partitions)",
1041                 subsys          => "block",
1042                 devpath         => "/block/sda",
1043                 exp_name        => "node14",
1044                 exp_error       => "yes",
1045                 option          => "clear",
1046                 conf            => <<EOF
1047 BUS="scsi", KERNEL="sda", NAME{ignore_remove, all_partitions}="node"
1048 EOF
1049         },
1050         {
1051                 desc            => "SUBSYSTEM match test",
1052                 subsys          => "block",
1053                 devpath         => "/block/sda",
1054                 exp_name        => "node",
1055                 conf            => <<EOF
1056 BUS="scsi", KERNEL="sda", NAME="should_not_match", SUBSYSTEM="vc"
1057 BUS="scsi", KERNEL="sda", NAME="node", SUBSYSTEM="block"
1058 BUS="scsi", KERNEL="sda", NAME="should_not_match2", SUBSYSTEM="vc"
1059 EOF
1060         },
1061         {
1062                 desc            => "DRIVER match test",
1063                 subsys          => "block",
1064                 devpath         => "/block/sda",
1065                 exp_name        => "node",
1066                 conf            => <<EOF
1067 BUS="scsi", KERNEL="sda", NAME="should_not_match", DRIVER="sd-wrong"
1068 BUS="scsi", KERNEL="sda", NAME="node", DRIVER="sd"
1069 EOF
1070         },
1071 );
1072
1073 # set env
1074 $ENV{UDEV_TEST} = "yes";
1075 $ENV{SYSFS_PATH} = $sysfs;
1076 $ENV{UDEV_CONFIG_FILE} = $main_conf;
1077 $ENV{UDEV_NO_DEVD} = "yes";
1078 $ENV{UDEV_NO_HOTPLUGD} = "yes";
1079
1080
1081 sub udev {
1082         my ($action, $subsys, $devpath, $config) = @_;
1083
1084         $ENV{DEVPATH} = $devpath;
1085
1086         # create temporary config
1087         open CONF, ">$conf_tmp" || die "unable to create config file: $conf_tmp";
1088         print CONF $$config;
1089         close CONF;
1090
1091         $ENV{ACTION} = $action;
1092         system("$udev_bin $subsys");
1093 }
1094
1095 my $error = 0;
1096
1097 sub permissions_test {
1098         my($config, $uid, $gid, $mode) = @_;
1099
1100         my $wrong = 0;
1101         $config->{exp_perms} =~ m/^(.*):(.*):(.*)$/;
1102         if ($1 ne "") {
1103                 if ($uid != $1) { $wrong = 1; };
1104         }
1105         if ($2 ne "") {
1106                 if ($gid != $2) { $wrong = 1; };
1107         }
1108         if ($3 ne "") {
1109                 if (($mode & 07777) != oct($3)) { $wrong = 1; };
1110         }
1111         if ($wrong == 0) {
1112                 print "permissions: ok    ";
1113         } else {
1114                 printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3);
1115                 printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777;
1116                 $error++;
1117         }
1118 }
1119
1120 sub major_minor_test {
1121         my($config, $rdev) = @_;
1122
1123         my $major = ($rdev >> 8) & 0xfff;
1124         my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00);
1125         my $wrong = 0;
1126
1127         $config->{exp_majorminor} =~ m/^(.*):(.*)$/;
1128         if ($1 ne "") {
1129                 if ($major != $1) { $wrong = 1; };
1130         }
1131         if ($2 ne "") {
1132                 if ($minor != $2) { $wrong = 1; };
1133         }
1134         if ($wrong == 0) {
1135                 print "major:minor: ok    ";
1136         } else {
1137                 printf "expected major:minor is: %i:%i\n", $1, $2;
1138                 printf "created major:minor is : %i:%i\n", $major, $minor;
1139                 print "major:minor: error    ";
1140                 $error++;
1141         }
1142 }
1143
1144 sub symlink_test {
1145         my ($config) = @_;
1146
1147         my $output = `ls -l $PWD/$udev_root$config->{exp_name}`;
1148
1149         if ($output =~ m/(.*)-> (.*)/) {
1150                 if ($2 eq $config->{exp_target}) {
1151                         print "symlink: ok    ";
1152                 } else {
1153                         print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n";
1154                         print "created symlink from: \'$config->{exp_name}\' to \'$2\'\n";
1155                         if ($config->{exp_error}) {
1156                                 print "as expected    ";
1157                         } else {
1158                                 $error++;
1159                         }
1160                 }
1161         } else {
1162                 print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n";
1163                 print "symlink: not created ";
1164                 if ($config->{exp_error}) {
1165                         print "as expected    ";
1166                 } else {
1167                         $error++;
1168                 }
1169         }
1170 }
1171
1172 sub run_test {
1173         my ($config, $number) = @_;
1174
1175         print "TEST $number: $config->{desc}\n";
1176
1177         if ($config->{exp_target}) {
1178                 print "device \'$config->{devpath}\' expecting symlink '$config->{exp_name}' to node \'$config->{exp_target}\'\n";
1179         } else {
1180                 print "device \'$config->{devpath}\' expecting node \'$config->{exp_name}\'\n";
1181         }
1182
1183
1184         udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf});
1185         if ((-e "$PWD/$udev_root$config->{exp_name}") ||
1186             (-l "$PWD/$udev_root$config->{exp_name}")) {
1187
1188                 my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
1189                     $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$config->{exp_name}");
1190
1191                 if (defined($config->{exp_perms})) {
1192                         permissions_test($config, $uid, $gid, $mode);
1193                 }
1194                 if (defined($config->{exp_majorminor})) {
1195                         major_minor_test($config, $rdev);
1196                 }
1197                 if (defined($config->{exp_target})) {
1198                         symlink_test($config);
1199                 }
1200                 print "add: ok    ";
1201         } else {
1202                 print "add: error ";
1203                 if ($config->{exp_error}) {
1204                         print "as expected    ";
1205                 } else {
1206                         print "\n\n";
1207                         system("tree $udev_root");
1208                         print "\n";
1209                         $error++;
1210                 }
1211         }
1212
1213         if (defined($config->{option}) && $config->{option} eq "keep") {
1214                 print "\n\n";
1215                 return;
1216         }
1217
1218         udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf});
1219         if ((-e "$PWD/$udev_root$config->{exp_name}") ||
1220             (-l "$PWD/$udev_root$config->{exp_name}")) {
1221                 print "remove: error ";
1222                 if ($config->{exp_error}) {
1223                         print "as expected\n\n";
1224                 } else {
1225                         print "\n\n";
1226                         system("tree $udev_root");
1227                         print "\n";
1228                         $error++;
1229                 }
1230         } else {
1231                 print "remove: ok\n\n";
1232         }
1233
1234         if (defined($config->{option}) && $config->{option} eq "clear") {
1235                 system("rm -rf $udev_db");
1236                 system("rm -rf $udev_root");
1237                 mkdir($udev_root) || die "unable to create udev_root: $udev_root\n";
1238         }
1239
1240 }
1241
1242 # only run if we have root permissions
1243 # due to mknod restrictions
1244 if (!($<==0)) {
1245         print "Must have root permissions to run properly.\n";
1246         exit;
1247 }
1248
1249 # prepare
1250 system("rm -rf $udev_root");
1251 mkdir($udev_root) || die "unable to create udev_root: $udev_root\n";
1252
1253 # create initial config file
1254 open CONF, ">$main_conf" || die "unable to create config file: $main_conf";
1255 print CONF "udev_root=\"$udev_root\"\n";
1256 print CONF "udev_db=\"$udev_db\"\n";
1257 print CONF "udev_rules=\"$conf_tmp\"\n";
1258 print CONF "default_mode=\"0660\"\n";
1259 print CONF "default_owner=\"root\"\n";
1260 print CONF "default_group=\"root\"\n";
1261 close CONF;
1262
1263 my $test_num = 1;
1264
1265 if ($ARGV[0]) {
1266         # only run one test
1267         $test_num = $ARGV[0];
1268
1269         if (defined($tests[$test_num-1]->{desc})) {
1270                 print "udev-test will run test number $test_num only:\n\n";
1271                 run_test($tests[$test_num-1], $test_num);
1272         } else {
1273                 print "test does not exist.\n";
1274         }
1275 } else {
1276         # test all
1277         print "\nudev-test will run ".($#tests + 1)." tests:\n\n";
1278
1279         foreach my $config (@tests) {
1280                 run_test($config, $test_num);
1281                 $test_num++;
1282         }
1283 }
1284
1285 print "$error errors occured\n\n";
1286
1287 # cleanup
1288 system("rm -rf $udev_db");
1289 system("rm -rf $udev_root");
1290 unlink($conf_tmp);
1291 unlink($main_conf);
1292