From 2f790c13a2be2ec78678b702ae72becb02b0c40f Mon Sep 17 00:00:00 2001 From: Alexandre Fiset Date: Mon, 30 Mar 2026 15:24:31 +0200 Subject: [PATCH] ci: cram: Add cram tests for tr181-schedules Problem: Cram tests should be added to cover tr181-schedules plugin References: PCF-2297 Signed-off-by: Alexandre Fiset --- .../154-tr181-schedules.t | 149 +++++++++++++ .../155-tr181-schedules-hosts.t | 198 ++++++++++++++++++ .../tests/cram/generic/ubus-datamodel-list.t | 3 + .../020-verify-backup-restore-flags.t | 1 + .../cram/mxl25641-hdk-6/005-build-config.t | 7 + .../tests/cram/wnc-freedom/005-build-config.t | 7 + 6 files changed, 365 insertions(+) create mode 100644 .gitlab/tests/cram/generic/acceleration-plan-components/154-tr181-schedules.t create mode 100644 .gitlab/tests/cram/generic/acceleration-plan-components/155-tr181-schedules-hosts.t diff --git a/.gitlab/tests/cram/generic/acceleration-plan-components/154-tr181-schedules.t b/.gitlab/tests/cram/generic/acceleration-plan-components/154-tr181-schedules.t new file mode 100644 index 0000000000..ac57dfa359 --- /dev/null +++ b/.gitlab/tests/cram/generic/acceleration-plan-components/154-tr181-schedules.t @@ -0,0 +1,149 @@ +Create R alias: + + $ alias R="${CRAM_REMOTE_COMMAND:-}" + +Check that we have expected datamodel: + + $ R "ba-cli -lj Device.Schedules.?" | jq . + [ + { + "Device.Schedules.": { + "Enable": 1, + "ScheduleNumberOfEntries": 0 + } + } + ] + +Add two schedule objects: + + $ R "ba-cli 'Device.Schedules.Schedule.+{Alias=\"work-hours\",Day=\"Monday,Tuesday,Wednesday,Thursday,Friday\",Duration=32400, Enable=1,StartTime=\"08:00\",Description=\"Schedule active during working hours\"}'" > /dev/null 2>&1 + $ R "ba-cli 'Device.Schedules.Schedule.+{Alias=\"weekend\",Day=\"Saturday,Sunday\",Duration=0, Enable=1,StartTime=\"\",Description=\"Schedule active on saturday and sunday\"}'" > /dev/null 2>&1 + +Check that we have expected datamodel: + + $ R "ba-cli -lj Device.Schedules.Schedule.?" | jq . | sed -E 's/\.Schedule\.[0-9]+\./.Schedule.X./' + [ + { + "Device.Schedules.Schedule.X.": { + "Status": .*, (re) + "TimeLeft": \d+, (re) + "Description": "Schedule active during working hours", + "InverseMode": 0, + "Enable": 1, + "StartTime": "08:00", + "Duration": 32400, + "Day": "Monday,Tuesday,Wednesday,Thursday,Friday", + "Alias": "work-hours" + }, + "Device.Schedules.Schedule.X.": { + "Status": .*, (re) + "TimeLeft": \d+, (re) + "Description": "Schedule active on saturday and sunday", + "InverseMode": 0, + "Enable": 1, + "StartTime": "", + "Duration": 0, + "Day": "Saturday,Sunday", + "Alias": "weekend" + } + } + ] + +Verify ScheduleNumberOfEntries is updated correctly: + + $ R "ba-cli Device.Schedules.ScheduleNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Schedules.ScheduleNumberOfEntries=2 + +Verify all Schedules.Schedule.*.Status parameters are set to StackDisabled + + $ R "ba-cli Device.Schedules.Enable=0" > /dev/null 2>&1 + $ R "ba-cli Device.Schedules.Schedule.*.Status?" | tail -n +2 | sed -E 's/\.Schedule\.[0-9]+\./.Schedule.X./' | head -n -1 + Device.Schedules.Schedule.X.Status="StackDisabled" + Device.Schedules.Schedule.X.Status="StackDisabled" + +Verify all Schedules.Schedule.*.Status parameters are set to Disabled + + $ R "ba-cli Device.Schedules.Enable=1" > /dev/null 2>&1 + $ R "ba-cli Device.Schedules.Schedule.*.Enable=0" > /dev/null 2>&1 + $ R "ba-cli Device.Schedules.Schedule.*.Status?" | tail -n +2 | sed -E 's/\.Schedule\.[0-9]+\./.Schedule.X./' | head -n -1 + Device.Schedules.Schedule.X.Status="Disabled" + Device.Schedules.Schedule.X.Status="Disabled" + +Test InverseMode functionality: + + $ SCHEDULE_PATH_WH="Device.Schedules.Schedule.work-hours" + $ R "ba-cli '${SCHEDULE_PATH_WH}.Enable=1'" > /dev/null 2>&1 + $ R "ba-cli ${SCHEDULE_PATH_WH}.InverseMode?" + * (glob) + Device.Schedules.Schedule.*.InverseMode=0 (glob) + * (glob) + +Verify initial status and TimeLeft (InverseMode=0): + + $ INITIAL_STATUS=$(R "ba-cli ${SCHEDULE_PATH_WH}.Status?" | tail -n +2 | head -n -1 | cut -d= -f2 | tr -d '"') + $ INITIAL_TIMELEFT=$(R "ba-cli ${SCHEDULE_PATH_WH}.TimeLeft?" | tail -n +2 | head -n -1 | cut -d= -f2) + $ [ ${INITIAL_TIMELEFT} -ge 0 ] + +Enable InverseMode and verify status changes: + + $ R "ba-cli ${SCHEDULE_PATH_WH}.InverseMode=1" > /dev/null 2>&1 + $ R "ba-cli ${SCHEDULE_PATH_WH}.InverseMode?" + * (glob) + Device.Schedules.Schedule.*.InverseMode=1 (glob) + * (glob) + +Verify status is inverted: + + $ INVERSE_STATUS=$(R "ba-cli ${SCHEDULE_PATH_WH}.Status?" | tail -n +2 | head -n -1 | cut -d= -f2 | tr -d '"') + $ [ "${INITIAL_STATUS}" != "${INVERSE_STATUS}" ] + +Disable InverseMode again: + + $ R "ba-cli ${SCHEDULE_PATH_WH}.InverseMode=0" > /dev/null 2>&1 + +Test Duration and TimeLeft: + + $ R "ba-cli ${SCHEDULE_PATH_WH}.Duration?" + * (glob) + Device.Schedules.Schedule.*.Duration=32400 (glob) + * (glob) + +Verify TimeLeft is a non-negative integer: + + $ TIMELEFT=$(R "ba-cli ${SCHEDULE_PATH_WH}.TimeLeft?" | tail -n +2 | head -n -1 | cut -d= -f2) + $ [ ${TIMELEFT} -ge 0 ] + +Verify TimeLeft changes over time: + + $ sleep 2 + $ TIMELEFT2=$(R "ba-cli ${SCHEDULE_PATH_WH}.TimeLeft?" | tail -n +2 | head -n -1 | cut -d= -f2) + $ [ ${TIMELEFT2} -ge 0 ] + +Verify TimeLeft is within valid range (0 to Duration): + + $ TIMELEFT_ACTUAL=$(R "ba-cli ${SCHEDULE_PATH_WH}.TimeLeft?" | tail -n +2 | head -n -1 | cut -d= -f2) + $ DURATION=$(R "ba-cli ${SCHEDULE_PATH_WH}.Duration?" | tail -n +2 | head -n -1 | cut -d= -f2) + $ [ ${TIMELEFT_ACTUAL} -ge 0 ] && [ ${TIMELEFT_ACTUAL} -le $((DURATION + 86400)) ] + +Test Schedule deletion and cleanup: + + $ R "ba-cli Device.Schedules.ScheduleNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Schedules.ScheduleNumberOfEntries=2 + +Delete the first schedule: + + $ R "ba-cli 'Device.Schedules.Schedule.weekend.-'" > /dev/null 2>&1 + +Verify ScheduleNumberOfEntries is decremented: + + $ R "ba-cli Device.Schedules.ScheduleNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Schedules.ScheduleNumberOfEntries=1 + +Delete the remaining schedule: + + $ R "ba-cli 'Device.Schedules.Schedule.work-hours.-'" > /dev/null 2>&1 + +Verify ScheduleNumberOfEntries is now 0: + + $ R "ba-cli Device.Schedules.ScheduleNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Schedules.ScheduleNumberOfEntries=0 diff --git a/.gitlab/tests/cram/generic/acceleration-plan-components/155-tr181-schedules-hosts.t b/.gitlab/tests/cram/generic/acceleration-plan-components/155-tr181-schedules-hosts.t new file mode 100644 index 0000000000..dd93c5c6c6 --- /dev/null +++ b/.gitlab/tests/cram/generic/acceleration-plan-components/155-tr181-schedules-hosts.t @@ -0,0 +1,198 @@ +Create R alias: + + $ alias R="${CRAM_REMOTE_COMMAND:-}" + +Check that Hosts and Schedules datamodels are available: + + $ R "ba-cli -lj Device.Hosts.AccessControlNumberOfEntries?" | jq . + [ + { + "Device.Hosts.": { + "AccessControlNumberOfEntries": \d+ (re) + } + } + ] + + $ R "ba-cli -lj Device.Schedules.ScheduleNumberOfEntries?" | jq . + [ + { + "Device.Schedules.": { + "ScheduleNumberOfEntries": \d+ (re) + } + } + ] + +Create an AccessControl entry: + + $ R "ba-cli 'Device.Hosts.AccessControl.+{Alias=\"test-access-control\"}'" > /dev/null 2>&1 + $ AC_PATH="Device.Hosts.AccessControl.test-access-control" + +Check AccessControl initial state: + + $ R "ba-cli -lj ${AC_PATH}.?" | jq . + [ + { + "*": { (glob) + "PhysAddressMask": "FF:FF:FF:FF:FF:FF", + "AccessPolicy": "Allow", + "ScheduleNumberOfEntries": 0, + "Enable": 0, + "ScheduleRef": "", + "Origin": "User", + "HostName": "", + "Alias": "test-access-control", + "PhysAddress": "" + } + } + ] + +Find the LAN test device in Hosts datamodel: + + $ R "ba-cli Device.Hosts.HostNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Hosts.HostNumberOfEntries=\d+ (re) + +Get our LAN IP address from the LAN interface: + + $ MY_IP=$(ip -4 addr show $TESTBED_LAN_INTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1) + +Get MAC address of this LAN test device from Hosts datamodel: + + $ HOST_MAC=$(R "ba-cli 'Device.Hosts.Host.[IPAddress==\"${MY_IP}\"].PhysAddress?' | grep -v '^>' | grep -v '^root' | grep -v '^$' | head -1 | cut -d'=' -f2 | tr -d '\"'" 2>/dev/null) + +Set PhysAddress for the AccessControl using the discovered MAC: + + $ R "ba-cli ${AC_PATH}.PhysAddress='${HOST_MAC}'" > /dev/null 2>&1 + $ R "ba-cli ${AC_PATH}.PhysAddress?" | tail -n +2 | head -n -1 + Device.Hosts.AccessControl.*.PhysAddress="([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}" (re) + +Verify baseline connectivity before access control: + + $ R "iptables -L FORWARD_Hosts_Block -n | grep -ic ${HOST_MAC}" + 0 + [1] + +Create a schedule for working hours: + + $ R "ba-cli 'Device.Schedules.Schedule.+{Alias=\"full\",Day=\"Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday\",Duration=86400,Enable=1,Description=\"Schedule active everytime\"}'" > /dev/null 2>&1 + +Get the Schedule instance path: + + $ SCHED_INSTANCE=$(R "ba-cli 'Device.Schedules.Schedule.[Alias==\"full\"].?'" | awk -F'.' '/^Device\.Schedules\.Schedule\.[0-9]+\./{print $4; exit}') + $ SCHED_PATH="Device.Schedules.Schedule.${SCHED_INSTANCE}" + +Link the schedule to AccessControl via ScheduleRef: + + $ R "ba-cli ${AC_PATH}.ScheduleRef='${SCHED_PATH}'" > /dev/null 2>&1 + +Verify ScheduleRef is set: + + $ R "ba-cli ${AC_PATH}.ScheduleRef?" | tail -n +2 | head -n -1 + Device.Hosts.AccessControl.*.ScheduleRef="Device.Schedules.Schedule.*" (glob) + +Enable the AccessControl: + + $ R "ba-cli ${AC_PATH}.Enable=1" > /dev/null 2>&1 + +Verify AccessControl is enabled with schedule: + + $ R "ba-cli -lj ${AC_PATH}.?" | jq 'del(.[0][].ScheduleNumberOfEntries)' | jq . + [ + { + "*": { (glob) + "PhysAddressMask": "FF:FF:FF:FF:FF:FF", + "AccessPolicy": "Allow", + "Enable": 1, + "ScheduleRef": "Device.Schedules.Schedule.*", (glob) + "Origin": "User", + "HostName": "", + "Alias": "test-access-control", + "PhysAddress": "([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}" (re) + } + } + ] + +Check Schedule status: + + $ R "ba-cli ${SCHED_PATH}.Status?" | tail -n +2 | head -n -1 + Device.Schedules.Schedule.*.Status="Active" (glob) + +Check Schedule TimeLeft: + + $ TIMELEFT=$(R "ba-cli ${SCHED_PATH}.TimeLeft?" | tail -n +2 | head -n -1 | cut -d= -f2) + $ [ ${TIMELEFT} -ge 0 ] + +Test connectivity with AccessControl and Schedule enabled: + + $ R "iptables -L FORWARD_Hosts_Block -n | grep -ic ${HOST_MAC}" + 0 + [1] + +Test InverseMode effect on schedule and access: + + $ INITIAL_STATUS=$(R "ba-cli ${SCHED_PATH}.Status?" | tail -n +2 | head -n -1 | cut -d= -f2 | tr -d '"') + $ R "ba-cli ${SCHED_PATH}.InverseMode=1" > /dev/null 2>&1 + $ sleep 5 + $ INVERSE_STATUS=$(R "ba-cli ${SCHED_PATH}.Status?" | tail -n +2 | head -n -1 | cut -d= -f2 | tr -d '"') + $ [ "${INITIAL_STATUS}" != "${INVERSE_STATUS}" ] + +Test ping after InverseMode enabled (should be blocked): + + $ R "iptables -L FORWARD_Hosts_Block -n | grep -ic ${HOST_MAC}" + 1 + +Reset InverseMode and verify connectivity restored: + + $ sleep 5 + $ R "ba-cli ${SCHED_PATH}.InverseMode=0" > /dev/null 2>&1 + $ sleep 5 + + $ R "iptables -L FORWARD_Hosts_Block -n | grep -ic ${HOST_MAC}" + 0 + [1] + +Change AccessPolicy to Deny and test: + + $ R "ba-cli ${AC_PATH}.AccessPolicy=Deny" > /dev/null 2>&1 + $ R "ba-cli ${AC_PATH}.AccessPolicy?" | tail -n +2 | head -n -1 + Device.Hosts.AccessControl.*.AccessPolicy="Deny" (glob) + $ sleep 5 + +Test ping with Deny policy during schedule active time: + + $ R "iptables -L FORWARD_Hosts_Block -n | grep -ic ${HOST_MAC}" + 1 + +Reset AccessPolicy back to Allow: + + $ sleep 5 + $ R "ba-cli ${AC_PATH}.AccessPolicy=Allow" > /dev/null 2>&1 + +Delete the schedule and verify cleanup: + + $ R "ba-cli '${SCHED_PATH}.-'" > /dev/null 2>&1 + +Verify ScheduleRef is cleared in AccessControl: + + $ R "ba-cli ${AC_PATH}.ScheduleRef?" | tail -n +2 | head -n -1 + Device.Hosts.AccessControl.*.ScheduleRef="" (glob) + +Verify ScheduleNumberOfEntries is back to 0: + + $ R "ba-cli Device.Schedules.ScheduleNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Schedules.ScheduleNumberOfEntries=0 + +Cleanup - Delete the AccessControl entry: + + $ R "ba-cli '${AC_PATH}.-'" > /dev/null 2>&1 + +Verify AccessControlNumberOfEntries is decremented: + + $ R "ba-cli Device.Hosts.AccessControlNumberOfEntries?" | tail -n +2 | head -n -1 + Device.Hosts.AccessControlNumberOfEntries=0 + +Test if connectivity is back: + + $ R "iptables -L FORWARD_Hosts_Block -n | grep -ic ${HOST_MAC}" + 0 + [1] + diff --git a/.gitlab/tests/cram/generic/ubus-datamodel-list.t b/.gitlab/tests/cram/generic/ubus-datamodel-list.t index 6d85babe8e..4317e5780a 100644 --- a/.gitlab/tests/cram/generic/ubus-datamodel-list.t +++ b/.gitlab/tests/cram/generic/ubus-datamodel-list.t @@ -116,6 +116,7 @@ Check that ubus has expected datamodels available: Device.Routing Device.SFPs Device.SSH + Device.Schedules Device.Security Device.SessionManagement Device.SoftwareModules @@ -339,6 +340,8 @@ Check that ubus has expected datamodels available: SSH SSH.AuthorizedKey SSH.Server + Schedules + Schedules.Schedule Security Security.CABundle Security.Certificate diff --git a/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t b/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t index 30ec2068cb..7b06263635 100644 --- a/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t +++ b/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t @@ -24,5 +24,6 @@ PPW-1729, PPW-1731 and PPW-1786: /etc/amx/gmap-server/mibs/information.odl /etc/amx/gmap-server/mibs/location.odl /etc/amx/gmap-server/mibs/mac.odl + /etc/amx/tr181-schedules/tr181-schedules_definition.odl $ logger -t cram "Backup and restore flags verification test finished" diff --git a/.gitlab/tests/cram/mxl25641-hdk-6/005-build-config.t b/.gitlab/tests/cram/mxl25641-hdk-6/005-build-config.t index 882d86c135..f291afe3fa 100644 --- a/.gitlab/tests/cram/mxl25641-hdk-6/005-build-config.t +++ b/.gitlab/tests/cram/mxl25641-hdk-6/005-build-config.t @@ -623,6 +623,7 @@ Assure expected build configuration (PCF-1413): CONFIG_PACKAGE_mod-ra-radvd=y CONFIG_PACKAGE_mod-routing-dhcp=y CONFIG_PACKAGE_mod-sahtrace=y + CONFIG_PACKAGE_mod-scheduler-amxp=y CONFIG_PACKAGE_mod-usp-registration=y CONFIG_PACKAGE_mod-vlan-ioctl=y CONFIG_PACKAGE_mod-vlan-uci=y @@ -802,6 +803,7 @@ Assure expected build configuration (PCF-1413): CONFIG_PACKAGE_tr181-qos=y CONFIG_PACKAGE_tr181-rest-api=y CONFIG_PACKAGE_tr181-routeradvertisement=y + CONFIG_PACKAGE_tr181-schedules=y CONFIG_PACKAGE_tr181-security=y CONFIG_PACKAGE_tr181-sfp=y CONFIG_PACKAGE_tr181-syslog=y @@ -1050,6 +1052,11 @@ Assure expected build configuration (PCF-1413): CONFIG_SAH_AMX_TR181_ROUTING_RUN_AS_USER="tr181_app" CONFIG_SAH_AMX_TR181_ROUTING_START_ORDER=30 CONFIG_SAH_AMX_TR181_ROUTING_STOP_ORDER=10 + CONFIG_SAH_AMX_TR181_SCHEDULES=y + CONFIG_SAH_AMX_TR181_SCHEDULES_RUN_AS_GROUP="tr181_app" + CONFIG_SAH_AMX_TR181_SCHEDULES_RUN_AS_USER="tr181_app" + CONFIG_SAH_AMX_TR181_SCHEDULES_START_ORDER=20 + CONFIG_SAH_AMX_TR181_SCHEDULES_STOP_ORDER=80 CONFIG_SAH_AMX_TR181_SECURITY=y CONFIG_SAH_AMX_TR181_SECURITY_ORDER=21 CONFIG_SAH_AMX_TR181_SFP=y diff --git a/.gitlab/tests/cram/wnc-freedom/005-build-config.t b/.gitlab/tests/cram/wnc-freedom/005-build-config.t index b5835d7e63..d0448fe894 100644 --- a/.gitlab/tests/cram/wnc-freedom/005-build-config.t +++ b/.gitlab/tests/cram/wnc-freedom/005-build-config.t @@ -435,6 +435,7 @@ Assure expected build configuration (PCF-1413): CONFIG_PACKAGE_mod-ra-radvd=y CONFIG_PACKAGE_mod-routing-dhcp=y CONFIG_PACKAGE_mod-sahtrace=y + CONFIG_PACKAGE_mod-scheduler-amxp=y CONFIG_PACKAGE_mod-usp-registration=y CONFIG_PACKAGE_mod-vlan-ioctl=y CONFIG_PACKAGE_mod-vlan-uci=y @@ -586,6 +587,7 @@ Assure expected build configuration (PCF-1413): CONFIG_PACKAGE_tr181-qos=y CONFIG_PACKAGE_tr181-rest-api=y CONFIG_PACKAGE_tr181-routeradvertisement=y + CONFIG_PACKAGE_tr181-schedules=y CONFIG_PACKAGE_tr181-security=y CONFIG_PACKAGE_tr181-sfp=y CONFIG_PACKAGE_tr181-syslog=y @@ -828,6 +830,11 @@ Assure expected build configuration (PCF-1413): CONFIG_SAH_AMX_TR181_ROUTING_RUN_AS_USER="tr181_app" CONFIG_SAH_AMX_TR181_ROUTING_START_ORDER=30 CONFIG_SAH_AMX_TR181_ROUTING_STOP_ORDER=10 + CONFIG_SAH_AMX_TR181_SCHEDULES=y + CONFIG_SAH_AMX_TR181_SCHEDULES_RUN_AS_GROUP="tr181_app" + CONFIG_SAH_AMX_TR181_SCHEDULES_RUN_AS_USER="tr181_app" + CONFIG_SAH_AMX_TR181_SCHEDULES_START_ORDER=20 + CONFIG_SAH_AMX_TR181_SCHEDULES_STOP_ORDER=80 CONFIG_SAH_AMX_TR181_SECURITY=y CONFIG_SAH_AMX_TR181_SECURITY_ORDER=21 CONFIG_SAH_AMX_TR181_SFP=y