Add preliminary tests (basically a placeholder for now) for the new modules
framework. At the moment, this just tests for plain load (i.e. no arguments passed to load) and later unload of the module through the modctl(2) system call. The tools are not tested yet.
This commit is contained in:
parent
1abe396003
commit
42d50c9507
6
tests/modules/Atffile
Normal file
6
tests/modules/Atffile
Normal file
@ -0,0 +1,6 @@
|
||||
Content-Type: application/X-atf-atffile; version="1"
|
||||
X-NetBSD-Id: "$NetBSD: Atffile,v 1.1 2008/02/10 12:40:10 jmmv Exp $"
|
||||
|
||||
prop: test-suite = "NetBSD"
|
||||
|
||||
tp-glob: t_*
|
21
tests/modules/Makefile
Normal file
21
tests/modules/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# $NetBSD: Makefile,v 1.1 2008/02/10 12:40:10 jmmv Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/modules
|
||||
|
||||
# Ideally this test could be in the parent Makefile, which could not descend
|
||||
# into this directory at all. Unfortunately, the etc/mtree/NetBSD.dist file
|
||||
# creates the 'modules' subdirectory unconditionally, which if left empty
|
||||
# will confuse atf-run. Therefore we must install, at the very least, the
|
||||
# Atffile into it.
|
||||
.if ${MKMODULAR} != no
|
||||
|
||||
TESTS_CXX= t_modctl
|
||||
|
||||
SUBDIR= k_helper
|
||||
|
||||
.endif
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
.include <bsd.test.mk>
|
15
tests/modules/k_helper/Makefile
Normal file
15
tests/modules/k_helper/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# $NetBSD: Makefile,v 1.1 2008/02/10 12:40:10 jmmv Exp $
|
||||
|
||||
KMOD= k_helper
|
||||
KMODDIR= ${TESTSBASE}/modules
|
||||
|
||||
SRCS= real-k_helper.c
|
||||
# XXX A hack to workaround the fact that the final module is named
|
||||
# k_helper.o. To be removed once we change the extension of modules.
|
||||
BUILDSYMLINKS= ${.CURDIR}/k_helper.c real-k_helper.c
|
||||
|
||||
NOATFFILE= # defined
|
||||
NOMAN= # defined
|
||||
|
||||
.include <bsd.test.mk>
|
||||
.include <bsd.kmod.mk>
|
118
tests/modules/k_helper/k_helper.c
Normal file
118
tests/modules/k_helper/k_helper.c
Normal file
@ -0,0 +1,118 @@
|
||||
/* $NetBSD: k_helper.c,v 1.1 2008/02/10 12:40:10 jmmv Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: k_helper.c,v 1.1 2008/02/10 12:40:10 jmmv Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
MODULE(MODULE_CLASS_MISC, k_helper, NULL);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Sysctl interface to query information about the module. */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct sysctllog *clog;
|
||||
static int present = 1;
|
||||
|
||||
#define K_HELPER 0x12345678
|
||||
#define K_HELPER_PRESENT 0
|
||||
|
||||
SYSCTL_SETUP(sysctl_k_helper_setup, "sysctl k_helper subtree setup")
|
||||
{
|
||||
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT,
|
||||
CTLTYPE_NODE, "k_helper", NULL,
|
||||
NULL, 0, NULL, 0,
|
||||
CTL_VENDOR, K_HELPER, CTL_EOL);
|
||||
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT,
|
||||
CTLTYPE_INT, "present",
|
||||
SYSCTL_DESCR("Whether the module was loaded or not"),
|
||||
NULL, 0, &present, 0,
|
||||
CTL_VENDOR, K_HELPER, K_HELPER_PRESENT, CTL_EOL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Module management. */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static
|
||||
int
|
||||
k_helper_init(void *arg)
|
||||
{
|
||||
|
||||
sysctl_k_helper_setup(&clog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
k_helper_fini(void *arg)
|
||||
{
|
||||
|
||||
sysctl_teardown(&clog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
k_helper_modcmd(modcmd_t cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MODULE_CMD_INIT:
|
||||
ret = k_helper_init(arg);
|
||||
break;
|
||||
|
||||
case MODULE_CMD_FINI:
|
||||
ret = k_helper_fini(arg);
|
||||
break;
|
||||
|
||||
case MODULE_CMD_STAT:
|
||||
default:
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
196
tests/modules/t_modctl.cpp
Normal file
196
tests/modules/t_modctl.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
// $NetBSD: t_modctl.cpp,v 1.1 2008/02/10 12:40:10 jmmv Exp $
|
||||
//
|
||||
// Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
// 3. All advertising materials mentioning features or use of this
|
||||
// software must display the following acknowledgement:
|
||||
// This product includes software developed by the NetBSD
|
||||
// Foundation, Inc. and its contributors.
|
||||
// 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
//
|
||||
|
||||
extern "C" {
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: t_modctl.cpp,v 1.1 2008/02/10 12:40:10 jmmv Exp $");
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/sysctl.h>
|
||||
}
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include <atf.hpp>
|
||||
|
||||
static bool have_modular = false;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Auxiliary functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Checks if the kernel has 'options MODULAR' built into it and returns
|
||||
* a boolean indicating this condition. This function must be called
|
||||
* during the test program's initialization and the result be stored
|
||||
* globally for further (efficient) usage of require_modular().
|
||||
*/
|
||||
static
|
||||
bool
|
||||
check_modular(void)
|
||||
{
|
||||
bool res;
|
||||
struct iovec iov;
|
||||
|
||||
iov.iov_base = NULL;
|
||||
iov.iov_len = 0;
|
||||
|
||||
if (::modctl(MODCTL_STAT, &iov) == 0)
|
||||
res = true;
|
||||
else
|
||||
res = (errno != ENOSYS);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Makes sure that the kernel has 'options MODULAR' built into it and
|
||||
* skips the test otherwise. Cannot be called unless check_modular()
|
||||
* has been executed before.
|
||||
*/
|
||||
static
|
||||
void
|
||||
require_modular(void)
|
||||
{
|
||||
|
||||
if (!have_modular)
|
||||
ATF_SKIP("Kernel does not have 'options MODULAR'.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a boolean indicating if the k_helper module was loaded
|
||||
* successfully.
|
||||
*/
|
||||
static
|
||||
bool
|
||||
k_helper_is_present(void)
|
||||
{
|
||||
size_t present, presentsize;
|
||||
int ret;
|
||||
|
||||
presentsize = sizeof(present);
|
||||
ret = ::sysctlbyname("vendor.k_helper.present", &present,
|
||||
&presentsize, NULL, 0);
|
||||
if (ret == -1 && errno != ENOENT) {
|
||||
int err = errno;
|
||||
std::cerr << "sysctlbyname(2) failed: " << std::strerror(err)
|
||||
<< std::endl;
|
||||
ATF_FAIL("Failed to query module status");
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the specified module from a file.
|
||||
*/
|
||||
static
|
||||
void
|
||||
load(const std::string& filename)
|
||||
{
|
||||
|
||||
std::cout << "Loading module " << filename << std::endl;
|
||||
if (::modctl(MODCTL_LOAD, __UNCONST(filename.c_str())) == -1) {
|
||||
int err = errno;
|
||||
std::cerr << "modctl(MODCTL_LOAD, " << filename
|
||||
<< ") failed: " << std::strerror(err)
|
||||
<< std::endl;
|
||||
ATF_FAIL("Module load failed");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unloads the specified module. If silent is true, nothing will be
|
||||
* printed and no errors will be raised if the unload was unsuccessful.
|
||||
*/
|
||||
static
|
||||
void
|
||||
unload(const char *name, bool silent = false)
|
||||
{
|
||||
|
||||
if (!silent) {
|
||||
std::cout << "Unloading module " << name << std::endl;
|
||||
if (::modctl(MODCTL_UNLOAD, __UNCONST(name)) == -1) {
|
||||
int err = errno;
|
||||
std::cerr << "modctl(MODCTL_UNLOAD, " << name
|
||||
<< ") failed: " << std::strerror(err)
|
||||
<< std::endl;
|
||||
ATF_FAIL("Module unload failed");
|
||||
}
|
||||
} else {
|
||||
(void)::modctl(MODCTL_UNLOAD, __UNCONST(name));
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Test cases */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ATF_TEST_CASE_WITH_CLEANUP(plain);
|
||||
ATF_TEST_CASE_HEAD(plain)
|
||||
{
|
||||
set("descr", "Checks that plain loading and unloading works");
|
||||
set("require.user", "root");
|
||||
}
|
||||
ATF_TEST_CASE_BODY(plain)
|
||||
{
|
||||
require_modular();
|
||||
|
||||
load(get_srcdir() + "/k_helper.o");
|
||||
|
||||
std::cout << "Checking if load was successful" << std::endl;
|
||||
ATF_CHECK(k_helper_is_present());
|
||||
|
||||
unload("k_helper");
|
||||
|
||||
std::cout << "Checking if unload was successful" << std::endl;
|
||||
ATF_CHECK(!k_helper_is_present());
|
||||
}
|
||||
ATF_TEST_CASE_CLEANUP(plain)
|
||||
{
|
||||
unload("k_helper", true);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Main */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ATF_INIT_TEST_CASES(tcs)
|
||||
{
|
||||
have_modular = check_modular();
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, plain);
|
||||
}
|
Loading…
Reference in New Issue
Block a user