Files
wlan-testing/cicd/testbed_poll.pl
Ben Greear 49132a2cae testbed-poll: Fix file glob operator
To properly detect bare sysupgrade images or not.

Signed-off-by: Ben Greear <greearb@candelatech.com>
2021-01-27 13:19:27 -08:00

526 lines
18 KiB
Perl
Executable File

#!/usr/bin/perl
# Query test-bed orchestator URL to see if there are new tests for us to run.
# This is expected to be run on the test-bed controller (not orchestrator)
# One of these processes will run for each test bed controlled by the controller.
use strict;
use warnings;
use Getopt::Long;
my $user = "";
my $passwd = "";
my $jfrog_user = "cicd_user";
my $jfrog_passwd = "";
my $url = "";
my $next_info = "__next_test.txt";
my $help = 0;
my $owt_log = "";
my $dut_passwd = "";
my $dut_user = "root";
my $sysupgrade_n = 0;
#my $prompt = "root\@OpenAp";
my $prompt = "root\@Open"; # match OpenWrt and OpenAp-foo
my $log = "";
my $usage = qq($0
[--jfrog_user { jfrog user (default: cicd_user) }
[--jfrog_passwd { jfrog password }
[--user { for accessing URL }
[--passwd { for accessing URL }
[--dut_user { for accessing DUT }
[--dut_passwd { for accessing DUT }
[--url { test-orchestrator URL for this test bed }
[--next_info { output text file containing info about the next test to process }
[--sysupgrade-n { 0 | 1 } 1 means use the -n option when doing sysupgrade.
[--log {location} For instance: --log stdout, for openwrt_ctl expect script.
Example:
$0 --user to_user --passwd secret --jfrog_user tip-read --jfrog_passwd tip-read \\
--url https://tip.cicd.mycloud.com/testbed-ferndale-01/ --dut_passwd owrt --dut_user root
# Use specific scenario file.
SCENARIO_CFG_FILE=/home/lanforge/git/wlan-testing/testbeds/ferndale-basic-01/scenario_small.txt \\
../testbed_poll.pl --jfrog_passwd tip-read --jfrog_user tip-read \\
--url http://192.168.100.195/tip/testbeds/ferndale-basic-01/pending_work/
);
GetOptions
(
'jfrog_user=s' => \$jfrog_user,
'jfrog_passwd=s' => \$jfrog_passwd,
'user=s' => \$user,
'passwd=s' => \$passwd,
'dut_passwd=s' => \$dut_passwd,
'dut_user=s' => \$dut_user,
'url=s' => \$url,
'next_info=s' => \$next_info,
'sysupgrade_n=i' => \$sysupgrade_n,
'log=s' => \$log,
'help|?' => \$help,
) || (print($usage) && exit(1));
if ($help) {
print($usage) && exit(0);
}
if ($jfrog_passwd eq "") {
print("ERROR: You must specify jfrog password.\n");
exit(1);
}
if ($user ne "" && $passwd eq "") {
print("ERROR: You must specify a password if specifying a user.\n");
exit(1);
}
if ($log ne "") {
$owt_log = "--log $log";
}
my $owt_args = " --prompt $prompt";
if ($dut_user ne "") {
$owt_args .= " --user $dut_user";
}
if ($dut_passwd ne "") {
$owt_args .= " --passwd $dut_passwd";
}
$owt_log .= $owt_args;
my $i;
my $cuser = "-u $user:$passwd";
if ($user eq "") {
$cuser = "";
}
my $cmd = "curl $cuser $url";
print_note("Checking Test-Orchestrator for new work-items");
my $listing = do_system($cmd);
my @lines = split(/\n/, $listing);
# First, if any have 'fast' in them, they get precedence.
for ($i = 0; $i<@lines; $i++) {
my $ln = $lines[$i];
chomp($ln);
my $fast = 0;
if ($ln =~ /href=\"(CICD_TEST-.*-fast)\">(.*)<\/a>\s+(.*)\s+\S+\s+\S+/) {
$fast = 1;
}
elsif ($ln =~ /href=\"(CICD_TEST-.*-fast)\">(.*)<\/a>/) {
$fast = 1;
}
if ($fast) {
@lines[0] = $ln;
last;
}
}
for ($i = 0; $i<@lines; $i++) {
my $ln = $lines[$i];
chomp($ln);
my $fname = "";
my $name = "";
my $date = "";
if ($ln =~ /href=\"(CICD_TEST-.*)\">(.*)<\/a>\s+(.*)\s+\S+\s+\S+/) {
$fname = $1;
$name = $2;
$date = $3;
}
elsif ($ln =~ /href=\"(CICD_TEST-.*)\">(.*)<\/a>/) {
$fname = $1;
}
if ($fname ne "") {
# Grab that test file
$cmd = "curl --location $cuser -o $next_info $url/$fname";
do_system($cmd);
# Read in that file
my $jurl = "";
my $jfile = "";
my $report_to = "";
my $report_name = "";
my $swver = "";
my $fdate = "";
my $ttype = "";
my $listing = do_system("cat $next_info");
my @lines = split(/\n/, $listing);
for ($i = 0; $i<@lines; $i++) {
my $ln = $lines[$i];
chomp($ln);
if ($ln =~ /^CICD_URL=(.*)/) {
$jurl = $1;
}
elsif ($ln =~ /^CICD_TYPE=(.*)/) {
$ttype = $1;
}
elsif ($ln =~ /^CICD_FILE_NAME=(.*)/) {
$jfile = $1;
}
elsif ($ln =~ /^CICD_RPT_DIR=(.*)/) {
$report_to = $1;
}
elsif ($ln =~ /^CICD_RPT_NAME=(.*)/) {
$report_name = $1;
}
elsif ($ln =~ /^CICD_GITHASH=(.*)/) {
$swver = $1;
}
elsif ($ln =~ /^CICD_FILEDATE=(.*)/) {
$fdate = $1;
}
}
if ($swver eq "") {
$swver = $fdate;
}
if ($swver eq "") {
$swver = "$jfile";
}
if ($jurl eq "") {
print("ERROR: No CICD_URL found, cannot download file.\n");
exit(1);
}
if ($jfile eq "") {
print("ERROR: No CICD_FILE_NAME found, cannot download file.\n");
exit(1);
}
# Refresh wlan-ap repo if it exists.
if ( -d "../../../wlan-ap") {
do_system("cd ../../../wlan-ap && git pull && cd -");
}
print_note("Download latest AP Build from jfrog repository.");
my $cmd = "curl --location -o $jfile -u $jfrog_user:$jfrog_passwd $jurl/$jfile";
do_system($cmd);
do_system("rm -f openwrt-*.bin");
do_system("rm -f *sysupgrade.*"); # just in case openwrt prefix changes.
do_system("tar xf $jfile");
# Detect if we are using full pkg or new trimmed sysupgrade image
my $full_owrt_pkg = 0;
my @listing = glob("*sysupgrade*");
if (@listing > 0) {
print("NOTE: Found full openwrt package.\n");
$full_owrt_pkg = 1;
}
else {
print("NOTE: Found trimmed sysupgrade openwrt package.\n");
}
print_note("Copy AP build to LANforge so LANforge can serve the file to AP");
# Next steps here are to put the OpenWrt file on the LANforge system
my $tb_info = do_system("cat TESTBED_INFO.txt");
my $tb_dir = "";
if ($tb_info =~ /TESTBED_DIR=(.*)/) {
$tb_dir = $1;
}
my $env = do_system(". $tb_dir/test_bed_cfg.bash && env");
my $lfmgr = "";
my $serial = "";
my $cloud_sdk = "";
if ($env =~ /LFMANAGER=(.*)/) {
$lfmgr = $1;
}
else {
print("ERRROR: Could not find LFMANAGER in environment, configuration error!\n");
print("env: $env\n");
exit(1);
}
if ($env =~ /USE_CLOUD_SDK=(\S+)/) {
$cloud_sdk = $1;
print("NOTE: Using cloud controller: $cloud_sdk\n");
}
else {
print("NOTE: NOT Using cloud controller\n");
}
#print("env: $env");
#exit(0);
if ($env =~ /AP_SERIAL=(.*)/) {
$serial = $1;
}
else {
print("ERRROR: Could not find AP_SERIAL in environment, configuration error!\n");
exit(1);
}
my $gmport = "3990";
my $gmanager = $lfmgr;
my $scenario = "tip-auto"; # matches basic_regression.bash
if ($env =~ /GMANAGER=(.*)/) {
$gmanager = $1;
}
if ($env =~ /GMPORT=(.*)/) {
$gmport = $1;
}
print_note("Restart LANforge GUI to be sure it is in known state.");
# Restart the GUI on the LANforge system
do_system("ssh lanforge\@$lfmgr pkill -f \"miglayout.*8080\"");
# and then get it onto the DUT, reboot DUT, re-configure as needed,
print_note("Request AP DUT to install the test image.");
if ($full_owrt_pkg) {
do_system("scp *sysupgrade.* lanforge\@$lfmgr:tip-$jfile");
}
else {
do_system("scp $jfile lanforge\@$lfmgr:tip-$jfile");
}
# TODO: Kill anything using the serial port
do_system("sudo lsof -t $serial | sudo xargs --no-run-if-empty kill -9");
print_note("Find AP DUT default gateway.");
# and then kick off automated regression test.
# Default gateway on the AP should be one of the ports on the LANforge system, so we can use
# that to scp the file to the DUT, via serial-console connection this controller has to the DUT.
my $ap_route = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"ip route show\"");
my $ap_gw = "";
if ($ap_route =~ /default via (\S+)/) {
$ap_gw = $1;
}
if ($ap_gw eq "") {
print("ERROR: Could not find default gateway for AP, route info:\n$ap_route\n");
if ($ap_route =~ /pexpect.exceptions.TIMEOUT/) {
# In case AP went into boot-loader, deal with that.
if ($ap_route =~ /\(IPQ\)/) {
print("WARNING: Detected Bootloader, will attempt to reset and recover.\n");
do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py --prompt \"(IPQ)\" --scheme serial --tty $serial --action cmd --value \"reset\"");
sleep(20);
$ap_route = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"ip route show\"");
if ($ap_route =~ /default via (\S+)/) {
$ap_gw = $1;
}
if ($ap_gw eq "") {
if ($ap_route =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out (find default GW, after bootloader reset).\n");
exit(55);
}
}
}
else {
print("FATAL-ERROR: DUT is in bad state, bail out (find default GW).\n");
exit(33);
}
}
# Re-apply scenario so the LANforge gateway/NAT is enabled for sure.
my $out = do_system("../../lanforge/lanforge-scripts/lf_gui_cmd.pl --manager $gmanager --port $gmport --scenario $scenario");
# TODO: Use power-controller to reboot the AP and retry.
if ($out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(34);
}
$out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action reboot");
print ("Reboot DUT to try to recover networking:\n$out\n");
if ($out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(35);
}
sleep(15);
$ap_route = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"ip route show\"");
if ($ap_route =~ /default via (\S+)/g) {
$ap_gw = $1;
}
if ($ap_route =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(36);
}
if ($ap_gw eq "") {
exit(1);
}
}
print_note("Request AP DUT to install the test image and reboot.");
# TODO: Change this to curl download??
my $ap_out;
if ($sysupgrade_n) {
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action sysupgrade-n --value \"lanforge\@$ap_gw:tip-$jfile\"");
}
else {
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action sysupgrade --value \"lanforge\@$ap_gw:tip-$jfile\"");
}
print ("Sys-upgrade results:\n$ap_out\n");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(37);
}
# TODO: Verify this (and reboot below) worked. DUT can get wedged and in that case it will need
# a power-cycle to continue.
# System should be rebooted at this point.
sleep(10); # Give it some more time
if ($cloud_sdk eq "") {
print_note("Initialize AP, disable OpenVsync since this is stand-alone testbed.");
# Disable openvsync, it will re-write /etc/config/wireless
# This code should not be used when we get cloud-sdk wired up.
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"service opensync stop\"");
print ("Stop openvsync:\n$ap_out\n");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(38);
}
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"service opensync disable\"");
print ("Disable openvsync:\n$ap_out\n");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(39);
}
}
else {
print_note("Initialize AP, enable OpenVsync since this testbed is using Cloud-Controler: $cloud_sdk.");
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"service opensync enable\"");
print ("Enable openvsync:\n$ap_out\n");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(40);
}
}
# Enable bugcheck script
my $etc_bugcheck = "$tb_dir/OpenWrt-overlay/etc/config/bugcheck";
open(FILE, ">", "$etc_bugcheck");
print FILE "DO_BUGCHECK=1
export DO_BUGCHECK
";
close(FILE);
# Re-apply overlay
print_note("Apply default AP configuration for this test bed.");
if ($cloud_sdk eq "") {
$ap_out = do_system("cd $tb_dir/OpenWrt-overlay && tar -cvzf ../overlay_tmp.tar.gz * && scp ../overlay_tmp.tar.gz lanforge\@$lfmgr:tip-overlay.tar.gz");
}
else {
# Create /etc/hosts file that points us towards correct cloud-sdk machine
my $etc_hosts = "$tb_dir/OpenWrt-overlay/etc/hosts";
open(FILE, ">", "$etc_hosts");
print FILE "# Auto-Created by CICD process
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
$cloud_sdk opensync-mqtt-broker
$cloud_sdk opensync-wifi-controller
$cloud_sdk opensync.zone1.art2wave.com
";
# Leave 'wireless' out of the overlay since opensync will be designed to work with default config.
$ap_out = do_system("cd $tb_dir/OpenWrt-overlay && tar -cvzf ../overlay_tmp.tar.gz --exclude etc/config/wireless * && scp ../overlay_tmp.tar.gz lanforge\@$lfmgr:tip-overlay.tar.gz");
unlink($etc_hosts);
close(FILE);
}
print ("Copy overlay to DUT\n");
for (my $q = 0; $q<10; $q++) {
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action download --value \"lanforge\@$ap_gw:tip-overlay.tar.gz\" --value2 \"overlay.tgz\"");
print ("Download overlay to DUT:\n$ap_out\n");
if ($ap_out =~ /ERROR: Could not connect to LANforge/g) {
# Try to restart the network
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"/etc/init.d/network restart\"");
print ("Request restart of DUT networking:\n$ap_out\n");
if ($q == 9) {
# We have failed to apply overlay at this point, bail out.
print("ERROR: Could not apply overlay to DUT, exiting test attempt.\n");
exit(1);
}
print("Will retry overlay download in 10 seconds, try $q / 10\n");
sleep(10);
}
else {
last;
}
}
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"cd / && tar -xzf /tmp/overlay.tgz\"");
print ("Un-zip overlay on DUT:\n$ap_out\n");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(41);
}
print_note("Reboot AP so that new configuration is applied.");
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action reboot");
print ("Rebooted DUT so overlay takes effect:\n$ap_out\n");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(42);
}
my $dt = `date`;
print_note("$dt");
if ($ttype eq "fast") {
print_note("Start 'Fast' LANforge regression test.");
$ap_out = do_system("cd $tb_dir && APGW=$ap_gw DUT_SW_VER=$swver OWRTCTL_ARGS=\"$owt_args\" ./run_basic_fast.bash");
}
else {
print_note("Start 'Fast' LANforge regression test.");
$ap_out = do_system("cd $tb_dir && APGW=$ap_gw DUT_SW_VER=$swver OWRTCTL_ARGS=\"$owt_args\" ./run_basic.bash");
}
print("Regression $ttype test script output:\n$ap_out\n");
print_note("Upload results.");
#When complete, upload the results to the requested location.
if ($ap_out =~ /Results-Dir: (.*)/) {
my $rslts_dir = $1;
if ($rslts_dir =~ /(.*)\'/) {
$rslts_dir = $1;
}
print ("Found results at: $rslts_dir\n");
do_system("rm -fr /tmp/$report_name");
do_system("mv $rslts_dir /tmp/$report_name");
do_system("chmod -R a+r /tmp/$report_name");
do_system("scp -C -r /tmp/$report_name $report_to/");
do_system("echo $fname > /tmp/NEW_RESULTS-$fname");
do_system("scp /tmp/NEW_RESULTS-$fname $report_to/");
# This will indirectly stop logread if it is running.
$ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"uptime\"");
if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) {
print("FATAL-ERROR: DUT is in bad state, bail out.\n");
exit(43);
}
}
exit(0);
}
#print "$ln\n";
}
exit 0;
sub do_system {
my $cmd = shift;
print ">>> $cmd\n";
return `$cmd 2>&1`;
}
sub print_note {
my $n = shift;
my $hdr = "###############################################################";
print "\n\n\n$hdr\n### $n\n$hdr\n\n";
}