Page MenuHomeFreeBSD

D60473.1794685944.diff
No OneTemporary

Authored By
Unknown
Size
28 KB
Referenced Files
None
Subscribers
None

D60473.1794685944.diff

diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -567,6 +567,8 @@
..
cam
ctl
+ nvmft
+ ..
..
..
capsicum
diff --git a/tests/sys/cam/ctl/Makefile b/tests/sys/cam/ctl/Makefile
--- a/tests/sys/cam/ctl/Makefile
+++ b/tests/sys/cam/ctl/Makefile
@@ -3,6 +3,8 @@
TESTSDIR= ${TESTSBASE}/sys/cam/ctl
BINDIR=${TESTSDIR}
+TESTS_SUBDIRS+= nvmft
+
${PACKAGE}FILES+= all-supported-opcodes.txt
${PACKAGE}FILES+= ctl.subr
diff --git a/tests/sys/cam/ctl/nvmft/Makefile b/tests/sys/cam/ctl/nvmft/Makefile
new file mode 100644
--- /dev/null
+++ b/tests/sys/cam/ctl/nvmft/Makefile
@@ -0,0 +1,15 @@
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/cam/ctl/nvmft
+BINDIR=${TESTSDIR}
+
+${PACKAGE}FILES+= README ctl.conf
+${PACKAGE}FILESMODE_ctl.conf= 440
+
+ATF_TESTS_SH+= shutdown
+
+PROGS+= nvmf_shutdown
+LIBADD+= nvmf
+CFLAGS+= -I${SRCTOP}/lib/libnvmf
+
+.include <bsd.test.mk>
diff --git a/tests/sys/cam/ctl/nvmft/README b/tests/sys/cam/ctl/nvmft/README
new file mode 100644
--- /dev/null
+++ b/tests/sys/cam/ctl/nvmft/README
@@ -0,0 +1,17 @@
+The tests in this directory are specialized NVMeoF hosts which must be
+run against an NVMeoF controller. The address of the controller is
+specified via FreeBSD Test Suite configuration variables which can be
+passed to kyua(1) or set in configuration variable as described in
+tests(7).
+
+A sample ctl.conf file is included in this directory which can be used
+with ctld(8) to provide a suitable test controller. To use this file,
+start ctld(8) by running the following as root:
+
+# ctld -f /usr/tests/sys/cam/ctl/nvmft/ctl.conf
+
+Then set the following configuration variables:
+
+test_suites.FreeBSD.nvmft.address = "127.0.0.1"
+test_suites.FreeBSD.nvmft.port = "4420"
+test_suites.FreeBSD.nvmft.nqn = "nqn.1994-09.org.freebsd:test"
diff --git a/tests/sys/cam/ctl/nvmft/ctl.conf b/tests/sys/cam/ctl/nvmft/ctl.conf
new file mode 100644
--- /dev/null
+++ b/tests/sys/cam/ctl/nvmft/ctl.conf
@@ -0,0 +1,13 @@
+transport-group tg0 {
+ listen tcp 127.0.0.1:4420
+}
+
+controller nqn.1994-09.org.freebsd:test {
+ auth-group no-authentication
+ transport-group tg0
+ namespace 1 {
+ backend ramdisk
+ size 64M
+ option capacity 64M
+ }
+}
diff --git a/tests/sys/cam/ctl/nvmft/genshutdown.sh b/tests/sys/cam/ctl/nvmft/genshutdown.sh
new file mode 100644
--- /dev/null
+++ b/tests/sys/cam/ctl/nvmft/genshutdown.sh
@@ -0,0 +1,190 @@
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2026 Chelsio Communications, Inc.
+
+# Generate shutdown.sh
+
+# Shared routines used by individual tests
+header()
+{
+ cat <<EOF
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2026 Chelsio Communications, Inc.
+
+require()
+{
+ atf_set "require.config" "nvmft.nqn nvmft.address nvmft.port"
+}
+
+fetch_vars()
+{
+ CMD=\$(atf_get_srcdir)/nvmf_shutdown
+ NQN=\$(atf_config_get nvmft.nqn)
+ ADDRESS=\$(atf_config_get nvmft.address):\$(atf_config_get nvmft.port)
+}
+
+# \$1 - mode
+# \$2 - delay (optional)
+shutdown_test()
+{
+ local delay
+
+ if [ "\$#" -eq 2 ]; then
+ delay="-d \$2"
+ fi
+
+ fetch_vars
+
+ atf_check \$CMD \$delay \$1 "\$ADDRESS" "\$NQN"
+}
+
+# \$1 - mode
+# \$2 - reenable mode
+# \$3 - reenable delay (optional)
+reenable_test()
+{
+ local delay
+
+ if [ "\$#" -eq 3 ]; then
+ delay="-D \$3"
+ fi
+
+ fetch_vars
+
+ atf_check \$CMD \$delay -R \$2 \$1 "\$ADDRESS" "\$NQN"
+}
+
+# \$1 - mode
+# \$2 - reenable mode
+# \$3 - reenable delay
+reenable_xfail()
+{
+ fetch_vars
+
+ atf_check -s exit:1 -e match:"Connection reset" \\
+ \$CMD -D \$3 -R \$2 \$1 "\$ADDRESS" "\$NQN"
+}
+
+EOF
+}
+
+# Test a shutdown mode without re-enabling
+simple_test()
+{
+ cat <<EOF
+atf_test_case ${1}
+${1}_head()
+{
+ atf_set "descr" "${1} with no delay"
+ require
+}
+
+${1}_body()
+{
+ shutdown_test ${1}
+}
+
+atf_test_case ${1}_short_delay
+${1}_short_delay_head()
+{
+ atf_set "descr" "${1} with 1 second delay"
+ require
+}
+
+${1}_short_delay_body()
+{
+ shutdown_test ${1} 1
+}
+
+atf_test_case ${1}_long_delay
+${1}_long_delay_head()
+{
+ atf_set "descr" "${1} with 130 second delay"
+ require
+}
+
+${1}_long_delay_body()
+{
+ shutdown_test ${1} 130
+}
+
+EOF
+ TESTS="${TESTS} ${1} ${1}_short_delay ${1}_long_delay"
+}
+
+# Test a shutdown mode and then reenable
+reenable_test()
+{
+ cat <<EOF
+atf_test_case ${1}_${2}
+${1}_${2}_head()
+{
+ atf_set "descr" "${1} reenable then ${2} with no delay"
+ require
+}
+
+${1}_${2}_body()
+{
+ reenable_test ${1} ${2}
+}
+
+atf_test_case ${1}_${2}_short_delay
+${1}_${2}_short_delay_head()
+{
+ atf_set "descr" "${1} reenable then ${2} with 1 second delay"
+ require
+}
+
+${1}_${2}_short_delay_body()
+{
+ reenable_test ${1} ${2} 1
+}
+
+atf_test_case ${1}_${2}_long_delay
+${1}_${2}_long_delay_head()
+{
+ atf_set "descr" "${1} reenable then ${2} with 130 second delay"
+ require
+}
+
+${1}_${2}_long_delay_body()
+{
+ reenable_xfail ${1} ${2} 130
+}
+
+EOF
+ TESTS="${TESTS} ${1}_${2} ${1}_${2}_short_delay ${1}_${2}_long_delay"
+}
+
+# Generate the test harness glue
+trailer()
+{
+ cat <<EOF
+atf_init_test_cases()
+{
+EOF
+ for t in $TESTS; do
+ echo " atf_add_test_case ${t}"
+ done
+
+ echo "}"
+}
+
+MODES="normal abrupt close reset"
+TESTS=""
+
+header
+for mode in $MODES; do
+ simple_test $mode
+
+ # "close" doesn't support reenable
+ if [ "$mode" = "close" ]; then
+ continue
+ fi
+
+ for rmode in $MODES; do
+ reenable_test $mode $rmode
+ done
+done
+trailer
diff --git a/tests/sys/cam/ctl/nvmft/nvmf_shutdown.c b/tests/sys/cam/ctl/nvmft/nvmf_shutdown.c
new file mode 100644
--- /dev/null
+++ b/tests/sys/cam/ctl/nvmft/nvmf_shutdown.c
@@ -0,0 +1,434 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023,2026 Chelsio Communications, Inc.
+ * Written by: John Baldwin <jhb@FreeBSD.org>
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <err.h>
+#include <inttypes.h>
+#include <libnvmf.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static bool header_digests, data_digests;
+static uint64_t cap;
+static u_int mps;
+
+enum shutdown_mode { NONE, NORMAL, ABRUPT, CLOSE, RESET };
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+"nvmf_connect [-FGg] [-D reenable delay] [-R mode] [-c cntlid] [-d delay]\n"
+" [-t transport] <mode> <address:port> <nqn>\n"
+"\n"
+" Where mode is one of:\n"
+"\tclose - just close the socket\n"
+"\tnormal - normal shutdown\n"
+"\tabrupt - abrupt shutdown\n"
+"\treset - controller reset\n");
+ exit(1);
+}
+
+static enum shutdown_mode
+parse_mode(const char *s)
+{
+ if (strcasecmp(s, "normal") == 0)
+ return (NORMAL);
+ else if (strcasecmp(s, "abrupt") == 0)
+ return (ABRUPT);
+ else if (strcasecmp(s, "close") == 0)
+ return (CLOSE);
+ else if (strcasecmp(s, "reset") == 0)
+ return (RESET);
+ else
+ errx(1, "Invalid mode: %s", s);
+}
+
+static void
+tcp_association_params(struct nvmf_association_params *params)
+{
+ params->tcp.pda = 0;
+ params->tcp.header_digests = header_digests;
+ params->tcp.data_digests = data_digests;
+ params->tcp.maxr2t = 1;
+}
+
+static int
+open_socket(const char *address, const char *port)
+{
+ struct addrinfo hints, *ai, *list;
+ int error, s;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_protocol = IPPROTO_TCP;
+ error = getaddrinfo(address, port, &hints, &list);
+ if (error != 0)
+ errx(1, "%s", gai_strerror(error));
+
+ for (ai = list; ai != NULL; ai = ai->ai_next) {
+ s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (s == -1)
+ continue;
+
+ if (connect(s, ai->ai_addr, ai->ai_addrlen) != 0) {
+ close(s);
+ continue;
+ }
+
+ freeaddrinfo(list);
+ return (s);
+ }
+ err(1, "Failed to connect to controller");
+}
+
+/* Wait for shutdown to complete by polling CSTS. */
+static void
+wait_for_shutdown(struct nvmf_qpair *qp)
+{
+ uint64_t csts;
+ int error, timo;
+
+ timo = NVME_CAP_LO_TO(cap);
+ for (;;) {
+ error = nvmf_read_property(qp, NVMF_PROP_CSTS, 4, &csts);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CSTS");
+
+ switch (NVME_CSTS_GET_SHST(csts)) {
+ case NVME_SHST_COMPLETE:
+ return;
+ case NVME_SHST_OCCURRING:
+ break;
+ default:
+ errx(1, "Invalid shutdown status: %u",
+ (u_int)NVME_CSTS_GET_SHST(csts));
+ }
+
+ if (timo == 0)
+ errx(1, "Controller failed to complete shutdown");
+ timo--;
+ usleep(500 * 1000);
+ }
+}
+
+/* Wait for CSTS.RDY in Controller Status */
+static void
+wait_for_ready(struct nvmf_qpair *qp, bool ready)
+{
+ uint64_t csts, rdy;
+ int error, timo;
+
+ timo = NVME_CAP_LO_TO(cap);
+ for (;;) {
+ error = nvmf_read_property(qp, NVMF_PROP_CSTS, 4, &csts);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CSTS");
+
+ rdy = NVMEV(NVME_CSTS_REG_RDY, csts);
+ if (ready) {
+ if (rdy != 0) {
+ if (NVME_CSTS_GET_SHST(csts) !=
+ NVME_SHST_NORMAL)
+ errx(1,
+ "Invalid shutdown status for ready controller: %u",
+ (u_int)NVME_CSTS_GET_SHST(csts));
+ break;
+ }
+ } else {
+ if (rdy == 0)
+ break;
+ }
+
+ if (timo == 0)
+ errx(1, "Controller failed to %s", ready ?
+ "become ready" : "reset");
+ timo--;
+ usleep(500 * 1000);
+ }
+}
+
+static void
+validate_idle_csts(struct nvmf_qpair *qp)
+{
+ uint64_t csts;
+ int error;
+
+ error = nvmf_read_property(qp, NVMF_PROP_CSTS, 4, &csts);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CSTS");
+
+ if (NVMEV(NVME_CSTS_REG_RDY, csts) != 0)
+ errx(1, "Idle controller is ready");
+
+ if (NVMEV(NVME_CSTS_REG_CFS, csts) != 0)
+ errx(1, "Idle controller has fatal error");
+}
+
+static void
+enable_controller(struct nvmf_qpair *qp)
+{
+ uint64_t cc;
+ int error;
+
+ validate_idle_csts(qp);
+
+ error = nvmf_read_property(qp, NVMF_PROP_CC, 4, &cc);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CC");
+
+ /* Clear known fields preserving any reserved fields. */
+ cc &= ~(NVMEM(NVME_CC_REG_IOCQES) | NVMEM(NVME_CC_REG_IOSQES) |
+ NVMEM(NVME_CC_REG_SHN) | NVMEM(NVME_CC_REG_AMS) |
+ NVMEM(NVME_CC_REG_MPS) | NVMEM(NVME_CC_REG_CSS));
+
+ cc |= NVMEF(NVME_CC_REG_IOCQES, 4); /* CQE entry size == 16 */
+ cc |= NVMEF(NVME_CC_REG_IOSQES, 6); /* SQE entry size == 64 */
+ cc |= NVMEF(NVME_CC_REG_AMS, 0); /* AMS 0 (Round-robin) */
+ cc |= NVMEF(NVME_CC_REG_MPS, mps);
+ cc |= NVMEF(NVME_CC_REG_CSS, 0); /* NVM command set */
+ cc |= NVMEF(NVME_CC_REG_EN, 1); /* EN = 1 */
+
+ error = nvmf_write_property(qp, NVMF_PROP_CC, 4, cc);
+ if (error != 0)
+ errc(1, error, "Failed to set CC");
+
+ wait_for_ready(qp, true);
+}
+
+static struct nvmf_qpair *
+connect_admin_queue(struct nvmf_association *na,
+ const struct nvmf_qpair_params *params, const uint8_t hostid[16],
+ uint16_t cntlid, const char *hostnqn, const char *subnqn)
+{
+ struct nvmf_qpair *qp;
+ u_int mpsmin, mpsmax;
+ int error;
+
+ qp = nvmf_connect(na, params, 0, NVMF_MIN_ADMIN_MAX_SQ_SIZE, hostid,
+ cntlid, subnqn, hostnqn, 0);
+ if (qp == NULL)
+ return (NULL);
+
+ error = nvmf_read_property(qp, NVMF_PROP_CAP, 8, &cap);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CAP");
+
+ /* Require the NVM command set. */
+ if (NVME_CAP_HI_CSS_NVM(cap >> 32) == 0)
+ errx(1, "Controller does not support the NVM command set");
+
+ /* Prefer native host page size if it fits. */
+ mpsmin = NVMEV(NVME_CAP_HI_REG_MPSMIN, cap >> 32);
+ mpsmax = NVMEV(NVME_CAP_HI_REG_MPSMAX, cap >> 32);
+ mps = ffs(getpagesize()) - 1;
+ if (mps < mpsmin + NVME_MPS_SHIFT)
+ mps = mpsmin;
+ else if (mps > mpsmax + NVME_MPS_SHIFT)
+ mps = mpsmax;
+ else
+ mps -= 12;
+
+ /* Configure controller. */
+ enable_controller(qp);
+
+ return (qp);
+}
+
+static void
+shutdown_controller(struct nvmf_qpair *qp, bool abrupt)
+{
+ uint64_t cc;
+ int error;
+
+ error = nvmf_read_property(qp, NVMF_PROP_CC, 4, &cc);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CC");
+
+ if (abrupt)
+ cc |= NVMEF(NVME_CC_REG_SHN, NVME_SHN_ABRUPT);
+ else
+ cc |= NVMEF(NVME_CC_REG_SHN, NVME_SHN_NORMAL);
+
+ error = nvmf_write_property(qp, NVMF_PROP_CC, 4, cc);
+ if (error != 0)
+ errc(1, error, "Failed to set CC to trigger shutdown");
+}
+
+static void
+reset_controller(struct nvmf_qpair *qp)
+{
+ uint64_t cc;
+ int error;
+
+ error = nvmf_read_property(qp, NVMF_PROP_CC, 4, &cc);
+ if (error != 0)
+ errc(1, error, "Failed to fetch CC");
+
+ cc &= ~NVMEM(NVME_CC_REG_EN);
+
+ error = nvmf_write_property(qp, NVMF_PROP_CC, 4, cc);
+ if (error != 0)
+ errc(1, error, "Failed to set CC to reset controller");
+}
+
+int
+main(int ac, char **av)
+{
+ const char *transport;
+ char *address, *port;
+ struct nvmf_association_params aparams;
+ struct nvmf_qpair_params qparams;
+ struct nvmf_association *na;
+ struct nvmf_qpair *admin;
+ char hostnqn[NVMF_NQN_MAX_LEN];
+ uint8_t hostid[16];
+ enum nvmf_trtype trtype;
+ enum shutdown_mode mode, reenable_mode;
+ u_int cntlid, delay, reenable_delay;
+ int ch, error;
+ bool flow_control;
+
+ cntlid = NVMF_CNTLID_DYNAMIC;
+ delay = 0;
+ flow_control = false;
+ mode = NONE;
+ reenable_delay = 0;
+ reenable_mode = NONE;
+ transport = "tcp";
+ while ((ch = getopt(ac, av, "D:FGR:c:d:gt:")) != -1) {
+ switch (ch) {
+ case 'D':
+ reenable_delay = strtoumax(optarg, NULL, 0);
+ break;
+ case 'F':
+ flow_control = true;
+ break;
+ case 'G':
+ data_digests = true;
+ break;
+ case 'R':
+ reenable_mode = parse_mode(optarg);
+ break;
+ case 'c':
+ if (strcasecmp(optarg, "dynamic") == 0)
+ cntlid = NVMF_CNTLID_DYNAMIC;
+ else if (strcasecmp(optarg, "static") == 0)
+ cntlid = NVMF_CNTLID_STATIC_ANY;
+ else
+ cntlid = strtoul(optarg, NULL, 0);
+ break;
+ case 'd':
+ delay = strtoumax(optarg, NULL, 0);
+ break;
+ case 'g':
+ header_digests = true;
+ break;
+ case 't':
+ transport = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ av += optind;
+ ac -= optind;
+
+ if (ac != 3)
+ usage();
+
+ mode = parse_mode(av[0]);
+
+ if (mode == CLOSE && reenable_mode != NONE)
+ errx(1, "close mode doesn't support re-enabling");
+
+ address = av[1];
+ port = strrchr(address, ':');
+ if (port == NULL || port[1] == '\0')
+ errx(1, "Invalid address %s", address);
+ *port = '\0';
+ port++;
+
+ memset(&aparams, 0, sizeof(aparams));
+ aparams.sq_flow_control = flow_control;
+ if (strcasecmp(transport, "tcp") == 0) {
+ trtype = NVMF_TRTYPE_TCP;
+ tcp_association_params(&aparams);
+ } else
+ errx(1, "Invalid transport %s", transport);
+
+ error = nvmf_hostid_from_hostuuid(hostid);
+ if (error != 0)
+ errc(1, error, "Failed to generate hostid");
+ error = nvmf_nqn_from_hostuuid(hostnqn);
+ if (error != 0)
+ errc(1, error, "Failed to generate host NQN");
+
+ na = nvmf_allocate_association(trtype, false, &aparams);
+ if (na == NULL)
+ err(1, "Failed to create association");
+
+ memset(&qparams, 0, sizeof(qparams));
+ qparams.admin = true;
+ qparams.tcp.fd = open_socket(address, port);
+
+ admin = connect_admin_queue(na, &qparams, hostid, cntlid, hostnqn,
+ av[2]);
+ if (admin == NULL)
+ errx(1, "Failed to create admin queue: %s",
+ nvmf_association_error(na));
+ nvmf_free_association(na);
+
+ switch (mode) {
+ case CLOSE:
+ nvmf_close_qpair(admin);
+ break;
+ case NORMAL:
+ case ABRUPT:
+ shutdown_controller(admin, mode == ABRUPT);
+ if (reenable_mode != NONE)
+ wait_for_shutdown(admin);
+ break;
+ case RESET:
+ reset_controller(admin);
+ break;
+ case NONE:
+ __unreachable();
+ }
+
+ if (reenable_mode != NONE) {
+ wait_for_ready(admin, false);
+ if (reenable_delay != 0)
+ sleep(reenable_delay);
+ enable_controller(admin);
+ switch (reenable_mode) {
+ case CLOSE:
+ break;
+ case NORMAL:
+ case ABRUPT:
+ shutdown_controller(admin, mode == ABRUPT);
+ break;
+ case RESET:
+ reset_controller(admin);
+ break;
+ case NONE:
+ __unreachable();
+ }
+ }
+
+ if (delay != 0)
+ sleep(delay);
+
+ nvmf_free_qpair(admin);
+ return (0);
+}
diff --git a/tests/sys/cam/ctl/nvmft/shutdown.sh b/tests/sys/cam/ctl/nvmft/shutdown.sh
new file mode 100644
--- /dev/null
+++ b/tests/sys/cam/ctl/nvmft/shutdown.sh
@@ -0,0 +1,685 @@
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2026 Chelsio Communications, Inc.
+
+require()
+{
+ atf_set "require.config" "nvmft.nqn nvmft.address nvmft.port"
+}
+
+fetch_vars()
+{
+ CMD=$(atf_get_srcdir)/nvmf_shutdown
+ NQN=$(atf_config_get nvmft.nqn)
+ ADDRESS=$(atf_config_get nvmft.address):$(atf_config_get nvmft.port)
+}
+
+# $1 - mode
+# $2 - delay (optional)
+shutdown_test()
+{
+ local delay
+
+ if [ "$#" -eq 2 ]; then
+ delay="-d $2"
+ fi
+
+ fetch_vars
+
+ atf_check $CMD $delay $1 "$ADDRESS" "$NQN"
+}
+
+# $1 - mode
+# $2 - reenable mode
+# $3 - reenable delay (optional)
+reenable_test()
+{
+ local delay
+
+ if [ "$#" -eq 3 ]; then
+ delay="-D $3"
+ fi
+
+ fetch_vars
+
+ atf_check $CMD $delay -R $2 $1 "$ADDRESS" "$NQN"
+}
+
+# $1 - mode
+# $2 - reenable mode
+# $3 - reenable delay
+reenable_xfail()
+{
+ fetch_vars
+
+ atf_check -s exit:1 -e match:"Connection reset" \
+ $CMD -D $3 -R $2 $1 "$ADDRESS" "$NQN"
+}
+
+atf_test_case normal
+normal_head()
+{
+ atf_set "descr" "normal with no delay"
+ require
+}
+
+normal_body()
+{
+ shutdown_test normal
+}
+
+atf_test_case normal_short_delay
+normal_short_delay_head()
+{
+ atf_set "descr" "normal with 1 second delay"
+ require
+}
+
+normal_short_delay_body()
+{
+ shutdown_test normal 1
+}
+
+atf_test_case normal_long_delay
+normal_long_delay_head()
+{
+ atf_set "descr" "normal with 130 second delay"
+ require
+}
+
+normal_long_delay_body()
+{
+ shutdown_test normal 130
+}
+
+atf_test_case normal_normal
+normal_normal_head()
+{
+ atf_set "descr" "normal reenable then normal with no delay"
+ require
+}
+
+normal_normal_body()
+{
+ reenable_test normal normal
+}
+
+atf_test_case normal_normal_short_delay
+normal_normal_short_delay_head()
+{
+ atf_set "descr" "normal reenable then normal with 1 second delay"
+ require
+}
+
+normal_normal_short_delay_body()
+{
+ reenable_test normal normal 1
+}
+
+atf_test_case normal_normal_long_delay
+normal_normal_long_delay_head()
+{
+ atf_set "descr" "normal reenable then normal with 130 second delay"
+ require
+}
+
+normal_normal_long_delay_body()
+{
+ reenable_xfail normal normal 130
+}
+
+atf_test_case normal_abrupt
+normal_abrupt_head()
+{
+ atf_set "descr" "normal reenable then abrupt with no delay"
+ require
+}
+
+normal_abrupt_body()
+{
+ reenable_test normal abrupt
+}
+
+atf_test_case normal_abrupt_short_delay
+normal_abrupt_short_delay_head()
+{
+ atf_set "descr" "normal reenable then abrupt with 1 second delay"
+ require
+}
+
+normal_abrupt_short_delay_body()
+{
+ reenable_test normal abrupt 1
+}
+
+atf_test_case normal_abrupt_long_delay
+normal_abrupt_long_delay_head()
+{
+ atf_set "descr" "normal reenable then abrupt with 130 second delay"
+ require
+}
+
+normal_abrupt_long_delay_body()
+{
+ reenable_xfail normal abrupt 130
+}
+
+atf_test_case normal_close
+normal_close_head()
+{
+ atf_set "descr" "normal reenable then close with no delay"
+ require
+}
+
+normal_close_body()
+{
+ reenable_test normal close
+}
+
+atf_test_case normal_close_short_delay
+normal_close_short_delay_head()
+{
+ atf_set "descr" "normal reenable then close with 1 second delay"
+ require
+}
+
+normal_close_short_delay_body()
+{
+ reenable_test normal close 1
+}
+
+atf_test_case normal_close_long_delay
+normal_close_long_delay_head()
+{
+ atf_set "descr" "normal reenable then close with 130 second delay"
+ require
+}
+
+normal_close_long_delay_body()
+{
+ reenable_xfail normal close 130
+}
+
+atf_test_case normal_reset
+normal_reset_head()
+{
+ atf_set "descr" "normal reenable then reset with no delay"
+ require
+}
+
+normal_reset_body()
+{
+ reenable_test normal reset
+}
+
+atf_test_case normal_reset_short_delay
+normal_reset_short_delay_head()
+{
+ atf_set "descr" "normal reenable then reset with 1 second delay"
+ require
+}
+
+normal_reset_short_delay_body()
+{
+ reenable_test normal reset 1
+}
+
+atf_test_case normal_reset_long_delay
+normal_reset_long_delay_head()
+{
+ atf_set "descr" "normal reenable then reset with 130 second delay"
+ require
+}
+
+normal_reset_long_delay_body()
+{
+ reenable_xfail normal reset 130
+}
+
+atf_test_case abrupt
+abrupt_head()
+{
+ atf_set "descr" "abrupt with no delay"
+ require
+}
+
+abrupt_body()
+{
+ shutdown_test abrupt
+}
+
+atf_test_case abrupt_short_delay
+abrupt_short_delay_head()
+{
+ atf_set "descr" "abrupt with 1 second delay"
+ require
+}
+
+abrupt_short_delay_body()
+{
+ shutdown_test abrupt 1
+}
+
+atf_test_case abrupt_long_delay
+abrupt_long_delay_head()
+{
+ atf_set "descr" "abrupt with 130 second delay"
+ require
+}
+
+abrupt_long_delay_body()
+{
+ shutdown_test abrupt 130
+}
+
+atf_test_case abrupt_normal
+abrupt_normal_head()
+{
+ atf_set "descr" "abrupt reenable then normal with no delay"
+ require
+}
+
+abrupt_normal_body()
+{
+ reenable_test abrupt normal
+}
+
+atf_test_case abrupt_normal_short_delay
+abrupt_normal_short_delay_head()
+{
+ atf_set "descr" "abrupt reenable then normal with 1 second delay"
+ require
+}
+
+abrupt_normal_short_delay_body()
+{
+ reenable_test abrupt normal 1
+}
+
+atf_test_case abrupt_normal_long_delay
+abrupt_normal_long_delay_head()
+{
+ atf_set "descr" "abrupt reenable then normal with 130 second delay"
+ require
+}
+
+abrupt_normal_long_delay_body()
+{
+ reenable_xfail abrupt normal 130
+}
+
+atf_test_case abrupt_abrupt
+abrupt_abrupt_head()
+{
+ atf_set "descr" "abrupt reenable then abrupt with no delay"
+ require
+}
+
+abrupt_abrupt_body()
+{
+ reenable_test abrupt abrupt
+}
+
+atf_test_case abrupt_abrupt_short_delay
+abrupt_abrupt_short_delay_head()
+{
+ atf_set "descr" "abrupt reenable then abrupt with 1 second delay"
+ require
+}
+
+abrupt_abrupt_short_delay_body()
+{
+ reenable_test abrupt abrupt 1
+}
+
+atf_test_case abrupt_abrupt_long_delay
+abrupt_abrupt_long_delay_head()
+{
+ atf_set "descr" "abrupt reenable then abrupt with 130 second delay"
+ require
+}
+
+abrupt_abrupt_long_delay_body()
+{
+ reenable_xfail abrupt abrupt 130
+}
+
+atf_test_case abrupt_close
+abrupt_close_head()
+{
+ atf_set "descr" "abrupt reenable then close with no delay"
+ require
+}
+
+abrupt_close_body()
+{
+ reenable_test abrupt close
+}
+
+atf_test_case abrupt_close_short_delay
+abrupt_close_short_delay_head()
+{
+ atf_set "descr" "abrupt reenable then close with 1 second delay"
+ require
+}
+
+abrupt_close_short_delay_body()
+{
+ reenable_test abrupt close 1
+}
+
+atf_test_case abrupt_close_long_delay
+abrupt_close_long_delay_head()
+{
+ atf_set "descr" "abrupt reenable then close with 130 second delay"
+ require
+}
+
+abrupt_close_long_delay_body()
+{
+ reenable_xfail abrupt close 130
+}
+
+atf_test_case abrupt_reset
+abrupt_reset_head()
+{
+ atf_set "descr" "abrupt reenable then reset with no delay"
+ require
+}
+
+abrupt_reset_body()
+{
+ reenable_test abrupt reset
+}
+
+atf_test_case abrupt_reset_short_delay
+abrupt_reset_short_delay_head()
+{
+ atf_set "descr" "abrupt reenable then reset with 1 second delay"
+ require
+}
+
+abrupt_reset_short_delay_body()
+{
+ reenable_test abrupt reset 1
+}
+
+atf_test_case abrupt_reset_long_delay
+abrupt_reset_long_delay_head()
+{
+ atf_set "descr" "abrupt reenable then reset with 130 second delay"
+ require
+}
+
+abrupt_reset_long_delay_body()
+{
+ reenable_xfail abrupt reset 130
+}
+
+atf_test_case close
+close_head()
+{
+ atf_set "descr" "close with no delay"
+ require
+}
+
+close_body()
+{
+ shutdown_test close
+}
+
+atf_test_case close_short_delay
+close_short_delay_head()
+{
+ atf_set "descr" "close with 1 second delay"
+ require
+}
+
+close_short_delay_body()
+{
+ shutdown_test close 1
+}
+
+atf_test_case close_long_delay
+close_long_delay_head()
+{
+ atf_set "descr" "close with 130 second delay"
+ require
+}
+
+close_long_delay_body()
+{
+ shutdown_test close 130
+}
+
+atf_test_case reset
+reset_head()
+{
+ atf_set "descr" "reset with no delay"
+ require
+}
+
+reset_body()
+{
+ shutdown_test reset
+}
+
+atf_test_case reset_short_delay
+reset_short_delay_head()
+{
+ atf_set "descr" "reset with 1 second delay"
+ require
+}
+
+reset_short_delay_body()
+{
+ shutdown_test reset 1
+}
+
+atf_test_case reset_long_delay
+reset_long_delay_head()
+{
+ atf_set "descr" "reset with 130 second delay"
+ require
+}
+
+reset_long_delay_body()
+{
+ shutdown_test reset 130
+}
+
+atf_test_case reset_normal
+reset_normal_head()
+{
+ atf_set "descr" "reset reenable then normal with no delay"
+ require
+}
+
+reset_normal_body()
+{
+ reenable_test reset normal
+}
+
+atf_test_case reset_normal_short_delay
+reset_normal_short_delay_head()
+{
+ atf_set "descr" "reset reenable then normal with 1 second delay"
+ require
+}
+
+reset_normal_short_delay_body()
+{
+ reenable_test reset normal 1
+}
+
+atf_test_case reset_normal_long_delay
+reset_normal_long_delay_head()
+{
+ atf_set "descr" "reset reenable then normal with 130 second delay"
+ require
+}
+
+reset_normal_long_delay_body()
+{
+ reenable_xfail reset normal 130
+}
+
+atf_test_case reset_abrupt
+reset_abrupt_head()
+{
+ atf_set "descr" "reset reenable then abrupt with no delay"
+ require
+}
+
+reset_abrupt_body()
+{
+ reenable_test reset abrupt
+}
+
+atf_test_case reset_abrupt_short_delay
+reset_abrupt_short_delay_head()
+{
+ atf_set "descr" "reset reenable then abrupt with 1 second delay"
+ require
+}
+
+reset_abrupt_short_delay_body()
+{
+ reenable_test reset abrupt 1
+}
+
+atf_test_case reset_abrupt_long_delay
+reset_abrupt_long_delay_head()
+{
+ atf_set "descr" "reset reenable then abrupt with 130 second delay"
+ require
+}
+
+reset_abrupt_long_delay_body()
+{
+ reenable_xfail reset abrupt 130
+}
+
+atf_test_case reset_close
+reset_close_head()
+{
+ atf_set "descr" "reset reenable then close with no delay"
+ require
+}
+
+reset_close_body()
+{
+ reenable_test reset close
+}
+
+atf_test_case reset_close_short_delay
+reset_close_short_delay_head()
+{
+ atf_set "descr" "reset reenable then close with 1 second delay"
+ require
+}
+
+reset_close_short_delay_body()
+{
+ reenable_test reset close 1
+}
+
+atf_test_case reset_close_long_delay
+reset_close_long_delay_head()
+{
+ atf_set "descr" "reset reenable then close with 130 second delay"
+ require
+}
+
+reset_close_long_delay_body()
+{
+ reenable_xfail reset close 130
+}
+
+atf_test_case reset_reset
+reset_reset_head()
+{
+ atf_set "descr" "reset reenable then reset with no delay"
+ require
+}
+
+reset_reset_body()
+{
+ reenable_test reset reset
+}
+
+atf_test_case reset_reset_short_delay
+reset_reset_short_delay_head()
+{
+ atf_set "descr" "reset reenable then reset with 1 second delay"
+ require
+}
+
+reset_reset_short_delay_body()
+{
+ reenable_test reset reset 1
+}
+
+atf_test_case reset_reset_long_delay
+reset_reset_long_delay_head()
+{
+ atf_set "descr" "reset reenable then reset with 130 second delay"
+ require
+}
+
+reset_reset_long_delay_body()
+{
+ reenable_xfail reset reset 130
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case normal
+ atf_add_test_case normal_short_delay
+ atf_add_test_case normal_long_delay
+ atf_add_test_case normal_normal
+ atf_add_test_case normal_normal_short_delay
+ atf_add_test_case normal_normal_long_delay
+ atf_add_test_case normal_abrupt
+ atf_add_test_case normal_abrupt_short_delay
+ atf_add_test_case normal_abrupt_long_delay
+ atf_add_test_case normal_close
+ atf_add_test_case normal_close_short_delay
+ atf_add_test_case normal_close_long_delay
+ atf_add_test_case normal_reset
+ atf_add_test_case normal_reset_short_delay
+ atf_add_test_case normal_reset_long_delay
+ atf_add_test_case abrupt
+ atf_add_test_case abrupt_short_delay
+ atf_add_test_case abrupt_long_delay
+ atf_add_test_case abrupt_normal
+ atf_add_test_case abrupt_normal_short_delay
+ atf_add_test_case abrupt_normal_long_delay
+ atf_add_test_case abrupt_abrupt
+ atf_add_test_case abrupt_abrupt_short_delay
+ atf_add_test_case abrupt_abrupt_long_delay
+ atf_add_test_case abrupt_close
+ atf_add_test_case abrupt_close_short_delay
+ atf_add_test_case abrupt_close_long_delay
+ atf_add_test_case abrupt_reset
+ atf_add_test_case abrupt_reset_short_delay
+ atf_add_test_case abrupt_reset_long_delay
+ atf_add_test_case close
+ atf_add_test_case close_short_delay
+ atf_add_test_case close_long_delay
+ atf_add_test_case reset
+ atf_add_test_case reset_short_delay
+ atf_add_test_case reset_long_delay
+ atf_add_test_case reset_normal
+ atf_add_test_case reset_normal_short_delay
+ atf_add_test_case reset_normal_long_delay
+ atf_add_test_case reset_abrupt
+ atf_add_test_case reset_abrupt_short_delay
+ atf_add_test_case reset_abrupt_long_delay
+ atf_add_test_case reset_close
+ atf_add_test_case reset_close_short_delay
+ atf_add_test_case reset_close_long_delay
+ atf_add_test_case reset_reset
+ atf_add_test_case reset_reset_short_delay
+ atf_add_test_case reset_reset_long_delay
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 14, 7:52 PM (3 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41716247
Default Alt Text
D60473.1794685944.diff (28 KB)

Event Timeline