minix/test/testvm.c
Ben Gras 32a4e0d84d many new tests
. test70: regression test for m_out vfs race condition

The following tests use testcache.c to generate test i/o
patterns, generate random write data and verify the reads.

	. test71: blackbox full-stack test of FS operation, testing
	  using the regular VFS interface crazy i/o patterns
	  with various working set sizes, triggering only
	  primary cache, also secondary cache, and finally
	  disk i/o and verifying contents all the time
	. test72: unit test of libminixfs, implementing
	  functions it needs from -lsys and -lblockdriver
	  and the client in order to simulate a working
	  cache client and backend environment.
	. test73: blackbox test of secondary vm cache in isolation

Change-Id: I1287e9753182b8719e634917ad158e3c1e079ceb
2013-04-19 16:21:48 +00:00

172 lines
3.1 KiB
C

/* testvm - service-started code that goes with test73.o
*/
#include <minix/drivers.h>
#include <minix/chardriver.h>
#include <minix/ds.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "testvm.h"
#include "common.h"
#include "testcache.h"
static char *pipefilename = NULL, *progname;
int pipefd = -1;
int memfd;
static char *bdata = NULL;
int dowriteblock(int b, int blocksize, u32_t seed, char *block)
{
int r;
r=vm_yield_block_get_block(VM_BLOCKID_NONE, b, bdata, blocksize);
if(r != OK && r != ESRCH) {
printf("dowriteblock: vm_yield_block_get_block get %d\n", r);
exit(1);
}
memcpy(bdata, block, blocksize);
r=vm_yield_block_get_block(b, VM_BLOCKID_NONE, bdata, blocksize);
if(r != OK) {
printf("dowriteblock: vm_yield_block_get_block yield %d\n", r);
exit(1);
}
return blocksize;
}
int readblock(int b, int blocksize, u32_t seed, char *block)
{
int r;
r=vm_yield_block_get_block(VM_BLOCKID_NONE, b, bdata, blocksize);
if(r == ESRCH) {
return OK_BLOCK_GONE;
}
if(r != OK) {
printf("readblock: vm_yield_block_get_block get %d\n", r);
exit(1);
}
memcpy(block, bdata, blocksize);
r=vm_yield_block_get_block(b, VM_BLOCKID_NONE, bdata, blocksize);
if(r != OK) {
printf("readblock: vm_yield_block_get_block yield %d\n", r);
exit(1);
}
return blocksize;
}
void testend(void) { vm_forgetblocks(); }
static void
writepipe(struct info *i)
{
if(write(pipefd, i, sizeof(*i)) != sizeof(*i)) {
printf("%s: pipe write failed\n", progname);
exit(1);
}
}
static int
testinit(void)
{
struct stat st;
int attempts = 0;
for(attempts = 0; attempts < 5 && pipefd < 0; attempts++) {
if(attempts > 0) sleep(1);
pipefd = open(pipefilename, O_WRONLY | O_NONBLOCK);
}
if(pipefd < 0) {
printf("%s: could not open pipe %s, errno %d\n",
progname, pipefilename, errno);
exit(1);
}
if(fstat(pipefd, &st) < 0) {
printf("%s: could not fstat pipe %s\n", progname, pipefilename);
exit(1);
}
if(!(st.st_mode & I_NAMED_PIPE)) {
printf("%s: file %s is not a pipe\n", progname, pipefilename);
exit(1);
}
return OK;
}
static int
sef_cb_init(int type, sef_init_info_t *UNUSED(info))
{
return OK;
}
static void
init(void)
{
/* SEF init */
sef_setcb_init_fresh(sef_cb_init);
sef_setcb_init_lu(sef_cb_init);
sef_setcb_init_restart(sef_cb_init);
sef_startup();
}
int
main(int argc, char *argv[])
{
struct info info;
int big;
u32_t totalmem, freemem, cachedmem;
progname = argv[0];
if(argc < 2) { printf("no args\n"); return 1; }
pipefilename=argv[1];
big = !!strstr(pipefilename, "big");
init();
info.result = time(NULL);
if(testinit() != OK) { printf("%s: testinit failed\n", progname); return 1; }
cachequiet(!big);
if(!(bdata = alloc_contig(PAGE_SIZE, 0, NULL))) {
printf("could not allocate block\n");
exit(1);
}
if(dotest(PAGE_SIZE, 10, 3)) { e(11); exit(1); }
if(dotest(PAGE_SIZE, 1000, 3)) { e(11); exit(1); }
if(dotest(PAGE_SIZE, 50000, 3)) { e(11); exit(1); }
if(big) {
getmem(&totalmem, &freemem, &cachedmem);
if(dotest(PAGE_SIZE, totalmem*1.5, 3)) { e(11); exit(1); }
}
info.result = 0;
writepipe(&info);
return 0;
}