summaryrefslogtreecommitdiff
path: root/bin
diff options
authorPMR <pmr@pmr-lander>2020-05-28 15:21:24 +0000
committerPMR <pmr@pmr-lander>2020-05-28 15:21:24 +0000
commit7bded3d298d997d2b84fdbc8e6a1d0d906f62770 (patch)
treedb739742b2ada88df2dd2f30b712b57cab0b8777 /bin
parent5bb77b16f3a4eec58db991e5717b2408f555978a (diff)
Import plainbox-provider-checkbox_0.54.0~rc1.orig.tar.gzupstream-0.54.0_rc1patched-0.54.0_rc1-1
Diffstat (limited to 'bin')
-rwxr-xr-xbin/audio_test6
-rwxr-xr-xbin/check-prerelease89
-rwxr-xr-xbin/frequency_governors_test27
-rwxr-xr-xbin/gst_pipeline_test4
-rwxr-xr-xbin/mac_passthrough.py119
-rwxr-xr-xbin/network10
-rwxr-xr-xbin/removable_storage_test7
7 files changed, 201 insertions, 61 deletions
diff --git a/bin/audio_test b/bin/audio_test
index 466b760..7bd6c44 100755
--- a/bin/audio_test
+++ b/bin/audio_test
@@ -24,6 +24,10 @@ except ImportError:
print((sys.version), file=sys.stderr)
sys.exit(127)
+try:
+ from collections.abc import Callable
+except ImportError:
+ from collections import Callable # backward compatible
#Frequency bands for FFT
BINS = 256
@@ -124,7 +128,7 @@ class PAVolumeController(object):
self._volume = None
self.identifier = None
self.method = method
- if not isinstance(method, collections.Callable):
+ if not isinstance(method, Callable):
self.method = self._pactl_output
self.logger = logger
diff --git a/bin/check-prerelease b/bin/check-prerelease
index 1f3d017..5e24902 100755
--- a/bin/check-prerelease
+++ b/bin/check-prerelease
@@ -32,7 +32,7 @@ import platform
import shlex
import sys
-from subprocess import Popen, PIPE
+from subprocess import CalledProcessError, check_output
def check_kernel_status():
@@ -43,37 +43,47 @@ def check_kernel_status():
"""
kernel_release = platform.release()
- retval = False
- command = "apt-cache show linux-image-{}".format(kernel_release)
- aptinfo = []
- aptinfo_bytes = (Popen(shlex.split(command), stdout=PIPE)
- .communicate()[0])
- aptinfo = (aptinfo_bytes.decode(encoding="utf-8", errors="ignore")
- .splitlines())
-
- """Kernel apt-cache info includes a 'Supported:' line on release
- kernels to identify the period of support. This line is missing on
- pre-release kernels. Thus, we return a True value only if this
- line is present and shows a 5-year support period."""
- if any("Supported: 5y" in s for s in aptinfo):
- retval = True
- if any("Supported: 9m" in s for s in aptinfo):
- print("* Kernel is supported for 9 months; it is an interim release!")
- if not any("Supported:" in s for s in aptinfo):
- print("* Could not find a kernel support period; "
- "may be a pre-release kernel!")
-
- """We also want to exclude 'edge' kernels, which are identified via
- the 'Source:' line in the apt-cache output...."""
- if any("Source: linux-signed-hwe-edge" in s for s in aptinfo):
+ retval = True
+ command = "apt-cache showpkg linux-image-{}".format(kernel_release)
+ aptinfo = check_output(shlex.split(command), universal_newlines=True)
+
+ # Exclude kernels that come from obvious PPAs....
+ if "ppa.launchpad.net" in aptinfo:
+ print("* Kernel appears to have come from a PPA!")
+ retval = False
+
+ # Exclude kernels that don't come from the main repo
+ if "main_binary" not in aptinfo:
+ print("* Kernel does not come from the main Ubuntu repository!")
+ retval = False
+
+ try:
+ command = "apt-cache show linux-image-{}".format(kernel_release)
+ aptinfo = check_output(shlex.split(command), universal_newlines=True)
+ except CalledProcessError:
+ # "apt-cache show" returns an error status if called on a
+ # non-existent package.
+ print("* Kernel does not match any installed package!")
+ aptinfo = ""
+ retval = False
+
+ # Exclude 'edge' kernels, which are identified via the 'Source:' line
+ # in the apt-cache show output....
+ if "Source: linux-signed-hwe-edge" in aptinfo:
print("* Kernel is an 'edge' kernel!")
retval = False
- if any("Source: linux-hwe-edge" in s for s in aptinfo):
+ if "Source: linux-hwe-edge" in aptinfo:
print("* Kernel is an 'edge' kernel!")
retval = False
- """We also want to exclude low-latency kernels, which are identified
- via the kernel name string itself...."""
+ # Exclude kernels that aren't from the "linux" (or variant, like
+ # "linux-hwe" or "linux-signed") source....
+ if "Source: linux" not in aptinfo:
+ print("* Kernel is not a Canonical kernel!")
+ retval = False
+
+ # Exclude low-latency kernels, which are identified via the kernel name
+ # string itself....
if "lowlatency" in kernel_release:
print("* Kernel is a low-latency kernel!")
retval = False
@@ -86,30 +96,29 @@ def check_kernel_status():
def check_os_status():
- """Check OS to see if it's supported for certification. Note that this
- passes any release version (even a non-LTS version), but not pre-release
- versions.
+ """Check OS to see if it's supported for certification. The OS must be
+ BOTH an LTS version and a non-development branch to pass this test.
:returns:
True if OK, False if not
"""
retval = True
command = "lsb_release -s -d"
- lsbinfo = []
- lsbinfo_bytes = (Popen(shlex.split(command), stdout=PIPE)
- .communicate()[0])
- lsbinfo = (lsbinfo_bytes.decode(encoding="utf-8", errors="ignore")
- .rstrip())
-
- """OS information include '(development branch)' on pre-release
- installations. Such installations should fail this test."""
+ lsbinfo = check_output(shlex.split(command), universal_newlines=True)
+
+ # OS information include '(development branch)' on pre-release
+ # installations. Such installations should fail this test.
if "(development branch)" in lsbinfo:
- print("* 'lsb_release -s -d' result is '{}'".format(lsbinfo))
print("* OS is reported as a development branch:")
print("* {}".format(lsbinfo))
retval = False
print("")
+ if "LTS" not in lsbinfo:
+ print("* OS is a non-LTS version:")
+ print("* {}".format(lsbinfo))
+ retval = False
+
return retval
@@ -126,7 +135,7 @@ def main():
elif (retval == 1):
print("** Test FAILS; running ineligible kernel!")
elif (retval == 2):
- print("** Test FAILS; running pre-release OS!")
+ print("** Test FAILS; running pre-release or non-LTS OS!")
else:
print("** Test FAILS; running pre-release OS with ineligible kernel!")
diff --git a/bin/frequency_governors_test b/bin/frequency_governors_test
index 2b8661e..6072ded 100755
--- a/bin/frequency_governors_test
+++ b/bin/frequency_governors_test
@@ -23,6 +23,8 @@ class CPUScalingTest(object):
self.idaSpeedupFactor = 8.0 # percent
self.selectorExe = "cpufreq-selector"
self.ifSelectorExe = None
+ self.minFreq = None
+ self.maxFreq = None
def getCPUFreqDirectories(self):
logging.debug("Getting CPU Frequency Directories")
@@ -43,7 +45,7 @@ class CPUScalingTest(object):
return None
# otherwise
self.cpufreqDirectories.append(cpufreqDirectory)
- if len(self.cpufreqDirectories) is 0:
+ if len(self.cpufreqDirectories) == 0:
return None
# otherwise
logging.debug("Located the following CPU Freq Directories:")
@@ -279,16 +281,17 @@ class CPUScalingTest(object):
logging.info("System has %u cpus" % len(self.cpufreqDirectories))
# Ensure all CPUs support the same frequencies
- freqFileName = "scaling_available_frequencies"
- self.frequencies = self.checkParameters(freqFileName)
- if not self.frequencies:
+ freqFileName = "scaling_min_freq"
+ self.minFreq = int(self.checkParameters(freqFileName)[0])
+ if not self.minFreq:
return False
-
- logging.info("Supported CPU Frequencies: ")
- for freq in self.frequencies:
- f = int(freq) / 1000
- logging.info(" %u MHz" % f)
-
+ freqFileName = "scaling_max_freq"
+ self.maxFreq = int(self.checkParameters(freqFileName)[0])
+ if not self.maxFreq:
+ return False
+ logging.info(
+ "Supported CPU Frequencies: %s - %s MHz",
+ self.minFreq / 1000, self.maxFreq / 1000)
# Check governors to verify all CPUs support the same control methods
governorFileName = "scaling_available_governors"
self.governors = self.checkParameters(governorFileName)
@@ -352,7 +355,7 @@ class CPUScalingTest(object):
success = False
# Set the the CPU speed to it's lowest value
- frequency = self.frequencies[-1]
+ frequency = self.minFreq
logging.info("Setting CPU frequency to %u MHz" % (int(frequency) / 1000))
if not self.setFrequency(frequency):
success = False
@@ -377,7 +380,7 @@ class CPUScalingTest(object):
% self.minimumFrequencyTestTime)
# Set the CPU speed to it's highest value as above.
- frequency = self.frequencies[0]
+ frequency = self.maxFreq
logging.info("Setting CPU frequency to %u MHz" % (int(frequency) / 1000))
if not self.setFrequency(frequency):
success = False
diff --git a/bin/gst_pipeline_test b/bin/gst_pipeline_test
index f6b6703..c7a9af5 100755
--- a/bin/gst_pipeline_test
+++ b/bin/gst_pipeline_test
@@ -22,8 +22,8 @@ def check_state(device):
data = sink_info.split("\n")
try:
- device_name = re.findall(".*Name:\s.*%s.*" % device, sink_info)[0].lstrip()
- sink = re.findall(".*Name:\s(.*%s.*)" % device, sink_info)[0].lstrip()
+ device_name = re.findall(".*Name:\s.*%s.*" % device, sink_info, re.IGNORECASE)[0].lstrip()
+ sink = re.findall(".*Name:\s(.*%s.*)" % device, sink_info, re.IGNORECASE)[0].lstrip()
status = data[data.index("\t" + device_name) - 1]
except (IndexError, ValueError):
logging.error("Failed to find status for device: %s" % device)
diff --git a/bin/mac_passthrough.py b/bin/mac_passthrough.py
new file mode 100755
index 0000000..92d2eb6
--- /dev/null
+++ b/bin/mac_passthrough.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright 2020 Canonical Ltd.
+# All rights reserved.
+#
+# Written by:
+# Nara Huang <nara.huang@canonical.com>
+#
+# Script to get system ethernet device MAC address, and from ACPI DSDT table,
+# grep "AUXMAC" to get pass-through MAC address,
+# then compare them to check if MAC address pass-through function is working
+import subprocess
+import glob
+import os
+import shutil
+MAC_PASS_SMBIOS_TOKEN = '0x49b'
+
+
+def get_system_mac():
+ """ Get mac addresses from ethernet devices
+ Returns:
+ List: Mac addresses of ethernet devices
+ """
+ mac_addresses = []
+ for interface in glob.glob("/sys/class/net/en*/address"):
+ try:
+ with open(interface, 'r') as iface:
+ mac = iface.read()
+ mac = mac.strip()
+ mac = mac.replace(':', '')
+ mac_addresses.append(mac)
+ except Exception as err:
+ raise SystemExit(err)
+ return mac_addresses
+ # Since system could have multiple ethernet interfaces,
+ # the return value is a list.
+
+
+def get_pass_through_mac():
+ """ Get pass-through mac address from BIOS ACPI DSDT table
+ iasl command is included in acpica-tools package
+ Returns:
+ String: Pass-through MAC address from DSDT table
+ """
+ tmp_path = os.environ.get("SNAP_USER_DATA", "/tmp")
+ aml_path = os.path.join(tmp_path, 'dsdt.aml')
+ dsl_path = os.path.join(tmp_path, 'dsdt.dsl')
+ try:
+ shutil.copy('/sys/firmware/acpi/tables/DSDT', aml_path)
+ subprocess.call(['iasl', '-d', aml_path], stdout=subprocess.DEVNULL,
+ stderr=subprocess.STDOUT)
+ with open(dsl_path, encoding='utf-8', errors='ignore') as dsl:
+ dsdt = dsl.readlines()
+ for line in dsdt:
+ if 'AUXMAC' in line:
+ bios_mac = line.split('#')[1]
+ print('Pass-through MAC address from DSDT table: '
+ + bios_mac.lower())
+ return bios_mac.lower()
+ raise SystemExit('No AUXMAC is found in DSDT table, '
+ 'MAC address pass-through is not working.')
+ except Exception as err:
+ raise SystemExit(err)
+
+
+def check_mac_passthrough(mac, bios_mac):
+ """ Compare pass-through MAC address from BIOS DSDT table
+ and system MAC address, to check if the pass-through function works.
+ Args:
+ mac: A list contains MAC addresses from system
+ bios_mac: A string of MAC address from BIOS DSDT table
+ """
+ if len(mac) == 2 and mac[0] == mac[1]:
+ print('AUXMAC in DSDT table is identical to onboard NIC MAC, which '
+ 'means in BIOS setting, it is set to '
+ '"Integrated NIC 1 MAC Address".')
+ return 0
+ if bios_mac in mac:
+ print('AUXMAC in DSDT table is passed to dock, MAC address '
+ 'pass-through is working.')
+ return 0
+ else:
+ raise SystemExit('MAC address pass-through is not working, '
+ 'maybe the dock is not connected?')
+ # If a system enables mac pass-through function,
+ # but not connected with a dock, it goes here.
+
+
+def check_smbios_token(index):
+ """ Check SMBIOS for BIOS MAC address pass-through setting.
+ If it shows "false", then the function is enabled in
+ BIOS setting.
+ This function requires command "smbios-token-ctl",
+ which comes with package "smbios-utils"
+ Args:
+ index: A string for SMBIOS token index
+ """
+ smbios_token_cmd = ['smbios-token-ctl', '--token-id=']
+ smbios_token_cmd[1] += index
+ try:
+ out = subprocess.check_output(smbios_token_cmd)
+ for line in out.decode("utf-8").splitlines():
+ if 'value: bool' in line:
+ if 'true' in line:
+ raise SystemExit('MAC address pass-through '
+ 'is disabled in BIOS setting.')
+ except Exception as err:
+ raise SystemExit(err)
+ print('MAC address pass-through is enabled in BIOS setting.')
+
+
+def main():
+ check_smbios_token(MAC_PASS_SMBIOS_TOKEN)
+ pasthrough_mac_addresses = get_pass_through_mac()
+ os_mac_addresses = get_system_mac()
+ check_mac_passthrough(os_mac_addresses, pasthrough_mac_addresses)
+
+
+if __name__ == '__main__':
+ raise SystemExit(main())
diff --git a/bin/network b/bin/network
index 5bdf1f0..fea7f72 100755
--- a/bin/network
+++ b/bin/network
@@ -252,16 +252,16 @@ class IPerfPerformanceTest(object):
cpu_load = 0
if percent < self.fail_threshold or \
cpu_load > self.cpu_load_fail_threshold:
- logging.warning("Poor network performance detected against {}".
+ logging.warning("The network test against {} failed because:".
format(self.target))
if percent < self.fail_threshold:
- logging.warning(" Transfer speed: {} Mb/s".
+ logging.error(" Transfer speed: {} Mb/s".
format(throughput))
- logging.warning(" {:03.2f}% of theoretical max {} Mb/s\n".
+ logging.error(" {:03.2f}% of theoretical max {} Mb/s\n".
format(percent, int(self.iface.max_speed)))
if cpu_load > self.cpu_load_fail_threshold:
- logging.warning(" CPU load: {}%".format(cpu_load))
- logging.warning(" CPU load is above {}% maximum\n".
+ logging.error(" CPU load: {}%".format(cpu_load))
+ logging.error(" CPU load is above {}% maximum\n".
format(self.cpu_load_fail_threshold))
return 30
diff --git a/bin/removable_storage_test b/bin/removable_storage_test
index bbace30..82f1595 100755
--- a/bin/removable_storage_test
+++ b/bin/removable_storage_test
@@ -249,7 +249,7 @@ class DiskTest():
UDISKS2_BLOCK_INTERFACE in interfaces):
# To be an IO candidate there must be a drive object
drive = interfaces[UDISKS2_BLOCK_INTERFACE].get('Drive:')
- if drive is None or drive is '/':
+ if drive is None or drive == '/':
continue
drive_object = udisks_devices[os.path.basename(drive)]
@@ -617,6 +617,11 @@ def main():
test = DiskTest(args.device, args.memorycard, args.lsblkcommand)
+ # LP:1876966
+ if os.getuid() != 0:
+ print("ERROR: This script must be run as root!")
+ return 1
+
errors = 0
# If we do have removable drives attached and mounted
if len(test.rem_disks) > 0 or len(test.rem_disks_nm) > 0: