summaryrefslogtreecommitdiff
diff options
authorSylvain Pineau <sylvain.pineau@canonical.com>2019-05-09 14:37:20 +0200
committerSylvain Pineau <sylvain.pineau@canonical.com>2019-05-09 14:37:20 +0200
commit9ac21efe28040e27b305095cf5f093746b5e94c8 (patch)
treea986e5d772bf1d1d6b3be6eee0792704a8ccd8e4
parent9ac6fd633170bb5b68e70726d21d6ce5dbd5274d (diff)
parent0ea5ae58375181992cbca691dc9bb35db71a6e67 (diff)
record new upstream branch created by importing plainbox-provider-checkbox_0.48.0~rc1.orig.tar.gz and merge it
-rwxr-xr-xbin/cpu_stress9
-rwxr-xr-xbin/disk_stats_test6
-rwxr-xr-xbin/disk_stress_ng8
-rwxr-xr-xbin/hotkey_tests.py439
-rwxr-xr-xbin/maas-version-check3
-rwxr-xr-xbin/memory_stress_ng8
-rwxr-xr-xbin/net_driver_info6
-rwxr-xr-xbin/network_device_info.py (renamed from bin/network_device_info)131
-rwxr-xr-xbin/removable_storage_test12
-rwxr-xr-xbin/sleep_time_check17
-rwxr-xr-xbin/storage_test9
-rwxr-xr-xbin/wifi_nmcli_backup.py79
-rwxr-xr-xbin/wifi_nmcli_test.py (renamed from bin/wifi_nmcli_test)81
-rw-r--r--debian/.git-dpm14
-rwxr-xr-xmanage.py2
-rw-r--r--units/dock/jobs.pxu28
-rw-r--r--units/ethernet/jobs.pxu25
-rw-r--r--units/ethernet/manifest.pxu4
-rw-r--r--units/ethernet/test-plan.pxu24
-rw-r--r--units/gpgpu/category.pxu3
-rw-r--r--units/gpgpu/jobs.pxu8
-rw-r--r--units/gpgpu/test-plan.pxu8
-rw-r--r--units/graphics/test-plan.pxu96
-rw-r--r--units/info/jobs.pxu2
-rw-r--r--units/led/test-plan.pxu22
-rw-r--r--units/oob-management/jobs.pxu4
-rw-r--r--units/stress/jobs.pxu41
-rw-r--r--units/stress/test-plan.pxu10
-rw-r--r--units/suspend/suspend-graphics.pxu50
-rw-r--r--units/suspend/test-plan.pxu4
-rw-r--r--units/wireless/jobs.pxu42
-rw-r--r--units/wireless/nm-hotspot.pxu42
-rw-r--r--units/wireless/test-plan.pxu20
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
diff --git a/manage.py b/manage.py
index 764e61f..1f5070b 100755
--- a/manage.py
+++ b/manage.py
@@ -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_.*