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 void test_dirname(void) { struct DirnameTest { const char *input; const char *expected; } tests[] = { {NULL,"."}, {"","."}, {"/","/"}, {".","."}, {"..","."}, {"a","."}, {"foo","."}, {"/foo/bar","/foo"}, {"/foo/bar/","/foo"}, {"/foo/bar///","/foo"}, {"/a/","/"}, {"abc///","."}, {"abc//def///","abc"}, {"abc/def/.","abc/def"}, }; test_caseStart("Testing dirname"); for(size_t i = 0; i < ARRAY_SIZE(tests); ++i) { char *cpy = tests[i].input ? strdup(tests[i].input) : NULL; test_assertTrue(tests[i].input == NULL || cpy != NULL); test_assertStr(dirname(cpy),tests[i].expected); free(cpy); } test_caseSucceeded(); }
static void test_1(void) { ulong x = 0x100; size_t i,len,oldFree; bool res = true; sSLList *list; test_caseStart("Append & check & remove index 0"); oldFree = heapspace(); list = sll_create(); for(i = 0; i < 20; i++) { sll_append(list,(void*)x++); } x = 0x100; for(i = 0; i < 20; i++) { if(sll_get(list,i) != (void*)x++) { res = false; break; } } if(res) { for(i = 0; i < 20; i++) { sll_removeIndex(list,0); } } test_assertTrue(res); len = sll_length(list); test_assertSSize(len,0); sll_destroy(list,false); test_assertSize(heapspace(),oldFree); test_caseSucceeded(); }
static void test_6(void) { ulong x = 0x100; size_t i,oldFree; sSLList *list; bool res = true; test_caseStart("Create & append & set somewhere & destroy"); oldFree = heapspace(); list = sll_create(); for(i = 0; i < 5; i++) { sll_append(list,(void*)x++); } sll_set(list,(void*)0x200,3); if(sll_get(list,3) != (void*)0x200) res = false; sll_set(list,(void*)0x201,2); if(sll_get(list,2) != (void*)0x201) res = false; sll_set(list,(void*)0x202,1); if(sll_get(list,1) != (void*)0x202) res = false; sll_set(list,(void*)0x203,0); if(sll_get(list,0) != (void*)0x203) res = false; sll_set(list,(void*)0x204,4); if(sll_get(list,4) != (void*)0x204) res = false; if(sll_length(list) != 5) res = false; sll_destroy(list,false); test_assertTrue(res); test_assertSize(heapspace(),oldFree); 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 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 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_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_errors(void) { const char *errors[] = { "", ":root:0", ":::", "0:::" }; size_t i,count,oldFree; test_caseStart("Testing errors"); for(i = 0; i < ARRAY_SIZE(errors); i++) { sGroup *g; oldFree = heapspace(); g = group_parse(errors[i],&count); test_assertTrue(g == NULL); test_assertSize(heapspace(),oldFree); } test_caseSucceeded(); }
static void test_regunsave0(void) { static octa specials[SPECIAL_NUM]; static octa locals[LREG_NUM]; static octa globals[GREG_NUM]; // set some state reg_setSpecial(rG,100); reg_setSpecial(rS,0x1000); reg_setSpecial(rO,0x1000); for(size_t i = 100; i < GREG_NUM; i++) reg_setGlobal(i,i); for(size_t i = 0; i < 10; i++) reg_set(i,i); // backup for(size_t i = 0; i < LREG_NUM; i++) locals[i] = reg_get(i); for(size_t i = 100; i < GREG_NUM; i++) globals[i] = reg_getGlobal(i); for(size_t i = 0; i < SPECIAL_NUM; i++) specials[i] = reg_getSpecial(i); // arrange things so that an unsave fails at the beginning { jmp_buf env; int ex = setjmp(env); if(ex != EX_NONE) { for(size_t i = 0; i < LREG_NUM; i++) test_assertOcta(reg_get(i),locals[i]); for(size_t i = 100; i < GREG_NUM; i++) test_assertOcta(reg_getGlobal(i),globals[i]); for(size_t i = 0; i < SPECIAL_NUM; i++) test_assertOcta(reg_getSpecial(i),specials[i]); } else { ex_push(&env); reg_unsave(STACK_ADDR,false); test_assertFalse(true); } ex_pop(); } // PTE 1 for 0x100000000 .. 0x1FFFFFFFF (---) cache_write(CACHE_DATA,0x400000008,0x0000000400000000,0); // PTE 2 for 0x200000000 .. 0x2FFFFFFFF (rwx) cache_write(CACHE_DATA,0x400000010,0x0000000500000007,0); // arrange things so that an unsave fails when reading rL { // set rG|rA mmu_writeOcta(0x200000020,0xFE00000000000000,MEM_SIDE_EFFECTS); jmp_buf env; int ex = setjmp(env); if(ex != EX_NONE) { for(size_t i = 0; i < LREG_NUM; i++) test_assertOcta(reg_get(i),locals[i]); for(size_t i = 100; i < GREG_NUM; i++) test_assertOcta(reg_getGlobal(i),globals[i]); for(size_t i = 0; i < SPECIAL_NUM; i++) test_assertOcta(reg_getSpecial(i),specials[i]); } else { ex_push(&env); reg_unsave(0x200000020,false); test_assertFalse(true); } ex_pop(); } // arrange things so that an unsave fails when testing the range { // set rG|rA mmu_writeOcta(0x200000080,0xFE00000000000000,MEM_SIDE_EFFECTS); jmp_buf env; int ex = setjmp(env); if(ex != EX_NONE) { for(size_t i = 0; i < LREG_NUM; i++) test_assertOcta(reg_get(i),locals[i]); for(size_t i = 100; i < GREG_NUM; i++) test_assertOcta(reg_getGlobal(i),globals[i]); for(size_t i = 0; i < SPECIAL_NUM; i++) test_assertOcta(reg_getSpecial(i),specials[i]); } else { ex_push(&env); reg_unsave(0x200000080,false); test_assertFalse(true); } ex_pop(); } // arrange things so that it works, but one value more would fail { // we have 13 specials, rL, rL locals and rG globals octa off = (13 + 1 + 10 + (256 - 254) - 1) * sizeof(octa); // set rG|rA mmu_writeOcta(0x200000000 + off,0xFE00000000000000,MEM_SIDE_EFFECTS); // rL is saved 13+rG positions further mmu_writeOcta(0x200000000 + off - (13 + (256 - 254)) * sizeof(octa),10,MEM_SIDE_EFFECTS); reg_unsave(0x200000000 + off,false); test_assertTrue(true); test_assertOcta(reg_getSpecial(rG),254); test_assertOcta(reg_getSpecial(rL),10); // this proves that one read more would have failed test_assertOcta(reg_getSpecial(rS),0x200000000); test_assertOcta(reg_getSpecial(rO),0x200000000); } // undo mapping cache_write(CACHE_DATA,0x400000008,0,0); cache_write(CACHE_DATA,0x400000010,0,0); tc_removeAll(TC_DATA); }
static void test_basics(void) { size_t count,oldFree; test_caseStart("Testing basics"); { sGroup *g; oldFree = heapspace(); g = group_parse("0:root:0",&count); test_assertTrue(g != NULL); test_assertSize(count,1); if(g) { test_assertTrue(g->next == NULL); test_assertUInt(g->gid,0); test_assertStr(g->name,"root"); test_assertSize(g->userCount,1); test_assertUInt(g->users[0],0); } group_free(g); test_assertSize(heapspace(),oldFree); } { sGroup *g; oldFree = heapspace(); g = group_parse("0:root\n",&count); test_assertTrue(g != NULL); test_assertSize(count,1); if(g) { test_assertTrue(g->next == NULL); test_assertUInt(g->gid,0); test_assertStr(g->name,"root"); test_assertSize(g->userCount,0); } group_free(g); test_assertSize(heapspace(),oldFree); } { sGroup *g; oldFree = heapspace(); g = group_parse("0:root:",&count); test_assertTrue(g != NULL); test_assertSize(count,1); if(g) { test_assertTrue(g->next == NULL); test_assertUInt(g->gid,0); test_assertStr(g->name,"root"); test_assertSize(g->userCount,0); } group_free(g); test_assertSize(heapspace(),oldFree); } { sGroup *g; oldFree = heapspace(); g = group_parse("2444:a:100:200",&count); test_assertTrue(g != NULL); test_assertSize(count,1); if(g) { test_assertTrue(g->next == NULL); test_assertUInt(g->gid,2444); test_assertStr(g->name,"a"); test_assertSize(g->userCount,2); test_assertUInt(g->users[0],100); test_assertUInt(g->users[1],200); } group_free(g); test_assertSize(heapspace(),oldFree); } { sGroup *g,*res; oldFree = heapspace(); res = group_parse("1:a:1:2\n\n2:b:4",&count); test_assertSize(count,2); g = res; test_assertTrue(g != NULL); if(g) { test_assertUInt(g->gid,1); test_assertStr(g->name,"a"); test_assertSize(g->userCount,2); test_assertUInt(g->users[0],1); test_assertUInt(g->users[1],2); g = g->next; } test_assertTrue(g != NULL); if(g) { test_assertUInt(g->gid,2); test_assertStr(g->name,"b"); test_assertSize(g->userCount,1); test_assertUInt(g->users[0],4); } group_free(res); test_assertSize(heapspace(),oldFree); } test_caseSucceeded(); }
static void test_assertCan(const char *path,uint mode) { int fd = open(path,mode); test_assertTrue(fd >= 0); close(fd); }