+ {
+ desc => "apply NAME only once",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "link",
+ exp_target => "ok",
+ rules => <<EOF
+KERNEL=="sda", NAME="ok"
+KERNEL=="sda", NAME="not-ok"
+KERNEL=="sda", SYMLINK+="link"
+EOF
+ },
+ {
+ desc => "test RUN key",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "testsymlink",
+ exp_target => "ok",
+ exp_rem_error => "yes",
+ option => "clean",
+ rules => <<EOF
+KERNEL=="sda", NAME="ok", RUN+="/bin/ln -s ok %r/testsymlink"
+KERNEL=="sda", NAME="not-ok"
+EOF
+ },
+ {
+ desc => "test RUN key and DEVNAME",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "testsymlink",
+ exp_target => "ok",
+ exp_rem_error => "yes",
+ option => "clean",
+ rules => <<EOF
+KERNEL=="sda", NAME="ok", RUN+="/bin/sh -c 'ln -s `basename \$\$DEVNAME` %r/testsymlink'"
+KERNEL=="sda", NAME="not-ok"
+EOF
+ },
+ {
+ desc => "test RUN key remove",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "testsymlink2",
+ exp_target => "ok2",
+ rules => <<EOF
+KERNEL=="sda", NAME="ok2", RUN+="/bin/ln -s ok2 %r/testsymlink2"
+KERNEL=="sda", ACTION=="remove", RUN+="/bin/rm -f %r/testsymlink2"
+KERNEL=="sda", NAME="not-ok2"
+EOF
+ },
+ {
+ desc => "final assignment",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "ok",
+ exp_perms => "root:nobody:0640",
+ rules => <<EOF
+KERNEL=="sda", GROUP:="nobody"
+KERNEL=="sda", GROUP="not-ok", MODE="0640", NAME="ok"
+EOF
+ },
+ {
+ desc => "final assignment",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "ok",
+ exp_perms => "root:nobody:0640",
+ rules => <<EOF
+KERNEL=="sda", GROUP:="nobody"
+SUBSYSTEM=="block", MODE:="640"
+KERNEL=="sda", GROUP="not-ok", MODE="0666", NAME="ok"
+EOF
+ },
+ {
+ desc => "env substitution",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "node-add-me",
+ rules => <<EOF
+KERNEL=="sda", MODE="0666", NAME="node-\$env{ACTION}-me"
+EOF
+ },
+ {
+ desc => "reset list to current value",
+ subsys => "tty",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "three",
+ not_exp_name => "two",
+ exp_target => "node",
+ rules => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="one"
+KERNEL=="ttyACM[0-9]*", SYMLINK+="two"
+KERNEL=="ttyACM[0-9]*", SYMLINK="three"
+KERNEL=="ttyACM[0-9]*", NAME="node"
+EOF
+ },
+ {
+ desc => "test empty NAME",
+ subsys => "tty",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "node",
+ not_exp_name => "wrong",
+ exp_add_error => "yes",
+ rules => <<EOF
+KERNEL=="ttyACM[0-9]*", NAME=""
+KERNEL=="ttyACM[0-9]*", NAME="wrong"
+EOF
+ },
+ {
+ desc => "test empty NAME 2",
+ subsys => "tty",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "right",
+ rules => <<EOF
+KERNEL=="ttyACM[0-9]*", NAME="right"
+KERNEL=="ttyACM[0-9]*", NAME=""
+KERNEL=="ttyACM[0-9]*", NAME="wrong"
+EOF
+ },
+ {
+ desc => "test multi matches",
+ subsys => "tty",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "right",
+ rules => <<EOF
+KERNEL=="ttyACM*|nothing", NAME="right"
+KERNEL=="ttyACM*", NAME="wrong"
+EOF
+ },
+ {
+ desc => "test multi matches 2",
+ subsys => "tty",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "right",
+ rules => <<EOF
+KERNEL=="dontknow*|*nothing", NAME="nomatch"
+KERNEL=="dontknow*|ttyACM*|nothing*", NAME="right"
+KERNEL=="ttyACM*", NAME="wrong"
+EOF
+ },
+ {
+ desc => "IMPORT parent test sequence 1/2 (keep)",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "parent",
+ option => "keep",
+ rules => <<EOF
+KERNEL=="sda", IMPORT="/bin/echo -e \'PARENT_KEY=parent_right\\nWRONG_PARENT_KEY=parent_wrong'"
+KERNEL=="sda", NAME="parent"
+EOF
+ },
+ {
+ desc => "IMPORT parent test sequence 2/2 (keep)",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+ exp_name => "parentenv-parent_right",
+ option => "clean",
+ rules => <<EOF
+KERNEL=="sda1", IMPORT{parent}="PARENT*", NAME="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}"
+EOF
+ },
+ {
+ desc => "GOTO test",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+ exp_name => "right",
+ rules => <<EOF
+KERNEL=="sda1", GOTO="TEST"
+KERNEL=="sda1", NAME="wrong"
+KERNEL=="sda1", NAME="", LABEL="NO"
+KERNEL=="sda1", NAME="right", LABEL="TEST"
+KERNEL=="sda1", NAME="wrong2"
+EOF
+ },
+ {
+ desc => "NAME compare test",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+ exp_name => "link",
+ exp_target => "node",
+ not_exp_name => "wronglink",
+ rules => <<EOF
+KERNEL=="sda1", NAME="node"
+KERNEL=="sda2", NAME="wrong"
+KERNEL=="sda1", NAME=="wrong*", SYMLINK+="wronglink"
+KERNEL=="sda1", NAME=="?*", SYMLINK+="link"
+KERNEL=="sda1", NAME=="node*", SYMLINK+="link2"
+EOF
+ },
+ {
+ desc => "NAME compare test 2",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+ exp_name => "link2",
+ exp_target => "sda1",
+ not_exp_name => "link",
+ rules => <<EOF
+KERNEL=="sda1", NAME=="?*", SYMLINK+="link"
+KERNEL=="sda1", NAME!="?*", SYMLINK+="link2"
+EOF
+ },
+ {
+ desc => "invalid key operation",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+ exp_name => "yes",
+ rules => <<EOF
+KERNEL="sda1", NAME="no"
+KERNEL=="sda1", NAME="yes"
+EOF
+ },
+ {
+ desc => "operator chars in attribute",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "yes",
+ rules => <<EOF
+KERNEL=="sda", ATTR{test:colon+plus}=="?*", NAME="yes"
+EOF
+ },
+ {
+ desc => "overlong comment line",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+ exp_name => "yes",
+ rules => <<EOF
+# 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+ # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+KERNEL="sda1", NAME=="no"
+KERNEL=="sda1", NAME="yes"
+EOF
+ },
+ {
+ desc => "magic subsys/kernel lookup",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "00:16:41:e2:8d:ff",
+ rules => <<EOF
+KERNEL=="sda", NAME="\$attr{[net/eth0]address}"
+EOF
+ },
+ {
+ desc => "TEST absolute path",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "there",
+ rules => <<EOF
+TEST=="/etc/hosts", NAME="there"
+NAME="notthere"
+EOF
+ },
+ {
+ desc => "TEST subsys/kernel lookup",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "yes",
+ rules => <<EOF
+KERNEL=="sda", TEST=="[net/eth0]", NAME="yes"
+EOF
+ },
+ {
+ desc => "TEST relative path",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "relative",
+ rules => <<EOF
+KERNEL=="sda", TEST=="size", NAME="relative"
+EOF
+ },
+ {
+ desc => "TEST wildcard substitution (find queue/nr_requests)",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "found-subdir",
+ rules => <<EOF
+KERNEL=="sda", TEST=="*/nr_requests", NAME="found-subdir"
+EOF
+ },
+ {
+ desc => "TEST MODE=0000",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "sda",
+ exp_perms => "0:0:0000",
+ rules => <<EOF
+KERNEL=="sda", MODE="0000"
+EOF
+ },
+ {
+ desc => "TEST PROGRAM feeds MODE",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "sda",
+ exp_perms => "0:0:0400",
+ rules => <<EOF
+KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+ },
+ {
+ desc => "TEST PROGRAM feeds MODE with overflow",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "sda",
+ exp_perms => "0:0:0400",
+ rules => <<EOF
+KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400letsdoabuffferoverflow0123456789012345789012345678901234567890", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+ },
+