File: task.yaml

package info (click to toggle)
snapd 2.71-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 79,536 kB
  • sloc: ansic: 16,114; sh: 16,105; python: 9,941; makefile: 1,890; exp: 190; awk: 40; xml: 22
file content (191 lines) | stat: -rw-r--r-- 8,011 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
summary: Create ubuntu classic image, install snapd and test hotplug feature

details: |
    Snapd contains a little-used subsystem for reacting to dynamic device
    reconfiguration events, and in response, maintains a set of system-provided
    slots for certain snapd interfaces.

    One of the first interfaces to support this feature was the serial-port
    interface. Using this, snapd was able to detect serial ports that were not declared
    statically in the gadget snap, but instead were enumerated on startup or
    discovered dynamically when attached to the system over the USB bus.

    Simulating and testing this sort of interaction requires a nested virtual machine, where
    qemu can be scripted to dynamically attach devices to the running virtual
    machine.

prepare: |
    echo "Install snapd.deb in the nested vm"
    remote.push "${GOHOME}"/snapd_*.deb
    remote.exec "sudo apt update"
    remote.exec "sudo apt install -y ./snapd_*.deb"
    
    echo "Install linux-modules-extra package as it provides ftdi_sio and usbserial kernel modules"
    #shellcheck disable=SC2016
    remote.exec 'DEBIAN_FRONTEND=noninteractive sudo -E apt install -y "linux-modules-extra-$(uname -r)"'

    snap pack "$TESTSLIB"/snaps/serial-port-hotplug
    remote.push serial-port-hotplug_1.0_all.snap
    echo "Add test user to dialout group required for ttyUSB* devices"
    remote.exec "sudo usermod -a -G dialout user1"

restore: |
    rm -f /tmp/serialport{0,1}

debug: |
    remote.exec "snap connections --all" || true
    remote.exec "snap list" || true
    remote.exec "dmesg" || true
    remote.exec 'sudo cat /var/lib/snapd/state.json' | gojq -r ".data[\"hotplug-slots\"]" || true
    remote.exec 'lsmod' || true

