diff --git a/checkbox-provider-ce-oem/bin/env-setup.py b/checkbox-provider-ce-oem/bin/env_setup.py similarity index 69% rename from checkbox-provider-ce-oem/bin/env-setup.py rename to checkbox-provider-ce-oem/bin/env_setup.py index 86211c0..342a888 100755 --- a/checkbox-provider-ce-oem/bin/env-setup.py +++ b/checkbox-provider-ce-oem/bin/env_setup.py @@ -2,6 +2,7 @@ import json import logging import argparse +import os from checkbox_support.snap_utils.snapd import Snapd from checkbox_support.snap_utils.system import get_gadget_snap @@ -9,39 +10,6 @@ "test-strict-confinement": { "channel": "edge", "plugs": { - "jace-bt-led": { - "gadget": "bt-led", - }, - "jace-hb-led": { - "gadget": "hb-led", - }, - "jace-shutdown-led": { - "gadget": "shutdown-led", - }, - "jace-status-led": { - "gadget": "status-led", - }, - "jace-wifi-grn-led": { - "gadget": "wifi-grn-led", - }, - "jace-wifi-yel-led": { - "gadget": "wifi-yel-led", - }, - "thermal": { - "snapd": "hardware-observe", - }, - "button": { - "snapd": "device-buttons", - }, - "time": { - "snapd": "time-control", - }, - "serial": { - "snapd": "raw-usb", - }, - "media-card": { - "snapd": "removable-media", - }, "power-management": { "snapd": "shutdown", }, @@ -51,7 +19,7 @@ logging.basicConfig( - level=logging.DEBUG, + level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[ logging.StreamHandler(), @@ -72,34 +40,40 @@ def get_snap_plugs(snapd, snap): List[str]: A list of plugs associated with the specified snap. """ snap_plugs = [] - for x in snapd.interfaces()["plugs"]: - if x["snap"] == snap: - snap_plugs.append(x["plug"]) + for plug in snapd.interfaces()["plugs"]: + if plug["snap"] == snap: + snap_plugs.append(plug["plug"]) return snap_plugs def get_config(config_file, config_path): """ Load and retrieve the configuration from a JSON file. - Parameters: - - config_file (dict): The default configuration dictionary. - config_path (str): The path to the JSON configuration file. - Returns: - dict: The loaded configuration dictionary. Return default - config file if not found additional one. + dict: The loaded configuration dictionary. Returns DEFAULT_CONFIG_FILE + if config_path is empty, not provided, or does not meet criteria. """ - if config_path: + if not config_path: + logging.info("Config path not provided. Using default config.") + # Check if the path exists and has a .json extension + elif os.path.exists(config_path) and config_path.lower().endswith('.json'): try: - config_file = json.load(open(config_path)) - return config_file + with open(config_path) as file: + return json.load(file) except FileNotFoundError: - logging.warning("Config file {} not found".format(config_path)) - logging.info("Using default config.") - return config_file + logging.warning("Config file %s not found. Using default config.", + config_path) + except json.JSONDecodeError as e: + logging.warning("Error decoding JSON in %s: %s. Using default " + "config.", + config_path, e) else: - return config_file + logging.warning("Invalid config path: %s. Using default config.", + config_path) + + return config_file def connect_interfaces(snapd, @@ -130,27 +104,24 @@ def connect_interfaces(snapd, slot_snap = get_gadget_snap() try: logging.info("Attempting to connect interface " - "\"{}:{}\" \"{}:{}\"" - .format(plug_snap, - plug, - slot_snap, - slot_plug)) + "\"%s:%s\" \"%s:%s\"", + plug_snap, plug, slot_snap, slot_plug + ) snapd.connect(slot_snap, slot_plug, plug_snap, plug) except Exception as err: status = False - logging.error("Not able to connect plug \"{}:{}\" " - "to slot \"{}:{}\"." - .format(plug_snap, - plug, - slot_snap, - slot_plug)) + logging.error("Not able to connect plug \"%s:%s\" " + "to slot \"%s:%s\".", + plug_snap, plug, slot_snap, slot_plug + ) logging.error(err) else: - logging.error("Expect plug \"{}\" not in the snap \"{}\"." - .format(plug, plug_snap)) + logging.error("Expect plug \"%s\" not in the snap \"%s\".", + plug, plug_snap + ) status = False return status @@ -197,7 +168,7 @@ def main(): snapd = Snapd() config_file = get_config(CONFIG_FILE, args.file) for plug_snap in config_file.keys(): - logging.info("Attempting to install {}".format(plug_snap)) + logging.info("Attempting to install %s snap", plug_snap) if not snapd.list(plug_snap): try: snapd.install(plug_snap, diff --git a/checkbox-provider-ce-oem/tests/test_env_setup.py b/checkbox-provider-ce-oem/tests/test_env_setup.py new file mode 100755 index 0000000..17e9c8a --- /dev/null +++ b/checkbox-provider-ce-oem/tests/test_env_setup.py @@ -0,0 +1,103 @@ +import unittest +from unittest.mock import patch, mock_open +import json +import env_setup + + +class TestGetConfig(unittest.TestCase): + + @patch('os.path.exists', return_value=True) + def test_valid_config_file(self, mock_exists): + config_path = '/path/to/valid_config.json' + mock_file_content = '{"key": "value"}' + config_file = {} + with patch('builtins.open', mock_open( + read_data=mock_file_content)) as mock_file: + config = env_setup.get_config(config_file, config_path) + + mock_file.assert_called_once_with(config_path) + self.assertEqual(config, {"key": "value"}) + + def test_invalid_config_file(self): + config_path = '/path/to/invalid_config.json' + config_file = { + "test-strict-confinement": { + "channel": "edge", + "plugs": { + "jace-bt-led": { + "gadget": "bt-led", + }, + }, + }, + } + + with patch('builtins.open', side_effect=json.JSONDecodeError): + config = env_setup.get_config(config_file, config_path) + + self.assertEqual(config, + { + "test-strict-confinement": { + "channel": "edge", + "plugs": { + "jace-bt-led": { + "gadget": "bt-led", + }, + }, + }, + }) + + def test_nonexistent_config_file(self): + config_path = '/path/to/nonexistent_config.json' + config_file = { + "test-strict-confinement": { + "channel": "edge", + "plugs": { + "jace-bt-led": { + "gadget": "bt-led", + }, + }, + }, + } + + with patch('builtins.open', side_effect=FileNotFoundError): + config = env_setup.get_config(config_file, config_path) + + self.assertEqual(config, + { + "test-strict-confinement": { + "channel": "edge", + "plugs": { + "jace-bt-led": { + "gadget": "bt-led", + }, + }, + }, + }) + # Additional checks/assertions if needed + + def test_empty_config_path(self): + config_path = '' + config_file = { + "test-strict-confinement": { + "channel": "edge", + "plugs": { + "jace-bt-led": { + "gadget": "bt-led", + }, + }, + }, + } + + config = env_setup.get_config(config_file, config_path) + + self.assertEqual(config, + { + "test-strict-confinement": { + "channel": "edge", + "plugs": { + "jace-bt-led": { + "gadget": "bt-led", + }, + }, + }, + }) diff --git a/checkbox-provider-ce-oem/units/strict-confinement/README.md b/checkbox-provider-ce-oem/units/strict-confinement/README.md index be1a26b..ad5fee5 100644 --- a/checkbox-provider-ce-oem/units/strict-confinement/README.md +++ b/checkbox-provider-ce-oem/units/strict-confinement/README.md @@ -2,7 +2,9 @@ The test jobs under this category are intended to test the Ubuntu Core functions in snap strict confinement mode. This means snap needs the right to access system resources by connecting interfaces. +Running script *env_setup.py* to install and connect the interface before +testing. ## id: dbus-{cold|warm}-boot-loop-reboot Those jobs call dbus command to let system go into cold or warm reboot status. -And it rely on the snapd interface *shutdown*. \ No newline at end of file +And it rely on the snapd interface *shutdown*. diff --git a/checkbox-provider-ce-oem/units/strict-confinement/category.pxu b/checkbox-provider-ce-oem/units/strict-confinement/category.pxu index e32a16b..45ba278 100644 --- a/checkbox-provider-ce-oem/units/strict-confinement/category.pxu +++ b/checkbox-provider-ce-oem/units/strict-confinement/category.pxu @@ -1,3 +1,3 @@ unit: category id: strict-confinement-mode -_name: Test for strict confinement mode in Uubuntu Core +_name: Test for strict confinement mode in Ubuntu Core diff --git a/checkbox-provider-ce-oem/units/strict-confinement/env-setup.pxu b/checkbox-provider-ce-oem/units/strict-confinement/env-setup.pxu deleted file mode 100644 index 717b718..0000000 --- a/checkbox-provider-ce-oem/units/strict-confinement/env-setup.pxu +++ /dev/null @@ -1,8 +0,0 @@ -id: test-strict-confinement-env-setup -_summary: Install and connect interface of test-strict-confinement snap. -_purpose: Install and connect interface of test-strict-confinement snap for strict confinement test. -plugin: shell -user: root -category_id: strict-confinement-mode -estimated_duration: 30 -command: env-setup.py diff --git a/checkbox-provider-ce-oem/units/strict-confinement/powermanagement-strict-confinement.pxu b/checkbox-provider-ce-oem/units/strict-confinement/powermanagement-strict-confinement.pxu new file mode 100644 index 0000000..efa50a4 --- /dev/null +++ b/checkbox-provider-ce-oem/units/strict-confinement/powermanagement-strict-confinement.pxu @@ -0,0 +1,71 @@ +id: dbus-cold-boot-reboot +category_id: strict-confinement-mode +_summary: Perform cold reboot via dbus +_description: This test will check your system shutdown/booting cycle via dbus command. +unit: job +plugin: shell +environ: STRESS_BOOT_WAKEUP_DELAY RTC_DEVICE_FILE +command: + set -e + rtcwake -d "${RTC_DEVICE_FILE:-rtc0}" -v -m on -s "${STRESS_BOOT_WAKEUP_DELAY:-120}" & + test-strict-confinement.reboot cold +user: root +flags: preserve-locale noreturn autorestart +estimated_duration: 180.0 +imports: + from com.canonical.certification import snap + from com.canonical.certification import lsb +requires: + lsb.distributor_id == 'Ubuntu Core' + snap.name == 'test-strict-confinement' +depends: com.canonical.certification::init-boot-loop-data + + +id: dbus-cold-boot-test +category_id: strict-confinement-mode +_summary: Cold boot system configuration test via dbus +_description: This is a job to check system bootup without error after cold reboot. +unit: job +plugin: shell +environ: LD_LIBRARY_PATH +command: + reboot_check_test.sh -c "$PLAINBOX_SESSION_SHARE/before_reboot" -d "$PLAINBOX_SESSION_SHARE/cold_reboot" -s -f +user: root +flags: preserve-locale +estimated_duration: 1.0 +depends: dbus-cold-boot-reboot + + +id: dbus-warm-boot-reboot +category_id: strict-confinement-mode +_summary: Perform warm reboot via dbus +_description: Perform warm reboot of the system via dbus command. +unit: job +plugin: shell +command: + test-strict-confinement.reboot warm +user: root +flags: preserve-locale noreturn autorestart +estimated_duration: 60s +imports: + from com.canonical.certification import snap + from com.canonical.certification import lsb +requires: + lsb.distributor_id == 'Ubuntu Core' + snap.name == 'test-strict-confinement' +depends: com.canonical.certification::init-boot-loop-data + + +id: dbus-warm-boot-test +category_id: strict-confinement-mode +_summary: Warm boot system configuration test via dbus +_description: This is a job to check system bootup without error after warm reboot. +unit: job +plugin: shell +environ: LD_LIBRARY_PATH +command: + reboot_check_test.sh -c "$PLAINBOX_SESSION_SHARE/before_reboot" -d "$PLAINBOX_SESSION_SHARE/warm_reboot" -s -f +user: root +flags: preserve-locale +estimated_duration: 1.0 +depends: dbus-warm-boot-reboot diff --git a/checkbox-provider-ce-oem/units/strict-confinement/stress-strict-confinement.pxu b/checkbox-provider-ce-oem/units/strict-confinement/stress-strict-confinement.pxu deleted file mode 100644 index 506a0fe..0000000 --- a/checkbox-provider-ce-oem/units/strict-confinement/stress-strict-confinement.pxu +++ /dev/null @@ -1,174 +0,0 @@ -id: dbus-cold-boot-loop-reboot1 -category_id: strict-confinement-mode -_summary: Perform cold reboot 1 via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is how the device will be request a - reboot. -unit: job -plugin: shell -environ: STRESS_BOOT_WAKEUP_DELAY RTC_DEVICE_FILE -command: - set -e - rtcwake -d "${RTC_DEVICE_FILE:-rtc0}" -v -m on -s "${STRESS_BOOT_WAKEUP_DELAY:-120}" & - test-strict-confinement.reboot cold -user: root -flags: preserve-locale noreturn autorestart -estimated_duration: 180.0 -imports: - from com.canonical.certification import snap - from com.canonical.certification import lsb -requires: - lsb.distributor_id == 'Ubuntu Core' - snap.name == 'test-strict-confinement' -depends: com.canonical.certification::init-boot-loop-data - - -id: dbus-cold-boot-loop-reboot{reboot_id} -category_id: strict-confinement-mode -_summary: Perform cold reboot {reboot_id} via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is how the device will be request a - reboot. -unit: template -template-resource: com.canonical.certification::reboot-run-generator -template-unit: job -plugin: shell -environ: STRESS_BOOT_WAKEUP_DELAY STRESS_BOOT_WAIT_DELAY RTC_DEVICE_FILE -command: - set -e - sleep "${{STRESS_BOOT_WAIT_DELAY:-120}}" - rtcwake -d "${{RTC_DEVICE_FILE:-rtc0}}" -v -m on -s "${{STRESS_BOOT_WAKEUP_DELAY:-120}}" & - test-strict-confinement.reboot cold -user: root -flags: preserve-locale noreturn autorestart -estimated_duration: 180.0 -imports: - from com.canonical.certification import snap - from com.canonical.certification import lsb -requires: - lsb.distributor_id == 'Ubuntu Core' - snap.name == 'test-strict-confinement' -after: dbus-cold-boot-loop-test{reboot_id_previous} -depends: com.canonical.certification::init-boot-loop-data - - -id: dbus-cold-boot-loop-test1 -category_id: strict-confinement-mode -_summary: Cold boot system configuration test 1 via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is the test that will be performed - on each cycle to verify that all hardware is detected. -unit: job -plugin: shell -environ: LD_LIBRARY_PATH -command: - reboot_check_test.sh -c "$PLAINBOX_SESSION_SHARE/before_reboot" -d "$PLAINBOX_SESSION_SHARE/cold_reboot_cycle1" -s -f -user: root -flags: preserve-locale -estimated_duration: 1.0 -depends: dbus-cold-boot-loop-reboot1 - - -id: dbus-cold-boot-loop-test{reboot_id} -category_id: strict-confinement-mode -_summary: Cold boot system configuration test {reboot_id} via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is the test that will be performed - on each cycle to verify that all hardware is detected. -unit: template -template-resource: com.canonical.certification::reboot-run-generator -template-unit: job -plugin: shell -environ: LD_LIBRARY_PATH -command: - reboot_check_test.sh -c "$PLAINBOX_SESSION_SHARE/before_reboot" -d "$PLAINBOX_SESSION_SHARE/cold_reboot_cycle{reboot_id}" -s -f -user: root -flags: preserve-locale -estimated_duration: 1.0 -depends: dbus-cold-boot-loop-reboot{reboot_id} - - -id: dbus-warm-boot-loop-reboot1 -category_id: strict-confinement-mode -_summary: Perform warm reboot 1 via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is how the device will be request a - reboot. -unit: job -plugin: shell -command: - test-strict-confinement.reboot warm -user: root -flags: preserve-locale noreturn autorestart -estimated_duration: 60s -imports: - from com.canonical.certification import snap - from com.canonical.certification import lsb -requires: - lsb.distributor_id == 'Ubuntu Core' - snap.name == 'test-strict-confinement' -depends: com.canonical.certification::init-boot-loop-data - - -id: dbus-warm-boot-loop-reboot{reboot_id} -category_id: strict-confinement-mode -_summary: Perform warm reboot {reboot_id} via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is how the device will be request a - reboot. -unit: template -template-resource: com.canonical.certification::reboot-run-generator -template-unit: job -plugin: shell -environ: STRESS_BOOT_WAIT_DELAY -command: - set -e - sleep "${{STRESS_BOOT_WAIT_DELAY:-120}}" - test-strict-confinement.reboot warm -user: root -flags: preserve-locale noreturn autorestart -estimated_duration: 60.0 -imports: - from com.canonical.certification import snap - from com.canonical.certification import lsb -requires: - lsb.distributor_id == 'Ubuntu Core' - snap.name == 'test-strict-confinement' -after: dbus-warm-boot-loop-test{reboot_id_previous} -depends: com.canonical.certification::init-boot-loop-data - - -id: dbus-warm-boot-loop-test1 -category_id: strict-confinement-mode -_summary: Warm boot system configuration test 1 via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is the test that will be performed - on each cycle to verify that all hardware is detected. -unit: job -plugin: shell -environ: LD_LIBRARY_PATH -command: - reboot_check_test.sh -c "$PLAINBOX_SESSION_SHARE/before_reboot" -d "$PLAINBOX_SESSION_SHARE/warm_reboot_cycle1" -s -f -user: root -flags: preserve-locale -estimated_duration: 1.0 -depends: dbus-warm-boot-loop-reboot1 - - -id: dbus-warm-boot-loop-test{reboot_id} -category_id: strict-confinement-mode -_summary: Warm boot system configuration test {reboot_id} via dbus -_description: This is a template that will be used to generate a stress test - of the system boot. Specifically this is the test that will be performed - on each cycle to verify that all hardware is detected. -unit: template -template-resource: com.canonical.certification::reboot-run-generator -template-unit: job -plugin: shell -environ: LD_LIBRARY_PATH -command: - reboot_check_test.sh -c "$PLAINBOX_SESSION_SHARE/before_reboot" -d "$PLAINBOX_SESSION_SHARE/warm_reboot_cycle1" -s -f -user: root -flags: preserve-locale -estimated_duration: 1.0 -depends: dbus-warm-boot-loop-reboot{reboot_id} diff --git a/checkbox-provider-ce-oem/units/strict-confinement/test-plan-stress-strict-confinement.pxu b/checkbox-provider-ce-oem/units/strict-confinement/test-plan-stress-strict-confinement.pxu index d66e7fa..df61c67 100644 --- a/checkbox-provider-ce-oem/units/strict-confinement/test-plan-stress-strict-confinement.pxu +++ b/checkbox-provider-ce-oem/units/strict-confinement/test-plan-stress-strict-confinement.pxu @@ -1,20 +1,20 @@ -id: stress-warm-boot-dbus +id: dbus-warm-boot unit: test plan -_name: Warm reboot stress test via dbus -_description: Warm reboot stress test by using dbus command +_name: Warm reboot test via dbus +_description: Warm reboot test by using dbus command bootstrap_include: com.canonical.certification::reboot-run-generator include: - dbus-warm-boot-loop-boot.* - dbus-warm-boot-loop-test.* + dbus-warm-boot-boot + dbus-warm-boot-test -id: stress-cold-boot-dbus +id: dbus-cold-boot unit: test plan -_name: Cold boot stress test via dbus -_description: Cold boot stress test by using dbus command +_name: Cold boot test via dbus +_description: Cold boot test by using dbus command bootstrap_include: com.canonical.certification::reboot-run-generator include: - dbus-cold-boot-loop-boot.* - dbus-cold-boot-loop-test.* + dbus-cold-boot-boot + dbus-cold-boot-test diff --git a/checkbox-provider-ce-oem/units/test-plan-strict-confinement.pxu b/checkbox-provider-ce-oem/units/test-plan-strict-confinement.pxu index 39d5a6b..9111022 100644 --- a/checkbox-provider-ce-oem/units/test-plan-strict-confinement.pxu +++ b/checkbox-provider-ce-oem/units/test-plan-strict-confinement.pxu @@ -50,8 +50,7 @@ _description: Ubuntu Core QA test plan that includes all stress tests required for strict confinement mode bootstrap_include: include: - test-strict-confinement-env-setup nested_part: - stress-warm-boot-dbus - stress-cold-boot-dbus + dbus-warm-boot + dbus-cold-boot exclude: