Prechádzať zdrojové kódy

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

Tibor Nagy 6 rokov pred
rodič
commit
fa2c6d29db

+ 21 - 18
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

+ 0 - 3
tests/expected/unistd/sleep.stderr

@@ -1,3 +0,0 @@
-sleep: Success
-usleep: Success
-nanosleep: Success

+ 1 - 0
tests/expected/unistd/sleep.stdout

@@ -0,0 +1 @@
+unslept: 0

+ 110 - 65
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 }
+};
+
+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;
 }

+ 11 - 6
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);
 }