execute: |
    #shellcheck source=tests/lib/hotplug.sh
    . "$TESTSLIB/hotplug.sh"
    #shellcheck source=tests/lib/nested.sh
    . "$TESTSLIB/nested.sh"
    
    if remote.exec "udevadm info -e" | MATCH "ID_MODEL=QEMU_USB_SERIAL"; then
        echo "USB serial already registered, exiting..."
        exit 1
    fi

    remote.exec "sudo snap install hello-world"

    echo "Enabling hotplug"
    remote.exec "sudo snap set core experimental.hotplug=true"

    echo "Plugging the device"
    hotplug_add_dev1

    # precondition checks to make sure qemu setup is correct
    remote.exec "retry --wait 1 -n 5 sh -c 'udevadm info -e | MATCH ID_MODEL=QEMU_USB_SERIAL'"

    remote.exec "ls /dev/tty*" | MATCH "ttyUSB0"

    echo "Checking that qemuusbserial hotplug slot is present"
    check_slot_present qemuusbserial
    check_slot_not_gone qemuusbserial
    check_slot_device_path qemuusbserial "/dev/ttyUSB0"

    echo "Unplugging the device with no connections on the slot"
    hotplug_del_dev1

    # precondition check to make sure qemu event was triggered correctly
    remote.exec "retry --wait 1 -n 5 sh -c 'udevadm info -e | NOMATCH ID_MODEL=QEMU_USB_SERIAL'"
    if remote.exec "udevadm info -e" | MATCH "ID_MODEL=QEMU_USB_SERIAL"; then
        echo "USB serial should not be registered anymore, exiting..."
        exit 1
    fi

    echo "Checking that hotplug slot is no longer present"
    check_slot_not_present qemuusbserial
    check_slot_not_present_in_state qemuusbserial

    echo "Plugging the device back"
    hotplug_add_dev1

    echo "Checking that qemuusbserial hotplug slot is present again"
    check_slot_present qemuusbserial

    echo "Installing test snap with serial port plug"
    remote.exec "sudo snap install --dangerous serial-port-hotplug_1.0_all.snap"

    echo "Connecting hotplug slot of the first device"
    remote.exec "sudo snap connect serial-port-hotplug:serial-port :qemuusbserial"
    check_slot_connected qemuusbserial

    echo "Verifying serial-port permissions of the snap"
    verify_apparmor_profile "/dev/ttyUSB0"
    remote.exec "/snap/bin/serial-port-hotplug.consumer write-1" | MATCH "Access to /dev/ttyUSB0 ok"
    remote.exec "/snap/bin/serial-port-hotplug.consumer write-2" | MATCH "Access to /dev/ttyUSB1 failed"
    MATCH "write-1 on /dev/ttyUSB0" < /tmp/serialport1

    echo "Unplugging the device"
    hotplug_del_dev1

    echo "Checking that qemuusbserial hotplug slot is no longer present, but is remembered"
    check_slot_not_present qemuusbserial
    check_slot_gone qemuusbserial

    echo "Plugging device back, checking that the slot and connection are restored"
    hotplug_add_dev1
    check_slot_connected qemuusbserial
    check_slot_not_gone qemuusbserial

    echo "Unplugging the device again"
    hotplug_del_dev1

    echo "Checking that qemuusbserial hotplug slot is not present, but is still remembered"
    check_slot_not_present qemuusbserial
    check_slot_gone qemuusbserial

    echo "Plugging second device creates a slot with new name and it's expected on /dev/ttyUSB0"
    hotplug_add_dev2
    check_slot_present qemuusbserial-1
    check_slot_not_gone qemuusbserial-1
    check_slot_device_path qemuusbserial-1 "/dev/ttyUSB0"

    echo "Plugging first device back while second device is present, checking that connection is restored"
    hotplug_add_dev1
    check_slot_connected qemuusbserial
    check_slot_not_gone qemuusbserial

    echo "Verifying serial-port permissions of the snap, the first device is now expected on ttyUSB1"
    check_slot_device_path qemuusbserial "/dev/ttyUSB1"
    verify_apparmor_profile "/dev/ttyUSB1"
    remote.exec "/snap/bin/serial-port-hotplug.consumer write-3" | MATCH "Access to /dev/ttyUSB0 failed"
    remote.exec "/snap/bin/serial-port-hotplug.consumer write-4" | MATCH "Access to /dev/ttyUSB1 ok"
    MATCH "write-3 on /dev/ttyUSB1" < /tmp/serialport1

    echo "Restarting snapd should restore both hotplug slots since devices are still present"
    remote.exec "sudo systemctl stop snapd.service snapd.socket"
    remote.exec "sudo systemctl start snapd.service snapd.socket"
    check_slot_connected qemuusbserial
    check_slot_not_gone qemuusbserial
    check_slot_present qemuusbserial-1
    remote.exec "/snap/bin/serial-port-hotplug.consumer write-5" | MATCH "Access to /dev/ttyUSB1 ok"
    MATCH "write-5 on /dev/ttyUSB1" < /tmp/serialport1

    echo "Unplugging first device while snapd is stopped and then starting snapd remembers the slot internally due to connection"
    remote.exec "sudo systemctl stop snapd.service snapd.socket"
    hotplug_del_dev1
    remote.exec "sudo systemctl start snapd.service snapd.socket"
    check_slot_not_present qemuusbserial
    check_slot_gone qemuusbserial

    echo "Plugging first device back restores the slot and connection"
    hotplug_add_dev1
    check_slot_connected qemuusbserial
    check_slot_not_gone qemuusbserial

    echo "Disconnecting first slot and then unplugging the device removes the slot completely"
    # manual snap disconnect doesn't implement retry and errors out if there are conflicting changes, so wait for hotplug changes to complete
    wait_for_all_changes
    remote.exec "sudo snap disconnect serial-port-hotplug:serial-port :qemuusbserial"
    check_slot_present qemuusbserial
    hotplug_del_dev1
    check_slot_not_present qemuusbserial
    check_slot_not_present_in_state qemuusbserial

    echo "Unplugging second device removes the slot completely"
    hotplug_del_dev2
    check_slot_not_present qemuusbserial-1
    check_slot_not_present_in_state qemuusbserial-1

    echo "Plugging device back creates the slot again"
    hotplug_add_dev1
    check_slot_present qemuusbserial
    check_slot_not_gone qemuusbserial
    check_slot_device_path qemuusbserial "/dev/ttyUSB0"

    echo "Connecting hotplug slot of the first device again"
    remote.exec "sudo snap connect serial-port-hotplug:serial-port :qemuusbserial"
    check_slot_connected qemuusbserial

    remote.exec "cat /var/snap/serial-port-hotplug/common/connect-plug-done" | MATCH "/dev/ttyUSB0"

    echo "Hotplug slot stays after removing the snap"
    remote.exec "sudo snap remove serial-port-hotplug"
    check_slot_present qemuusbserial
    check_slot_not_gone qemuusbserial