[RFC PATCH] selftests: Add example test and Makefiles

From: Michael Ellerman
Date: Mon Nov 02 2015 - 00:27:31 EST


This commit adds an example directory with a simple and verbose
Makefile, and some trivial example programs.

As always this could probably be improved but it's a start.

Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
---

Some folks at kernel summit expressed an interest in an example of how to add a
test case. This is an attempt to provide a simple example, but also guide
people who want to do more complicated things.

I just bashed this out so it could probably use some tweaks, comments welcome.


tools/testing/selftests/example/.gitignore | 2 +
tools/testing/selftests/example/Makefile.simple | 12 ++++
tools/testing/selftests/example/Makefile.verbose | 91 ++++++++++++++++++++++++
tools/testing/selftests/example/README | 50 +++++++++++++
tools/testing/selftests/example/hello.c | 8 +++
tools/testing/selftests/example/hello.h | 1 +
tools/testing/selftests/example/hello.sh | 8 +++
tools/testing/selftests/example/message.txt | 1 +
tools/testing/selftests/example/saymessage.c | 41 +++++++++++
9 files changed, 214 insertions(+)
create mode 100644 tools/testing/selftests/example/.gitignore
create mode 100644 tools/testing/selftests/example/Makefile.simple
create mode 100644 tools/testing/selftests/example/Makefile.verbose
create mode 100644 tools/testing/selftests/example/README
create mode 100644 tools/testing/selftests/example/hello.c
create mode 100644 tools/testing/selftests/example/hello.h
create mode 100755 tools/testing/selftests/example/hello.sh
create mode 100644 tools/testing/selftests/example/message.txt
create mode 100644 tools/testing/selftests/example/saymessage.c

