2003-11-23 16:47:28 +03:00
#!/usr/bin/perl
# udev-test
#
# Provides automated testing of the udev binary.
# The whole test is self contained in this file, except the matching sysfs tree.
# Simply extend the @tests array, to add a new test variant.
#
# Every test is driven by its own temporary config file.
# This program prepares the environment, creates the config and calls udev.
#
# udev reads the config, looks at the provided sysfs and
# first creates and then removes the device node.
# After creation and removal the result is checked against the
# expected value and the result is printed.
#
# happy testing,
# Kay Sievers <kay.sievers@vrfy.org>, 2003
use warnings ;
use strict ;
2003-11-24 16:44:01 +03:00
my $ PWD = $ ENV { PWD } ;
2003-11-23 16:47:28 +03:00
my $ sysfs = "sys/" ;
my $ udev_bin = "../udev" ;
my $ udev_root = "udev-root/" ; # !!! directory will be removed !!!
2003-11-25 10:45:38 +03:00
my $ udev_db = ".udev.tdb" ;
2003-11-23 16:47:28 +03:00
my $ perm = "udev.permissions" ;
2003-12-03 19:13:53 +03:00
my $ main_conf = "udev-test.conf" ;
my $ conf_tmp = "udev-test.rules" ;
2003-11-23 16:47:28 +03:00
my @ tests = (
{
desc = > "label test of scsi disc" ,
subsys = > "block" ,
devpath = > "block/sda" ,
expected = > "boot_disk" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "boot_disk%n"
2003-12-07 20:12:07 +03:00
REPLACE , KERNEL = "ttyUSB0" , NAME = "visor"
2003-11-23 16:47:28 +03:00
EOF
} ,
{
desc = > "label test of scsi partition" ,
subsys = > "block" ,
devpath = > "block/sda/sda1" ,
expected = > "boot_disk1" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "boot_disk%n"
2003-12-05 06:21:31 +03:00
EOF
} ,
{
desc = > "label test of pattern match" ,
subsys = > "block" ,
devpath = > "block/sda/sda1" ,
expected = > "boot_disk1" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "?IBM-ESXS" , NAME = "boot_disk%n-1"
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS?" , NAME = "boot_disk%n-2"
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ES??" , NAME = "boot_disk%n"
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXSS" , NAME = "boot_disk%n-3"
2003-12-23 09:32:06 +03:00
EOF
} ,
{
desc = > "label test of multiple sysfs files" ,
subsys = > "block" ,
devpath = > "block/sda/sda1" ,
expected = > "boot_disk1" ,
conf = > << EOF
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , SYSFS_model = "ST336605LW !#" , NAME = "boot_diskX%n"
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , SYSFS_model = "ST336605LW !#" , NAME = "boot_disk%n"
EOF
} ,
{
desc = > "label test of max sysfs files" ,
subsys = > "block" ,
devpath = > "block/sda/sda1" ,
expected = > "boot_disk1" ,
conf = > << EOF
LABEL , 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"
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , SYSFS_model = "ST336605LW !#" , SYSFS_scsi_level = "4" , SYSFS_rev = "B245" , SYSFS_type = "0" , NAME = "boot_disk%n"
2003-12-03 04:52:26 +03:00
EOF
} ,
{
2003-12-03 17:22:53 +03:00
desc = > "catch device by *" ,
2003-12-03 04:52:26 +03:00
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor/0" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB*" , NAME = "visor/%n"
2003-12-03 17:22:53 +03:00
EOF
} ,
{
desc = > "catch device by ?" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor/0" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB??*" , NAME = "visor/%n-1"
REPLACE , KERNEL = "ttyUSB??" , NAME = "visor/%n-2"
REPLACE , KERNEL = "ttyUSB?" , NAME = "visor/%n"
EOF
} ,
{
desc = > "catch device by character class" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor/0" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB[A-Z]*" , NAME = "visor/%n-1"
REPLACE , KERNEL = "ttyUSB?[0-9]" , NAME = "visor/%n-2"
REPLACE , KERNEL = "ttyUSB[0-9]*" , NAME = "visor/%n"
2003-11-23 16:47:28 +03:00
EOF
} ,
{
desc = > "replace kernel name" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB0" , NAME = "visor"
2003-12-18 05:28:05 +03:00
EOF
} ,
{
desc = > "Handle comment lines in config file (and replace kernel name)" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor" ,
conf = > << EOF
# this is a comment
REPLACE , KERNEL = "ttyUSB0" , NAME = "visor"
EOF
} ,
{
desc = > "Handle comment lines in config file with whitespace (and replace kernel name)" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor" ,
conf = > << EOF
# this is a comment with whitespace before the comment
REPLACE , KERNEL = "ttyUSB0" , NAME = "visor"
EOF
} ,
{
desc = > "Handle empty lines in config file (and replace kernel name)" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB0" , NAME = "visor"
2003-11-25 09:27:23 +03:00
EOF
} ,
{
desc = > "subdirectory handling" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "sub/direct/ory/visor" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB0" , NAME = "sub/direct/ory/visor"
2003-11-23 16:47:28 +03:00
EOF
} ,
{
desc = > "place on bus of scsi partition" ,
subsys = > "block" ,
devpath = > "block/sda/sda3" ,
expected = > "first_disk3" ,
conf = > << EOF
TOPOLOGY , BUS = "scsi" , PLACE = "0:0:0:0" , NAME = "first_disk%n"
EOF
} ,
{
desc = > "test NAME substitution chars" ,
subsys = > "block" ,
devpath = > "block/sda/sda3" ,
expected = > "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" ,
conf = > << EOF
TOPOLOGY , BUS = "scsi" , PLACE = "0:0:0:0" , NAME = "Major:%M:minor:%m:kernelnumber:%n:bus:%b"
EOF
} ,
{
2003-12-03 17:22:53 +03:00
desc = > "callout result substitution" ,
2003-11-23 16:47:28 +03:00
subsys = > "block" ,
devpath = > "block/sda/sda3" ,
expected = > "special-device-3" ,
conf = > << EOF
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n special-device" , ID = "-special-*" , NAME = "%c-1-%n"
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n special-device" , ID = "special--*" , NAME = "%c-2-%n"
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n special-device" , ID = "special-device-" , NAME = "%c-3-%n"
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n special-device" , ID = "special-devic" , NAME = "%c-4-%n"
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n special-device" , ID = "special-*" , NAME = "%c-%n"
2003-11-24 09:25:13 +03:00
EOF
} ,
{
2003-11-24 16:44:01 +03:00
desc = > "callout program substitution" ,
2003-11-24 09:25:13 +03:00
subsys = > "block" ,
devpath = > "block/sda/sda3" ,
expected = > "test-0:0:0:0" ,
conf = > << EOF
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n test-%b" , ID = "test-*" , NAME = "%c"
[PATCH] get part of callout return string
Try this patch if you like, to get special parts of the callout output.
This beast works now:
CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", ID="node *", NAME="%1c", SYMLINK="%2c %3c"
The callout returned string is separated by spaces and is
addressed by the "len" value of the 'c' format char.
Since we support symlinks, this my be useful for other uses of callout too.
introduce 'len number' for format chars
the first use is 'c'-the callout return to select a part of the output string like:
CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", ID="node *", NAME="%1c", SYMLINK="%2c %3c"
(note: first part is requested by len=1, len=0 will return the whole string)
add a test to udev-test.pl
2003-12-16 09:54:38 +03:00
EOF
} ,
{
desc = > "callout program substitution (numbered part of)" ,
subsys = > "block" ,
devpath = > "block/sda/sda3" ,
expected = > "link1" ,
conf = > << EOF
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n node link1 link2" , ID = "node *" , NAME = "%1c" , SYMLINK = "%2c %3c"
2003-12-25 10:56:54 +03:00
EOF
} ,
{
2003-12-25 11:05:28 +03:00
desc = > "invalid callout for device with no bus" ,
2003-12-25 10:56:54 +03:00
subsys = > "tty" ,
devpath = > "class/tty/console" ,
expected = > "TTY" ,
conf = > << EOF
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n foo" , ID = "foo" , NAME = "foo"
REPLACE , KERNEL = "console" , NAME = "TTY"
2003-12-25 11:05:28 +03:00
EOF
} ,
{
desc = > "valid callout for device with no bus" ,
subsys = > "tty" ,
devpath = > "class/tty/console" ,
expected = > "foo" ,
conf = > << EOF
CALLOUT , PROGRAM = "/bin/echo -n foo" , ID = "foo" , NAME = "foo"
2003-12-25 11:33:56 +03:00
REPLACE , KERNEL = "console" , NAME = "TTY"
EOF
} ,
{
desc = > "invalid label for device with no bus" ,
subsys = > "tty" ,
devpath = > "class/tty/console" ,
expected = > "TTY" ,
conf = > << EOF
LABEL , BUS = "foo" , SYSFS_dev = "5:1" , NAME = "foo"
REPLACE , KERNEL = "console" , NAME = "TTY"
EOF
} ,
{
desc = > "valid label for device with no bus" ,
subsys = > "tty" ,
devpath = > "class/tty/console" ,
expected = > "foo" ,
conf = > << EOF
LABEL , SYSFS_dev = "5:1" , NAME = "foo"
REPLACE , KERNEL = "console" , NAME = "TTY"
2003-11-25 10:45:38 +03:00
EOF
} ,
{
desc = > "devfs disk naming substitution" ,
subsys = > "block" ,
devpath = > "block/sda" ,
2003-12-11 09:12:30 +03:00
expected = > "lun0/disc" ,
2003-11-25 10:45:38 +03:00
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "lun0/%D"
2003-11-25 10:45:38 +03:00
EOF
} ,
{
desc = > "devfs disk naming substitution" ,
subsys = > "block" ,
devpath = > "block/sda/sda2" ,
expected = > "lun0/part2" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "lun0/%D"
2003-11-27 04:45:26 +03:00
EOF
} ,
{
desc = > "callout bus type" ,
subsys = > "block" ,
devpath = > "block/sda" ,
expected = > "scsi-0:0:0:0" ,
conf = > << EOF
CALLOUT , BUS = "usb" , PROGRAM = "/bin/echo -n usb-%b" , ID = "*" , NAME = "%c"
CALLOUT , BUS = "scsi" , PROGRAM = "/bin/echo -n scsi-%b" , ID = "*" , NAME = "%c"
CALLOUT , BUS = "foo" , PROGRAM = "/bin/echo -n foo-%b" , ID = "*" , NAME = "%c"
2003-12-07 20:12:07 +03:00
EOF
} ,
{
desc = > "symlink creation (same directory)" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "visor0" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB[0-9]*" , NAME = "ttyUSB%n" , SYMLINK = "visor%n"
EOF
} ,
{
desc = > "symlink creation (relative link back)" ,
subsys = > "block" ,
devpath = > "block/sda/sda2" ,
expected = > "1/2/a/b/symlink" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "1/2/node" , SYMLINK = "1/2/a/b/symlink"
2003-12-07 20:12:07 +03:00
EOF
} ,
{
desc = > "symlink creation (relative link forward)" ,
subsys = > "block" ,
devpath = > "block/sda/sda2" ,
expected = > "1/2/symlink" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "1/2/a/b/node" , SYMLINK = "1/2/symlink"
2003-12-07 20:12:07 +03:00
EOF
} ,
{
desc = > "symlink creation (relative link back and forward)" ,
subsys = > "block" ,
devpath = > "block/sda/sda2" ,
expected = > "1/2/c/d/symlink" ,
conf = > << EOF
2003-12-17 10:36:19 +03:00
LABEL , BUS = "scsi" , SYSFS_vendor = "IBM-ESXS" , NAME = "1/2/a/b/node" , SYMLINK = "1/2/c/d/symlink"
2003-12-10 11:47:00 +03:00
EOF
} ,
{
desc = > "multiple symlinks" ,
subsys = > "tty" ,
devpath = > "class/tty/ttyUSB0" ,
expected = > "second-0" ,
conf = > << EOF
REPLACE , KERNEL = "ttyUSB0" , NAME = "visor" , SYMLINK = "first-%n second-%n third-%n"
2003-11-23 16:47:28 +03:00
EOF
} ,
) ;
# set env
$ ENV { UDEV_TEST } = "yes" ;
$ ENV { SYSFS_PATH } = $ sysfs ;
2003-12-03 19:13:53 +03:00
$ ENV { UDEV_CONFIG_FILE } = $ main_conf ;
2003-11-23 16:47:28 +03:00
sub udev {
my ( $ action , $ subsys , $ devpath , $ config ) = @ _ ;
$ ENV { DEVPATH } = $ devpath ;
# create temporary config
open CONF , ">$conf_tmp" || die "unable to create config file: $conf_tmp" ;
print CONF $$ config ;
close CONF ;
$ ENV { ACTION } = $ action ;
system ( "$udev_bin $subsys" ) ;
}
# prepare
system ( "rm -rf $udev_root" ) ;
mkdir ( $ udev_root ) || die "unable to create udev_root: $udev_root\n" ;
# test
2003-11-24 08:17:34 +03:00
my $ error = 0 ;
2003-11-23 16:47:28 +03:00
print "\nudev-test will run " . ( $# tests + 1 ) . " tests:\n\n" ;
2003-12-03 19:13:53 +03:00
# create initial config file
open CONF , ">$main_conf" || die "unable to create config file: $main_conf" ;
print CONF "udev_root=\"$udev_root\"\n" ;
print CONF "udev_db=\"$udev_db\"\n" ;
print CONF "udev_rules=\"$conf_tmp\"\n" ;
print CONF "udev_permissions=\"$perm\"\n" ;
close CONF ;
2003-11-23 16:47:28 +03:00
foreach my $ config ( @ tests ) {
2003-12-23 10:30:51 +03:00
$ config - > { conf } =~ m/([A-Z]+)\s*,/ ;
2003-11-23 16:47:28 +03:00
my $ method = $ 1 ;
print "TEST: $config->{desc}\n" ;
print "method \'$method\' for \'$config->{devpath}\' expecting node \'$config->{expected}\'\n" ;
udev ( "add" , $ config - > { subsys } , $ config - > { devpath } , \ $ config - > { conf } ) ;
if ( - e "$PWD/$udev_root$config->{expected}" ) {
print "add: ok " ;
} else {
print "add: error\n" ;
system ( "tree $udev_root" ) ;
print "\n" ;
$ error + + ;
}
udev ( "remove" , $ config - > { subsys } , $ config - > { devpath } , \ $ config - > { conf } ) ;
2003-12-07 20:12:07 +03:00
if ( ( - e "$PWD/$udev_root$config->{expected}" ) ||
( - l "$PWD/$udev_root$config->{expected}" ) ) {
2003-11-23 16:47:28 +03:00
print "remove: error\n\n" ;
system ( "tree $udev_root" ) ;
$ error + + ;
} else {
print "remove: ok\n\n" ;
}
}
print "$error errors occured\n\n" ;
# cleanup
2003-11-25 10:45:38 +03:00
unlink ( $ udev_db ) ;
2003-11-23 16:47:28 +03:00
system ( "rm -rf $udev_root" ) ;
unlink ( $ conf_tmp ) ;
2003-12-03 19:13:53 +03:00
unlink ( $ main_conf ) ;
2003-11-23 16:47:28 +03:00