summary: Ensure that the custom-device interface works.

details: |
    The custom-device interface allows a gadget snap to provide custom slots
    granting access to the devices it defines.

systems: [ubuntu-2*]

prepare: |
    # Add our interface to the gadget snap
    VERSION="$(tests.nested show version)"
    rm -rf pc-gadget
    snap download --basename=pc --channel="$VERSION/edge" pc
    unsquashfs -d pc-gadget pc.snap
    cat >> pc-gadget/meta/snap.yaml << EOF
    slots:
      v4l:
        interface: custom-device
        devices:
          - /dev/video[0-9]
        files:
          read:
            - /sys/bus/usb/devices
            - /sys/class/video4linux
            - /sys/kernel/debug/sleep_time
          write:
            - /proc/sys/vm/stat_interval
        udev-tagging:
          - kernel: video[0-9]
            subsystem: v4l
            environment:
              var1: foo
              var2: bar
            attributes:
              attr1: one
              attr2: two
    EOF
    snap pack pc-gadget/ --filename=pc-gadget-v4l.snap
    remote.push pc-gadget-v4l.snap
    remote.exec sudo snap install --dangerous pc-gadget-v4l.snap

    # create and install consumer snap
    snap pack devices-plug
    remote.push devices-plug_1.0_all.snap
    remote.exec sudo snap install --dangerous devices-plug_1.0_all.snap

execute: |
    echo "When the interface is connected"
    remote.exec sudo snap connect devices-plug:v4l pc:v4l

    echo "Verify that the udev rule has been generated"
    UDEV_RULE="$(remote.exec grep -v '^#' /etc/udev/rules.d/70-snap.devices-plug.rules)"

    # Since ENV and ATTR elements appear in random order, we first match the
    # rule in its entirety, but without specifying the exact values of ENV and
    # ATTR sub-rules:
    echo "$UDEV_RULE" | MATCH '^KERNEL=="video\[0-9\]", SUBSYSTEM=="v4l"(, (ENV|ATTR){\w+}=="\w+")+, TAG\+="snap_devices-plug_cmd"$'
    # Then we match them individually:
    echo "$UDEV_RULE" | MATCH 'ENV{var1}=="foo"'
    echo "$UDEV_RULE" | MATCH 'ENV{var2}=="bar"'
    echo "$UDEV_RULE" | MATCH 'ATTR{attr1}=="one"'
    echo "$UDEV_RULE" | MATCH 'ATTR{attr2}=="two"'

    echo "Verify that the snap can write to the writable paths"
    OLD_VALUE="$(remote.exec sudo devices-plug.cmd cat /proc/sys/vm/stat_interval)"
    # The double quotation is needed or our command will get split and the
    # shell redirection will not happen in the right session
    remote.exec sudo devices-plug.cmd sh -c "'echo 3 > /proc/sys/vm/stat_interval'"
    remote.exec sudo devices-plug.cmd cat /proc/sys/vm/stat_interval | MATCH "3"
    remote.exec sudo devices-plug.cmd sh -c "'echo $OLD_VALUE > /proc/sys/vm/stat_interval'"

    echo "And can read the readable paths"
    remote.exec sudo devices-plug.cmd cat /sys/kernel/debug/sleep_time | MATCH "time"