diff --git a/tools/testing/selftests/example/.gitignore b/tools/testing/selftests/example/.gitignore
new file mode 100644
index 000000000000..7ae919160b5f
--- /dev/null
+++ b/tools/testing/selftests/example/.gitignore
@@ -0,0 +1,2 @@
+hello
+saymessage
diff --git a/tools/testing/selftests/example/Makefile.simple b/tools/testing/selftests/example/Makefile.simple
new file mode 100644
index 000000000000..6e781e0fc007
--- /dev/null
+++ b/tools/testing/selftests/example/Makefile.simple
@@ -0,0 +1,12 @@
+# This is an example for a dead simple binary test case with no extra
+# frills. This should work for many tests, see Makefile.verbose for a fuller
+# description of all the options.
+
+TEST_PROGS := hello saymessage
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+ $(RM) $(TEST_PROGS)
diff --git a/tools/testing/selftests/example/Makefile.verbose b/tools/testing/selftests/example/Makefile.verbose
new file mode 100644
index 000000000000..2201e1f34fb3
--- /dev/null
+++ b/tools/testing/selftests/example/Makefile.verbose
@@ -0,0 +1,91 @@
+# Verbose example selftest test case.
+
+# It's often neat to have a variable that holds all your generated binaries.
+# The name PROGS here is not special. If all your tests are generated binaries
+# then you can just use TEST_PROGS in place of PROGS, in this example we also
+# have a shell script in TEST_PROGS so we need to separate PROGS.
+PROGS := hello saymessage
+
+# TEST_PROGS defines a list of tests that should be run.
+# It can include either binaries or shell scripts.
+TEST_PROGS := $(PROGS) hello.sh
+
+# If you need other files installed that aren't tests, you can list them in
+# TEST_FILES.
+TEST_FILES := message.txt
+
+# TEST_FILES can also include binaries but they won't be run by default. This
+# can be useful if for example you have a destructive test which you want to
+# build and install, but not run by default. The test will be there for people
+# to run if they choose to.
+
+# The upper level Makefile will call the first target in your Makefile,
+# typically it's called "all", but doesn't have to be.
+all: $(PROGS)
+
+$(PROGS): hello.h
+
+# CC is already defined for you to include CROSS_COMPILE, if that's defined, so
+# you shouldn't need to modify CC.
+
+# The normal Make implicit rules are available, so you do not need to define
+# how to build a binary from a .c file. For example we don't have an explicit
+# rule here for hello.
+
+# You can add to CFLAGS, don't override it unless you absolutely must.
+CFLAGS += -Wall
+
+# You can add flags for only a particular file, this works with CFLAGS, LDLIBS,
+# LDFLAGS etc.
+saymessage: CFLAGS += -Werror -DHAVE_MESSAGE_TXT
+
+# If you need extra libs you should append to LDLIBS.
+LDLIBS += -lc
+
+# Similarly you can append to LDFLAGS for linker flags.
+LDFLAGS += -g
+
+# Then include lib.mk, it provides the run_test and install logic for you.
+# You need to define the top-level target, ie. "all" above, before you include
+# lib.mk.
+include ../lib.mk
+
+# If for some reason it's tricky to define your "all" target before including
+# lib.mk, you can define it initially as having no dependencies, and then add
+# dependencies later, eg:
+#
+# all:
+#
+# include ../lib.mk
+#
+# all: $(SOMETHING_COMPLICATED)
+#
+# ifeq ($(SOMETHING_ELSE),1)
+# all: $(MORE_STUFF)
+# endif
+
+# If you need custom logic for running tests, you can override RUN_TESTS.
+# This can be used to pass arguments etc.
+# HOWEVER it's much more preferable if your test just does something sane with
+# no arguments or extra logic.
+# If you do define your own rule you are responsible for printing a failure
+# message. You can do that in your test program itself, or in the shell as
+# below.
+override define RUN_TESTS
+./hello || echo "selftests: hello [FAIL]" ; \
+./saymessage || echo "selftests: saymessage [FAIL]" ; \
+./hello.sh "world" || echo "selftests: hello.sh [FAIL]"
+endef
+
+# If you override RUN_TESTS you probably also need to override EMIT_TESTS. This
+# rule is used by the install logic to emit a shell script fragment that is
+# added to the installed script that runs the tests.
+# You can often just echo your RUN_TESTS definition, though you may need to be
+# careful of shell quoting etc.
+override define EMIT_TESTS
+ echo "$(RUN_TESTS)"
+endef
+
+# You need to define your own clean rule.
+clean:
+ $(RM) $(PROGS)
diff --git a/tools/testing/selftests/example/README b/tools/testing/selftests/example/README
new file mode 100644
index 000000000000..155a247541a1
--- /dev/null
+++ b/tools/testing/selftests/example/README
@@ -0,0 +1,50 @@
+Selftest examples
+=================
+
+This directory contains two examples of how to add a new selftest.
+
+The first is a simple example. You should be able to use this if your test is
+just a few simple binaries built from C files.
+
+To use this example for your test, create a directory named after your test and
+copy Makefile.simple to it, eg:
+
+ $ cd tools/testing/selftests
+ $ mkdir footest
+ $ cp example/Makefile.simple footest/Makefile
+
+Then add your directory to the top-level selftest Makefile by adding a line
+like:
+
+ TARGETS += footest
+
+(Please keep the list of targets alphabetically sorted)
+
+Then update footest/Makefile to build your test program by changing the
+TEST_PROGS line appropriately, eg:
+
+ TEST_PROGS := testfoo
+
+And copy your testfoo.c file into footest.
+
+Finally create footest/.gitignore to ignore the test binary:
+
+ $ echo "testfoo" > footest/.gitignore
+
+Then you should be able to see your test built by running:
+
+ $ make TARGETS=footest
+
+You should also test that install works, eith:
+
+ $ make TARGETS=footest install
+
+And then check the result with:
+
+ $ find install/
+ $ cat install/run_kselftest.sh
+
+
+To use the verbose example, you can either do as above but copy
+Makefile.verbose instead of Makefile.simple, or copy the whole directory and
+delete the parts you don't need.
diff --git a/tools/testing/selftests/example/hello.c b/tools/testing/selftests/example/hello.c
new file mode 100644
index 000000000000..aedc93fa8d74
--- /dev/null
+++ b/tools/testing/selftests/example/hello.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main(void)
+{
+ printf("hello selftest world\n");
+
+ return 0;
+}
diff --git a/tools/testing/selftests/example/hello.h b/tools/testing/selftests/example/hello.h
new file mode 100644
index 000000000000..c8b49f26d172
--- /dev/null
+++ b/tools/testing/selftests/example/hello.h
@@ -0,0 +1 @@
+#include <stdlib.h>
diff --git a/tools/testing/selftests/example/hello.sh b/tools/testing/selftests/example/hello.sh
new file mode 100755
index 000000000000..80510616bb84
--- /dev/null
+++ b/tools/testing/selftests/example/hello.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# Tests can just be scripts.
+# But they need to marked executable in git in order to run.
+
+echo "Shell says hello '$1'"
+
+exit 0
diff --git a/tools/testing/selftests/example/message.txt b/tools/testing/selftests/example/message.txt
new file mode 100644
index 000000000000..557db03de997
--- /dev/null
+++ b/tools/testing/selftests/example/message.txt
@@ -0,0 +1 @@
+Hello World
diff --git a/tools/testing/selftests/example/saymessage.c b/tools/testing/selftests/example/saymessage.c
new file mode 100644
index 000000000000..ab9e5d6ae892
--- /dev/null
+++ b/tools/testing/selftests/example/saymessage.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int main(void)
+{
+ char buf[128];
+ FILE *f;
+
+ /*
+ * The selftests machinery runs the test in the directory it is built in,
+ * so you can find data files easily, they are in the current directory.
+ * To support installing the selftests you need to add any data files
+ * to TEST_FILES, they will then be copied into the install directory,
+ * where your tests will be run, so the C code doesn't need any extra
+ * logic.
+ */
+
+ /*
+ * This test is written to work with or without message.txt, mainly
+ * just to demonstrate that it's possible. Your code should probably
+ * just always install any extra files.
+ */
+
+#ifdef HAVE_MESSAGE_TXT
+ f = fopen("message.txt", "r");
+ if (!f) {
+ perror("fopen");
+ return 1;
+ }
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ perror("fgets");
+ return 1;
+ }
+#else
+ snprintf(buf, sizeof(buf), "builtin message\n");
+#endif
+
+ printf("Test message is: %s", buf);
+
+ return 0;
+}
--
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/