mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-07 01:56:56 +00:00
9d63035a4d
The comment named only the DHCP cases; the provisioning ones are kept out of that phase for the same kind of reason -- they add an interface, nodes, a network and a rewritten zone.
1101 lines
42 KiB
Perl
1101 lines
42 KiB
Perl
# IBM(c) 2022 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Getopt::Long;
|
|
use Data::Dumper;
|
|
use Time::Local;
|
|
use File::Basename;
|
|
use File::Path;
|
|
use File::Find;
|
|
use LWP::UserAgent;
|
|
use HTTP::Request;
|
|
use Encode;
|
|
use Encode::CN;
|
|
use JSON;
|
|
use URI::Escape;
|
|
use LWP::Simple;
|
|
use Cwd;
|
|
|
|
use Term::ANSIColor qw(:constants);
|
|
$Term::ANSIColor::AUTORESET = 1;
|
|
|
|
#---Global attributes---
|
|
my $rst = 0;
|
|
my $retries = 5; # Try this many times to get response
|
|
my $check_result_str="``CI CHECK RESULT`` : ";
|
|
my $last_func_start = timelocal(localtime());
|
|
my $GITHUB_API = "https://api.github.com";
|
|
|
|
# The workflow starts us in the checked out source tree. The unit tests under
|
|
# xCAT-test/unit resolve xCAT modules and fixture files relative to that tree
|
|
# through FindBin, so they can only be run from a source tree. Take a copy
|
|
# before building and run the unit tests out of the copy.
|
|
#
|
|
# This used to be mandatory rather than tidy: build-ubunturepo set
|
|
# local_core_repo_path="$curdir/../../xcat-core"
|
|
# which, under the work/<repo>/<repo> layout GitHub checks out into, resolved to
|
|
# the checkout's own parent, and it rm -rf'd that path to make room for the apt
|
|
# repository -- destroying the tree the tests need. builddebs.pl writes under
|
|
# dist/debs INSIDE the checkout and restores every file it edits, so the copy is
|
|
# now only isolating the tests from build residue.
|
|
my $srcdir = getcwd();
|
|
my $unitsrc = ($ENV{'RUNNER_TEMP'} ? $ENV{'RUNNER_TEMP'} : "/tmp") . "/xcat-core-unitsrc";
|
|
|
|
# Cases whose output is printed even when they pass. A passing case is normally
|
|
# silent, which is the right default for 250 of them but makes it impossible to
|
|
# tell from the log whether a case did real work or skipped everything -- a
|
|
# distinction that matters for cases wrapping prove, since prove exits 0 either
|
|
# way. Name a case here to see its output; empty the list for the quiet
|
|
# behaviour.
|
|
my @verbose_cases = qw(integration_tests);
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: runcmd
|
|
# Description: run a command after 'cmd' label in one case
|
|
# Attributes:
|
|
# Return code:
|
|
# $::RUNCMD_RC : the return code of command
|
|
# @$outref : the output of command
|
|
#--------------------------------------------------------
|
|
sub runcmd
|
|
{
|
|
my ($cmd) = @_;
|
|
my $rc = 0;
|
|
$::RUNCMD_RC = 0;
|
|
my $outref = [];
|
|
@$outref = `$cmd 2>&1`;
|
|
if ($?)
|
|
{
|
|
$rc = $?;
|
|
$rc = $rc >> 8;
|
|
$::RUNCMD_RC = $rc;
|
|
}
|
|
chomp(@$outref);
|
|
return @$outref;
|
|
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: get_files_recursive
|
|
# Description: Search all file in one directory recursively
|
|
# Attributes:
|
|
# $dir (input attribute)
|
|
# The target scan directory
|
|
# $files_path_ref (output attribute)
|
|
# the reference of array where save all vaild files under $dir
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub get_files_recursive
|
|
{
|
|
my $dir = shift;
|
|
my $files_path_ref = shift;
|
|
|
|
my $fd = undef;
|
|
if(!opendir($fd, $dir)){
|
|
print "[get_files_recursive]: failed to open $dir :$!\n";
|
|
return 1;
|
|
}
|
|
|
|
for (; ;)
|
|
{
|
|
my $direntry = readdir($fd);
|
|
last unless (defined($direntry));
|
|
next if ($direntry =~ m/^\.\w*/);
|
|
next if ($direntry eq '..');
|
|
my $target = "$dir/$direntry";
|
|
if (-d $target) {
|
|
get_files_recursive($target, $files_path_ref);
|
|
} else {
|
|
push(@{$files_path_ref}, glob("$target\n"));
|
|
}
|
|
}
|
|
closedir($fd);
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: check_pr_format
|
|
# Description:
|
|
# Attributes:
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub check_pr_format{
|
|
if($ENV{'TRAVIS_EVENT_TYPE'} eq "pull_request"){
|
|
my $pr_url = "$GITHUB_API/repos/$ENV{'TRAVIS_REPO_SLUG'}/pulls/$ENV{'TRAVIS_PULL_REQUEST'}";
|
|
my $pr_url_resp;
|
|
my $counter = 1;
|
|
while($counter <= $retries) {
|
|
$pr_url_resp = get($pr_url);
|
|
if ($pr_url_resp) {
|
|
last; # Got response, no more retries
|
|
} else {
|
|
sleep($counter*2); # Sleep and try again
|
|
print "[check_pr_format] $counter Did not get response, sleeping ". $counter*2 . "\n";
|
|
$counter++;
|
|
}
|
|
}
|
|
unless ($pr_url_resp) {
|
|
print "[check_pr_format] After $retries retries, not able to get response from $pr_url \n";
|
|
# Failed after trying a few times, return error
|
|
return $counter;
|
|
}
|
|
my $pr_content = decode_json($pr_url_resp);
|
|
my $pr_title = $pr_content->{title};
|
|
my $pr_body = $pr_content->{body};
|
|
my $pr_milestone = $pr_content->{milestone};
|
|
my $pr_labels_len = @{$pr_content->{labels}};
|
|
|
|
#print "[check_pr_format] Dumper pr_content:\n";
|
|
#print Dumper $pr_content;
|
|
print "[check_pr_format] pr title = $pr_title\n";
|
|
print "[check_pr_format] pr body = $pr_body \n";
|
|
|
|
my $checkrst="";
|
|
if(! $pr_title){
|
|
$checkrst.="Missing title.";
|
|
}
|
|
if(! $pr_body){
|
|
$checkrst.="Missing description.";
|
|
}
|
|
|
|
if(! $pr_milestone){
|
|
$checkrst.="Missing milestone.";
|
|
}
|
|
|
|
if(! $pr_labels_len){
|
|
$checkrst.="Missing labels.";
|
|
}
|
|
|
|
# Guard against root user making commits
|
|
$checkrst.=check_commit_owner('root');
|
|
|
|
if(length($checkrst) == 0){
|
|
$check_result_str .= "> **PR FORMAT CORRECT**";
|
|
#send_back_comment("$check_result_str");
|
|
}else{
|
|
# Warning if missing milestone or labels, others are errors
|
|
if($checkrst =~ /milestone/ || $checkrst =~ /labels/){
|
|
$check_result_str .= "> **PR FORMAT WARNING** : $checkrst";
|
|
#send_back_comment("$check_result_str");
|
|
}else{
|
|
$check_result_str .= "> **PR FORMAT ERROR** : $checkrst";
|
|
#send_back_comment("$check_result_str");
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: check_commit_owner
|
|
# Description: Verify commits are not done by specified user
|
|
# Attributes: user login to reject
|
|
# Return:
|
|
# Error string -User rejected,
|
|
# Empty string -User not rejected
|
|
#--------------------------------------------------------
|
|
sub check_commit_owner{
|
|
my $invalid_user = shift;
|
|
if($ENV{'TRAVIS_EVENT_TYPE'} eq "pull_request"){
|
|
my $commits_content;
|
|
my $commits_len = 0;
|
|
my $json = new JSON;
|
|
my $commits_url = "$GITHUB_API/repos/$ENV{'TRAVIS_REPO_SLUG'}/pulls/$ENV{'TRAVIS_PULL_REQUEST'}/commits";
|
|
my $commits_url_resp;
|
|
my $counter = 1;
|
|
while($counter <= $retries) {
|
|
$commits_url_resp = get($commits_url);
|
|
if ($commits_url_resp) {
|
|
last; # Got response, no more retries
|
|
} else {
|
|
sleep($counter*2); # Sleep and try again
|
|
print "[check_commit_owner] $counter Did not get response, sleeping ". $counter*2 . "\n";
|
|
$counter++;
|
|
}
|
|
}
|
|
if ($commits_url_resp) {
|
|
$commits_content = $json->decode($commits_url_resp);
|
|
$commits_len = @$commits_content;
|
|
} else {
|
|
print "[check_commit_owner] After $retries retries, not able to get response from $commits_url \n";
|
|
return "Unable to verify login of committer.";
|
|
}
|
|
|
|
if($commits_len > 0) {
|
|
foreach my $commit (@{$commits_content}){
|
|
my $committer = $commit->{committer};
|
|
my $committer_login = $committer->{login};
|
|
print "[check_commit_owner] Committer login $committer_login \n";
|
|
if($committer_login =~ /^$invalid_user$/) {
|
|
# Committer logins matches
|
|
return "Commits by $invalid_user not allowed";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
#--------------------------------------------------------
|
|
# Fuction name: send_back_comment
|
|
# Description: Append to comment of the PR passed $message
|
|
# Attributes: Message to append to PR
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub send_back_comment{
|
|
my $message = shift;
|
|
|
|
my $comment_url = "$GITHUB_API/repos/$ENV{'TRAVIS_REPO_SLUG'}/issues/$ENV{'TRAVIS_PULL_REQUEST'}/comments";
|
|
my $json = new JSON;
|
|
my $comment_len = 0;
|
|
my $comment_content;
|
|
my $comment_url_resp;
|
|
my $counter = 1;
|
|
while($counter <= $retries) {
|
|
$comment_url_resp = get($comment_url);
|
|
if ($comment_url_resp) {
|
|
last; # Got response, no more retries
|
|
} else {
|
|
sleep($counter*2); # Sleep and try again
|
|
print "[send_back_comment] $counter Did not get response, sleeping ". $counter*2 . "\n";
|
|
$counter++;
|
|
}
|
|
}
|
|
unless ($comment_url_resp) {
|
|
print "[send_back_comment] After $retries retries, not able to get response from $comment_url \n";
|
|
# Failed after trying a few times, return
|
|
return;
|
|
}
|
|
print "\n\n>>>>>Dumper comment_url_resp:\n";
|
|
print Dumper $comment_url_resp;
|
|
|
|
$comment_content = $json->decode($comment_url_resp);
|
|
$comment_len = @$comment_content;
|
|
|
|
my $post_url = $comment_url;
|
|
my $post_method = "POST";
|
|
if($comment_len > 0){
|
|
foreach my $comment (@{$comment_content}){
|
|
if($comment->{'body'} =~ /CI CHECK RESULT/) {
|
|
$post_url = $comment->{'url'};
|
|
$post_method = "PATCH";
|
|
}
|
|
}
|
|
}
|
|
|
|
print "[send_back_comment] method = $post_method to $post_url. Message = $message\n";
|
|
if ( $ENV{'xcatbotuser'} and $ENV{'xcatbotpw'}) {
|
|
`curl -u "$ENV{'xcatbotuser'}:$ENV{'xcatbotpw'}" -X $post_method -d '{"body":"$message"}' $post_url`;
|
|
}
|
|
else {
|
|
print "Not able to update pull request with message: $message\n";
|
|
}
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: preserve_source_tree
|
|
# Description: Copy the checkout aside before the build destroys it, so the
|
|
# unit tests still have a source tree to run against afterwards.
|
|
# Must be called before build_xcat_core().
|
|
# Attributes:
|
|
# Return code: 0 Success 1 Failed
|
|
#--------------------------------------------------------
|
|
sub preserve_source_tree{
|
|
my $cmd = "rm -rf $unitsrc && cp -a $srcdir $unitsrc";
|
|
print "[preserve_source_tree] running $cmd\n";
|
|
my @output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[preserve_source_tree] $cmd ....[Failed]\n";
|
|
print Dumper \@output;
|
|
return 1;
|
|
}
|
|
|
|
@output = runcmd("find $unitsrc/xCAT-test/unit -name '*.t' | wc -l");
|
|
my $perl_count = $output[0];
|
|
@output = runcmd("find $unitsrc/xCAT-test/bats -name '*.bats' 2>/dev/null | wc -l");
|
|
my $bats_count = $output[0];
|
|
print "[preserve_source_tree] preserved $srcdir in $unitsrc ($perl_count Perl unit tests, $bats_count BATS tests)\n";
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: build_xcat_core
|
|
# Description:
|
|
# Attributes:
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub build_xcat_core{
|
|
my @output;
|
|
|
|
my $cmd = "sudo ./builddebs.pl --force";
|
|
@output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
my $lastline = $output[-1];
|
|
$lastline =~ s/[\r\n\t\\"']*//g;
|
|
print "[build_xcat_core] $cmd ....[Failed]\n";
|
|
$check_result_str .= "> **BUILD ERROR**, Please click ``Details`` label in ``Merge pull request`` box for detailed information";
|
|
print $check_result_str;
|
|
return 1;
|
|
}else{
|
|
print "[build_xcat_core] $cmd ....[Pass]\n";
|
|
$check_result_str .= "> **BUILD SUCCESSFUL** ";
|
|
print $check_result_str;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: install_xcat
|
|
# Description:
|
|
# Attributes:
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub install_xcat{
|
|
|
|
my $repo = "$srcdir/dist/debs/xcat-core";
|
|
unless (-x "$repo/mklocalrepo.sh") {
|
|
print RED "[install_xcat] $repo/mklocalrepo.sh missing -- did the build run?\n";
|
|
$check_result_str .= "> **INSTALL XCAT ERROR** : the build produced no apt repository ";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
my @cmds = ("sudo $repo/mklocalrepo.sh",
|
|
"sudo chmod 777 /etc/apt/sources.list",
|
|
"sudo echo \"deb [arch=amd64 allow-insecure=yes] http://xcat.org/files/xcat/repos/apt/latest/xcat-dep noble main\" >> /etc/apt/sources.list",
|
|
"sudo echo \"deb [arch=ppc64el allow-insecure=yes] http://xcat.org/files/xcat/repos/apt/latest/xcat-dep noble main\" >> /etc/apt/sources.list",
|
|
"sudo timeout 600 apt-get -qq -o Acquire::Retries=3 -o Acquire::http::Timeout=30 --allow-insecure-repositories update");
|
|
chdir $ENV{RUNNER_WORKSPACE};;
|
|
|
|
my @output;
|
|
foreach my $cmd (@cmds){
|
|
print "[install_xcat] running $cmd\n";
|
|
@output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[install_xcat] $cmd. ...[Failed]\n";
|
|
print "[install_xcat] error message:\n";
|
|
print Dumper \@output;
|
|
$check_result_str .= "> **INSTALL XCAT ERROR** : Please click ``Details`` label in ``Merge pull request`` box for detailed information ";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
my $cmd = "sudo timeout 1200 env DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=30 install -y xcat --allow-remove-essential --allow-unauthenticated";
|
|
@output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
my $lastline = $output[-1];
|
|
$lastline =~ s/[\r\n\t\\"']*//g;
|
|
print "[install_xcat] $cmd ....[Failed]\n";
|
|
print ">>>>>Dumper the output of '$cmd'\n";
|
|
print Dumper \@output;
|
|
$check_result_str .= "> **INSTALL XCAT ERROR** : Please click ``Details`` label in ``Merge pull request`` box for detailed information";
|
|
print $check_result_str;
|
|
return 1;
|
|
}else{
|
|
print "[install_xcat] $cmd ....[Pass]\n";
|
|
|
|
print "\n------Config xcat and verify xcat is working correctly-----\n";
|
|
@cmds = ("sudo -s /opt/xcat/share/xcat/scripts/setup-local-client.sh -f runner",
|
|
"sudo -s /opt/xcat/sbin/chtab priority=1.1 policy.name=runner policy.rule=allow",
|
|
". /etc/profile.d/xcat.sh && tabdump policy",
|
|
". /etc/profile.d/xcat.sh && tabdump site",
|
|
". /etc/profile.d/xcat.sh && lsxcatd -a",
|
|
"ls /opt/xcat/sbin",
|
|
"service xcatd status");
|
|
my $ret = 0;
|
|
foreach my $cmd (@cmds){
|
|
print "\n[install_xcat] running $cmd.....\n";
|
|
@output = runcmd("$cmd");
|
|
print Dumper \@output;
|
|
if($::RUNCMD_RC){
|
|
print RED "[install_xcat] $cmd. ...[Failed]\n";
|
|
#print Dumper \@output;
|
|
$ret = 1;
|
|
}else{
|
|
print "[install_xcat] $cmd....[Pass]\n";
|
|
}
|
|
}
|
|
$cmd = "sudo timeout 1200 env DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=30 install -y xcat-probe --allow-remove-essential --allow-unauthenticated";
|
|
@output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[install_xcat] $cmd ....[Failed]\n";
|
|
print Dumper \@output;
|
|
$ret = 1;
|
|
}else{
|
|
print "[install_xcat] $cmd ....[Pass]:\n";
|
|
}
|
|
|
|
if($ret){
|
|
$check_result_str .= "> **INSTALL XCAT ERROR** : Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
$check_result_str .= "> **INSTALL XCAT SUCCESSFUL**";
|
|
print $check_result_str;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_unit_tests
|
|
# Description: Run every Perl unit test under xCAT-test/unit with prove.
|
|
# Runs against the pre-build copy of the source tree taken by
|
|
# preserve_source_tree(): the tests reach for xCAT modules and
|
|
# fixture files through FindBin, so the installed copy under
|
|
# /opt/xcat/share/xcat/tools/autotest is not enough for them.
|
|
# Attributes:
|
|
# Return code: 0 all tests passed, 1 otherwise
|
|
#--------------------------------------------------------
|
|
sub run_unit_tests{
|
|
my $cmd = "cd $unitsrc && prove -r xCAT-test/unit";
|
|
print "[run_unit_tests] running $cmd\n";
|
|
my @output = runcmd("$cmd");
|
|
print Dumper \@output;
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_unit_tests] $cmd ....[Failed]\n";
|
|
$check_result_str .= "> **UNIT TESTS Failed** : Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
print "[run_unit_tests] $cmd ....[Pass]\n";
|
|
$check_result_str .= "> **UNIT TESTS Successful**\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_bats_tests
|
|
# Description: Run shell-script unit tests under xCAT-test/bats.
|
|
# Runs against the pre-build copy of the source tree taken by
|
|
# preserve_source_tree(), like the Perl unit tests.
|
|
# Attributes:
|
|
# Return code: 0 all tests passed, 1 otherwise
|
|
#--------------------------------------------------------
|
|
sub run_bats_tests{
|
|
my $testdir = "$unitsrc/xCAT-test/bats";
|
|
my @output = runcmd("find $testdir -name '*.bats' -print -quit 2>/dev/null");
|
|
if (!@output) {
|
|
print "[run_bats_tests] no BATS tests found under $testdir\n";
|
|
return 0;
|
|
}
|
|
|
|
my $cmd = "cd $unitsrc && bats -r xCAT-test/bats";
|
|
print "[run_bats_tests] running $cmd\n";
|
|
@output = runcmd("$cmd");
|
|
print Dumper \@output;
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_bats_tests] $cmd ....[Failed]\n";
|
|
$check_result_str .= "> **BATS TESTS Failed** : Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
print "[run_bats_tests] $cmd ....[Pass]\n";
|
|
$check_result_str .= "> **BATS TESTS Successful**\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_dhcptest_unit_tests
|
|
# Description: Run the dhcptest offline checks: its Python unit tests and
|
|
# `dhcptest validate` over every shipped .conf. Both are
|
|
# unprivileged and touch no network -- the wire scenarios need a
|
|
# provisioning NIC and a DHCP server, so they are not run here.
|
|
# Skipped when python3 is absent rather than failing the build.
|
|
# Attributes:
|
|
# Return code: 0 all checks passed, 1 otherwise
|
|
#--------------------------------------------------------
|
|
sub run_dhcptest_unit_tests{
|
|
my $testdir = "$unitsrc/xCAT-test/dhcptest";
|
|
if (! -d $testdir) {
|
|
print "[run_dhcptest_unit_tests] no dhcptest found under $testdir\n";
|
|
return 0;
|
|
}
|
|
runcmd("which python3 2>/dev/null");
|
|
if($::RUNCMD_RC){
|
|
print "[run_dhcptest_unit_tests] python3 is not installed, skipping\n";
|
|
return 0;
|
|
}
|
|
|
|
my $cmd = "cd $testdir && python3 -m unittest discover -s tests"
|
|
. " && python3 src/dhcptest validate conf/*.conf";
|
|
print "[run_dhcptest_unit_tests] running $cmd\n";
|
|
my @output = runcmd("$cmd");
|
|
print Dumper \@output;
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_dhcptest_unit_tests] $cmd ....[Failed]\n";
|
|
$check_result_str .= "> **DHCPTEST TESTS Failed** : Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
print "[run_dhcptest_unit_tests] $cmd ....[Pass]\n";
|
|
$check_result_str .= "> **DHCPTEST TESTS Successful**\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_provtest_unit_tests
|
|
# Description: Run the provtest offline checks: its Python unit tests and
|
|
# `provtest validate` over every shipped .conf. Both are
|
|
# unprivileged and touch no network -- the wire scenarios need a
|
|
# veth pair, a network namespace and a running xcatd, so they are
|
|
# not run here. Skipped when python3 is absent rather than
|
|
# failing the build.
|
|
# Attributes:
|
|
# Return code: 0 all checks passed, 1 otherwise
|
|
#--------------------------------------------------------
|
|
sub run_provtest_unit_tests{
|
|
my $testdir = "$unitsrc/xCAT-test/provtest";
|
|
if (! -d $testdir) {
|
|
print "[run_provtest_unit_tests] no provtest found under $testdir\n";
|
|
return 0;
|
|
}
|
|
runcmd("which python3 2>/dev/null");
|
|
if($::RUNCMD_RC){
|
|
print "[run_provtest_unit_tests] python3 is not installed, skipping\n";
|
|
return 0;
|
|
}
|
|
|
|
# The unit tests are discovered from inside tests/ because that is where
|
|
# their own context module puts the package on the path.
|
|
my $cmd = "cd $testdir/tests && python3 -m unittest discover -s . -p 'test_*.py'"
|
|
. " && cd $testdir && python3 src/provtest validate conf/*.conf";
|
|
print "[run_provtest_unit_tests] running $cmd\n";
|
|
my @output = runcmd("$cmd");
|
|
print Dumper \@output;
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_provtest_unit_tests] $cmd ....[Failed]\n";
|
|
$check_result_str .= "> **PROVTEST TESTS Failed** : Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
print "[run_provtest_unit_tests] $cmd ....[Pass]\n";
|
|
$check_result_str .= "> **PROVTEST TESTS Successful**\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: check_syntax
|
|
# Description:
|
|
# Attributes:
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub check_syntax{
|
|
my @output;
|
|
my @syntax_err;
|
|
my $ret = 0;
|
|
|
|
my @target_dirs=("/opt/xcat",
|
|
"/install");
|
|
foreach my $dir (@target_dirs){
|
|
my @files = ();
|
|
get_files_recursive("$dir", \@files);
|
|
|
|
foreach my $file (@files) {
|
|
next if($file =~ /\/opt\/xcat\/share\/xcat\/netboot\/genesis\//);
|
|
next if($file =~ /\/opt\/xcat\/probe\//);
|
|
next if($file =~ /\/opt\/xcat\/share\/xcat\/tools\/autotest\/unit\//);
|
|
|
|
@output = runcmd("file $file");
|
|
if($output[0] =~ /perl /i){
|
|
@output = runcmd("sudo bash -c '. /etc/profile.d/xcat.sh && perl -I /opt/xcat/lib/perl -I /opt/xcat/lib -I /usr/lib/perl5 -I /usr/share/perl -c $file'");
|
|
if($::RUNCMD_RC){
|
|
push @syntax_err, @output;
|
|
$ret = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(@syntax_err){
|
|
print "[check_syntax] syntax checking ....[Failed]\n";
|
|
print "[check_syntax] Dumper error message:\n";
|
|
print Dumper @syntax_err;
|
|
$check_result_str .= "> **CODE SYNTAX ERROR** : Please click ``Details`` label in ``Merge pull request`` box for detailed information";
|
|
print $check_result_str;
|
|
}else{
|
|
print "[check_syntax] syntax checking ....[Pass]\n";
|
|
$check_result_str .= "> **CODE SYNTAX CORRECT**";
|
|
print $check_result_str;
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: write_regression_conf
|
|
# Description: write an xcattest configuration file and return its path
|
|
# Attributes: $name - the file name, under the working directory
|
|
# $pin_backend - set site.dhcpbackend in [Table_site]
|
|
#
|
|
# xcattest applies [Table_site] before every case it runs, so a file that
|
|
# pins dhcpbackend pins it again on each invocation. That is what the fast
|
|
# regression set wants -- one known backend for the whole run -- and exactly
|
|
# what the DHCP wire phase must not have: it selects the backend itself, once
|
|
# per pass, and a conf file that reset it would undo the kea pass case by
|
|
# case and leave the run silently testing isc twice.
|
|
# Return code: the path written
|
|
#--------------------------------------------------------
|
|
sub write_regression_conf{
|
|
my ($name, $pin_backend) = @_;
|
|
|
|
my $hostname = `hostname`;
|
|
chomp($hostname);
|
|
print "hostname = $hostname\n";
|
|
|
|
my $conf_file = "$ENV{'PWD'}/$name";
|
|
system "sudo touch $conf_file";
|
|
system "sudo chmod 777 $conf_file";
|
|
open(my $fh, '>', $conf_file) or die "Could not open test configuration file $!";
|
|
print $fh "[System]\nMN=$hostname\n[Table_site]\nkey=domain\nvalue=pok.stglabs.ibm.com\n";
|
|
print $fh "key=dhcpbackend\nvalue=isc\n" if($pin_backend);
|
|
close($fh);
|
|
|
|
print "Dumper $name:\n";
|
|
my @output = runcmd("cat $conf_file");
|
|
print Dumper \@output;
|
|
|
|
return $conf_file;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: list_cases
|
|
# Description: the names of the cases matching an xcattest label expression
|
|
# Attributes: $expression - e.g. "ci_test-dhcp_wire"
|
|
# Return code: the list of case names, empty if none match or the query failed
|
|
#--------------------------------------------------------
|
|
sub list_cases{
|
|
my $expression = shift;
|
|
my $cmd = "sudo bash -c '. /etc/profile.d/xcat.sh && xcattest -s \"$expression\" -l'";
|
|
my @cases = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[list_cases] $cmd ....[Failed]\n";
|
|
print Dumper \@cases;
|
|
return ();
|
|
}
|
|
print "[list_cases] $expression:\n";
|
|
print Dumper \@cases;
|
|
# "There are no cases match search expression ..." is a sentence, not a case.
|
|
return grep { /^\S+$/ } @cases;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_cases
|
|
# Description: run a list of cases, one xcattest invocation each
|
|
# Attributes: $conf_file - the regression configuration
|
|
# $cases - the case names
|
|
# $suffix - appended to a failing case name in the summary, so
|
|
# a case run more than once says which run failed
|
|
# $counts - hashref accumulating pass/fail across every call
|
|
# $tag - the phase name to print log lines under
|
|
# Return code: none; results land in $counts and @{$counts->{failed}}
|
|
#--------------------------------------------------------
|
|
sub run_cases{
|
|
my ($conf_file, $cases, $suffix, $counts, $tag) = @_;
|
|
$tag = "run_fast_regression_test" unless($tag);
|
|
my $x = 0;
|
|
foreach my $case (@{$cases}){
|
|
++$x;
|
|
my $cmd = "sudo bash -c '. /etc/profile.d/xcat.sh && xcattest -f $conf_file -t $case'";
|
|
print "[$tag] run $x$suffix: $cmd\n";
|
|
my @output = runcmd("$cmd");
|
|
my $verbose = grep { $_ eq $case } @verbose_cases;
|
|
if($verbose){
|
|
print "[$tag] output of $case (listed in \@verbose_cases):\n";
|
|
print Dumper \@output;
|
|
}
|
|
for(my $i = $#output; $i>-1; --$i){
|
|
if($output[$i] =~ /------END::(.+)::Failed/){
|
|
push @{$counts->{failed}}, "$1$suffix";
|
|
++$counts->{fail};
|
|
print Dumper \@output unless($verbose);
|
|
last;
|
|
}elsif ($output[$i] =~ /------END::(.+)::Passed/){
|
|
++$counts->{pass};
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_dhcp_wire_test
|
|
# Description: run the DHCP wire cases, once per backend installed here.
|
|
#
|
|
# This is the last phase of the run, after the ci_test set, and the wire
|
|
# cases are deliberately not labelled ci_test. They do not leave the machine
|
|
# alone while they run -- a veth pair appears, site.dhcpinterfaces and
|
|
# site.dhcpbackend change, the DHCP daemon is stopped and started -- and
|
|
# although each case restores all of it from a trap, a ci_test case running
|
|
# in between would be sharing a management node that is mid-reconfiguration.
|
|
# Keeping them out of the set is also what stops them being run twice.
|
|
#
|
|
# Which DHCP backend a management node runs is an implementation default --
|
|
# kea on the newer distros, isc on the older ones -- so a node booting on the
|
|
# same network must be told the same things either way. Testing whichever
|
|
# backend the runner happened to configure proves half of that and hides
|
|
# every drift between the two.
|
|
#
|
|
# The whole set is therefore run against one backend and then again against
|
|
# the other, rather than each case switching backends internally: the daemon
|
|
# is reconfigured once per pass instead of once per case, and each failure in
|
|
# the summary carries the backend it belongs to.
|
|
#
|
|
# dhcpfixture.sh brackets each pass -- backend-setup selects the backend and
|
|
# stops the other daemon, backend-teardown puts the site table back and
|
|
# restarts what was running before.
|
|
# Attributes:
|
|
# Return code: 0 if every case passed under every backend
|
|
#--------------------------------------------------------
|
|
sub run_dhcp_wire_test{
|
|
my @cases = list_cases("dhcp_wire");
|
|
unless(@cases){
|
|
print "[run_dhcp_wire_test] no DHCP wire cases to run\n";
|
|
$check_result_str .= "> **DHCP WIRE TEST Skipped**: no case carries the dhcp_wire label\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
my $conf_file = write_regression_conf("dhcp-wire.conf", 0);
|
|
my $fixture = "/opt/xcat/share/xcat/tools/autotest/testcase/dhcptest/dhcpfixture.sh";
|
|
unless(-f $fixture){
|
|
print RED "[run_dhcp_wire_test] $fixture is missing, so the wire cases cannot be run per backend\n";
|
|
$check_result_str .= "> **DHCP WIRE TEST Failed**: $fixture is not installed\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
my @backends = runcmd("sudo bash -c '. /etc/profile.d/xcat.sh && $fixture backends'");
|
|
@backends = split ' ', join ' ', @backends;
|
|
unless(@backends){
|
|
print RED "[run_dhcp_wire_test] no DHCP daemon is installed, so the wire cases have nothing to talk to\n";
|
|
$check_result_str .= "> **DHCP WIRE TEST Failed**: no DHCP daemon is installed\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
print "[run_dhcp_wire_test] DHCP backends installed here: @backends\n";
|
|
|
|
my %counts = (pass => 0, fail => 0, failed => []);
|
|
foreach my $backend (@backends){
|
|
my $cmd = "sudo bash -c '. /etc/profile.d/xcat.sh && $fixture backend-setup $backend'";
|
|
my @output = runcmd("$cmd");
|
|
print Dumper \@output;
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_dhcp_wire_test] cannot serve with $backend\n";
|
|
push @{$counts{failed}}, "backend-setup($backend)";
|
|
++$counts{fail};
|
|
next;
|
|
}
|
|
|
|
run_cases($conf_file, \@cases, "($backend)", \%counts, "run_dhcp_wire_test");
|
|
|
|
@output = runcmd("sudo bash -c '. /etc/profile.d/xcat.sh && $fixture backend-teardown $backend'");
|
|
print Dumper \@output;
|
|
}
|
|
|
|
my $backend_str = join(" and ", @backends);
|
|
if(@backends < 2){
|
|
print "[run_dhcp_wire_test] WARNING: only $backend_str is installed here, so the backends were not compared\n";
|
|
}
|
|
|
|
# Case runs rather than cases: each case is run once per backend.
|
|
my $casenum = $counts{pass} + $counts{fail};
|
|
if($counts{fail}){
|
|
my $log_str = join(",", @{$counts{failed}});
|
|
$check_result_str .= "> **DHCP WIRE TEST Failed** ($backend_str): Totalrun $casenum Passed $counts{pass} Failed $counts{fail} FailedCases: $log_str. Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
$check_result_str .= "> **DHCP WIRE TEST Successful** ($backend_str): Totalrun $casenum Passed $counts{pass} Failed $counts{fail}\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_prov_wire_test
|
|
# Description: run the provisioning wire cases.
|
|
#
|
|
# These come after the ci_test set and before the DHCP wire phase, which is
|
|
# the order a node experiences: DNS, then the loader and its config, then the
|
|
# install tree, then the discovery and xcatd protocols. They are deliberately
|
|
# not labelled ci_test, for the same reason the DHCP wire cases are not --
|
|
# while one runs, the management node has an extra veth pair and network
|
|
# namespace, a network object and four nodes it did not have, a rewritten
|
|
# zone, and possibly a web server on another port. Each case puts all of it
|
|
# back from a trap, but a ci_test case running in between would be sharing a
|
|
# machine that is mid-reconfiguration.
|
|
#
|
|
# Unlike the DHCP cases these are run once rather than once per backend:
|
|
# nothing here depends on which DHCP server is installed, and the cases that
|
|
# would -- what a node is told over DHCP -- are dhcptest's subject.
|
|
# Attributes:
|
|
# Return code: 0 if every case passed
|
|
#--------------------------------------------------------
|
|
sub run_prov_wire_test{
|
|
my @cases = list_cases("prov_wire");
|
|
unless(@cases){
|
|
print "[run_prov_wire_test] no provisioning wire cases to run\n";
|
|
$check_result_str .= "> **PROVISION WIRE TEST Skipped**: no case carries the prov_wire label\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
my $fixture = "/opt/xcat/share/xcat/tools/autotest/testcase/provtest/provfixture.sh";
|
|
unless(-f $fixture){
|
|
print RED "[run_prov_wire_test] $fixture is missing, so the wire cases cannot be run\n";
|
|
$check_result_str .= "> **PROVISION WIRE TEST Failed**: $fixture is not installed\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
my $conf_file = write_regression_conf("prov-wire.conf", 0);
|
|
my %counts = (pass => 0, fail => 0, failed => []);
|
|
run_cases($conf_file, \@cases, "", \%counts, "run_prov_wire_test");
|
|
|
|
my $casenum = $counts{pass} + $counts{fail};
|
|
if($counts{fail}){
|
|
my $log_str = join(",", @{$counts{failed}});
|
|
$check_result_str .= "> **PROVISION WIRE TEST Failed**: Totalcase $casenum Passed $counts{pass} Failed $counts{fail} FailedCases: $log_str. Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}
|
|
|
|
$check_result_str .= "> **PROVISION WIRE TEST Successful**: Totalcase $casenum Passed $counts{pass} Failed $counts{fail}\n";
|
|
print $check_result_str;
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: run_fast_regression_test
|
|
# Description:
|
|
# Attributes:
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub run_fast_regression_test{
|
|
my $cmd = "sudo timeout 1200 env DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=30 install -y xcat-test --allow-remove-essential --allow-unauthenticated";
|
|
my @output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_fast_regression_test] $cmd ....[Failed]\n";
|
|
print Dumper \@output;
|
|
return 1;
|
|
}else{
|
|
print "[run_fast_regression_test] $cmd .....:\n";
|
|
print Dumper \@output;
|
|
}
|
|
|
|
$cmd = "sudo bash -c '. /etc/profile.d/xcat.sh && xcattest -h'";
|
|
@output = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_fast_regression_test] $cmd ....[Failed]\n";
|
|
print "[run_fast_regression_test] error dumper:\n";
|
|
print Dumper \@output;
|
|
return 1;
|
|
}else{
|
|
print "[run_fast_regression_test] $cmd .....:\n";
|
|
print Dumper \@output;
|
|
}
|
|
|
|
my $conf_file = write_regression_conf("regression.conf", 1);
|
|
|
|
$cmd = "sudo bash -c '. /etc/profile.d/xcat.sh && xcattest -s \"ci_test\" -l'";
|
|
my @caseslist = runcmd("$cmd");
|
|
if($::RUNCMD_RC){
|
|
print RED "[run_fast_regression_test] $cmd ....[Failed]\n";
|
|
print "[run_fast_regression_test] error dumper:\n";
|
|
print Dumper \@caseslist;
|
|
return 1;
|
|
}else{
|
|
print "[run_fast_regression_test] $cmd .....:\n";
|
|
print Dumper \@caseslist;
|
|
}
|
|
|
|
# Neither wire set is in this one: the DHCP cases reconfigure the DHCP
|
|
# server out from under whatever else is running, and the provisioning
|
|
# cases add an interface, nodes, a network and a rewritten zone. Both are
|
|
# labelled separately -- dhcp_wire and prov_wire -- and run as their own
|
|
# phases after this one. See run_prov_wire_test and run_dhcp_wire_test.
|
|
my $casenum = @caseslist;
|
|
my %counts = (pass => 0, fail => 0, failed => []);
|
|
run_cases($conf_file, \@caseslist, "", \%counts);
|
|
|
|
my $passnum = $counts{pass};
|
|
my $failnum = $counts{fail};
|
|
my @failcase = @{$counts{failed}};
|
|
|
|
if($failnum){
|
|
my $log_str = join (",", @failcase );
|
|
$check_result_str .= "> **FAST REGRESSION TEST Failed**: Totalcase $casenum Passed $passnum Failed $failnum FailedCases: $log_str. Please click ``Details`` label in ``Merge pull request`` box for detailed information\n";
|
|
print $check_result_str;
|
|
return 1;
|
|
}else{
|
|
$check_result_str .= "> **FAST REGRESSION TEST Successful**: Totalcase $casenum Passed $passnum Failed $failnum\n";
|
|
print $check_result_str;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#--------------------------------------------------------
|
|
# Fuction name: mark_time
|
|
# Description:
|
|
# Attributes:
|
|
# Return code:
|
|
#--------------------------------------------------------
|
|
sub mark_time{
|
|
my $func_name=shift;
|
|
my $nowtime = timelocal(localtime());
|
|
my $nowtime_str = scalar(localtime());
|
|
my $duration = $nowtime - $last_func_start;
|
|
$last_func_start = $nowtime;
|
|
print "[mark_time] $nowtime_str, ElapsedTime of $func_name is $duration s\n";
|
|
}
|
|
|
|
#===============Main Process=============================
|
|
|
|
my @os_info = runcmd("cat /etc/os-release");
|
|
print "Current OS information:\n";
|
|
print Dumper \@os_info;
|
|
|
|
my @perl_vserion = runcmd("perl -v");
|
|
print "Current perl information:\n";
|
|
print Dumper \@perl_vserion;
|
|
|
|
my @disk = runcmd("df -h");
|
|
print "Disk information:\n";
|
|
print Dumper \@disk;
|
|
|
|
# Hacking the netmask. Not sure if we need to recover it after finish xcattest
|
|
# Note: Here has an assumption from Travis VM: only 1 UP Ethernet interface available (CHANGEME if it not as is)
|
|
my @intfinfo = runcmd("ip -o link |grep 'link/ether'|grep 'state UP' |awk -F ':' '{print \$2}'|head -1");
|
|
foreach my $nic (@intfinfo) {
|
|
print "Hacking the netmask length to 16 if it is 32: $nic\n";
|
|
runcmd("ip -4 addr show $nic|grep 'inet'|grep -q '/32' && sudo ip addr add \$(hostname -I|awk '{print \$1}')/16 dev $nic");
|
|
}
|
|
my @ipinfo = runcmd("ip addr");
|
|
print "Networking information:\n";
|
|
print Dumper \@ipinfo;
|
|
|
|
#Start to build xcat core
|
|
|
|
#Save the source tree before the build deletes it, the unit tests need it later
|
|
print GREEN "\n------ Preserving the source tree for the unit tests ------\n";
|
|
$rst = preserve_source_tree();
|
|
if($rst){
|
|
print RED "Preserving the source tree failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("preserve_source_tree");
|
|
|
|
print GREEN "\n------ Building xCAT core package ------\n";
|
|
$rst = build_xcat_core();
|
|
if($rst){
|
|
print RED "Build of xCAT core package failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("build_xcat_core");
|
|
|
|
#Start to install xcat
|
|
print GREEN "\n------Installing xCAT ------\n";
|
|
$rst = install_xcat();
|
|
if($rst){
|
|
print RED "Install of xCAT failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("install_xcat");
|
|
|
|
#Run the xCAT-test unit tests. They need the perl dependencies xCAT pulls in
|
|
#(Net::DNS, XML::Simple) and a usable xCAT database, so they run after install.
|
|
print GREEN "\n------Running xCAT-test unit tests ------\n";
|
|
$rst = run_unit_tests();
|
|
if($rst){
|
|
print RED "Run of xCAT-test unit tests failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_unit_tests");
|
|
|
|
#Run shell-script unit tests.
|
|
print GREEN "\n------Running xCAT-test BATS tests ------\n";
|
|
$rst = run_bats_tests();
|
|
if($rst){
|
|
print RED "Run of xCAT-test BATS tests failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_bats_tests");
|
|
|
|
#Check the syntax of changing code
|
|
print GREEN "\n------ Checking the syntax of changed code------\n";
|
|
$rst = check_syntax();
|
|
if($rst){
|
|
print RED "Check syntax of changed code failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("check_syntax");
|
|
|
|
#run fast regression
|
|
print GREEN "\n------Running fast regression test ------\n";
|
|
$rst = run_fast_regression_test();
|
|
if($rst){
|
|
print RED "Run of fast regression test failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_fast_regression_test");
|
|
|
|
#The provisioning wire cases come next: after the ci_test set, so they are not
|
|
#reconfiguring the machine underneath it, and before the DHCP phases, which is
|
|
#the order a booting node meets them in. Their offline checks run first, so a
|
|
#scenario file that does not even parse is reported as that rather than as a
|
|
#case failure.
|
|
print GREEN "\n------Running xCAT-test provtest checks ------\n";
|
|
$rst = run_provtest_unit_tests();
|
|
if($rst){
|
|
print RED "Run of xCAT-test provtest checks failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_provtest_unit_tests");
|
|
|
|
print GREEN "\n------Running provisioning on-wire test ------\n";
|
|
$rst = run_prov_wire_test();
|
|
if($rst){
|
|
print RED "Run of provisioning on-wire test failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_prov_wire_test");
|
|
|
|
#Run the dhcptest offline checks -- unit tests plus `dhcptest validate` -- last:
|
|
#they exercise the source tree rather than the installed copy, and nothing else
|
|
#in the run depends on them.
|
|
print GREEN "\n------Running xCAT-test dhcptest checks ------\n";
|
|
$rst = run_dhcptest_unit_tests();
|
|
if($rst){
|
|
print RED "Run of xCAT-test dhcptest checks failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_dhcptest_unit_tests");
|
|
|
|
#The DHCP wire cases go last, once per backend installed. They are the only
|
|
#phase that reconfigures the DHCP server and restarts the daemon, so nothing
|
|
#that follows them could be trusted to be running against the machine it was
|
|
#given -- and the ci_test set above must not be sharing a management node that
|
|
#is mid-reconfiguration, which is why they are not labelled ci_test.
|
|
print GREEN "\n------Running DHCP on-wire test on every backend ------\n";
|
|
$rst = run_dhcp_wire_test();
|
|
if($rst){
|
|
print RED "Run of DHCP on-wire test failed\n";
|
|
exit $rst;
|
|
}
|
|
mark_time("run_dhcp_wire_test");
|
|
|
|
exit 0;
|