void test_array_addn (void) { char **array, **ret; size_t len; /* Check that we can append strings to a NULL-terminated array. */ TEST_FUNCTION ("nih_str_array_addn"); array = nih_str_array_new (NULL); len = 0; TEST_ALLOC_FAIL { ret = nih_str_array_addn (&array, NULL, &len, "testing", 4); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_STR (array[0], "test"); TEST_EQ_P (array[1], NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (array[0], array); TEST_ALLOC_SIZE (array[0], 5); TEST_EQ_STR (array[0], "test"); TEST_EQ_P (array[1], NULL); } nih_free (array); }
void test_main_loop_add_func (void) { NihMainLoopFunc *func; /* Check that we can add a callback function to the main loop, * and that the structure returned is correctly populated and * placed in a list. */ TEST_FUNCTION ("nih_main_loop_add_func"); TEST_ALLOC_FAIL { func = nih_main_loop_add_func (NULL, my_callback, &func); if (test_alloc_failed) { TEST_EQ_P (func, NULL); continue; } TEST_ALLOC_SIZE (func, sizeof (NihMainLoopFunc)); TEST_LIST_NOT_EMPTY (&func->entry); TEST_EQ_P (func->callback, my_callback); TEST_EQ_P (func->data, &func); nih_free (func); } }
void test_new (void) { Process *process; /* Check that we can create a new Process structure; the structure * should be allocated with nih_alloc and have sensible defaults. */ TEST_FUNCTION ("process_new"); TEST_ALLOC_FAIL { process = process_new (NULL); if (test_alloc_failed) { TEST_EQ_P (process, NULL); continue; } TEST_ALLOC_SIZE (process, sizeof (Process)); TEST_EQ (process->script, FALSE); TEST_EQ_P (process->command, NULL); nih_free (process); } }
void test_operator_reset (void) { EventOperator *oper1, *oper2, *oper3, *oper4, *oper5; Event *event1, *event2; /* Check that we can reset all of the operators in the tree, * discarding any events that were referenced or blocked and setting * all the values back to FALSE. */ TEST_FUNCTION ("event_operator_reset"); oper1 = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper2 = event_operator_new (NULL, EVENT_AND, NULL, NULL); oper3 = event_operator_new (NULL, EVENT_MATCH, "foo", NULL); oper4 = event_operator_new (NULL, EVENT_MATCH, "bar", NULL); oper5 = event_operator_new (NULL, EVENT_MATCH, "baz", NULL); nih_tree_add (&oper1->node, &oper2->node, NIH_TREE_LEFT); nih_tree_add (&oper2->node, &oper3->node, NIH_TREE_LEFT); nih_tree_add (&oper2->node, &oper4->node, NIH_TREE_RIGHT); nih_tree_add (&oper1->node, &oper5->node, NIH_TREE_RIGHT); event1 = event_new (NULL, "foo", NULL); event2 = event_new (NULL, "bar", NULL); event_operator_handle (oper1, event1, NULL); event_operator_handle (oper1, event2, NULL); TEST_EQ (oper1->value, TRUE); TEST_EQ (oper2->value, TRUE); TEST_EQ (oper3->value, TRUE); TEST_EQ_P (oper3->event, event1); TEST_EQ (oper4->value, TRUE); TEST_EQ (oper4->event, event2); TEST_EQ (oper5->value, FALSE); TEST_EQ (event1->blockers, 1); TEST_EQ (event2->blockers, 1); event_operator_reset (oper1); TEST_EQ (oper1->value, FALSE); TEST_EQ (oper2->value, FALSE); TEST_EQ (oper3->value, FALSE); TEST_EQ_P (oper3->event, NULL); TEST_EQ (oper4->value, FALSE); TEST_EQ (oper4->event, NULL); TEST_EQ (oper5->value, FALSE); TEST_EQ (event1->blockers, 0); TEST_EQ (event2->blockers, 0); nih_free (oper1); nih_free (oper2); nih_free (oper3); nih_free (oper4); nih_free (oper5); event_poll (); }
void test_preamble (void) { char *str; TEST_FUNCTION ("output_preamble"); /* Check that a preamble for a source file is correctly generated, * with the package name, source file path and copyright all * present. */ TEST_FEATURE ("with path"); TEST_ALLOC_FAIL { str = output_preamble (NULL, "path.c"); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("/* test\n" " *\n" " * path.c - auto-generated D-Bus bindings\n" " *\n" " * Copyright (C) 2009 Joe Bloggs.\n" " *\n" " * This file was automatically generated; see the source for copying\n" " * conditions.\n" " */\n" "\n")); nih_free (str); } /* Check that a preamble for a header file (NULL path) is correctly * generated with the package name and copyright present. */ TEST_FEATURE ("with no path"); TEST_ALLOC_FAIL { str = output_preamble (NULL, NULL); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("/* test\n" " *\n" " * Copyright (C) 2009 Joe Bloggs.\n" " *\n" " * This file was automatically generated; see the source for copying\n" " * conditions.\n" " */\n" "\n")); nih_free (str); } }
void test_cgroup_name_new (void) { CGroupName *cgname; nih_local char *parent = NULL; TEST_FUNCTION ("cgroup_name_new"); parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FEATURE ("no parent, name"); TEST_ALLOC_FAIL { cgname = cgroup_name_new (NULL, "foo."); if (test_alloc_failed) { TEST_EQ_P (cgname, NULL); continue; } TEST_NE_P (cgname, NULL); TEST_ALLOC_SIZE (cgname, sizeof (CGroupName)); TEST_ALLOC_PARENT (cgname, NULL); TEST_EQ_STR (cgname->name, "foo."); TEST_ALLOC_SIZE (cgname->name, 1+strlen ("foo.")); TEST_ALLOC_PARENT (cgname->name, cgname); TEST_LIST_EMPTY (&cgname->settings); } TEST_FEATURE ("parent, name"); TEST_ALLOC_FAIL { cgname = cgroup_name_new (parent, "bar"); if (test_alloc_failed) { TEST_EQ_P (cgname, NULL); continue; } TEST_NE_P (cgname, NULL); TEST_ALLOC_SIZE (cgname, sizeof (CGroupName)); TEST_ALLOC_PARENT (cgname, parent); TEST_EQ_STR (cgname->name, "bar"); TEST_ALLOC_SIZE (cgname->name, 1+strlen ("bar")); TEST_ALLOC_PARENT (cgname->name, cgname); TEST_LIST_EMPTY (&cgname->settings); } }
void test_getn (void) { char **env = NULL; size_t len = 0; const char *ret; TEST_FUNCTION ("environ_getn"); len = 0; env = nih_str_array_new (NULL); /* Check that an empty table always returns NULL. */ TEST_FEATURE ("with empty table"); ret = environ_getn (env, "FOO", 3); TEST_EQ_P (ret, NULL); assert (nih_str_array_add (&env, NULL, &len, "FOOLISH=no")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); /* Check that a key that is present is returned. */ TEST_FEATURE ("with key to be found"); ret = environ_getn (env, "BAR", 3); TEST_EQ_STR (ret, "BAZ"); /* Check that a key that doesn't exist returns NULL. */ TEST_FEATURE ("with key not found"); ret = environ_getn (env, "MEEP", 4); TEST_EQ_P (ret, NULL); /* Check that the key is not prefix-matched. */ TEST_FEATURE ("with key that is prefix of another"); ret = environ_getn (env, "FOO", 3); TEST_EQ_P (ret, NULL); /* Check that the length is honoured. */ TEST_FEATURE ("with longer key"); ret = environ_getn (env, "FOOLISH", 3); TEST_EQ_P (ret, NULL); nih_free (env); }
void test_sprintf (void) { char *str1, *str2; TEST_FUNCTION ("nih_sprintf"); /* Check that we can create a formatted string with no parent, * it should be allocated with nih_alloc and be the right length. */ TEST_FEATURE ("with no parent"); TEST_ALLOC_FAIL { str1 = nih_sprintf (NULL, "this %s a test %d", "is", 54321); if (test_alloc_failed) { TEST_EQ_P (str1, NULL); continue; } TEST_ALLOC_PARENT (str1, NULL); TEST_ALLOC_SIZE (str1, strlen (str1) + 1); TEST_EQ_STR (str1, "this is a test 54321"); nih_free (str1); } /* Check that we can create a string with a parent. */ TEST_FEATURE ("with a parent"); str1 = nih_sprintf (NULL, "this %s a test %d", "is", 54321); TEST_ALLOC_FAIL { str2 = nih_sprintf (str1, "another %d test %s", 12345, "string"); if (test_alloc_failed) { TEST_EQ_P (str2, NULL); continue; } TEST_ALLOC_PARENT (str2, str1); TEST_ALLOC_SIZE (str2, strlen (str2) + 1); TEST_EQ_STR (str2, "another 12345 test string"); nih_free (str2); } nih_free (str1); }
void test_vsprintf (void) { char *str1, *str2; TEST_FUNCTION ("nih_vsprintf"); /* Check that we can create a formatted string for a va_list, * first with no parent. */ TEST_FEATURE ("with no parent"); TEST_ALLOC_FAIL { str1 = my_vsprintf (NULL, "this %s a test %d", "is", 54321); if (test_alloc_failed) { TEST_EQ_P (str1, NULL); continue; } TEST_ALLOC_PARENT (str1, NULL); TEST_ALLOC_SIZE (str1, strlen (str1) + 1); TEST_EQ_STR (str1, "this is a test 54321"); nih_free (str1); } /* And then with a parent. */ TEST_FEATURE ("with a parent"); str1 = my_vsprintf (NULL, "this %s a test %d", "is", 54321); TEST_ALLOC_FAIL { str2 = my_vsprintf (str1, "another %d test %s", 12345, "string"); if (test_alloc_failed) { TEST_EQ_P (str2, NULL); continue; } TEST_ALLOC_PARENT (str2, str1); TEST_ALLOC_SIZE (str2, strlen (str2) + 1); TEST_EQ_STR (str2, "another 12345 test string"); nih_free (str2); } nih_free (str1); }
void test_strdup (void) { char *str1, *str2; TEST_FUNCTION ("nih_strdup"); /* Check that we can create a duplicate of another string, * allocated with nih_alloc and no parent. */ TEST_FEATURE ("with no parent"); TEST_ALLOC_FAIL { str1 = nih_strdup (NULL, "this is a test"); if (test_alloc_failed) { TEST_EQ_P (str1, NULL); continue; } TEST_ALLOC_PARENT (str1, NULL); TEST_ALLOC_SIZE (str1, strlen (str1) + 1); TEST_EQ_STR (str1, "this is a test"); nih_free (str1); } /* And check we can allocate with a parent. */ TEST_FEATURE ("with a parent"); str1 = nih_strdup (NULL, "this is a test"); TEST_ALLOC_FAIL { str2 = nih_strdup (str1, "another test string"); if (test_alloc_failed) { TEST_EQ_P (str2, NULL); continue; } TEST_ALLOC_PARENT (str2, str1); TEST_ALLOC_SIZE (str2, strlen (str2) + 1); TEST_EQ_STR (str2, "another test string"); nih_free (str2); } nih_free (str1); }
void test_main_loop (void) { NihMainLoopFunc *func; NihTimer *timer; int ret; /* Check that we can run through the main loop, and that the * callback function will be run. Also schedule an immediate * timeout and make sure that's run too, that'll terminate the * main loop with an exit value, make sure it's returned. */ TEST_FUNCTION ("nih_main_loop"); callback_called = 0; last_data = NULL; func = nih_main_loop_add_func (NULL, my_callback, &func); timer = nih_timer_add_timeout (NULL, 1, my_timeout, NULL); ret = nih_main_loop (); TEST_EQ (ret, 42); TEST_TRUE (callback_called); TEST_EQ_P (last_data, &func); nih_free (func); }
void test_name (void) { const char *name; TEST_FUNCTION ("process_name"); /* Check that PROCESS_MAIN returns the right string. */ TEST_FEATURE ("with main process"); name = process_name (PROCESS_MAIN); TEST_EQ_STR (name, "main"); /* Check that PROCESS_SECURITY returns the right string. */ TEST_FEATURE ("with security process"); name = process_name (PROCESS_SECURITY); TEST_EQ_STR (name, "security"); /* Check that PROCESS_PRE_START returns the right string. */ TEST_FEATURE ("with pre-start process"); name = process_name (PROCESS_PRE_START); TEST_EQ_STR (name, "pre-start"); /* Check that PROCESS_POST_START returns the right string. */ TEST_FEATURE ("with post-start process"); name = process_name (PROCESS_POST_START); TEST_EQ_STR (name, "post-start"); /* Check that PROCESS_PRE_STOP returns the right string. */ TEST_FEATURE ("with pre-stop process"); name = process_name (PROCESS_PRE_STOP); TEST_EQ_STR (name, "pre-stop"); /* Check that PROCESS_POST_STOP returns the right string. */ TEST_FEATURE ("with post-stop process"); name = process_name (PROCESS_POST_STOP); TEST_EQ_STR (name, "post-stop"); /* Check that an invalid process returns NULL. */ TEST_FEATURE ("with invalid process"); name = process_name (1234); TEST_EQ_P (name, NULL); }
void test_set (void) { char **env = NULL, **ret; size_t len = 0; TEST_FUNCTION ("environ_set"); /* Check that an environment variable can be set from a format * string. */ TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); } ret = environ_set (&env, NULL, &len, TRUE, "FOO=%d", 1234); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (env[0], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_ALLOC_SIZE (env[0], 9); TEST_EQ_STR (env[0], "FOO=1234"); TEST_EQ_P (env[1], NULL); nih_free (env); } }
void test_array_new (void) { char **array; /* Check that we can allocate a NULL-terminated array of strings using * nih_alloc(). */ TEST_FUNCTION ("nih_str_array_new"); TEST_ALLOC_FAIL { array = nih_str_array_new (NULL); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *)); TEST_EQ_P (array[0], NULL); nih_free (array); } }
void test_alloc (void) { void *ptr1; void *ptr2; TEST_FUNCTION ("nih_alloc"); /* Check allocation remembers the size, and is possible without * a parent. */ TEST_FEATURE ("with no parent"); ptr1 = nih_alloc (NULL, 8096); memset (ptr1, 'x', 8096); TEST_ALLOC_SIZE (ptr1, 8096); TEST_ALLOC_PARENT (ptr1, NULL); /* Check that allocation with a parent remembers the parent */ TEST_FEATURE ("with a parent"); ptr2 = nih_alloc (ptr1, 10); memset (ptr2, 'x', 10); TEST_ALLOC_SIZE (ptr2, 10); TEST_ALLOC_PARENT (ptr2, ptr1); nih_free (ptr1); /* Check that nih_alloc returns NULL if allocation fails. */ TEST_FEATURE ("with failed allocation"); __nih_malloc = malloc_null; ptr1 = nih_new (NULL, int); __nih_malloc = malloc; TEST_EQ_P (ptr1, NULL); }
void test_new (void) { void *ptr1; void *ptr2; TEST_FUNCTION ("nih_new"); /* Check that nih_new works if we don't give it a parent, the block * should be allocated with the size of the type given. */ TEST_FEATURE ("with no parent"); ptr1 = nih_new (NULL, int); TEST_ALLOC_SIZE (ptr1, sizeof (int)); TEST_ALLOC_PARENT (ptr1, NULL); /* Check that nih_new works if we do give a parent. */ TEST_FEATURE ("with parent"); ptr2 = nih_new (ptr1, char); TEST_ALLOC_SIZE (ptr2, sizeof (char)); TEST_ALLOC_PARENT (ptr2, ptr1); nih_free (ptr1); /* Check that nih_new returns NULL if allocation fails. */ TEST_FEATURE ("with failed allocation"); __nih_malloc = malloc_null; ptr1 = nih_new (NULL, int); __nih_malloc = malloc; TEST_EQ_P (ptr1, NULL); }
void test_add (void) { char **env = NULL, **ret; size_t len = 0; TEST_FUNCTION ("environ_add"); /* Check that we can add a variable to a new environment table * and that it is appended to the array. */ TEST_FEATURE ("with empty table"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); } ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (env[0], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_ALLOC_SIZE (env[0], 8); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_P (env[1], NULL); nih_free (env); } /* Check that we can add a variable to an environment table with * existing different entries and that it is appended to the array. */ TEST_FEATURE ("with new variable"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO=BAGGINS"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that we can add a variable from the environment to the table * and that it is appended to the array. */ TEST_FEATURE ("with new variable from environment"); putenv ("FRODO=BAGGINS"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } unsetenv ("FRODO"); /* Check that when we attempt to add a variable that's not in the * environment, the table is not extended. */ TEST_FEATURE ("with new variable unset in environment"); unsetenv ("FRODO"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); } /* Check that we can replace a variable in the environment table * when one already exists with the same or different value. */ TEST_FEATURE ("with replacement variable"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR=WIBBLE"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_ALLOC_PARENT (env[1], env); TEST_ALLOC_SIZE (env[1], 11); TEST_EQ_STR (env[1], "BAR=WIBBLE"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that we can replace a variable from the environment in the * environment table when one already exists with the same or * different value. */ TEST_FEATURE ("with replacement variable from environment"); putenv ("BAR=WIBBLE"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_ALLOC_PARENT (env[1], env); TEST_ALLOC_SIZE (env[1], 11); TEST_EQ_STR (env[1], "BAR=WIBBLE"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that when we attempt to replace a variable that's unset * in the environment, the existing variable is removed from the * table. */ TEST_FEATURE ("with replacement variable unset in environment"); unsetenv ("BAR"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "FRODO=BAGGINS"); TEST_EQ_STR (env[2], "BILBO=TOOK"); TEST_EQ_P (env[3], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that we can add a variable to an environment table with * existing different entries and that it is appended to the array, * even if replace is FALSE. */ TEST_FEATURE ("with new variable but no replace"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, FALSE, "FRODO=BAGGINS"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that when a variable already exists in the environment * table, and we're not replacing, the original value is left * untouched. */ TEST_FEATURE ("with existing variable"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR=WIBBLE"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that when a variable from the environment already exists in * the environment table, and we're not replacing, the original value * is left untouched. */ TEST_FEATURE ("with existing variable from environment"); putenv ("BAR=WIBBLE"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that when a variable from the environment is unset it * does not remove an existing variable in the environment table * if we're not replacing. */ TEST_FEATURE ("with existing variable unset in environment"); unsetenv ("BAR"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); }
void test_strcat (void) { char *str, *ret; TEST_FUNCTION ("nih_strcat"); /* Check that we can extend a string with another, resulting in the * original string being modified and the new pointer stored in the * argument and returned. */ TEST_FEATURE ("with string"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this is a test"); } tmp = str; ret = nih_strcat (&str, NULL, " of strdup"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this is a test"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 25); TEST_EQ_STR (str, "this is a test of strdup"); nih_free (str); } /* Check that when no string is passed, this behaves as strdup. */ TEST_FEATURE ("with NULL"); TEST_ALLOC_FAIL { str = NULL; ret = nih_strcat (&str, NULL, "test of strdup"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, NULL); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 15); TEST_EQ_STR (str, "test of strdup"); nih_free (str); } }
void test_realloc (void) { void *ptr1; void *ptr2; void *ptr3; TEST_FUNCTION ("nih_realloc"); /* Check that nih_realloc behaves like nih_alloc if the pointer is * NULL (it should, in fact, just call it) */ TEST_FEATURE ("as nih_alloc"); ptr1 = nih_realloc (NULL, NULL, 4096); memset (ptr1, 'x', 4096); TEST_ALLOC_SIZE (ptr1, 4096); TEST_ALLOC_PARENT (ptr1, NULL); nih_free (ptr1); /* Check that nih_realloc works if the block doesn't have a parent. */ TEST_FEATURE ("with no parent"); ptr1 = nih_alloc (NULL, 4096); memset (ptr1, 'x', 4096); ptr1 = nih_realloc (ptr1, NULL, 8096); memset (ptr1, 'x', 8096); TEST_ALLOC_SIZE (ptr1, 8096); TEST_ALLOC_PARENT (ptr1, NULL); /* Check that nih_realloc works if the block has a parent, the size * should change but the parent should remain the same. */ TEST_FEATURE ("with a parent"); ptr2 = nih_alloc (ptr1, 5); memset (ptr2, 'x', 5); ptr2 = nih_realloc (ptr2, ptr1, 10); memset (ptr2, 'x', 10); TEST_ALLOC_SIZE (ptr2, 10); TEST_ALLOC_PARENT (ptr2, ptr1); nih_free (ptr1); /* Check that nih_realloc works if the block being reallocated has * a child. This is fiddly as they need their parent pointers * adjusted. */ TEST_FEATURE ("with a child"); ptr1 = nih_alloc (NULL, 128); memset (ptr1, 'x', 128); ptr2 = nih_alloc (ptr1, 512); memset (ptr2, 'x', 512); ptr3 = nih_realloc (ptr1, NULL, 1024); memset (ptr3, 'x', 1024); TEST_ALLOC_PARENT (ptr2, ptr3); nih_free (ptr3); /* Check that nih_realloc returns NULL and doesn't alter the block * if the allocator fails. */ TEST_FEATURE ("with failing realloc"); ptr1 = nih_alloc (NULL, 10); assert (ptr1); memset (ptr1, 'x', 10); __nih_realloc = realloc_null; ptr2 = nih_realloc (ptr1, NULL, 200); __nih_realloc = realloc; TEST_EQ_P (ptr2, NULL); TEST_ALLOC_SIZE (ptr1, 10); nih_free (ptr1); }
void test_cgroup_new (void) { nih_local char *parent = NULL; CGroup *cgroup; TEST_FUNCTION ("cgroup_new"); parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FEATURE ("no parent, controller"); TEST_ALLOC_FAIL { cgroup = cgroup_new (NULL, "cpuset"); if (test_alloc_failed) { TEST_EQ_P (cgroup, NULL); continue; } TEST_NE_P (cgroup, NULL); TEST_ALLOC_SIZE (cgroup, sizeof (CGroup)); TEST_ALLOC_PARENT (cgroup, NULL); TEST_EQ_STR (cgroup->controller, "cpuset"); TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("cpuset")); TEST_ALLOC_PARENT (cgroup->controller, cgroup); TEST_LIST_EMPTY (&cgroup->names); nih_free (cgroup); } TEST_FEATURE ("parent, controller"); TEST_ALLOC_FAIL { cgroup = cgroup_new (parent, "perf_event"); if (test_alloc_failed) { TEST_EQ_P (cgroup, NULL); continue; } TEST_NE_P (cgroup, NULL); TEST_ALLOC_SIZE (cgroup, sizeof (CGroup)); TEST_ALLOC_PARENT (cgroup, parent); TEST_EQ_STR (cgroup->controller, "perf_event"); TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("perf_event")); TEST_ALLOC_PARENT (cgroup->controller, cgroup); TEST_LIST_EMPTY (&cgroup->names); nih_free (cgroup); } }
void test_strncat (void) { char *str, *ret; TEST_FUNCTION ("nih_strncat"); /* Check that we can extend a string with the first number of bytes * from another, resulting in the original string being modified and * the new pointer stored in the argument and returned. */ TEST_FEATURE ("with larger string than length"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this is a test"); } tmp = str; ret = nih_strncat (&str, NULL, " of strndup", 3); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this is a test"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 18); TEST_EQ_STR (str, "this is a test of"); nih_free (str); } /* Check that if a longer length than the string is given, enough * space is reserved but the string copy stops at the NULL. */ TEST_FEATURE ("with larger length than string"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this is a test"); } tmp = str; ret = nih_strncat (&str, NULL, " of strndup", 21); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this is a test"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 36); TEST_EQ_STR (str, "this is a test of strndup"); nih_free (str); } /* Check that when no string is passed, this behaves as strndup. */ TEST_FEATURE ("with NULL"); TEST_ALLOC_FAIL { str = NULL; ret = nih_strncat (&str, NULL, "test of strndup", 12); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, NULL); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 13); TEST_EQ_STR (str, "test of strn"); nih_free (str); } }
void test_strndup (void) { char *str1, *str2; TEST_FUNCTION ("nih_strndup"); /* Check that we can create a duplicate of the first portion of * another string, allocated with nih_alloc and no parent. The * new string should still include a NULL byte. */ TEST_FEATURE ("with no parent"); TEST_ALLOC_FAIL { str1 = nih_strndup (NULL, "this is a test", 7); if (test_alloc_failed) { TEST_EQ_P (str1, NULL); continue; } TEST_ALLOC_PARENT (str1, NULL); TEST_ALLOC_SIZE (str1, 8); TEST_EQ_STR (str1, "this is"); nih_free (str1); } /* Check that it works with a parent. */ TEST_FEATURE ("with a parent"); str1 = nih_strndup (NULL, "this is a test", 7); TEST_ALLOC_FAIL { str2 = nih_strndup (str1, "another test string", 12); if (test_alloc_failed) { TEST_EQ_P (str2, NULL); continue; } TEST_ALLOC_PARENT (str2, str1); TEST_ALLOC_SIZE (str2, 13); TEST_EQ_STR (str2, "another test"); nih_free (str2); } nih_free (str1); /* Check that the right thing happens if the length we give is * longer than the string, the returned size should be ample but * with the complete string copied in. */ TEST_FEATURE ("with larger length than string"); TEST_ALLOC_FAIL { str1 = nih_strndup (NULL, "small string", 20); if (test_alloc_failed) { TEST_EQ_P (str1, NULL); continue; } TEST_ALLOC_SIZE (str1, 21); TEST_EQ_STR (str1, "small string"); nih_free (str1); } }
void test_strcat_vsprintf (void) { char *str, *ret; TEST_FUNCTION ("test_strcat_vsprintf"); /* Check that we can extend a string with a formatted string, * resulting in the original string being modified and the new * pointer stored in the argument and returned. */ TEST_FEATURE ("with original string"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this"); } tmp = str; ret = my_strcat_vsprintf (&str, NULL, " %s a test %d", "is", 54321); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 21); TEST_EQ_STR (str, "this is a test 54321"); nih_free (str); } /* Check that when no string is passed, this behaves as sprintf. */ TEST_FEATURE ("with NULL"); TEST_ALLOC_FAIL { str = NULL; ret = my_strcat_vsprintf (&str, NULL, "%s a test %d", "is", 54321); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, NULL); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 15); TEST_EQ_STR (str, "is a test 54321"); nih_free (str); } }
void test_append (void) { char **env = NULL, **new_env, **ret; size_t len = 0; TEST_FUNCTION ("environ_append"); /* Check that we can append all new entries onto the end of an * existing environment table, without modifying the entries passed. */ TEST_FEATURE ("with new entries"); new_env = nih_str_array_new (NULL); assert (environ_add (&new_env, NULL, NULL, TRUE, "MILK=white")); assert (environ_add (&new_env, NULL, NULL, TRUE, "TEA=green")); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (environ_add (&env, NULL, &len, TRUE, "FOO=BAR")); assert (environ_add (&env, NULL, &len, TRUE, "BAR=BAZ")); } ret = environ_append (&env, NULL, &len, TRUE, new_env); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); nih_free (env); continue; } TEST_EQ_P (ret, env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "MILK=white"); TEST_EQ_STR (env[3], "TEA=green"); TEST_EQ_P (env[4], NULL); nih_free (env); } nih_free (new_env); /* Check that if entries are being replaced, those values from the * new table replace the values in the old table. */ TEST_FEATURE ("with replacement entries"); new_env = nih_str_array_new (NULL); assert (environ_add (&new_env, NULL, NULL, TRUE, "MILK=white")); assert (environ_add (&new_env, NULL, NULL, TRUE, "TEA=green")); assert (environ_add (&new_env, NULL, NULL, TRUE, "FOO=apricot")); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (environ_add (&env, NULL, &len, TRUE, "FOO=BAR")); assert (environ_add (&env, NULL, &len, TRUE, "BAR=BAZ")); } ret = environ_append (&env, NULL, &len, TRUE, new_env); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); nih_free (env); continue; } TEST_EQ_P (ret, env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=apricot"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "MILK=white"); TEST_EQ_STR (env[3], "TEA=green"); TEST_EQ_P (env[4], NULL); nih_free (env); } nih_free (new_env); /* Check that if entries are being preserved, those values from the * new table are ignored. */ TEST_FEATURE ("with preserve existing entries"); new_env = nih_str_array_new (NULL); assert (environ_add (&new_env, NULL, NULL, TRUE, "MILK=white")); assert (environ_add (&new_env, NULL, NULL, TRUE, "TEA=green")); assert (environ_add (&new_env, NULL, NULL, TRUE, "FOO=apricot")); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (environ_add (&env, NULL, &len, TRUE, "FOO=BAR")); assert (environ_add (&env, NULL, &len, TRUE, "BAR=BAZ")); } ret = environ_append (&env, NULL, &len, FALSE, new_env); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); nih_free (env); continue; } TEST_EQ_P (ret, env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "MILK=white"); TEST_EQ_STR (env[3], "TEA=green"); TEST_EQ_P (env[4], NULL); nih_free (env); } nih_free (new_env); }
void test_init (void) { TEST_FUNCTION ("nih_main_init_full"); /* Check that we can initialise the program with all of the arguments * and that they're all copied correctly into the globals. When the * program and package names are the same, the package string should * only contain one copy. */ TEST_FEATURE ("with same program and package names"); TEST_ALLOC_FAIL { nih_main_init_full ("test", "test", "1.0", "bugreport", "copyright"); TEST_EQ_STR (program_name, "test"); TEST_EQ_STR (package_name, "test"); TEST_EQ_STR (package_version, "1.0"); TEST_EQ_STR (package_bugreport, "bugreport"); TEST_EQ_STR (package_copyright, "copyright"); TEST_EQ_STR (package_string, "test 1.0"); } /* Check that when the program and package names differ, the * package string contains both. */ TEST_FEATURE ("with different program and package names"); TEST_ALLOC_FAIL { nih_main_init_full ("test", "wibble", "1.0", "bugreport", "copyright"); TEST_EQ_STR (program_name, "test"); TEST_EQ_STR (package_name, "wibble"); TEST_EQ_STR (package_version, "1.0"); TEST_EQ_STR (package_bugreport, "bugreport"); TEST_EQ_STR (package_copyright, "copyright"); TEST_EQ_STR (package_string, "test (wibble 1.0)"); } /* Check that we can pass NULL for both the bug report address and * the copyright message. */ TEST_FEATURE ("with missing arguments"); package_bugreport = package_copyright = NULL; nih_main_init_full ("argv0", "package", "1.0", NULL, NULL); TEST_EQ_P (package_bugreport, NULL); TEST_EQ_P (package_copyright, NULL); /* Check that the bug report address and copyright message are set * to NULL if empty strings are passed instead. */ TEST_FEATURE ("with empty arguments"); package_bugreport = package_copyright = NULL; nih_main_init_full ("argv0", "package", "1.0", "", ""); TEST_EQ_P (package_bugreport, NULL); TEST_EQ_P (package_copyright, NULL); /* Check that the program name contains only the basename of a * full path supplied, and this is replicated into the package * string. */ TEST_FEATURE ("with full program path"); TEST_ALLOC_FAIL { nih_main_init_full ("/usr/bin/argv0", "package", "1.0", "bugreport", "copyright"); TEST_EQ_STR (program_name, "argv0"); TEST_EQ_STR (package_name, "package"); TEST_EQ_STR (package_string, "argv0 (package 1.0)"); } /* Check that the program name contains only the actual name * of the program when it's supplied as a login shell path * (prefixed with a dash). */ TEST_FEATURE ("with login shell path"); TEST_ALLOC_FAIL { nih_main_init_full ("-argv0", "package", "1.0", "bugreport", "copyright"); TEST_EQ_STR (program_name, "argv0"); TEST_EQ_STR (package_name, "package"); TEST_EQ_STR (package_string, "argv0 (package 1.0)"); } /* Check that the nih_main_init macro passes all the arguments for * us, except the program name, which we pass. */ TEST_FUNCTION ("nih_main_init"); TEST_ALLOC_FAIL { nih_main_init ("argv[0]"); TEST_EQ_STR (program_name, "argv[0]"); TEST_EQ_STR (package_name, PACKAGE_NAME); TEST_EQ_STR (package_version, PACKAGE_VERSION); TEST_EQ_STR (package_bugreport, PACKAGE_BUGREPORT); TEST_EQ_STR (package_copyright, PACKAGE_COPYRIGHT); } }
void test_str_split (void) { char **array; int i; TEST_FUNCTION ("nih_str_split"); /* Check that we can split a string into a NULL-terminated array * at each matching character. The array should be allocated with * nih_alloc, and each element should also be with the array as * their parent. */ TEST_FEATURE ("with no repeat"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "this is a\ttest", " \t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 6); for (i = 0; i < 5; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "this"); TEST_EQ_STR (array[1], "is"); TEST_EQ_STR (array[2], ""); TEST_EQ_STR (array[3], "a"); TEST_EQ_STR (array[4], "test"); TEST_EQ_P (array[5], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple identical delimiter " "characters at string start"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "\t\tthis is a test", " \t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 7); for (i = 0; i < 6; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], ""); TEST_EQ_STR (array[1], ""); TEST_EQ_STR (array[2], "this"); TEST_EQ_STR (array[3], "is"); TEST_EQ_STR (array[4], "a"); TEST_EQ_STR (array[5], "test"); TEST_EQ_P (array[6], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple different delimiter " "characters at string start"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, " \tthis is a test", " \t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 7); for (i = 0; i < 6; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], ""); TEST_EQ_STR (array[1], ""); TEST_EQ_STR (array[2], "this"); TEST_EQ_STR (array[3], "is"); TEST_EQ_STR (array[4], "a"); TEST_EQ_STR (array[5], "test"); TEST_EQ_P (array[6], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple identical delimiter " "characters within string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "this is a\t\ttest", " \t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 8); for (i = 0; i < 7; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "this"); TEST_EQ_STR (array[1], "is"); TEST_EQ_STR (array[2], ""); TEST_EQ_STR (array[3], ""); TEST_EQ_STR (array[4], "a"); TEST_EQ_STR (array[5], ""); TEST_EQ_STR (array[6], "test"); TEST_EQ_P (array[7], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple different delimiter " "characters within string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "this is \n\ta\ttest", " \t\n", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 7); for (i = 0; i < 6; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "this"); TEST_EQ_STR (array[1], "is"); TEST_EQ_STR (array[2], ""); TEST_EQ_STR (array[3], ""); TEST_EQ_STR (array[4], "a"); TEST_EQ_STR (array[5], "test"); TEST_EQ_P (array[6], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple identical delimiter " "characters at string end"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "this is a test ", " \t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 6); for (i = 0; i < 5; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "this"); TEST_EQ_STR (array[1], "is"); TEST_EQ_STR (array[2], "a"); TEST_EQ_STR (array[3], "test"); TEST_EQ_STR (array[4], ""); TEST_EQ_P (array[5], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple different delimiter " "characters at string end"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "this is a test \t", " \t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 6); for (i = 0; i < 5; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "this"); TEST_EQ_STR (array[1], "is"); TEST_EQ_STR (array[2], "a"); TEST_EQ_STR (array[3], "test"); TEST_EQ_STR (array[4], ""); TEST_EQ_P (array[5], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple identical delimiter " "characters at beginning, middle and end of string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, " this is\n\n\na test\t\t\t", " \t\n", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 12); for (i = 0; i < 11; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], ""); TEST_EQ_STR (array[1], ""); TEST_EQ_STR (array[2], ""); TEST_EQ_STR (array[3], "this"); TEST_EQ_STR (array[4], "is"); TEST_EQ_STR (array[5], ""); TEST_EQ_STR (array[6], ""); TEST_EQ_STR (array[7], "a"); TEST_EQ_STR (array[8], "test"); TEST_EQ_STR (array[9], ""); TEST_EQ_STR (array[10], ""); TEST_EQ_P (array[11], NULL); nih_free (array); } TEST_FEATURE ("with no repeat and multiple different delimiter " "characters at beginning, middle and end of string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, ": \nthis is\t \n:a test:\n ", "\n :\t", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 13); for (i = 0; i < 12; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], ""); TEST_EQ_STR (array[1], ""); TEST_EQ_STR (array[2], ""); TEST_EQ_STR (array[3], "this"); TEST_EQ_STR (array[4], "is"); TEST_EQ_STR (array[5], ""); TEST_EQ_STR (array[6], ""); TEST_EQ_STR (array[7], ""); TEST_EQ_STR (array[8], "a"); TEST_EQ_STR (array[9], "test"); TEST_EQ_STR (array[10], ""); TEST_EQ_STR (array[11], ""); TEST_EQ_P (array[12], NULL); nih_free (array); } /* Check that we can split a string treating multiple consecutive * matching characters as a single separator to be skipped. */ TEST_FEATURE ("with repeat"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "this is a\ttest", " \t", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 5); for (i = 0; i < 4; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "this"); TEST_EQ_STR (array[1], "is"); TEST_EQ_STR (array[2], "a"); TEST_EQ_STR (array[3], "test"); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can split a string containing multiple * occurences of one of the delimiter characters at the * beginning of the string. */ TEST_FEATURE ("with repeat and multiple identical adjacent delimiter characters at string start"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "\n\nhello", " \t\r\n", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 2); for (i = 0; i < 1; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_P (array[1], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple different adjacent delimiter characters at string start"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "\n\r hello", " \t\r\n", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 2); for (i = 0; i < 1; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_P (array[1], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple identical adjacent delimiter " "characters within string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "hello\n\rworld", " \t\n\r", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 3); for (i = 0; i < 2; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_STR (array[1], "world"); TEST_EQ_P (array[2], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple different adjacent delimiter " "characters within string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "hello\n\r\tworld", " \t\n\r", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 3); for (i = 0; i < 2; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_STR (array[1], "world"); TEST_EQ_P (array[2], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple identical adjacent delimiter " "characters at string end"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "hello\n\n\n\n\n\n\n", " \t\r\n", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 2); for (i = 0; i < 1; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_P (array[1], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple different adjacent delimiter " "characters at string end"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "hello \r\t\r\t\n ", " \t\r\n", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 2); for (i = 0; i < 1; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_P (array[1], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple identical adjacent delimiter " "characters at beginning, middle and end of string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, " hello\n\n\n, world\n\n\n", "\r\t\n ", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 4); for (i = 0; i < 3; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_STR (array[1], ","); TEST_EQ_STR (array[2], "world"); TEST_EQ_P (array[3], NULL); nih_free (array); } TEST_FEATURE ("with repeat and multiple different adjacent delimiter " "characters at beginning, middle and end of string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "\n \r\thello\n\n\r , \n\t\rworld\t \r\n \n", " \t\n\r", TRUE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *) * 4); for (i = 0; i < 3; i++) TEST_ALLOC_PARENT (array[i], array); TEST_EQ_STR (array[0], "hello"); TEST_EQ_STR (array[1], ","); TEST_EQ_STR (array[2], "world"); TEST_EQ_P (array[3], NULL); nih_free (array); } /* Check that we can give an empty string, and end up with a * one-element array that only contains a NULL pointer. */ TEST_FEATURE ("with empty string"); TEST_ALLOC_FAIL { array = nih_str_split (NULL, "", " ", FALSE); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *)); TEST_EQ_P (array[0], NULL); nih_free (array); } }
void test_sentinel (void) { char *str; TEST_FUNCTION ("output_sentinel"); /* Check that a header file sentinel is correctly generated for a * local path. */ TEST_FEATURE ("with local path"); TEST_ALLOC_FAIL { str = output_sentinel (NULL, "foo.h"); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, "TEST_FOO_H"); nih_free (str); } /* Check that a header file sentinel is correctly generated for a * sub-directory path. */ TEST_FEATURE ("with sub-directory path"); TEST_ALLOC_FAIL { str = output_sentinel (NULL, "path/to/foo.h"); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, "TEST_PATH_TO_FOO_H"); nih_free (str); } /* Check that a header file sentinel is generated for an absolute * path; we might want to change the format of this later, but it's * ok for now. */ TEST_FEATURE ("with absolute path"); TEST_ALLOC_FAIL { str = output_sentinel (NULL, "/path/to/foo.h"); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, "TEST__PATH_TO_FOO_H"); nih_free (str); } }
void test_cgroup_setting_new (void) { CGroupSetting *setting; nih_local char *parent= NULL; parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FUNCTION ("cgroup_setting_new"); TEST_FEATURE ("no parent, key, no value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (NULL, "foo", NULL); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, NULL); TEST_EQ_STR (setting->key, "foo"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("foo")); TEST_ALLOC_PARENT (setting->key, setting); nih_free (setting); } TEST_FEATURE ("parent, key, no value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (parent, "hello world", NULL); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, parent); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); nih_free (setting); } TEST_FEATURE ("no parent, key, value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (NULL, "hello world", "a value"); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, NULL); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); TEST_EQ_STR (setting->value, "a value"); TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value")); TEST_ALLOC_PARENT (setting->value, setting); nih_free (setting); } TEST_FEATURE ("parent, key, value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (parent, "hello world", "a value"); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, parent); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); TEST_EQ_STR (setting->value, "a value"); TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value")); TEST_ALLOC_PARENT (setting->value, setting); nih_free (setting); } }
void test_expand (void) { NihError *error; char *env[7], *str; TEST_FUNCTION ("environ_expand"); env[0] = "FOO=frodo"; env[1] = "BAR=bilbo"; env[2] = "BAZ=xx"; env[3] = "HOBBIT=FOO"; env[4] = "NULL="; env[5] = "DOH=oops"; env[6] = NULL; nih_error_push_context(); nih_error_pop_context (); /* Check that we can expand a string containing no expansion. */ TEST_FEATURE ("with no expansion"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "this is a test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "this is a test"); nih_free (str); } /* Check that we can expand a simple string containing a reference * from the environment, with the reference replaced by the environment * variable value. */ TEST_FEATURE ("with simple expansion"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "this is a $FOO test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "this is a frodo test"); nih_free (str); } /* Check that we can expand a simple string containing a reference * from the environment that is smaller than the reference, with the * reference replaced by the environment variable value. */ TEST_FEATURE ("with simple expansion of smaller value"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "this is a $BAZ test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "this is a xx test"); nih_free (str); } /* Check that we can expand a simple string containing a reference * from the environment that is exactly the same size as the * reference, with the reference replaced by the environment variable * value. */ TEST_FEATURE ("with simple expansion of same size value"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "this is a $DOH test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "this is a oops test"); nih_free (str); } /* Check that we can expand a string containing multiple simple * references, with each replaced by the variable value. */ TEST_FEATURE ("with multiple simple expansions"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "test $FOO $BAR$BAZ", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "test frodo bilboxx"); nih_free (str); } /* Check that we can expand a string containing a bracketed * reference, allowing it to nestle against other alphanumerics. */ TEST_FEATURE ("with simple bracketed expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${BAR}test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "bilbotest"); nih_free (str); } /* Check that we can expand a string containing multiple bracketed * references, allowing it to nestle against other alphanumerics. */ TEST_FEATURE ("with multiple simple bracketed expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${BAR}${FOO}test${BAZ}", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "bilbofrodotestxx"); nih_free (str); } /* Check that simple expressions may appear within bracketed * expressions, causing them to be evaluted and the evalution * serving as the reference. */ TEST_FEATURE ("with simple expression inside bracketed expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${$HOBBIT} baggins", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "frodo baggins"); nih_free (str); } /* Check that bracketed expressions may appear within bracketed * expressions. */ TEST_FEATURE ("with bracketed expression inside bracketed expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${${HOBBIT}} baggins", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "frodo baggins"); nih_free (str); } /* Check that we can substitute a default value if the variable * we were after was unset. */ TEST_FEATURE ("with bracketed default expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${MEEP-a }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "a test"); nih_free (str); } /* Check that a default expression uses the environment value if * it is actually set. */ TEST_FEATURE ("with bracketed default expression for set variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${BAZ-a }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "xxtest"); nih_free (str); } /* Check that a default expression uses the environment value if * it is actually set, even if it is NULL. */ TEST_FEATURE ("with bracketed default expression for null variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${NULL-a }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "test"); nih_free (str); } /* Check that we can substitute a default value if the variable * we were after was unset (or null). */ TEST_FEATURE ("with bracketed default or null expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${MEEP:-a }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "a test"); nih_free (str); } /* Check that a default or null expression uses the environment value * if it is actually set and not null. */ TEST_FEATURE ("with bracketed default or null expression for set variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${BAZ:-a }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "xxtest"); nih_free (str); } /* Check that we can substitute a default value if the variable * we were after was null. */ TEST_FEATURE ("with bracketed default or null expression for null variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${NULL:-a }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "a test"); nih_free (str); } /* Check that we don't substitute an alternate value if the * variable we were after was unset. */ TEST_FEATURE ("with bracketed alternate expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${MEEP+good }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "test"); nih_free (str); } /* Check that we use the alternate value if the environment variable * is actually set. */ TEST_FEATURE ("with bracketed alternate expression for set variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${BAZ+good }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "good test"); nih_free (str); } /* Check that we use the alternate value if the environment variable * is set, even if it is NULL. */ TEST_FEATURE ("with bracketed alternate expression for null variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${NULL+good }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "good test"); nih_free (str); } /* Check that we don't substitute an alternate value if the * variable we were after was unset (or null). */ TEST_FEATURE ("with bracketed alternate or null expression"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${MEEP:+good }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "test"); nih_free (str); } /* Check that we use the alternate value if the environment variable * is actually set and not null. */ TEST_FEATURE ("with bracketed alternate or null expression for set variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${BAZ:+good }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "good test"); nih_free (str); } /* Check that we don't substitute an alternate value if the * variable we were after was set, but was null. */ TEST_FEATURE ("with bracketed alternate or null expression for null variable"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${NULL:+good }test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "test"); nih_free (str); } /* Check that references on either side of an expression are * expanded before evaluation. */ TEST_FEATURE ("with references in bracketed expression argument"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${$BAZ:-${$HOBBIT}}test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "frodotest"); nih_free (str); } /* Check that a literal dollar sign with no following text is * treated just as a dollar sign. */ TEST_FEATURE ("with dollar sign in whitespace"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "this is a $ test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "this is a $ test"); nih_free (str); } /* Check that a literal dollar sign in text can be followed by empty * brackets to be just as a dollar sign. */ TEST_FEATURE ("with bracketed dollar sign"); TEST_ALLOC_FAIL { str = environ_expand (NULL, "${}test", env); if (test_alloc_failed) { TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENOMEM); nih_free (error); continue; } TEST_EQ_STR (str, "$test"); nih_free (str); } /* Check that attempting to expand an unknown variable results in * an error being raised. */ TEST_FEATURE ("with simple expansion of unknown variable"); str = environ_expand (NULL, "this is a $WIBBLE test", env); TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENVIRON_UNKNOWN_PARAM); nih_free (error); /* Check that attempting to expand an unknown variable results in * an error being raised. */ TEST_FEATURE ("with bracketed expansion of unknown variable"); str = environ_expand (NULL, "this is a ${WIBBLE} test", env); TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENVIRON_UNKNOWN_PARAM); nih_free (error); /* Check that attempting to expand an unknown variable results in * an error being raised. */ TEST_FEATURE ("with expansion of unknown variable within expression name"); str = environ_expand (NULL, "this is a ${$WIBBLE:-$FOO} test", env); TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENVIRON_UNKNOWN_PARAM); nih_free (error); /* Check that attempting to expand an unknown variable results in * an error being raised. */ TEST_FEATURE ("with expansion of unknown variable within expression argument"); str = environ_expand (NULL, "this is a ${$FOO:-$WIBBLE} test", env); TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENVIRON_UNKNOWN_PARAM); nih_free (error); /* Check that inventing a new operator results in an error * being raised. */ TEST_FEATURE ("with unknown operator in expression"); str = environ_expand (NULL, "this is a ${$FOO:!$BAR test", env); TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENVIRON_EXPECTED_OPERATOR); nih_free (error); /* Check that forgetting to close a brace results in an error * being raised. */ TEST_FEATURE ("with missing close brace after expression"); str = environ_expand (NULL, "this is a ${$FOO:-$BAR test", env); TEST_EQ_P (str, NULL); error = nih_error_get (); TEST_EQ (error->number, ENVIRON_MISMATCHED_BRACES); nih_free (error); }
void test_str_screen_wrap (void) { char *str = NULL; struct winsize winsize; int pty, pts; TEST_FUNCTION ("nih_str_screen_wrap"); unsetenv ("COLUMNS"); winsize.ws_row = 24; winsize.ws_col = 40; winsize.ws_xpixel = 0; winsize.ws_ypixel = 0; openpty (&pty, &pts, NULL, NULL, &winsize); /* Check that we correctly wrap text to the width of the screen * when it is available. */ TEST_FEATURE ("with screen width"); TEST_ALLOC_FAIL { TEST_DIVERT_STDOUT_FD (pts) { str = nih_str_screen_wrap ( NULL, ("this is a string that " "should need wrapping at " "any different screen width " "that we choose to set"), 0, 0); } if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("this is a string that should need\n" "wrapping at any different screen width\n" "that we choose to set")); nih_free (str); } /* Check that we wrap at the number specified in the COLUMNS * variable in preference to the width of the screen. */ TEST_FEATURE ("with COLUMNS variable"); putenv ("COLUMNS=30"); TEST_ALLOC_FAIL { TEST_DIVERT_STDOUT_FD (pts) { str = nih_str_screen_wrap ( NULL, ("this is a string that " "should need wrapping at " "any different screen width " "that we choose to set"), 0, 0); } if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("this is a string that should\n" "need wrapping at any\n" "different screen width that\n" "we choose to set")); nih_free (str); } unsetenv ("COLUMNS"); close (pts); close (pty); /* Check that we fallback to assuming 80 columns if we don't have * any luck with either the tty or COLUMNS variable. */ TEST_FEATURE ("with fallback to 80 columns"); pts = open ("/dev/null", O_RDWR | O_NOCTTY); TEST_ALLOC_FAIL { TEST_DIVERT_STDOUT_FD (pts) { str = nih_str_screen_wrap ( NULL, ("this is a string that " "should need wrapping at " "any different screen width " "that we choose to set"), 0, 0); } if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("this is a string that should need " "wrapping at any different screen width " "that\n" "we choose to set")); nih_free (str); } close (pts); }