aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2023-03-27 17:43:56 +0300
committerGitHub <noreply@github.com>2023-03-27 17:43:56 +0300
commitfad9423ae3c64bfd48c207de34a1177000d45fa8 (patch)
tree029968890d65f01d2de102c754575cdcec189fd8
parentf6c0dbf63842d5751000c5527808aca38354db55 (diff)
parente0204ebca1486eb7e174ccca15bfed6d3ad64e36 (diff)
downloadcros-ec-tests-main.tar.gz
Merge pull request #1 from penvirus/for-clean-upmain
For clean up
-rw-r--r--cros/helpers/ec_cmd.py143
-rw-r--r--cros/helpers/kernel.py13
-rw-r--r--cros/helpers/mcu.py220
-rw-r--r--[-rwxr-xr-x]cros/helpers/sysfs.py41
-rw-r--r--[-rwxr-xr-x]cros/runners/lava_runner.py101
-rw-r--r--cros/tests/__init__.py7
-rw-r--r--[-rwxr-xr-x]cros/tests/cros_ec_accel.py75
-rw-r--r--[-rwxr-xr-x]cros/tests/cros_ec_extcon.py36
-rw-r--r--cros/tests/cros_ec_gyro.py9
-rw-r--r--cros/tests/cros_ec_mcu.py69
-rw-r--r--cros/tests/cros_ec_power.py3
-rw-r--r--cros/tests/cros_ec_pwm.py62
-rw-r--r--[-rwxr-xr-x]cros/tests/cros_ec_rtc.py54
-rw-r--r--docs/source/testhelpers.rst4
-rw-r--r--setup.py2
15 files changed, 377 insertions, 462 deletions
diff --git a/cros/helpers/ec_cmd.py b/cros/helpers/ec_cmd.py
new file mode 100644
index 0000000..dbcb565
--- /dev/null
+++ b/cros/helpers/ec_cmd.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+from ctypes import addressof
+from ctypes import c_ubyte, c_uint8, c_uint32, c_uint64
+from ctypes import memmove
+from ctypes import sizeof
+from ctypes import Structure
+import fcntl
+
+
+EC_HOST_PARAM_SIZE = 0xFC
+EC_DEV_IOCXCMD = 0xC014EC00 # _IOWR(EC_DEV_IOC, 0, struct cros_ec_command)
+
+# EC commands
+EC_CMD_PROTO_VERSION = 0x0000
+EC_CMD_HELLO = 0x0001
+EC_CMD_GET_VERSION = 0x0002
+EC_CMD_GET_FEATURES = 0x000D
+EC_CMD_REBOOT = 0x00D1
+
+ECFEATURES_CACHE = -1
+# EC features
+EC_FEATURE_LIMITED = 0
+EC_FEATURE_FLASH = 1
+EC_FEATURE_PWM_FAN = 2
+EC_FEATURE_PWM_KEYB = 3
+EC_FEATURE_LIGHTBAR = 4
+EC_FEATURE_LED = 5
+EC_FEATURE_MOTION_SENSE = 6
+EC_FEATURE_KEYB = 7
+EC_FEATURE_PSTORE = 8
+EC_FEATURE_PORT80 = 9
+EC_FEATURE_THERMAL = 10
+EC_FEATURE_BKLIGHT_SWITCH = 11
+EC_FEATURE_WIFI_SWITCH = 12
+EC_FEATURE_HOST_EVENTS = 13
+EC_FEATURE_GPIO = 14
+EC_FEATURE_I2C = 15
+EC_FEATURE_CHARGER = 16
+EC_FEATURE_BATTERY = 17
+EC_FEATURE_SMART_BATTERY = 18
+EC_FEATURE_HANG_DETECT = 19
+EC_FEATURE_PMU = 20
+EC_FEATURE_SUB_MCU = 21
+EC_FEATURE_USB_PD = 22
+EC_FEATURE_USB_MUX = 23
+EC_FEATURE_MOTION_SENSE_FIFO = 24
+EC_FEATURE_VSTORE = 25
+EC_FEATURE_USBC_SS_MUX_VIRTUAL = 26
+EC_FEATURE_RTC = 27
+EC_FEATURE_FINGERPRINT = 28
+EC_FEATURE_TOUCHPAD = 29
+EC_FEATURE_RWSIG = 30
+EC_FEATURE_DEVICE_EVENT = 31
+EC_FEATURE_UNIFIED_WAKE_MASKS = 32
+EC_FEATURE_HOST_EVENT64 = 33
+EC_FEATURE_EXEC_IN_RAM = 34
+EC_FEATURE_CEC = 35
+EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS = 36
+EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS = 37
+EC_FEATURE_SCP = 39
+EC_FEATURE_ISH = 40
+
+# enum ec_current_image
+EC_IMAGE_UNKNOWN = 0
+EC_IMAGE_RO = 1
+EC_IMAGE_RW = 2
+
+
+class cros_ec_command(Structure):
+ _fields_ = [
+ ("version", c_uint32),
+ ("command", c_uint32),
+ ("outsize", c_uint32),
+ ("insize", c_uint32),
+ ("result", c_uint32),
+ ("data", c_uint8 * EC_HOST_PARAM_SIZE),
+ ]
+
+
+class ec_params_hello(Structure):
+ _fields_ = [("in_data", c_uint32)]
+
+
+class ec_response_hello(Structure):
+ _fields_ = [("out_data", c_uint32)]
+
+
+class ec_response_get_version(Structure):
+ _fields_ = [
+ ("version_string_ro", c_ubyte * 32),
+ ("version_string_rw", c_ubyte * 32),
+ ("reserved", c_ubyte * 32),
+ ("current_image", c_uint32),
+ ]
+
+
+class ec_response_get_features(Structure):
+ _fields_ = [("in_data", c_uint64)]
+
+
+def EC_FEATURE_MASK_0(event_code):
+ return 1 << (event_code % 32)
+
+
+def EC_FEATURE_MASK_1(event_code):
+ return 1 << (event_code - 32)
+
+
+def is_feature_supported(feature):
+ """ Returns true if the Embedded Controller supports the specified
+ 'feature'.
+ """
+ global ECFEATURES_CACHE
+
+ if ECFEATURES_CACHE == -1:
+ param, response = None, ec_response_get_features()
+
+ cmd = send_ec_command("/dev/cros_ec", EC_CMD_GET_FEATURES, param, response)
+ if cmd.result == 0:
+ ECFEATURES_CACHE = response.in_data
+ else:
+ return False
+
+ return bool(ECFEATURES_CACHE & EC_FEATURE_MASK_0(feature))
+
+
+def send_ec_command(dev, command, param=None, resp=None):
+ cmd = cros_ec_command()
+ cmd.version = 0
+ cmd.command = command
+ cmd.outsize = 0 if param is None else sizeof(param)
+ cmd.insize = 0 if resp is None else sizeof(resp)
+
+ if cmd.outsize != 0:
+ memmove(addressof(cmd.data), addressof(param), cmd.outsize)
+ with open(dev) as fh:
+ fcntl.ioctl(fh, EC_DEV_IOCXCMD, cmd)
+ if cmd.insize != 0:
+ memmove(addressof(resp), addressof(cmd.data), cmd.insize)
+
+ return cmd
diff --git a/cros/helpers/kernel.py b/cros/helpers/kernel.py
index db0c69f..c3a29e2 100644
--- a/cros/helpers/kernel.py
+++ b/cros/helpers/kernel.py
@@ -14,9 +14,8 @@ def current_kernel_version():
""" Returns the current kernel version as an integer you can
compare.
"""
- fd = open("/proc/version", "r")
- current = fd.read().split()[2].split("-")[0].split(".")
- fd.close()
+ with open("/proc/version") as fh:
+ current = fh.read().split()[2].split("-")[0].split(".")
return version_to_int(int(current[0]), int(current[1]), int(current[2]))
@@ -24,15 +23,11 @@ def kernel_lower_than(version, major, minor):
""" Returns true if the given version is lower than the running kernel
version.
"""
- if version_to_int(version, major, minor) > current_kernel_version():
- return True
- return False
+ return current_kernel_version() < version_to_int(version, major, minor)
def kernel_greater_than(version, major, minor):
""" Returns true if the given version is greater than the running kernel
version.
"""
- if version_to_int(version, major, minor) < current_kernel_version():
- return True
- return False
+ return current_kernel_version() > version_to_int(version, major, minor)
diff --git a/cros/helpers/mcu.py b/cros/helpers/mcu.py
deleted file mode 100644
index 36d125b..0000000
--- a/cros/helpers/mcu.py
+++ /dev/null
@@ -1,220 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-import fcntl
-import os
-from cros.helpers.sysfs import *
-from ctypes import *
-
-EC_CMD_PROTO_VERSION = 0x0000
-EC_CMD_HELLO = 0x0001
-EC_CMD_GET_VERSION = 0x0002
-EC_CMD_GET_FEATURES = 0x000D
-EC_CMD_REBOOT = 0x00D1
-
-EC_HOST_PARAM_SIZE = 0xFC
-
-EC_DEV_IOCXCMD = 0xC014EC00 # _IOWR(EC_DEV_IOC, 0, struct cros_ec_command)
-
-ECFEATURES = -1
-# Supported features
-EC_FEATURE_LIMITED = 0
-EC_FEATURE_FLASH = 1
-EC_FEATURE_PWM_FAN = 2
-EC_FEATURE_PWM_KEYB = 3
-EC_FEATURE_LIGHTBAR = 4
-EC_FEATURE_LED = 5
-EC_FEATURE_MOTION_SENSE = 6
-EC_FEATURE_KEYB = 7
-EC_FEATURE_PSTORE = 8
-EC_FEATURE_PORT80 = 9
-EC_FEATURE_THERMAL = 10
-EC_FEATURE_BKLIGHT_SWITCH = 11
-EC_FEATURE_WIFI_SWITCH = 12
-EC_FEATURE_HOST_EVENTS = 13
-EC_FEATURE_GPIO = 14
-EC_FEATURE_I2C = 15
-EC_FEATURE_CHARGER = 16
-EC_FEATURE_BATTERY = 17
-EC_FEATURE_SMART_BATTERY = 18
-EC_FEATURE_HANG_DETECT = 19
-EC_FEATURE_PMU = 20
-EC_FEATURE_SUB_MCU = 21
-EC_FEATURE_USB_PD = 22
-EC_FEATURE_USB_MUX = 23
-EC_FEATURE_MOTION_SENSE_FIFO = 24
-EC_FEATURE_VSTORE = 25
-EC_FEATURE_USBC_SS_MUX_VIRTUAL = 26
-EC_FEATURE_RTC = 27
-EC_FEATURE_FINGERPRINT = 28
-EC_FEATURE_TOUCHPAD = 29
-EC_FEATURE_RWSIG = 30
-EC_FEATURE_DEVICE_EVENT = 31
-EC_FEATURE_UNIFIED_WAKE_MASKS = 32
-EC_FEATURE_HOST_EVENT64 = 33
-EC_FEATURE_EXEC_IN_RAM = 34
-EC_FEATURE_CEC = 35
-EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS = 36
-EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS = 37
-EC_FEATURE_SCP = 39
-EC_FEATURE_ISH = 40
-
-EC_IMAGE_UNKNOWN = 0
-EC_IMAGE_RO = 1
-EC_IMAGE_RW = 2
-
-class cros_ec_command(Structure):
- _fields_ = [
- ("version", c_uint),
- ("command", c_uint),
- ("outsize", c_uint),
- ("insize", c_uint),
- ("result", c_uint),
- ("data", c_ubyte * EC_HOST_PARAM_SIZE),
- ]
-
-
-class ec_params_hello(Structure):
- _fields_ = [("in_data", c_uint)]
-
-
-class ec_response_hello(Structure):
- _fields_ = [("out_data", c_uint)]
-
-class ec_response_get_version(Structure):
- _fields_ = [
- ("version_string_ro", c_ubyte * 32),
- ("version_string_rw", c_ubyte * 32),
- ("reserved", c_ubyte * 32),
- ("current_image", c_uint),
- ]
-
-class ec_params_get_features(Structure):
- _fields_ = [("in_data", c_ulong)]
-
-
-class ec_response_get_features(Structure):
- _fields_ = [("out_data", c_ulong)]
-
-
-def EC_FEATURE_MASK_0(event_code):
- return 1 << (event_code % 32)
-
-
-def EC_FEATURE_MASK_1(event_code):
- return 1 << (event_code - 32)
-
-
-def is_feature_supported(feature):
- """ Returns true if the Embedded Controller supports the specified
- 'feature'.
- """
- global ECFEATURES
-
- if ECFEATURES == -1:
- fd = open("/dev/cros_ec", "r")
-
- param = ec_params_get_features()
- response = ec_response_get_features()
-
- cmd = cros_ec_command()
- cmd.version = 0
- cmd.command = EC_CMD_GET_FEATURES
- cmd.insize = sizeof(param)
- cmd.outsize = sizeof(response)
-
- memmove(addressof(cmd.data), addressof(param), cmd.outsize)
- fcntl.ioctl(fd, EC_DEV_IOCXCMD, cmd)
- memmove(addressof(response), addressof(cmd.data), cmd.outsize)
-
- fd.close()
-
- if cmd.result == 0:
- ECFEATURES = response.out_data
- else:
- return False
-
- return (ECFEATURES & EC_FEATURE_MASK_0(feature)) > 0
-
-
-def check_mcu_abi(s, name):
- """ Checks that the MCU character device exists in /dev and then verifies
- the standard MCU ABI in /sys/class/chromeos.
- """
- if not os.path.exists(os.path.join("/dev", name)):
- s.skipTest(f"MCU {name} not supported")
- files = ["flashinfo", "reboot", "version"]
- sysfs_check_attributes_exists(
- s, "/sys/class/chromeos/", name, files, False
- )
-
-
-def mcu_hello(s, name):
- """ Checks basic comunication with MCU. """
- devpath = os.path.join("/dev", name)
- if not os.path.exists(devpath):
- s.skipTest(f"MCU {name} not present")
- fd = open(devpath, "r")
- param = ec_params_hello()
- param.in_data = 0xA0B0C0D0 # magic number that the EC expects on HELLO
-
- response = ec_response_hello()
-
- cmd = cros_ec_command()
- cmd.version = 0
- cmd.command = EC_CMD_HELLO
- cmd.insize = sizeof(param)
- cmd.outsize = sizeof(response)
-
- memmove(addressof(cmd.data), addressof(param), cmd.insize)
- fcntl.ioctl(fd, EC_DEV_IOCXCMD, cmd)
- memmove(addressof(response), addressof(cmd.data), cmd.outsize)
-
- fd.close()
-
- s.assertEqual(cmd.result, 0, msg="Error sending EC HELLO")
- # magic number that the EC answers on HELLO
- s.assertEqual(response.out_data, 0xA1B2C3D4,
- msg=f"Wrong EC HELLO magic number ({response.out_data})")
-
-def mcu_get_version(name):
- devpath = os.path.join("/dev", name)
- if os.path.exists(devpath):
- fd = open(devpath, "r")
-
- response = ec_response_get_version()
-
- cmd = cros_ec_command()
- cmd.version = 0
- cmd.command = EC_CMD_GET_VERSION
- cmd.insize = sizeof(response)
- cmd.outsize = 0
-
- fcntl.ioctl(fd, EC_DEV_IOCXCMD, cmd)
- memmove(addressof(response), addressof(cmd.data), cmd.insize)
-
- fd.close()
- if cmd.result == 0:
- return response
-
-def mcu_reboot(name):
- fd = open(os.path.join("/dev", name), "r")
- cmd = cros_ec_command()
- cmd.version = 0
- cmd.command = EC_CMD_REBOOT
- cmd.insize = 0
- cmd.outsize = 0
- try:
- fcntl.ioctl(fd, EC_DEV_IOCXCMD, cmd)
- except IOError:
- pass
- fd.close()
-
-def check_mcu_reboot_rw(s, name):
- if not os.path.exists(os.path.join("/dev", name)):
- s.skipTest("cros_fp not present")
- mcu_reboot(name)
- response = mcu_get_version(name)
- s.assertEqual(response.current_image, EC_IMAGE_RW,
- msg="Current EC image is not RW")
-
diff --git a/cros/helpers/sysfs.py b/cros/helpers/sysfs.py
index 83dc38b..131584a 100755..100644
--- a/cros/helpers/sysfs.py
+++ b/cros/helpers/sysfs.py
@@ -4,36 +4,27 @@
import os
-def read_file(name):
- """ Returns the content of the file named 'name'."""
- fd = open(name, "r")
- contents = fd.read()
- fd.close()
- return contents
-
-
def sysfs_check_attributes_exists(s, path, name, files, check_devtype):
""" Checks that all attributes listed in 'files' for a given 'path' exists.
Note that the 'name' parameter is used to define a pattern to match
before checking a device path.
"""
match = 0
- try:
- for devname in os.listdir(path):
- if check_devtype:
- fd = open(os.path.join(path, devname, 'name'), "r")
- devtype = fd.read()
- fd.close()
- if not devtype.startswith(name):
- continue
- else:
- if not devname.startswith(name):
- continue
- match += 1
- for filename in files:
- p = os.path.join(path, devname, filename)
- s.assertTrue(os.path.exists(p), msg=f"{p} not found")
- except IOError as e:
- s.skipTest(f"{e}")
+ for devname in os.listdir(path):
+ if check_devtype:
+ p = os.path.join(path, devname, "name")
+ if not os.path.exists(p):
+ s.skipTest(f"{p} not found")
+ with open(p) as fh:
+ devtype = fh.read()
+ if not devtype.startswith(name):
+ continue
+ else:
+ if not devname.startswith(name):
+ continue
+ match += 1
+ for filename in files:
+ p = os.path.join(path, devname, filename)
+ s.assertTrue(os.path.exists(p), msg=f"{p} not found")
if match == 0:
s.skipTest(f"No {name} found")
diff --git a/cros/runners/lava_runner.py b/cros/runners/lava_runner.py
index 554a79e..baedb83 100755..100644
--- a/cros/runners/lava_runner.py
+++ b/cros/runners/lava_runner.py
@@ -1,107 +1,50 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-import sys
+import functools
import unittest
-import traceback
-from cros.tests.cros_ec_accel import *
-from cros.tests.cros_ec_gyro import *
-from cros.tests.cros_ec_mcu import *
-from cros.tests.cros_ec_pwm import *
-from cros.tests.cros_ec_rtc import *
-from cros.tests.cros_ec_power import *
-from cros.tests.cros_ec_extcon import *
+class LavaTestResult(unittest.TextTestResult):
+ def writeLavaSignal(self, test, result):
+ test_case_id = test.id().rsplit(".")[-1]
-class LavaTextTestResult(unittest.TestResult):
- def __init__(self, runner, verbosity=0):
- super().__init__()
- self.trace_on = verbosity > 0
- self.debug_on = verbosity > 1
- self.runner = runner
+ # LAVA signal must be start-of-line. Print a newline if verbosity >= 1.
+ if self.showAll or self.dots:
+ self.stream.writeln()
+
+ self.stream.writeln(
+ f"<LAVA_SIGNAL_TESTCASE TEST_CASE_ID={test_case_id} RESULT={result}>"
+ )
+ self.stream.flush()
def addSuccess(self, test):
super().addSuccess(test)
- testcase = test.id().rsplit(".")[-1]
- self.runner.writeUpdate(
- f"<LAVA_SIGNAL_TESTCASE TEST_CASE_ID={testcase} RESULT=pass>\n")
+ self.writeLavaSignal(test, "pass")
def addError(self, test, err):
super().addError(test, err)
- testcase = test.id().rsplit(".")[-1]
- if self.trace_on:
- exc_type, exc_value, exc_tb = err
- msg = str(exc_value).split(' : ')
- if len(msg) > 1:
- msg = ''.join(msg[1:])
- else:
- msg = msg[0]
- self.runner.writeUpdate(f"{testcase} ERROR: {msg}\n")
- if self.debug_on:
- exc_type, exc_value, exc_tb = err
- traceback.print_tb(exc_tb, file=self.runner.stream)
- self.runner.writeUpdate(
- f"<LAVA_SIGNAL_TESTCASE TEST_CASE_ID={testcase} RESULT=unknown>\n")
+ self.writeLavaSignal(test, "unknown")
def addFailure(self, test, err):
super().addFailure(test, err)
- testcase = test.id().rsplit(".")[-1]
- if self.trace_on:
- exc_type, exc_value, exc_tb = err
- msg = str(exc_value).split(' : ')
- if len(msg) > 1:
- msg = ''.join(msg[1:])
- else:
- msg = msg[0]
- self.runner.writeUpdate(f"{testcase} FAIL: {msg}\n")
- if self.debug_on:
- exc_type, exc_value, exc_tb = err
- traceback.print_tb(exc_tb, file=self.runner.stream)
- self.runner.writeUpdate(
- f"<LAVA_SIGNAL_TESTCASE TEST_CASE_ID={testcase} RESULT=fail>\n")
+ self.writeLavaSignal(test, "fail")
def addSkip(self, test, reason):
super().addSkip(test, reason)
- testcase = test.id().rsplit(".")[-1]
- if self.trace_on:
- self.runner.writeUpdate(f"{testcase} SKIP: {reason}\n")
- self.runner.writeUpdate(
- f"<LAVA_SIGNAL_TESTCASE TEST_CASE_ID={testcase} RESULT=skip>\n")
-
-
-class LavaTestRunner:
- def __init__(self, stream=sys.stderr, verbosity=0):
- self.stream = stream
- self.verbosity = verbosity
+ self.writeLavaSignal(test, "skip")
- def writeUpdate(self, message):
- self.stream.write(message)
- def run(self, test):
- result = LavaTextTestResult(self, self.verbosity)
- test(result)
- result.testsRun
- return result
+class LavaTestRunner(unittest.TextTestRunner):
+ __init__ = functools.partialmethod(
+ unittest.TextTestRunner.__init__,
+ resultclass=LavaTestResult)
if __name__ == "__main__":
- verbosity = 0
- # Parse additional "verbosity" parameter and strip it from sys.argv
- # so that unittest can do the rest of the command line parsing
- if '--verbosity' in sys.argv:
- i = sys.argv.index('--verbosity')
- try:
- verbosity = int(sys.argv[i+1])
- sys.argv.pop(i+1)
- except IndexError:
- pass
- except ValueError:
- sys.argv.pop(i+1)
- finally:
- sys.argv.pop(i)
unittest.main(
- testRunner=LavaTestRunner(verbosity=verbosity),
+ module="cros.tests",
+ testRunner=LavaTestRunner,
# these make sure that some options that are not applicable
# remain hidden from the help menu.
failfast=False,
diff --git a/cros/tests/__init__.py b/cros/tests/__init__.py
index e69de29..36f6890 100644
--- a/cros/tests/__init__.py
+++ b/cros/tests/__init__.py
@@ -0,0 +1,7 @@
+from .cros_ec_accel import *
+from .cros_ec_extcon import *
+from .cros_ec_gyro import *
+from .cros_ec_mcu import *
+from .cros_ec_power import *
+from .cros_ec_pwm import *
+from .cros_ec_rtc import *
diff --git a/cros/tests/cros_ec_accel.py b/cros/tests/cros_ec_accel.py
index bf3aaf0..308b42f 100755..100644
--- a/cros/tests/cros_ec_accel.py
+++ b/cros/tests/cros_ec_accel.py
@@ -1,12 +1,17 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.kernel import *
-from cros.helpers.mcu import *
-from cros.helpers.sysfs import *
+import glob
import math
-import unittest
import os
+import unittest
+
+from cros.helpers.ec_cmd import EC_FEATURE_MOTION_SENSE_FIFO
+from cros.helpers.ec_cmd import is_feature_supported
+from cros.helpers.kernel import kernel_greater_than
+from cros.helpers.kernel import kernel_lower_than
+from cros.helpers.sysfs import sysfs_check_attributes_exists
+
class TestCrosECAccel(unittest.TestCase):
def test_cros_ec_accel_iio_abi(self):
@@ -29,7 +34,7 @@ class TestCrosECAccel(unittest.TestCase):
"sampling_frequency",
"sampling_frequency_available",
"scale",
- "scan_elements/",
+ "scan_elements",
"trigger",
]
if (kernel_greater_than(5, 6, 0) and
@@ -51,32 +56,40 @@ class TestCrosECAccel(unittest.TestCase):
"""
ACCEL_1G_IN_MS2 = 9.8185
ACCEL_MAG_VALID_OFFSET = 0.25
+ exp = ACCEL_1G_IN_MS2
+ err = exp * ACCEL_MAG_VALID_OFFSET
+
match = 0
- try:
- basepath = "/sys/bus/iio/devices"
- for devname in os.listdir(basepath):
- dev_basepath = os.path.join(basepath, devname)
- fd = open(os.path.join(dev_basepath, "name"), "r")
- devtype = fd.read()
- if devtype.startswith("cros-ec-accel"):
- accel_scale = float(read_file(os.path.join(dev_basepath, "scale")))
- exp = ACCEL_1G_IN_MS2
- err = exp * ACCEL_MAG_VALID_OFFSET
- mag = 0
- for axis in ["in_accel_x_raw",
- "in_accel_y_raw",
- "in_accel_z_raw"]:
- axis_path = os.path.join(dev_basepath, axis)
- value = int(read_file(axis_path))
- value *= accel_scale
- mag += value * value
- mag = math.sqrt(mag)
- self.assertTrue(abs(mag - exp) <= err,
- msg=("Incorrect accelerometer data "
- f"in {dev_basepath} ({abs(mag - exp)})"))
- match += 1
- fd.close()
- except IOError as e:
- self.skipTest(f"{e}")
+ for dev in glob.glob("/sys/bus/iio/devices/*"):
+ p = os.path.join(dev, "name")
+ if not os.path.exists(p):
+ self.skipTest(f"{p} not found")
+ with open(p) as fh:
+ devtype = fh.read()
+ if not devtype.startswith("cros-ec-accel"):
+ continue
+
+ p = os.path.join(dev, "scale")
+ if not os.path.exists(p):
+ self.skipTest(f"{p} not found")
+ with open(p) as fh:
+ accel_scale = float(fh.read())
+
+ mag = 0
+ for axis in ["in_accel_x_raw", "in_accel_y_raw", "in_accel_z_raw"]:
+ axis_path = os.path.join(dev, axis)
+ if not os.path.exists(axis_path):
+ self.skipTest(f"{axis_path} not found")
+
+ with open(axis_path) as fh:
+ value = int(fh.read())
+ value *= accel_scale
+ mag += value * value
+ mag = math.sqrt(mag)
+
+ self.assertTrue(abs(mag - exp) <= err,
+ msg=("Incorrect accelerometer data "
+ f"in {dev} ({abs(mag - exp)})"))
+ match += 1
if match == 0:
self.skipTest("No accelerometer found")
diff --git a/cros/tests/cros_ec_extcon.py b/cros/tests/cros_ec_extcon.py
index 9d3e84c..c1bc966 100755..100644
--- a/cros/tests/cros_ec_extcon.py
+++ b/cros/tests/cros_ec_extcon.py
@@ -1,30 +1,30 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.sysfs import *
-import unittest
+import glob
import os
+import unittest
+
class TestCrosECextcon(unittest.TestCase):
def test_cros_ec_extcon_usbc_abi(self):
""" Checks the cros-ec extcon ABI. """
match = 0
- try:
- basepath = "/sys/class/extcon"
- for devname in os.listdir(basepath):
- dev_basepath = os.path.join(basepath, devname)
- devtype = read_file(os.path.join(dev_basepath, "name"))
- if ".spi:ec@0:extcon@" in devtype:
- p = os.path.join(dev_basepath, "state")
+ for dev in glob.glob("/sys/class/extcon/*"):
+ with open(os.path.join(dev, "name")) as fh:
+ devtype = fh.read()
+ if ".spi:ec@0:extcon@" not in devtype:
+ continue
+
+ p = os.path.join(dev, "state")
+ self.assertTrue(os.path.exists(p), msg=f"{p} not found")
+
+ for cable in os.listdir(dev):
+ if cable.startswith("cable"):
+ p = os.path.join(dev, cable, "name")
+ self.assertTrue(os.path.exists(p), msg=f"{p} not found")
+ p = os.path.join(dev, cable, "state")
self.assertTrue(os.path.exists(p), msg=f"{p} not found")
- for cable in os.listdir(dev_basepath):
- if cable.startswith("cable"):
- p = os.path.join(dev_basepath, cable, "name")
- self.assertTrue(os.path.exists(p), msg=f"{p} not found")
- p = os.path.join(dev_basepath, cable, "state")
- self.assertTrue(os.path.exists(p), msg=f"{p} not found")
- match += 1
- except IOError as e:
- self.skipTest(f"{e}")
+ match += 1
if match == 0:
self.skipTest("No extcon device found")
diff --git a/cros/tests/cros_ec_gyro.py b/cros/tests/cros_ec_gyro.py
index 88a549c..28783a2 100644
--- a/cros/tests/cros_ec_gyro.py
+++ b/cros/tests/cros_ec_gyro.py
@@ -1,11 +1,14 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.kernel import *
-from cros.helpers.mcu import *
-from cros.helpers.sysfs import *
import unittest
+from cros.helpers.ec_cmd import EC_FEATURE_MOTION_SENSE_FIFO
+from cros.helpers.ec_cmd import is_feature_supported
+from cros.helpers.kernel import kernel_greater_than
+from cros.helpers.kernel import kernel_lower_than
+from cros.helpers.sysfs import sysfs_check_attributes_exists
+
class TestCrosECGyro(unittest.TestCase):
def test_cros_ec_gyro_iio_abi(self):
diff --git a/cros/tests/cros_ec_mcu.py b/cros/tests/cros_ec_mcu.py
index 1465286..1e6d29b 100644
--- a/cros/tests/cros_ec_mcu.py
+++ b/cros/tests/cros_ec_mcu.py
@@ -1,48 +1,95 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.mcu import *
-import fcntl
+import os
import unittest
+from cros.helpers.ec_cmd import ec_params_hello, ec_response_hello
+from cros.helpers.ec_cmd import send_ec_command
+from cros.helpers import ec_cmd
+from cros.helpers.sysfs import sysfs_check_attributes_exists
+
class TestCrosECMCU(unittest.TestCase):
+ def check_abi(self, name):
+ """ Checks that the MCU character device exists in /dev and then verifies
+ the standard MCU ABI in /sys/class/chromeos.
+ """
+ dev = os.path.join("/dev", name)
+ if not os.path.exists(dev):
+ self.skipTest(f"MCU {name} not supported")
+
+ files = ["flashinfo", "reboot", "version"]
+ sysfs_check_attributes_exists(
+ self, "/sys/class/chromeos/", name, files, False
+ )
+
def test_cros_ec_abi(self):
""" Checks the standard ABI for the main Embedded Controller. """
- check_mcu_abi(self, "cros_ec")
+ self.check_abi("cros_ec")
def test_cros_fp_abi(self):
""" Checks the standard ABI for the Fingerprint EC. """
- check_mcu_abi(self, "cros_fp")
+ self.check_abi("cros_fp")
def test_cros_tp_abi(self):
""" Checks the standard ABI for the Touchpad EC. """
- check_mcu_abi(self, "cros_tp")
+ self.check_abi("cros_tp")
def test_cros_pd_abi(self):
""" Checks the standard ABI for the Power Delivery EC. """
- check_mcu_abi(self, "cros_pd")
+ self.check_abi("cros_pd")
def test_cros_ec_chardev(self):
""" Checks the main Embedded controller character device. """
self.assertTrue(os.path.exists("/dev/cros_ec"),
msg="/dev/cros_ec not found")
+ def check_hello(self, name):
+ """ Checks basic comunication with MCU. """
+ dev = os.path.join("/dev", name)
+ if not os.path.exists(dev):
+ self.skipTest(f"MCU {name} not found")
+
+ param, response = ec_params_hello(), ec_response_hello()
+ # magic number that the EC expects on HELLO
+ param.in_data = 0xA0B0C0D0
+
+ cmd = send_ec_command(dev, ec_cmd.EC_CMD_HELLO, param, response)
+ self.assertEqual(cmd.result, 0, msg="Error sending EC HELLO")
+ # magic number that the EC answers on HELLO
+ self.assertEqual(response.out_data, 0xA1B2C3D4,
+ msg=f"Wrong EC HELLO magic number ({response.out_data})")
+
def test_cros_ec_hello(self):
""" Checks basic comunication with the main Embedded controller. """
- mcu_hello(self, "cros_ec")
+ self.check_hello("cros_ec")
def test_cros_fp_hello(self):
""" Checks basic comunication with the fingerprint controller. """
- mcu_hello(self, "cros_fp")
+ self.check_hello("cros_fp")
def test_cros_tp_hello(self):
""" Checks basic comunication with the touchpad controller. """
- mcu_hello(self, "cros_tp")
+ self.check_hello("cros_tp")
def test_cros_pd_hello(self):
""" Checks basic comunication with the power delivery controller. """
- mcu_hello(self, "cros_pd")
+ self.check_hello("cros_pd")
+
+ def check_reboot_rw(self, name):
+ dev = os.path.join("/dev", name)
+ if not os.path.exists(dev):
+ self.skipTest(f"MCU {name} not found")
+
+ cmd = send_ec_command(dev, ec_cmd.EC_CMD_REBOOT)
+ self.assertEqual(cmd.result, 0, msg="Failed to REBOOT")
+
+ param, response = None, ec_response_get_version()
+ cmd = send_ec_command(dev, ec_cmd.EC_CMD_GET_VERSION, param, response)
+ self.assertEqual(cmd.result, 0, msg="Failed to GET_VERSION")
+ self.assertEqual(response.current_image, EC_IMAGE_RW,
+ msg="Current EC image is not RW")
def test_cros_fp_reboot(self):
""" Test reboot command on Fingerprint MCU.
@@ -62,4 +109,4 @@ class TestCrosECMCU(unittest.TestCase):
("platform/chrome: cros_ec: Query EC protocol version if EC
transitions between RO/RW).
"""
- check_mcu_reboot_rw(self, "cros_fp")
+ self.check_reboot_rw("cros_fp")
diff --git a/cros/tests/cros_ec_power.py b/cros/tests/cros_ec_power.py
index e72ce90..d0250a2 100644
--- a/cros/tests/cros_ec_power.py
+++ b/cros/tests/cros_ec_power.py
@@ -1,9 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.sysfs import *
import unittest
+from cros.helpers.sysfs import sysfs_check_attributes_exists
+
class TestCrosECPower(unittest.TestCase):
def test_cros_ec_usbpd_charger_abi(self):
diff --git a/cros/tests/cros_ec_pwm.py b/cros/tests/cros_ec_pwm.py
index c8e6180..90723c7 100644
--- a/cros/tests/cros_ec_pwm.py
+++ b/cros/tests/cros_ec_pwm.py
@@ -1,10 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.sysfs import *
+import re
import unittest
import os
+
class TestCrosECPWM(unittest.TestCase):
def test_cros_ec_pwm_backlight(self):
""" Check that the backlight is connected to a pwm of the EC and that
@@ -13,42 +14,31 @@ class TestCrosECPWM(unittest.TestCase):
"""
if not os.path.exists("/sys/class/backlight/backlight/max_brightness"):
self.skipTest("No backlight pwm found")
- is_ec_pwm = False
+
if not os.path.exists("/sys/kernel/debug/pwm"):
self.skipTest("/sys/kernel/debug/pwm not found")
- fd = open("/sys/kernel/debug/pwm", "r")
- line = fd.readline()
- while line and not is_ec_pwm:
- if line[0] != " " and ":ec-pwm" in line:
- line = fd.readline()
- while line:
- if line[0] == "\n":
- is_ec_pwm = False
- break
- if "backlight" in line:
- is_ec_pwm = True
- break
- line = fd.readline()
- line = fd.readline()
- fd.close()
- if not is_ec_pwm:
+
+ with open("/sys/kernel/debug/pwm") as fh:
+ pwm = fh.read()
+ for s in pwm.split("\n\n"):
+ if re.match(r".*:ec-pwm.*backlight", s, re.DOTALL):
+ ec_pwm = s
+ break
+ else:
self.skipTest("No EC backlight pwm found")
- fd = open("/sys/class/backlight/backlight/max_brightness", "r")
- brightness = int(int(fd.read()) / 2)
- fd.close()
- fd = open("/sys/class/backlight/backlight/brightness", "w")
- fd.write(str(brightness))
- fd.close()
- fd = open("/sys/kernel/debug/pwm", "r")
- line = fd.readline()
- while line:
- if "backlight" in line:
- start = line.find("duty") + 6
- self.assertNotEqual(start, 5, msg=f"error reading back PWM info: {line}")
- end = start + line[start:].find(" ")
- self.assertNotEqual(start, end, msg=f"error reading back PWM info: {line}")
- duty = int(line[start:end])
- self.assertNotEqual(duty, 0, msg=f"error reading back PWM info: {line}")
+
+ with open("/sys/class/backlight/backlight/max_brightness") as fh:
+ brightness = int(int(fh.read()) / 2)
+ with open("/sys/class/backlight/backlight/brightness", "w") as fh:
+ fh.write(str(brightness))
+ for s in ec_pwm.split("\n"):
+ if "backlight" not in s:
+ continue
+
+ m = re.search(r"duty: (\d+)", s)
+ if m:
+ duty = int(m.group(1))
+ self.assertNotEqual(duty, 0, msg="duty should not be 0")
break
- line = fd.readline()
- fd.close()
+ else:
+ self.fail("Failed to parse duty")
diff --git a/cros/tests/cros_ec_rtc.py b/cros/tests/cros_ec_rtc.py
index 471a04c..75cae50 100755..100644
--- a/cros/tests/cros_ec_rtc.py
+++ b/cros/tests/cros_ec_rtc.py
@@ -1,37 +1,39 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from cros.helpers.mcu import *
-from cros.helpers.sysfs import *
-import unittest
+import glob
import os
+import unittest
+
+from cros.helpers.ec_cmd import EC_FEATURE_RTC
+from cros.helpers.ec_cmd import is_feature_supported
+
class TestCrosECRTC(unittest.TestCase):
def test_cros_ec_rtc_abi(self):
""" Check the cros RTC ABI. """
if not is_feature_supported(EC_FEATURE_RTC):
self.skipTest("EC_FEATURE_RTC not supported, skipping")
+
+ files = [
+ "date",
+ "hctosys",
+ "max_user_freq",
+ "since_epoch",
+ "time",
+ "wakealarm",
+ ]
+
match = 0
- try:
- basepath = "/sys/class/rtc"
- for devname in os.listdir(basepath):
- dev_basepath = os.path.join(basepath, devname)
- fd = open(os.path.join(dev_basepath, "name"), "r")
- devtype = fd.read()
- fd.close()
- if devtype.startswith("cros-ec-rtc"):
- files = [
- "date",
- "hctosys",
- "max_user_freq",
- "since_epoch",
- "time",
- "wakealarm",
- ]
- match += 1
- for filename in files:
- p = os.path.join(dev_basepath, filename)
- self.assertTrue(os.path.exists(p), msg=f"{p} not found")
- except IOError as e:
- self.skipTest(f"{e}")
- self.assertNotEqual(match, 0, msg="No RTC device found")
+ for dev in glob.glob("/sys/class/rtc/*"):
+ with open(os.path.join(dev, "name")) as fh:
+ devtype = fh.read()
+ if not devtype.startswith("cros-ec-rtc"):
+ continue
+
+ match += 1
+ for filename in files:
+ p = os.path.join(dev, filename)
+ self.assertTrue(os.path.exists(p), msg=f"{p} not found")
+ if match == 0:
+ self.skipTest("No RTC device found")
diff --git a/docs/source/testhelpers.rst b/docs/source/testhelpers.rst
index 380b1bd..2db0605 100644
--- a/docs/source/testhelpers.rst
+++ b/docs/source/testhelpers.rst
@@ -8,10 +8,10 @@ kernel
.. automodule:: cros.helpers.kernel
:members:
-mcu
+ec_cmd
===
-.. automodule:: cros.helpers.mcu
+.. automodule:: cros.helpers.ec_cmd
:members:
sysfs
diff --git a/setup.py b/setup.py
index 92e4ed7..958aaa8 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
import setuptools
-with open("README.md", "r") as fh:
+with open("README.md") as fh:
long_description = fh.read()
setuptools.setup(