From 2085777ce5d7d3a04a490f9b397b1a8a77e60722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Sat, 22 Apr 2023 11:05:55 +0200 Subject: [PATCH] ci: cdrouter: enable wireless LAN testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable testing of wireless stack using following essential CDRouter tests: wifi_1 Graceful wireless LAN client restart wifi_2 Restart wireless LAN client without releasing address wifi_3 Restart wireless LAN client without releasing or obtaining a new address wifi_10 Verify connectivity using all wifi modes advertised by the DUT wifi_11 Verify DUT prevents use of TKIP cipher when using HT/VHT/HE wifi_20 Verify DUT's wifi beacons contain expected mode information wifi_30 WiFi association stress test wifi_40 WiFi SSID scan test Run those 8 testcases, in a loop 2 times and repeat each test 2 times. References: PCF-883 Signed-off-by: Petr Štetiar (cherry picked from commit eb74a59a99925f040813d364ca19b8b91260ad6c) --- .gitlab/cdrouter/glinet-b1300.yml | 7 +++++++ .gitlab/cdrouter/prpl-haze.yml | 7 +++++++ .gitlab/cdrouter/turris-omnia.yml | 7 +++++++ .../cdrouter-dut-configure-wireless.sh | 4 ++++ .testbed/cdrouter/configurations/wireless | 18 +++++++++--------- .../cdrouter/packages/CDRouter-Wireless.gz | Bin 0 -> 17799 bytes 6 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 .gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh create mode 100644 .testbed/cdrouter/packages/CDRouter-Wireless.gz diff --git a/.gitlab/cdrouter/glinet-b1300.yml b/.gitlab/cdrouter/glinet-b1300.yml index 4f47aa8e72..0dcee3fa2a 100644 --- a/.gitlab/cdrouter/glinet-b1300.yml +++ b/.gitlab/cdrouter/glinet-b1300.yml @@ -28,6 +28,13 @@ CDRouter-Top-100+mDNS Gl.iNet PPPoE WAN initramfs: .gitlab/scripts/dut-init/cdrouter-dut-configure-dyndns.sh .gitlab/scripts/dut-init/cdrouter-dut-enable-pppoe.sh +CDRouter-Wireless Gl.iNet initramfs: + <<: *glinet_cdrouter + variables: + CDROUTER_TEST_CONFIG: wireless + DUT_INIT_SCRIPTS: | + .gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh + .glinet-cdrouter-ipv6: &glinet_cdrouter_ipv6 <<: *glinet_cdrouter diff --git a/.gitlab/cdrouter/prpl-haze.yml b/.gitlab/cdrouter/prpl-haze.yml index 79264af857..c339ae3c52 100644 --- a/.gitlab/cdrouter/prpl-haze.yml +++ b/.gitlab/cdrouter/prpl-haze.yml @@ -28,6 +28,13 @@ CDRouter-Top-100+mDNS Haze PPPoE WAN initramfs: .gitlab/scripts/dut-init/cdrouter-dut-configure-dyndns.sh .gitlab/scripts/dut-init/cdrouter-dut-enable-pppoe.sh +CDRouter-Wireless Haze initramfs: + <<: *prpl_haze + variables: + CDROUTER_TEST_CONFIG: wireless + DUT_INIT_SCRIPTS: | + .gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh + .prpl-haze-ipv6: &prpl_haze_ipv6 <<: *prpl_haze diff --git a/.gitlab/cdrouter/turris-omnia.yml b/.gitlab/cdrouter/turris-omnia.yml index 2b5df95172..d114860f14 100644 --- a/.gitlab/cdrouter/turris-omnia.yml +++ b/.gitlab/cdrouter/turris-omnia.yml @@ -28,6 +28,13 @@ CDRouter-Top-100+mDNS Turris PPPoE WAN initramfs: .gitlab/scripts/dut-init/cdrouter-dut-configure-dyndns.sh .gitlab/scripts/dut-init/cdrouter-dut-enable-pppoe.sh +CDRouter-Wireless Turris initramfs: + <<: *turris_cdrouter + variables: + CDROUTER_TEST_CONFIG: wireless + DUT_INIT_SCRIPTS: | + .gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh + .turris-cdrouter-ipv6: &turris_cdrouter_ipv6 <<: *turris_cdrouter diff --git a/.gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh b/.gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh new file mode 100644 index 0000000000..2847d0bc55 --- /dev/null +++ b/.gitlab/scripts/dut-init/cdrouter-dut-configure-wireless.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +ssh "root@$TARGET_LAN_IP" "ubus -t 200 wait_for WiFi.AccessPoint.1" +ssh "root@$TARGET_LAN_IP" "ubus -S call WiFi.AccessPoint.1 _set '{\"parameters\":{\"Enable\":1}}'" diff --git a/.testbed/cdrouter/configurations/wireless b/.testbed/cdrouter/configurations/wireless index 832b974ca6..8899c6bf7e 100644 --- a/.testbed/cdrouter/configurations/wireless +++ b/.testbed/cdrouter/configurations/wireless @@ -287,7 +287,7 @@ SECTION "Base Configuration" { SECTION "Dynamic DNS" { - testvar supportsDynDns yes + # testvar supportsDynDns no # testvar dynDnsServerIp 66.37.215.49 # testvar dynDnsTransport http testvar dynDnsHostname cpe01.prplOS.prplfoundation.org @@ -324,10 +324,10 @@ SECTION "Base Configuration" { SECTION "LAN Interface" { - # testvar lanInterface eth1 + testvar lanInterface wifi0-acn # testvar lanMode DHCP # testvar lanClients 1 - # testvar lanSecurity NONE + testvar lanSecurity WPA # testvar lanIp 192.168.1.1 # testvar lanMask 255.255.255.0 # testvar lanDomainName qacafe.com @@ -397,7 +397,7 @@ SECTION "Base Configuration" { SECTION "802.11 Wireless" { - # testvar lanSSID qa-net + testvar lanSSID prplOS # testvar lanChannel auto # testvar lan80211Phy auto # testvar lanBSSID auto @@ -405,8 +405,8 @@ SECTION "Base Configuration" { SECTION "WPA Configuration Options" { - # testvar wpaMode auto - # testvar wpaKey qacafe123 + testvar wpaMode WPA2-Personal + testvar wpaKey password # testvar wpaSaePassword "sae secret" # testvar wpaKeyMgmt PSK # testvar wpaCipher auto @@ -446,12 +446,12 @@ SECTION "Base Configuration" { SECTION "Expected Beacon Information" { - # testvar wifiBeaconWpaMode none + testvar wifiBeaconWpaMode RSN # testvar wifiBeaconWpaKeyMgmt PSK # testvar wifiBeaconWpaCipher CCMP-128 # testvar wifiBeaconRsnCipher CCMP-128 # testvar wifiBeaconWpaGroupCipher CCMP-128 - # testvar wifiBeaconPhy "n a ac" + testvar wifiBeaconPhy "b g n" } @@ -2292,7 +2292,7 @@ SECTION "CDRouter Storage Add-On" { SECTION "CDRouter TR-069 Add-On" { - testvar supportsCWMP yes + testvar supportsCWMP no SECTION "Basic ACS Configuration" { diff --git a/.testbed/cdrouter/packages/CDRouter-Wireless.gz b/.testbed/cdrouter/packages/CDRouter-Wireless.gz new file mode 100644 index 0000000000000000000000000000000000000000..5a5224d4a27137b89cad2c1712cb0289309eaaa6 GIT binary patch literal 17799 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