]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
testsuite: add trap to fopen() including tests
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Wed, 25 Jan 2012 04:44:45 +0000 (02:44 -0200)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Thu, 26 Jan 2012 18:05:04 +0000 (16:05 -0200)
Makefile.am
testsuite/.gitignore
testsuite/path.c [new file with mode: 0644]
testsuite/rootfs.tar.xz [new file with mode: 0644]
testsuite/test-testsuite.c
testsuite/testsuite.h

index 4766424027b1a45cd580cd88e7807379ac9eafca..6e9a45d2609740e1d0ab2f58925cd611f4307521 100644 (file)
@@ -1,5 +1,6 @@
 SUBDIRS = . libkmod/docs man
 
+DISTCLEAN_LOCAL_HOOKS =
 EXTRA_DIST =
 CLEANFILES =
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
@@ -128,6 +129,10 @@ ${noinst_SCRIPTS}: tools/kmod-nolib
                $(LN_S) $(notdir $<) $@)
 endif
 
+# ------------------------------------------------------------------------------
+# TESTSUITE
+# ------------------------------------------------------------------------------
+
 # libtool will not create a shared library that is not installed. Workaround
 # this by creating it by ourselves
 CREATE_SHARED_OVERRIDE_LIB = \
@@ -137,13 +142,30 @@ CREATE_SHARED_OVERRIDE_LIB = \
 testsuite/uname.so: testsuite/uname.c
        $(CREATE_SHARED_OVERRIDE_LIB)
 
-EXTRA_DIST += testsuite/uname.c
-CLEANFILES += testsuite/uname.so
+testsuite/path.so: testsuite/path.c
+       $(CREATE_SHARED_OVERRIDE_LIB)
+
+EXTRA_DIST += testsuite/uname.c testsuite/path.c
+CLEANFILES += testsuite/uname.so testsuite/path.so
+
+testsuite/rootfs:
+       $(AM_V_GEN) tar -C testsuite/ \
+               -xJf $(top_srcdir)/testsuite/rootfs.tar.xz
+
+testsuite-distclean:
+       -rm -rf testsuite/rootfs
+
+DISTCLEAN_LOCAL_HOOKS += testsuite-distclean
+EXTRA_DIST += testsuite/rootfs.tar.xz
 
 check_LTLIBRARIES = testsuite/libtestsuite.la
 testsuite_libtestsuite_la_SOURCES = testsuite/testsuite.c \
                                    testsuite/testsuite.h
-testsuite_libtestsuite_la_DEPENDENCIES = testsuite/uname.so
+testsuite_libtestsuite_la_DEPENDENCIES = testsuite/uname.so \
+                                        testsuite/path.so \
+                                        testsuite/rootfs
+testsuite_test_testsuite_CPPFLAGS = $(AM_CPPFLAGS) \
+                                   -DTESTSUITE_ROOTFS=\"$(abs_top_builddir)/testsuite/rootfs/\"
 
 TESTSUITE = testsuite/test-init testsuite/test-testsuite
 check_PROGRAMS = $(TESTSUITE)
@@ -154,6 +176,7 @@ testsuite_test_testsuite_LDADD = testsuite/libtestsuite.la
 
 DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
 
+distclean-local: $(DISTCLEAN_LOCAL_HOOKS)
 
 # ------------------------------------------------------------------------------
 # custom release helpers
index 4b5d6967ba1a330e52c8f893032a50aef34435c4..2cd9099e1a87e790a7d45de093d7c8c6c3f173e2 100644 (file)
@@ -4,3 +4,4 @@
 *.so
 test-testsuite
 test-init
+rootfs/
diff --git a/testsuite/path.c b/testsuite/path.c
new file mode 100644 (file)
index 0000000..9b435b4
--- /dev/null
@@ -0,0 +1,90 @@
+#include <assert.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "testsuite.h"
+
+static void *nextlib;
+static const char *rootpath;
+static size_t rootpathlen;
+
+static inline bool need_trap(const char *path)
+{
+       return path != NULL && path[0] == '/';
+}
+
+static const char *trap_path(const char *path, char buf[PATH_MAX * 2])
+{
+       size_t len;
+
+       if (!need_trap(path))
+               return path;
+
+       len = strlen(path);
+
+       if (len + rootpathlen > PATH_MAX * 2) {
+               errno = ENAMETOOLONG;
+               return NULL;
+       }
+
+       memcpy(buf, rootpath, rootpathlen);
+       strcpy(buf + rootpathlen, path);
+       return buf;
+}
+
+static bool get_rootpath(const char *f)
+{
+       if (rootpath != NULL)
+               return true;
+
+       rootpath = getenv(S_TC_ROOTFS);
+       if (rootpath == NULL) {
+               ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS);
+               errno = ENOENT;
+               return false;
+       }
+
+       rootpathlen = strlen(rootpath);
+
+       return true;
+}
+
+static void *get_libc_func(const char *f)
+{
+       void *fp;
+
+       if (nextlib == NULL) {
+#ifdef RTLD_NEXT
+               nextlib = RTLD_NEXT;
+#else
+               nextlib = dlopen("libc.so.6", RTLD_LAZY);
+#endif
+       }
+
+       fp = dlsym(nextlib, f);
+       assert(fp);
+
+       return fp;
+}
+
+TS_EXPORT FILE *fopen(const char *path, const char *mode)
+{
+       const char *p;
+       char buf[PATH_MAX * 2];
+       static int (*_fopen)(const char *path, const char *mode);
+
+       if (!get_rootpath(__func__))
+               return NULL;
+
+       _fopen = get_libc_func("fopen");
+
+       p = trap_path(path, buf);
+       if (p == NULL)
+               return NULL;
+
+       return (void *) (long) (*_fopen)(p, mode);
+}
diff --git a/testsuite/rootfs.tar.xz b/testsuite/rootfs.tar.xz
new file mode 100644 (file)
index 0000000..233caeb
Binary files /dev/null and b/testsuite/rootfs.tar.xz differ
index edbfe45c4e3f580de37de0fdcd3010e7eecd1076..f5b6fceb573c5ebfcbb41290540684ce91eea95e 100644 (file)
@@ -38,8 +38,38 @@ static const struct test stestsuite_uname = {
        .need_spawn = true,
 };
 
+static int testsuite_rootfs_fopen(const struct test *t)
+{
+       FILE *fp;
+       char s[100];
+       int n;
+
+       fp = fopen("/lib/modules/a", "r");
+       if (fp == NULL)
+               return EXIT_FAILURE;;
+
+       n = fscanf(fp, "%s", s);
+       if (n != 1)
+               return EXIT_FAILURE;
+
+       if (strcmp(s, "kmod-test-chroot-works") != 0)
+               return EXIT_FAILURE;
+
+       return EXIT_SUCCESS;
+}
+static const struct test stestsuite_rootfs_fopen = {
+       .name = "testsuite_rootfs_fopen",
+       .description = "test if rootfs works - fopen()",
+       .func = testsuite_rootfs_fopen,
+       .config = {
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-rootfs/",
+       },
+       .need_spawn = true,
+};
+
 static const struct test *tests[] = {
        &stestsuite_uname,
+       &stestsuite_rootfs_fopen,
        NULL,
 };
 
index 669b9d70728c750e9b39ddc79ceb9c7a3570d9ca..e06ecf2dfa40a9c6d352dbea6f8b5d2446f2fa1b 100644 (file)
@@ -13,6 +13,7 @@ enum test_config {
        _TC_LAST,
 };
 
+#define S_TC_ROOTFS "TESTSUITE_ROOTFS"
 #define S_TC_UNAME_R "TESTSUITE_UNAME_R"