diff --git a/test/Makefile b/test/Makefile index 7d4762dc4..87ee03dd6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -34,6 +34,7 @@ OBJS.test57= test57loop.o # Cache testing programs OBJS.test71+= testcache.o OBJS.test72+= testcache.o +OBJS.test74+= testcache.o LDADD.test72+= -lminixfs PROGS += testvm @@ -47,7 +48,7 @@ MINIX_TESTS= \ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \ 41 42 43 44 45 46 48 49 50 52 53 54 55 56 58 59 60 \ -61 64 65 66 67 68 69 70 71 72 73 +61 64 65 66 67 68 69 70 71 72 73 74 .if ${MACHINE_ARCH} == "i386" MINIX_TESTS+= \ diff --git a/test/common.c b/test/common.c index ca6725843..d0bebb75b 100644 --- a/test/common.c +++ b/test/common.c @@ -13,8 +13,7 @@ #include "common.h" int common_test_nr = -1, errct = 0, subtest; - -int quietflag = 1; +int quietflag = 1, bigflag = 0; /* provide a default max_error symbol as Max_error with a value * of 5. The test program can override it wit its own max_error @@ -30,6 +29,11 @@ int test_nr; char buf[64]; int i; + /* if this variable is set, specify to tests we are running + * in 'overnight' mode + */ + bigflag = !!getenv(BIGVARNAME); + common_test_nr = test_nr; printf("Test %2d ", test_nr); fflush(stdout); /* since stdout is probably line buffered */ diff --git a/test/test71.c b/test/test71.c index 94b7b4b42..954b972c8 100644 --- a/test/test71.c +++ b/test/test71.c @@ -23,32 +23,6 @@ #include "common.h" #include "testcache.h" -/* we want to flexibly split this test over multiple files - * - for big working sets we might run over the 2GB MFS file limit - * - we might want to test the FS being able to handle lots of - * files / unusual metadata situations - */ -#define MBPERFILE 100 -#define MB (1024*1024) -#define MAXFILES ((u64_t) MAXBLOCKS * MAXBLOCKSIZE / MB / MBPERFILE + 1) - -static int fds[MAXFILES]; - -static void -get_fd_offset(int b, int blocksize, u64_t *file_offset, int *fd) -{ - u64_t offset = (u64_t) b * blocksize; - int filenumber; - - filenumber = offset / MB / MBPERFILE; - - assert(filenumber >= 0 && filenumber < MAXFILES); - assert(fds[filenumber] > 0); - - *fd = fds[filenumber]; - *file_offset = offset - (filenumber * MBPERFILE * MB); -} - int dowriteblock(int b, int blocksize, u32_t seed, char *data) { @@ -86,19 +60,14 @@ void testend(void) { } int main(int argc, char *argv[]) { - int f, big = !!getenv(BIGVARNAME), iter = 2; + int iter = 2; start(71); - cachequiet(!big); - if(big) iter = 3; + cachequiet(!bigflag); + if(bigflag) iter = 3; - for(f = 0; f < MAXFILES; f++) { - char tempfilename[] = "cachetest.XXXXXXXX"; - fds[f] = mkstemp(tempfilename); - if(fds[f] < 0) { perror("mkstemp"); e(20); return 1; } - assert(fds[f] > 0); - } + makefiles(MAXFILES); /* Try various combinations working set sizes * and block sizes in order to specifically @@ -112,18 +81,13 @@ main(int argc, char *argv[]) if(dotest(PAGE_SIZE*3, 100, iter)) e(3); if(dotest(PAGE_SIZE, 20000, iter)) e(5); - if(big) { + if(bigflag) { u32_t totalmem, freemem, cachedmem; if(dotest(PAGE_SIZE, 150000, iter)) e(5); getmem(&totalmem, &freemem, &cachedmem); if(dotest(PAGE_SIZE, totalmem*1.5, iter)) e(6); } - for(f = 0; f < MAXFILES; f++) { - assert(fds[f] > 0); - close(fds[f]); - } - quit(); return 0; diff --git a/test/test74.c b/test/test74.c new file mode 100644 index 000000000..8ccdaaaa0 --- /dev/null +++ b/test/test74.c @@ -0,0 +1,113 @@ +/* Test 74 - mmap functionality test. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "testcache.h" + +int +dowriteblock(int b, int blocksize, u32_t seed, char *data) +{ + u64_t offset; + int fd; + + get_fd_offset(b, blocksize, &offset, &fd); + + if(pwrite(fd, data, blocksize, offset) < blocksize) { + perror("pwrite"); + return -1; + } + + return blocksize; +} + +int +readblock(int b, int blocksize, u32_t seed, char *data) +{ + u64_t offset; + int fd; + char *mmapdata; + int pread_first = random() % 2; + + get_fd_offset(b, blocksize, &offset, &fd); + + if(pread_first) { + if(pread(fd, data, blocksize, offset) < blocksize) { + perror("pread"); + return -1; + } + } + + if((mmapdata = minix_mmap(NULL, blocksize, PROT_READ, MAP_PRIVATE | MAP_FILE, + fd, offset)) == MAP_FAILED) { + perror("mmap"); + return -1; + } + + if(!pread_first) { + if(pread(fd, data, blocksize, offset) < blocksize) { + perror("pread"); + return -1; + } + } + + if(memcmp(mmapdata, data, blocksize)) { + fprintf(stderr, "readblock: mmap, pread mismatch\n"); + return -1; + } + + if(minix_munmap(mmapdata, blocksize) < 0) { + perror("munmap"); + return -1; + } + + return blocksize; +} + +void testend(void) { } + +int +main(int argc, char *argv[]) +{ + int iter = 2; + + start(74); + + makefiles(MAXFILES); + + cachequiet(!bigflag); + if(bigflag) iter = 3; + + /* Try various combinations working set sizes + * and block sizes in order to specifically + * target the primary cache, then primary+secondary + * cache, then primary+secondary cache+secondary + * cache eviction. + */ + + if(dotest(PAGE_SIZE, 100, iter)) e(5); + if(dotest(PAGE_SIZE*2, 100, iter)) e(2); + if(dotest(PAGE_SIZE*3, 100, iter)) e(3); + if(dotest(PAGE_SIZE, 20000, iter)) e(5); + + if(bigflag) { + u32_t totalmem, freemem, cachedmem; + if(dotest(PAGE_SIZE, 150000, iter)) e(5); + getmem(&totalmem, &freemem, &cachedmem); + if(dotest(PAGE_SIZE, totalmem*1.5, iter)) e(6); + } + + quit(); + + return 0; +} + diff --git a/test/testcache.c b/test/testcache.c index b25141a27..e58925067 100644 --- a/test/testcache.c +++ b/test/testcache.c @@ -23,6 +23,8 @@ extern int quietflag; +int fds[MAXFILES]; + static void genblock(int b, char *blockdata, int blocksize, u32_t seed) { @@ -210,6 +212,37 @@ dotest(int blocksize, int nblocks, int iterations) return 0; } +void +get_fd_offset(int b, int blocksize, u64_t *file_offset, int *fd) +{ + u64_t offset = (u64_t) b * blocksize; + int filenumber; + + filenumber = offset / MB / MBPERFILE; + + assert(filenumber >= 0 && filenumber < MAXFILES); + assert(fds[filenumber] > 0); + + *fd = fds[filenumber]; + *file_offset = offset - (filenumber * MBPERFILE * MB); +} + +void +makefiles(int n) +{ + int f; + for(f = 0; f < n; f++) { + char tempfilename[] = "cachetest.XXXXXXXX"; + fds[f] = mkstemp(tempfilename); + if(fds[f] < 0) { + perror("mkstemp"); + fprintf(stderr, "mkstemp %d/%d failed\n", f, n); + exit(1); + } + assert(fds[f] > 0); + } +} + void cachequiet(int quiet) { quietflag = quiet; diff --git a/test/testcache.h b/test/testcache.h index de735f6ae..01ad939db 100644 --- a/test/testcache.h +++ b/test/testcache.h @@ -14,5 +14,21 @@ int readblock(int b, int blocksize, u32_t seed, char *block); void testend(void); int dotest(int blocksize, int nblocks, int iterations); void cachequiet(int quiet); +void get_fd_offset(int b, int blocksize, u64_t *file_offset, int *fd); +void makefiles(int n); #define OK_BLOCK_GONE -999 + +/* for file-oriented tests: + * + * we want to flexibly split tests over multiple files + * - for big working sets we might run over the 2GB MFS file limit + * - we might want to test the FS being able to handle lots of + * files / unusual metadata situations + */ +#define MBPERFILE 2000 +#define MB (1024*1024) +#define MAXFILES ((u64_t) MAXBLOCKS * MAXBLOCKSIZE / MB / MBPERFILE + 1) + +extern int fds[MAXFILES], bigflag; +