/* -----------------------------------------------------------
Function: void TestANMProteinRRT::run()

Description:
Runs all the basic tests for a this test suite.

In:
void

Out:
void
-----------------------------------------------------------------*/
void TestANMProteinRRT::run(){
	Test::run();

	//----------------------------------------------------
	//TEST_FUNCTION(test_rrt_build)
	TEST_FUNCTION(test_solve_weights)
	//TEST_FUNCTION(test_expansion)
	//TEST_FUNCTION(test_sampling)
	//TEST_FUNCTION(test_angular_weight_metric)
	//TEST_FUNCTION(test_cartesian_weight_metric)
	//-----------------------------------------------------

	finish();
}
Ejemplo n.º 2
0
void
test_read_pidfile (void)
{
	FILE *f;
	char  filename[PATH_MAX];

	TEST_FUNCTION ("nih_main_read_pidfile");
	TEST_FILENAME (filename);
	nih_main_set_pidfile (filename);

	/* Check that reading from a valid pid file will return the pid
	 * stored there.
	 */
	TEST_FEATURE ("with valid pid file");
	f = fopen (filename, "w");
	fprintf (f, "1234\n");
	fclose (f);

	TEST_EQ (nih_main_read_pidfile (), 1234);


	/* Check that reading from a pid file without a newline will still
	 * return the pid stored there.
	 */
	TEST_FEATURE ("with no newline in pid file");
	f = fopen (filename, "w");
	fprintf (f, "1234");
	fclose (f);

	TEST_EQ (nih_main_read_pidfile (), 1234);


	/* Check that reading from an invalid pid file returns -1. */
	TEST_FEATURE ("with invalid pid file");
	f = fopen (filename, "w");
	fprintf (f, "foo\n1234\n");
	fclose (f);

	TEST_EQ (nih_main_read_pidfile (), -1);


	/* Check that reading from a non-existant pid file returns -1. */
	TEST_FEATURE ("with non-existant pid file");
	nih_main_unlink_pidfile ();

	TEST_EQ (nih_main_read_pidfile (), -1);


	nih_main_set_pidfile (NULL);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
void
test_get (void)
{
	char       **env = NULL;
	size_t       len = 0;
	const char  *ret;

	TEST_FUNCTION ("environ_get");

	len = 0;
	env = nih_str_array_new (NULL);


	/* Check that an empty table always returns NULL. */
	TEST_FEATURE ("with empty table");
	ret = environ_get (env, "FOO");

	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_get (env, "BAR");

	TEST_EQ_STR (ret, "BAZ");


	/* Check that a key that doesn't exist returns NULL. */
	TEST_FEATURE ("with key not found");
	ret = environ_get (env, "MEEP");

	TEST_EQ_P (ret, NULL);


	/* Check that the key is not prefix-matched. */
	TEST_FEATURE ("with key that is prefix of another");
	ret = environ_get (env, "FOO");

	TEST_EQ_P (ret, NULL);


	nih_free (env);
}
Ejemplo n.º 8
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);
	}
}
Ejemplo n.º 9
0
void
test_suggest_help (void)
{
	FILE *output;

	/* Check that the message to suggest help is placed on standard
	 * error, and formatted as we expect.
	 */
	TEST_FUNCTION ("nih_main_suggest_help");
	program_name = "test";

	output = tmpfile ();
	TEST_DIVERT_STDERR (output) {
		nih_main_suggest_help ();
	}
	rewind (output);

	TEST_FILE_EQ (output, "Try `test --help' for more information.\n");
	TEST_FILE_END (output);

	fclose (output);
}
Ejemplo n.º 10
0
void
test_alloc (void)
{
	void *ptr1;
	void *ptr2;

	TEST_FUNCTION ("nih_alloc");

	/* Check allocation remembers the size, and is possible without
	 * a parent.
	 */
	TEST_FEATURE ("with no parent");
	ptr1 = nih_alloc (NULL, 8096);
	memset (ptr1, 'x', 8096);

	TEST_ALLOC_SIZE (ptr1, 8096);
	TEST_ALLOC_PARENT (ptr1, NULL);


	/* Check that allocation with a parent remembers the parent */
	TEST_FEATURE ("with a parent");
	ptr2 = nih_alloc (ptr1, 10);
	memset (ptr2, 'x', 10);

	TEST_ALLOC_SIZE (ptr2, 10);
	TEST_ALLOC_PARENT (ptr2, ptr1);

	nih_free (ptr1);


	/* Check that nih_alloc returns NULL if allocation fails. */
	TEST_FEATURE ("with failed allocation");
	__nih_malloc = malloc_null;
	ptr1 = nih_new (NULL, int);
	__nih_malloc = malloc;

	TEST_EQ_P (ptr1, NULL);
}
Ejemplo n.º 11
0
void
test_array_new (void)
{
    char **array;

    /* Check that we can allocate a NULL-terminated array of strings using
     * nih_alloc().
     */
    TEST_FUNCTION ("nih_str_array_new");
    TEST_ALLOC_FAIL {
        array = nih_str_array_new (NULL);

        if (test_alloc_failed) {
            TEST_EQ_P (array, NULL);
            continue;
        }

        TEST_ALLOC_SIZE (array, sizeof (char *));
        TEST_EQ_P (array[0], NULL);

        nih_free (array);
    }
}
Ejemplo n.º 12
0
void
test_operator_destroy (void)
{
	EventOperator *oper;
	Event         *event;

	TEST_FUNCTION ("event_operator_destroy");


	/* Check that when an event operator is destroyed, the referenced
	 * event is unblocked and unreferenced.
	 */
	TEST_FEATURE ("with referenced event");
	oper = event_operator_new (NULL, EVENT_MATCH, "foo", NULL);
	oper->value = TRUE;

	event = event_new (NULL, "foo", NULL);
	oper->event = event;
	event_block (event);

	nih_free (oper);

	TEST_EQ (event->blockers, 0);

	nih_free (event);


	/* Check that when an event operator without an event is destroyed,
	 * everything works.
	 */
	TEST_FEATURE ("without referenced event");
	oper = event_operator_new (NULL, EVENT_MATCH, "foo", NULL);
	nih_free (oper);


	event_poll ();
}
Ejemplo n.º 13
0
void
test_new (void)
{
	void *ptr1;
	void *ptr2;

	TEST_FUNCTION ("nih_new");

	/* Check that nih_new works if we don't give it a parent, the block
	 * should be allocated with the size of the type given.
	 */
	TEST_FEATURE ("with no parent");
	ptr1 = nih_new (NULL, int);

	TEST_ALLOC_SIZE (ptr1, sizeof (int));
	TEST_ALLOC_PARENT (ptr1, NULL);


	/* Check that nih_new works if we do give a parent. */
	TEST_FEATURE ("with parent");
	ptr2 = nih_new (ptr1, char);

	TEST_ALLOC_SIZE (ptr2, sizeof (char));
	TEST_ALLOC_PARENT (ptr2, ptr1);

	nih_free (ptr1);


	/* Check that nih_new returns NULL if allocation fails. */
	TEST_FEATURE ("with failed allocation");
	__nih_malloc = malloc_null;
	ptr1 = nih_new (NULL, int);
	__nih_malloc = malloc;

	TEST_EQ_P (ptr1, NULL);
}
Ejemplo n.º 14
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);
	}
}
Ejemplo n.º 15
0
void
test_write_pidfile (void)
{
	FILE     *f;
	NihError *err;
	char      dirname[PATH_MAX], filename[PATH_MAX], tmpname[PATH_MAX];
	int       ret;

	TEST_FUNCTION ("nih_main_write_pidfile");
	TEST_FILENAME (dirname);
	mkdir (dirname, 0755);

	strcpy (filename, dirname);
	strcat (filename, "/test.pid");

	strcpy (tmpname, dirname);
	strcat (tmpname, "/.test.pid.tmp");

	nih_main_set_pidfile (filename);

	/* Check that we can write a pid to the file, and have it appaer
	 * on disk where we expect.
	 */
	TEST_FEATURE ("with successful write");
	ret = nih_main_write_pidfile (1234);

	TEST_EQ (ret, 0);

	f = fopen (filename, "r");
	TEST_FILE_EQ (f, "1234\n");
	fclose (f);


	/* Check that we can overwrite an existing pid file with a new
	 * value.
	 */
	TEST_FEATURE ("with overwrite of existing pid");
	ret = nih_main_write_pidfile (5678);

	TEST_EQ (ret, 0);

	f = fopen (filename, "r");
	TEST_FILE_EQ (f, "5678\n");
	fclose (f);


	/* Check that an error writing to the temporary file does not result
	 * in the replacement of the existing file and does not result in
	 * the unlinking of the temporary file.
	 */
	TEST_FEATURE ("with failure to write to temporary file");
	f = fopen (tmpname, "w");
	fclose (f);
	chmod (tmpname, 0000);

	ret = nih_main_write_pidfile (1234);

	TEST_LT (ret, 0);

	err = nih_error_get ();
	TEST_EQ (err->number, EACCES);
	nih_free (err);

	f = fopen (filename, "r");
	TEST_FILE_EQ (f, "5678\n");
	fclose (f);

	TEST_EQ (chmod (tmpname, 0644), 0);


	nih_main_unlink_pidfile ();
	unlink (tmpname);
	rmdir (dirname);

	nih_main_set_pidfile (NULL);
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
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");
}
Ejemplo n.º 18
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);
	}
}
Ejemplo n.º 19
0
void
test_unref (void)
{
	void *ptr1;
	void *ptr2;
	void *ptr3;

	TEST_FUNCTION ("nih_unref");


	/* Check that we can remove a reference from an object with multiple
	 * parents, which means the object will not be freed.
	 */
	TEST_FEATURE ("with multiple parents");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (ptr1, 100);
	memset (ptr2, 'y', 100);

	ptr3 = nih_alloc (NULL, 100);
	memset (ptr2, 'z', 100);

	nih_ref (ptr2, ptr3);

	nih_alloc_set_destructor (ptr2, destructor_called);
	destructor_was_called = 0;

	nih_unref (ptr2, ptr1);

	TEST_FALSE (destructor_was_called);
	TEST_ALLOC_PARENT (ptr2, ptr3);

	nih_free (ptr1);
	nih_free (ptr3);


	/* Check that when we remove the last reference from an object,
	 * the object is freed.
	 */
	TEST_FEATURE ("with last parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (ptr1, 100);
	memset (ptr2, 'y', 100);

	nih_alloc_set_destructor (ptr2, destructor_called);
	destructor_was_called = 0;

	nih_unref (ptr2, ptr1);

	TEST_TRUE (destructor_was_called);

	nih_free (ptr1);


	/* Check that we have to remove the NULL reference from an object
	 * for it to be freed.
	 */
	TEST_FEATURE ("with only NULL parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	nih_alloc_set_destructor (ptr1, destructor_called);
	destructor_was_called = 0;

	nih_unref (ptr1, NULL);

	TEST_TRUE (destructor_was_called);


	/* Check that we can remove the NULL reference leaving a reference
	 * to a different object.
	 */
	TEST_FEATURE ("with no parent and other parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (NULL, 100);
	memset (ptr2, 'y', 100);

	nih_ref (ptr2, ptr1);

	nih_alloc_set_destructor (ptr2, destructor_called);
	destructor_was_called = 0;

	nih_unref (ptr2, NULL);

	TEST_FALSE (destructor_was_called);

	TEST_ALLOC_PARENT (ptr2, ptr1);
	TEST_FALSE (nih_alloc_parent (ptr2, NULL));

	nih_free (ptr1);


	/* Check that an object with multiple NULL references must have
	 * them both removed before it will be freed.
	 */
	TEST_FEATURE ("with multiple NULL parents");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	nih_ref (ptr1, NULL);

	nih_alloc_set_destructor (ptr1, destructor_called);
	destructor_was_called = 0;

	nih_unref (ptr1, NULL);

	TEST_FALSE (destructor_was_called);

	nih_unref (ptr1, NULL);

	TEST_TRUE (destructor_was_called);


	/* Check that an object with multiple identical references must have
	 * them both removed before it will be freed.
	 */
	TEST_FEATURE ("with multiple identical parents");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (ptr1, 100);
	memset (ptr2, 'y', 100);

	nih_ref (ptr2, ptr1);

	nih_alloc_set_destructor (ptr2, destructor_called);
	destructor_was_called = 0;

	nih_unref (ptr2, ptr1);

	TEST_FALSE (destructor_was_called);

	nih_unref (ptr2, ptr1);

	TEST_TRUE (destructor_was_called);

	nih_free (ptr1);
}
Ejemplo n.º 20
0
void
test_ref (void)
{
	void *ptr1;
	void *ptr2;
	void *ptr3;

	TEST_FUNCTION ("nih_ref");


	/* Check that we can add a reference to an object that has no
	 * parent, and this does not remove the NULL reference.
	 */
	TEST_FEATURE ("with no parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (NULL, 100);
	memset (ptr2, 'y', 100);

	nih_ref (ptr1, ptr2);

	TEST_ALLOC_PARENT (ptr1, ptr2);
	TEST_ALLOC_PARENT (ptr1, NULL);

	nih_free (ptr1);
	nih_free (ptr2);


	/* Check that we can add a reference to an object that already has
	 * a parent, and that both shall be parents afterwards.
	 */
	TEST_FEATURE ("with existing parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (ptr1, 100);
	memset (ptr2, 'y', 100);

	ptr3 = nih_alloc (NULL, 100);
	memset (ptr2, 'z', 100);

	nih_ref (ptr2, ptr3);

	TEST_ALLOC_PARENT (ptr2, ptr1);
	TEST_ALLOC_PARENT (ptr2, ptr3);

	nih_free (ptr1);
	nih_free (ptr3);


	/* Check that we can add a new NULL reference to an object that
	 * already has a parent, and that both shall be parents afterwards.
	 */
	TEST_FEATURE ("with existing parent and new NULL");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (ptr1, 100);
	memset (ptr2, 'y', 100);

	nih_ref (ptr2, NULL);

	TEST_ALLOC_PARENT (ptr2, ptr1);
	TEST_ALLOC_PARENT (ptr2, NULL);

	nih_free (ptr1);
	nih_free (ptr2);


	/* Check that we can add a second NULL reference to an object that
	 * already has one.
	 */
	TEST_FEATURE ("with additional NULL parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	nih_ref (ptr1, NULL);

	TEST_ALLOC_PARENT (ptr1, NULL);

	nih_free (ptr1);


	/* Check that we can add a second reference to an object that already
	 * has a reference from the same parent.
	 */
	TEST_FEATURE ("with additional existing parent");
	ptr1 = nih_alloc (NULL, 100);
	memset (ptr1, 'x', 100);

	ptr2 = nih_alloc (ptr1, 100);
	memset (ptr2, 'y', 100);

	nih_ref (ptr2, ptr1);

	TEST_ALLOC_PARENT (ptr2, ptr1);

	nih_free (ptr2);
	nih_free (ptr1);
}
Ejemplo n.º 21
0
void
test_discard (void)
{
	void *ptr1;
	void *ptr2;
	int   ret;

	TEST_FUNCTION ("nih_discard");

	/* Check that nih_discard works if the block has no parent, freeing
	 * the object.  The destructor should get called and nih_discard
	 * should return that return value.
	 */
	TEST_FEATURE ("with no parent");
	ptr1 = nih_alloc (NULL, 10);
	nih_alloc_set_destructor (ptr1, destructor_called);
	destructor_was_called = 0;
	ret = nih_discard (ptr1);

	TEST_TRUE (destructor_was_called);
	TEST_EQ (ret, 2);


	/* Check that nih_discard does nothing it the block has a parent.
	 */
	TEST_FEATURE ("with parent");
	ptr2 = nih_alloc (NULL, 20);

	ptr1 = nih_alloc (ptr2, 10);
	nih_alloc_set_destructor (ptr1, destructor_called);
	destructor_was_called = 0;
	ret = nih_discard (ptr1);

	TEST_FALSE (destructor_was_called);
	TEST_EQ (ret, 0);

	nih_free (ptr2);


	/* Check that the destructor on any children also gets called, which
	 * is as good a indication as any that the children are being freed.
	 */
	TEST_FEATURE ("with destructor on child");
	ptr1 = nih_alloc (NULL, 10);
	ptr2 = nih_alloc (ptr1, 10);
	nih_alloc_set_destructor (ptr2, child_destructor_called);
	child_destructor_was_called = 0;
	ret = nih_discard (ptr1);

	TEST_TRUE (child_destructor_was_called);
	TEST_EQ (ret, 0);


	/* Check that both destructors on parent and children are called,
	 * and that the return value from nih_discard is that of the parent's.
	 */
	TEST_FEATURE ("with child and destructors");
	ptr1 = nih_alloc (NULL, 10);
	ptr2 = nih_alloc (ptr1, 10);
	nih_alloc_set_destructor (ptr1, destructor_called);
	nih_alloc_set_destructor (ptr2, child_destructor_called);
	destructor_was_called = 0;
	child_destructor_was_called = 0;
	ret = nih_discard (ptr1);

	TEST_TRUE (destructor_was_called);
	TEST_TRUE (child_destructor_was_called);
	TEST_EQ (ret, 2);
}
Ejemplo n.º 22
0
void
test_realloc (void)
{
	void *ptr1;
	void *ptr2;
	void *ptr3;

	TEST_FUNCTION ("nih_realloc");

	/* Check that nih_realloc behaves like nih_alloc if the pointer is
	 * NULL (it should, in fact, just call it)
	 */
	TEST_FEATURE ("as nih_alloc");
	ptr1 = nih_realloc (NULL, NULL, 4096);
	memset (ptr1, 'x', 4096);

	TEST_ALLOC_SIZE (ptr1, 4096);
	TEST_ALLOC_PARENT (ptr1, NULL);

	nih_free (ptr1);


	/* Check that nih_realloc works if the block doesn't have a parent.
	 */
	TEST_FEATURE ("with no parent");
	ptr1 = nih_alloc (NULL, 4096);
	memset (ptr1, 'x', 4096);

	ptr1 = nih_realloc (ptr1, NULL, 8096);
	memset (ptr1, 'x', 8096);

	TEST_ALLOC_SIZE (ptr1, 8096);
	TEST_ALLOC_PARENT (ptr1, NULL);


	/* Check that nih_realloc works if the block has a parent, the size
	 * should change but the parent should remain the same.
	 */
	TEST_FEATURE ("with a parent");
	ptr2 = nih_alloc (ptr1, 5);
	memset (ptr2, 'x', 5);

	ptr2 = nih_realloc (ptr2, ptr1, 10);
	memset (ptr2, 'x', 10);

	TEST_ALLOC_SIZE (ptr2, 10);
	TEST_ALLOC_PARENT (ptr2, ptr1);

	nih_free (ptr1);


	/* Check that nih_realloc works if the block being reallocated has
	 * a child.  This is fiddly as they need their parent pointers
	 * adjusted.
	 */
	TEST_FEATURE ("with a child");
	ptr1 = nih_alloc (NULL, 128);
	memset (ptr1, 'x', 128);

	ptr2 = nih_alloc (ptr1, 512);
	memset (ptr2, 'x', 512);

	ptr3 = nih_realloc (ptr1, NULL, 1024);
	memset (ptr3, 'x', 1024);

	TEST_ALLOC_PARENT (ptr2, ptr3);

	nih_free (ptr3);


	/* Check that nih_realloc returns NULL and doesn't alter the block
	 * if the allocator fails.
	 */
	TEST_FEATURE ("with failing realloc");
	ptr1 = nih_alloc (NULL, 10);
	assert (ptr1);
	memset (ptr1, 'x', 10);

	__nih_realloc = realloc_null;
	ptr2 = nih_realloc (ptr1, NULL, 200);
	__nih_realloc = realloc;

	TEST_EQ_P (ptr2, NULL);
	TEST_ALLOC_SIZE (ptr1, 10);

	nih_free (ptr1);
}
Ejemplo n.º 23
0
void
test_free (void)
{
	void *  ptr1;
	void *  ptr2;
	Parent *parent;
	int     ret;

	TEST_FUNCTION ("nih_free");

	/* Check that nih_free works if the block has no parent.  The
	 * destructor should get called and nih_free should return that
	 * return value.
	 */
	TEST_FEATURE ("with no parent");
	ptr1 = nih_alloc (NULL, 10);
	nih_alloc_set_destructor (ptr1, destructor_called);
	destructor_was_called = 0;
	ret = nih_free (ptr1);

	TEST_TRUE (destructor_was_called);
	TEST_EQ (ret, 2);


	/* Check that nih_free works if the block has a parent.  The
	 * destructor should get called and nih_free should return that
	 * return value.
	 */
	TEST_FEATURE ("with parent");
	ptr2 = nih_alloc (NULL, 20);

	ptr1 = nih_alloc (ptr2, 10);
	nih_alloc_set_destructor (ptr1, destructor_called);
	destructor_was_called = 0;
	ret = nih_free (ptr1);

	TEST_TRUE (destructor_was_called);
	TEST_EQ (ret, 2);

	nih_free (ptr2);


	/* Check that the destructor on any children also gets called, which
	 * is as good a indication as any that the children are being freed.
	 */
	TEST_FEATURE ("with destructor on child");
	ptr1 = nih_alloc (NULL, 10);
	ptr2 = nih_alloc (ptr1, 10);
	nih_alloc_set_destructor (ptr2, child_destructor_called);
	child_destructor_was_called = 0;
	ret = nih_free (ptr1);

	TEST_TRUE (child_destructor_was_called);
	TEST_EQ (ret, 0);


	/* Check that both destructors on parent and children are called,
	 * and that the return value from nih_free is that of the parent's.
	 */
	TEST_FEATURE ("with child and destructors");
	ptr1 = nih_alloc (NULL, 10);
	ptr2 = nih_alloc (ptr1, 10);
	nih_alloc_set_destructor (ptr1, destructor_called);
	nih_alloc_set_destructor (ptr2, child_destructor_called);
	destructor_was_called = 0;
	child_destructor_was_called = 0;
	ret = nih_free (ptr1);

	TEST_TRUE (destructor_was_called);
	TEST_TRUE (child_destructor_was_called);
	TEST_EQ (ret, 2);


	/* Check that a child of an object may be included in a sibling
	 * linked list allocated earlier.  At the point the child destructor
	 * is called, the sibling must not have been freed otherwise it
	 * cannot cut itself out.
	 */
	TEST_FEATURE ("with child in older sibling list");
	parent = nih_new (NULL, Parent);

	__nih_malloc = my_list_head_malloc;
	parent->list = nih_new (parent, NihList);
	nih_list_init (parent->list);
	__nih_malloc = malloc;

	parent->child = nih_new (parent, Child);
	nih_list_init (&parent->child->entry);

	nih_list_add (parent->list, &parent->child->entry);
	nih_alloc_set_destructor (parent->child, child_destructor_test);

	__nih_free = my_list_head_free;
	nih_free (parent);
	__nih_free = free;


	/* Check that a child of an object may be included in a sibling
	 * linked list allocated later.  At the point the child destructor
	 * is called, the sibling must not have been freed otherwise it
	 * cannot cut itself out.
	 */
	TEST_FEATURE ("with child in younger sibling list");
	parent = nih_new (NULL, Parent);

	parent->child = nih_new (parent, Child);
	nih_list_init (&parent->child->entry);

	__nih_malloc = my_list_head_malloc;
	parent->list = nih_new (parent, NihList);
	nih_list_init (parent->list);
	__nih_malloc = malloc;

	nih_list_add (parent->list, &parent->child->entry);
	nih_alloc_set_destructor (parent->child, child_destructor_test);

	__nih_free = my_list_head_free;
	nih_free (parent);
	__nih_free = free;
}
Ejemplo n.º 24
0
static void
test_generic (mp_prec_t p0, mp_prec_t p1, unsigned int N)
{
  mp_prec_t prec, xprec, yprec;
  mpfr_t x, y, z, t;
#ifdef TWO_ARGS
  mpfr_t u;
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_t u;
  double d;
#endif
  mp_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;
  unsigned long ctrt = 0, ctrn = 0;
  mp_exp_t old_emin, old_emax;

  old_emin = mpfr_get_emin ();
  old_emax = mpfr_get_emax ();

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (t);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_init (u);
#endif

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;
      mpfr_set_prec (y, yprec);

      /* Note: in precision p1, we test 4 special cases. */
      for (n = 0; n < (prec == p1 ? N + 4 : N); n++)
        {
          xprec = prec;
          if (randlimb () & 1)
            {
              xprec *= (double) randlimb () / MP_LIMB_T_MAX;
              if (xprec < MPFR_PREC_MIN)
                xprec = MPFR_PREC_MIN;
            }
          mpfr_set_prec (x, xprec);
#ifdef TWO_ARGS
          mpfr_set_prec (u, xprec);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
          mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
#endif

          if (n > 3 || prec < p1)
            {
#if defined(RAND_FUNCTION)
              RAND_FUNCTION (x);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              RAND_FUNCTION (u);
#endif
#else
              tests_default_random (x, TEST_RANDOM_POS,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              tests_default_random (u, TEST_RANDOM_POS2,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
#endif
#endif
            }
          else
            {
              /* Special cases tested in precision p1 if n <= 3. They are
                 useful really in the extended exponent range. */
              set_emin (MPFR_EMIN_MIN);
              set_emax (MPFR_EMAX_MAX);
              if (n <= 1)
                {
                  mpfr_set_si (x, n == 0 ? 1 : -1, GMP_RNDN);
                  mpfr_set_exp (x, mpfr_get_emin ());
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, GMP_RNDN);
                  mpfr_set_exp (u, mpfr_get_emin ());
#endif
                }
              else  /* 2 <= n <= 3 */
                {
                  if (getenv ("MPFR_CHECK_MAX") == NULL)
                    goto next_n;
                  mpfr_set_si (x, n == 0 ? 1 : -1, GMP_RNDN);
                  mpfr_setmax (x, REDUCE_EMAX);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, GMP_RNDN);
                  mpfr_setmax (u, mpfr_get_emax ());
#endif
                }
            }

          rnd = RND_RAND ();
          mpfr_clear_flags ();
#ifdef DEBUG_TGENERIC
          TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
#endif
#if defined(TWO_ARGS)
          compare = TEST_FUNCTION (y, x, u, rnd);
#elif defined(DOUBLE_ARG1)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, d, x, rnd);
#elif defined(DOUBLE_ARG2)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, x, d, rnd);
#else
          compare = TEST_FUNCTION (y, x, rnd);
#endif
          TGENERIC_CHECK ("Bad inexact flag",
                          (compare != 0) ^ (mpfr_inexflag_p () == 0));
          ctrt++;
          if (MPFR_IS_SINGULAR (y))
            {
              if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
                TGENERIC_CHECK ("Bad NaN flag",
                                MPFR_IS_NAN (y) && mpfr_nanflag_p ());
              else if (MPFR_IS_INF (y))
                TGENERIC_CHECK ("Bad overflow flag",
                                (compare != 0) ^ (mpfr_overflow_p () == 0));
              else if (MPFR_IS_ZERO (y))
                TGENERIC_CHECK ("Bad underflow flag",
                                (compare != 0) ^ (mpfr_underflow_p () == 0));
            }
          else if (mpfr_overflow_p ())
            {
              TGENERIC_CHECK ("Bad compare value (overflow)", compare != 0);
              mpfr_nexttoinf (y);
              TGENERIC_CHECK ("Should have been max MPFR number",
                              MPFR_IS_INF (y));
            }
          else if (mpfr_underflow_p ())
            {
              TGENERIC_CHECK ("Bad compare value (underflow)", compare != 0);
              mpfr_nexttozero (y);
              TGENERIC_CHECK ("Should have been min MPFR number",
                              MPFR_IS_ZERO (y));
            }
          else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
            {
              ctrn++;
              mpfr_set (t, y, rnd);
              /* Risk of failures are known when some flags are already set
                 before the function call. Do not set the erange flag, as
                 it will remain set after the function call and no checks
                 are performed in such a case (see the mpfr_erangeflag_p
                 test below). */
              if (randlimb () & 1)
                __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
#ifdef DEBUG_TGENERIC
              TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
#endif
              /* Let's increase the precision of the inputs in a random way.
                 In most cases, this doesn't make any difference, but this
                 triggers the mpfr_fmod bug fixed in r6235. */
              mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
                               GMP_RNDN);
#if defined(TWO_ARGS)
              mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
                               GMP_RNDN);
              inexact = TEST_FUNCTION (z, x, u, rnd);
#elif defined(DOUBLE_ARG1)
              inexact = TEST_FUNCTION (z, d, x, rnd);
#elif defined(DOUBLE_ARG2)
              inexact = TEST_FUNCTION (z, x, d, rnd);
#else
              inexact = TEST_FUNCTION (z, x, rnd);
#endif
              if (mpfr_erangeflag_p ())
                goto next_n;
              if (mpfr_nan_p (z) || mpfr_cmp (t, z) != 0)
                {
                  printf ("results differ for x=");
                  mpfr_out_str (stdout, 2, xprec, x, GMP_RNDN);
#ifdef TWO_ARGS
                  printf ("\nu=");
                  mpfr_out_str (stdout, 2, xprec, u, GMP_RNDN);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  printf ("\nu=");
                  mpfr_out_str (stdout, 2, IEEE_DBL_MANT_DIG, u, GMP_RNDN);
#endif
                  printf (" prec=%u rnd_mode=%s\n", (unsigned) prec,
                          mpfr_print_rnd_mode (rnd));
                  printf ("got      ");
                  mpfr_out_str (stdout, 2, prec, z, GMP_RNDN);
                  puts ("");
                  printf ("expected ");
                  mpfr_out_str (stdout, 2, prec, t, GMP_RNDN);
                  puts ("");
                  printf ("approx   ");
                  mpfr_print_binary (y);
                  puts ("");
                  exit (1);
                }
              compare2 = mpfr_cmp (t, y);
              /* if rounding to nearest, cannot know the sign of t - f(x)
                 because of composed rounding: y = o(f(x)) and t = o(y) */
              if (compare * compare2 >= 0)
                compare = compare + compare2;
              else
                compare = inexact; /* cannot determine sign(t-f(x)) */
              if (((inexact == 0) && (compare != 0)) ||
                  ((inexact > 0) && (compare <= 0)) ||
                  ((inexact < 0) && (compare >= 0)))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x="); mpfr_print_binary (x); puts ("");
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  printf ("u="); mpfr_print_binary (u); puts ("");
#endif
                  printf ("y="); mpfr_print_binary (y); puts ("");
                  printf ("t="); mpfr_print_binary (t); puts ("");
                  exit (1);
                }
            }
          else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
            {
              /* For developers only! */
              MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
              mpfr_nexttoinf (y);
              if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
                  && !mpfr_overflow_p ())
                {
                  printf ("Possible bug! |y| is the maximum finite number "
                          "and has been obtained when\nrounding toward zero"
                          " (%s). Thus there is a very probable overflow,\n"
                          "but the overflow flag is not set!\n",
                          mpfr_print_rnd_mode (rnd));
                  printf ("x="); mpfr_print_binary (x); puts ("");
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  printf ("u="); mpfr_print_binary (u); puts ("");
#endif
                  exit (1);
                }
            }

        next_n:
          /* In case the exponent range has been changed by
             tests_default_random() or for special values... */
          mpfr_set_emin (old_emin);
          mpfr_set_emax (old_emax);
        }
    }

#ifndef TGENERIC_NOWARNING
  if (3 * ctrn < 2 * ctrt)
    printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
            ctrn, ctrt);
#endif

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_clear (u);
#endif
}
Ejemplo n.º 25
0
static void
test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
{
  mpfr_prec_t prec, xprec, yprec;
  mpfr_t x, y, z, t, w;
#if defined(TWO_ARGS_ALL)
  mpfr_t u;
#endif
#if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  double d;
#endif
#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
  unsigned long i;
#endif
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;
  unsigned long ctrt = 0, ctrn = 0;
  int test_of = 1, test_uf = 1;
  mpfr_exp_t old_emin, old_emax;

  old_emin = mpfr_get_emin ();
  old_emax = mpfr_get_emax ();

  mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_init2 (u, MPFR_PREC_MIN);
#endif

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;
      mpfr_set_prec (y, yprec);
      mpfr_set_prec (w, yprec);

      /* Note: in precision p1, we test 4 special cases. */
      for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
        {
          int infinite_input = 0;
          unsigned int flags;
          mpfr_exp_t oemin, oemax;

          xprec = prec;
          if (randlimb () & 1)
            {
              xprec *= (double) randlimb () / MP_LIMB_T_MAX;
              if (xprec < MPFR_PREC_MIN)
                xprec = MPFR_PREC_MIN;
            }
          mpfr_set_prec (x, xprec);
#if defined(TWO_ARGS)
          mpfr_set_prec (u, xprec);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
          mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
#elif defined(ULONG_ARG1) || defined(ULONG_ARG2)
          mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT);
#endif

          if (n > 3 || prec < p1)
            {
#if defined(RAND_FUNCTION)
              RAND_FUNCTION (x);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              RAND_FUNCTION (u);
#endif
#else  /* ! defined(RAND_FUNCTION) */
              tests_default_random (x, TEST_RANDOM_POS,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
                                    TEST_RANDOM_ALWAYS_SCALE);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              tests_default_random (u, TEST_RANDOM_POS2,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
                                    TEST_RANDOM_ALWAYS_SCALE);
#endif
#endif  /* ! defined(RAND_FUNCTION) */
            }
          else
            {
              /* Special cases tested in precision p1 if n <= 3. They are
                 useful really in the extended exponent range. */
#if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
              goto next_n;
#endif
              set_emin (MPFR_EMIN_MIN);
              set_emax (MPFR_EMAX_MAX);
              if (n <= 1)
                {
                  mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_set_exp (x, mpfr_get_emin ());
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_set_exp (u, mpfr_get_emin ());
#endif
                }
              else  /* 2 <= n <= 3 */
                {
                  if (getenv ("MPFR_CHECK_MAX") == NULL)
                    goto next_n;
                  mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_setmax (x, REDUCE_EMAX);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_setmax (u, mpfr_get_emax ());
#endif
                }
            }

#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
          i = randlimb ();
          inexact = mpfr_set_ui (u, i, MPFR_RNDN);
          MPFR_ASSERTN (inexact == 0);
#endif

          /* Exponent range for the test. */
          oemin = mpfr_get_emin ();
          oemax = mpfr_get_emax ();

          rnd = RND_RAND ();
          mpfr_clear_flags ();
#ifdef DEBUG_TGENERIC
          TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
#endif
#if defined(TWO_ARGS)
          compare = TEST_FUNCTION (y, x, u, rnd);
#elif defined(DOUBLE_ARG1)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, d, x, rnd);
          /* d can be infinite due to overflow in mpfr_get_d */
          infinite_input |= DOUBLE_ISINF (d);
#elif defined(DOUBLE_ARG2)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, x, d, rnd);
          /* d can be infinite due to overflow in mpfr_get_d */
          infinite_input |= DOUBLE_ISINF (d);
#elif defined(ULONG_ARG1)
          compare = TEST_FUNCTION (y, i, x, rnd);
#elif defined(ULONG_ARG2)
          compare = TEST_FUNCTION (y, x, i, rnd);
#else
          compare = TEST_FUNCTION (y, x, rnd);
#endif
          flags = __gmpfr_flags;
          if (mpfr_get_emin () != oemin ||
              mpfr_get_emax () != oemax)
            {
              printf ("tgeneric: the exponent range has been modified"
                      " by the tested function!\n");
              exit (1);
            }
          TGENERIC_CHECK ("bad inexact flag",
                          (compare != 0) ^ (mpfr_inexflag_p () == 0));
          ctrt++;

          /* Tests in a reduced exponent range. */
          {
            unsigned int oldflags = flags;
            mpfr_exp_t e, emin, emax;

            /* Determine the smallest exponent range containing the
               exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
               and output (y). */
            emin = MPFR_EMAX_MAX;
            emax = MPFR_EMIN_MIN;
            if (MPFR_IS_PURE_FP (x))
              {
                e = MPFR_GET_EXP (x);
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
#if defined(TWO_ARGS)
            if (MPFR_IS_PURE_FP (u))
              {
                e = MPFR_GET_EXP (u);
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
#endif
            if (MPFR_IS_PURE_FP (y))
              {
                e = MPFR_GET_EXP (y);
                if (test_of && e - 1 >= emax)
                  {
                    unsigned int ex_flags;

                    mpfr_set_emax (e - 1);
                    mpfr_clear_flags ();
#if defined(TWO_ARGS)
                    inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                    inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                    inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                    inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                    inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                    inexact = TEST_FUNCTION (w, x, rnd);
#endif
                    flags = __gmpfr_flags;
                    mpfr_set_emax (oemax);
                    ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
                    if (flags != ex_flags)
                      {
                        printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                                ", reduced exponent range [%"
                                MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
                                "d] (overflow test) on:\n",
                                (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
                        printf ("x = ");
                        mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                        printf ("u = ");
                        mpfr_dump (u);
#endif
                        printf ("yprec = %u, rnd_mode = %s\n",
                                (unsigned int) yprec,
                                mpfr_print_rnd_mode (rnd));
                        printf ("Expected flags =");
                        flags_out (ex_flags);
                        printf ("     got flags =");
                        flags_out (flags);
                        printf ("inex = %d, w = ", inexact);
                        mpfr_dump (w);
                        exit (1);
                      }
                    test_of = 0;  /* Overflow is tested only once. */
                  }
                if (test_uf && e + 1 <= emin)
                  {
                    unsigned int ex_flags;

                    mpfr_set_emin (e + 1);
                    mpfr_clear_flags ();
#if defined(TWO_ARGS)
                    inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                    inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                    inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                    inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                    inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                    inexact = TEST_FUNCTION (w, x, rnd);
#endif
                    flags = __gmpfr_flags;
                    mpfr_set_emin (oemin);
                    ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
                    if (flags != ex_flags)
                      {
                        printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                                ", reduced exponent range [%"
                                MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
                                "d] (underflow test) on:\n",
                                (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
                        printf ("x = ");
                        mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                        printf ("u = ");
                        mpfr_dump (u);
#endif
                        printf ("yprec = %u, rnd_mode = %s\n",
                                (unsigned int) yprec,
                                mpfr_print_rnd_mode (rnd));
                        printf ("Expected flags =");
                        flags_out (ex_flags);
                        printf ("     got flags =");
                        flags_out (flags);
                        printf ("inex = %d, w = ", inexact);
                        mpfr_dump (w);
                        exit (1);
                      }
                    test_uf = 0;  /* Underflow is tested only once. */
                  }
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
            if (emin > emax)
              emin = emax;  /* case where all values are singular */
            /* Consistency test in a reduced exponent range. Doing it
               for the first 10 samples and for prec == p1 (which has
               some special cases) should be sufficient. */
            if (ctrt <= 10 || prec == p1)
              {
                mpfr_set_emin (emin);
                mpfr_set_emax (emax);
#ifdef DEBUG_TGENERIC
                /* Useful information in case of assertion failure. */
                printf ("tgeneric: reduced exponent range [%"
                        MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
                        (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
#endif
                mpfr_clear_flags ();
#if defined(TWO_ARGS)
                inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                inexact = TEST_FUNCTION (w, x, rnd);
#endif
                flags = __gmpfr_flags;
                mpfr_set_emin (oemin);
                mpfr_set_emax (oemax);
                if (! (SAME_VAL (w, y) &&
                       SAME_SIGN (inexact, compare) &&
                       flags == oldflags))
                  {
                    printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                            ", reduced exponent range [%"
                            MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
                            (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
                    printf ("x = ");
                    mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                    printf ("u = ");
                    mpfr_dump (u);
#endif
                    printf ("yprec = %u, rnd_mode = %s\n",
                            (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
                    printf ("Expected:\n  y = ");
                    mpfr_dump (y);
                    printf ("  inex = %d, flags =", compare);
                    flags_out (oldflags);
                    printf ("Got:\n  w = ");
                    mpfr_dump (w);
                    printf ("  inex = %d, flags =", inexact);
                    flags_out (flags);
                    exit (1);
                  }
              }
            __gmpfr_flags = oldflags;  /* restore the flags */
          }

          if (MPFR_IS_SINGULAR (y))
            {
              if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
                TGENERIC_CHECK ("bad NaN flag",
                                MPFR_IS_NAN (y) && mpfr_nanflag_p ());
              else if (MPFR_IS_INF (y))
                {
                  TGENERIC_CHECK ("bad overflow flag",
                                  (compare != 0) ^ (mpfr_overflow_p () == 0));
                  TGENERIC_CHECK ("bad divide-by-zero flag",
                                  (compare == 0 && !infinite_input) ^
                                  (mpfr_divby0_p () == 0));
                }
              else if (MPFR_IS_ZERO (y))
                TGENERIC_CHECK ("bad underflow flag",
                                (compare != 0) ^ (mpfr_underflow_p () == 0));
            }
          else if (mpfr_divby0_p ())
            {
              TGENERIC_CHECK ("both overflow and divide-by-zero",
                              ! mpfr_overflow_p ());
              TGENERIC_CHECK ("both underflow and divide-by-zero",
                              ! mpfr_underflow_p ());
              TGENERIC_CHECK ("bad compare value (divide-by-zero)",
                              compare == 0);
            }
          else if (mpfr_overflow_p ())
            {
              TGENERIC_CHECK ("both underflow and overflow",
                              ! mpfr_underflow_p ());
              TGENERIC_CHECK ("bad compare value (overflow)", compare != 0);
              mpfr_nexttoinf (y);
              TGENERIC_CHECK ("should have been max MPFR number (overflow)",
                              MPFR_IS_INF (y));
            }
          else if (mpfr_underflow_p ())
            {
              TGENERIC_CHECK ("bad compare value (underflow)", compare != 0);
              mpfr_nexttozero (y);
              TGENERIC_CHECK ("should have been min MPFR number (underflow)",
                              MPFR_IS_ZERO (y));
            }
          else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
            {
              ctrn++;
              mpfr_set (t, y, rnd);
              /* Risk of failures are known when some flags are already set
                 before the function call. Do not set the erange flag, as
                 it will remain set after the function call and no checks
                 are performed in such a case (see the mpfr_erangeflag_p
                 test below). */
              if (randlimb () & 1)
                __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
#ifdef DEBUG_TGENERIC
              TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
#endif
              /* Let's increase the precision of the inputs in a random way.
                 In most cases, this doesn't make any difference, but for
                 the mpfr_fmod bug fixed in r6230, this triggers the bug. */
              mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
                               MPFR_RNDN);
#if defined(TWO_ARGS)
              mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
                               MPFR_RNDN);
              inexact = TEST_FUNCTION (z, x, u, rnd);
#elif defined(DOUBLE_ARG1)
              inexact = TEST_FUNCTION (z, d, x, rnd);
#elif defined(DOUBLE_ARG2)
              inexact = TEST_FUNCTION (z, x, d, rnd);
#elif defined(ULONG_ARG1)
              inexact = TEST_FUNCTION (z, i, x, rnd);
#elif defined(ULONG_ARG2)
              inexact = TEST_FUNCTION (z, x, i, rnd);
#else
              inexact = TEST_FUNCTION (z, x, rnd);
#endif
              if (mpfr_erangeflag_p ())
                goto next_n;
              if (! mpfr_equal_p (t, z))
                {
                  printf ("tgeneric: results differ for "
                          MAKE_STR(TEST_FUNCTION) " on\n  x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("  u = ");
                  mpfr_dump (u);
#endif
                  printf ("  prec = %u, rnd_mode = %s\n",
                          (unsigned int) prec, mpfr_print_rnd_mode (rnd));
                  printf ("Got      ");
                  mpfr_dump (z);
                  printf ("Expected ");
                  mpfr_dump (t);
                  printf ("Approx   ");
                  mpfr_dump (y);
                  exit (1);
                }
              compare2 = mpfr_cmp (t, y);
              /* if rounding to nearest, cannot know the sign of t - f(x)
                 because of composed rounding: y = o(f(x)) and t = o(y) */
              if (compare * compare2 >= 0)
                compare = compare + compare2;
              else
                compare = inexact; /* cannot determine sign(t-f(x)) */
              if (! SAME_SIGN (inexact, compare))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("u = ");
                  mpfr_dump (u);
#endif
                  printf ("y = ");
                  mpfr_dump (y);
                  printf ("t = ");
                  mpfr_dump (t);
                  exit (1);
                }
            }
          else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
            {
              /* For developers only! */
              MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
              mpfr_nexttoinf (y);
              if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
                  && !mpfr_overflow_p () && TGENERIC_SO_TEST)
                {
                  printf ("Possible bug! |y| is the maximum finite number "
                          "and has been obtained when\nrounding toward zero"
                          " (%s). Thus there is a very probable overflow,\n"
                          "but the overflow flag is not set!\n",
                          mpfr_print_rnd_mode (rnd));
                  printf ("x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("u = ");
                  mpfr_dump (u);
#endif
                  exit (1);
                }
            }

        next_n:
          /* In case the exponent range has been changed by
             tests_default_random() or for special values... */
          mpfr_set_emin (old_emin);
          mpfr_set_emax (old_emax);
        }
    }

#ifndef TGENERIC_NOWARNING
  if (3 * ctrn < 2 * ctrt)
    printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
            ctrn, ctrt);
#endif

  mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_clear (u);
#endif
}
Ejemplo n.º 26
0
void
test_output (void)
{
	FILE *        source;
	FILE *        header;
	Node *        node = NULL;
	Interface *   interface = NULL;
	Method *      method = NULL;
	Signal *      signal = NULL;
	Argument *    argument = NULL;
	Property *    property = NULL;
	int           ret;
	NihError *    err;

	TEST_FUNCTION ("output");
	source = tmpfile ();
	header = tmpfile ();


	/* Check that we can generate a valid source file and accompanying
	 * header file for a node in proxy mode.
	 */
	TEST_FEATURE ("with proxy");
	TEST_ALLOC_FAIL {
		TEST_ALLOC_SAFE {
			node = node_new (NULL, NULL);

			interface = interface_new (node, "com.netsplit.Nih.Test");
			interface->symbol = "test";
			nih_list_add (&node->interfaces, &interface->entry);

			method = method_new (interface, "Poke");
			method->symbol = "poke";
			nih_list_add (&interface->methods, &method->entry);

			argument = argument_new (method, "address",
						 "u", NIH_DBUS_ARG_IN);
			argument->symbol = "address";
			nih_list_add (&method->arguments, &argument->entry);

			argument = argument_new (method, "value",
						 "s", NIH_DBUS_ARG_IN);
			argument->symbol = "value";
			nih_list_add (&method->arguments, &argument->entry);

			method = method_new (interface, "Peek");
			method->symbol = "peek";
			nih_list_add (&interface->methods, &method->entry);

			argument = argument_new (method, "address",
						 "u", NIH_DBUS_ARG_IN);
			argument->symbol = "address";
			nih_list_add (&method->arguments, &argument->entry);

			argument = argument_new (method, "value",
						 "s", NIH_DBUS_ARG_OUT);
			argument->symbol = "value";
			nih_list_add (&method->arguments, &argument->entry);

			method = method_new (interface, "IsValidAddress");
			method->symbol = "is_valid_address";
			nih_list_add (&interface->methods, &method->entry);

			argument = argument_new (method, "address",
						 "u", NIH_DBUS_ARG_IN);
			argument->symbol = "address";
			nih_list_add (&method->arguments, &argument->entry);


			signal = signal_new (interface, "Bounce");
			signal->symbol = "bounce";
			nih_list_add (&interface->signals, &signal->entry);

			argument = argument_new (signal, "height",
						 "u", NIH_DBUS_ARG_OUT);
			argument->symbol = "height";
			nih_list_add (&signal->arguments, &argument->entry);

			argument = argument_new (signal, "velocity",
						 "i", NIH_DBUS_ARG_OUT);
			argument->symbol = "velocity";
			nih_list_add (&signal->arguments, &argument->entry);

			signal = signal_new (interface, "Exploded");
			signal->symbol = "exploded";
			nih_list_add (&interface->signals, &signal->entry);


			property = property_new (interface, "colour",
						 "s", NIH_DBUS_READWRITE);
			property->symbol = "colour";
			nih_list_add (&interface->properties, &property->entry);

			property = property_new (interface, "size",
						 "u", NIH_DBUS_READ);
			property->symbol = "size";
			nih_list_add (&interface->properties, &property->entry);

			property = property_new (interface, "touch",
						 "b", NIH_DBUS_WRITE);
			property->symbol = "touch";
			nih_list_add (&interface->properties, &property->entry);


			interface = interface_new (node, "com.netsplit.Nih.Foo");
			interface->symbol = "foo";
			nih_list_add (&node->interfaces, &interface->entry);

			method = method_new (interface, "Bing");
			method->symbol = "bing";
			nih_list_add (&interface->methods, &method->entry);

			signal = signal_new (interface, "NewResult");
			signal->symbol = "new_result";
			nih_list_add (&interface->signals, &signal->entry);

			property = property_new (interface, "preferences",
						 "(us)", NIH_DBUS_READWRITE);
			property->symbol = "preferences";
			nih_list_add (&interface->properties, &property->entry);

		}

		ret = output ("test.c", fileno (source),
			      "test.h", fileno (header),
			      "my", node, FALSE);

		rewind (source);
		rewind (header);

		if (test_alloc_failed) {
			TEST_LT (ret, 0);

			err = nih_error_get ();
			TEST_EQ (err->number, ENOMEM);
			nih_free (err);

			TEST_FILE_RESET (source);
			TEST_FILE_RESET (header);

			nih_free (node);
			continue;
		}

		TEST_EQ (ret, 0);

		TEST_EXPECTED_FILE (source, "test_output_proxy_standard.c");
		TEST_EXPECTED_FILE (header, "test_output_proxy_standard.h");

		nih_free (node);
	}


	/* Check that when there are no interfaces, a valid empty source
	 * and header file are generated.
	 */
	TEST_FEATURE ("with proxy but no interfaces");
	TEST_ALLOC_FAIL {
		TEST_ALLOC_SAFE {
			node = node_new (NULL, NULL);
		}

		ret = output ("test.c", fileno (source),
			      "test.h", fileno (header),
			      "my", node, FALSE);

		rewind (source);
		rewind (header);

		if (test_alloc_failed) {
			TEST_LT (ret, 0);

			err = nih_error_get ();
			TEST_EQ (err->number, ENOMEM);
			nih_free (err);

			TEST_FILE_RESET (source);
			TEST_FILE_RESET (header);

			nih_free (node);
			continue;
		}

		TEST_EQ (ret, 0);

		TEST_EXPECTED_FILE (source, "test_output_proxy_no_interfaces.c");
		TEST_EXPECTED_FILE (header, "test_output_proxy_no_interfaces.h");

		nih_free (node);
	}


	/* Check that we can generate a valid source file and accompanying
	 * header file for a node in object mode.
	 */
	TEST_FEATURE ("with object");
	TEST_ALLOC_FAIL {
		TEST_ALLOC_SAFE {
			node = node_new (NULL, NULL);

			interface = interface_new (node, "com.netsplit.Nih.Test");
			interface->symbol = "test";
			nih_list_add (&node->interfaces, &interface->entry);

			method = method_new (interface, "Poke");
			method->symbol = "poke";
			nih_list_add (&interface->methods, &method->entry);

			argument = argument_new (method, "address",
						 "u", NIH_DBUS_ARG_IN);
			argument->symbol = "address";
			nih_list_add (&method->arguments, &argument->entry);

			argument = argument_new (method, "value",
						 "s", NIH_DBUS_ARG_IN);
			argument->symbol = "value";
			nih_list_add (&method->arguments, &argument->entry);

			method = method_new (interface, "Peek");
			method->symbol = "peek";
			method->async = TRUE;
			nih_list_add (&interface->methods, &method->entry);

			argument = argument_new (method, "address",
						 "u", NIH_DBUS_ARG_IN);
			argument->symbol = "address";
			nih_list_add (&method->arguments, &argument->entry);

			argument = argument_new (method, "value",
						 "s", NIH_DBUS_ARG_OUT);
			argument->symbol = "value";
			nih_list_add (&method->arguments, &argument->entry);

			method = method_new (interface, "IsValidAddress");
			method->symbol = "is_valid_address";
			nih_list_add (&interface->methods, &method->entry);

			argument = argument_new (method, "address",
						 "u", NIH_DBUS_ARG_IN);
			argument->symbol = "address";
			nih_list_add (&method->arguments, &argument->entry);

			argument = argument_new (method, "is_valid",
						 "b", NIH_DBUS_ARG_OUT);
			argument->symbol = "is_valid";
			nih_list_add (&method->arguments, &argument->entry);


			signal = signal_new (interface, "Bounce");
			signal->symbol = "bounce";
			nih_list_add (&interface->signals, &signal->entry);

			argument = argument_new (signal, "height",
						 "u", NIH_DBUS_ARG_OUT);
			argument->symbol = "height";
			nih_list_add (&signal->arguments, &argument->entry);

			argument = argument_new (signal, "velocity",
						 "i", NIH_DBUS_ARG_OUT);
			argument->symbol = "velocity";
			nih_list_add (&signal->arguments, &argument->entry);

			signal = signal_new (interface, "Exploded");
			signal->symbol = "exploded";
			nih_list_add (&interface->signals, &signal->entry);


			property = property_new (interface, "colour",
						 "s", NIH_DBUS_READWRITE);
			property->symbol = "colour";
			nih_list_add (&interface->properties, &property->entry);

			property = property_new (interface, "size",
						 "u", NIH_DBUS_READ);
			property->symbol = "size";
			nih_list_add (&interface->properties, &property->entry);

			property = property_new (interface, "touch",
						 "b", NIH_DBUS_WRITE);
			property->symbol = "touch";
			nih_list_add (&interface->properties, &property->entry);


			interface = interface_new (node, "com.netsplit.Nih.Foo");
			interface->symbol = "foo";
			nih_list_add (&node->interfaces, &interface->entry);

			method = method_new (interface, "Bing");
			method->symbol = "bing";
			nih_list_add (&interface->methods, &method->entry);

			signal = signal_new (interface, "NewResult");
			signal->symbol = "new_result";
			nih_list_add (&interface->signals, &signal->entry);

			property = property_new (interface, "preferences",
						 "(us)", NIH_DBUS_READWRITE);
			property->symbol = "preferences";
			nih_list_add (&interface->properties, &property->entry);
		}

		ret = output ("test.c", fileno (source),
			      "test.h", fileno (header),
			      "my", node, TRUE);

		rewind (source);
		rewind (header);

		if (test_alloc_failed) {
			TEST_LT (ret, 0);

			err = nih_error_get ();
			TEST_EQ (err->number, ENOMEM);
			nih_free (err);

			TEST_FILE_RESET (source);
			TEST_FILE_RESET (header);

			nih_free (node);
			continue;
		}

		TEST_EQ (ret, 0);

		TEST_EXPECTED_FILE (source, "test_output_object_standard.c");
		TEST_EXPECTED_FILE (header, "test_output_object_standard.h");

		nih_free (node);
	}


	/* Check that when there are no interfaces, a valid empty source
	 * and header file are generated.
	 */
	TEST_FEATURE ("with object but no interfaces");
	TEST_ALLOC_FAIL {
		TEST_ALLOC_SAFE {
			node = node_new (NULL, NULL);
		}

		ret = output ("test.c", fileno (source),
			      "test.h", fileno (header),
			      "my", node, TRUE);

		rewind (source);
		rewind (header);

		if (test_alloc_failed) {
			TEST_LT (ret, 0);

			err = nih_error_get ();
			TEST_EQ (err->number, ENOMEM);
			nih_free (err);

			TEST_FILE_RESET (source);
			TEST_FILE_RESET (header);

			nih_free (node);
			continue;
		}

		TEST_EQ (ret, 0);

		TEST_EXPECTED_FILE (source, "test_output_object_no_interfaces.c");
		TEST_EXPECTED_FILE (header, "test_output_object_no_interfaces.h");

		nih_free (node);
	}


	fclose (source);
	fclose (header);
}
Ejemplo n.º 27
0
static void
test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
{
  mpfr_prec_t prec, yprec;
  mpfr_t x, y, z, t;
  INTEGER_TYPE u;
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (t);

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (x, prec);
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;

      for (n = 0; n <= N; n++)
        {
          if (n > 1 || prec < p1)
            RAND_FUNCTION (x);
          else
            {
              /* Special cases tested in precision p1 if n <= 1. */
              mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
              mpfr_set_exp (x, mpfr_get_emin ());
            }
          u = INT_RAND_FUNCTION ();
          rnd = RND_RAND ();
          mpfr_set_prec (y, yprec);
          compare = TEST_FUNCTION (y, x, u, rnd);
          if (mpfr_can_round (y, yprec, rnd, rnd, prec))
            {
              mpfr_set (t, y, rnd);
              inexact = TEST_FUNCTION (z, x, u, rnd);
              if (mpfr_cmp (t, z))
                {
                  printf ("results differ for x=");
                  mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
                  printf ("\nu=%lu", (unsigned long) u);
                  printf (" prec=%lu rnd_mode=%s\n",
                          (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
#ifdef TEST_FUNCTION_NAME
                  printf ("Function: %s\n", TEST_FUNCTION_NAME);
#endif
                  printf ("got      ");
                  mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
                  puts ("");
                  printf ("expected ");
                  mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
                  puts ("");
                  printf ("approx  ");
                  mpfr_print_binary (y);
                  puts ("");
                  exit (1);
                }
              compare2 = mpfr_cmp (t, y);
              /* if rounding to nearest, cannot know the sign of t - f(x)
                 because of composed rounding: y = o(f(x)) and t = o(y) */
              if (compare * compare2 >= 0)
                compare = compare + compare2;
              else
                compare = inexact; /* cannot determine sign(t-f(x)) */
              if (((inexact == 0) && (compare != 0)) ||
                  ((inexact > 0) && (compare <= 0)) ||
                  ((inexact < 0) && (compare >= 0)))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x="); mpfr_print_binary (x); puts ("");
                  printf ("u=%lu", (unsigned long) u);
                  printf ("y="); mpfr_print_binary (y); puts ("");
                  printf ("t="); mpfr_print_binary (t); puts ("");
                  exit (1);
                }
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);
}
Ejemplo n.º 28
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);
	}
}
Ejemplo n.º 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);
}
Ejemplo n.º 30
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);
	}
}