static void test_rename(void) { test_caseStart("Testing rename()"); fs_createFile("/newfile","test!"); test_assertCan("/newfile",O_READ); test_assertInt(rename("/newfile","/newerfile"),0); test_assertCanNot("/newfile",O_READ,-ENOENT); test_assertInt(unlink("/newerfile"),0); test_assertCanNot("/newerfile",O_READ,-ENOENT); test_caseSucceeded(); }
static void fs_readFile(const char *name,const char *content) { char buf[100] = {0}; FILE *f = fopen(name,"r"); test_assertTrue(f != NULL); if(f != NULL) { test_assertInt(fseek(f,0,SEEK_END),0); test_assertInt(ftell(f),strlen(content)); rewind(f); test_assertInt(fread(buf,1,strlen(content),f),strlen(content)); test_assertStr(buf,content); fclose(f); } }
static void test_largeFile(void) { /* ensure that the blocksize is not a multiple of this array size */ uint8_t pattern[62]; uint8_t buf[62]; /* reach some double indirect blocks */ const size_t size = 12 * 1024 + 256 * 1024 + 256 * 1024; test_caseStart("Creating a large file and reading it back"); for(size_t i = 0; i < ARRAY_SIZE(pattern); ++i) pattern[i] = i; /* write it */ { FILE *f = fopen("/largefile","w"); test_assertTrue(f != NULL); size_t rem = size; while(rem > 0) { size_t amount = MIN(rem,ARRAY_SIZE(pattern)); test_assertSize(fwrite(pattern,1,amount,f),amount); rem -= amount; } /* flush buffer cache */ test_assertInt(syncfs(fileno(f)),0); fclose(f); } /* read it back */ { FILE *f = fopen("/largefile","r"); test_assertTrue(f != NULL); size_t rem = size; while(rem > 0) { size_t amount = MIN(rem,ARRAY_SIZE(pattern)); test_assertSize(fread(buf,1,amount,f),amount); for(size_t i = 0; i < amount; ++i) test_assertInt(buf[i],pattern[i]); rem -= amount; } fclose(f); } test_assertInt(unlink("/largefile"),0); test_caseSucceeded(); }
static bool test_fileio_checkPrint(int res,int expRes,char *recvStr,const char *expStr) { if(!test_assertStr(recvStr,expStr)) return false; if(!test_assertInt(res,expRes == -1 ? (int)strlen(expStr) : expRes)) return false; return true; }
static void fs_createFile(const char *name,const char *content) { FILE *f = fopen(name,"w"); test_assertTrue(f != NULL); if(f != NULL) { test_assertInt(fwrite(content,1,strlen(content),f),strlen(content)); fclose(f); } }
static bool test_fileio_checkScan(uint recvRes,uint expRes,const char *fmt,...) { va_list ap; char ch; char *rs,*es; uint ru,eu; int rd,ed; if(!test_assertUInt(recvRes,expRes)) return false; va_start(ap,fmt); while((ch = *fmt++)) { if(ch == '%') ch = *fmt++; switch(ch) { /* signed */ case 'c': case 'd': rd = va_arg(ap,int); ed = va_arg(ap,int); if(!test_assertInt(rd,ed)) { va_end(ap); return false; } break; /* unsigned */ case 'x': case 'b': case 'o': case 'u': ru = va_arg(ap,uint); eu = va_arg(ap,uint); if(!test_assertUInt(ru,eu)) { va_end(ap); return false; } break; /* string */ case 's': rs = va_arg(ap,char*); es = va_arg(ap,char*); if(!test_assertStr(rs,es)) { va_end(ap); return false; } break; } } va_end(ap); return true; }
static void test_perms(void) { size_t i; struct stat info; struct { const char *dir; const char *file; } paths[] = { {"/newfile","/newfile/test"}, {"/sys/newfile","/sys/newfile/test"} }; test_caseStart("Testing permissions"); for(i = 0; i < ARRAY_SIZE(paths); i++) { /* create new file */ fs_createFile(paths[i].dir,"foobar"); test_assertInt(chmod(paths[i].dir,0600),0); test_assertInt(chown(paths[i].dir,1,1),0); /* I'm the owner */ RUN_IN_CHILD( test_assertInt(setgid(1),0); test_assertInt(setuid(1),0); test_assertCan(paths[i].dir,O_READ); test_assertCan(paths[i].dir,O_WRITE); ); /* I'm NOT the owner */ RUN_IN_CHILD( test_assertInt(setgid(1),0); test_assertInt(setuid(2),0); test_assertCanNot(paths[i].dir,O_READ,-EACCES); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); );
static void test_qsort(void) { test_caseStart("Testing qsort"); { int ints[] = {}; qsort(ints,ARRAY_SIZE(ints),sizeof(int),intCompare); } { int ints[] = {1,1,1}; qsort(ints,ARRAY_SIZE(ints),sizeof(int),intCompare); test_assertInt(ints[0],1); test_assertInt(ints[1],1); test_assertInt(ints[2],1); } { int ints[] = {1,2,3}; qsort(ints,ARRAY_SIZE(ints),sizeof(int),intCompare); test_assertInt(ints[0],1); test_assertInt(ints[1],2); test_assertInt(ints[2],3); } { int ints[] = {6,7,3,4,2,1,5}; qsort(ints,ARRAY_SIZE(ints),sizeof(int),intCompare); test_assertInt(ints[0],1); test_assertInt(ints[1],2); test_assertInt(ints[2],3); test_assertInt(ints[3],4); test_assertInt(ints[4],5); test_assertInt(ints[5],6); test_assertInt(ints[6],7); } { const char *strs[] = { "m3/m3-11.png", "m3/m3-03.png", "m3/m3-09.png", "m3/m3-20.png", "m3/m3-22.png", "m3/m3-17.png", "m3/m3-24.png", "m3/m3-12.png", "m3/m3-04.png", "m3/m3-23.png", "m3/m3-18.png", "m3/m3-01.png", "m3/m3-28.png", "m3/m3-14.png", "m3/m3-07.png", "m3/m3-26.png", "m3/m3-00.png", "m3/m3-05.png", "m3/m3-21.png", "m3/m3-16.png", "m3/m3-25.png", "m3/m3-08.png", "m3/m3-10.png", "m3/m3-02.png", "m3/m3-19.png", "m3/m3-06.png", "m3/m3-13.png", "m3/m3-15.png", "m3/m3-27.png", }; qsort(strs,ARRAY_SIZE(strs),sizeof(int),strCompare); for(size_t i = 0; i < ARRAY_SIZE(strs); ++i) { const char *sno = strs[i] + SSTRLEN("m3/m3-"); int no = atoi(sno); test_assertInt(no,i); } } test_caseSucceeded(); }
static void test_basics(void) { struct stat info1; struct stat info2; test_caseStart("Testing fs"); test_assertInt(mkdir("/newdir",DIR_DEF_MODE),0); fs_createFile("/newdir/file1","foobar"); fs_readFile("/newdir/file1","foobar"); test_assertInt(link("/newdir/file1","/newdir/file2"),0); test_assertInt(stat("/newdir/file1",&info1),0); test_assertInt(stat("/newdir/file2",&info2),0); // compare elements individually, because the structs might contain uninitialized padding test_assertUInt(info1.st_atime,info2.st_atime); test_assertUInt(info1.st_mtime,info2.st_mtime); test_assertUInt(info1.st_ctime,info2.st_ctime); test_assertUInt(info1.st_blocks,info2.st_blocks); test_assertUInt(info1.st_blksize,info2.st_blksize); test_assertUInt(info1.st_dev,info2.st_dev); test_assertUInt(info1.st_uid,info2.st_uid); test_assertUInt(info1.st_gid,info2.st_gid); test_assertUInt(info1.st_ino,info2.st_ino); test_assertUInt(info1.st_nlink,info2.st_nlink); test_assertUInt(info1.st_mode,info2.st_mode); test_assertUInt(info1.st_size,info2.st_size); test_assertUInt(info1.st_nlink,2); test_assertInt(unlink("/newdir/file1"),0); test_assertInt(rmdir("/newdir"),-ENOTEMPTY); test_assertInt(stat("/newdir/file1",&info1),-ENOENT); test_assertInt(stat("/newdir/file2",&info2),0); test_assertUInt(info2.st_nlink,1); test_assertInt(unlink("/newdir/file2"),0); test_assertInt(rmdir("/newdir"),0); int fd = open("/",O_RDONLY); test_assertTrue(fd >= 0); test_assertInt(syncfs(fd),0); close(fd); test_caseSucceeded(); }
static void test_perms(void) { size_t i; struct stat info; struct { const char *dir; const char *file; } paths[] = { {"/newfile","/newfile/test"}, {"/sys/newfile","/sys/newfile/test"} }; test_caseStart("Testing permissions"); for(i = 0; i < ARRAY_SIZE(paths); i++) { /* create new file */ fs_createFile(paths[i].dir,"foobar"); test_assertInt(chmod(paths[i].dir,0600),0); test_assertInt(chown(paths[i].dir,1,1),0); /* I'm the owner */ test_assertInt(setegid(1),0); test_assertInt(seteuid(1),0); test_assertCan(paths[i].dir,O_READ); test_assertCan(paths[i].dir,O_WRITE); /* I'm NOT the owner */ test_assertInt(seteuid(0),0); test_assertInt(seteuid(2),0); test_assertCanNot(paths[i].dir,O_READ,-EACCES); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); /* give group read-perm */ test_assertInt(seteuid(0),0); test_assertInt(chmod(paths[i].dir,0640),0); test_assertInt(seteuid(2),0); test_assertCan(paths[i].dir,O_READ); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); /* neither owner nor group */ test_assertInt(seteuid(0),0); test_assertInt(setegid(0),0); test_assertInt(setegid(2),0); test_assertInt(seteuid(2),0); test_assertCanNot(paths[i].dir,O_READ,-EACCES); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); /* give others read+write perm */ test_assertInt(seteuid(0),0); test_assertInt(chmod(paths[i].dir,0646),0); test_assertInt(seteuid(2),0); test_assertCan(paths[i].dir,O_READ); test_assertCan(paths[i].dir,O_WRITE); /* delete it */ test_assertInt(seteuid(0),0); test_assertInt(unlink(paths[i].dir),0); /* create new folder */ test_assertInt(mkdir(paths[i].dir,DIR_DEF_MODE),0); test_assertInt(chmod(paths[i].dir,0700),0); test_assertInt(chown(paths[i].dir,1,1),0); /* I'm the owner */ test_assertInt(setegid(1),0); test_assertInt(seteuid(1),0); test_assertCan(paths[i].dir,O_READ); test_assertCan(paths[i].dir,O_WRITE); fs_createFile(paths[i].file,"foo"); test_assertInt(stat(paths[i].file,&info),0); /* I'm NOT the owner */ test_assertInt(seteuid(0),0); test_assertInt(seteuid(2),0); test_assertCanNot(paths[i].dir,O_READ,-EACCES); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); test_assertInt(stat(paths[i].file,&info),-EACCES); /* give group read-perm */ test_assertInt(seteuid(0),0); test_assertInt(chmod(paths[i].dir,0740),0); test_assertInt(seteuid(2),0); test_assertCan(paths[i].dir,O_READ); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); test_assertInt(stat(paths[i].file,&info),-EACCES); /* neither owner nor group */ test_assertInt(seteuid(0),0); test_assertInt(setegid(0),0); test_assertInt(setegid(2),0); test_assertInt(seteuid(2),0); test_assertCanNot(paths[i].dir,O_READ,-EACCES); test_assertCanNot(paths[i].dir,O_WRITE,-EACCES); test_assertInt(stat(paths[i].file,&info),-EACCES); /* give others read+write perm */ test_assertInt(seteuid(0),0); test_assertInt(chmod(paths[i].dir,0747),0); test_assertInt(seteuid(2),0); test_assertCan(paths[i].dir,O_READ); test_assertCan(paths[i].dir,O_WRITE); test_assertInt(stat(paths[i].file,&info),0); /* delete it */ test_assertInt(seteuid(0),0); test_assertInt(unlink(paths[i].file),0); test_assertInt(rmdir(paths[i].dir),0); } test_caseSucceeded(); }
static void test_basics(void) { struct stat info1; struct stat info2; test_caseStart("Testing fs"); test_assertInt(mkdir("/newdir",DIR_DEF_MODE),0); fs_createFile("/newdir/file1","foobar"); fs_readFile("/newdir/file1","foobar"); test_assertInt(link("/newdir/file1","/newdir/file2"),0); test_assertInt(stat("/newdir/file1",&info1),0); test_assertInt(stat("/newdir/file2",&info2),0); test_assertInt(memcmp(&info1,&info2,sizeof(struct stat)),0); test_assertUInt(info1.st_nlink,2); test_assertInt(unlink("/newdir/file1"),0); test_assertInt(rmdir("/newdir"),-ENOTEMPTY); test_assertInt(stat("/newdir/file1",&info1),-ENOENT); test_assertInt(stat("/newdir/file2",&info2),0); test_assertUInt(info2.st_nlink,1); test_assertInt(unlink("/newdir/file2"),0); test_assertInt(rmdir("/newdir"),0); int fd = open("/",O_RDONLY); test_assertTrue(fd >= 0); test_assertInt(syncfs(fd),0); close(fd); test_caseSucceeded(); }
static void test_assertCanNot(const char *path,uint mode,int err) { test_assertInt(open(path,mode),err); }