. 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
		
			
				
	
	
		
			132 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Test 71 - full hierachy storage test.
 | 
						|
 *
 | 
						|
 * Black box test of storage: test consistent file contents
 | 
						|
 * under various working sets and access patterns.
 | 
						|
 *
 | 
						|
 * Using varying working set sizes, exercise various cache
 | 
						|
 * layers separately.
 | 
						|
 *
 | 
						|
 * There is a 'smoke test' mode, suitable for running interactively,
 | 
						|
 * and a 'regression test' (big) mode, meant for batch invocation only
 | 
						|
 * as it takes very long.
 | 
						|
 */
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/ioc_memory.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <assert.h>
 | 
						|
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <fcntl.h>
 | 
						|
 | 
						|
#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)
 | 
						|
{
 | 
						|
	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;
 | 
						|
 | 
						|
	get_fd_offset(b, blocksize, &offset, &fd);
 | 
						|
 | 
						|
	if(pread(fd, data, blocksize, offset) < blocksize) {
 | 
						|
		perror("pread");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	return blocksize;
 | 
						|
}
 | 
						|
 | 
						|
void testend(void) { }
 | 
						|
 | 
						|
int
 | 
						|
main(int argc, char *argv[])
 | 
						|
{
 | 
						|
	int f, big = !!getenv(BIGVARNAME), iter = 2;
 | 
						|
 | 
						|
	start(71);
 | 
						|
 | 
						|
	cachequiet(!big);
 | 
						|
	if(big) 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);
 | 
						|
	}
 | 
						|
 | 
						|
	/* 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(big) {
 | 
						|
		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;
 | 
						|
}
 | 
						|
 |