#include #include #include #include "common.h" #include "debug.h" #include "unittest.h" #include "file.h" enum { DEBUG_TESTFILE = true }; typedef void (*execfunc)(void *data); enum { FILE_REMOVE_FAIL = -1 }; static bool run(execfunc execfn, void *data) { bool result = false; int pid; Waitmsg *msg; assert_valid(execfn); switch(pid = fork()) { case -1: ERROR(DEBUG_TESTFILE, "run fork() failed"); break; case 0: execfn(data); ERROR(DEBUG_TESTFILE, "execl() failed"); result = false; break; default: while((msg = wait()) != nil) { if(msg->pid == pid) { result = strlen(msg->msg) == 0; } free(msg); } } NOISE(DEBUG_TESTFILE, "run 0x%X result: %d", execfn, result); return result; } typedef struct TestFileData { char *original; char *copy; char *dir; } TestFileData; static void *testfile_setup(void) { TestFileData *result = emalloc_fs(sizeof(*result)); result->original = "testfile.tmp"; result->copy = "testfile.tmp.copy"; result->dir = estrdup_fs("tmp/a/b/c/d"); return result; } static void testfile_teardown(void *data) { TestFileData *testfiledata = (TestFileData*)data; assert_valid(testfiledata); free(testfiledata->dir); free(testfiledata); } static void cmp_copy(void *data) { TestFileData *testfiledata = (TestFileData *)data; assert_valid(testfiledata); execl("/bin/cmp", "/bin/cmp", testfiledata->original, testfiledata->copy, nil); } static bool testfile_write_file(char *filename, char *content) { int fd; long writtensize; long contentsize = strlen(content); assert_valid(filename); assert_valid(content); fd = create(filename, OWRITE, 0644L); if(!fd_isopen(fd)) { ERROR(DEBUG_TESTFILE, "testfile_write_file unable to create %s for write %d", filename, fd); return false; } writtensize = write(fd, content, contentsize); close(fd); NOISE(DEBUG_TESTFILE, "testfile_write_file writtensize: %d, contentsize: %d", writtensize, contentsize); return writtensize == contentsize; } bool testfile_copy(void *data) { bool result; int from; int to; TestFileData *testfiledata = (TestFileData *)data; assert_valid(testfiledata); test_assert( testfile_write_file( testfiledata->original, "this is the content\nand more")); from = open(testfiledata->original, OREAD); test_assert(fd_isopen(from)); to = create(testfiledata->copy, OWRITE, 0755); test_assert(fd_isopen(to)); result = file_copy(from, to); close(from); close(to); NOISE(DEBUG_TESTFILE, "return from file_copy %d", result); test_assert(result); test_assert(run(cmp_copy, data)); test_assert(remove(testfiledata->original) != FILE_REMOVE_FAIL); test_assert(remove(testfiledata->copy) != FILE_REMOVE_FAIL); return true; } static void remove_dir(void *data) { TestFileData *testfiledata = (TestFileData *)data; assert_valid(testfiledata); execl("/bin/rm", "/bin/rm", "-r", testfiledata->dir, nil); } static bool testfile_recursive_mkdir(void *data) { TestFileData *testfiledata = (TestFileData *)data; assert_valid(testfiledata); test_assert(file_relative_recursive_mkdir(testfiledata->dir)); test_assert(run(remove_dir, data)); return true; } static TestFixure testfile_fixure = { .setup = testfile_setup, .teardown = testfile_teardown }; static TestCaseNamePair testfile_testcases[] = { testcasenamepair_make(testfile_copy), testcasenamepair_make(testfile_recursive_mkdir) }; AbstractTest *testfile_testsuite(void) { return (AbstractTest *) testsuite_make("testfile", testfile_testcases, static_array_length(testfile_testcases), &testfile_fixure); }