chiark / gitweb /
f442b162ec31cf5ff314480b269284ec5ff30e13
[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", PLACE="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", PLACE="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", PLACE="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 to empty name",
783                 subsys          => "block",
784                 devpath         => "/block/sda",
785                 exp_name        => "symlink",
786                 exp_target      => "",
787                 exp_add_error   => "yes",
788                 conf            => <<EOF
789 BUS="scsi", KERNEL="sda", NAME="", SYMLINK="symlink"
790 EOF
791         },
792         {
793                 desc            => "symlink and name empty",
794                 subsys          => "block",
795                 devpath         => "/block/sda",
796                 exp_name        => "",
797                 exp_target      => "",
798                 exp_add_error   => "yes",
799                 exp_rem_error   => "yes",
800                 conf            => <<EOF
801 BUS="scsi", KERNEL="sda", NAME="", SYMLINK=""
802 EOF
803         },
804         {
805                 desc            => "symlink node to itself",
806                 subsys          => "tty",
807                 devpath         => "/class/tty/tty0",
808                 exp_name        => "link",
809                 exp_target      => "link",
810                 exp_rem_error   => "yes",
811                 option          => "clear",
812                 conf            => <<EOF
813 KERNEL="tty0", NAME="link", SYMLINK="link"
814 EOF
815         },
816         {
817                 desc            => "symlink %n substitution",
818                 subsys          => "tty",
819                 devpath         => "/class/tty/ttyUSB0",
820                 exp_name        => "symlink0",
821                 exp_target      => "ttyUSB0",
822                 conf            => <<EOF
823 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink%n"
824 EOF
825         },
826         {
827                 desc            => "symlink %k substitution",
828                 subsys          => "tty",
829                 devpath         => "/class/tty/ttyUSB0",
830                 exp_name        => "symlink-ttyUSB0",
831                 exp_target      => "ttyUSB0",
832                 conf            => <<EOF
833 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink-%k"
834 EOF
835         },
836         {
837                 desc            => "symlink %M:%m substitution",
838                 subsys          => "tty",
839                 devpath         => "/class/tty/ttyUSB0",
840                 exp_name        => "major-188:0",
841                 exp_target      => "ttyUSB0",
842                 conf            => <<EOF
843 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="major-%M:%m"
844 EOF
845         },
846         {
847                 desc            => "symlink %b substitution",
848                 subsys          => "block",
849                 devpath         => "/block/sda",
850                 exp_name        => "symlink-0:0:0:0",
851                 exp_target      => "node",
852                 conf            => <<EOF
853 BUS="scsi", KERNEL="sda", NAME="node", SYMLINK="symlink-%b"
854 EOF
855         },
856         {
857                 desc            => "symlink %c substitution",
858                 subsys          => "tty",
859                 devpath         => "/class/tty/ttyUSB0",
860                 exp_name        => "test",
861                 exp_target      => "ttyUSB0",
862                 conf            => <<EOF
863 KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo test" NAME="ttyUSB%n", SYMLINK="%c"
864 EOF
865         },
866         {
867                 desc            => "symlink %c{N} substitution",
868                 subsys          => "tty",
869                 devpath         => "/class/tty/ttyUSB0",
870                 exp_name        => "test",
871                 exp_target      => "ttyUSB0",
872                 conf            => <<EOF
873 KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2}"
874 EOF
875         },
876         {
877                 desc            => "symlink %c{N+} substitution",
878                 subsys          => "tty",
879                 devpath         => "/class/tty/ttyUSB0",
880                 exp_name        => "this",
881                 exp_target      => "ttyUSB0",
882                 conf            => <<EOF
883 KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2+}"
884 EOF
885         },
886         {
887                 desc            => "symlink only rule with %c{N+}",
888                 subsys          => "block",
889                 devpath         => "/block/sda",
890                 exp_name        => "test",
891                 exp_target      => "link",
892                 conf            => <<EOF
893 BUS="scsi", KERNEL="sda", PROGRAM="/bin/echo link test this" SYMLINK="%c{2+}"
894 BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0"
895 EOF
896         },
897         {
898                 desc            => "symlink %s{filename} substitution",
899                 subsys          => "tty",
900                 devpath         => "/class/tty/ttyUSB0",
901                 exp_name        => "188:0",
902                 exp_target      => "ttyUSB0",
903                 conf            => <<EOF
904 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%s{dev}"
905 EOF
906         },
907         {
908                 desc            => "symlink %Ns{filename} substitution",
909                 subsys          => "tty",
910                 devpath         => "/class/tty/ttyUSB0",
911                 exp_name        => "188",
912                 exp_target      => "ttyUSB0",
913                 conf            => <<EOF
914 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%3s{dev}"
915 EOF
916         },
917         {
918                 desc            => "symlink with '%' in name",
919                 subsys          => "tty",
920                 devpath         => "/class/tty/ttyUSB0",
921                 exp_name        => "percent%sign",
922                 exp_target      => "ttyUSB0",
923                 conf            => <<EOF
924 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="percent%%sign"
925 EOF
926         },
927         {
928                 desc            => "symlink with '%' in name",
929                 subsys          => "tty",
930                 devpath         => "/class/tty/ttyUSB0",
931                 exp_name        => "%ttyUSB0_name",
932                 exp_target      => "ttyUSB0",
933                 conf            => <<EOF
934 KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%%%k_name"
935 EOF
936         },
937         {
938                 desc            => "program result substitution (numbered part of)",
939                 subsys          => "block",
940                 devpath         => "/block/sda/sda3",
941                 exp_name        => "link1",
942                 exp_target      => "node",
943                 conf            => <<EOF
944 BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", RESULT="node *", NAME="%c{1}", SYMLINK="%c{2} %c{3}"
945 EOF
946         },
947         {
948                 desc            => "program result substitution (numbered part of+)",
949                 subsys          => "block",
950                 devpath         => "/block/sda/sda3",
951                 exp_name        => "link4",
952                 exp_target      => "node",
953                 conf            => <<EOF
954 BUS="scsi", PROGRAM="/bin/echo -n node link1 link2 link3 link4", RESULT="node *", NAME="%c{1}", SYMLINK="%c{2+}"
955 EOF
956         },
957         {
958                 desc            => "enumeration char test (single test)",
959                 subsys          => "block",
960                 devpath         => "/block/sda",
961                 exp_name        => "cdrom",
962                 conf            => <<EOF
963 KERNEL="sda", NAME="cdrom%e"
964 EOF
965         },
966         {
967                 desc            => "enumeration char test sequence 1/5 (keep)",
968                 subsys          => "block",
969                 devpath         => "/block/sda",
970                 exp_name        => "cdrom",
971                 option          => "keep",
972                 conf            => <<EOF
973 KERNEL="sda", NAME="cdrom%e"
974 EOF
975         },
976         {
977                 desc            => "enumeration char test sequence 2/5 (keep)",
978                 subsys          => "block",
979                 devpath         => "/block/sda/sda1",
980                 exp_name        => "enum",
981                 option          => "keep",
982                 conf            => <<EOF
983 KERNEL="sda1", NAME="enum%e"
984 EOF
985         },
986         {
987                 desc            => "enumeration char test sequence 3/5 (keep)",
988                 subsys          => "block",
989                 devpath         => "/block/sda/sda2",
990                 exp_name        => "cdrom1",
991                 option          => "keep",
992                 conf            => <<EOF
993 KERNEL="sda2", NAME="cdrom%e"
994 EOF
995         },
996         {
997                 desc            => "enumeration char test sequence 4/5 (keep)",
998                 subsys          => "block",
999                 devpath         => "/block/sda/sda3",
1000                 exp_name        => "enum1",
1001                 option          => "keep",
1002                 conf            => <<EOF
1003 KERNEL="sda3", NAME="enum%e"
1004 EOF
1005         },
1006         {
1007                 desc            => "enumeration char test sequence 5/5 (clean)",
1008                 subsys          => "block",
1009                 devpath         => "/block/sda/sda4",
1010                 exp_name        => "cdrom2",
1011                 option          => "clear",
1012                 conf            => <<EOF
1013 KERNEL="sda4", NAME="cdrom%e"
1014 EOF
1015         },
1016         {
1017                 desc            => "enumeration char test after cleanup (single test)",
1018                 subsys          => "block",
1019                 devpath         => "/block/sda",
1020                 exp_name        => "cdrom",
1021                 conf            => <<EOF
1022 KERNEL="sda", NAME="cdrom%e"
1023 EOF
1024         },
1025         {
1026                 desc            => "ignore rule test",
1027                 subsys          => "block",
1028                 devpath         => "/block/sda",
1029                 exp_name        => "node",
1030                 exp_add_error   => "yes",
1031                 conf            => <<EOF
1032 BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore"
1033 EOF
1034         },
1035         {
1036                 desc            => "all_partitions, option-only rule",
1037                 subsys          => "block",
1038                 devpath         => "/block/sda",
1039                 exp_name        => "node6",
1040                 conf            => <<EOF
1041 SUBSYSTEM="block", OPTIONS="all_partitions"
1042 BUS="scsi", KERNEL="sda", NAME="node"
1043 EOF
1044         },
1045         {
1046                 desc            => "all_partitions, option-only rule (fail on partition)",
1047                 subsys          => "block",
1048                 devpath         => "/block/sda/sda1",
1049                 exp_name        => "node6",
1050                 exp_add_error   => "yes",
1051                 conf            => <<EOF
1052 SUBSYSTEM="block", OPTIONS="all_partitions"
1053 BUS="scsi", KERNEL="sda", NAME="node"
1054 EOF
1055         },
1056         {
1057                 desc            => "ignore remove event test",
1058                 subsys          => "block",
1059                 devpath         => "/block/sda",
1060                 exp_name        => "node",
1061                 exp_rem_error   => "yes",
1062                 conf            => <<EOF
1063 BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore_remove"
1064 EOF
1065         },
1066         {
1067                 desc            => "ignore remove event test (with all partitions)",
1068                 subsys          => "block",
1069                 devpath         => "/block/sda",
1070                 exp_name        => "node14",
1071                 exp_rem_error   => "yes",
1072                 option          => "clear",
1073                 conf            => <<EOF
1074 BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore_remove, all_partitions"
1075 EOF
1076         },
1077         {
1078                 desc            => "SUBSYSTEM match test",
1079                 subsys          => "block",
1080                 devpath         => "/block/sda",
1081                 exp_name        => "node",
1082                 conf            => <<EOF
1083 BUS="scsi", KERNEL="sda", NAME="should_not_match", SUBSYSTEM="vc"
1084 BUS="scsi", KERNEL="sda", NAME="node", SUBSYSTEM="block"
1085 BUS="scsi", KERNEL="sda", NAME="should_not_match2", SUBSYSTEM="vc"
1086 EOF
1087         },
1088         {
1089                 desc            => "DRIVER match test",
1090                 subsys          => "block",
1091                 devpath         => "/block/sda",
1092                 exp_name        => "node",
1093                 conf            => <<EOF
1094 BUS="scsi", KERNEL="sda", NAME="should_not_match", DRIVER="sd-wrong"
1095 BUS="scsi", KERNEL="sda", NAME="node", DRIVER="sd"
1096 EOF
1097         },
1098         {
1099                 desc            => "temporary node creation test",
1100                 subsys          => "block",
1101                 devpath         => "/block/sda",
1102                 exp_name        => "node",
1103                 conf            => <<EOF
1104 BUS="scsi", KERNEL="sda", PROGRAM="/usr/bin/test -b %N" NAME="node"
1105 EOF
1106         },
1107         {
1108                 desc            => "devpath substitution test",
1109                 subsys          => "block",
1110                 devpath         => "/block/sda",
1111                 exp_name        => "sda",
1112                 conf            => <<EOF
1113 BUS="scsi", KERNEL="sda", PROGRAM="/bin/echo %p", RESULT="/block/sda" NAME="%k"
1114 EOF
1115         },
1116         {
1117                 desc            => "parent node name substitution test sequence 1/2 (keep)",
1118                 subsys          => "block",
1119                 devpath         => "/block/sda",
1120                 exp_name        => "main_device",
1121                 option          => "keep",
1122                 conf            => <<EOF
1123 BUS="scsi", KERNEL="sda", NAME="main_device"
1124 EOF
1125         },
1126         {
1127                 desc            => "parent node name substitution test sequence 2/2 (clean)",
1128                 subsys          => "block",
1129                 devpath         => "/block/sda/sda1",
1130                 exp_name        => "main_device-part-1",
1131                 option          => "clean",
1132                 conf            => <<EOF
1133 BUS="scsi", KERNEL="sda1", NAME="%P-part-1"
1134 EOF
1135         },
1136         {
1137                 desc            => "udev_root substitution",
1138                 subsys          => "block",
1139                 devpath         => "/block/sda/sda1",
1140                 exp_name        => "start-udev-root-end",
1141                 option          => "clean",
1142                 conf            => <<EOF
1143 BUS="scsi", KERNEL="sda1", NAME="start-%r-end"
1144 EOF
1145         },
1146 );
1147
1148 # set env
1149 $ENV{UDEV_TEST} = "yes";
1150 $ENV{SYSFS_PATH} = $sysfs;
1151 $ENV{UDEV_CONFIG_FILE} = $main_conf;
1152 $ENV{UDEV_NO_DEVD} = "yes";
1153 $ENV{UDEV_NO_HOTPLUGD} = "yes";
1154
1155
1156 sub udev {
1157         my ($action, $subsys, $devpath, $config) = @_;
1158
1159         $ENV{DEVPATH} = $devpath;
1160
1161         # create temporary config
1162         open CONF, ">$conf_tmp" || die "unable to create config file: $conf_tmp";
1163         print CONF $$config;
1164         close CONF;
1165
1166         $ENV{ACTION} = $action;
1167         system("$udev_bin $subsys");
1168 }
1169
1170 my $error = 0;
1171
1172 sub permissions_test {
1173         my($config, $uid, $gid, $mode) = @_;
1174
1175         my $wrong = 0;
1176         $config->{exp_perms} =~ m/^(.*):(.*):(.*)$/;
1177         if ($1 ne "") {
1178                 if ($uid != $1) { $wrong = 1; };
1179         }
1180         if ($2 ne "") {
1181                 if ($gid != $2) { $wrong = 1; };
1182         }
1183         if ($3 ne "") {
1184                 if (($mode & 07777) != oct($3)) { $wrong = 1; };
1185         }
1186         if ($wrong == 0) {
1187                 print "permissions: ok    ";
1188         } else {
1189                 printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3);
1190                 printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777;
1191                 $error++;
1192         }
1193 }
1194
1195 sub major_minor_test {
1196         my($config, $rdev) = @_;
1197
1198         my $major = ($rdev >> 8) & 0xfff;
1199         my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00);
1200         my $wrong = 0;
1201
1202         $config->{exp_majorminor} =~ m/^(.*):(.*)$/;
1203         if ($1 ne "") {
1204                 if ($major != $1) { $wrong = 1; };
1205         }
1206         if ($2 ne "") {
1207                 if ($minor != $2) { $wrong = 1; };
1208         }
1209         if ($wrong == 0) {
1210                 print "major:minor: ok    ";
1211         } else {
1212                 printf "expected major:minor is: %i:%i\n", $1, $2;
1213                 printf "created major:minor is : %i:%i\n", $major, $minor;
1214                 print "major:minor: error    ";
1215                 $error++;
1216         }
1217 }
1218
1219 sub symlink_test {
1220         my ($config) = @_;
1221
1222         my $output = `ls -l $PWD/$udev_root$config->{exp_name}`;
1223
1224         if ($output =~ m/(.*)-> (.*)/) {
1225                 if ($2 eq $config->{exp_target}) {
1226                         print "symlink: ok    ";
1227                 } else {
1228                         print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n";
1229                         print "created symlink from: \'$config->{exp_name}\' to \'$2\'\n";
1230                         if ($config->{exp_add_error}) {
1231                                 print "as expected    ";
1232                         } else {
1233                                 $error++;
1234                         }
1235                 }
1236         } else {
1237                 print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n";
1238                 print "symlink: not created ";
1239                 if ($config->{exp_add_error}) {
1240                         print "as expected    ";
1241                 } else {
1242                         $error++;
1243                 }
1244         }
1245 }
1246
1247 sub run_test {
1248         my ($config, $number) = @_;
1249
1250         print "TEST $number: $config->{desc}\n";
1251
1252         if ($config->{exp_target}) {
1253                 print "device \'$config->{devpath}\' expecting symlink '$config->{exp_name}' to node \'$config->{exp_target}\'\n";
1254         } else {
1255                 print "device \'$config->{devpath}\' expecting node \'$config->{exp_name}\'\n";
1256         }
1257
1258
1259         udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf});
1260         if ((-e "$PWD/$udev_root$config->{exp_name}") ||
1261             (-l "$PWD/$udev_root$config->{exp_name}")) {
1262
1263                 my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
1264                     $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$config->{exp_name}");
1265
1266                 if (defined($config->{exp_perms})) {
1267                         permissions_test($config, $uid, $gid, $mode);
1268                 }
1269                 if (defined($config->{exp_majorminor})) {
1270                         major_minor_test($config, $rdev);
1271                 }
1272                 if (defined($config->{exp_target})) {
1273                         symlink_test($config);
1274                 }
1275                 print "add: ok    ";
1276         } else {
1277                 print "add: error ";
1278                 if ($config->{exp_add_error}) {
1279                         print "as expected    ";
1280                 } else {
1281                         print "\n\n";
1282                         system("tree $udev_root");
1283                         print "\n";
1284                         $error++;
1285                 }
1286         }
1287
1288         if (defined($config->{option}) && $config->{option} eq "keep") {
1289                 print "\n\n";
1290                 return;
1291         }
1292
1293         udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf});
1294         if ((-e "$PWD/$udev_root$config->{exp_name}") ||
1295             (-l "$PWD/$udev_root$config->{exp_name}")) {
1296                 print "remove: error ";
1297                 if ($config->{exp_rem_error}) {
1298                         print "as expected\n\n";
1299                 } else {
1300                         print "\n\n";
1301                         system("tree $udev_root");
1302                         print "\n";
1303                         $error++;
1304                 }
1305         } else {
1306                 print "remove: ok\n\n";
1307         }
1308
1309         if (defined($config->{option}) && $config->{option} eq "clear") {
1310                 system("rm -rf $udev_db");
1311                 system("rm -rf $udev_root");
1312                 mkdir($udev_root) || die "unable to create udev_root: $udev_root\n";
1313         }
1314
1315 }
1316
1317 # only run if we have root permissions
1318 # due to mknod restrictions
1319 if (!($<==0)) {
1320         print "Must have root permissions to run properly.\n";
1321         exit;
1322 }
1323
1324 # prepare
1325 system("rm -rf $udev_root");
1326 mkdir($udev_root) || die "unable to create udev_root: $udev_root\n";
1327
1328 # create initial config file
1329 open CONF, ">$main_conf" || die "unable to create config file: $main_conf";
1330 print CONF "udev_root=\"$udev_root\"\n";
1331 print CONF "udev_db=\"$udev_db\"\n";
1332 print CONF "udev_rules=\"$conf_tmp\"\n";
1333 close CONF;
1334
1335 my $test_num = 1;
1336
1337 if ($ARGV[0]) {
1338         # only run one test
1339         $test_num = $ARGV[0];
1340
1341         if (defined($tests[$test_num-1]->{desc})) {
1342                 print "udev-test will run test number $test_num only:\n\n";
1343                 run_test($tests[$test_num-1], $test_num);
1344         } else {
1345                 print "test does not exist.\n";
1346         }
1347 } else {
1348         # test all
1349         print "\nudev-test will run ".($#tests + 1)." tests:\n\n";
1350
1351         foreach my $config (@tests) {
1352                 run_test($config, $test_num);
1353                 $test_num++;
1354         }
1355 }
1356
1357 print "$error errors occured\n\n";
1358
1359 # cleanup
1360 system("rm -rf $udev_db");
1361 system("rm -rf $udev_root");
1362 unlink($conf_tmp);
1363 unlink($main_conf);
1364