diff --git a/dasharo-compatibility/os-opnsense.robot b/dasharo-compatibility/os-opnsense.robot new file mode 100644 index 0000000000..e1db47e835 --- /dev/null +++ b/dasharo-compatibility/os-opnsense.robot @@ -0,0 +1,74 @@ +*** Settings *** +Library Collections +Library DateTime +Library Dialogs +Library OperatingSystem +Library Process +Library String +Library Telnet timeout=20 seconds connection_timeout=120 seconds +Resource ../variables.robot +Resource ../keywords.robot +Resource ../keys.robot + +# Log Out And Close Connection - elementary teardown keyword for all tests. +Suite Setup Run Keywords +... Prepare Test Suite +Suite Teardown Run Keywords +... Log Out And Close Connection +Test Setup Run Keyword +... Restore Initial DUT Connection Method + + +*** Test Cases *** +OPN001.503 Install OPNsense (serial output) on disk + [Documentation] Install OPNsense (serial output) from preseeded + ... USB stick on disk. Make sure to use linux fatlabel command + ... to rename installer ESP to OPNBOOT. Next, please refer to + ... scripts/freebsd/preseed_opnsense.sh for OPNsense installer + ... modification. + Power On + Boot OPNsense Installer + ${installer_message}= Catenate Click OK, after test execution ends, + ... connect to DUT via serial and continue manual installation. + Pause Execution ${installer_message} + +OPN002.503 Boot OPNsense (serial output) from disk + [Documentation] Boot OPNsense (serial output) from disk. + Power On + Boot OPNsense + +OPN003.503 Boot OPNsense (serial output) from disk after cold-boot + [Documentation] Boot OPNsense (serial output) from disk after cold-boot + @{supported_power_ctrls}= Create List RteCtrl sonoff + Skip If '${POWER_CTRL}' not in ${supported_power_ctrls} + Execute Cold Boot + ${start_date}= Get Current Date + Boot OPNsense + ${end_date}= Get Current Date + ${delta_time}= Subtract Date From Date ${end_date} ${start_date} + Log To Console Cold boot duration in seconds: ${delta_time} + +OPN004.503 Boot OPNsense (serial output) from disk after warm-boot + [Documentation] Boot OPNsense (serial output) from disk after warm-boot + Power On + Boot OPNsense + Enter OPNsense Shell + Write Into Terminal poweroff + Power On + ${start_date}= Get Current Date + Boot OPNsense + ${end_date}= Get Current Date + ${delta_time}= Subtract Date From Date ${end_date} ${start_date} + Log To Console Warm boot duration in seconds: ${delta_time} + +OPN005.503 Boot OPNsense (serial output) from disk after reboot + [Documentation] Boot OPNsense (serial output) from disk after reboot + Power On + Boot OPNsense + Enter OPNsense Shell + Write Into Terminal reboot + ${start_date}= Get Current Date + Boot OPNsense + ${end_date}= Get Current Date + ${delta_time}= Subtract Date From Date ${end_date} ${start_date} + Log To Console Reboot duration in seconds: ${delta_time} diff --git a/dasharo-compatibility/os-pfsense.robot b/dasharo-compatibility/os-pfsense.robot new file mode 100644 index 0000000000..f147dbe363 --- /dev/null +++ b/dasharo-compatibility/os-pfsense.robot @@ -0,0 +1,103 @@ +*** Settings *** +Library Collections +Library DateTime +Library Dialogs +Library OperatingSystem +Library Process +Library String +Library Telnet timeout=20 seconds connection_timeout=120 seconds +Resource ../variables.robot +Resource ../keywords.robot +Resource ../keys.robot + +# Log Out And Close Connection - elementary teardown keyword for all tests. +Suite Setup Run Keywords +... Prepare Test Suite +Suite Teardown Run Keywords +... Log Out And Close Connection +Test Setup Run Keyword +... Restore Initial DUT Connection Method + + +*** Test Cases *** +PFS001.502 Install pfSense LTS CE (serial output) on disk + [Documentation] Install pfSense LTS CE (serial output) from preseeded + ... USB stick on disk. Refer to test case PFS006.502 for preseed. + Power On + Boot PfSense Installer + ${installer_message}= Catenate Click OK, after test execution ends, + ... connect to DUT via serial and continue manual installation. + Pause Execution ${installer_message} + +PFS002.502 Boot pfSense LTS CE (serial output) from disk + [Documentation] Boot pfSense LTS CE (serial output) from disk. + Power On + Boot PfSense + +PFS003.502 Boot pfSense LTS CE (serial output) from disk after cold-boot + [Documentation] Boot pfSense LTS CE (serial output) from disk after cold-boot + @{supported_power_ctrls}= Create List RteCtrl sonoff + Skip If '${POWER_CTRL}' not in ${supported_power_ctrls} + Execute Cold Boot + ${start_date}= Get Current Date + Boot PfSense + ${end_date}= Get Current Date + ${delta_time}= Subtract Date From Date ${end_date} ${start_date} + Log To Console Cold boot duration in seconds: ${delta_time} + +PFS004.502 Boot pfSense LTS CE (serial output) from disk after warm-boot + [Documentation] Boot pfSense LTS CE (serial output) from disk after warm-boot + Power On + Boot PfSense + Enter PfSense Shell + Write Into Terminal poweroff + Power On + ${start_date}= Get Current Date + Boot PfSense + ${end_date}= Get Current Date + ${delta_time}= Subtract Date From Date ${end_date} ${start_date} + Log To Console Warm boot duration in seconds: ${delta_time} + +PFS005.502 Boot pfSense LTS CE (serial output) from disk after reboot + [Documentation] Boot pfSense LTS CE (serial output) from disk after reboot + Power On + Boot PfSense + Enter PfSense Shell + Write Into Terminal reboot + ${start_date}= Get Current Date + Boot PfSense + ${end_date}= Get Current Date + ${delta_time}= Subtract Date From Date ${end_date} ${start_date} + Log To Console Reboot duration in seconds: ${delta_time} + +PFS006.502 Preseed pfSense Installer (serial output) + [Documentation] Please use linux fatlabel program to rename ESP partition of + ... pfSense installer to PFEFI. + ${pfefi_message}= Catenate SEPARATOR=${SPACE} Rename ESP partition of pfSense + ... serial installer to PFEFI.\nOn Linux: (sudo) fatlabel /dev/sdX1 PFEFI + Execute Manual Step ${pfefi_message} + Execute Manual Step Connect pfSense serial installer USB stick to DUT. + + Power On + Boot PfSense Installer + Enter PfSense Rescue Shell + ${awk_args}= Catenate SEPARATOR=${SPACE} -v sq="'" -v dq='"' + ... -v ROOT_LABEL=PFBOOT '/^NEWFS_ESP=/ { print "NEWFS_ESP=" + ... sq "newfs_msdos -L " ROOT_LABEL " " dq "%s" dq sq; next; }; + ... { print; }' + Execute Command In Terminal + ... awk ${awk_args} /usr/libexec/bsdinstall/zfsboot > /tmp/zfsboot + Execute Command In Terminal mount -u / + Execute Command In Terminal mv /tmp/zfsboot /usr/libexec/bsdinstall/zfsboot + Execute Command In Terminal chmod +x /usr/libexec/bsdinstall/zfsboot + Execute Command In Terminal sync + ${output}= Execute Command In Terminal grep PFBOOT /usr/libexec/bsdinstall/zfsboot + Should Contain ${output} PFBOOT + +PFS007.502 Boot pfSense Installer (serial output) into rescue shell + Power On + Boot PfSense Installer + Enter PfSense Rescue Shell + ${output}= Execute Command In Terminal ls + Should Contain ${output} COPYRIGHT + Should Contain ${output} .profile diff --git a/keys.robot b/keys.robot index 39a50f7d44..abc652aa76 100644 --- a/keys.robot +++ b/keys.robot @@ -1,26 +1,30 @@ *** Variables *** -${ARROW_UP}= \x1b\x5b\x41 -${ARROW_DOWN}= \x1b\x5b\x42 -${ARROW_RIGHT}= \x1b\x5b\x43 -${ARROW_LEFT}= \x1b\x5b\x44 -${F1}= \x1b\x4f\x50 -${F2}= \x1b\x4f\x51 -${F3}= \x1b\x4f\x52 -${F4}= \x1b\x4f\x53 -${F5}= \x1b\x5b\x31\x35\x7e -${F6}= \x1b\x5b\x31\x37\x7e -${F7}= \x1b\x5b\x31\x38\x7e -${F8}= \x1b\x5b\x31\x39\x7e -${F9}= \x1b\x5b\x32\x30\x7e -${F10}= \x1b\x5b\x32\x31\x7e -${F11}= \x1b\x5b\x32\x33\x7e -${F12}= \x1b\x5b\x32\x34\x7e -${CTRL_B}= \x02 -${CTRL_C}= \x03 -${CTRL_D}= \x04 -${ESC}= \x1b -${ENTER}= \x0d -${BACKSPACE}= \x08 -${KEY_SPACE}= \x20 -${DELETE}= \x1b\x5b\x33\x7e -${KEY_PLUS}= \x2b +${ARROW_UP}= \x1b\x5b\x41 +${ARROW_DOWN}= \x1b\x5b\x42 +${ARROW_RIGHT}= \x1b\x5b\x43 +${ARROW_LEFT}= \x1b\x5b\x44 +${ARROW_UP_APP}= \x1b\x4f\x41 +${ARROW_DOWN_APP}= \x1b\x4f\x42 +${ARROW_RIGHT_APP}= \x1b\x4f\x43 +${ARROW_LEFT_APP}= \x1b\x4f\x44 +${F1}= \x1b\x4f\x50 +${F2}= \x1b\x4f\x51 +${F3}= \x1b\x4f\x52 +${F4}= \x1b\x4f\x53 +${F5}= \x1b\x5b\x31\x35\x7e +${F6}= \x1b\x5b\x31\x37\x7e +${F7}= \x1b\x5b\x31\x38\x7e +${F8}= \x1b\x5b\x31\x39\x7e +${F9}= \x1b\x5b\x32\x30\x7e +${F10}= \x1b\x5b\x32\x31\x7e +${F11}= \x1b\x5b\x32\x33\x7e +${F12}= \x1b\x5b\x32\x34\x7e +${CTRL_B}= \x02 +${CTRL_C}= \x03 +${CTRL_D}= \x04 +${ESC}= \x1b +${ENTER}= \x0d +${BACKSPACE}= \x08 +${KEY_SPACE}= \x20 +${DELETE}= \x1b\x5b\x33\x7e +${KEY_PLUS}= \x2b diff --git a/keywords.robot b/keywords.robot index 105fa04d66..20072cc6de 100644 --- a/keywords.robot +++ b/keywords.robot @@ -15,6 +15,7 @@ Resource lib/sleep-lib.robot Resource lib/framework.robot Resource lib/me.robot Resource lib/network.robot +Resource lib/bsd.robot *** Keywords *** diff --git a/lib/bios/menus.py b/lib/bios/menus.py index 6dda394754..7213db73ef 100644 --- a/lib/bios/menus.py +++ b/lib/bios/menus.py @@ -217,6 +217,11 @@ def merge_lists(list1, list2): "Power Management Options", "CPU Throttling", ], + "PowerStateAfterPowerAcLoss": [ + "Dasharo System Features", + "Power Management Options", + "Power state after", + ], } diff --git a/lib/bios/menus.robot b/lib/bios/menus.robot index 74cde9acf2..ae35b90ef1 100644 --- a/lib/bios/menus.robot +++ b/lib/bios/menus.robot @@ -468,17 +468,22 @@ Enter Submenu From Snapshot ... === Arguments === ... - ``${menu}``: ``string`` - the submenu construction or snapshot ... - ``${option}``: ``string`` - the name of the submenu to enter + ... - ``${cursor_key_mode}``: ``string`` - VT100 cursor key mode, APP for BSD ... ... === Return Value === ... None ... ... === Effects === ... - A setup submenu is entered - [Arguments] ${menu} ${option} + [Arguments] ${menu} ${option} ${cursor_key_mode}="ST" ${index}= Get Index Of Matching Option In Menu ${menu} ${option} Should Not Be Equal As Integers ${index} -1 msg=Option ${option} not found in menu - Press Key N Times And Enter ${index} ${ARROW_DOWN} + IF ${cursor_key_mode} == "APP" + Press Key N Times And Enter ${index} ${ARROW_DOWN_APP} + ELSE + Press Key N Times And Enter ${index} ${ARROW_DOWN} + END Enter Submenu From Snapshot And Return Construction [Documentation] Enter given Setup Menu Tianocore option after entering diff --git a/lib/bsd.robot b/lib/bsd.robot new file mode 100644 index 0000000000..93f7b2b4e7 --- /dev/null +++ b/lib/bsd.robot @@ -0,0 +1,80 @@ +*** Settings *** +Library Collections +Resource ../keywords.robot +Resource ../lib/platform/power.robot + + +*** Keywords *** +Boot PfSense Installer + [Documentation] Run /EFI/BOOT/bootx64.efi file from PFEFI-labeled partition; + ... Select console type vt100 and accept the license + Enter Boot From File + Enter Volume In File Explorer PFEFI + Execute File In File Explorer EFI + Execute File In File Explorer BOOT + Execute File In File Explorer bootx64.efi + Read From Terminal Until Console type [vt100]: + Write Into Terminal vt100 + Read From Terminal Until [Accept] + Press Enter + Set Suite Variable ${BOOTED_OS_ID} ${ENV_ID_PFSENSE} + Import Variables ${CURDIR}/../os-config/${BOOTED_OS_ID}-credentials.py + +Boot OPNsense Installer + [Documentation] Run /efi/boot/bootx64.efi file from OPNEFI-labeled partition; + Enter Boot From File + Enter Volume In File Explorer OPNEFI + Execute File In File Explorer efi + Execute File In File Explorer boot + Execute File In File Explorer bootx64.efi + Read From Terminal Until FreeBSD/amd64 (OPNsense.localdomain) (ttyu0) + Read From Terminal Until login: + Set Suite Variable ${BOOTED_OS_ID} ${ENV_ID_OPNSENSE} + Import Variables ${CURDIR}/../os-config/${BOOTED_OS_ID}-credentials.py + +Enter PfSense Shell + Write Into Terminal 8 + Read From Terminal Until ${DEVICE_OS_ROOT_PROMPT} + Set Prompt For Terminal ${DEVICE_OS_ROOT_PROMPT} + +Enter PfSense Rescue Shell + ${menu}= Read From Terminal Until + # end would be 5 but it's 3 due to two empty lines + ${construction}= Parse Menu Snapshot Into Construction ${menu} 5 3 + Enter Submenu From Snapshot + ... ${construction} + ... Rescue Shell Launch a shell for rescue operations + ... "APP" + Set Prompt For Terminal ${DEVICE_OS_RESCUE_PROMPT} + +Enter OPNsense Shell + Read From Terminal Until login: + Write Into Terminal ${DEVICE_OS_USERNAME} + Read From Terminal Until Password: + Write Into Terminal ${DEVICE_OS_PASSWORD} + Read From Terminal Until Enter an option: + Write Into Terminal 8 + Read From Terminal Until ${DEVICE_OS_ROOT_PROMPT} + Set Prompt For Terminal ${DEVICE_OS_ROOT_PROMPT} + +Boot PfSense + [Documentation] PFBOOT -> /efi/boot/bootx64.efi + Enter Boot From File + Enter Volume In File Explorer PFBOOT + Execute File In File Explorer efi + Execute File In File Explorer boot + Execute File In File Explorer bootx64.efi + Read From Terminal Until Enter an option: + Set Suite Variable ${BOOTED_OS_ID} ${ENV_ID_PFSENSE} + Import Variables ${CURDIR}/../os-config/${BOOTED_OS_ID}-credentials.py + +Boot OPNsense + [Documentation] OPNBOOT -> /efi/boot/bootx64.efi + Enter Boot From File + Enter Volume In File Explorer OPNBOOT + Execute File In File Explorer efi + Execute File In File Explorer boot + Execute File In File Explorer bootx64.efi + Read From Terminal Until FreeBSD/amd64 (OPNsense.localdomain) (ttyu0) + Set Suite Variable ${BOOTED_OS_ID} ${ENV_ID_OPNSENSE} + Import Variables ${CURDIR}/../os-config/${BOOTED_OS_ID}-credentials.py diff --git a/lib/platform/power.robot b/lib/platform/power.robot index 27e48ecb63..298b0dc2bb 100644 --- a/lib/platform/power.robot +++ b/lib/platform/power.robot @@ -105,3 +105,20 @@ Power Cycle Into Windows Power Cycle Into Firmware Setup Power On Enter Setup Menu Tianocore + +Execute Cold Boot + [Documentation] Performs cold boot, either with RTE relay or Sonoff + Power On + Set UEFI Option PowerStateAfterPowerAcLoss Powered On + Sleep 2 + IF '${POWER_CTRL}' == 'RteCtrl' + Rte Psu Off + ELSE IF '${POWER_CTRL}' == 'sonoff' + Sonoff Off + END + Sleep 12 + IF '${POWER_CTRL}' == 'RteCtrl' + Rte Psu On + ELSE IF '${POWER_CTRL}' == 'sonoff' + Sonoff On + END diff --git a/os-config/502-credentials.py b/os-config/502-credentials.py new file mode 100644 index 0000000000..76049ca9a0 --- /dev/null +++ b/os-config/502-credentials.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2025 3mdeb +# +# SPDX-License-Identifier: Apache-2.0 + +DEVICE_OS_USERNAME = "root" +DEVICE_OS_PASSWORD = "pfsense" +DEVICE_OS_HOSTNAME = "pfSense.home.arpa" + +DEVICE_OS_ROOT_PROMPT = ( + f"[2.7.2-RELEASE][{DEVICE_OS_USERNAME}@{DEVICE_OS_HOSTNAME}]/{DEVICE_OS_USERNAME}" +) +DEVICE_OS_RESCUE_PROMPT = "#" diff --git a/os-config/503-credentials.py b/os-config/503-credentials.py new file mode 100644 index 0000000000..5e313c5986 --- /dev/null +++ b/os-config/503-credentials.py @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2025 3mdeb +# +# SPDX-License-Identifier: Apache-2.0 + +DEVICE_OS_USERNAME = "root" +DEVICE_OS_PASSWORD = "opnsense" + +DEVICE_OS_ROOT_PROMPT = f"{DEVICE_OS_USERNAME}@OPNsense:~ #" diff --git a/os-config/environment-test-ids.py b/os-config/environment-test-ids.py index fa01ddf12a..ba48228099 100644 --- a/os-config/environment-test-ids.py +++ b/os-config/environment-test-ids.py @@ -21,6 +21,11 @@ # 4xx - Other ENV_ID_ESXI = "401" # ESXi +# 5xx - BSD +ENV_ID_FREEBSD = "501" +ENV_ID_PFSENSE = "502" +ENV_ID_OPNSENSE = "503" + ENV_ID_OS_BOOTMENU_NAMES = { ENV_ID_UBUNTU: "Ubuntu", ENV_ID_FEDORA: "Fedora", diff --git a/scripts/freebsd/preseed_opnsense.sh b/scripts/freebsd/preseed_opnsense.sh new file mode 100644 index 0000000000..9f0930d86e --- /dev/null +++ b/scripts/freebsd/preseed_opnsense.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2025 3mdeb +# +# SPDX-License-Identifier: Apache-2.0 + +LABEL=OPNBOOT +INSTALLER_ROOT_PARTITION=/dev/da0p4 +INSTALLER_MOUNT_DIR=/mnt +BSDINSTALL_DIR=/usr/libexec/bsdinstall +TARGET_FILES="opnsense-zfs zfsboot" + +echo FreeBSD+OPNsense bsdinstall modifier +echo +echo "WARNING: This script is supposed to be executed on any FreeBSD-compatible system." +echo "Please connect OPNsense Installer USB stick and verify it's root partition device name to be: " ${INSTALLER_ROOT_PARTITION} +echo "Please type 'yes' to continue." +echo + +read ANSWER_WARN +if [ $ANSWER_WARN != yes ]; +then + exit 1; +fi + +# patch_esp_command $new_esp_label $file_prefix $file_to_patch +patch_esp_command() +{ + local new_esp_label="$1" file_prefix="$2" file_to_patch="$3" + echo + echo ${new_esp_label} "->" ${file_prefix}/${file_to_patch} + + awk -v sq="'" -v dq='"' -v ROOT_LABEL=${new_esp_label} '/^NEWFS_ESP=/ { print "NEWFS_ESP=" sq "newfs_msdos -L " ROOT_LABEL " " dq "%s" dq sq; next; }; { print; }' ${file_prefix}/${file_to_patch} > /tmp/${file_to_patch} + echo " -- DIFF:" + diff /tmp/${file_to_patch} ${INSTALLER_MOUNT_DIR}${BSDINSTALL_DIR}/${file_to_patch} + echo "--- END OF DIFF" + + echo Do you want to apply? Type 'yes'. + echo + + read ANSWER_DIFF + if [ $ANSWER_DIFF != yes ]; + then + return + fi + mv /tmp/${file_to_patch} ${file_prefix}/${file_to_patch} + chmod +x ${file_prefix}/${file_to_patch} +} + +umount ${INSTALLER_MOUNT_DIR} +mount -w /dev/da0p4 ${INSTALLER_MOUNT_DIR} +ls -l ${INSTALLER_MOUNT_DIR}${BSDINSTALL_DIR}/*zfs* + +for installer_file in ${TARGET_FILES}; do + patch_esp_command ${LABEL} ${INSTALLER_MOUNT_DIR}${BSDINSTALL_DIR} ${installer_file} +done + +umount ${INSTALLER_MOUNT_DIR} +echo "It is done." diff --git a/test_cases.json b/test_cases.json index ea8c375526..79826ce666 100644 --- a/test_cases.json +++ b/test_cases.json @@ -10077,5 +10077,89 @@ "name": "Bluetooth scanning (Fedora)", "module": "Dasharo Compatibility" } + }, + { + "doc": { + "_id": "PFS001.502", + "name": "Install pfSense LTS CE (serial output) on disk", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "PFS002.502", + "name": "Boot pfSense LTS CE (serial output) from disk", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "PFS003.502", + "name": "Boot pfSense LTS CE (serial output) from disk after cold-boot", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "PFS004.502", + "name": "Boot pfSense LTS CE (serial output) from disk after warm-boot", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "PFS005.502", + "name": "Boot pfSense LTS CE (serial output) from disk after reboot", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "PFS006.502", + "name": "Preseed pfSense Installer (serial output)", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "PFS007.502", + "name": "Boot pfSense Installer (serial output) into rescue shell", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "OPN001.503", + "name": "Install OPNsense (serial output) on disk", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "OPN002.503", + "name": "Boot OPNsense (serial output) from disk", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "OPN003.503", + "name": "Boot OPNsense (serial output) from disk after cold-boot", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "OPN004.503", + "name": "Boot OPNsense (serial output) from disk after warm-boot", + "module": "Dasharo Compatibility" + } + }, + { + "doc": { + "_id": "OPN005.503", + "name": "Boot OPNsense (serial output) from disk after reboot", + "module": "Dasharo Compatibility" + } } ]