#include <u.h>
#include <libc.h>
#include <String.h>
#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);
}
|