virfiletst: Test virFileIsSharedFS

Introduce some basic test cases for virFileIsSharedFS(). More
will be added later. In order to achieve desired result, mocks
for setmntent() and statfs() need to be invented because the
first thing that virFileIsSharedFS() does is calling the latter.
If it finds a FUSE mount it'll call the former.

The mock might look a bit complicated, but in fact it's quite
simple. The test sets LIBVIRT_MTAB env variable to hold the
absolute path to a file containing mount table. Then, statfs()
returns matching FS it finds, and setmntent() is there just to
replace /proc/mounts with the file the test wants to load.

Adding this test also exposed a bug we have - because we assume
the given path points to a file we cut off what we assume is a
file name to obtain directory path and only then we call
statfs(). This is buggy because the passed path could be already
a mount point.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Michal Privoznik
2018-10-09 13:06:00 +02:00
parent 6814ac678e
commit a7b4eb7d26
4 changed files with 254 additions and 2 deletions

View File

@@ -30,6 +30,7 @@
# include <linux/falloc.h>
#endif
#define VIR_FROM_THIS VIR_FROM_NONE
#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
static int testFileCheckMounts(const char *prefix,
@@ -309,6 +310,48 @@ testFileInData(const void *opaque)
}
struct testFileIsSharedFSType {
const char *mtabFile;
const char *filename;
const bool expected;
};
static int
testFileIsSharedFSType(const void *opaque ATTRIBUTE_UNUSED)
{
#ifndef __linux__
return EXIT_AM_SKIP;
#else
const struct testFileIsSharedFSType *data = opaque;
char *mtabFile = NULL;
bool actual;
int ret = -1;
if (virAsprintf(&mtabFile, abs_srcdir "/virfiledata/%s", data->mtabFile) < 0)
return -1;
if (setenv("LIBVIRT_MTAB", mtabFile, 1) < 0) {
fprintf(stderr, "Unable to set env variable\n");
goto cleanup;
}
actual = virFileIsSharedFS(data->filename);
if (actual != data->expected) {
fprintf(stderr, "Unexpected FS type. Expected %d got %d\n",
data->expected, actual);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(mtabFile);
unsetenv("LIBVIRT_MTAB");
return ret;
#endif
}
static int
mymain(void)
{
@@ -396,7 +439,24 @@ mymain(void)
DO_TEST_IN_DATA(true, 8, 16, 32, 64, 128, 256, 512);
DO_TEST_IN_DATA(false, 8, 16, 32, 64, 128, 256, 512);
}
#define DO_TEST_FILE_IS_SHARED_FS_TYPE(mtab, file, exp) \
do { \
struct testFileIsSharedFSType data = { \
.mtabFile = mtab, .filename = file, .expected = exp \
}; \
if (virTestRun(virTestCounterNext(), testFileIsSharedFSType, &data) < 0) \
ret = -1; \
} while (0)
virTestCounterReset("testFileIsSharedFSType ");
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts1.txt", "/boot/vmlinuz", false);
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts2.txt", "/run/user/501/gvfs/some/file", false);
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/file", true);
/* TODO Detect bind mounts */
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", true);
return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
VIR_TEST_MAIN(mymain)
VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virfilemock.so")