The current override for the contents of meminfo via a replacement
read_meminfo will not work now that these functions are in a library.
Switch to overriding the files returned from open by overriding that
instead.  This is actually a superior way to test as it also allows us
to test the library implementation of read_meminfo.

Signed-off-by: Andy Whitcroft <[EMAIL PROTECTED]>
---
 tests/gethugepagesizes.c |  187 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 151 insertions(+), 36 deletions(-)

diff --git a/tests/gethugepagesizes.c b/tests/gethugepagesizes.c
index 0cd97ed..8e61c50 100644
--- a/tests/gethugepagesizes.c
+++ b/tests/gethugepagesizes.c
@@ -26,16 +26,21 @@
 #include <dlfcn.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
 #include <hugetlbfs.h>
 
 #include "hugetests.h"
 
-#define REAL_SYSFS_DIR "/sys/kernel/mm/hugepages/"
+int faked_data = 0;
 char fake_sysfs[] = "/tmp/sysfs-XXXXXX";
+char fake_meminfo[] = "/tmp/meminfo-XXXXXX";
+
+#define REAL_SYSFS_DIR "/sys/kernel/mm/hugepages/"
 DIR *(*real_opendir)(const char *name);
-int cleanup_dir = 0;
 
-long (*real_read_meminfo)(const char *tag);
+int (*real_open)(const char *name, int flags, int mode);
+
 enum {
        OVERRIDE_OFF,           /* Pass-through to real function */
        OVERRIDE_ON,            /* Ovewrride with local function */
@@ -61,7 +66,7 @@ DIR *opendir(const char *name)
                return real_opendir(name);
        case OVERRIDE_ON:
                /* Only safe to override of fake_sysfs was set up */
-               if (cleanup_dir)
+               if (faked_data)
                        return real_opendir(fake_sysfs);
                else
                        FAIL("Trying to override opendir before initializing "
@@ -75,32 +80,53 @@ DIR *opendir(const char *name)
 #define HPAGE_SIZE (16 * 1024)
 
 /*
- * Override read_meminfo to simulate various conditions
+ * Override open to simulate various contents for meminfo
  */
-long read_meminfo(const char *tag)
+int open(const char *file, int flags, ...)
 {
-       if (!real_read_meminfo)
-               real_read_meminfo = dlsym(RTLD_NEXT, "read_meminfo");
+       int mode = 0;
+       if (flags & O_CREAT) {
+               va_list arg;
+               va_start(arg, flags);
+               mode = va_arg(arg, int);
+               va_end(arg);
+       }
 
-       /* Only override calls that check the page size */
-       if (strcmp(tag, "Hugepagesize:"))
-               return real_read_meminfo(tag);
+       if (!real_open)
+               real_open = dlsym(RTLD_NEXT, "open");
 
        switch (meminfo_state) {
-               case OVERRIDE_OFF:      return real_read_meminfo(tag);
-               case OVERRIDE_ON:       return HPAGE_SIZE;
-               default:                return -1;
+               case OVERRIDE_OFF:
+                       break;
+               case OVERRIDE_ON: {
+                       char fname[PATH_MAX];
+                       sprintf(fname, "%s/meminfo-hugepages", fake_meminfo);
+                       file = fname;
+                       break;
+               }
+               case OVERRIDE_MISSING: {
+                       char fname[PATH_MAX];
+                       sprintf(fname, "%s/meminfo-none", fake_meminfo);
+                       file = fname;
+                       break;
+               }
+               default:
+                       return -1;
        }
+       return real_open(file, flags, mode);
 }
 
-void cleanup_fake_sysfs(void)
+void cleanup_fake_data(void)
 {
        DIR *dir;
        struct dirent *ent;
        char fname[PATH_MAX+1];
 
-       cleanup_dir = 0;
-       dir = real_opendir(fake_sysfs);
+       meminfo_state = OVERRIDE_OFF;
+       sysfs_state = OVERRIDE_OFF;
+
+       faked_data = 0;
+       dir = opendir(fake_sysfs);
        if (!dir)
                FAIL("opendir %s: %s", fake_sysfs, strerror(errno));
 
@@ -115,19 +141,72 @@ void cleanup_fake_sysfs(void)
        closedir(dir);
        if (rmdir(fake_sysfs))
                FAIL("rmdir %s: %s", fake_sysfs, strerror(errno));
+
+       sprintf(fname, "%s/meminfo-none", fake_meminfo);
+       if (unlink(fname) < 0)
+               FAIL("unlink %s: %s", fname, strerror(errno));
+       sprintf(fname, "%s/meminfo-hugepages", fake_meminfo);
+       if (unlink(fname) < 0)
+               FAIL("unlink %s: %s", fname, strerror(errno));
+       if (rmdir(fake_meminfo))
+               FAIL("rmdir %s: %s", fake_meminfo, strerror(errno));
 }
 
-void setup_fake_sysfs(long sizes[], int n_elem)
+char *meminfo_base = "\
+MemTotal:      4004132 kB\n\
+MemFree:       3563748 kB\n\
+Buffers:         34804 kB\n\
+Cached:         252544 kB\n\
+SwapCached:          0 kB\n\
+Active:         108912 kB\n\
+Inactive:       187420 kB\n\
+SwapTotal:     8008392 kB\n\
+SwapFree:      8008392 kB\n\
+Dirty:               4 kB\n\
+Writeback:           0 kB\n\
+AnonPages:        9100 kB\n\
+Mapped:           7908 kB\n\
+Slab:            40212 kB\n\
+SReclaimable:    33312 kB\n\
+SUnreclaim:       6900 kB\n\
+PageTables:       1016 kB\n\
+NFS_Unstable:        0 kB\n\
+Bounce:              0 kB\n\
+WritebackTmp:        0 kB\n\
+CommitLimit:   9974616 kB\n\
+Committed_AS:    29616 kB\n\
+VmallocTotal: 34359738367 kB\n\
+VmallocUsed:     23760 kB\n\
+VmallocChunk: 34359714543 kB\n\
+";
+
+char *meminfo_huge = "\
+HugePages_Total:    35\n\
+HugePages_Free:     35\n\
+HugePages_Rsvd:      0\n\
+HugePages_Surp:      0\n\
+Hugepagesize:     2048 kB\n\
+";
+
+void setup_fake_data(long sizes[], int n_elem)
 {
+       int old_meminfo_state = meminfo_state;
+       int old_sysfs_state = sysfs_state;
+
        int i;
        char fname[PATH_MAX+1];
+       int fd;
 
-       if (cleanup_dir)
-               cleanup_fake_sysfs();
+       meminfo_state = OVERRIDE_OFF;
+       sysfs_state = OVERRIDE_OFF;
+
+       if (faked_data)
+               cleanup_fake_data();
 
+       /* Generate some fake sysfs data. */
        if (!mkdtemp(fake_sysfs))
                FAIL("mkdtemp: %s", strerror(errno));
-       cleanup_dir = 1;
+       faked_data = 1;
 
        for (i = 0; i < n_elem; i++) {
                snprintf(fname, PATH_MAX, "%s/hugepages-%lukB", fake_sysfs,
@@ -135,12 +214,42 @@ void setup_fake_sysfs(long sizes[], int n_elem)
                if (mkdir(fname, 0700))
                        FAIL("mkdir %s: %s", fname, strerror(errno));
        }
+
+       /* Generate fake meminfo data. */
+       if (!mkdtemp(fake_meminfo))
+               FAIL("mkdtemp: %s", strerror(errno));
+
+       sprintf(fname, "%s/meminfo-none", fake_meminfo);
+       fd = open(fname, O_WRONLY|O_CREAT);
+       if (fd < 0)
+               FAIL("open: %s", strerror(errno));
+       if (write(fd, meminfo_base,
+                       strlen(meminfo_base)) != strlen(meminfo_base))
+               FAIL("write: %s", strerror(errno));
+       if (close(fd) < 0)
+               FAIL("close: %s", strerror(errno));
+
+       sprintf(fname, "%s/meminfo-hugepages", fake_meminfo);
+       fd = open(fname, O_WRONLY|O_CREAT);
+       if (fd < 0)
+               FAIL("open: %s", strerror(errno));
+       if (write(fd, meminfo_base,
+                       strlen(meminfo_base)) != strlen(meminfo_base))
+               FAIL("write: %s", strerror(errno));
+       if (write(fd, meminfo_huge,
+                       strlen(meminfo_huge)) != strlen(meminfo_huge))
+               FAIL("write: %s", strerror(errno));
+       if (close(fd) < 0)
+               FAIL("close: %s", strerror(errno));
+
+       meminfo_state = old_meminfo_state;
+       sysfs_state = old_sysfs_state;
 }
 
 void cleanup(void)
 {
-       if (cleanup_dir)
-               cleanup_fake_sysfs();
+       if (faked_data)
+               cleanup_fake_data();
 }
 
 void validate_sizes(int line, long actual_sizes[], int actual, int max_actual,
@@ -159,6 +268,14 @@ void validate_sizes(int line, long actual_sizes[], int 
actual, int max_actual,
                        FAIL("Line %i: Expected size %li not found in actual "
                                "results", line, expected_sizes[i]);
        }
+       for (i = 0; i < actual; i++) {
+               for (j = 0; j < expected; j++)
+                       if (actual_sizes[i] == expected_sizes[j])
+                               break;
+               if (j >= expected)
+                       FAIL("Line %i: Actual size %li not found in expected "
+                               "results", line, expected_sizes[i]);
+       }
 
        for (i = expected; i < max_actual; i++)
                if (actual_sizes[i] != 42)
@@ -188,7 +305,7 @@ void validate_sizes(int line, long actual_sizes[], int 
actual, int max_actual,
 
 int main(int argc, char *argv[])
 {
-       long expected_sizes[MAX], actual_sizes[MAX], meminfo_size;
+       long expected_sizes[MAX], actual_sizes[MAX];
        long base_size = sysconf(_SC_PAGESIZE);
 
        test_init(argc, argv);
@@ -217,39 +334,37 @@ int main(int argc, char *argv[])
         * ===
         */
 
+       INIT_LIST(expected_sizes, 2048 * 1024, 1024 * 1024, 64 * 1024);
+       setup_fake_data(expected_sizes, 3);
+
        /*
         * Check handling when /proc/meminfo indicates no huge page support
+        * and the sysfs heirachy is not present.
         */
        meminfo_state = OVERRIDE_MISSING;
+       sysfs_state = OVERRIDE_MISSING;
 
        EXPECT_SIZES(gethugepagesizes, MAX, 0, expected_sizes);
 
        INIT_LIST(expected_sizes, base_size);
        EXPECT_SIZES(getpagesizes, MAX, 1, expected_sizes);
 
-       /*
-        * When the sysfs heirarchy is not present ...
-        */
-       sysfs_state = OVERRIDE_MISSING;
-
        /* ... only the meminfo size is returned. */
        meminfo_state = OVERRIDE_ON;
-       meminfo_size = read_meminfo("Hugepagesize:") * 1024;
 
-       INIT_LIST(expected_sizes, meminfo_size);
+       INIT_LIST(expected_sizes, 2048 * 1024);
        EXPECT_SIZES(gethugepagesizes, MAX, 1, expected_sizes);
 
-       INIT_LIST(expected_sizes, base_size, meminfo_size);
+       INIT_LIST(expected_sizes, base_size, 2048 * 1024);
        EXPECT_SIZES(getpagesizes, MAX, 2, expected_sizes);
 
        /*
         * When sysfs defines additional sizes ...
         */
-       INIT_LIST(expected_sizes, meminfo_size, 1024 * 1024, 2048 * 1024);
-
-       setup_fake_sysfs(expected_sizes, 3);
        sysfs_state = OVERRIDE_ON;
 
+       INIT_LIST(expected_sizes, 2048 * 1024, 1024 * 1024, 64 * 1024);
+
        /* ... make sure all sizes are returned without duplicates */
        /* ... while making sure we do not overstep our limit */
        EXPECT_SIZES(gethugepagesizes, MAX, 3, expected_sizes);
@@ -259,7 +374,7 @@ int main(int argc, char *argv[])
        EXPECT_SIZES(gethugepagesizes, 4, 3, expected_sizes);
 
        INIT_LIST(expected_sizes,
-                       base_size, meminfo_size, 1024 * 1024, 2048 * 1024);
+                       base_size, 2048 * 1024, 1024 * 1024, 64 * 1024);
        EXPECT_SIZES(getpagesizes, MAX, 4, expected_sizes);
        EXPECT_SIZES(getpagesizes, 1, 4, expected_sizes);
        EXPECT_SIZES(getpagesizes, 2, 4, expected_sizes);
-- 
1.6.0.2.711.gf1ba4


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to