示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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);
	}
}
示例#4
0
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);
	}
}
示例#5
0
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);
}
示例#6
0
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);
}
示例#7
0
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);
}
示例#8
0
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);
}
示例#9
0
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);
}
示例#10
0
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");
	}
}
示例#11
0
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);
}
示例#12
0
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);
	}
}
示例#13
0
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);
    }
}
示例#14
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");
}
示例#15
0
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);
}
示例#16
0
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);
}
示例#17
0
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);
}
示例#18
0
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);

	/*******************************************************************/

}
示例#19
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);
	}
}
示例#20
0
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);
	}
}
示例#21
0
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);
	}
}
示例#22
0
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);
	}
}
示例#23
0
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);
    }
}
示例#24
0
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);
}
示例#25
0
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);
    }
}
示例#26
0
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);
    }
}
示例#27
0
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);
    }
}
示例#28
0
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);
    }
}
示例#29
0
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);
}
示例#30
0
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);
}