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