Commit 2e7da5f8 authored by Philippe Gerum's avatar Philippe Gerum

lib/smokey: introduce infrastructure for building smoke tests

A new copperplate-based API called "smokey" is introduced, which
automates cumbersome boilerplate tasks when writing smoke tests.
Smokey provides a simple plugin-oriented infrastructure, with the
ability to host and run a set of tests embodied into a single
executable.

A companion program is provided in testsuite/smokey, for running the
individual tests formerly available under testsuite/unit, illustrating
the usage of the smokey API.  testsuite/regression will be converted
next.
parent b48cf507
......@@ -14230,7 +14230,7 @@ XENO_CONFIG_ARGS="$ac_configure_args"
ac_config_files="$ac_config_files Makefile config/Makefile scripts/Makefile scripts/xeno-config:scripts/xeno-config-$rtcore_type.in scripts/xeno lib/Makefile lib/boilerplate/Makefile lib/cobalt/Makefile lib/cobalt/arch/Makefile lib/cobalt/arch/arm/Makefile lib/cobalt/arch/arm/include/Makefile lib/cobalt/arch/arm/include/asm/Makefile lib/cobalt/arch/arm/include/asm/xenomai/Makefile lib/cobalt/arch/powerpc/Makefile lib/cobalt/arch/powerpc/include/Makefile lib/cobalt/arch/powerpc/include/asm/Makefile lib/cobalt/arch/powerpc/include/asm/xenomai/Makefile lib/cobalt/arch/blackfin/Makefile lib/cobalt/arch/blackfin/include/Makefile lib/cobalt/arch/blackfin/include/asm/Makefile lib/cobalt/arch/blackfin/include/asm/xenomai/Makefile lib/cobalt/arch/x86/Makefile lib/cobalt/arch/x86/include/Makefile lib/cobalt/arch/x86/include/asm/Makefile lib/cobalt/arch/x86/include/asm/xenomai/Makefile lib/cobalt/arch/nios2/Makefile lib/cobalt/arch/nios2/include/Makefile lib/cobalt/arch/nios2/include/asm/Makefile lib/cobalt/arch/nios2/include/asm/xenomai/Makefile lib/cobalt/arch/sh/Makefile lib/cobalt/arch/sh/include/Makefile lib/cobalt/arch/sh/include/asm/Makefile lib/cobalt/arch/sh/include/asm/xenomai/Makefile lib/copperplate/Makefile lib/copperplate/regd/Makefile lib/alchemy/Makefile lib/vxworks/Makefile lib/psos/Makefile lib/analogy/Makefile testsuite/Makefile testsuite/latency/Makefile testsuite/switchtest/Makefile testsuite/clocktest/Makefile testsuite/unit/Makefile testsuite/xeno-test/Makefile testsuite/regression/Makefile testsuite/regression/posix/Makefile utils/Makefile utils/can/Makefile utils/analogy/Makefile utils/ps/Makefile utils/slackspot/Makefile demo/Makefile demo/posix/Makefile demo/posix/cobalt/Makefile demo/alchemy/Makefile demo/alchemy/cobalt/Makefile include/Makefile include/nocore/Makefile include/cobalt/uapi/Makefile include/cobalt/uapi/asm-generic/Makefile include/cobalt/uapi/kernel/Makefile include/cobalt/uapi/rtdm/Makefile include/cobalt/Makefile include/cobalt/sys/Makefile include/cobalt/kernel/Makefile include/cobalt/kernel/rtdm/Makefile include/cobalt/kernel/rtdm/analogy/Makefile include/cobalt/boilerplate/Makefile include/rtdm/Makefile include/rtdm/uapi/Makefile include/mercury/Makefile include/mercury/boilerplate/Makefile include/boilerplate/Makefile include/copperplate/Makefile include/alchemy/Makefile include/vxworks/Makefile include/psos/Makefile doc/Makefile doc/doxygen/Makefile doc/doxygen/xeno3prm-common.conf doc/doxygen/xeno3prm-html.conf doc/doxygen/xeno3prm-latex.conf doc/asciidoc/Makefile"
ac_config_files="$ac_config_files Makefile config/Makefile scripts/Makefile scripts/xeno-config:scripts/xeno-config-$rtcore_type.in scripts/xeno lib/Makefile lib/boilerplate/Makefile lib/cobalt/Makefile lib/cobalt/arch/Makefile lib/cobalt/arch/arm/Makefile lib/cobalt/arch/arm/include/Makefile lib/cobalt/arch/arm/include/asm/Makefile lib/cobalt/arch/arm/include/asm/xenomai/Makefile lib/cobalt/arch/powerpc/Makefile lib/cobalt/arch/powerpc/include/Makefile lib/cobalt/arch/powerpc/include/asm/Makefile lib/cobalt/arch/powerpc/include/asm/xenomai/Makefile lib/cobalt/arch/blackfin/Makefile lib/cobalt/arch/blackfin/include/Makefile lib/cobalt/arch/blackfin/include/asm/Makefile lib/cobalt/arch/blackfin/include/asm/xenomai/Makefile lib/cobalt/arch/x86/Makefile lib/cobalt/arch/x86/include/Makefile lib/cobalt/arch/x86/include/asm/Makefile lib/cobalt/arch/x86/include/asm/xenomai/Makefile lib/cobalt/arch/nios2/Makefile lib/cobalt/arch/nios2/include/Makefile lib/cobalt/arch/nios2/include/asm/Makefile lib/cobalt/arch/nios2/include/asm/xenomai/Makefile lib/cobalt/arch/sh/Makefile lib/cobalt/arch/sh/include/Makefile lib/cobalt/arch/sh/include/asm/Makefile lib/cobalt/arch/sh/include/asm/xenomai/Makefile lib/copperplate/Makefile lib/copperplate/regd/Makefile lib/alchemy/Makefile lib/vxworks/Makefile lib/psos/Makefile lib/analogy/Makefile lib/smokey/Makefile testsuite/Makefile testsuite/latency/Makefile testsuite/switchtest/Makefile testsuite/smokey/Makefile testsuite/smokey/arith/Makefile testsuite/smokey/sched-quota/Makefile testsuite/smokey/sched-tp/Makefile testsuite/smokey/rtdm/Makefile testsuite/smokey/vdso-access/Makefile testsuite/smokey/cond-torture/Makefile testsuite/smokey/mutex-torture/Makefile testsuite/clocktest/Makefile testsuite/xeno-test/Makefile testsuite/regression/Makefile testsuite/regression/posix/Makefile utils/Makefile utils/can/Makefile utils/analogy/Makefile utils/ps/Makefile utils/slackspot/Makefile demo/Makefile demo/posix/Makefile demo/posix/cobalt/Makefile demo/alchemy/Makefile demo/alchemy/cobalt/Makefile include/Makefile include/nocore/Makefile include/cobalt/uapi/Makefile include/cobalt/uapi/asm-generic/Makefile include/cobalt/uapi/kernel/Makefile include/cobalt/uapi/rtdm/Makefile include/cobalt/Makefile include/cobalt/sys/Makefile include/cobalt/kernel/Makefile include/cobalt/kernel/rtdm/Makefile include/cobalt/kernel/rtdm/analogy/Makefile include/cobalt/boilerplate/Makefile include/rtdm/Makefile include/rtdm/uapi/Makefile include/mercury/Makefile include/mercury/boilerplate/Makefile include/boilerplate/Makefile include/copperplate/Makefile include/alchemy/Makefile include/vxworks/Makefile include/psos/Makefile include/smokey/Makefile doc/Makefile doc/doxygen/Makefile doc/doxygen/xeno3prm-common.conf doc/doxygen/xeno3prm-html.conf doc/doxygen/xeno3prm-latex.conf doc/asciidoc/Makefile"
cat >confcache <<\_ACEOF
......@@ -15333,11 +15333,19 @@ do
"lib/vxworks/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vxworks/Makefile" ;;
"lib/psos/Makefile") CONFIG_FILES="$CONFIG_FILES lib/psos/Makefile" ;;
"lib/analogy/Makefile") CONFIG_FILES="$CONFIG_FILES lib/analogy/Makefile" ;;
"lib/smokey/Makefile") CONFIG_FILES="$CONFIG_FILES lib/smokey/Makefile" ;;
"testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
"testsuite/latency/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/latency/Makefile" ;;
"testsuite/switchtest/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/switchtest/Makefile" ;;
"testsuite/smokey/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/Makefile" ;;
"testsuite/smokey/arith/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/arith/Makefile" ;;
"testsuite/smokey/sched-quota/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/sched-quota/Makefile" ;;
"testsuite/smokey/sched-tp/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/sched-tp/Makefile" ;;
"testsuite/smokey/rtdm/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/rtdm/Makefile" ;;
"testsuite/smokey/vdso-access/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/vdso-access/Makefile" ;;
"testsuite/smokey/cond-torture/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/cond-torture/Makefile" ;;
"testsuite/smokey/mutex-torture/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/smokey/mutex-torture/Makefile" ;;
"testsuite/clocktest/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/clocktest/Makefile" ;;
"testsuite/unit/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/unit/Makefile" ;;
"testsuite/xeno-test/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/xeno-test/Makefile" ;;
"testsuite/regression/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/regression/Makefile" ;;
"testsuite/regression/posix/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/regression/posix/Makefile" ;;
......@@ -15372,6 +15380,7 @@ do
"include/alchemy/Makefile") CONFIG_FILES="$CONFIG_FILES include/alchemy/Makefile" ;;
"include/vxworks/Makefile") CONFIG_FILES="$CONFIG_FILES include/vxworks/Makefile" ;;
"include/psos/Makefile") CONFIG_FILES="$CONFIG_FILES include/psos/Makefile" ;;
"include/smokey/Makefile") CONFIG_FILES="$CONFIG_FILES include/smokey/Makefile" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"doc/doxygen/Makefile") CONFIG_FILES="$CONFIG_FILES doc/doxygen/Makefile" ;;
"doc/doxygen/xeno3prm-common.conf") CONFIG_FILES="$CONFIG_FILES doc/doxygen/xeno3prm-common.conf" ;;
......
......@@ -839,11 +839,19 @@ AC_CONFIG_FILES([ \
lib/vxworks/Makefile \
lib/psos/Makefile \
lib/analogy/Makefile \
lib/smokey/Makefile \
testsuite/Makefile \
testsuite/latency/Makefile \
testsuite/switchtest/Makefile \
testsuite/smokey/Makefile \
testsuite/smokey/arith/Makefile \
testsuite/smokey/sched-quota/Makefile \
testsuite/smokey/sched-tp/Makefile \
testsuite/smokey/rtdm/Makefile \
testsuite/smokey/vdso-access/Makefile \
testsuite/smokey/cond-torture/Makefile \
testsuite/smokey/mutex-torture/Makefile \
testsuite/clocktest/Makefile \
testsuite/unit/Makefile \
testsuite/xeno-test/Makefile \
testsuite/regression/Makefile \
testsuite/regression/posix/Makefile \
......@@ -878,6 +886,7 @@ AC_CONFIG_FILES([ \
include/alchemy/Makefile \
include/vxworks/Makefile \
include/psos/Makefile \
include/smokey/Makefile \
doc/Makefile \
doc/doxygen/Makefile \
doc/doxygen/xeno3prm-common.conf \
......
......@@ -6,6 +6,7 @@ SUBDIRS = \
nocore \
boilerplate \
copperplate \
smokey \
alchemy \
psos \
vxworks
......@@ -27,4 +28,5 @@ DIST_SUBDIRS = \
nocore \
psos \
rtdm \
smokey \
vxworks
......@@ -377,7 +377,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
nodist_include_HEADERS = $(CONFIG_HEADER)
include_HEADERS = version.h
SUBDIRS = nocore boilerplate copperplate alchemy psos vxworks \
SUBDIRS = nocore boilerplate copperplate smokey alchemy psos vxworks \
$(am__append_1) $(am__append_2)
DIST_SUBDIRS = \
alchemy \
......@@ -388,6 +388,7 @@ DIST_SUBDIRS = \
nocore \
psos \
rtdm \
smokey \
vxworks
all: xeno_config.h
......
includesubdir = $(includedir)/smokey
includesub_HEADERS = smokey.h
This diff is collapsed.
/*
* Copyright (C) 2014 Philippe Gerum <rpm@xenomai.org>.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#ifndef _XENOMAI_SMOKEY_SMOKEY_H
#define _XENOMAI_SMOKEY_SMOKEY_H
#include <boilerplate/list.h>
#include <copperplate/clockobj.h>
#define SMOKEY_INT(__name) { \
.name = # __name, \
.parser = smokey_int, \
.matched = 0, \
}
#define SMOKEY_BOOL(__name) { \
.name = # __name, \
.parser = smokey_bool, \
.matched = 0, \
}
#define SMOKEY_STRING(__name) { \
.name = # __name, \
.parser = smokey_string, \
.matched = 0, \
}
#define SMOKEY_ARGLIST(__args...) ((struct smokey_arg[]){ __args })
#define SMOKEY_NOARGS (((struct smokey_arg[]){ { .name = NULL } }))
struct smokey_arg {
const char *name;
int (*parser)(const char *s,
struct smokey_arg *arg);
union {
int n_val;
char *s_val;
} u;
int matched;
};
struct smokey_test {
const char *name;
struct smokey_arg *args;
int nargs;
const char *description;
int (*run)(struct smokey_test *t,
int argc, char *const argv[]);
struct {
int id;
struct pvholder next;
} __reserved;
};
#define for_each_smokey_test(__pos) \
pvlist_for_each_entry((__pos), &smokey_test_list, __reserved.next)
#define __SMOKEYPLUG_CTOR_PRIO 310
#define __smokey_arg_count(__args) \
(sizeof(__args) / sizeof(__args[0]))
#define smokey_test_plugin(__name, __args, __desc) \
static int run_ ## __name(struct smokey_test *t, \
int argc, char *const argv[]); \
static struct smokey_test __name = { \
.name = #__name, \
.args = (__args), \
.nargs = __smokey_arg_count(__args), \
.description = (__desc), \
.run = run_ ## __name, \
}; \
void smokey_plugin_ ## __name(void); \
__attribute__((constructor(__SMOKEYPLUG_CTOR_PRIO))) \
void smokey_plugin_ ## __name(void) \
{ \
smokey_register_plugin(&(__name)); \
}
#define SMOKEY_ARG(__name, __pos) ((__name).args + __pos)
#define SMOKEY_ARG_ISSET(__name, __pos) (SMOKEY_ARG(__name, __pos)->matched)
#define SMOKEY_ARG_INT(__name, __pos) (SMOKEY_ARG(__name, __pos)->u.n_val)
#define SMOKEY_ARG_STRING(__name, __pos) (SMOKEY_ARG(__name, __pos)->u.s_val)
#ifdef __cplusplus
extern "C" {
#endif
void smokey_register_plugin(struct smokey_test *t);
int smokey_int(const char *s, struct smokey_arg *arg);
int smokey_bool(const char *s, struct smokey_arg *arg);
int smokey_string(const char *s, struct smokey_arg *arg);
int smokey_parse_args(struct smokey_test *t,
int argc, char *const argv[]);
#ifdef __cplusplus
}
#endif
extern struct pvlist smokey_test_list;
extern int smokey_keep_going;
#endif /* _XENOMAI_SMOKEY_SMOKEY_H */
......@@ -8,6 +8,7 @@ endif
SUBDIRS += \
copperplate \
smokey \
alchemy \
vxworks \
psos
......@@ -19,4 +20,5 @@ DIST_SUBDIRS = \
cobalt \
copperplate \
psos \
smokey \
vxworks
......@@ -342,7 +342,8 @@ target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = boilerplate $(am__append_1) copperplate alchemy vxworks psos
SUBDIRS = boilerplate $(am__append_1) copperplate smokey alchemy \
vxworks psos
DIST_SUBDIRS = \
alchemy \
analogy \
......@@ -350,6 +351,7 @@ DIST_SUBDIRS = \
cobalt \
copperplate \
psos \
smokey \
vxworks
all: all-recursive
......
......@@ -18,7 +18,6 @@
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
......
lib_LTLIBRARIES = libsmokey.la
libsmokey_la_LDFLAGS = @XENO_LIB_LDFLAGS@ -version-info 0:0:0
libsmokey_la_SOURCES = \
helpers.c \
init.c
libsmokey_la_CPPFLAGS = \
@XENO_USER_CFLAGS@ \
-I$(top_srcdir)/include \
-I$(top_srcdir)/lib
This diff is collapsed.
/*
* Copyright (C) 2014 Philippe Gerum <rpm@xenomai.org>.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <errno.h>
#include <boilerplate/ancillaries.h>
#include <smokey/smokey.h>
int smokey_int(const char *s, struct smokey_arg *arg)
{
char *name, *p;
int ret;
ret = sscanf(s, "%m[a-z]=%m[^\n]", &name, &p);
if (ret != 2 || !(isdigit(*p) || *p == '-'))
return 0;
ret = !strcmp(name, arg->name);
if (ret)
arg->u.n_val = atoi(p);
free(p);
free(name);
return ret;
}
int smokey_bool(const char *s, struct smokey_arg *arg)
{
int ret;
ret = smokey_int(s, arg);
if (ret) {
arg->u.n_val = !!arg->u.n_val;
return 1;
}
if (strcmp(s, arg->name) == 0) {
arg->u.n_val = 1;
return 1;
}
return 0;
}
int smokey_string(const char *s, struct smokey_arg *arg)
{
char *name, *p;
int ret;
ret = sscanf(s, "%m[a-z]=%m[^\n]", &name, &p);
if (ret != 2)
return 0;
ret = !strcmp(name, arg->name);
if (ret)
arg->u.s_val = p;
else
free(p);
free(name);
return ret;
}
int smokey_parse_args(struct smokey_test *t,
int argc, char *const argv[])
{
int matched = 0, n = 0, ac;
struct smokey_arg *arg;
while (++n < argc) {
for (arg = t->args, ac = 0;
arg->name && ac < t->nargs; arg++, ac++) {
arg->matched = !!arg->parser(argv[n], arg);
if (arg->matched) {
matched++;
break;
}
}
}
return matched;
}
/*
* Copyright (C) 2014 Philippe Gerum <rpm@xenomai.org>.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <fnmatch.h>
#include <boilerplate/list.h>
#include <boilerplate/ancillaries.h>
#include <copperplate/init.h>
#include "copperplate/internal.h"
#include <smokey/smokey.h>
/**
* @defgroup smokey Smokey API
*
* A simple infrastructure for writing and running smoke tests.
*/
DEFINE_PRIVATE_LIST(smokey_test_list);
int smokey_keep_going;
static DEFINE_PRIVATE_LIST(register_list);
static int test_count;
static int do_list;
static const struct option smokey_options[] = {
{
#define keep_going_opt 0
.name = "keep-going",
.flag = &smokey_keep_going,
.val = 1,
},
{
#define run_opt 1
.name = "run",
.has_arg = 2,
},
{
#define list_opt 2
.name = "list",
.flag = &do_list,
.val = 1,
},
{
.name = NULL,
}
};
static void smokey_help(void)
{
fprintf(stderr, "--keep-going don't stop upon test error\n");
fprintf(stderr, "--list list all tests\n");
fprintf(stderr, "--run[=<id[,id...]>]] run [portion of] test list\n");
}
static inline void pick_test_range(int start, int end)
{
struct smokey_test *t, *tmp;
/* Pick tests in the suggested range order. */
if (start <= end) {
pvlist_for_each_entry_safe(t, tmp, &register_list, __reserved.next) {
if (t->__reserved.id >= start &&
t->__reserved.id <= end) {
pvlist_remove(&t->__reserved.next);
pvlist_append(&t->__reserved.next, &smokey_test_list);
}
}
} else {
pvlist_for_each_entry_reverse_safe(t, tmp, &register_list, __reserved.next) {
if (t->__reserved.id >= end &&
t->__reserved.id <= start) {
pvlist_remove(&t->__reserved.next);
pvlist_append(&t->__reserved.next, &smokey_test_list);
}
}
}
}
static int resolve_id(const char *s)
{
struct smokey_test *t;
if (isdigit(*s))
return atoi(s);
/*
* CAUTION: as we transfer items from register_list to
* smokey_test_list, we may end up with an empty source list,
* which is a perfectly valid situation. Unlike having an
* empty registration list at startup, which would mean that
* no test is available from the current program.
*/
if (pvlist_empty(&register_list))
return -1;
pvlist_for_each_entry(t, &register_list, __reserved.next)
if (!fnmatch(s, t->name, FNM_PATHNAME))
return t->__reserved.id;
return -1;
}
static int build_test_list(const char *test_enum)
{
char *s = strdup(test_enum), *n, *range, *range_p, *id, *id_r;
int start, end;
n = s;
while ((range = strtok_r(n, ",", &range_p)) != NULL) {
if (*range == '\0')
continue;
end = -1;
if (range[strlen(range)-1] == '-')
end = test_count - 1;
id = strtok_r(range, "-", &id_r);
if (id) {
start = resolve_id(id);
if (*range == '-') {
end = start;
start = 0;
}
id = strtok_r(NULL, "-", &id_r);
if (id)
end = resolve_id(id);
else if (end < 0)
end = start;
if (start < 0 || start >= test_count ||
end < 0 || end >= test_count)
goto fail;
} else {
start = 0;
end = test_count - 1;
}
pick_test_range(start, end);
n = NULL;
}
free(s);
return 0;
fail:
warning("invalid test range in %s (each id. should be within [0-%d])",
test_enum, test_count - 1);
free(s);
return -EINVAL;
}
static void list_all_tests(void)
{
struct smokey_test *t;
if (pvlist_empty(&register_list))
return;
pvlist_for_each_entry(t, &register_list, __reserved.next)
printf("#%-3d %s\n\t%s\n",
t->__reserved.id, t->name, t->description);
}
static int smokey_parse_option(int optnum, const char *optarg)
{
int ret = 0;
switch (optnum) {
case keep_going_opt:
break;
case run_opt:
if (pvlist_empty(&register_list)) {
warning("no test registered");
return -EINVAL;
}
if (optarg)
ret = build_test_list(optarg);
else
pick_test_range(0, test_count);
if (pvlist_empty(&smokey_test_list)) {
warning("no test selected");
return -EINVAL;
}
break;
case list_opt:
list_all_tests();
break;
default:
ret = -EINVAL;
}
return ret;
}
static int smokey_init(void)
{
if (pvlist_empty(&smokey_test_list))
copperplate_set_silent();
return 0;
}
static struct copperskin smokey_interface = {
.name = "smokey",
.init = smokey_init,
.options = smokey_options,
.parse_option = smokey_parse_option,
.help = smokey_help,
};
static __attribute__ ((constructor(__SMOKEYPLUG_CTOR_PRIO+1)))
void register_smokey(void)
{
copperplate_register_skin(&smokey_interface);
}
void smokey_register_plugin(struct smokey_test *t)
{
pvlist_append(&t->__reserved.next, &register_list);
t->__reserved.id = test_count++;
}
SUBDIRS = latency unit
SUBDIRS = latency smokey
if XENO_COBALT
SUBDIRS += \
......@@ -13,6 +13,6 @@ DIST_SUBDIRS = \
clocktest \
latency \
regression \
smokey \
switchtest \
unit \
xeno-test
......@@ -344,13 +344,13 @@ target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@