+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:tty:0640",
+ rules => <<EOF
+KERNEL=="sda", GROUP:="tty"
+KERNEL=="sda", GROUP="not-ok", MODE="0640", NAME="ok"
+EOF
+ },
+ {
+ desc => "final assignment 2",
+ 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:tty:0640",
+ rules => <<EOF
+KERNEL=="sda", GROUP:="tty"
+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 => "<none>",
+ not_exp_name => "wrong",
+ exp_add_error => "yes",
+ rules => <<EOF
+KERNEL=="ttyACM[0-9]*", NAME="wrong"
+KERNEL=="ttyACM[0-9]*", NAME=""
+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=""
+KERNEL=="ttyACM[0-9]*", NAME="wrong"
+KERNEL=="ttyACM[0-9]*", NAME="right"
+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*", NAME="before"
+KERNEL=="ttyACM*|nothing", NAME="right"
+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=="ttyACM*", NAME="before"
+KERNEL=="dontknow*|ttyACM*|nothing*", NAME="right"
+EOF
+ },
+ {
+ desc => "test multi matches 3",
+ 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|ttyACM0a|nothing|attyACM0", NAME="wrong1"
+KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", NAME="wrong2"
+KERNEL=="dontknow|ttyACM0|nothing", NAME="right"
+EOF
+ },
+ {
+ desc => "test multi matches 4",
+ 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|ttyACM0a|nothing|attyACM0", NAME="wrong1"
+KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", NAME="wrong2"
+KERNEL=="all|dontknow|ttyACM0", NAME="right"
+KERNEL=="ttyACM0a|nothing", NAME="wrong3"
+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", GOTO="BAD"
+KERNEL=="sda1", NAME="", LABEL="NO"
+KERNEL=="sda1", NAME="right", LABEL="TEST"
+KERNEL=="sda1", LABEL="BAD"
+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
+ # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+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"
+TEST!="/etc/hosts", NAME="notthere"
+EOF
+ },
+ {
+ desc => "TEST invalid NAME= only (skip invalid rule)",
+ 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
+SUBSYSTEM=="block", NAME="yes"
+NAME="no"
+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", MODE="666"
+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:0660",
+ rules => <<EOF
+KERNEL=="sda", MODE="440"
+KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400letsdoabuffferoverflow0123456789012345789012345678901234567890", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+ },
+ {
+ desc => "magic [subsys/sysname] attribute substitution",
+ subsys => "block",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "sda-8741C4G-end",
+ exp_perms => "0:0:0660",
+ rules => <<EOF
+KERNEL=="sda", PROGRAM="/bin/true create-envp"
+KERNEL=="sda", ENV{TESTENV}="change-envp"
+KERNEL=="sda", NAME="%k-%s{[dmi/id]product_name}-end", RUN+="socket:@/org/kernel/udev/monitor"