From 0f42de92fa19a8a2243e06fcceb0f685e71286f2 Mon Sep 17 00:00:00 2001 From: stanley31huang Date: Mon, 14 Jul 2025 13:19:28 +0800 Subject: [PATCH 1/6] add regulator test add regulator test --- .../bin/regulator_test.py | 225 ++++++++++++++++++ .../units/regulator/category.pxu | 3 + .../units/regulator/jobs.pxu | 16 ++ .../units/regulator/manifest.pxu | 4 + .../units/regulator/test-plan.pxu | 40 ++++ 5 files changed, 288 insertions(+) create mode 100755 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/category.pxu create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/manifest.pxu create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/test-plan.pxu diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py new file mode 100755 index 0000000000..330db2e6e0 --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +import sys +import logging +import argparse +from enum import Enum +from pathlib import Path + + +def init_logger(): + """ + Set the logger to log DEBUG and INFO to stdout, and + WARNING, ERROR, CRITICAL to stderr. + """ + root_logger = logging.getLogger() + root_logger.setLevel(logging.INFO) + logger_format = "%(message)s" + date_format = "%Y-%m-%d %H:%M:%S" + + # Log DEBUG and INFO to stdout, others to stderr + stdout_handler = logging.StreamHandler(sys.stdout) + #stdout_handler.setFormatter(logging.Formatter(logger_format, date_format)) + + stderr_handler = logging.StreamHandler(sys.stderr) + # stderr_handler.setFormatter(logging.Formatter(logger_format, date_format)) + + stdout_handler.setLevel(logging.DEBUG) + stderr_handler.setLevel(logging.WARNING) + + # Add a filter to the stdout handler to limit log records to + # INFO level and below + stdout_handler.addFilter(lambda record: record.levelno <= logging.INFO) + + root_logger.addHandler(stderr_handler) + root_logger.addHandler(stdout_handler) + + return root_logger + + +class RegulatorEnum(Enum): + VOLTAGE = "voltage" + CURRENT = "current" + + +SYS_REGULATOR_PATH = "/sys/class/regulator" +VOLTAGE_REGULATOR_ATTRIBUTES = ["name", "microvolts"] + + +class RegulatorBase(): + + def __init__(self, regulator_type): + self.regulator_type = regulator_type + self.raw_regulators = {} + self.regulators = {} + + def collect_data(self, node): + try: + rg_type_node = node.joinpath("type") + rg_type_text = rg_type_node.read_text().strip() + rg_type = RegulatorEnum(rg_type_text) + if rg_type == RegulatorEnum.VOLTAGE: + possible_keys = VOLTAGE_REGULATOR_ATTRIBUTES + rg_type = RegulatorEnum.VOLTAGE.value + elif rg_type == RegulatorEnum.CURRENT: + possible_keys = [] + + logging.info("\ntype: %s", rg_type) + data = {"type": rg_type} + for key in possible_keys: + child = node.joinpath(key) + if child.exists(): + value = child.read_text().strip() + data[key] = value + logging.info("%s: %s", key, value) + return data + except ValueError: + logging.error("Unexpected regulator type: %s", rg_type_text) + except FileNotFoundError: + logging.error("%s regulator type does not exists", node.name) + + def dump_sysfs_regulator(self): + for rg_dev in sorted(Path(SYS_REGULATOR_PATH).glob("regulator*")): + self.raw_regulators[rg_dev.name] = self.collect_data(rg_dev) + + def filter_regulators_by_type(self): + logging.info("\n# filtering %s regulator..", self.regulator_type) + for dev in self.raw_regulators.values(): + if dev["type"] != self.regulator_type: + logging.info("skip '%s' regulator", dev["name"]) + continue + + key = dev.pop("name") + self.regulators[key] = dev + + def is_regulator_available(self, name): + if name in self.regulators.keys(): + return True + logging.error("%s regulator not found", name) + return False + + def is_regulator_attr_available(self, regulator, attr): + if attr in self.regulators[regulator].keys(): + return True + logging.error("%s attribute not exists", attr) + return False + + def get_regulator_attr(self, regulator, attr): + return self.regulators[regulator][attr] + + +def convert_regulator_devices(type, data): + devices = {} + + for part in data.split("|"): + if RegulatorEnum(type) == RegulatorEnum.VOLTAGE: + parts = part.split(":") + if len(parts) != len(VOLTAGE_REGULATOR_ATTRIBUTES): + logging.error("Unexpected regulator data: %s", part) + continue + dev = dict(zip(VOLTAGE_REGULATOR_ATTRIBUTES, parts)) + + key = dev.pop("name") + devices[key] = dev + + return devices + + +def summarize_test_results(details_logs): + logging.info("\n# Details Test Results") + for regulator, msgs in details_logs.items(): + log = "## '{}' regulator: ".format(regulator) + log += "Failed" if msgs else "Passed" + log += msgs + logging.info(log) + + +def check_difference(exp_regulators, sysfs_regulators): + test_results = {"result": False, "logs": {}} + + for regulator, data in exp_regulators.items(): + details = "" + if not sysfs_regulators.is_regulator_available(regulator): + details += "\n- regulator device not exists" + test_results["logs"][regulator] = details + test_results["result"] = True + continue + + for attr, value in data.items(): + if not sysfs_regulators.is_regulator_attr_available( + regulator, attr + ): + details += "\n- {} attribute not exits".format(attr) + test_results["result"] = True + continue + + actual_attr = sysfs_regulators.get_regulator_attr(regulator, attr) + if value != actual_attr: + details += ( + "\n- mismatch value for {}. expected: {}, actual: {}" + ).format( + attr, value, actual_attr + ) + test_results["result"] = True + test_results["logs"][regulator] = details + + return test_results + + +def compare_regulators(args): + type = args.type + exp_regulator_devs = convert_regulator_devices(type, args.devices) + if not exp_regulator_devs: + raise SystemExit("Invalid input argument for devices") + + regulator = RegulatorBase(type) + regulator.dump_sysfs_regulator() + regulator.filter_regulators_by_type() + + results = check_difference( + exp_regulator_devs, regulator + ) + summarize_test_results(results["logs"]) + if results["result"]: + raise SystemExit( + "\nFailed: the expected {} regulatorss does not match".format( + type + ) + ) + else: + logging.info( + "\nPassed: the expected %s regulatorss are all available", type + ) + + +def register_arguments(): + parser = argparse.ArgumentParser( + description="Voltage Regulator detection Tests", + ) + parser.add_argument( + "devices", + type=str, + help=( + "provides expected regulator information with following format.\n" + "format: name:microvolts|..." + "e.g. LO1:1800000|LO2:3300000" + ), + ) + parser.add_argument( + "--type", + "-t", + choices=[RegulatorEnum.VOLTAGE.value, RegulatorEnum.CURRENT.value], + help="the regulator type" + ) + + args = parser.parse_args() + return args + + +def main(): + init_logger() + args = register_arguments() + compare_regulators(args) + + +if __name__ == "__main__": + main() diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/category.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/category.pxu new file mode 100644 index 0000000000..8ccf4199ed --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/category.pxu @@ -0,0 +1,3 @@ +unit: category +id: regulator +_name: Regulator Device Test \ No newline at end of file diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu new file mode 100644 index 0000000000..ad0352d987 --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu @@ -0,0 +1,16 @@ +id: ce-oem-regulator/check-voltage-regulators +category_id: regulator +_summary: Verify the voltage regulators match regulators defined in VOLTAGE_REGULATORS variable +_description: + Check the regulator name and voltage for the platform, relies on the user specifying the information of regualtor. + Usage of parameter: {name:microvolts|name:microvolts|...} + VOLTAGE_REGULATORS="LDO5:1800000|BUCK4:3300000" +plugin: shell +user: root +flags: also-after-suspend +estimated_duration: 5 +requires: manifest.has_voltage_regulator == 'True' +environ: VOLTAGE_REGULATORS +imports: from com.canonical.plainbox import manifest +command: + regulator_test.py --type voltage "$VOLTAGE_REGULATORS" \ No newline at end of file diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/manifest.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/manifest.pxu new file mode 100644 index 0000000000..df9904f3c0 --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/manifest.pxu @@ -0,0 +1,4 @@ +unit: manifest entry +id: has_voltage_regulator +_name: Does platfrom supported Voltage Regulator Device? +value-type: bool \ No newline at end of file diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/test-plan.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/test-plan.pxu new file mode 100644 index 0000000000..818acb7867 --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/test-plan.pxu @@ -0,0 +1,40 @@ +id: ce-oem-regulaotr-full +unit: test plan +_name: Regulator tests +_description: Full Regulator tests for devices +include: +nested_part: + ce-oem-regulator-manual + ce-oem-regulator-automated + after-suspend-ce-oem-regulator-manual + after-suspend-ce-oem-regulator-automated + + +id: ce-oem-regulator-manual +unit: test plan +_name: Regulator manual tests +_description: Manual regulator tests for devices +include: + + +id: ce-oem-regulator-automated +unit: test plan +_name: Regulator auto tests +_description: Automated led tests for devices +include: + ce-oem-regulator/check-voltage-regulators + + +id: after-suspend-ce-oem-regulator-manual +unit: test plan +_name: Post suspend Regulator manual tests +_description: Manual Regulator tests for devices +include: + + +id: after-suspend-ce-oem-regulator-automated +unit: test plan +_name: Post suspend regulator auto tests +_description: Automated Regulator tests for devices +include: + after-suspend-ce-oem-regulator/check-voltage-regulators From 693e494cda6ac380cc8f8f8845919c51d946acd4 Mon Sep 17 00:00:00 2001 From: stanley31huang Date: Mon, 14 Jul 2025 14:11:35 +0800 Subject: [PATCH 2/6] fixed pep8 error fixed pep8 error --- .../bin/regulator_test.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py index 330db2e6e0..9a45d75c00 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py @@ -18,10 +18,7 @@ def init_logger(): # Log DEBUG and INFO to stdout, others to stderr stdout_handler = logging.StreamHandler(sys.stdout) - #stdout_handler.setFormatter(logging.Formatter(logger_format, date_format)) - stderr_handler = logging.StreamHandler(sys.stderr) - # stderr_handler.setFormatter(logging.Formatter(logger_format, date_format)) stdout_handler.setLevel(logging.DEBUG) stderr_handler.setLevel(logging.WARNING) @@ -45,7 +42,7 @@ class RegulatorEnum(Enum): VOLTAGE_REGULATOR_ATTRIBUTES = ["name", "microvolts"] -class RegulatorBase(): +class RegulatorBase: def __init__(self, regulator_type): self.regulator_type = regulator_type @@ -156,9 +153,7 @@ def check_difference(exp_regulators, sysfs_regulators): if value != actual_attr: details += ( "\n- mismatch value for {}. expected: {}, actual: {}" - ).format( - attr, value, actual_attr - ) + ).format(attr, value, actual_attr) test_results["result"] = True test_results["logs"][regulator] = details @@ -175,15 +170,11 @@ def compare_regulators(args): regulator.dump_sysfs_regulator() regulator.filter_regulators_by_type() - results = check_difference( - exp_regulator_devs, regulator - ) + results = check_difference(exp_regulator_devs, regulator) summarize_test_results(results["logs"]) if results["result"]: raise SystemExit( - "\nFailed: the expected {} regulatorss does not match".format( - type - ) + "\nFailed: the expected {} regulators does not match".format(type) ) else: logging.info( @@ -208,7 +199,7 @@ def register_arguments(): "--type", "-t", choices=[RegulatorEnum.VOLTAGE.value, RegulatorEnum.CURRENT.value], - help="the regulator type" + help="the regulator type", ) args = parser.parse_args() From 2e4bd775405ef7d16cf52a64e8629f1994bb0e13 Mon Sep 17 00:00:00 2001 From: stanley31huang Date: Mon, 14 Jul 2025 16:14:31 +0800 Subject: [PATCH 3/6] revised regulator tests revised regulator tests --- .../bin/regulator_test.py | 51 ++++--------------- .../units/regulator/jobs.pxu | 7 ++- 2 files changed, 13 insertions(+), 45 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py index 9a45d75c00..54ddeb7f16 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py @@ -14,11 +14,13 @@ def init_logger(): root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) logger_format = "%(message)s" - date_format = "%Y-%m-%d %H:%M:%S" # Log DEBUG and INFO to stdout, others to stderr stdout_handler = logging.StreamHandler(sys.stdout) + stdout_handler.setFormatter(logging.Formatter(logger_format)) + stderr_handler = logging.StreamHandler(sys.stderr) + stderr_handler.setFormatter(logging.Formatter(logger_format)) stdout_handler.setLevel(logging.DEBUG) stderr_handler.setLevel(logging.WARNING) @@ -39,7 +41,7 @@ class RegulatorEnum(Enum): SYS_REGULATOR_PATH = "/sys/class/regulator" -VOLTAGE_REGULATOR_ATTRIBUTES = ["name", "microvolts"] +VOLTAGE_REGULATOR_ATTRIBUTES = ["name"] class RegulatorBase: @@ -104,23 +106,6 @@ def get_regulator_attr(self, regulator, attr): return self.regulators[regulator][attr] -def convert_regulator_devices(type, data): - devices = {} - - for part in data.split("|"): - if RegulatorEnum(type) == RegulatorEnum.VOLTAGE: - parts = part.split(":") - if len(parts) != len(VOLTAGE_REGULATOR_ATTRIBUTES): - logging.error("Unexpected regulator data: %s", part) - continue - dev = dict(zip(VOLTAGE_REGULATOR_ATTRIBUTES, parts)) - - key = dev.pop("name") - devices[key] = dev - - return devices - - def summarize_test_results(details_logs): logging.info("\n# Details Test Results") for regulator, msgs in details_logs.items(): @@ -133,36 +118,20 @@ def summarize_test_results(details_logs): def check_difference(exp_regulators, sysfs_regulators): test_results = {"result": False, "logs": {}} - for regulator, data in exp_regulators.items(): + for regulator in exp_regulators: details = "" if not sysfs_regulators.is_regulator_available(regulator): details += "\n- regulator device not exists" - test_results["logs"][regulator] = details test_results["result"] = True - continue - - for attr, value in data.items(): - if not sysfs_regulators.is_regulator_attr_available( - regulator, attr - ): - details += "\n- {} attribute not exits".format(attr) - test_results["result"] = True - continue - - actual_attr = sysfs_regulators.get_regulator_attr(regulator, attr) - if value != actual_attr: - details += ( - "\n- mismatch value for {}. expected: {}, actual: {}" - ).format(attr, value, actual_attr) - test_results["result"] = True - test_results["logs"][regulator] = details + test_results["logs"][regulator] = details return test_results def compare_regulators(args): type = args.type - exp_regulator_devs = convert_regulator_devices(type, args.devices) + + exp_regulator_devs = args.devices.split("|") if not exp_regulator_devs: raise SystemExit("Invalid input argument for devices") @@ -191,8 +160,8 @@ def register_arguments(): type=str, help=( "provides expected regulator information with following format.\n" - "format: name:microvolts|..." - "e.g. LO1:1800000|LO2:3300000" + "format: name|...\n" + " e.g. LO1|LO2" ), ) parser.add_argument( diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu index ad0352d987..0ae3cd4dc7 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/regulator/jobs.pxu @@ -1,12 +1,11 @@ id: ce-oem-regulator/check-voltage-regulators category_id: regulator -_summary: Verify the voltage regulators match regulators defined in VOLTAGE_REGULATORS variable +_summary: Verify the voltage regulators match regulators defined in VOLTAGE_REGULATORS VAR _description: Check the regulator name and voltage for the platform, relies on the user specifying the information of regualtor. - Usage of parameter: {name:microvolts|name:microvolts|...} - VOLTAGE_REGULATORS="LDO5:1800000|BUCK4:3300000" + Usage of parameter: {name|name|...} + VOLTAGE_REGULATORS="LDO5|BUCK4" plugin: shell -user: root flags: also-after-suspend estimated_duration: 5 requires: manifest.has_voltage_regulator == 'True' From bc52e4a225207259dcad489cee8c4901476fd699 Mon Sep 17 00:00:00 2001 From: stanley31huang Date: Tue, 15 Jul 2025 17:09:12 +0800 Subject: [PATCH 4/6] revised the regulator test scripts revised the regulator test scripts --- .../bin/regulator_test.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py index 54ddeb7f16..8904e02b2f 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py @@ -39,9 +39,11 @@ class RegulatorEnum(Enum): VOLTAGE = "voltage" CURRENT = "current" + def __str__(self): + return self.value + SYS_REGULATOR_PATH = "/sys/class/regulator" -VOLTAGE_REGULATOR_ATTRIBUTES = ["name"] class RegulatorBase: @@ -54,13 +56,11 @@ def __init__(self, regulator_type): def collect_data(self, node): try: rg_type_node = node.joinpath("type") + if not rg_type_node.exists(): + pass rg_type_text = rg_type_node.read_text().strip() rg_type = RegulatorEnum(rg_type_text) - if rg_type == RegulatorEnum.VOLTAGE: - possible_keys = VOLTAGE_REGULATOR_ATTRIBUTES - rg_type = RegulatorEnum.VOLTAGE.value - elif rg_type == RegulatorEnum.CURRENT: - possible_keys = [] + possible_keys = ["name"] logging.info("\ntype: %s", rg_type) data = {"type": rg_type} @@ -72,7 +72,11 @@ def collect_data(self, node): logging.info("%s: %s", key, value) return data except ValueError: - logging.error("Unexpected regulator type: %s", rg_type_text) + logging.error( + "Unexpected type for '%s' regulator: %s", + node.name, + rg_type_text, + ) except FileNotFoundError: logging.error("%s regulator type does not exists", node.name) @@ -147,7 +151,7 @@ def compare_regulators(args): ) else: logging.info( - "\nPassed: the expected %s regulatorss are all available", type + "\nPassed: the expected %s regulators are all available", type ) @@ -165,9 +169,10 @@ def register_arguments(): ), ) parser.add_argument( - "--type", "-t", - choices=[RegulatorEnum.VOLTAGE.value, RegulatorEnum.CURRENT.value], + "--type", + type=RegulatorEnum, + choices=list(RegulatorEnum), help="the regulator type", ) From cc61c9fd20d1dca8c60c501f5a37c149cd936279 Mon Sep 17 00:00:00 2001 From: stanley31huang Date: Wed, 16 Jul 2025 10:42:47 +0800 Subject: [PATCH 5/6] revised regulator test scripts revised regulator test scripts --- .../bin/regulator_test.py | 102 +++++++++++++----- 1 file changed, 76 insertions(+), 26 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py index 8904e02b2f..fbf4304f25 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/regulator_test.py @@ -2,6 +2,9 @@ import sys import logging import argparse +import copy + +from collections import Counter from enum import Enum from pathlib import Path @@ -35,7 +38,10 @@ def init_logger(): return root_logger -class RegulatorEnum(Enum): +SYS_REGULATOR_PATH = "/sys/class/regulator" + + +class RegulatorTypeEnum(Enum): VOLTAGE = "voltage" CURRENT = "current" @@ -43,7 +49,26 @@ def __str__(self): return self.value -SYS_REGULATOR_PATH = "/sys/class/regulator" +class RegulatorAttribute: + + def __init__(self): + self.name = "name" + self.type = "type" + + +def read_node_text(node): + try: + value = node.read_text().strip() + except FileNotFoundError: + logging.error("'%s' does not exists", str(node)) + return None + except OSError as err: + logging.error( + "Unexpected error while accessing %s. %s", str(node), err + ) + return None + + return value class RegulatorBase: @@ -52,24 +77,23 @@ def __init__(self, regulator_type): self.regulator_type = regulator_type self.raw_regulators = {} self.regulators = {} + self.duplicated_regulators = [] def collect_data(self, node): + regulator_attr = RegulatorAttribute() + rg_type_text = read_node_text(node.joinpath(regulator_attr.type)) + if not rg_type_text: + return None + try: - rg_type_node = node.joinpath("type") - if not rg_type_node.exists(): - pass - rg_type_text = rg_type_node.read_text().strip() - rg_type = RegulatorEnum(rg_type_text) - possible_keys = ["name"] - - logging.info("\ntype: %s", rg_type) - data = {"type": rg_type} - for key in possible_keys: - child = node.joinpath(key) - if child.exists(): - value = child.read_text().strip() + RegulatorTypeEnum(rg_type_text) + data = {} + for key in regulator_attr.__dict__: + value = read_node_text(node.joinpath(key)) + if value is not None: data[key] = value logging.info("%s: %s", key, value) + return data except ValueError: logging.error( @@ -77,22 +101,43 @@ def collect_data(self, node): node.name, rg_type_text, ) - except FileNotFoundError: - logging.error("%s regulator type does not exists", node.name) def dump_sysfs_regulator(self): for rg_dev in sorted(Path(SYS_REGULATOR_PATH).glob("regulator*")): - self.raw_regulators[rg_dev.name] = self.collect_data(rg_dev) + logging.info("- %s", rg_dev.name) + data = self.collect_data(rg_dev) + if data: + self.raw_regulators[rg_dev.name] = data def filter_regulators_by_type(self): - logging.info("\n# filtering %s regulator..", self.regulator_type) + logging.info("\n# filtering %s regulator ..", self.regulator_type) for dev in self.raw_regulators.values(): - if dev["type"] != self.regulator_type: + if RegulatorTypeEnum(dev["type"]) != self.regulator_type: logging.info("skip '%s' regulator", dev["name"]) continue - key = dev.pop("name") - self.regulators[key] = dev + rg = copy.deepcopy(dev) + key = rg.pop("name") + self.regulators[key] = rg + + def has_duplicated_regulators(self): + logging.info("\n# checking duplicated regulators ..") + name_counts = Counter( + [attrs["name"] for attrs in self.raw_regulators.values()] + ) + result = { + node: attrs["name"] + for node, attrs in self.raw_regulators.items() + if name_counts[attrs["name"]] > 1 + } + + if result: + logging.error("# Some regulators has the same name") + for node, name in result.items(): + logging.error("- node: %s, name: %s", node, name) + return True + + return False def is_regulator_available(self, name): if name in self.regulators.keys(): @@ -120,6 +165,7 @@ def summarize_test_results(details_logs): def check_difference(exp_regulators, sysfs_regulators): + logging.info("\n# comparing regulators ..") test_results = {"result": False, "logs": {}} for regulator in exp_regulators: @@ -142,18 +188,22 @@ def compare_regulators(args): regulator = RegulatorBase(type) regulator.dump_sysfs_regulator() regulator.filter_regulators_by_type() + duplicated = regulator.has_duplicated_regulators() results = check_difference(exp_regulator_devs, regulator) summarize_test_results(results["logs"]) if results["result"]: - raise SystemExit( - "\nFailed: the expected {} regulators does not match".format(type) + logging.error( + "\nFailed: the expected %s regulators does not match", type ) else: logging.info( "\nPassed: the expected %s regulators are all available", type ) + if duplicated or results["result"]: + raise SystemExit(1) + def register_arguments(): parser = argparse.ArgumentParser( @@ -171,8 +221,8 @@ def register_arguments(): parser.add_argument( "-t", "--type", - type=RegulatorEnum, - choices=list(RegulatorEnum), + type=RegulatorTypeEnum, + choices=list(RegulatorTypeEnum), help="the regulator type", ) From f5a4ddc60feb2d25c88ee05fbfcc91d6db8bee76 Mon Sep 17 00:00:00 2001 From: stanley31huang Date: Tue, 22 Jul 2025 15:17:46 +0800 Subject: [PATCH 6/6] add regulator test plan into ce-oem test plan add regulator test plan into ce-oem test plan --- .../checkbox-provider-ce-oem/units/test-plan-ce-oem.pxu | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/test-plan-ce-oem.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/test-plan-ce-oem.pxu index c5d78f0f35..176d006eed 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/test-plan-ce-oem.pxu +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/test-plan-ce-oem.pxu @@ -48,6 +48,7 @@ nested_part: ce-oem-iio-sensors-manual ce-oem-digital-io-manual ce-oem-secure-boot-manual + ce-oem-regulator-manual certification_status_overrides: apply blocker to .* @@ -90,6 +91,7 @@ nested_part: ce-oem-gadget-automated ce-oem-mir-automated ce-oem-wifi-ap-automated + ce-oem-regulator-automated ce-oem-power-automated-by-pdu certification_status_overrides: apply blocker to .* @@ -123,6 +125,7 @@ nested_part: after-suspend-ce-oem-iio-sensors-manual after-suspend-ce-oem-digital-io-manual after-suspend-ce-oem-mir-automated + after-suspend-ce-oem-regulator-manual certification_status_overrides: apply blocker to .* @@ -158,6 +161,7 @@ nested_part: after-suspend-ce-oem-iio-sensors-automated after-suspend-ce-oem-digital-io-automated after-suspend-ce-oem-spi-automated + after-suspend-ce-oem-regulator-automated certification_status_overrides: apply blocker to .*