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_array_add (void) { char **array, **ret; size_t len; /* Check that we can append strings to a NULL-terminated array. */ TEST_FUNCTION ("nih_str_array_add"); array = nih_str_array_new (NULL); len = 0; TEST_ALLOC_FAIL { ret = nih_str_array_add (&array, NULL, &len, "test"); 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_all_valid (void) { char **env; int valid; TEST_FUNCTION ("environ_all_valid"); /* Check that a valid environment table returns TRUE. */ TEST_FEATURE ("with valid table"); env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, NULL, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, NULL, "BAR=BAZ")); valid = environ_all_valid (env); TEST_TRUE (valid); nih_free (env); /* Check that an empty environment table is valid. */ TEST_FEATURE ("with empty table"); env = nih_str_array_new (NULL); valid = environ_all_valid (env); TEST_TRUE (valid); nih_free (env); /* Check that an entry without an equals means the table is not * valid. */ TEST_FEATURE ("with missing equals"); env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, NULL, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, NULL, "BAR")); assert (nih_str_array_add (&env, NULL, NULL, "WIBBLE=woo")); valid = environ_all_valid (env); TEST_FALSE (valid); nih_free (env); }
/** * env_option: * @option: NihOption invoked, * @arg: argument to parse. * * This option setter is used to append @arg to the list of environment * variables pointed to by the value member of option, which must be a * pointer to a char **. * * The arg_name member of @option must not be NULL. * * Returns: zero on success, non-zero on error. **/ int env_option (NihOption *option, const char *arg) { char ***value; nih_assert (option != NULL); nih_assert (option->value != NULL); nih_assert (arg != NULL); value = (char ***)option->value; NIH_MUST (nih_str_array_add (value, NULL, NULL, arg)); return 0; }
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_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_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); }
void test_operator_new (void) { EventOperator *oper; char **env; TEST_FUNCTION ("event_operator_new"); /* Check that we can create a new EventOperator structure to match * an event, and have the details filled in and returned. It * should not be placed into any tree structure. */ TEST_FEATURE ("with EVENT_MATCH"); TEST_ALLOC_FAIL { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); if (test_alloc_failed) { TEST_EQ_P (oper, NULL); continue; } TEST_ALLOC_SIZE (oper, sizeof (EventOperator)); TEST_EQ_P (oper->node.parent, NULL); TEST_EQ_P (oper->node.left, NULL); TEST_EQ_P (oper->node.right, NULL); TEST_EQ (oper->value, FALSE); TEST_EQ_STR (oper->name, "test"); TEST_ALLOC_PARENT (oper->name, oper); TEST_EQ_P (oper->env, NULL); TEST_EQ_P (oper->event, NULL); nih_free (oper); } /* Check that environment passed to event_operator_new is reparented * to belong to the structure itself. */ TEST_FEATURE ("with EVENT_MATCH and environment"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { env = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&env, NULL, NULL, "foo")); NIH_MUST (nih_str_array_add (&env, NULL, NULL, "BAR=frodo")); } oper = event_operator_new (NULL, EVENT_MATCH, "test", env); if (test_alloc_failed) { TEST_EQ_P (oper, NULL); TEST_ALLOC_PARENT (env, NULL); nih_free (env); continue; } nih_discard (env); TEST_ALLOC_SIZE (oper, sizeof (EventOperator)); TEST_EQ_P (oper->node.parent, NULL); TEST_EQ_P (oper->node.left, NULL); TEST_EQ_P (oper->node.right, NULL); TEST_EQ (oper->value, FALSE); TEST_EQ_STR (oper->name, "test"); TEST_ALLOC_PARENT (oper->name, oper); TEST_EQ_P (oper->env, env); TEST_ALLOC_PARENT (oper->env, oper); TEST_EQ_P (oper->event, NULL); nih_free (oper); } /* Check that an ordinary operator needs no name attached. */ TEST_FEATURE ("with EVENT_OR"); TEST_ALLOC_FAIL { oper = event_operator_new (NULL, EVENT_OR, NULL, NULL); if (test_alloc_failed) { TEST_EQ_P (oper, NULL); continue; } TEST_ALLOC_SIZE (oper, sizeof (EventOperator)); TEST_EQ_P (oper->node.parent, NULL); TEST_EQ_P (oper->node.left, NULL); TEST_EQ_P (oper->node.right, NULL); TEST_EQ (oper->value, FALSE); TEST_EQ_P (oper->name, NULL); TEST_EQ_P (oper->env, NULL); TEST_EQ_P (oper->event, NULL); nih_free (oper); } }
void test_operator_copy (void) { EventOperator *oper = NULL, *copy; EventOperator *oper1 = NULL, *oper2 = NULL, *copy1, *copy2; TEST_FUNCTION ("event_operator_copy"); event_init (); /* Check that we can copy a plain event operator, the value should * be copied as well, and the other fields left as NULL. */ TEST_FEATURE ("with EVENT_OR"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper->value = TRUE; } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_OR); TEST_EQ (copy->value, TRUE); TEST_EQ_P (copy->name, NULL); TEST_EQ_P (copy->env, NULL); TEST_EQ_P (copy->event, NULL); nih_free (copy); nih_free (oper); } /* Check that we can copy and EVENT_MATCH operator which does not * have any environment or matched event. */ TEST_FEATURE ("with EVENT_MATCH and no environment or event"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); oper->value = TRUE; } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_MATCH); TEST_EQ (copy->value, TRUE); TEST_EQ_STR (copy->name, "test"); TEST_ALLOC_PARENT (copy->name, copy); TEST_EQ_P (copy->env, NULL); TEST_EQ_P (copy->event, NULL); nih_free (copy); nih_free (oper); } /* Check that environment to an EVENT_MATCH operator are also copied, * and each entry within the array copied too. */ TEST_FEATURE ("with EVENT_MATCH and environment"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); oper->value = TRUE; NIH_MUST (nih_str_array_add (&oper->env, oper, NULL, "FOO=foo")); NIH_MUST (nih_str_array_add (&oper->env, oper, NULL, "BAR=bar")); } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_MATCH); TEST_EQ (copy->value, TRUE); TEST_EQ_STR (copy->name, "test"); TEST_ALLOC_PARENT (copy->name, copy); TEST_ALLOC_PARENT (copy->env, copy); TEST_ALLOC_SIZE (copy->env, sizeof (char *) * 3); TEST_ALLOC_PARENT (copy->env[0], copy->env); TEST_ALLOC_PARENT (copy->env[1], copy->env); TEST_EQ_STR (copy->env[0], "FOO=foo"); TEST_EQ_STR (copy->env[1], "BAR=bar"); TEST_EQ_P (copy->env[2], NULL); TEST_EQ_P (copy->event, NULL); nih_free (copy); nih_free (oper); } /* Check that if the EVENT_MATCH operator has a referenced event, * the event is copied and referenced a second time. */ TEST_FEATURE ("with EVENT_MATCH and referenced event"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); oper->value = TRUE; oper->event = event_new (oper, "test", NULL); event_block (oper->event); } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_MATCH); TEST_EQ (copy->value, TRUE); TEST_EQ_STR (copy->name, "test"); TEST_ALLOC_PARENT (copy->name, copy); TEST_EQ_P (copy->env, NULL); TEST_EQ_P (copy->event, oper->event); TEST_EQ (copy->event->blockers, 2); nih_free (copy); nih_free (oper); } /* Check that if the operator has children, these are copied as * well, including their state. */ TEST_FEATURE ("with children"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper->value = TRUE; oper1 = event_operator_new (NULL, EVENT_MATCH, "foo", NULL); oper1->value = TRUE; oper1->event = event_new (oper1, "foo", NULL); event_block (oper1->event); nih_tree_add (&oper->node, &oper1->node, NIH_TREE_LEFT); oper2 = event_operator_new (NULL, EVENT_MATCH, "bar", NULL); oper2->value = TRUE; oper2->event = event_new (oper2, "foo", NULL); event_block (oper2->event); nih_tree_add (&oper->node, &oper2->node, NIH_TREE_RIGHT); } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); TEST_EQ (oper1->event->blockers, 1); nih_free (oper1); TEST_EQ (oper2->event->blockers, 1); nih_free (oper2); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_NE_P (copy->node.left, NULL); TEST_NE_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_OR); TEST_EQ (copy->value, TRUE); TEST_EQ_P (copy->name, NULL); TEST_EQ_P (copy->env, NULL); copy1 = (EventOperator *)copy->node.left; TEST_ALLOC_SIZE (copy1, sizeof (EventOperator)); TEST_ALLOC_PARENT (copy1, copy); TEST_EQ_P (copy1->node.parent, ©->node); TEST_EQ_P (copy1->node.left, NULL); TEST_EQ_P (copy1->node.right, NULL); TEST_EQ (copy1->type, EVENT_MATCH); TEST_EQ (copy1->value, TRUE); TEST_EQ_STR (copy1->name, "foo"); TEST_ALLOC_PARENT (copy1->name, copy1); TEST_EQ_P (copy1->env, NULL); TEST_EQ_P (copy1->event, oper1->event); TEST_EQ (copy1->event->blockers, 2); nih_free (copy1); copy2 = (EventOperator *)copy->node.right; TEST_ALLOC_SIZE (copy2, sizeof (EventOperator)); TEST_ALLOC_PARENT (copy2, copy); TEST_EQ_P (copy2->node.parent, ©->node); TEST_EQ_P (copy2->node.left, NULL); TEST_EQ_P (copy2->node.right, NULL); TEST_EQ (copy2->type, EVENT_MATCH); TEST_EQ (copy2->value, TRUE); TEST_EQ_STR (copy2->name, "bar"); TEST_ALLOC_PARENT (copy2->name, copy2); TEST_EQ_P (copy2->env, NULL); TEST_EQ_P (copy2->event, oper2->event); TEST_EQ (copy2->event->blockers, 2); nih_free (copy2); nih_free (copy); nih_free (oper1); nih_free (oper2); nih_free (oper); } event_poll (); }