[libvirt] [PATCHv3 07/10] Add unit test for virCgroupGetBlkioIo*Serviced

Thorsten Behrens tbehrens at suse.com
Mon Feb 3 17:44:33 UTC 2014


---

Adds another dummy device to push the cgroup parsing code a bit
harder

 tests/vircgroupmock.c | 107 +++++++++++++++++++++++++++++++++++++++-
 tests/vircgrouptest.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 238 insertions(+), 2 deletions(-)

diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
index 6542973..d772652 100644
--- a/tests/vircgroupmock.c
+++ b/tests/vircgroupmock.c
@@ -34,6 +34,8 @@
 static int (*realopen)(const char *path, int flags, ...);
 static FILE *(*realfopen)(const char *path, const char *mode);
 static int (*realaccess)(const char *path, int mode);
+static int (*realstat)(const char *path, struct stat *sb);
+static int (*real__xstat)(int ver, const char *path, struct stat *sb);
 static int (*reallstat)(const char *path, struct stat *sb);
 static int (*real__lxstat)(int ver, const char *path, struct stat *sb);
 static int (*realmkdir)(const char *path, mode_t mode);
@@ -43,6 +45,8 @@ static int (*realmkdir)(const char *path, mode_t mode);
  * vircgroupmock.c:462:22: error: static variable 'fakesysfsdir' is used in an inline function with external linkage [-Werror,-Wstatic-in-inline]
  */
 char *fakesysfsdir;
+char *fakedevicedir0;
+char *fakedevicedir1;
 
 
 # define SYSFS_PREFIX "/not/really/sys/fs/cgroup/"
@@ -332,13 +336,23 @@ static int make_controller(const char *path, mode_t mode)
                   "8:0 Write 411440480256\n"
                   "8:0 Sync 248486822912\n"
                   "8:0 Async 222495764480\n"
-                  "8:0 Total 470982587392\n");
+                  "8:0 Total 470982587392\n"
+                  "9:0 Read 59542107137\n"
+                  "9:0 Write 411440480257\n"
+                  "9:0 Sync 248486822912\n"
+                  "9:0 Async 222495764480\n"
+                  "9:0 Total 470982587392\n");
         MAKE_FILE("blkio.throttle.io_serviced",
                   "8:0 Read 4832583\n"
                   "8:0 Write 36641903\n"
                   "8:0 Sync 30723171\n"
                   "8:0 Async 10751315\n"
-                  "8:0 Total 41474486\n");
+                  "8:0 Total 41474486\n"
+                  "9:0 Read 4832584\n"
+                  "9:0 Write 36641904\n"
+                  "9:0 Sync 30723171\n"
+                  "9:0 Async 10751315\n"
+                  "9:0 Total 41474486\n");
         MAKE_FILE("blkio.throttle.read_bps_device", "");
         MAKE_FILE("blkio.throttle.read_iops_device", "");
         MAKE_FILE("blkio.throttle.write_bps_device", "");
@@ -382,6 +396,7 @@ static void init_syms(void)
     LOAD_SYM(fopen);
     LOAD_SYM(access);
     LOAD_SYM_ALT(lstat, __lxstat);
+    LOAD_SYM_ALT(stat, __xstat);
     LOAD_SYM(mkdir);
     LOAD_SYM(open);
 }
@@ -396,6 +411,16 @@ static void init_sysfs(void)
         abort();
     }
 
+    if (!(fakedevicedir0 = getenv("LIBVIRT_FAKE_DEVICE_DIR0"))) {
+        fprintf(stderr, "Missing LIBVIRT_FAKE_DEVICE_DIR0 env variable\n");
+        abort();
+    }
+
+    if (!(fakedevicedir1 = getenv("LIBVIRT_FAKE_DEVICE_DIR1"))) {
+        fprintf(stderr, "Missing LIBVIRT_FAKE_DEVICE_DIR1 env variable\n");
+        abort();
+    }
+
 # define MAKE_CONTROLLER(subpath)                               \
     do {                                                        \
         char *path;                                             \
@@ -529,6 +554,14 @@ int __lxstat(int ver, const char *path, struct stat *sb)
         }
         ret = real__lxstat(ver, newpath, sb);
         free(newpath);
