diff options
author | Sylvain Pineau <sylvain.pineau@canonical.com> | 2019-05-09 14:37:20 +0200 |
---|---|---|
committer | Sylvain Pineau <sylvain.pineau@canonical.com> | 2019-05-09 14:37:20 +0200 |
commit | 9ac21efe28040e27b305095cf5f093746b5e94c8 (patch) | |
tree | a986e5d772bf1d1d6b3be6eee0792704a8ccd8e4 | |
parent | 9ac6fd633170bb5b68e70726d21d6ce5dbd5274d (diff) | |
parent | 0ea5ae58375181992cbca691dc9bb35db71a6e67 (diff) |
record new upstream branch created by importing plainbox-provider-checkbox_0.48.0~rc1.orig.tar.gz and merge it
33 files changed, 1038 insertions, 219 deletions
diff --git a/bin/cpu_stress b/bin/cpu_stress index abcb983..56fccee 100755 --- a/bin/cpu_stress +++ b/bin/cpu_stress @@ -62,9 +62,14 @@ if [ $result = "0" ] ; then echo "* stress-ng CPU test passed!" else if [ $result = "137" ] ; then - echo "* stress-ng CPU test timed out and was forcefully terminated!" + echo "** stress-ng CPU test timed out and SIGKILL was used to " \ + "terminate the test (Error $result)!" + elif [ $return_code = "124" ] ; then + echo "* stress-ng CPU test timed out and was forcefully terminated " \ + "(Error $result)!" + else + echo "* stress-ng CPU test failed with result $result" fi - echo "* stress-ng CPU test failed with result $result" fi echo "**********************************************************" exit $result diff --git a/bin/disk_stats_test b/bin/disk_stats_test index 3c88a6c..60b48f5 100755 --- a/bin/disk_stats_test +++ b/bin/disk_stats_test @@ -26,6 +26,12 @@ if [[ "$1" != '' ]]; then DISK="$1" fi +nvdimm="pmem" +if [ -z "${DISK##*$nvdimm*}" ];then + echo "Disk $DISK appears to be an NVDIMM, skipping" + exit $STATUS +fi + #Check /proc/partitions, exit with fail if disk isn't found grep -w -q $DISK /proc/partitions check_return_code $? "Disk $DISK not found in /proc/partitions" diff --git a/bin/disk_stress_ng b/bin/disk_stress_ng index 27db58f..9d8668e 100755 --- a/bin/disk_stress_ng +++ b/bin/disk_stress_ng @@ -245,8 +245,12 @@ run_stressor() { fi had_error=1 echo "*****************************************************************" - if [ $return_code = "137" ] ; then - echo "** stress-ng disk test timed out and was forcefully terminated!" + if [ $return_code = "124" ] ; then + echo "** stress-ng $stressor test timed out and was forcefully " \ + "terminated! (Error $return_code)" + elif [ $return_code = "137" ] ; then + echo "** stress-ng $stressor test timed out and SIGKILL was used to " \ + "terminate the test case! (Error $return_code)" else echo "** Error $return_code reported on stressor $stressor!)" fi diff --git a/bin/hotkey_tests.py b/bin/hotkey_tests.py new file mode 100755 index 0000000..2a9282b --- /dev/null +++ b/bin/hotkey_tests.py @@ -0,0 +1,439 @@ +#!/usr/bin/env python3 +# +# Copyright 2019 Canonical Ltd. +# Written by: +# Maciej Kisielewski <maciej.kisielewski@canonical.com> +# +# This is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# as published by the Free Software Foundation. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this file. If not, see <http://www.gnu.org/licenses/>. +import datetime +import enum +import os +import re +import struct +import subprocess +import sys +import time + + +class KeyCodes(enum.Enum): + KEY_RESERVED = 0 + KEY_ESC = 1 + KEY_1 = 2 + KEY_2 = 3 + KEY_3 = 4 + KEY_4 = 5 + KEY_5 = 6 + KEY_6 = 7 + KEY_7 = 8 + KEY_8 = 9 + KEY_9 = 10 + KEY_0 = 11 + KEY_MINUS = 12 + KEY_EQUAL = 13 + KEY_BACKSPACE = 14 + KEY_TAB = 15 + KEY_Q = 16 + KEY_W = 17 + KEY_E = 18 + KEY_R = 19 + KEY_T = 20 + KEY_Y = 21 + KEY_U = 22 + KEY_I = 23 + KEY_O = 24 + KEY_P = 25 + KEY_LEFTBRACE = 26 + KEY_RIGHTBRACE = 27 + KEY_ENTER = 28 + KEY_LEFTCTRL = 29 + KEY_A = 30 + KEY_S = 31 + KEY_D = 32 + KEY_F = 33 + KEY_G = 34 + KEY_H = 35 + KEY_J = 36 + KEY_K = 37 + KEY_L = 38 + KEY_SEMICOLON = 39 + KEY_APOSTROPHE = 40 + KEY_GRAVE = 41 + KEY_LEFTSHIFT = 42 + KEY_BACKSLASH = 43 + KEY_Z = 44 + KEY_X = 45 + KEY_C = 46 + KEY_V = 47 + KEY_B = 48 + KEY_N = 49 + KEY_M = 50 + KEY_COMMA = 51 + KEY_DOT = 52 + KEY_SLASH = 53 + KEY_RIGHTSHIFT = 54 + KEY_KPASTERISK = 55 + KEY_LEFTALT = 56 + KEY_SPACE = 57 + KEY_CAPSLOCK = 58 + KEY_F1 = 59 + KEY_F2 = 60 + KEY_F3 = 61 + KEY_F4 = 62 + KEY_F5 = 63 + KEY_F6 = 64 + KEY_F7 = 65 + KEY_F8 = 66 + KEY_F9 = 67 + KEY_F10 = 68 + KEY_NUMLOCK = 69 + KEY_SCROLLLOCK = 70 + KEY_KP7 = 71 + KEY_KP8 = 72 + KEY_KP9 = 73 + KEY_KPMINUS = 74 + KEY_KP4 = 75 + KEY_KP5 = 76 + KEY_KP6 = 77 + KEY_KPPLUS = 78 + KEY_KP1 = 79 + KEY_KP2 = 80 + KEY_KP3 = 81 + KEY_KP0 = 82 + KEY_KPDOT = 83 + KEY_ZENKAKUHANKAKU = 85 + KEY_102ND = 86 + KEY_F11 = 87 + KEY_F12 = 88 + KEY_RO = 89 + KEY_KATAKANA = 90 + KEY_HIRAGANA = 91 + KEY_HENKAN = 92 + KEY_KATAKANAHIRAGANA = 93 + KEY_MUHENKAN = 94 + KEY_KPJPCOMMA = 95 + KEY_KPENTER = 96 + KEY_RIGHTCTRL = 97 + KEY_KPSLASH = 98 + KEY_SYSRQ = 99 + KEY_RIGHTALT = 100 + KEY_LINEFEED = 101 + KEY_HOME = 102 + KEY_UP = 103 + KEY_PAGEUP = 104 + KEY_LEFT = 105 + KEY_RIGHT = 106 + KEY_END = 107 + KEY_DOWN = 108 + KEY_PAGEDOWN = 109 + KEY_INSERT = 110 + KEY_DELETE = 111 + KEY_MACRO = 112 + KEY_MUTE = 113 + KEY_VOLUMEDOWN = 114 + KEY_VOLUMEUP = 115 + KEY_POWER = 116 # SC System Power Down + KEY_KPEQUAL = 117 + KEY_KPPLUSMINUS = 118 + KEY_PAUSE = 119 + KEY_SCALE = 120 # AL Compiz Scale (Expose) + + KEY_KPCOMMA = 121 + KEY_HANGEUL = 122 + KEY_HANGUEL = KEY_HANGEUL + KEY_HANJA = 123 + KEY_YEN = 124 + KEY_LEFTMETA = 125 + KEY_RIGHTMETA = 126 + KEY_COMPOSE = 127 + + KEY_STOP = 128 # AC Stop + KEY_AGAIN = 129 + KEY_PROPS = 130 # AC Properties + KEY_UNDO = 131 # AC Undo + KEY_FRONT = 132 + KEY_COPY = 133 # AC Copy + KEY_OPEN = 134 # AC Open + KEY_PASTE = 135 # AC Paste + KEY_FIND = 136 # AC Search + KEY_CUT = 137 # AC Cut + KEY_HELP = 138 # AL Integrated Help Center + KEY_MENU = 139 # Menu (show menu) + KEY_CALC = 140 # AL Calculator + KEY_SETUP = 141 + KEY_SLEEP = 142 # SC System Sleep + KEY_WAKEUP = 143 # System Wake Up + KEY_FILE = 144 # AL Local Machine Browser + KEY_SENDFILE = 145 + KEY_DELETEFILE = 146 + KEY_XFER = 147 + KEY_PROG1 = 148 + KEY_PROG2 = 149 + KEY_WWW = 150 # AL Internet Browser + KEY_MSDOS = 151 + KEY_COFFEE = 152 # AL Terminal Lock/Screensaver + KEY_SCREENLOCK = KEY_COFFEE + KEY_ROTATE_DISPLAY = 153 # Display orientation for e.g. tablets + KEY_DIRECTION = KEY_ROTATE_DISPLAY + KEY_CYCLEWINDOWS = 154 + KEY_MAIL = 155 + KEY_BOOKMARKS = 156 # AC Bookmarks + KEY_COMPUTER = 157 + KEY_BACK = 158 # AC Back + KEY_FORWARD = 159 # AC Forward + KEY_CLOSECD = 160 + KEY_EJECTCD = 161 + KEY_EJECTCLOSECD = 162 + KEY_NEXTSONG = 163 + KEY_PLAYPAUSE = 164 + KEY_PREVIOUSSONG = 165 + KEY_STOPCD = 166 + KEY_RECORD = 167 + KEY_REWIND = 168 + KEY_PHONE = 169 # Media Select Telephone + KEY_ISO = 170 + KEY_CONFIG = 171 # AL Consumer Control Configuration + KEY_HOMEPAGE = 172 # AC Home + KEY_REFRESH = 173 # AC Refresh + KEY_EXIT = 174 # AC Exit + KEY_MOVE = 175 + KEY_EDIT = 176 + KEY_SCROLLUP = 177 + KEY_SCROLLDOWN = 178 + KEY_KPLEFTPAREN = 179 + KEY_KPRIGHTPAREN = 180 + KEY_NEW = 181 # AC New + KEY_REDO = 182 # AC Redo/Repeat + + KEY_F13 = 183 + KEY_F14 = 184 + KEY_F15 = 185 + KEY_F16 = 186 + KEY_F17 = 187 + KEY_F18 = 188 + KEY_F19 = 189 + KEY_F20 = 190 + KEY_F21 = 191 + KEY_F22 = 192 + KEY_F23 = 193 + KEY_F24 = 194 + + KEY_PLAYCD = 200 + KEY_PAUSECD = 201 + KEY_PROG3 = 202 + KEY_PROG4 = 203 + KEY_DASHBOARD = 204 # AL Dashboard + KEY_SUSPEND = 205 + KEY_CLOSE = 206 # AC Close + KEY_PLAY = 207 + KEY_FASTFORWARD = 208 + KEY_BASSBOOST = 209 + KEY_PRINT = 210 # AC Print + KEY_HP = 211 + KEY_CAMERA = 212 + KEY_SOUND = 213 + KEY_QUESTION = 214 + KEY_EMAIL = 215 + KEY_CHAT = 216 + KEY_SEARCH = 217 + KEY_CONNECT = 218 + KEY_FINANCE = 219 # AL Checkbook/Finance + KEY_SPORT = 220 + KEY_SHOP = 221 + KEY_ALTERASE = 222 + KEY_CANCEL = 223 # AC Cancel + KEY_BRIGHTNESSDOWN = 224 + KEY_BRIGHTNESSUP = 225 + KEY_MEDIA = 226 + # Cycle between available video outputs (Monitor/LCD/TV-out/etc) + KEY_SWITCHVIDEOMODE = 227 + KEY_KBDILLUMTOGGLE = 228 + KEY_KBDILLUMDOWN = 229 + KEY_KBDILLUMUP = 230 + KEY_SEND = 231 # AC Send + KEY_REPLY = 232 # AC Reply + KEY_FORWARDMAIL = 233 # AC Forward Msg + KEY_SAVE = 234 # AC Save + KEY_DOCUMENTS = 235 + KEY_BATTERY = 236 + KEY_BLUETOOTH = 237 + KEY_WLAN = 238 + KEY_UWB = 239 + KEY_UNKNOWN = 240 + KEY_VIDEO_NEXT = 241 # drive next video source + KEY_VIDEO_PREV = 242 # drive previous video source + KEY_BRIGHTNESS_CYCLE = 243 # brightness up, after max is min + # Set Auto Brightness = manual brightness control is off, rely on ambient + KEY_BRIGHTNESS_AUTO = 244 + KEY_BRIGHTNESS_ZERO = KEY_BRIGHTNESS_AUTO + KEY_DISPLAY_OFF = 245 # display device to off state + KEY_WWAN = 246 # Wireless WAN (LTE, UMTS, GSM, etc.) + KEY_WIMAX = KEY_WWAN + KEY_RFKILL = 247 # Key that controls all radios + KEY_MICMUTE = 248 # Mute / unmute the microphone + + def from_char(c): + obvious_keys = { + '/': KeyCodes.KEY_SLASH, + ' ': KeyCodes.KEY_SPACE, + '-': KeyCodes.KEY_MINUS, + } + if c in obvious_keys.keys(): + return obvious_keys[c] + keycode_name = 'KEY_{}'.format(c.upper()) + try: + return KeyCodes[keycode_name] + except KeyError: + raise SystemExit( + 'One does not simply convert {} to a keycode'.format(c)) + + +def guess_kb_dev_path(): + """ + Guess the path of the keyboard device that we can send events to. + """ + # most intel-based devices I tested had platform-i8042-serio-0-event-kbd + # device, so let's use that if it is present + intel_generic = '/dev/input/by-path/platform-i8042-serio-0-event-kbd' + + if os.path.exists(intel_generic): + return intel_generic + raise SystemExit("Couldn't guess a proper keyboard device") + + +class FauxKeyboard(): + def __init__(self, dev_path=guess_kb_dev_path()): + self.kb_dev_file = open(dev_path, 'wb') + self.event_struct = struct.Struct('llHHi') + + def __del__(self): + self.kb_dev_file.close() + + def type_text(self, text): + for c in text: + self.press_key(KeyCodes.from_char(c)) + + def press_key(self, key_code, modifiers=set(), repetitions=1, delay=0.05): + # simple key press actions contains four events: + # EV_MSC, MSC_SCAN, {KEY_CODE} + # EV_KEY, {KEY_CODE}, 1 + # EV_SYN, 0, 0 + # EV_KEY, {KEY_CODE}, 0 + # XXX: ATM there's no distinction between left and right modifiers + assert(repetitions >= 0) + while repetitions: + if not modifiers.issubset({'alt', 'ctrl', 'shift', 'meta'}): + raise SystemExit('Unknown modifier') + if type(key_code) == KeyCodes: + key_code = key_code.value + data = bytes() + data += self.event_struct.pack(0, 0, 4, 4, key_code) + for mod in modifiers: + mod_code = KeyCodes['KEY_LEFT{}'.format(mod.upper())].value + data += self.event_struct.pack(0, 0, 1, mod_code, 1) + data += self.event_struct.pack(0, 0, 1, key_code, 1) + data += self.event_struct.pack(0, 0, 0, 0, 0) + data += self.event_struct.pack(0, 10, 1, key_code, 0) + for mod in modifiers: + mod_code = KeyCodes['KEY_LEFT{}'.format(mod.upper())].value + data += self.event_struct.pack(0, 10, 1, mod_code, 0) + data += self.event_struct.pack(0, 10, 0, 0, 0) + self.kb_dev_file.write(data) + self.kb_dev_file.flush() + time.sleep(delay) + repetitions -= 1 + + +class HotKeyTesting: + + def __init__(self): + self.kb = FauxKeyboard() + + def check_volume_media_keys(self): + """ + Check if the volume media keys have an effect on ALSA + """ + # if the volume is already on max, then raising it won't make any + # difference, so first, let's lower it before establishing the baseline + self.kb.press_key(KeyCodes.KEY_VOLUMEDOWN, repetitions=4, delay=0.2) + self.kb.press_key(KeyCodes.KEY_VOLUMEUP) + # let's grab output of alsa mixer to establish what is the baseline + # before we start raising the volume + before = subprocess.check_output('amixer').decode( + sys.stdout.encoding).splitlines() + self.kb.press_key(KeyCodes.KEY_VOLUMEUP, repetitions=3, delay=0.2) + after = subprocess.check_output('amixer').decode( + sys.stdout.encoding).splitlines() + temp = before.copy() + for line in temp: + if line in after: + before.remove(line) + after.remove(line) + if not before: + # all lines removed from before, so there's no state change + # of the stuff reported bevore hitting volume up, so let's fail + # the test + return False + # we expect that the lines that changed are status information about + # the output devices. Percentage volume is in square brackets so let's + # search for those and see if they got higher + regex = re.compile(r'\[(\d*)%\]') + if len(before) != len(after): + # more of an assertion - the lines diff should match + return False + for b, a in zip(before, after): + vol_b = regex.search(b).groups() + vol_a = regex.search(a).groups() + if vol_a and vol_b: + if int(vol_b[0]) < int(vol_a[0]): + return True + return False + + def check_terminal_hotkey(self): + # spawn a terminal window using ctrl+alt+t + # touch a unique temporary file, and check if it got created + timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + filename = os.path.join('/tmp/hotkey-testing-{}'.format(timestamp)) + self.kb.press_key(KeyCodes.KEY_T, {'ctrl', 'alt'}) + # wait for the terminal window to appear + assert(not os.path.exists(filename)) + time.sleep(2) + self.kb.type_text('touch {}'.format(filename)) + self.kb.press_key(KeyCodes.KEY_ENTER) + result = os.path.exists(filename) + if not result: + return result + self.kb.press_key(KeyCodes.KEY_D, {'ctrl'}) + os.unlink(filename) + return result + + +def main(): + if not (os.geteuid() == 0): + raise SystemExit('Must be run as root.') + hkt = HotKeyTesting() + failed = False + for member in dir(hkt): + attr = getattr(hkt, member) + if not member.startswith('check_') or not callable(attr): + continue + print('{}... '.format(member), end='', flush=True) + if not attr(): + print("FAIL") + failed = True + else: + print("PASS") + if failed: + raise SystemExit('Some test failed!') + +if __name__ == '__main__': + main() diff --git a/bin/maas-version-check b/bin/maas-version-check index 412717d..678088a 100755 --- a/bin/maas-version-check +++ b/bin/maas-version-check @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (C) 2012-2015 Canonical Ltd. +# Copyright (C) 2012-2019 Canonical Ltd. # Authors # Jeff Lane <jeff@ubuntu.com> @@ -26,6 +26,7 @@ if [ -s $MAAS_FILE ]; then echo $maas_version else echo "ERROR: This system does not appear to have been installed by MAAS" + echo "ERROR: " $(ls -l $MAAS_FILE 2>&1) exit 1 fi diff --git a/bin/memory_stress_ng b/bin/memory_stress_ng index 905ed50..e717f12 100755 --- a/bin/memory_stress_ng +++ b/bin/memory_stress_ng @@ -99,8 +99,12 @@ run_stressor() { fi had_error=1 echo "*****************************************************************" - if [ $return_code = "137" ] ; then - echo "** stress-ng memory test timed out and was forcefully terminated!" + if [ $return_code = "124" ] ; then + echo "** stress-ng $stressor timed out and was forcefully " + "terminated! (Error $return_code)" + elif [ $return_code = "137" ] ; then + echo "** stress-ng memory test timed out and SIGKILL was used to " \ + "terminate the test case! (Error $return_code)" else echo "** Error $return_code reported on stressor $stressor!)" fi diff --git a/bin/net_driver_info b/bin/net_driver_info index 6bc8058..05585ba 100755 --- a/bin/net_driver_info +++ b/bin/net_driver_info @@ -10,6 +10,7 @@ # identify in the special interest list! from pathlib import Path +import subprocess as sp import sys # Store pairs of (interface, driver) @@ -43,3 +44,8 @@ for interface, driver in driver_list: with open(str(path), 'r') as f: print(" {}: {}".format(path.name, f.read().strip())) print() + print('Checking kernel ring buffer for {} messages:'.format(driver)) + cmd = "dmesg -T -x | grep {} || true".format(driver) + output = sp.check_output(cmd, shell=True) + print(output.decode(sys.stdout.encoding)) + print() diff --git a/bin/network_device_info b/bin/network_device_info.py index 174fbe8..29a4aed 100755 --- a/bin/network_device_info +++ b/bin/network_device_info.py @@ -17,7 +17,7 @@ # NetworkManager # http://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python # -# Copyright (C) 2012 Canonical, Ltd. +# Copyright (C) 2012-2019 Canonical, Ltd. from subprocess import check_output, CalledProcessError, STDOUT import sys @@ -125,7 +125,7 @@ class NetworkingDevice(): cmd = ['/sbin/modinfo', driver] try: stream = check_output(cmd, stderr=STDOUT, universal_newlines=True) - except CalledProcessError as err: + except CalledProcessError: return None if not stream: @@ -156,6 +156,35 @@ class NetworkingDevice(): return "%d.%d.%d.%d" % (ip[0], ip[1], ip[2], ip[3]) +def print_udev_devices(): + print("[ Devices found by udev ]".center(80, '-')) + for device in udev_devices: + for attribute in attributes: + value = getattr(device, attribute) + if value is not None: + if attribute == 'driver': + props = {} + props['Driver'] = value + network_dev = NetworkingDevice( + None, props, None, None) + print("%s: %s (ver: %s)" % ( + attribute.capitalize(), value, + network_dev._driver_ver)) + else: + print("%s: %s" % (attribute.capitalize(), value)) + vendor_id = getattr(device, 'vendor_id') + product_id = getattr(device, 'product_id') + subvendor_id = getattr(device, 'subvendor_id') + subproduct_id = getattr(device, 'subproduct_id') + if vendor_id and product_id: + print("ID: [{0:04x}:{1:04x}]".format( + vendor_id, product_id)) + if subvendor_id and subproduct_id: + print("Subsystem ID: [{0:04x}:{1:04x}]".format( + subvendor_id, subproduct_id)) + print() + + def get_nm_devices(): devices = [] bus = dbus.SystemBus() @@ -183,30 +212,11 @@ def get_nm_devices(): return devices -def match_counts(nm_devices, udev_devices, devtype): - """ - Ensures that the count of devices matching devtype is the same for the - two passed in lists, devices from Network Manager and devices from lspci. - """ - # now check that the count (by type) matches - nm_type_devices = [dev for dev in nm_devices if dev.gettype() in devtype] - udevtype = 'NETWORK' - udev_type_devices = [ - udev - for udev in udev_devices - if udev.category == udevtype] - if len(nm_type_devices) != len(udev_type_devices): - print("ERROR: devices missing - udev showed %d %s devices, but " - "NetworkManager saw %d devices in %s" % - (len(udev_type_devices), udevtype, - len(nm_type_devices), devtype), - file=sys.stderr) - return False - else: - return True - - -def main(args): +def main(): + if len(sys.argv) != 2 or sys.argv[1] not in ('detect', 'info'): + raise SystemExit('ERROR: please specify detect or info') + action = sys.argv[1] + try: output = check_output(['udevadm', 'info', '--export-db']) except CalledProcessError as err: @@ -219,48 +229,33 @@ def main(args): result = UdevResult() udev.run(result) - if udev_devices: - print("[ Devices found by udev ]".center(80, '-')) - for device in udev_devices: - for attribute in attributes: - value = getattr(device, attribute) - if value is not None: - if attribute == 'driver': - props = {} - props['Driver'] = value - network_dev = NetworkingDevice(None, props, None, None) - print("%s: %s (ver: %s)" % (attribute.capitalize(), - value, network_dev._driver_ver)) - else: - print("%s: %s" % (attribute.capitalize(), value)) - vendor_id = getattr(device, 'vendor_id') - product_id = getattr(device, 'product_id') - subvendor_id = getattr(device, 'subvendor_id') - subproduct_id = getattr(device, 'subproduct_id') - if vendor_id and product_id: - print("ID: [{0:04x}:{1:04x}]".format(vendor_id, product_id)) - if subvendor_id and subproduct_id: - print("Subsystem ID: [{0:04x}:{1:04x}]".format(subvendor_id, subproduct_id)) - print() + # The detect action should indicate presence of an ethernet adatper and + # cause the job to fail if none present - rely on udev for this + if action == 'detect': + if udev_devices: + print_udev_devices() + else: + raise SystemExit('No devices detected by udev') + + # The info action should just gather infomation about any ethernet devices + # found and report for inclusion in e.g. an attachment job + if action == 'info': + # Report udev detected devices first + if udev_devices: + print_udev_devices() + + # Attempt to report devices found by NetworkManager - this doesn't + # make sense for server installs so skipping is acceptable + try: + nm_devices = get_nm_devices() + except dbus.exceptions.DBusException: + # server's don't have network manager installed + print('Network Manager not found') + else: + print("[ Devices found by Network Manager ]".center(80, '-')) + for nm_dev in nm_devices: + print(nm_dev) - try: - nm_devices = get_nm_devices() - except dbus.exceptions.DBusException as e: - # server's don't have network manager installed - print("Warning: Exception while talking to Network Manager over dbus." - " Skipping the remainder of this test. If this is a server, this" - " is expected.", file=sys.stderr) - print("The Error Generated was:\n %s" % e, file=sys.stderr) - return 0 - - print("[ Devices found by Network Manager ]".center(80, '-')) - for nm_dev in nm_devices: - print(nm_dev) - - if not match_counts(nm_devices, udev_devices, "Ethernet"): - return 1 - else: - return 0 if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) + main() diff --git a/bin/removable_storage_test b/bin/removable_storage_test index 6de3f97..a7abdfe 100755 --- a/bin/removable_storage_test +++ b/bin/removable_storage_test @@ -21,6 +21,7 @@ from checkbox_support.dbus import connect_to_system_bus from checkbox_support.dbus.udisks2 import UDISKS2_BLOCK_INTERFACE from checkbox_support.dbus.udisks2 import UDISKS2_DRIVE_INTERFACE from checkbox_support.dbus.udisks2 import UDISKS2_FILESYSTEM_INTERFACE +from checkbox_support.dbus.udisks2 import UDISKS2_LOOP_INTERFACE from checkbox_support.dbus.udisks2 import UDisks2Model, UDisks2Observer from checkbox_support.dbus.udisks2 import is_udisks2_supported from checkbox_support.dbus.udisks2 import lookup_udev_device @@ -38,6 +39,7 @@ from checkbox_support.udev import get_udev_xhci_devices class ActionTimer(): '''Class to implement a simple timer''' + def __enter__(self): self.start = time.time() return self @@ -49,6 +51,7 @@ class ActionTimer(): class RandomData(): '''Class to create data files''' + def __init__(self, size): self.tfile = tempfile.NamedTemporaryFile(delete=False) self.path = '' @@ -299,7 +302,8 @@ class DiskTest(): udev_devices = get_udev_block_devices(GUdev.Client()) for udev_device in udev_devices: if udev_device.get_device_file() == dev_file: - interconnect_speed = get_interconnect_speed(udev_device) + interconnect_speed = get_interconnect_speed( + udev_device) if interconnect_speed: self.rem_disks_speed[dev_file] = ( interconnect_speed * 10 ** 6) @@ -329,7 +333,8 @@ class DiskTest(): """ for udisks2_object_path, interfaces in udisks2_objects.items(): if (UDISKS2_FILESYSTEM_INTERFACE in interfaces and - UDISKS2_BLOCK_INTERFACE in interfaces): + UDISKS2_BLOCK_INTERFACE in interfaces and + UDISKS2_LOOP_INTERFACE not in interfaces): yield udisks2_object_path # We need to know about all IO candidates, # let's iterate over all the block devices reported by udisks2 @@ -605,7 +610,7 @@ def main(): help=("Detect the driver of the host controller." "Only xhci_hcd for usb3 is supported so far.")) parser.add_argument("--lsblkcommand", action='store', type=str, - default="lsblk -i -n -P -o KNAME,TYPE,MOUNTPOINT", + default="lsblk -i -n -P -e 7 -o KNAME,TYPE,MOUNTPOINT", help=("Command to execute to get lsblk information. " "Only change it if you know what you're doing.")) @@ -870,5 +875,6 @@ def main(): logging.error("No removable drives were detected, aborting") return 1 + if __name__ == '__main__': sys.exit(main()) diff --git a/bin/sleep_time_check b/bin/sleep_time_check index 9e7f084..f9513fa 100755 --- a/bin/sleep_time_check +++ b/bin/sleep_time_check @@ -41,12 +41,17 @@ def main(): resume_times = [] # find our times for line in lines: - if "Average time to sleep" in line: - sleep_time = float(line.split(':')[1].strip()) - sleep_times.append(sleep_time) - elif "Average time to resume" in line: - resume_time = float(line.split(':')[1].strip()) - resume_times.append(resume_time) + try: + if "Average time to sleep" in line: + sleep_time = float(line.split(':')[1].strip()) + sleep_times.append(sleep_time) + elif "Average time to resume" in line: + resume_time = float(line.split(':')[1].strip()) + resume_times.append(resume_time) + except ValueError as e: + print("ERROR: One or more times was not reported correctly:") + print(e) + return 1 if (sleep_time is None or resume_time is None) or \ (len(sleep_times) != len(resume_times)): diff --git a/bin/storage_test b/bin/storage_test index da4b717..9649dc1 100755 --- a/bin/storage_test +++ b/bin/storage_test @@ -59,7 +59,7 @@ find_largest_lv() { } # find_largest_lv() -# Find the largest partition that holds a supported filesystem on $disk_device. +# Find the largest partition that holds a supported filesystem on $disk. # This code is adapted from a similar function in `disk_stress_ng`. # Output: # $largest_part -- Device filename of largest qualifying partition or logical volume @@ -67,13 +67,14 @@ find_largest_lv() { # $largest_fs -- Filesystem (ext4, etc.) used on largest qualifying partition or logical volume # $unsupported_fs -- Empty or contains name of unsupported filesystem found on disk find_largest_partition() { + echo "Find largest partition on $disk..." largest_part="" largest_size=0 mapper_string="dm-" - if [ "${disk_device#*$mapper_string}" = "$disk_device" ]; then - partitions=$(lsblk -b -l -n -o NAME,SIZE,TYPE,MOUNTPOINT $disk_device | grep part | tr -s " ") + if [ "${disk_device#*$mapper_string}" = "$disk" ]; then + partitions=$(lsblk -b -l -n -o NAME,SIZE,TYPE,MOUNTPOINT $disk | grep part | tr -s " ") else - partitions=$(lsblk -b -l -n -o NAME,SIZE,TYPE,MOUNTPOINT $disk_device) + partitions=$(lsblk -b -l -n -o NAME,SIZE,TYPE,MOUNTPOINT $disk) fi unsupported_fs="" for partition in $(echo "$partitions" | cut -d " " -f 1) ; do diff --git a/bin/wifi_nmcli_backup.py b/bin/wifi_nmcli_backup.py new file mode 100755 index 0000000..7ec9c89 --- /dev/null +++ b/bin/wifi_nmcli_backup.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# Copyright 2019 Canonical Ltd. +# All rights reserved. +# +# Written by: +# Jonathan Cave <jonathan.cave@canonical.com> +# +# Save/Restore NetworkManager wifi connections + +import os +import shutil +import subprocess as sp +import sys + +NM_CON_DIR = '/etc/NetworkManager/system-connections' +SAVE_DIR = os.path.join(os.path.expandvars( + '$PLAINBOX_SESSION_SHARE'), 'stored-system-connections') + + +def get_nm_connections(): + c = [] + cmd = 'nmcli -t -f TYPE,NAME c' + output = sp.check_output(cmd, shell=True) + for line in output.decode(sys.stdout.encoding).splitlines(): + con_type, name = line.strip().split(':') + if con_type == '802-11-wireless': + c.append(name) + return c + + +def reload_nm_connections(): + cmd = 'nmcli c reload' + sp.check_call(cmd, shell=True) + + +def save_connections(con_list): + if len(con_list) == 0: + print('No stored 802.11 connections to save') + return + if not os.path.exists(SAVE_DIR): + os.makedirs(SAVE_DIR) + for c in con_list: + print('Save connection {}'.format(c)) + c_loc = os.path.join(NM_CON_DIR, c) + if not os.path.exists(c_loc): + print(' No stored connection fount at {}'.format(c_loc)) + continue + print(' Found file {}'.format(c_loc)) + save_f = shutil.copy(c_loc, SAVE_DIR) + print(' Saved copy at {}'.format(save_f)) + + +def restore_connections(): + saved_list = [f for f in os.listdir( + SAVE_DIR) if os.path.isfile(os.path.join(SAVE_DIR, f))] + if len(saved_list) == 0: + print('No stored 802.11 connections found') + return + for f in saved_list: + save_f = os.path.join(SAVE_DIR, f) + print('Restore connection {}'.format(save_f)) + restore_f = shutil.copy(save_f, NM_CON_DIR) + print(' Restored file at {}'.format(restore_f)) + os.remove(save_f) + print(' Removed copy from {}'.format(save_f)) + + +if __name__ == '__main__': + if len(sys.argv) != 2: + raise SystemExit('ERROR: please specify save or restore') + action = sys.argv[1] + + if action == 'save': + save_connections(get_nm_connections()) + elif action == 'restore': + restore_connections() + reload_nm_connections() + else: + raise SystemExit('ERROR: unrecognised action') diff --git a/bin/wifi_nmcli_test b/bin/wifi_nmcli_test.py index b89a525..971b363 100755 --- a/bin/wifi_nmcli_test +++ b/bin/wifi_nmcli_test.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2017-2018 Canonical Ltd. +# Copyright 2017-2019 Canonical Ltd. # All rights reserved. # # Written by: @@ -13,6 +13,7 @@ import argparse import functools import subprocess as sp import sys +import time from distutils.version import LooseVersion @@ -61,7 +62,13 @@ def device_rescan(): print_head("Calling a rescan") cmd = "nmcli d wifi rescan" print_cmd(cmd) - sp.call(cmd, shell=True) + retcode = sp.call(cmd, shell=True) + if retcode != 0: + # Most often the rescan request fails because NM has itself started + # a scan in recent past, we should let these operations complete before + # attempting a connection + print('Scan request failed, allow other operations to complete (15s)') + time.sleep(15) print() @@ -73,7 +80,8 @@ def list_aps(args): cmd = "nmcli -t -f {} d wifi list iface {}".format(fields, args.device) else: fields = "SSID,CHAN,FREQ,SIGNAL" - cmd = "nmcli -t -f {} d wifi list ifname {}".format(fields, args.device) + cmd = "nmcli -t -f {} d wifi list ifname {}".format( + fields, args.device) print_cmd(cmd) output = sp.check_output(cmd, shell=True) for line in output.decode(sys.stdout.encoding).splitlines(): @@ -108,10 +116,11 @@ def open_connection(args): print_cmd(cmd) sp.call(cmd, shell=True) if legacy_nmcli(): - cmd_part = "nmcli -m tabular -t -f GENERAL d list | " - cmd = cmd_part + "grep {} | awk -F: '{{print $15}}'".format(args.device) + cmd = ("nmcli -m tabular -t -f GENERAL d list | grep {} | " + "awk -F: '{{print $15}}'".format(args.device)) else: - cmd = "nmcli -m tabular -t -f GENERAL.STATE d show {}".format(args.device) + cmd = "nmcli -m tabular -t -f GENERAL.STATE d show {}".format( + args.device) print_cmd(cmd) output = sp.check_output(cmd, shell=True) state = output.decode(sys.stdout.encoding).strip() @@ -126,18 +135,19 @@ def open_connection(args): def secured_connection(args): print_head("Connection attempt") if legacy_nmcli(): - cmd = "nmcli d wifi connect {} password {} iface {} name TEST_CON".format( - args.essid, args.psk, args.device) + cmd = ("nmcli d wifi connect {} password {} iface {} name " + "TEST_CON".format(args.essid, args.psk, args.device)) else: - cmd = "nmcli d wifi connect {} password {} ifname {} name TEST_CON".format( - args.essid, args.psk, args.device) + cmd = ("nmcli d wifi connect {} password {} ifname {} name " + "TEST_CON".format(args.essid, args.psk, args.device)) print_cmd(cmd) sp.call(cmd, shell=True) if legacy_nmcli(): - cmd_part = "nmcli -m tabular -t -f GENERAL d list | " - cmd = cmd_part + "grep {} | awk -F: '{{print $15}}'".format(args.device) + cmd = ("nmcli -m tabular -t -f GENERAL d list | " + "grep {} | awk -F: '{{print $15}}'".format(args.device)) else: - cmd = "nmcli -m tabular -t -f GENERAL.STATE d show {}".format(args.device) + cmd = "nmcli -m tabular -t -f GENERAL.STATE d show {}".format( + args.device) print_cmd(cmd) output = sp.check_output(cmd, shell=True) state = output.decode(sys.stdout.encoding).strip() @@ -149,6 +159,43 @@ def secured_connection(args): return rc +def hotspot(args): + print_head("Create Wi-Fi hotspot") + cmd = ("nmcli c add type wifi ifname {} con-name TEST_CON autoconnect no" + " ssid CHECKBOX_AP".format(args.device)) + print_cmd(cmd) + retcode = sp.call(cmd, shell=True) + if retcode != 0: + print("Connection creation failed\n") + return retcode + cmd = ("nmcli c modify TEST_CON 802-11-wireless.mode ap ipv4.method shared" + " 802-11-wireless.band {}".format(args.band)) + print_cmd(cmd) + retcode = sp.call(cmd, shell=True) + if retcode != 0: + print("Set band failed\n") + return retcode + cmd = "nmcli c modify TEST_CON wifi-sec.key-mgmt wpa-psk" + print_cmd(cmd) + retcode = sp.call(cmd, shell=True) + if retcode != 0: + print("Set key-mgmt failed\n") + return retcode + cmd = "nmcli connection modify TEST_CON wifi-sec.psk \"ubuntu1234\"" + print_cmd(cmd) + retcode = sp.call(cmd, shell=True) + if retcode != 0: + print("Set PSK failed\n") + return retcode + cmd = "nmcli connection up TEST_CON" + print_cmd(cmd) + retcode = sp.call(cmd, shell=True) + if retcode != 0: + print("Failed to bring up connection\n") + print() + return retcode + + if __name__ == '__main__': parser = argparse.ArgumentParser( description='WiFi connection test using mmcli') @@ -175,6 +222,14 @@ if __name__ == '__main__': parser_secured.add_argument('essid', type=str, help='ESSID') parser_secured.add_argument('psk', type=str, help='Pre-Shared Key') parser_secured.set_defaults(func=secured_connection) + + parser_ap = subparsers.add_parser( + 'ap', help='Test creation of a hotspot') + parser_ap.add_argument( + 'device', type=str, help='Device name e.g. wlan0') + parser_ap.add_argument('band', type=str, help='Band') + parser_ap.set_defaults(func=hotspot) + args = parser.parse_args() cleanup_nm_connections() diff --git a/debian/.git-dpm b/debian/.git-dpm index 878097b..893d5c4 100644 --- a/debian/.git-dpm +++ b/debian/.git-dpm @@ -1,8 +1,8 @@ # see git-dpm(1) from git-dpm package -701d01192d9bf510e77d97dfdf373fb36edb065f -701d01192d9bf510e77d97dfdf373fb36edb065f -701d01192d9bf510e77d97dfdf373fb36edb065f -701d01192d9bf510e77d97dfdf373fb36edb065f -plainbox-provider-checkbox_0.47.0.orig.tar.gz -f93bc5512845308ddf0a66027252d64546a4c333 -1937032 +0ea5ae58375181992cbca691dc9bb35db71a6e67 +0ea5ae58375181992cbca691dc9bb35db71a6e67 +0ea5ae58375181992cbca691dc9bb35db71a6e67 +0ea5ae58375181992cbca691dc9bb35db71a6e67 +plainbox-provider-checkbox_0.48.0~rc1.orig.tar.gz +922820451d85860ea959b614aabfb6e2ec02a1eb +1942548 @@ -5,7 +5,7 @@ from plainbox.provider_manager import N_ setup( name='plainbox-provider-checkbox', namespace='com.canonical.certification', - version="0.47.0", + version="0.48.0rc1", description=N_("Checkbox provider"), gettext_domain='plainbox-provider-checkbox', strict=False, deprecated=False, diff --git a/units/dock/jobs.pxu b/units/dock/jobs.pxu index 34decb6..c425402 100644 --- a/units/dock/jobs.pxu +++ b/units/dock/jobs.pxu @@ -478,18 +478,22 @@ id: dock/mac-address-pass-through category_id: dock-network plugin: manual depends: dock/cold-plug -estimated_duration: 60 -_summary: MAC address pass through function test -_purpose: - Test MAC address pass through function with docking station (Dell Dock specific function, TB15, WD15) -_steps: - Skip this test if your docking station does not support MAC address pass through. - 1. Make sure the dock is connected to network using an Ethernet cable - 2. Run 'ifconfig' to get system specific MAC address and IP - 3. Ping the IP address from another system - 4. Run 'arp -a IP' from another system to get the MAC address of the test unit through dock -_verification: - Is the MAC address got from arp matching with specific MAC address? +estimated_duration: 180 +_summary: MAC address passthrough function test +_purpose: + Test MAC address passthrough function with dock station. +_steps: + Skip this test if your dock station does not support MAC address passthrough. + 1. Find Passthrough MAC Address in BIOS setup + 2. Check "Passthrough MAC Address" is enabled + 2. Connect dock to system + 3. Boot to OS + 4. Run "ip a" in terminal to get dock ethernet MAC address +_verification: + 1. Is the Passthrough MAC Address the same as MAC address found in step 4? + 2. If BIOS doesn't have Passthrough MAC Address in BIOS setup, a bug should be filed. + 3. If dock ethernet MAC address is not the same as BIOS Passthrough MAC Address, a + bug should be filed. ### USB Tests ### diff --git a/units/ethernet/jobs.pxu b/units/ethernet/jobs.pxu index cf1c02b..b5f068a 100644 --- a/units/ethernet/jobs.pxu +++ b/units/ethernet/jobs.pxu @@ -2,13 +2,15 @@ plugin: shell category_id: com.canonical.plainbox::ethernet id: ethernet/detect flags: also-after-suspend -command: network_device_info +command: network_device_info.py detect estimated_duration: 2.0 _summary: - Report info about available network devices + Detect if at least one ethernet device is detected _description: Test to detect and return information about available network controllers on the system under test. +imports: from com.canonical.plainbox import manifest +requires: manifest.has_ethernet_adapter == 'True' plugin: shell category_id: com.canonical.plainbox::ethernet @@ -82,6 +84,25 @@ template-resource: device template-filter: device.category == 'NETWORK' and device.interface != 'UNKNOWN' plugin: shell category_id: com.canonical.plainbox::ethernet +id: ethernet/multi_iperf3_nic_underspeed_device{__index__}_{interface} +_summary: Underspeed Enabled Multi-NIC Iperf3 stress testing for NIC {interface} +estimated_duration: 7400.0 +requires: + package.name == 'iperf3' or executable.name == 'iperf3' + package.name == 'ethtool' or executable.name == 'ethtool' + package.name == 'nmap' or executable.name == 'nmap' +user: root +environ: TEST_TARGET_IPERF +command: network test -i {interface} -t iperf --iperf3 --scan-timeout 3600 --fail-threshold 80 --cpu-load-fail-threshold 90 --runtime 900 --num_runs 4 --underspeed-ok +_description: + This is the standard Multi-NIC Iperf3 test with the speed check disabled + for retesting systems that are incorrectly reporting supported speeds. + +unit: template +template-resource: device +template-filter: device.category == 'NETWORK' and device.interface != 'UNKNOWN' +plugin: shell +category_id: com.canonical.plainbox::ethernet id: ethernet/ethertool_check_device{__index__}_{interface} _summary: ethtool check for NIC {interface} estimated_duration: 330.0 diff --git a/units/ethernet/manifest.pxu b/units/ethernet/manifest.pxu new file mode 100644 index 0000000..6936344 --- /dev/null +++ b/units/ethernet/manifest.pxu @@ -0,0 +1,4 @@ +unit: manifest entry +id: has_ethernet_adapter +_name: An Ethernet Adapter +value-type: bool diff --git a/units/ethernet/test-plan.pxu b/units/ethernet/test-plan.pxu index 6a6af73..ec2310f 100644 --- a/units/ethernet/test-plan.pxu +++ b/units/ethernet/test-plan.pxu @@ -55,3 +55,27 @@ include: after-suspend-ethernet/ping_.* bootstrap_include: device + +id: server-ethernet +unit: test plan +_name: Server Ethernet Tests +_description: Automated ethernet tests for server certification +estimated_duration: 4h +include: + ethernet/detect + ethernet/info_automated + ethernet/ethtool_info + ethernet/ethertool_check_.* + ethernet/multi_iperf3_nic_device.* + +id: server-ethernet-underspeed +unit: test plan +_name: Server Ethernet Tests (Speed Check Disabled) +_description: Automated ethernet tests for server certification without speed check +estimated_duration: 4h +include: + ethernet/detect + ethernet/info_automated + ethernet/ethtool_info + ethernet/ethertool_check_.* + ethernet/multi_iperf3_nic_underspeed_device.* diff --git a/units/gpgpu/category.pxu b/units/gpgpu/category.pxu new file mode 100644 index 0000000..e07d1b4 --- /dev/null +++ b/units/gpgpu/category.pxu @@ -0,0 +1,3 @@ +unit: category +id: gpgpu +_name: GPGPU Compute Tests diff --git a/units/gpgpu/jobs.pxu b/units/gpgpu/jobs.pxu new file mode 100644 index 0000000..2c823a0 --- /dev/null +++ b/units/gpgpu/jobs.pxu @@ -0,0 +1,8 @@ +id: gpgpu/gpu-burn +category_id: gpgpu +plugin: shell +estimated_duration: 300 +requires: + package.name == 'cuda' +_summary: GPGPU stress testing +command: cd /opt/gpu-burn/ && ./gpu_burn 1800 diff --git a/units/gpgpu/test-plan.pxu b/units/gpgpu/test-plan.pxu new file mode 100644 index 0000000..eaf0db8 --- /dev/null +++ b/units/gpgpu/test-plan.pxu @@ -0,0 +1,8 @@ +id: gpgpu-tests +unit: test plan +_name: GPGPU Compute Testing +_description: + Tests for GPGPU Computations (non-graphical) +mandatory_include: + gpgpu/gpu-burn +include: diff --git a/units/graphics/test-plan.pxu b/units/graphics/test-plan.pxu index 5b58844..9085cb8 100644 --- a/units/graphics/test-plan.pxu +++ b/units/graphics/test-plan.pxu @@ -60,7 +60,7 @@ _name: Graphics tests (discrete GPU) (Manual) _description: Graphics tests (discrete GPU) (Manual) include: - graphics/2_switch_card_.*_xenial certification-status=blocker + graphics/2_auto_switch_card_.* certification-status=blocker graphics/2_maximum_resolution_.* certification-status=blocker graphics/2_glxgears_.* certification-status=blocker graphics/2_rotation_.* certification-status=blocker @@ -88,44 +88,44 @@ unit: test plan _name: After suspend tests (integrated GPU) _description: After suspend tests (integrated GPU) include: - graphics/1_switch_card_.*_xenial certification-status=blocker - suspend/1_resolution_before_suspend_.*_xenial certification-status=blocker + graphics/1_auto_switch_card_.* certification-status=blocker + suspend/1_resolution_before_suspend_.*_auto certification-status=blocker # The following after suspend jobs will automatically select the right suspend job # depending on the amount of graphic cards available on the SUT: # suspend/suspend_advanced (one GPU) - # or suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial (two GPUs) - suspend/1_suspend-time-check_.*_xenial certification-status=non-blocker - suspend/1_suspend-single-log-attach_.*_xenial - power-management/lid certification-status=blocker - power-management/lid_close certification-status=blocker - power-management/lid_open certification-status=blocker - suspend/1_compiz_check_after_suspend_.*_xenial certification-status=blocker - suspend/1_driver_version_after_suspend_.*_xenial certification-status=blocker - suspend/1_resolution_after_suspend_.*_xenial certification-status=blocker - suspend/1_display_after_suspend_.*_xenial certification-status=blocker - suspend/1_glxgears_after_suspend_.*_xenial certification-status=blocker - suspend/1_video_after_suspend_.*_xenial certification-status=blocker - suspend/1_cycle_resolutions_after_suspend_.*_xenial certification-status=non-blocker - suspend/1_xrandr_screens_after_suspend.tar.gz_xenial + # or suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto (two GPUs) + suspend/1_suspend-time-check_.*_auto certification-status=non-blocker + suspend/1_suspend-single-log-attach_.*_auto + power-management/lid certification-status=blocker + power-management/lid_close certification-status=blocker + power-management/lid_open certification-status=blocker + suspend/1_compiz_check_after_suspend_.*_auto certification-status=blocker + suspend/1_driver_version_after_suspend_.*_auto certification-status=blocker + suspend/1_resolution_after_suspend_.*_auto certification-status=blocker + suspend/1_display_after_suspend_.*_auto certification-status=blocker + suspend/1_glxgears_after_suspend_.*_auto certification-status=blocker + suspend/1_video_after_suspend_.*_auto certification-status=blocker + suspend/1_cycle_resolutions_after_suspend_.*_auto certification-status=non-blocker + suspend/1_xrandr_screens_after_suspend.tar.gz_auto id: after-suspend-graphics-discrete-gpu-cert-full unit: test plan _name: After suspend tests (discrete GPU) _description: After suspend tests (discrete GPU) include: - suspend/2_resolution_before_suspend_.*_xenial certification-status=blocker - suspend/2_suspend_after_switch_to_card_.*_xenial certification-status=blocker - suspend/2_suspend-time-check_.*_xenial certification-status=non-blocker - suspend/2_suspend-single-log-attach_.*_xenial - suspend/2_compiz_check_after_suspend_.*_xenial certification-status=blocker - suspend/2_driver_version_after_suspend_.*_xenial certification-status=blocker - suspend/2_resolution_after_suspend_.*_xenial certification-status=blocker - suspend/2_display_after_suspend_.*_xenial certification-status=blocker - suspend/2_glxgears_after_suspend_.*_xenial certification-status=blocker - suspend/2_video_after_suspend_.*_xenial certification-status=blocker - suspend/2_cycle_resolutions_after_suspend_.*_xenial certification-status=non-blocker - suspend/2_xrandr_screens_after_suspend_.*.tar.gz_xenial - after-suspend-manual-monitor/2_dim_brightness_.* certification-status=blocker + suspend/2_resolution_before_suspend_.*_auto certification-status=blocker + suspend/2_suspend_after_switch_to_card_.*_auto certification-status=blocker + suspend/2_suspend-time-check_.*_auto certification-status=non-blocker + suspend/2_suspend-single-log-attach_.*_auto + suspend/2_compiz_check_after_suspend_.*_auto certification-status=blocker + suspend/2_driver_version_after_suspend_.*_auto certification-status=blocker + suspend/2_resolution_after_suspend_.*_auto certification-status=blocker + suspend/2_display_after_suspend_.*_auto certification-status=blocker + suspend/2_glxgears_after_suspend_.*_auto certification-status=blocker + suspend/2_video_after_suspend_.*_auto certification-status=blocker + suspend/2_cycle_resolutions_after_suspend_.*_auto certification-status=non-blocker + suspend/2_xrandr_screens_after_suspend_.*.tar.gz_auto + after-suspend-manual-monitor/2_dim_brightness_.* certification-status=blocker id: graphics-integrated-gpu-cert-blockers unit: test plan @@ -150,7 +150,7 @@ unit: test plan _name: Graphics tests (discrete GPU, certification blockers only) _description: Graphics tests (discrete GPU, certification blockers only) include: - graphics/2_switch_card_.*_xenial certification-status=blocker + graphics/2_auto_switch_card_.* certification-status=blocker graphics/2_maximum_resolution_.* certification-status=blocker graphics/2_valid_opengl_renderer_.* certification-status=blocker graphics/2_glxgears_.* certification-status=blocker @@ -166,18 +166,18 @@ unit: test plan _name: After suspend tests (integrated GPU, certification blockers only) _description: After suspend tests (integrated GPU, certification blockers only) include: - graphics/1_switch_card_.*_xenial certification-status=blocker - suspend/1_resolution_before_suspend_.*_xenial certification-status=blocker + graphics/1_auto_switch_card_.* certification-status=blocker + suspend/1_resolution_before_suspend_.*_auto certification-status=blocker suspend/suspend_advanced certification-status=blocker power-management/lid certification-status=blocker power-management/lid_close certification-status=blocker power-management/lid_open certification-status=blocker - suspend/1_compiz_check_after_suspend_.*_xenial certification-status=blocker - suspend/1_driver_version_after_suspend_.*_xenial certification-status=blocker - suspend/1_resolution_after_suspend_.*_xenial certification-status=blocker - suspend/1_display_after_suspend_.*_xenial certification-status=blocker - suspend/1_glxgears_after_suspend_.*_xenial certification-status=blocker - suspend/1_video_after_suspend_.*_xenial certification-status=blocker + suspend/1_compiz_check_after_suspend_.*_auto certification-status=blocker + suspend/1_driver_version_after_suspend_.*_auto certification-status=blocker + suspend/1_resolution_after_suspend_.*_auto certification-status=blocker + suspend/1_display_after_suspend_.*_auto certification-status=blocker + suspend/1_glxgears_after_suspend_.*_auto certification-status=blocker + suspend/1_video_after_suspend_.*_auto certification-status=blocker after-suspend-manual-monitor/1_dim_brightness_.* certification-status=blocker id: after-suspend-graphics-discrete-gpu-cert-blockers @@ -185,12 +185,12 @@ unit: test plan _name: After suspend tests (discrete GPU, certification blockers only) _description: After suspend tests (discrete GPU, certification blockers only) include: - suspend/2_resolution_before_suspend_.*_xenial certification-status=blocker - suspend/2_suspend_after_switch_to_card_.*_xenial certification-status=blocker - suspend/2_compiz_check_after_suspend_.*_xenial certification-status=blocker - suspend/2_driver_version_after_suspend_.*_xenial certification-status=blocker - suspend/2_resolution_after_suspend_.*_xenial certification-status=blocker - suspend/2_display_after_suspend_.*_xenial certification-status=blocker - suspend/2_glxgears_after_suspend_.*_xenial certification-status=blocker - suspend/2_video_after_suspend_.*_xenial certification-status=blocker - after-suspend-manual-monitor/2_dim_brightness_.* certification-status=blocker + suspend/2_resolution_before_suspend_.*_auto certification-status=blocker + suspend/2_suspend_after_switch_to_card_.*_auto certification-status=blocker + suspend/2_compiz_check_after_suspend_.*_auto certification-status=blocker + suspend/2_driver_version_after_suspend_.*_auto certification-status=blocker + suspend/2_resolution_after_suspend_.*_auto certification-status=blocker + suspend/2_display_after_suspend_.*_auto certification-status=blocker + suspend/2_glxgears_after_suspend_.*_auto certification-status=blocker + suspend/2_video_after_suspend_.*_auto certification-status=blocker + after-suspend-manual-monitor/2_dim_brightness_.* certification-status=blocker diff --git a/units/info/jobs.pxu b/units/info/jobs.pxu index 3170566..93ccd92 100644 --- a/units/info/jobs.pxu +++ b/units/info/jobs.pxu @@ -310,7 +310,7 @@ _description: Lists the device driver and version for all audio devices. plugin: attachment category_id: com.canonical.plainbox::info id: info/network_devices -command: network_device_info +command: network_device_info.py info estimated_duration: 0.550 _description: Provides information about network devices diff --git a/units/led/test-plan.pxu b/units/led/test-plan.pxu index 0329717..40f5697 100644 --- a/units/led/test-plan.pxu +++ b/units/led/test-plan.pxu @@ -25,10 +25,13 @@ include: led/battery-charged led/battery-charging led/battery-low - camera/led_.* - led/caps-lock - led/power - led/touchpad + camera/led_.* certification-status=blocker + led/caps-lock certification-status=blocker + led/numeric-keypad certification-status=blocker + led/power certification-status=blocker + led/bluetooth certification-status=non-blocker + led/wlan certification-status=non-blocker + led/wlan-disabled certification-status=non-blocker bootstrap_include: device @@ -52,10 +55,13 @@ include: suspend/led_after_suspend/battery-charged suspend/led_after_suspend/battery-charging suspend/led_after_suspend/battery-low - after-suspend-manual-camera/led_.* - suspend/led_after_suspend/caps-lock - suspend/led_after_suspend/power - suspend/led_after_suspend/touchpad + after-suspend-manual-camera/led_.* certification-status=blocker + suspend/led_after_suspend/caps-lock certification-status=blocker + suspend/led_after_suspend/numeric-keypad certification-status=blocker + suspend/led_after_suspend/power certification-status=blocker + suspend/led_after_suspend/bluetooth certification-status=non-blocker + suspend/led_after_suspend/wlan certification-status=non-blocker + suspend/led_after_suspend/wlan-disabled certification-status=non-blocker bootstrap_include: device diff --git a/units/oob-management/jobs.pxu b/units/oob-management/jobs.pxu index 5615a65..cf3ebd1 100644 --- a/units/oob-management/jobs.pxu +++ b/units/oob-management/jobs.pxu @@ -113,14 +113,14 @@ plugin: shell template-engine: jinja2 requires: {%- if __on_ubuntucore__ %} - # TODO: name is a guess until snap provided + {# TODO: name is a guess until snap provided #} snap.name == 'lms' {%- else %} package.name == 'lms' {% endif -%} command: {%- if __on_ubuntucore__ %} - # TODO: name is a guess until snap provided + {# TODO: name is a guess until snap provided #} SERVICE_NAME="snap.lms.lms.service" {%- else %} SERVICE_NAME="lms.service" diff --git a/units/stress/jobs.pxu b/units/stress/jobs.pxu index 261a0a3..756d537 100644 --- a/units/stress/jobs.pxu +++ b/units/stress/jobs.pxu @@ -71,7 +71,7 @@ id: power-management/suspend_30_cycles_with_reboots estimated_duration: 5400.0 depends: power-management/rtc - suspend/suspend_advanced + suspend/suspend_advanced_auto requires: executable.name == 'x-terminal-emulator' flags: noreturn @@ -79,8 +79,16 @@ user: root environ: PM_TEST_DRY_RUN command: pm_test reboot --checkbox-respawn-cmd $PLAINBOX_SESSION_SHARE/__respawn_checkbox --fwts --log-level=debug --log-dir=$PLAINBOX_SESSION_SHARE --suspends-before-reboot=30 -r 3 --silent --check-hardware-list +_summary: 30 suspend/resume cycles and 1 reboot, 3 times (automated stress test) _description: This is an automated stress test that will run a sequence of '30 suspend/resume cycles and one reboot' 3 times. +_siblings: [ + { "id": "power-management/suspend_30_cycles_with_coldboots", + "command": "pm_test poweroff --checkbox-respawn-cmd $PLAINBOX_SESSION_SHARE/__respawn_checkbox --fwts --log-level=debug --log-dir=$PLAINBOX_SESSION_SHARE --suspends-before-reboot=30 -r 3 --silent --check-hardware-list", + "_description": "This is an automated stress test that will run a sequence of '30 suspend/resume cycles and one poweroff' 3 times.", + "_summary": "30 suspend/resume cycles and 1 poweroff, 3 times (automated stress test)" + } + ] plugin: shell category_id: com.canonical.plainbox::stress @@ -118,8 +126,17 @@ id: power-management/suspend-30-cycles-log-check-with-reboots depends: power-management/suspend_30_cycles_with_reboots estimated_duration: 1.0 command: [ -e $PLAINBOX_SESSION_SHARE/pm_test.reboot.3.log ] && sleep_test_log_check -v s3 $PLAINBOX_SESSION_SHARE/pm_test.reboot.3.log +_summary: 30 suspend/resume cycles and 1 reboot, 3 times (check logs for errors) _description: Automated check of the '30 cycle suspend and 1 reboot times 3' logs for errors detected by fwts. +_siblings: [ + { "id": "power-management/suspend-30-cycles-log-check-with-coldboots", + "depends": "power-management/suspend_30_cycles_with_coldboots", + "command": "[ -e $PLAINBOX_SESSION_SHARE/pm_test.poweroff.3.log ] && sleep_test_log_check -v s3 $PLAINBOX_SESSION_SHARE/pm_test.poweroff.3.log", + "_description": "Automated check of the '30 cycle suspend and 1 poweroff times 3' logs for errors detected by fwts.", + "_summary": "30 suspend/resume cycles and 1 poweroff, 3 times (check logs for errors)" + } + ] plugin: attachment category_id: com.canonical.plainbox::stress @@ -136,8 +153,17 @@ id: power-management/suspend-30-cycle-log-attach-with-reboots estimated_duration: 1.0 depends: power-management/suspend_30_cycles_with_reboots command: [ -e $PLAINBOX_SESSION_SHARE/pm_test.reboot.3.log ] && cat $PLAINBOX_SESSION_SHARE/pm_test.reboot.3.log +_summary: 30 suspend/resume cycles and 1 reboot, 3 times (attach logs) _description: - Attaches the log from the '30 cycle Suspend/Resume and one reboot times 3' test if it exists + Attaches the log from the '30 cycle suspend/resume and one reboot times 3' test if it exists +_siblings: [ + { "id": "power-management/suspend-30-cycle-log-attach-with-coldboots", + "depends": "power-management/suspend_30_cycles_with_coldboots", + "command": "[ -e $PLAINBOX_SESSION_SHARE/pm_test.poweroff.3.log ] && cat $PLAINBOX_SESSION_SHARE/pm_test.poweroff.3.log", + "_description": "Attaches the log from the '30 cycle Suspend/Resume and one poweroff times 3' test if it exists", + "_summary": "30 suspend/resume cycles and 1 poweroff, 3 times (attach logs)" + } + ] plugin: shell category_id: com.canonical.plainbox::stress @@ -154,8 +180,17 @@ id: power-management/suspend-30-cycles-time-check-with-reboots estimated_duration: 1.0 depends: power-management/suspend_30_cycles_with_reboots command: [ -e $PLAINBOX_SESSION_SHARE/pm_test.reboot.3.log ] && sleep_time_check $PLAINBOX_SESSION_SHARE/pm_test.reboot.3.log +_summary: 30 suspend/resume cycles and 1 reboot, 3 times (check logs for timing issues) _description: - Checks the sleep times to ensure that a machine suspends and resumes within a given threshold + Checks the sleep times to ensure that a machine suspends and resumes within a given threshold (warm boots) +_siblings: [ + { "id": "power-management/suspend-30-cycles-time-check-with-coldboots", + "depends": "power-management/suspend_30_cycles_with_coldboots", + "command": "[ -e $PLAINBOX_SESSION_SHARE/pm_test.poweroff.3.log ] && sleep_time_check $PLAINBOX_SESSION_SHARE/pm_test.poweroff.3.log", + "_description": "Checks the sleep times to ensure that a machine suspends and resumes within a given threshold (cold boots)", + "_summary": "30 suspend/resume cycles and 1 poweroff, 3 times (check logs for timing issues)" + } + ] plugin: shell category_id: com.canonical.plainbox::stress diff --git a/units/stress/test-plan.pxu b/units/stress/test-plan.pxu index 2f6ff8b..8e7929a 100644 --- a/units/stress/test-plan.pxu +++ b/units/stress/test-plan.pxu @@ -51,6 +51,16 @@ include: power-management/suspend-30-cycle-log-attach-with-reboots power-management/suspend-30-cycles-time-check-with-reboots +id: stress-suspend-30-cycles-with-coldboots-automated +unit: test plan +_name: Suspend stress tests (with coldboots) +_description: Suspend stress tests (with coldboots) +include: + power-management/suspend_30_cycles_with_coldboots + power-management/suspend-30-cycles-log-check-with-coldboots + power-management/suspend-30-cycle-log-attach-with-coldboots + power-management/suspend-30-cycles-time-check-with-coldboots + id: stress-hibernate-30-cycles-automated unit: test plan _name: Hibernate stress tests diff --git a/units/suspend/suspend-graphics.pxu b/units/suspend/suspend-graphics.pxu index 43a7246..be820a7 100644 --- a/units/suspend/suspend-graphics.pxu +++ b/units/suspend/suspend-graphics.pxu @@ -3,8 +3,8 @@ template-resource: graphics_card template-filter: graphics_card.prime_gpu_offload == 'Off' plugin: shell category_id: com.canonical.plainbox::suspend -id: suspend/{index}_resolution_before_suspend_{product_slug}_xenial -after: graphics/{index}_switch_card_{product_slug}_xenial +id: suspend/{index}_resolution_before_suspend_{product_slug}_auto +after: graphics/{index}_auto_switch_card_{product_slug} estimated_duration: 1.2 _description: Record the current resolution before suspending. command: @@ -16,11 +16,11 @@ template-resource: graphics_card template-filter: graphics_card.prime_gpu_offload == 'Off' plugin: user-interact-verify category_id: com.canonical.plainbox::suspend -id: suspend/{index}_suspend_after_switch_to_card_{product_slug}_xenial +id: suspend/{index}_suspend_after_switch_to_card_{product_slug}_auto requires: sleep.mem == 'supported' rtc.state == 'supported' -after: graphics/{index}_switch_card_{product_slug}_xenial +after: graphics/{index}_auto_switch_card_{product_slug} user: root environ: PLAINBOX_SESSION_SHARE command: @@ -52,12 +52,12 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: shell category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_resolution_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_resolution_after_suspend_{{ product_slug }}_auto estimated_duration: 1.2 depends: - suspend/{{ index }}_resolution_before_suspend_{{ product_slug }}_xenial + suspend/{{ index }}_resolution_before_suspend_{{ product_slug }}_auto {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -72,10 +72,10 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: manual category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_display_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_display_after_suspend_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -94,11 +94,11 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: user-interact-verify category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_cycle_resolutions_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_cycle_resolutions_after_suspend_{{ product_slug }}_auto requires: package.name == 'xorg' depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -119,8 +119,8 @@ template-resource: graphics_card template-filter: graphics_card.prime_gpu_offload == 'Off' plugin: attachment category_id: com.canonical.plainbox::suspend -id: suspend/{index}_xrandr_screens_after_suspend.tar.gz_xenial -depends: suspend/{index}_cycle_resolutions_after_suspend_{product_slug}_xenial +id: suspend/{index}_xrandr_screens_after_suspend.tar.gz_auto +depends: suspend/{index}_cycle_resolutions_after_suspend_{product_slug}_auto command: [ -f $PLAINBOX_SESSION_SHARE/{index}_xrandr_screens_after_suspend.tgz ] && cat $PLAINBOX_SESSION_SHARE/{index}_xrandr_screens_after_suspend.tgz _description: This attaches screenshots from the suspend/cycle_resolutions_after_suspend test to the results submission. @@ -130,10 +130,10 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: shell category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_compiz_check_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_compiz_check_after_suspend_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -150,10 +150,10 @@ template-resource: graphics_card template-engine: jinja2 plugin: user-interact-verify category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_glxgears_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_glxgears_after_suspend_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -176,10 +176,10 @@ _description: unit: template template-resource: graphics_card template-engine: jinja2 -id: suspend/{{ index }}_video_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_video_after_suspend_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -206,10 +206,10 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: shell category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_driver_version_after_suspend_{{ product_slug }}_xenial +id: suspend/{{ index }}_driver_version_after_suspend_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -226,10 +226,10 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: attachment category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_suspend-single-log-attach_{{ product_slug }}_xenial +id: suspend/{{ index }}_suspend-single-log-attach_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} @@ -243,10 +243,10 @@ template-filter: graphics_card.prime_gpu_offload == 'Off' template-engine: jinja2 plugin: shell category_id: com.canonical.plainbox::suspend -id: suspend/{{ index }}_suspend-time-check_{{ product_slug }}_xenial +id: suspend/{{ index }}_suspend-time-check_{{ product_slug }}_auto depends: {%- if gpu_count > "1" %} - suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_xenial + suspend/{{ index }}_suspend_after_switch_to_card_{{ product_slug }}_auto {%- else %} suspend/suspend_advanced {%- endif %} diff --git a/units/suspend/test-plan.pxu b/units/suspend/test-plan.pxu index e7359c0..edc6aaa 100644 --- a/units/suspend/test-plan.pxu +++ b/units/suspend/test-plan.pxu @@ -22,8 +22,8 @@ include: keys/sleep certification-status=blocker suspend/oops_after_suspend certification-status=blocker suspend/oops_results_after_suspend.log - led/power-blink-suspend - led/suspend + led/power-blink-suspend certification-status=blocker + led/suspend certification-status=blocker id: before-suspend-reference-cert-automated unit: test plan diff --git a/units/wireless/jobs.pxu b/units/wireless/jobs.pxu index 52b2b01..b3d6604 100644 --- a/units/wireless/jobs.pxu +++ b/units/wireless/jobs.pxu @@ -7,7 +7,7 @@ id: wireless/wireless_scanning_{{ interface }} _summary: Test system can discover Wi-Fi networks on {{ interface }} command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test scan {{ interface }} + wifi_nmcli_test.py scan {{ interface }} plugin: shell category_id: com.canonical.plainbox::wireless estimated_duration: 6 @@ -31,7 +31,7 @@ _purpose: plugin: shell command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test secured {{ interface }} "$WPA_BG_SSID" "$WPA_BG_PSK" + wifi_nmcli_test.py secured {{ interface }} "$WPA_BG_SSID" "$WPA_BG_PSK" category_id: com.canonical.plainbox::wireless estimated_duration: 30.0 flags: preserve-locale also-after-suspend also-after-suspend-manual @@ -52,7 +52,7 @@ _purpose: plugin: shell command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test open {{ interface }} "$OPEN_BG_SSID" + wifi_nmcli_test.py open {{ interface }} "$OPEN_BG_SSID" category_id: com.canonical.plainbox::wireless estimated_duration: 30.0 flags: preserve-locale also-after-suspend also-after-suspend-manual @@ -73,7 +73,7 @@ _purpose: plugin: shell command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test secured {{ interface }} "$WPA_N_SSID" "$WPA_N_PSK" + wifi_nmcli_test.py secured {{ interface }} "$WPA_N_SSID" "$WPA_N_PSK" category_id: com.canonical.plainbox::wireless estimated_duration: 30.0 flags: preserve-locale also-after-suspend also-after-suspend-manual @@ -94,7 +94,7 @@ _purpose: plugin: shell command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test open {{ interface }} "$OPEN_N_SSID" + wifi_nmcli_test.py open {{ interface }} "$OPEN_N_SSID" category_id: com.canonical.plainbox::wireless estimated_duration: 30.0 flags: preserve-locale also-after-suspend also-after-suspend-manual @@ -115,7 +115,7 @@ _purpose: plugin: shell command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test secured {{ interface }} "$WPA_AC_SSID" "$WPA_AC_PSK" + wifi_nmcli_test.py secured {{ interface }} "$WPA_AC_SSID" "$WPA_AC_PSK" category_id: com.canonical.plainbox::wireless estimated_duration: 30.0 flags: preserve-locale also-after-suspend also-after-suspend-manual @@ -137,7 +137,7 @@ _purpose: plugin: shell command: net_driver_info $NET_DRIVER_INFO - wifi_nmcli_test open {{ interface }} "$OPEN_AC_SSID" + wifi_nmcli_test.py open {{ interface }} "$OPEN_AC_SSID" category_id: com.canonical.plainbox::wireless estimated_duration: 30.0 flags: preserve-locale also-after-suspend also-after-suspend-manual @@ -442,3 +442,31 @@ command: estimated_duration: 330.0 _description: Tests the performance of a system's wireless connection through the iperf tool, using UDP packets. + + +unit: template +template-resource: device +template-filter: device.category == 'WIRELESS' and device.interface != 'UNKNOWN' +id: wireless/nm_connection_save_{interface} +category_id: com.canonical.plainbox::wireless +_summary: Save any NetworkManager 802.11 configurations prior to testing +plugin: shell +user: root +command: + wifi_nmcli_backup.py save +estimated_duration: 2.0 +flags: preserve-locale also-after-suspend also-after-suspend-manual + +unit: template +template-resource: device +template-filter: device.category == 'WIRELESS' and device.interface != 'UNKNOWN' +id: wireless/nm_connection_restore_{interface} +category_id: com.canonical.plainbox::wireless +_summary: Restore any NetworkManager 802.11 configurations after testing +plugin: shell +user: root +command: + wifi_nmcli_backup.py restore +estimated_duration: 2.0 +depends: wireless/nm_connection_save_{interface} +flags: preserve-locale also-after-suspend also-after-suspend-manual diff --git a/units/wireless/nm-hotspot.pxu b/units/wireless/nm-hotspot.pxu new file mode 100644 index 0000000..5ffbe2b --- /dev/null +++ b/units/wireless/nm-hotspot.pxu @@ -0,0 +1,42 @@ + +unit: template +template-resource: device +template-filter: device.category == 'WIRELESS' and device.interface != 'UNKNOWN' +template-engine: jinja2 +template-unit: job +id: wireless/nmcli_wifi_ap_bg_{{ interface }} +_summary: Create 802.11b/g Wi-Fi AP on {{ interface }} using NetworkManager +command: + net_driver_info $NET_DRIVER_INFO + wifi_nmcli_test.py ap {{ interface }} bg +plugin: shell +category_id: com.canonical.plainbox::wireless +estimated_duration: 10 +flags: preserve-locale also-after-suspend +requires: + {%- if __on_ubuntucore__ %} + connections.slot == 'network-manager:service' and connections.plug == '{{ __system_env__["SNAP_NAME"] }}:network-manager' + {%- else %} + executable.name == 'nmcli' + {% endif -%} + +unit: template +template-resource: device +template-filter: device.category == 'WIRELESS' and device.interface != 'UNKNOWN' +template-engine: jinja2 +template-unit: job +id: wireless/nmcli_wifi_ap_a_{{ interface }} +_summary: Create 802.11a Wi-Fi AP on {{ interface }} using NetworkManager +command: + net_driver_info $NET_DRIVER_INFO + wifi_nmcli_test.py ap {{ interface }} a +plugin: shell +category_id: com.canonical.plainbox::wireless +estimated_duration: 10 +flags: preserve-locale also-after-suspend +requires: + {%- if __on_ubuntucore__ %} + connections.slot == 'network-manager:service' and connections.plug == '{{ __system_env__["SNAP_NAME"] }}:network-manager' + {%- else %} + executable.name == 'nmcli' + {% endif -%} \ No newline at end of file diff --git a/units/wireless/test-plan.pxu b/units/wireless/test-plan.pxu index 74bf271..8b4aafe 100644 --- a/units/wireless/test-plan.pxu +++ b/units/wireless/test-plan.pxu @@ -30,7 +30,10 @@ id: wireless-cert-automated unit: test plan _name: Wireless tests _description: Wireless connection tests +bootstrap_include: + device include: + wireless/nm_connection_save_.* wireless/wireless_scanning_.* certification-status=blocker wireless/wireless_connection_wpa_bg_nm_.* certification-status=blocker wireless/wireless_connection_open_bg_nm_.* certification-status=blocker @@ -38,36 +41,48 @@ include: wireless/wireless_connection_open_n_nm_.* certification-status=blocker wireless/wireless_connection_wpa_ac_nm_.* certification-status=blocker wireless/wireless_connection_open_ac_nm_.* certification-status=blocker + wireless/nm_connection_restore_.* id: after-suspend-wireless-cert-automated unit: test plan _name: Wireless tests (after suspend, automated) _description: Wireless connection tests (after suspend, automated) +bootstrap_include: + device include: + after-suspend-wireless/nm_connection_save_.* after-suspend-wireless/wireless_connection_wpa_bg_nm_.* certification-status=blocker after-suspend-wireless/wireless_connection_open_bg_nm_.* certification-status=blocker after-suspend-wireless/wireless_connection_wpa_n_nm_.* certification-status=blocker after-suspend-wireless/wireless_connection_open_n_nm_.* certification-status=blocker after-suspend-wireless/wireless_connection_wpa_ac_nm_.* certification-status=blocker after-suspend-wireless/wireless_connection_open_ac_nm_.* certification-status=blocker + after-suspend-wireless/nm_connection_restore_.* id: after-suspend-manual-wireless-cert-automated unit: test plan _name: Wireless tests (after manual suspend, automated) _description: Wireless connection tests (after manual suspend, automated) +bootstrap_include: + device include: + after-suspend-manual-wireless/nm_connection_save_.* after-suspend-manual-wireless/wireless_connection_wpa_bg_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_open_bg_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_wpa_n_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_open_n_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_wpa_ac_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_open_ac_nm_.* certification-status=blocker + after-suspend-manual-wireless/nm_connection_restore_.* id: wireless-cert-blockers unit: test plan _name: Wireless tests (certification blockers only) _description: Wireless connection tests (certification blockers only) +bootstrap_include: + device include: + wireless/nm_connection_save_.* wireless/wireless_scanning_.* certification-status=blocker wireless/wireless_connection_wpa_bg_nm_.* certification-status=blocker wireless/wireless_connection_open_bg_nm_.* certification-status=blocker @@ -75,16 +90,21 @@ include: wireless/wireless_connection_open_n_nm_.* certification-status=blocker wireless/wireless_connection_wpa_ac_nm_.* certification-status=blocker wireless/wireless_connection_open_ac_nm_.* certification-status=blocker + wireless/nm_connection_restore_.* id: after-suspend-wireless-cert-blockers unit: test plan _name: Wireless tests (after manual suspend, certification blockers only) _description: Wireless connection tests (after manual suspend, certification blockers only) +bootstrap_include: + device include: + after-suspend-manual-wireless/nm_connection_save_.* after-suspend-manual-wireless/wireless_connection_wpa_bg_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_open_bg_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_wpa_n_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_open_n_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_wpa_ac_nm_.* certification-status=blocker after-suspend-manual-wireless/wireless_connection_open_ac_nm_.* certification-status=blocker + after-suspend-manual-wireless/nm_connection_restore_.* |