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_set_pidfile (void) { const char *filename, *ptr; TEST_FUNCTION ("nih_main_set_pidfile"); program_name = "test"; /* Check that we can set a pidfile for use, and have the string * copied and returned. */ TEST_FEATURE ("with new location"); filename = "/path/to/pid"; nih_main_set_pidfile (filename); ptr = nih_main_get_pidfile (); TEST_EQ_STR (ptr, filename); TEST_NE_P (ptr, filename); /* Check that we can pass NULL to have the default location set * instead. */ TEST_FEATURE ("with default location"); nih_main_set_pidfile (NULL); ptr = nih_main_get_pidfile (); TEST_EQ_STR (ptr, "/var/run/test.pid"); nih_main_set_pidfile (NULL); }
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_init_gettext (void) { /* Check that the macro to initialise gettext sets the text domain to * the PACKAGE_NAME macro, and binds that to the LOCALEDIR macro. */ TEST_FUNCTION ("nih_main_init_gettext"); nih_main_init_gettext(); TEST_EQ_STR (textdomain (NULL), PACKAGE_NAME); TEST_EQ_STR (bindtextdomain (PACKAGE_NAME, NULL), LOCALEDIR); }
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_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_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_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 print_my_cgroup(void) { char *str; str = get_pid_cgroup("freezer", getpid()); if (str) { nih_warn("I am in freezer cgroup: %s", str); TEST_EQ_STR(str, "/"); nih_free(str); } else { TEST_FAILED("Failed to get my freezer cgroup"); } }
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_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_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_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_array_append (void) { char **array, **args, **ret; size_t len; TEST_FUNCTION ("nih_str_array_append"); args = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "this")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "is")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "a")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "test")); /* Check that we can append one array onto the end of the other, * and that the array is extended and each new element copied * into the new array. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { len = 0; TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&array, NULL, &len, "foo")); NIH_MUST (nih_str_array_add (&array, NULL, &len, "bar")); } ret = nih_str_array_append (&array, NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (array[0], "foo"); TEST_EQ_STR (array[1], "bar"); TEST_EQ_P (array[2], NULL); nih_free (array); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 6); TEST_EQ_STR (array[0], "foo"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "bar"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "this"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "is"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_STR (array[4], "a"); TEST_ALLOC_PARENT (array[4], array); TEST_EQ_STR (array[5], "test"); TEST_ALLOC_PARENT (array[5], array); TEST_EQ_P (array[6], NULL); nih_free (array); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&array, NULL, NULL, "foo")); NIH_MUST (nih_str_array_add (&array, NULL, NULL, "bar")); } ret = nih_str_array_append (&array, NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_STR (array[0], "foo"); TEST_EQ_STR (array[1], "bar"); TEST_EQ_P (array[2], NULL); nih_free (array); continue; } TEST_NE_P (ret, NULL); TEST_EQ_STR (array[0], "foo"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "bar"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "this"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "is"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_STR (array[4], "a"); TEST_ALLOC_PARENT (array[4], array); TEST_EQ_STR (array[5], "test"); TEST_ALLOC_PARENT (array[5], array); TEST_EQ_P (array[6], NULL); nih_free (array); } /* Check that we can pass a NULL array to get a copy of it, with * the returned length containing the new length. */ TEST_FEATURE ("with NULL array and length"); TEST_ALLOC_FAIL { len = 0; array = NULL; ret = nih_str_array_append (&array, NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (array, NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can pass a NULL array to get a copy of it, without * passing the length in. */ TEST_FEATURE ("with NULL array and no length"); TEST_ALLOC_FAIL { array = NULL; ret = nih_str_array_append (&array, NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array, NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } nih_free (args); }
void test_array_copy (void) { char **array, **args; size_t len; TEST_FUNCTION ("nih_str_array_copy"); args = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "this")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "is")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "a")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "test")); /* Check that we can make a copy of an array, with each element * a copy of the last. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { len = 0; array = nih_str_array_copy (NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ (len, 4); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { array = nih_str_array_copy (NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } nih_free (args); /* Check that we can make a copy of an array with a single NULL * element and have the same returned. */ TEST_FEATURE ("with zero-length array"); args = NIH_MUST (nih_str_array_new (NULL)); TEST_ALLOC_FAIL { len = 0; array = nih_str_array_copy (NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ (len, 0); TEST_EQ_P (array[0], NULL); nih_free (array); } nih_free (args); }
void test_cgroup_job_start (void) { char confdir[PATH_MAX]; char logdir[PATH_MAX]; char flagfile[PATH_MAX]; nih_local char *cmd = NULL; pid_t dbus_pid = 0; pid_t upstart_pid = 0; char **output; size_t lines; size_t len; nih_local char *logfile = NULL; nih_local char *logfile_name = NULL; nih_local char *contents = NULL; if (geteuid ()) { printf ("INFO: skipping %s tests as not running as root\n", __func__); fflush (NULL); return; } TEST_GROUP ("cgroup manager handling"); TEST_FILENAME (confdir); TEST_EQ (mkdir (confdir, 0755), 0); TEST_FILENAME (logdir); TEST_EQ (mkdir (logdir, 0755), 0); TEST_FILENAME (flagfile); /* Use the "secret" interface */ TEST_EQ (setenv ("UPSTART_CONFDIR", confdir, 1), 0); TEST_EQ (setenv ("UPSTART_LOGDIR", logdir, 1), 0); TEST_DBUS (dbus_pid); /*******************************************************************/ TEST_FEATURE ("Ensure startup job does not start until cgmanager available"); contents = nih_sprintf (NULL, "start on startup\n" "\n" "cgroup memory mem-%s\n" "\n" "exec echo hello\n", __func__); TEST_NE_P (contents, NULL); CREATE_FILE (confdir, "cgroup.conf", contents); logfile_name = NIH_MUST (nih_sprintf (NULL, "%s/%s", logdir, "cgroup.log")); start_upstart_common (&upstart_pid, FALSE, FALSE, confdir, logdir, NULL); cmd = nih_sprintf (NULL, "%s status %s 2>&1", get_initctl (), "cgroup"); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 1); /* job should *NOT* start on startup */ TEST_EQ_STR (output[0], "cgroup stop/waiting"); nih_free (output); TEST_FALSE (file_exists (logfile_name)); cmd = nih_sprintf (NULL, "%s notify-cgroup-manager-address %s 2>&1", get_initctl (), CGMANAGER_DBUS_SOCK); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 0); WAIT_FOR_FILE (logfile_name); logfile = nih_file_read (NULL, logfile_name, &len); TEST_NE_P (logfile, NULL); TEST_EQ_STR (logfile, "hello\r\n"); DELETE_FILE (confdir, "cgroup.conf"); assert0 (unlink (logfile_name)); /*******************************************************************/ TEST_FEATURE ("Ensure bogus cgroups don't crash init"); contents = nih_sprintf (NULL, "cgroup name\n" "\n" "exec echo hello\n"); TEST_NE_P (contents, NULL); CREATE_FILE (confdir, "cgroup-name.conf", contents); logfile_name = NIH_MUST (nih_sprintf (NULL, "%s/%s", logdir, "cgroup-name.log")); cmd = nih_sprintf (NULL, "%s status %s 2>&1", get_initctl (), "cgroup-name"); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 1); /* job is not running yet */ TEST_EQ_STR (output[0], "cgroup-name stop/waiting"); nih_free (output); TEST_FALSE (file_exists (logfile_name)); cmd = nih_sprintf (NULL, "%s start %s 2>&1", get_initctl (), "cgroup-name"); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 1); TEST_EQ_STR (output[0], "initctl: Job failed to start"); DELETE_FILE (confdir, "cgroup-name.conf"); /*******************************************************************/ STOP_UPSTART (upstart_pid); TEST_DBUS_END (dbus_pid); TEST_EQ (rmdir (confdir), 0); TEST_EQ (rmdir (logdir), 0); /*******************************************************************/ }
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_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_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_wrap (void) { char *str; TEST_FUNCTION ("nih_str_wrap"); /* Check that a string smaller than the wrap length is returned * unaltered. */ TEST_FEATURE ("with no wrapping"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, "this is a test", 80, 0, 0); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, "this is a test"); nih_free (str); } /* Check that a string with embedded new lines is returned with * the line breaks preserved. */ TEST_FEATURE ("with embedded newlines"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, "this is\na test", 80, 0, 0); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, "this is\na test"); nih_free (str); } /* Check that a smaller string is indented if one is given. */ TEST_FEATURE ("with no wrapping and indent"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, "this is a test", 80, 2, 0); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, " this is a test"); nih_free (str); } /* Check that a string with embedded newlines gets an indent on * each new line. */ TEST_FEATURE ("with embedded newlines and indent"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, "this is\na test", 80, 4, 2); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, " this is\n a test"); nih_free (str); } /* Check that a long string is split at the wrap point. */ TEST_FEATURE ("with simple wrapping"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, "this is an example of a string " "that will need wrapping to fit the line " "length we set", 20, 0, 0); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("this is an example\n" "of a string that\n" "will need wrapping\n" "to fit the line\n" "length we set")); nih_free (str); } /* Check that a long string is split at the wrap point, and each * new line indented, with the first line given a different indent. */ TEST_FEATURE ("with wrapping and indents"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, "this is an example of a string " "that will need wrapping to fit the line " "length we set", 20, 4, 2); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, (" this is an\n" " example of a\n" " string that will\n" " need wrapping to\n" " fit the line\n" " length we set")); nih_free (str); } /* Check that a long string that would be split inside a long word * is wrapepd before the word, and then split inside that word if it * is still too long. */ TEST_FEATURE ("with split inside word"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, ("this string is supercalifragilis" "ticexpialidocious even though the " "sound of it is something quite " "atrocious"), 30, 0, 0); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, ("this string is\n" "supercalifragilisticexpialidoc\n" "ious even though the sound of\n" "it is something quite\n" "atrocious")); nih_free (str); } /* Check that an indent is still applied if the split occurs inside * a word. */ TEST_FEATURE ("with split inside word and indents"); TEST_ALLOC_FAIL { str = nih_str_wrap (NULL, ("this string is supercalifragilis" "ticexpialidocious even though the " "sound of it is something quite " "atrocious"), 30, 4, 2); if (test_alloc_failed) { TEST_EQ_P (str, NULL); continue; } TEST_EQ_STR (str, (" this string is\n" " supercalifragilisticexpialid\n" " ocious even though the sound\n" " of it is something quite\n" " atrocious")); nih_free (str); } }
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); }
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 (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_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_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_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_operator_environment (void) { EventOperator *root, *oper1, *oper2, *oper3, *oper4, *oper5, *oper6; Event *event1, *event2, *event3; char **env, **ptr; size_t len; TEST_FUNCTION ("event_operator_environment"); root = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper1 = event_operator_new (root, EVENT_AND, NULL, NULL); oper2 = event_operator_new (root, EVENT_AND, NULL, NULL); oper3 = event_operator_new (root, EVENT_MATCH, "foo", NULL); oper4 = event_operator_new (root, EVENT_MATCH, "bar", NULL); oper5 = event_operator_new (root, EVENT_MATCH, "frodo", NULL); oper6 = event_operator_new (root, EVENT_MATCH, "bilbo", NULL); nih_tree_add (&root->node, &oper1->node, NIH_TREE_LEFT); nih_tree_add (&root->node, &oper2->node, NIH_TREE_RIGHT); nih_tree_add (&oper1->node, &oper3->node, NIH_TREE_LEFT); nih_tree_add (&oper1->node, &oper4->node, NIH_TREE_RIGHT); nih_tree_add (&oper2->node, &oper5->node, NIH_TREE_LEFT); nih_tree_add (&oper2->node, &oper6->node, NIH_TREE_RIGHT); root->value = TRUE; oper1->value = TRUE; oper3->value = TRUE; oper3->event = event1 = event_new (NULL, "foo", NULL); event_block (oper3->event); NIH_MUST (nih_str_array_add (&oper3->event->env, oper3->event, NULL, "FOO=APPLE")); NIH_MUST (nih_str_array_add (&oper3->event->env, oper3->event, NULL, "TEA=YES")); oper4->value = TRUE; oper4->event = event2 = event_new (NULL, "bar", NULL); event_block (oper4->event); NIH_MUST (nih_str_array_add (&oper4->event->env, oper4->event, NULL, "BAR=ORANGE")); NIH_MUST (nih_str_array_add (&oper4->event->env, oper4->event, NULL, "COFFEE=NO")); oper6->value = TRUE; oper6->event = event3 = event_new (NULL, "bilbo", NULL); event_block (oper6->event); NIH_MUST (nih_str_array_add (&oper6->event->env, oper6->event, NULL, "FRODO=BAGGINS")); NIH_MUST (nih_str_array_add (&oper6->event->env, oper6->event, NULL, "BILBO=WIBBLE")); /* Check that the environment from each of the events is appended * to the passed array; except for the event that was matched but not * in the true tree. */ TEST_FEATURE ("with environment table"); TEST_ALLOC_FAIL { env = NULL; len = 0; ptr = event_operator_environment (root, &env, NULL, &len, NULL); if (test_alloc_failed) { TEST_EQ_P (ptr, NULL); if (env) nih_free (env); continue; } TEST_NE_P (env, NULL); TEST_ALLOC_SIZE (env, sizeof (char *) * 5); TEST_EQ (len, 4); TEST_ALLOC_PARENT (env[0], env); TEST_EQ_STR (env[0], "FOO=APPLE"); TEST_ALLOC_PARENT (env[1], env); TEST_EQ_STR (env[1], "TEA=YES"); TEST_ALLOC_PARENT (env[2], env); TEST_EQ_STR (env[2], "BAR=ORANGE"); TEST_ALLOC_PARENT (env[3], env); TEST_EQ_STR (env[3], "COFFEE=NO"); TEST_EQ_P (env[4], NULL); nih_free (env); } /* Check that if we also give the name of an environment variable, * this will contain a space-separated list of the event names. */ TEST_FEATURE ("with environment variable for event list"); TEST_ALLOC_FAIL { env = NULL; len = 0; ptr = event_operator_environment (root, &env, NULL, &len, "UPSTART_EVENTS"); if (test_alloc_failed) { TEST_EQ_P (ptr, NULL); if (env) nih_free (env); continue; } TEST_NE_P (env, NULL); TEST_ALLOC_SIZE (env, sizeof (char *) * 6); TEST_EQ (len, 5); TEST_ALLOC_PARENT (env[0], env); TEST_EQ_STR (env[0], "FOO=APPLE"); TEST_ALLOC_PARENT (env[1], env); TEST_EQ_STR (env[1], "TEA=YES"); TEST_ALLOC_PARENT (env[2], env); TEST_EQ_STR (env[2], "BAR=ORANGE"); TEST_ALLOC_PARENT (env[3], env); TEST_EQ_STR (env[3], "COFFEE=NO"); TEST_ALLOC_PARENT (env[4], env); TEST_EQ_STR (env[4], "UPSTART_EVENTS=foo bar"); TEST_EQ_P (env[5], NULL); nih_free (env); } /* Check that if no events are matched the environment table only * has an empty events list. */ TEST_FEATURE ("with no matches"); TEST_ALLOC_FAIL { env = NULL; len = 0; ptr = event_operator_environment (oper5, &env, NULL, &len, "UPSTART_EVENTS"); if (test_alloc_failed) { TEST_EQ_P (ptr, NULL); if (env) nih_free (env); continue; } TEST_NE_P (env, NULL); TEST_ALLOC_SIZE (env, sizeof (char *) * 2); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_EQ_STR (env[0], "UPSTART_EVENTS="); TEST_EQ_P (env[1], NULL); nih_free (env); } nih_free (root); nih_free (event1); nih_free (event2); nih_free (event3); }