+    } else if (STRPREFIX(path, fakedevicedir0)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(8, 0);
+        return 0;
+    } else if (STRPREFIX(path, fakedevicedir1)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(9, 0);
+        return 0;
     } else {
         ret = real__lxstat(ver, path, sb);
     }
@@ -552,12 +585,82 @@ int lstat(const char *path, struct stat *sb)
         }
         ret = reallstat(newpath, sb);
         free(newpath);
+    } else if (STRPREFIX(path, fakedevicedir0)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(8, 0);
+        return 0;
+    } else if (STRPREFIX(path, fakedevicedir1)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(9, 0);
+        return 0;
     } else {
         ret = reallstat(path, sb);
     }
     return ret;
 }
 
+int __xstat(int ver, const char *path, struct stat *sb)
+{
+    int ret;
+
+    init_syms();
+
+    if (STRPREFIX(path, SYSFS_PREFIX)) {
+        init_sysfs();
+        char *newpath;
+        if (asprintf(&newpath, "%s/%s",
+                     fakesysfsdir,
+                     path + strlen(SYSFS_PREFIX)) < 0) {
+            errno = ENOMEM;
+            return -1;
+        }
+        ret = real__xstat(ver, newpath, sb);
+        free(newpath);
+    } else if (STRPREFIX(path, fakedevicedir0)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(8, 0);
+        return 0;
+    } else if (STRPREFIX(path, fakedevicedir1)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(9, 0);
+        return 0;
+    } else {
+        ret = real__xstat(ver, path, sb);
+    }
+    return ret;
+}
+
+int stat(const char *path, struct stat *sb)
+{
+    int ret;
+
+    init_syms();
+
+    if (STRPREFIX(path, SYSFS_PREFIX)) {
+        init_sysfs();
+        char *newpath;
+        if (asprintf(&newpath, "%s/%s",
+                     fakesysfsdir,
+                     path + strlen(SYSFS_PREFIX)) < 0) {
+            errno = ENOMEM;
+            return -1;
+        }
+        ret = realstat(newpath, sb);
+        free(newpath);
+    } else if (STRPREFIX(path, fakedevicedir0)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(8, 0);
+        return 0;
+    } else if (STRPREFIX(path, fakedevicedir1)) {
+        sb->st_mode = S_IFBLK;
+        sb->st_rdev = makedev(9, 0);
+        return 0;
+    } else {
+        ret = realstat(path, sb);
+    }
+    return ret;
+}
+
 int mkdir(const char *path, mode_t mode)
 {
     int ret;
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index d5ed016..a29cdd2 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -35,6 +35,9 @@
 
 # define VIR_FROM_THIS VIR_FROM_NONE
 
+# define FAKEDEVDIR0 "/fakedevdir0/bla/fasl"
+# define FAKEDEVDIR1 "/fakedevdir1/bla/fasl"
+
 static int validateCgroup(virCgroupPtr cgroup,
                           const char *expectPath,
                           const char **expectMountPoint,
@@ -529,6 +532,128 @@ static int testCgroupAvailable(const void *args)
     return 0;
 }
 
+static int testCgroupGetBlkioIoServiced(const void *args ATTRIBUTE_UNUSED)
+{
+    virCgroupPtr cgroup = NULL;
+    size_t i;
+    int rv, ret = -1;
+
+    const long long expected_values[] = {
+        119084214273,
+        822880960513,
+        9665167,
+        73283807
+    };
+    const char* names[] = {
+        "bytes read",
+        "bytes written",
+        "requests read",
+        "requests written"
+    };
+    long long values[ARRAY_CARDINALITY(expected_values)];
+
+    if ((rv = virCgroupNewPartition("/virtualmachines", true,
+                                    (1 << VIR_CGROUP_CONTROLLER_BLKIO),
+                                    &cgroup)) < 0) {
+        fprintf(stderr, "Could not create /virtualmachines cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    if ((rv = virCgroupGetBlkioIoServiced(cgroup,
+                                          values, &values[1],
+                                          &values[2], &values[3])) < 0) {
+        fprintf(stderr, "Could not retrieve BlkioIoServiced for /virtualmachines cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    for (i = 0; i < ARRAY_CARDINALITY(expected_values); i++) {
+        if (expected_values[i] != values[i]) {
+            fprintf(stderr,
+                    "Wrong value for %s from virCgroupBlkioIoServiced (expected %lld)\n",
+                    names[i], expected_values[i]);
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    virCgroupFree(&cgroup);
+    return ret;
+}
+
+static int testCgroupGetBlkioIoDeviceServiced(const void *args ATTRIBUTE_UNUSED)
+{
+    virCgroupPtr cgroup = NULL;
+    size_t i;
+    int rv, ret = -1;
+    const long long expected_values0[] = {
+        59542107136,
+        411440480256,
+        4832583,
+        36641903
+    };
+    const long long expected_values1[] = {
+        59542107137,
+        411440480257,
+        4832584,
+        36641904
+    };
+    const char* names[] = {
+        "bytes read",
+        "bytes written",
+        "requests read",
+        "requests written"
+    };
+    long long values[ARRAY_CARDINALITY(expected_values0)];
+
+    if ((rv = virCgroupNewPartition("/virtualmachines", true,
+                                    (1 << VIR_CGROUP_CONTROLLER_BLKIO),
+                                    &cgroup)) < 0) {
+        fprintf(stderr, "Could not create /virtualmachines cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    if ((rv = virCgroupGetBlkioIoDeviceServiced(cgroup,
+                                                FAKEDEVDIR0,
+                                                values, &values[1],
+                                                &values[2], &values[3])) < 0) {
+        fprintf(stderr, "Could not retrieve BlkioIoDeviceServiced for /virtualmachines cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    for (i = 0; i < ARRAY_CARDINALITY(expected_values0); i++) {
+        if (expected_values0[i] != values[i]) {
+            fprintf(stderr,
+                    "Wrong value for %s from virCgroupGetBlkioIoDeviceServiced (expected %lld)\n",
+                    names[i], expected_values0[i]);
+            goto cleanup;
+        }
+    }
+
+    if ((rv = virCgroupGetBlkioIoDeviceServiced(cgroup,
+                                                FAKEDEVDIR1,
+                                                values, &values[1],
+                                                &values[2], &values[3])) < 0) {
+        fprintf(stderr, "Could not retrieve BlkioIoDeviceServiced for /virtualmachines cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    for (i = 0; i < ARRAY_CARDINALITY(expected_values1); i++) {
+        if (expected_values1[i] != values[i]) {
+            fprintf(stderr,
+                    "Wrong value for %s from virCgroupGetBlkioIoDeviceServiced (expected %lld)\n",
+                    names[i], expected_values1[i]);
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    virCgroupFree(&cgroup);
+    return ret;
+}
 
 # define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
 
@@ -549,6 +674,8 @@ mymain(void)
     }
 
     setenv("LIBVIRT_FAKE_SYSFS_DIR", fakesysfsdir, 1);
+    setenv("LIBVIRT_FAKE_DEVICE_DIR0", FAKEDEVDIR0, 1);
+    setenv("LIBVIRT_FAKE_DEVICE_DIR1", FAKEDEVDIR1, 1);
 
     if (virtTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0)
         ret = -1;
@@ -571,6 +698,12 @@ mymain(void)
     if (virtTestRun("Cgroup available", testCgroupAvailable, (void*)0x1) < 0)
         ret = -1;
 
+    if (virtTestRun("virCgroupGetBlkioIoServiced works", testCgroupGetBlkioIoServiced, NULL) < 0)
+        ret = -1;
+
+    if (virtTestRun("virCgroupGetBlkioIoDeviceServiced works", testCgroupGetBlkioIoDeviceServiced, NULL) < 0)
+        ret = -1;
+
     setenv("VIR_CGROUP_MOCK_MODE", "allinone", 1);
     if (virtTestRun("New cgroup for self (allinone)", testCgroupNewForSelfAllInOne, NULL) < 0)
         ret = -1;
-- 
1.8.4




More information about the libvir-list mailing list