mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-21 23:28:19 +00:00
test(xcat-core): go-xcat asks to remove packages that are not installed
uninstall_xcat hands the whole GO_XCAT_UNINSTALL_LIST to the package manager. Most of that list is not installed on any one node -- it names packages xCAT stopped producing, so that `go-xcat uninstall` still removes them where they are present. apt answers "Unable to locate package" for a name it does not know and go-xcat prints a warning for each; dnf answers "No match for argument" and fails the whole call when nothing in the list matches. The test runs uninstall_xcat with rpm and dpkg-query answering from a fake package database and remove_package shadowed, and reads the argument list the package manager would have been given. A fourth case hands over a database where everything is installed, so a filter that dropped everything could not pass the other three. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
+109
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Temp qw(tempdir);
|
||||
use FindBin;
|
||||
use Test::More;
|
||||
|
||||
# `go-xcat uninstall` hands GO_XCAT_UNINSTALL_LIST to the package manager. That list names
|
||||
# packages xCAT stopped producing -- xCAT-genesis-builder, yaboot-xcat, conserver-xcat -- so
|
||||
# most of it is not installed on any one node. apt answers "Unable to locate package" for a
|
||||
# name it does not know, and go-xcat prints a warning for each; dnf answers "No match for
|
||||
# argument" and fails the whole call when nothing in the list matches.
|
||||
#
|
||||
# So what is not installed does not reach the package manager. That is also what makes keeping
|
||||
# a retired name in the list free, which is why the list outlives the build.
|
||||
#
|
||||
# uninstall_xcat is taken from the shipped script and run with the package database faked and
|
||||
# remove_package shadowed, so the assertions read the argument list the package manager would
|
||||
# have been given.
|
||||
|
||||
my $go_xcat = "$FindBin::Bin/../../xCAT-server/share/xcat/tools/go-xcat";
|
||||
plan skip_all => 'go-xcat not found' unless -r $go_xcat;
|
||||
plan tests => 4;
|
||||
|
||||
{
|
||||
my @handed = uninstall_args($go_xcat, ['xCAT-server', 'xCAT-client']);
|
||||
is_deeply([sort @handed], ['xCAT-client', 'xCAT-server'],
|
||||
'only the installed packages reach the package manager');
|
||||
}
|
||||
|
||||
{
|
||||
# The point of keeping a retired name: where it IS installed, it is still removed.
|
||||
my @handed = uninstall_args($go_xcat, ['xCAT-genesis-builder']);
|
||||
is_deeply(\@handed, ['xCAT-genesis-builder'],
|
||||
'a retired package that is installed is still removed');
|
||||
}
|
||||
|
||||
{
|
||||
my @handed = uninstall_args($go_xcat, []);
|
||||
is_deeply(\@handed, [],
|
||||
'a node with none of them installed hands the package manager nothing');
|
||||
}
|
||||
|
||||
{
|
||||
# Guards the fake: a database that says everything is installed must hand over the list,
|
||||
# or the three assertions above would pass against a filter that drops everything.
|
||||
my @handed = uninstall_args($go_xcat, ['*']);
|
||||
ok(scalar(@handed) > 10, 'with everything installed the whole list is handed over');
|
||||
}
|
||||
|
||||
# Extract `function NAME()` blocks by name, in the order asked for.
|
||||
sub extract {
|
||||
my ($text, @names) = @_;
|
||||
my @blocks;
|
||||
for my $name (@names) {
|
||||
my ($block) = $text =~ /^(function \Q$name\E\(\)\s*\n\{.*?^\})/ms;
|
||||
push @blocks, $block if $block;
|
||||
}
|
||||
return @blocks;
|
||||
}
|
||||
|
||||
# Run the shipped uninstall path with rpm and dpkg-query answering from a fake database and the
|
||||
# package manager shadowed, and collect what it was asked to remove.
|
||||
sub uninstall_args {
|
||||
my ($path, $installed) = @_;
|
||||
my $text = do { open my $fh, '<', $path or die "$path: $!"; local $/; <$fh> };
|
||||
|
||||
my ($lists) = $text =~ /^(GO_XCAT_INSTALL_LIST=\(.*?\n)\n/ms;
|
||||
BAIL_OUT("no package lists in $path") unless $lists;
|
||||
my @functions = extract($text, qw(function_dispatch installed_packages
|
||||
installed_packages_rpm installed_packages_deb
|
||||
uninstall_xcat));
|
||||
BAIL_OUT("no uninstall_xcat() in $path")
|
||||
unless grep { /^function uninstall_xcat\(\)/ } @functions;
|
||||
|
||||
my $dir = tempdir(CLEANUP => 1);
|
||||
my $driver = "$dir/driver.sh";
|
||||
my $present = join ' ', @{$installed};
|
||||
open my $fh, '>', $driver or die "$driver: $!";
|
||||
print {$fh} "set -u\n";
|
||||
print {$fh} "type() { return 1; }\n"; # the rpm branch of the lists
|
||||
print {$fh} $lists, "\n";
|
||||
print {$fh} <<"BASH";
|
||||
INSTALLED="$present"
|
||||
present() {
|
||||
case "\$INSTALLED" in *"*"*) return 0 ;; esac
|
||||
case " \$INSTALLED " in *" \$1 "*) return 0 ;; *) return 1 ;; esac
|
||||
}
|
||||
rpm() { for a in "\$\@"; do case "\$a" in -*) continue ;; esac; present "\$a" || return 1; done; return 0; }
|
||||
dpkg-query() {
|
||||
for a in "\$\@"; do
|
||||
case "\$a" in -*) continue ;; esac
|
||||
present "\$a" && echo "install ok installed"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
exit_if_bad() { :; }
|
||||
warn_if_bad() { :; }
|
||||
remove_package() { for a in "\$\@"; do case "\$a" in -y) continue ;; esac; echo "\$a"; done; }
|
||||
BASH
|
||||
print {$fh} join("\n", @functions), "\n";
|
||||
print {$fh} "uninstall_xcat -y\n";
|
||||
close $fh;
|
||||
|
||||
my @out = qx{bash '$driver' 2>/dev/null};
|
||||
chomp @out;
|
||||
return grep { length } @out;
|
||||
}
|
||||
Reference in New Issue
Block a user