On 04/10/2013 04:08 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Some aspects of the cgroups setup / detection code are quite subtle
and easy to break. It would greatly benefit from unit testing, but
this is difficult because the test suite won't have privileges to
play around with cgroups. The solution is to use monkey patching
via LD_PRELOAD to override the fopen, open, mkdir, access functions
to redirect access of cgroups files to some magic stubs in the
test suite.
Using this we provide custom content for the /proc/cgroup and
/proc/self/mounts files which report a fixed cgroup setup. We
then override open/mkdir/access so that access to the cgroups
filesystem gets redirected into files in a temporary directory
tree in the test suite build dir.
Do you also need to override openat/mkdirat/faccessat, in case we (or
even libc on our behalf) ever uses the newer *at syscalls?
Wow, this looks complicated, so I'll have to defer my review to sometime
earlier in my day when I'm thinking straight. But the premise is
useful, and a passing 'make check' even on a system with no cgroups
mounted is a pretty good indication of whether you got it right.
+/*
+ * The plan:
+ *
+ * We fake out /proc/mounts, so make it look as is cgroups
+ * are mounted on /not/really/sys/fs/cgroup. We don't
+ * use /sys/fs/cgroup, because we want to make it easy to
+ * detect places where we've not mocked enough syscalls.
and so that the testsuite will run and pass even on systems without
cgroups mounted.
+ *
+ * In any open/acces/mkdir calls we look at path and if
+ * it starts with /not/really/sys/fs/cgroup, we rewrite
+ * the path to point at a temporary directory referred
+ * to by LIBVIRT_FAKE_SYSFS_DIR env variable that is
+ * set by the main test suite
+ *
+ * In mkdir() calls, we simulate the cgroups behaviour
+ * whereby creating the directory auto-creates a bunch
+ * of files beneath it
+ */
Good luck!
+mymain(void)
+{
+ int ret = 0;
+ char *fakesysfsdir;
+
+ if (!(fakesysfsdir = strdup(FAKESYSFSDIRTEMPLATE))) {
+ fprintf(stderr, "Out of memory\n");
+ abort();
+ }
+
+ if (!mkdtemp(fakesysfsdir)) {
Does this compile on mingw, or do you need to modify bootstrap.conf to
pull in the mkdtemp gnulib module? [Then again, it won't compile on
mingw in the first place, since the Makefile.am limits it to platforms
with LD_PRELOAD support]
+ fprintf(stderr, "Cannot create fakesysfsdir");
+ abort();
+ }
+
+ setenv("LIBVIRT_FAKE_SYSFS_DIR", fakesysfsdir, 1);
+
+ if (virtTestRun("New cgroup for self", 1, testCgroupNewForSelf, NULL) <
0)
+ ret = -1;
+
+ if (virtTestRun("New cgroup for driver", 1, testCgroupNewForDriver, NULL)
< 0)
+ ret = -1;
+
+ if (virtTestRun("New cgroup for domain", 1, testCgroupNewForDomain, NULL)
< 0)
+ ret = -1;
+
+ if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
+ virFileDeleteTree(fakesysfsdir);
+
+ return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
Spaces around ==
+}
+
+VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/libvircgroupmock.so")
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org