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