mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-04 12:07:56 +00:00
test(utils): reuse and cover executable lookup
This commit is contained in:
@@ -5,7 +5,7 @@ cmd:mkdir -p /tmp/xcatprobe_l
|
||||
cmd:xcatprobe -l
|
||||
check:rc==0
|
||||
check:output=~Supported sub commands are:
|
||||
cmd:for module in GlobalDef.pm NetworkUtils.pm ServiceNodeUtils.pm; do test -r "/opt/xcat/probe/lib/perl/xCAT/$module" || exit 1; done
|
||||
cmd:for module in CommandUtils.pm GlobalDef.pm NetworkUtils.pm ServiceNodeUtils.pm; do test -r "/opt/xcat/probe/lib/perl/xCAT/$module" || exit 1; done
|
||||
check:rc==0
|
||||
cmd:xcatprobe -l|grep -v "Supported sub commands are" |awk '/^[[:graph:]]/ {print $1}'|sort > /tmp/xcatprobe_l/subcmd_from_xcatprobe_l
|
||||
cmd:ls -l /opt/xcat/probe/subcmds/ |awk '/^-/ {print $9}'|sort > /tmp/xcatprobe_l/subcmd_under_subcmds_dir
|
||||
|
||||
@@ -8,9 +8,10 @@ use File::Temp qw/tempfile/;
|
||||
use JSON ();
|
||||
use Test::More;
|
||||
|
||||
use xCAT::CommandUtils;
|
||||
use xCAT::DHCP::Backend::Kea;
|
||||
|
||||
my $kea_dhcp4 = command_path('kea-dhcp4');
|
||||
my $kea_dhcp4 = xCAT::CommandUtils::find_executable('kea-dhcp4');
|
||||
plan skip_all => 'kea-dhcp4 is not installed' unless $kea_dhcp4;
|
||||
|
||||
my $validation_dir = validation_temp_dir($kea_dhcp4);
|
||||
@@ -106,7 +107,7 @@ ok( !$result->{error}, 'generated Kea DHCPv4 config validates with kea-dhcp4 -t'
|
||||
|
||||
unlink $path;
|
||||
SKIP: {
|
||||
skip 'kea-dhcp6 is not installed', 1 unless command_path('kea-dhcp6');
|
||||
skip 'kea-dhcp6 is not installed', 1 unless xCAT::CommandUtils::find_executable('kea-dhcp6');
|
||||
my $dhcp6_json = $backend->render_dhcp6_config(
|
||||
{
|
||||
interfaces => ['*'],
|
||||
@@ -150,7 +151,7 @@ SKIP: {
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'kea-dhcp-ddns is not installed', 1 unless command_path('kea-dhcp-ddns');
|
||||
skip 'kea-dhcp-ddns is not installed', 1 unless xCAT::CommandUtils::find_executable('kea-dhcp-ddns');
|
||||
my $ddns_json = $backend->render_ddns_config(
|
||||
{
|
||||
'tsig-keys' => [
|
||||
@@ -180,7 +181,7 @@ SKIP: {
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'kea-ctrl-agent is not installed', 1 unless command_path('kea-ctrl-agent');
|
||||
skip 'kea-ctrl-agent is not installed', 1 unless xCAT::CommandUtils::find_executable('kea-ctrl-agent');
|
||||
my $ctrl_agent_json = $backend->render_ctrl_agent_config(
|
||||
{
|
||||
dhcp6 => 1,
|
||||
@@ -195,21 +196,6 @@ SKIP: {
|
||||
}
|
||||
done_testing();
|
||||
|
||||
sub command_path {
|
||||
my ($command) = @_;
|
||||
|
||||
foreach my $dir ( split /:/, $ENV{PATH} || '' ) {
|
||||
next unless $dir;
|
||||
return "$dir/$command" if -x "$dir/$command";
|
||||
}
|
||||
|
||||
foreach my $path ( "/usr/sbin/$command", "/usr/bin/$command", "/sbin/$command", "/bin/$command" ) {
|
||||
return $path if -x $path;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub validation_temp_dir {
|
||||
my ($kea_dhcp4) = @_;
|
||||
|
||||
|
||||
@@ -11,14 +11,15 @@ use POSIX qw/WNOHANG _exit setgid setuid/;
|
||||
use Test::More;
|
||||
use Time::HiRes qw/sleep time/;
|
||||
|
||||
use xCAT::CommandUtils;
|
||||
use xCAT::DHCP::Backend::Kea;
|
||||
|
||||
plan skip_all => 'set XCAT_KEA_LIVE_SMOKE=1 to run live Kea daemon smoke test'
|
||||
unless $ENV{XCAT_KEA_LIVE_SMOKE};
|
||||
plan skip_all => 'live Kea daemon smoke test must run as root' unless $> == 0;
|
||||
|
||||
my $kea_dhcp4 = command_path('kea-dhcp4');
|
||||
my $kea_ctrl = command_path('kea-ctrl-agent');
|
||||
my $kea_dhcp4 = xCAT::CommandUtils::find_executable('kea-dhcp4');
|
||||
my $kea_ctrl = xCAT::CommandUtils::find_executable('kea-ctrl-agent');
|
||||
plan skip_all => 'kea-dhcp4 and kea-ctrl-agent are required'
|
||||
unless $kea_dhcp4 && $kea_ctrl;
|
||||
|
||||
@@ -192,21 +193,6 @@ SKIP: {
|
||||
stop_daemons(\%children);
|
||||
done_testing();
|
||||
|
||||
sub command_path {
|
||||
my ($command) = @_;
|
||||
|
||||
foreach my $dir ( split /:/, $ENV{PATH} || '' ) {
|
||||
next unless $dir;
|
||||
return "$dir/$command" if -x "$dir/$command";
|
||||
}
|
||||
|
||||
foreach my $path ( "/usr/sbin/$command", "/usr/bin/$command", "/sbin/$command", "/bin/$command" ) {
|
||||
return $path if -x $path;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub start_daemon {
|
||||
my ( $account, $command, $log, @args ) = @_;
|
||||
my $pid = fork();
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
|
||||
use Cwd qw/getcwd/;
|
||||
use File::Path qw/make_path/;
|
||||
use File::Temp qw/tempdir/;
|
||||
use Test::More;
|
||||
|
||||
use xCAT::CommandUtils;
|
||||
|
||||
my $command_utils_source = "$FindBin::Bin/../../perl-xCAT/xCAT/CommandUtils.pm";
|
||||
open( my $source_fh, '<', $command_utils_source )
|
||||
or die "Unable to read $command_utils_source: $!";
|
||||
my $source = do { local $/; <$source_fh> };
|
||||
close($source_fh) or die "Unable to close $command_utils_source: $!";
|
||||
like(
|
||||
$source,
|
||||
qr/my \@SYSTEM_FALLBACK_DIRS = qw\(\s*\/usr\/sbin\s*\/usr\/bin\s*\/sbin\s*\/bin\s*\);/s,
|
||||
'the built-in system fallback order matches the replaced callers'
|
||||
);
|
||||
|
||||
my $root = tempdir(CLEANUP => 1);
|
||||
my $first_dir = "$root/first";
|
||||
my $second_dir = "$root/second";
|
||||
my $fallback_dir = "$root/fallback";
|
||||
make_path( $first_dir, $second_dir, $fallback_dir, "$root/relative" );
|
||||
|
||||
sub write_executable {
|
||||
my ($path) = @_;
|
||||
open( my $fh, '>', $path ) or die "Unable to write $path: $!";
|
||||
print {$fh} "#!/bin/sh\nexit 0\n";
|
||||
close($fh) or die "Unable to close $path: $!";
|
||||
chmod 0755, $path or die "Unable to make $path executable: $!";
|
||||
return $path;
|
||||
}
|
||||
|
||||
my $first_tool = write_executable("$first_dir/xcat-command-utils-tool");
|
||||
my $second_tool = write_executable("$second_dir/xcat-command-utils-tool");
|
||||
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-tool',
|
||||
path => "$first_dir:$second_dir",
|
||||
fallback_dirs => [],
|
||||
),
|
||||
$first_tool,
|
||||
'PATH entries are searched in order'
|
||||
);
|
||||
|
||||
chmod 0644, $first_tool or die "Unable to remove execute permission from $first_tool: $!";
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-tool',
|
||||
path => "$first_dir:$second_dir",
|
||||
fallback_dirs => [],
|
||||
),
|
||||
$second_tool,
|
||||
'non-executable candidates are skipped'
|
||||
);
|
||||
|
||||
{
|
||||
local $ENV{PATH} = $second_dir;
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable('xcat-command-utils-tool'),
|
||||
$second_tool,
|
||||
'the process PATH is used by default'
|
||||
);
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-tool',
|
||||
path => $first_dir,
|
||||
fallback_dirs => [],
|
||||
),
|
||||
undef,
|
||||
'an explicit path overrides the process PATH'
|
||||
);
|
||||
}
|
||||
|
||||
my $fallback_tool = write_executable("$fallback_dir/xcat-command-utils-fallback");
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-fallback',
|
||||
path => '',
|
||||
fallback_dirs => [ '', $fallback_dir ],
|
||||
),
|
||||
$fallback_tool,
|
||||
'custom fallback directories are searched after PATH and ignore empty entries'
|
||||
);
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-fallback',
|
||||
path => '',
|
||||
fallback_dirs => [],
|
||||
),
|
||||
undef,
|
||||
'fallback lookup can be disabled'
|
||||
);
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'bin',
|
||||
path => '',
|
||||
fallback_dirs => [''],
|
||||
),
|
||||
undef,
|
||||
'empty fallback entries are ignored instead of matching executable root directories'
|
||||
);
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-tool',
|
||||
path => '',
|
||||
fallback_dirs => [$first_dir],
|
||||
),
|
||||
undef,
|
||||
'non-executable fallback candidates are skipped'
|
||||
);
|
||||
|
||||
my $fallback_order_first = write_executable("$first_dir/xcat-command-utils-fallback-order");
|
||||
write_executable("$second_dir/xcat-command-utils-fallback-order");
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-fallback-order',
|
||||
path => '',
|
||||
fallback_dirs => [ $first_dir, $second_dir ],
|
||||
),
|
||||
$fallback_order_first,
|
||||
'custom fallback directories are searched in order'
|
||||
);
|
||||
|
||||
my $path_collision = write_executable("$second_dir/xcat-command-utils-collision");
|
||||
write_executable("$fallback_dir/xcat-command-utils-collision");
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-collision',
|
||||
path => $second_dir,
|
||||
fallback_dirs => [$fallback_dir],
|
||||
),
|
||||
$path_collision,
|
||||
'PATH matches take precedence over fallback matches'
|
||||
);
|
||||
|
||||
my $system_shell = xCAT::CommandUtils::find_executable( 'sh', path => '' );
|
||||
my ($expected_system_shell) = grep { -x "$_/sh" } qw(/usr/sbin /usr/bin /sbin /bin);
|
||||
is(
|
||||
$system_shell,
|
||||
defined($expected_system_shell) ? "$expected_system_shell/sh" : undef,
|
||||
'standard system directories are searched by default'
|
||||
);
|
||||
|
||||
my $original_dir = getcwd();
|
||||
chdir($root) or die "Unable to enter $root: $!";
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'bin',
|
||||
path => ":$second_dir",
|
||||
fallback_dirs => [],
|
||||
),
|
||||
undef,
|
||||
'empty PATH entries are ignored instead of matching executable root directories'
|
||||
);
|
||||
|
||||
write_executable("$root/relative/xcat-command-utils-relative");
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-relative',
|
||||
path => 'relative',
|
||||
fallback_dirs => [],
|
||||
),
|
||||
'relative/xcat-command-utils-relative',
|
||||
'relative PATH entries preserve the existing candidate path shape'
|
||||
);
|
||||
|
||||
make_path("$root/0");
|
||||
write_executable("$root/0/xcat-command-utils-zero-entry");
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
'xcat-command-utils-zero-entry',
|
||||
path => "0:$second_dir",
|
||||
fallback_dirs => [],
|
||||
),
|
||||
undef,
|
||||
'a PATH component named zero retains the existing falsy-entry behavior'
|
||||
);
|
||||
chdir($original_dir) or die "Unable to restore $original_dir: $!";
|
||||
|
||||
my $marker = "$root/shell-was-invoked";
|
||||
my $literal_name = 'xcat-command-utils;touch shell-was-invoked';
|
||||
my $literal_tool = write_executable("$second_dir/$literal_name");
|
||||
chdir($root) or die "Unable to enter $root for shell-safety lookup: $!";
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable(
|
||||
$literal_name,
|
||||
path => $second_dir,
|
||||
fallback_dirs => [],
|
||||
),
|
||||
$literal_tool,
|
||||
'command names are treated as filesystem paths without shell interpretation'
|
||||
);
|
||||
ok( !-e $marker, 'executable lookup never invokes a shell' );
|
||||
chdir($original_dir) or die "Unable to restore $original_dir: $!";
|
||||
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable( undef, path => $second_dir ),
|
||||
undef,
|
||||
'an undefined command is not searched'
|
||||
);
|
||||
is(
|
||||
xCAT::CommandUtils::find_executable( '', path => $second_dir ),
|
||||
undef,
|
||||
'an empty command is not searched'
|
||||
);
|
||||
|
||||
done_testing();
|
||||
@@ -307,4 +307,12 @@ is(
|
||||
'forced Kea succeeds when available'
|
||||
);
|
||||
|
||||
{
|
||||
local $ENV{PATH} = '';
|
||||
ok(
|
||||
xCAT::DHCP::Backend::_command_exists('sh'),
|
||||
'backend availability retains the standard system-directory fallback'
|
||||
);
|
||||
}
|
||||
|
||||
done_testing();
|
||||
|
||||
@@ -162,6 +162,15 @@ foreach my $case (@sysconfig_policy_cases) {
|
||||
close($ip_fh);
|
||||
chmod 0755, $fake_ip;
|
||||
|
||||
{
|
||||
local $ENV{PATH} = $tmpdir;
|
||||
is(
|
||||
xCAT_plugin::dhcp::kea_command_path('ip'),
|
||||
$fake_ip,
|
||||
'DHCP route command lookup retains the first executable PATH match'
|
||||
);
|
||||
}
|
||||
|
||||
no warnings 'redefine';
|
||||
local *xCAT_plugin::dhcp::kea_command_path = sub {
|
||||
my ($command) = @_;
|
||||
|
||||
@@ -580,6 +580,15 @@ FAKE_KEA
|
||||
close($fake_kea_fh) or die "Unable to close fake Kea command: $!";
|
||||
chmod 0755, $fake_kea_dhcp4 or die "Unable to make fake Kea command executable: $!";
|
||||
|
||||
{
|
||||
local $ENV{PATH} = $unit_dir;
|
||||
is(
|
||||
xCAT::DHCP::Backend::Kea::_command_path('kea-dhcp4-build-report'),
|
||||
$fake_kea_dhcp4,
|
||||
'Kea command lookup retains the first executable PATH match'
|
||||
);
|
||||
}
|
||||
|
||||
my $command_socket_backend = xCAT::DHCP::Backend::Kea->new(kea_dhcp4_command => $fake_kea_dhcp4);
|
||||
is( $command_socket_backend->control_socket_path('kea4-ctrl-socket'), '/xcat-test-command-run/kea/kea4-ctrl-socket', 'socket path comes from the Kea build-report command' );
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../xCAT-probe/lib/perl";
|
||||
|
||||
use Test::More;
|
||||
|
||||
@@ -3,6 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../xCAT-probe/lib/perl";
|
||||
|
||||
use File::Slurper qw(write_text);
|
||||
|
||||
@@ -3,6 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../xCAT-probe/lib/perl";
|
||||
|
||||
use File::Temp qw(tempdir);
|
||||
|
||||
@@ -3,6 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../xCAT-probe/lib/perl";
|
||||
|
||||
use Test::More;
|
||||
@@ -49,6 +50,14 @@ ok(probe_utils::_tcp_listener_output_has_port($netstat_output, 80, qr/httpd|apac
|
||||
ok(!probe_utils::_tcp_listener_output_has_port($netstat_output, 0), 'invalid port is rejected');
|
||||
ok(!probe_utils::_tcp_listener_output_has_port($netstat_output, 'http'), 'non-numeric port is rejected');
|
||||
|
||||
{
|
||||
local $ENV{PATH} = '';
|
||||
ok(
|
||||
!probe_utils::_command_available('sh'),
|
||||
'probe command discovery retains PATH-only lookup without system fallbacks'
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
no warnings 'redefine';
|
||||
my @commands;
|
||||
|
||||
@@ -9,11 +9,14 @@ use File::Spec;
|
||||
use File::Temp qw(tempdir);
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
use lib "$FindBin::Bin/../../build-utils/lib";
|
||||
use Test::More;
|
||||
|
||||
use XCAT::BuildUtils qw(XCAT_PROBE_HELPERS);
|
||||
use XCAT::Test::File qw(repo_path slurp_repo_file);
|
||||
|
||||
my @helpers = qw(
|
||||
CommandUtils.pm
|
||||
GlobalDef.pm
|
||||
NetworkUtils.pm
|
||||
ServiceNodeUtils.pm
|
||||
@@ -26,6 +29,9 @@ my @affected_subcommands = qw(
|
||||
);
|
||||
|
||||
my $builder = slurp_repo_file('buildrpms.pl');
|
||||
my $debian_builder = slurp_repo_file('build-ubunturepo');
|
||||
my $installed_probe_test =
|
||||
slurp_repo_file('xCAT-test/autotest/testcase/probe/xcatproble_list');
|
||||
my $rpm_spec = slurp_repo_file('xCAT-probe/xCAT-probe.spec');
|
||||
my $debian_control = slurp_repo_file('xCAT-probe/debian/control');
|
||||
like($builder, qr/sub prepare_xcat_probe_source_tar\b/, 'RPM builder has dedicated xCAT-probe source preparation');
|
||||
@@ -65,6 +71,20 @@ for my $helper (@helpers) {
|
||||
my $source = repo_path(File::Spec->catfile('perl-xCAT', 'xCAT', $helper));
|
||||
ok(-f $source, "$helper source exists");
|
||||
like($builder, qr/^\s*\Q$helper\E\s*$/m, "RPM builder stages $helper");
|
||||
ok(
|
||||
scalar(grep { $_ eq $helper } XCAT_PROBE_HELPERS),
|
||||
"the shared builder helper list carries $helper"
|
||||
);
|
||||
like(
|
||||
$debian_builder,
|
||||
qr{cp -f [^\n]*/perl-xCAT/xCAT/\Q$helper\E\s+[^\n]*/lib/perl/xCAT/},
|
||||
"Debian builder stages $helper"
|
||||
);
|
||||
like(
|
||||
$installed_probe_test,
|
||||
qr/cmd:for module in [^;]*\b\Q$helper\E\b[^;]*; do test -r/,
|
||||
"installed probe payload checks $helper"
|
||||
);
|
||||
}
|
||||
|
||||
my $tmpdir = tempdir(CLEANUP => 1);
|
||||
|
||||
Reference in New Issue
Block a user