Skip to content

Commit

Permalink
Merge pull request chaos#145 from chu11/test_failures
Browse files Browse the repository at this point in the history
redfishpower: add option to test host errors
  • Loading branch information
mergify[bot] committed Feb 22, 2024
2 parents 3939b01 + 07b3a3e commit 226d705
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 64 deletions.
12 changes: 6 additions & 6 deletions man/redfishpower.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ set simultaneously is limited by the file descriptor limit of the
system call.
.TP
.I "-H, --header string"
Set extra HEADER to use.
Set extra HEADER to use. Typically is Content-Type:application/json.
.TP
.I "-S, --statpath string"
Set Redfish path for obtaining power status. Typically is redfish/v1/Systems/1.
Expand Down Expand Up @@ -60,14 +60,14 @@ Set extra HEADER to use. Do not specify data to clear.
.I "setstatpath <path>"
Set path to obtain power status.
.TP
.I "setonpath <path> [data]"
.I "setonpath <path> [postdata]"
Set path and optional post data to turn on node.
.TP
.I "setoffpath <path> [data]"
.I "setoffpath <path> [postdata]"
Set path and optional post data to turn off node.
.TP
.I "setcyclepath <path> [data]"
Set path and optional post data to turn cycle node.
.I "setcyclepath <path> [postdata]"
Set path and optional post data to cycle node.
.TP
.I "settimeout <seconds>"
Set command timeout in seconds.
Expand All @@ -82,7 +82,7 @@ Turn on all nodes or specified subset of nodes. Will return "ok" after confirma
Turn off all nodes or specified subset of nodes. Will return "ok" after confirmation "off" has completed.
.TP
.I "cycle [nodes]"
Turn off all nodes or specified subset of nodes.
Power cycle all nodes or specified subset of nodes.

.SH "UPDATING REDFISHPOWER DEVICE FILES"
.LP
Expand Down
138 changes: 80 additions & 58 deletions src/redfishpower/redfishpower.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ static char *cyclepath = NULL;
static char *cyclepostdata = NULL;

static int test_mode = 0;
static zhashx_t *test_power_status = NULL;
static hostlist_t test_fail_power_cmd_hosts;
static zhashx_t *test_power_status;

/* in seconds */
#define MESSAGE_TIMEOUT 10
Expand Down Expand Up @@ -113,7 +114,7 @@ struct powermsg {
err_exit(false, "curl_easy_setopt: %s", curl_easy_strerror(_ec)); \
} while(0)

