diff --git a/tests/expected/libgen.stdout b/tests/expected/libgen.stdout index c19d73cc8b..6e32d2008d 100644 --- a/tests/expected/libgen.stdout +++ b/tests/expected/libgen.stdout @@ -1,18 +1,21 @@ -Testing libgen.h -OK on basename(/usr/lib), expected: 'lib', got: 'lib' -OK on basename(//usr//lib//), expected: 'lib', got: 'lib' -OK on basename(/usr/), expected: 'usr', got: 'usr' -OK on basename(), expected: '.', got: '.' -OK on basename(/), expected: '/', got: '/' -OK on basename(///), expected: '/', got: '/' -OK on basename(NULL), expected: '.', got: '.' -OK on dirname(/usr/lib), expected: '/usr', got: '/usr' -OK on dirname(//usr//lib//), expected: '//usr', got: '//usr' -OK on dirname(/usr), expected: '/', got: '/' -OK on dirname(usr), expected: '.', got: '.' -OK on dirname(/), expected: '/', got: '/' -OK on dirname(///), expected: '/', got: '/' -OK on dirname(.), expected: '.', got: '.' -OK on dirname(..), expected: '.', got: '.' -OK on dirname(), expected: '.', got: '.' -OK on dirname(NULL), expected: '.', got: '.' +dirname("") == "." +basename("") == "." +dirname(".") == "." +basename(".") == "." +dirname("..") == "." +basename("..") == ".." +dirname("/") == "/" +basename("/") == "/" +dirname("///") == "/" +basename("///") == "/" +dirname("//usr//lib//") == "//usr" +basename("//usr//lib//") == "lib" +dirname("/usr") == "/" +basename("/usr") == "usr" +dirname("/usr/") == "/" +basename("/usr/") == "usr" +dirname("/usr/lib") == "/usr" +basename("/usr/lib") == "lib" +dirname(NULL) == "." +basename(NULL) == "." +Success: 0 diff --git a/tests/expected/unistd/sleep.stderr b/tests/expected/unistd/sleep.stderr index df935fdb39..e69de29bb2 100644 --- a/tests/expected/unistd/sleep.stderr +++ b/tests/expected/unistd/sleep.stderr @@ -1,3 +0,0 @@ -sleep: Success -usleep: Success -nanosleep: Success diff --git a/tests/expected/unistd/sleep.stdout b/tests/expected/unistd/sleep.stdout index e69de29bb2..25867863a2 100644 --- a/tests/expected/unistd/sleep.stdout +++ b/tests/expected/unistd/sleep.stdout @@ -0,0 +1 @@ +unslept: 0 diff --git a/tests/libgen.c b/tests/libgen.c index 460e710fcb..0cdf8b8ade 100644 --- a/tests/libgen.c +++ b/tests/libgen.c @@ -5,78 +5,123 @@ #include "test_helpers.h" -typedef struct { - char * in; - char * expected_out; -} test_case; +#define TODO NULL -// API for basename and dirname allow the passed in string to -// be modified. This means we have to pass a modifiable copy. -char * get_mutable_string(char *str) { - if (str == NULL) - return NULL; - char * copy = malloc(sizeof(char) * (strlen(str) + 1)); - copy = strcpy(copy, str); - return copy; -} +// TODO: Tests for Redox schemes +struct test_case { + char *path; + char *dirname; + char *basename; +} test_cases[] = { + // Classic UNIX + // path dirname basename + { "", ".", "." }, + { ".", ".", "." }, + { "..", ".", ".." }, + { "/", "/", "/" }, + { "///", "/", "/" }, + { "//usr//lib//", "//usr", "lib" }, + { "/usr", "/", "usr" }, + { "/usr/", "/", "usr" }, + { "/usr/lib", "/usr", "lib" }, + { NULL, ".", "." } + // Root scheme + // path dirname basename + //{ ":", TODO, TODO }, + //{ ":/", TODO, TODO }, + //{ ":/scheme", TODO, TODO }, + // Regular scheme + // path dirname basename + //{ "file:", TODO, TODO }, + //{ "file:usr", TODO, TODO }, + //{ "file:usr/", TODO, TODO }, + //{ "file:usr/lib", TODO, TODO }, + //{ "file:/", TODO, TODO }, + //{ "file:/usr", TODO, TODO }, + //{ "file:/usr/", TODO, TODO }, + //{ "file:/usr/lib", TODO, TODO }, + //{ "file:///", TODO, TODO }, + //{ "file://usr", TODO, TODO }, + //{ "file://usr//", TODO, TODO }, + // Hierarchical scheme + // path dirname basename + //{ "disk/0:", TODO, TODO }, + //{ "disk/0:/", TODO, TODO }, + //{ "disk/0:///", TODO, TODO }, + //{ "disk/0:/usr", TODO, TODO }, + //{ "disk/0:/usr/", TODO, TODO }, + //{ "disk/0:/usr/lib", TODO, TODO }, + // Malformed + // path dirname basename + //{ "/file:/sys:/usr", TODO, TODO }, + //{ "/file:/usr", TODO, TODO }, + //{ "/file:sys:/usr", TODO, TODO }, + //{ "/file:usr", TODO, TODO }, + //{ ":file/usr", TODO, TODO }, + //{ "file:/sys:/usr", TODO, TODO }, + //{ "file::/", TODO, TODO }, + //{ "file::/usr/lib", TODO, TODO } +}; -void test_basename(void) { - test_case test_cases[] = - { {"/usr/lib", "lib"}, - {"//usr//lib//", "lib"}, - {"/usr/", "usr"}, - {"", "."}, - {"/", "/"}, - {"///","/"}, - {NULL, "."} - }; - for (int i = 0;i < sizeof(test_cases)/sizeof(test_case);i++) { - char * in = get_mutable_string(test_cases[i].in); - char * out = basename(in); - if (!out) { - printf("Error on basename(%s), expected: '%s', got NULL\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out); - } else if (strcmp(out, test_cases[i].expected_out) != 0) { - printf("Error on basename(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out); +size_t num_test_cases = sizeof(test_cases) / sizeof(struct test_case); + +int safe_strcmp(char *s1, char *s2) { + if (s1 == NULL && s2 == NULL) { + return 0; + } else if (s1 == NULL && s2 != NULL) { + return 1; + } else if (s1 != NULL && s2 == NULL) { + return -1; } else { - printf("OK on basename(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out); + return strcmp(s1, s2); } - if (!in) - free(in); - } - return; } -void test_dirname(void) { - test_case test_cases[] = - { {"/usr/lib", "/usr"}, - {"//usr//lib//", "//usr"}, - {"/usr", "/"}, - {"usr", "."}, - {"/", "/"}, - {"///","/"}, - {".", "."}, - {"..", "."}, - {"", "."}, - {NULL, "."} - }; - for (int i = 0;i < sizeof(test_cases)/sizeof(test_case);i++) { - char * in = get_mutable_string(test_cases[i].in); - char * out = dirname(in); - if (!out) { - printf("Error on dirname(%s), expected: '%s', got NULL\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out); - } else if (strcmp(out, test_cases[i].expected_out) != 0) { - printf("Error on dirname(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out); - } else { - printf("OK on dirname(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out); - } - if (!in) - free(in); - } - return; -} +#define CHECK_TEST(tc, fn, retval) \ + do { \ + /* API for basename and dirname allow the passed in string to */ \ + /* be modified. This means we have to pass a modifiable copy. */ \ + char *path = NULL; \ + if (tc.path != NULL) \ + path = strdup(tc.path); \ + \ + char *output = fn(path); \ + \ + /* Printing NULLs with printf("%s") is undefined behaviour, */ \ + /* that's why they are handled here this way. */ \ + char display_path[64] = "NULL"; \ + char display_output[64] = "NULL"; \ + char display_expected[64] = "NULL"; \ + if (tc.path != NULL) sprintf(display_path, "\"%s\"", tc.path); \ + if (output != NULL) sprintf(display_output, "\"%s\"", output); \ + if (tc.fn != NULL) sprintf(display_expected, "\"%s\"", tc.fn); \ + \ + if (safe_strcmp(output, tc.fn) != 0) { \ + retval = EXIT_FAILURE; \ + printf("%s(%s) != %s, expected: %s\n", \ + #fn, display_path, display_output, display_expected); \ + } else { \ + printf("%s(%s) == %s\n", \ + #fn, display_path, display_output); \ + } \ + \ + free(path); \ + } while (0) int main(void) { - printf("Testing libgen.h\n"); - test_basename(); - test_dirname(); + int retval = EXIT_SUCCESS; + + for(int i = 0; i < num_test_cases; ++i) { + struct test_case tc = test_cases[i]; + CHECK_TEST(tc, dirname, retval); + CHECK_TEST(tc, basename, retval); + } + + if (retval == EXIT_SUCCESS) { + printf("Success: %d\n", retval); + } else { + printf("Failure: %d\n", retval); + } + + return retval; } diff --git a/tests/unistd/sleep.c b/tests/unistd/sleep.c index 5f4005eb12..2d7457e2d2 100644 --- a/tests/unistd/sleep.c +++ b/tests/unistd/sleep.c @@ -5,11 +5,16 @@ #include "test_helpers.h" int main(void) { - sleep(2); - perror("sleep"); - usleep(1000); - perror("usleep"); + // sleep has no error codes and doesn't set errno + unsigned int unslept = sleep(2); + printf("unslept: %u\n", unslept); + + int us_status = usleep(1000); + ERROR_IF(usleep, us_status, == -1); + UNEXP_IF(usleep, us_status, != 0); + struct timespec tm = {0, 10000}; - nanosleep(&tm, NULL); - perror("nanosleep"); + int ns_status = nanosleep(&tm, NULL); + ERROR_IF(nanosleep, ns_status, == -1); + UNEXP_IF(nanosleep, ns_status, != 0); }