Files
freebsd/sbin/nvmecontrol/tests/basic.sh
T
Warner Losh a259b98fa2 tests: skip gracefully when the tested binary's own package isn't installed
pkgbase splits programs and their tests into separate packages (e.g.
unifdef/yacc/indent/file2c -> toolchain, jail -> jail, etc), while their
tests always land in the generic tests package.  Installing just the
tests package therefore leaves these suites unable to find the binary
they exercise, and they fail confusingly instead of skipping.

Rather than force all packages to be installed for the tests package,
make the tests cope with the missing packages.  Add require.progs (or,
for TAP/PLAIN-style suites with no atf_set hook: TEST_METADATA
required_programs) for the binary under test in: bectl, certctl,
ctfconvert, dhclient, file2c, indent, ipfw, jail, lastcomm, mixer,
newsyslog, nvmecontrol, pfctl, praudit, sa, syslogd, tunefs, unifdef,
yacc, ztest.

I skipped adding data for all the binaries in the base runtime
package for simplicity.

Assisted-by:		Claude Code (Sonnet 5)
Sponsored by:		Netflix
Reviewed by:		ngie
Differential Revision:	https://reviews.freebsd.org/D58262
2026-09-10 23:42:25 -06:00

246 lines
7.4 KiB
Bash
Executable File

# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 David A. Bright
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# A basic test for nvmecontrol. This isn't a thorough or complete test
# of nvmecontrol functionality; it is more of a sanity check that
# nvmecontrol basically works.
#
DANGEROUS=false # Set to true to run "dangerous" tests
# Select a nvme device to use for testing. If none exist, use nvme0.
TEST_DEV=$(cd /dev/; ls -1 nvme[0-9]* 2> /dev/null | grep -E 'nvme[0-9][0-9]*$' | head -n 1)
TEST_DEV=${TEST_DEV:-nvme0}
TEST_DEV_PATH=/dev/${TEST_DEV}
INV_OPT="-z"
INV_OPT_MSG="invalid option -- z"
atf_test_case fake_lib cleanup
fake_lib_head()
{
atf_set "descr" "check loading of a library from /lib"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
fake_lib_body()
{
local libdir="/lib/nvmecontrol"
local fakelib="${libdir}/fake.so"
if [ -d ${libdir} ] ; then
touch ${fakelib}
atf_check -s not-exit:0 -o ignore -e match:"Can't load ${fakelib}" nvmecontrol
rm -f ${fakelib}
else
atf_skip "Skipping; directory ${libdir} does not exist"
fi
}
fake_lib_cleanup()
{
rm -f /lib/nvmecontrol/fake.so
}
atf_test_case fake_local_lib cleanup
fake_local_lib_head()
{
atf_set "descr" "check loading of a library from /usr/local/lib"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
fake_local_lib_body()
{
local libdir="/usr/local/lib/nvmecontrol"
local fakelib="${libdir}/fake.so"
if [ -d ${libdir} ] ; then
touch ${fakelib}
atf_check -s not-exit:0 -o ignore -e match:"Can't load ${fakelib}" nvmecontrol
rm -f ${fakelib}
else
atf_skip "Skipping; directory ${libdir} does not exist"
fi
}
fake_local_lib_cleanup()
{
rm -f /usr/local/lib/nvmecontrol/fake.so
}
atf_test_case admin_passthru
admin_passthru_head()
{
atf_set "descr" "check the admin-passthru command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
admin_passthru_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol admin-passthru --opcode=06 --data-len=4096 --cdw10=1 -r ${TEST_DEV}
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol admin-passthru --opcode=06 --data-len=4096 --cdw10=1 -r ${TEST_DEV}
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol admin-passthru ${INV_OPT} --opcode=06 --data-len=4096 --cdw10=1 -r ${TEST_DEV}
}
atf_test_case devlist
devlist_head()
{
atf_set "descr" "check the devlist command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
devlist_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol devlist
else
atf_check -s not-exit:0 -o ignore -e ignore nvmecontrol devlist
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol devlist ${INV_OPT}
}
atf_test_case identify
identify_head()
{
atf_set "descr" "check the identify command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
identify_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol identify ${TEST_DEV}
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol identify ${TEST_DEV}
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol identify ${INV_OPT} ${TEST_DEV}
}
atf_test_case io_passthru
io_passthru_head()
{
atf_set "descr" "check the io-passthru command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
io_passthru_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol io-passthru --opcode=02 --data-len=4096 --cdw10=0 --cdw11=0 --cdw12=0x70000 -r nvme0 ${TEST_DEV}
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol io-passthru --opcode=02 --data-len=4096 --cdw10=0 --cdw11=0 --cdw12=0x70000 -r nvme0 ${TEST_DEV}
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol io-passthru ${INV_OPT} --opcode=02 --data-len=4096 --cdw10=0 --cdw11=0 --cdw12=0x70000 -r nvme0 ${TEST_DEV}
}
atf_test_case logpage
logpage_head()
{
atf_set "descr" "check the logpage command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
logpage_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol logpage -p 1 ${TEST_DEV}
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol logpage -p 1 ${TEST_DEV}
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol logpage -p 1 ${INV_OPT} ${TEST_DEV}
}
atf_test_case nsid
nsid_head()
{
atf_set "descr" "check the nsid command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
nsid_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol nsid ${TEST_DEV}
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol nsid ${TEST_DEV}
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol nsid ${INV_OPT} ${TEST_DEV}
}
atf_test_case power
power_head()
{
atf_set "descr" "check the power command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
power_body()
{
if [ -c "${TEST_DEV_PATH}" ] ; then
atf_check -o not-empty -e empty nvmecontrol power ${TEST_DEV}
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol power ${TEST_DEV}
fi
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol power ${INV_OPT} ${TEST_DEV}
}
atf_test_case reset
reset_head()
{
atf_set "descr" "check the reset command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
reset_body()
{
atf_check -s not-exit:0 -o ignore -e match:"${INV_OPT_MSG}" nvmecontrol reset ${INV_OPT} ${TEST_DEV}
if [ -c "${TEST_DEV_PATH}" ] ; then
# Reset of an active device seems a little dangerous,
# therefore, this is normally disabled.
if ${DANGEROUS} ; then
atf_check -o not-empty -e empty nvmecontrol reset ${TEST_DEV}
else
atf_skip "Skipping reset test"
fi
else
atf_check -s not-exit:0 -o empty -e not-empty nvmecontrol reset ${TEST_DEV}
fi
}
atf_init_test_cases()
{
atf_add_test_case fake_lib
atf_add_test_case fake_local_lib
atf_add_test_case admin_passthru
atf_add_test_case devlist
atf_add_test_case identify
atf_add_test_case io_passthru
atf_add_test_case logpage
atf_add_test_case nsid
atf_add_test_case power
atf_add_test_case reset
}