#define OPTIONS "h:H:S:O:F:C:P:G:D:Tv"
#define OPTIONS "h:H:S:O:F:C:P:G:D:TEv"
static struct option longopts[] = {
{"hostname", required_argument, 0, 'h' },
{"header", required_argument, 0, 'H' },
Expand All @@ -125,6 +126,7 @@ static struct option longopts[] = {
{"offpostdata", required_argument, 0, 'G' },
{"cyclepostdata", required_argument, 0, 'D' },
{"test-mode", no_argument, 0, 'T' },
{"test-fail-power-cmd-hosts", required_argument, 0, 'E' },
{"verbose", no_argument, 0, 'v' },
{0,0,0,0},
};
Expand All @@ -136,10 +138,10 @@ void help(void)
printf("Valid commands are:\n");
printf(" auth user:passwd\n");
printf(" setheader string\n");
printf(" setstatpath url\n");
printf(" setonpath url [data]\n");
printf(" setoffpath url [data]\n");
printf(" setcyclepath url [data]\n");
printf(" setstatpath path\n");
printf(" setonpath path [postdata]\n");
printf(" setoffpath path [postdata]\n");
printf(" setcyclepath path [postdata]\n");
printf(" settimeout seconds\n");
printf(" stat [nodes]\n");
printf(" on [nodes]\n");
Expand All @@ -149,26 +151,26 @@ void help(void)

static size_t output_cb(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct powermsg *pm = userp;

if (pm->output) {
char *tmp = calloc(1, pm->output_len + realsize + 1);
if (!tmp)
err_exit(true, "calloc");
memcpy(tmp, pm->output, pm->output_len);
memcpy(tmp + pm->output_len, contents, realsize);
pm->output_len += realsize;
free(pm->output);
pm->output = tmp;
}
else {
if (!(pm->output = calloc(1, realsize + 1)))
err_exit(true, "calloc");
memcpy(pm->output, contents, realsize);
pm->output_len = realsize;
}
return realsize;
size_t realsize = size * nmemb;
struct powermsg *pm = userp;

if (pm->output) {
char *tmp = calloc(1, pm->output_len + realsize + 1);
if (!tmp)
err_exit(true, "calloc");
memcpy(tmp, pm->output, pm->output_len);
memcpy(tmp + pm->output_len, contents, realsize);
pm->output_len += realsize;
free(pm->output);
pm->output = tmp;
}
else {
if (!(pm->output = calloc(1, realsize + 1)))
err_exit(true, "calloc");
memcpy(pm->output, contents, realsize);
pm->output_len = realsize;
}
return realsize;
}

static struct powermsg *powermsg_create(CURLM *mh,
Expand Down Expand Up @@ -329,9 +331,9 @@ static struct powermsg *stat_cmd_host(CURLM * mh, char *hostname)

static void stat_cmd(zlistx_t *activecmds, CURLM *mh, char **av)
{
hostlist_iterator_t itr = NULL;
hostlist_iterator_t itr;
char *hostname;
hostlist_t *hostsptr = NULL;
hostlist_t *hostsptr;
hostlist_t lhosts = NULL;

if (!statpath) {
Expand Down Expand Up @@ -410,7 +412,7 @@ static void parse_onoff(struct powermsg *pm, const char **strp)
}
}

static void stat_process (struct powermsg *pm)
static void stat_process(struct powermsg *pm)
{
const char *str;
parse_onoff(pm, &str);
Expand Down Expand Up @@ -452,9 +454,9 @@ static void power_cmd(zlistx_t *activecmds,
const char *path,
const char *postdata)
{
hostlist_iterator_t itr = NULL;
hostlist_iterator_t itr;
char *hostname;
hostlist_t *hostsptr = NULL;
hostlist_t *hostsptr;
hostlist_t lhosts = NULL;

if (!path) {
Expand Down Expand Up @@ -675,26 +677,27 @@ static void setpowerpath(char **av, char **path, char **postdata)
xfree(*postdata);
*postdata = NULL;
}
if (av[0])
if (av[0]) {
(*path) = xstrdup(av[0]);
if (av[1])
(*postdata) = xstrdup(av[1]);
if (av[1])
(*postdata) = xstrdup(av[1]);
}
}

static void settimeout(char **av)
{
if (av[0]) {
char *endptr;
long tmp;

errno = 0;
tmp = strtol (av[0], &endptr, 10);
if (errno
|| endptr[0] != '\0'
|| tmp <= 0)
printf("invalid timeout specified\n");
cmd_timeout = tmp;
}
if (av[0]) {
char *endptr;
long tmp;

errno = 0;
tmp = strtol (av[0], &endptr, 10);
if (errno
|| endptr[0] != '\0'
|| tmp <= 0)
printf("invalid timeout specified\n");
cmd_timeout = tmp;
}
}

static void process_cmd(zlistx_t *activecmds, CURLM *mh, char **av, int *exitflag)
Expand Down Expand Up @@ -758,6 +761,7 @@ static void shell(CURLM *mh)

if (!(delayedcmds = zlistx_new()))
err_exit(true, "zlistx_new");
zlistx_set_destructor(delayedcmds, cleanup_powermsg);

while (exitflag == 0) {
CURLMcode mc;
Expand Down Expand Up @@ -956,7 +960,10 @@ static void shell(CURLM *mh)
/* in test mode we assume all activecmds complete immediately */
struct powermsg *pm = zlistx_first(activecmds);
while (pm) {
power_cmd_process(delayedcmds, pm);
if (hostlist_find(test_fail_power_cmd_hosts, pm->hostname) >= 0)
printf("%s: %s\n", pm->hostname, "error");
else
power_cmd_process(delayedcmds, pm);
fflush(stdout);
zlistx_detach_cur(activecmds);
pm = zlistx_next(activecmds);
Expand Down Expand Up @@ -992,10 +999,30 @@ static void init_redfishpower(char *argv[])
if (!(hosts = hostlist_create(NULL)))
err_exit(true, "hostlist_create error");

if (!(test_fail_power_cmd_hosts = hostlist_create(NULL)))
err_exit(true, "hostlist_create error");

if (!(test_power_status = zhashx_new ()))
err_exit(false, "zhashx_new error");
}

static void cleanup_redfishpower(void)
{
xfree(userpwd);
xfree(statpath);
xfree(onpath);
xfree(onpostdata);
xfree(offpath);
xfree(offpostdata);
xfree(cyclepath);
xfree(cyclepostdata);

hostlist_destroy(hosts);

hostlist_destroy(test_fail_power_cmd_hosts);
zhashx_destroy(&test_power_status);
}

int main(int argc, char *argv[])
{
CURLM *mh = NULL;
Expand Down Expand Up @@ -1037,6 +1064,10 @@ int main(int argc, char *argv[])
case 'T': /* --test-mode */
test_mode = 1;
break;
case 'E': /* --test-fail-power-cmd-hosts */
if (!hostlist_push(test_fail_power_cmd_hosts, optarg))
err_exit(true, "hostlist_push error on %s", optarg);
break;
case 'v': /* --verbose */
verbose = 1;
break;
Expand All @@ -1060,7 +1091,7 @@ int main(int argc, char *argv[])
}
else {
/* All hosts initially are off for testing */
hostlist_iterator_t itr = NULL;
hostlist_iterator_t itr;
char *hostname;
if (!(itr = hostlist_iterator_create(hosts)))
err_exit(true, "hostlist_iterator_create");
Expand All @@ -1077,16 +1108,7 @@ int main(int argc, char *argv[])
if (!test_mode)
curl_multi_cleanup(mh);

xfree(userpwd);
hostlist_destroy(hosts);
xfree(statpath);
xfree(onpath);
xfree(onpostdata);
xfree(offpath);
xfree(offpostdata);
xfree(cyclepath);
xfree(cyclepostdata);
zhashx_destroy(&test_power_status);
cleanup_redfishpower();
exit(0);
}

Expand Down
42 changes: 42 additions & 0 deletions t/t0029-redfish.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ makeoutput() {
printf "unknown: %s\n" $3
}

#
# redfishpower core tests
#

test_expect_success 'create powerman.conf for 16 cray redfish nodes' '
cat >powerman.conf <<-EOT
listen "$testaddr"
Expand Down Expand Up @@ -102,6 +106,44 @@ test_expect_success 'stop powerman daemon' '
kill -15 $(cat powermand.pid) &&
wait
'

#
# redfishpower fail hosts coverage
#

test_expect_success 'create powerman.conf for 16 cray redfish nodes (failhosts)' '
cat >powerman_fail_hosts.conf <<-EOT
listen "$testaddr"
include "$devicesdir/redfishpower-cray-r272z30.dev"
device "d0" "redfishpower-cray-r272z30" "$redfishdir/redfishpower -h t[0-15] --test-mode --test-fail-power-cmd-hosts=t[8-15] |&"
node "t[0-15]" "d0"
EOT
'
test_expect_success 'start powerman daemon and wait for it to start (failhosts)' '
$powermand -Y -c powerman_fail_hosts.conf &
echo $! >powermand.pid &&
$powerman --retry-connect=100 --server-host=$testaddr -d
'
test_expect_success 'powerman -q shows t[0-7] off, t[8-15] unknown' '
$powerman -h $testaddr -q >test_failhosts_query.out &&
makeoutput "" "t[0-7]" "t[8-15]" >test_failhosts_query.exp &&
test_cmp test_failhosts_query.exp test_failhosts_query.out
'
test_expect_success 'powerman -1 t[0-15] completes' '
$powerman -h $testaddr -1 t[0-15] >test_failhosts_on.out &&
echo Command completed successfully >test_failhosts_on.exp &&
test_cmp test_failhosts_on.exp test_failhosts_on.out
'
test_expect_success 'powerman -q shows t[0-7] on' '
$powerman -h $testaddr -q >test_failhosts_query2.out &&
makeoutput "t[0-7]" "" "t[8-15]" >test_failhosts_query2.exp &&
test_cmp test_failhosts_query2.exp test_failhosts_query2.out
'
test_expect_success 'stop powerman daemon (failhosts)' '
kill -15 $(cat powermand.pid) &&
wait
'

test_done

# vi: set ft=sh

0 comments on commit 226d705

Please sign in to comment.