Commit fa2c6d29 authored by Nagy Tibor's avatar Nagy Tibor

tests: Rewrite libgen tests based on ctype (nice table layout), fix error handling of sleep tests

parent efd6947d
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
sleep: Success
usleep: Success
nanosleep: Success
......@@ -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 }
};
size_t num_test_cases = sizeof(test_cases) / sizeof(struct test_case);
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);
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);
#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) {
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("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);
printf("Failure: %d\n", retval);
}
if (!in)
free(in);
}
return;
}
int main(void) {
printf("Testing libgen.h\n");
test_basename();
test_dirname();
return retval;
}
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment