void test_cgroup_name_new (void) { CGroupName *cgname; nih_local char *parent = NULL; TEST_FUNCTION ("cgroup_name_new"); parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FEATURE ("no parent, name"); TEST_ALLOC_FAIL { cgname = cgroup_name_new (NULL, "foo."); if (test_alloc_failed) { TEST_EQ_P (cgname, NULL); continue; } TEST_NE_P (cgname, NULL); TEST_ALLOC_SIZE (cgname, sizeof (CGroupName)); TEST_ALLOC_PARENT (cgname, NULL); TEST_EQ_STR (cgname->name, "foo."); TEST_ALLOC_SIZE (cgname->name, 1+strlen ("foo.")); TEST_ALLOC_PARENT (cgname->name, cgname); TEST_LIST_EMPTY (&cgname->settings); } TEST_FEATURE ("parent, name"); TEST_ALLOC_FAIL { cgname = cgroup_name_new (parent, "bar"); if (test_alloc_failed) { TEST_EQ_P (cgname, NULL); continue; } TEST_NE_P (cgname, NULL); TEST_ALLOC_SIZE (cgname, sizeof (CGroupName)); TEST_ALLOC_PARENT (cgname, parent); TEST_EQ_STR (cgname->name, "bar"); TEST_ALLOC_SIZE (cgname->name, 1+strlen ("bar")); TEST_ALLOC_PARENT (cgname->name, cgname); TEST_LIST_EMPTY (&cgname->settings); } }
void test_set_pidfile (void) { const char *filename, *ptr; TEST_FUNCTION ("nih_main_set_pidfile"); program_name = "test"; /* Check that we can set a pidfile for use, and have the string * copied and returned. */ TEST_FEATURE ("with new location"); filename = "/path/to/pid"; nih_main_set_pidfile (filename); ptr = nih_main_get_pidfile (); TEST_EQ_STR (ptr, filename); TEST_NE_P (ptr, filename); /* Check that we can pass NULL to have the default location set * instead. */ TEST_FEATURE ("with default location"); nih_main_set_pidfile (NULL); ptr = nih_main_get_pidfile (); TEST_EQ_STR (ptr, "/var/run/test.pid"); nih_main_set_pidfile (NULL); }
void test_array_addn (void) { char **array, **ret; size_t len; /* Check that we can append strings to a NULL-terminated array. */ TEST_FUNCTION ("nih_str_array_addn"); array = nih_str_array_new (NULL); len = 0; TEST_ALLOC_FAIL { ret = nih_str_array_addn (&array, NULL, &len, "testing", 4); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_STR (array[0], "test"); TEST_EQ_P (array[1], NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (array[0], array); TEST_ALLOC_SIZE (array[0], 5); TEST_EQ_STR (array[0], "test"); TEST_EQ_P (array[1], NULL); } nih_free (array); }
void test_set (void) { char **env = NULL, **ret; size_t len = 0; TEST_FUNCTION ("environ_set"); /* Check that an environment variable can be set from a format * string. */ TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); } ret = environ_set (&env, NULL, &len, TRUE, "FOO=%d", 1234); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (env[0], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_ALLOC_SIZE (env[0], 9); TEST_EQ_STR (env[0], "FOO=1234"); TEST_EQ_P (env[1], NULL); nih_free (env); } }
void test_add (void) { char **env = NULL, **ret; size_t len = 0; TEST_FUNCTION ("environ_add"); /* Check that we can add a variable to a new environment table * and that it is appended to the array. */ TEST_FEATURE ("with empty table"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); } ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (env[0], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_ALLOC_SIZE (env[0], 8); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_P (env[1], NULL); nih_free (env); } /* Check that we can add a variable to an environment table with * existing different entries and that it is appended to the array. */ TEST_FEATURE ("with new variable"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO=BAGGINS"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that we can add a variable from the environment to the table * and that it is appended to the array. */ TEST_FEATURE ("with new variable from environment"); putenv ("FRODO=BAGGINS"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } unsetenv ("FRODO"); /* Check that when we attempt to add a variable that's not in the * environment, the table is not extended. */ TEST_FEATURE ("with new variable unset in environment"); unsetenv ("FRODO"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); } /* Check that we can replace a variable in the environment table * when one already exists with the same or different value. */ TEST_FEATURE ("with replacement variable"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR=WIBBLE"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_ALLOC_PARENT (env[1], env); TEST_ALLOC_SIZE (env[1], 11); TEST_EQ_STR (env[1], "BAR=WIBBLE"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that we can replace a variable from the environment in the * environment table when one already exists with the same or * different value. */ TEST_FEATURE ("with replacement variable from environment"); putenv ("BAR=WIBBLE"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_ALLOC_PARENT (env[1], env); TEST_ALLOC_SIZE (env[1], 11); TEST_EQ_STR (env[1], "BAR=WIBBLE"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that when we attempt to replace a variable that's unset * in the environment, the existing variable is removed from the * table. */ TEST_FEATURE ("with replacement variable unset in environment"); unsetenv ("BAR"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "FRODO=BAGGINS"); TEST_EQ_STR (env[2], "BILBO=TOOK"); TEST_EQ_P (env[3], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that we can add a variable to an environment table with * existing different entries and that it is appended to the array, * even if replace is FALSE. */ TEST_FEATURE ("with new variable but no replace"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, FALSE, "FRODO=BAGGINS"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that when a variable already exists in the environment * table, and we're not replacing, the original value is left * untouched. */ TEST_FEATURE ("with existing variable"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR=WIBBLE"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that when a variable from the environment already exists in * the environment table, and we're not replacing, the original value * is left untouched. */ TEST_FEATURE ("with existing variable from environment"); putenv ("BAR=WIBBLE"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that when a variable from the environment is unset it * does not remove an existing variable in the environment table * if we're not replacing. */ TEST_FEATURE ("with existing variable unset in environment"); unsetenv ("BAR"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); }
void test_libupstart (void) { nih_local NihDBusProxy *upstart = NULL; nih_local char *version = NULL; int ret; pid_t upstart_pid; pid_t dbus_pid; char xdg_runtime_dir[PATH_MAX]; nih_local char *orig_xdg_runtime_dir = NULL; nih_local char *session_file = NULL; nih_local char *path = NULL; TEST_GROUP ("libupstart"); TEST_FEATURE ("version"); TEST_FILENAME (xdg_runtime_dir); TEST_EQ (mkdir (xdg_runtime_dir, 0755), 0); /* Take care to avoid disrupting users environment by saving and * restoring this variable (assuming the tests all pass...). */ orig_xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR"); if (orig_xdg_runtime_dir) orig_xdg_runtime_dir = NIH_MUST (nih_strdup (NULL, orig_xdg_runtime_dir)); assert0 (setenv ("XDG_RUNTIME_DIR", xdg_runtime_dir, 1)); /*******************************************************************/ /* Create a private Session Init instance to connect to */ TEST_DBUS (dbus_pid); START_UPSTART (upstart_pid, TRUE); upstart = upstart_open (NULL); TEST_NE_P (upstart, NULL); /* Basic test (that does not change the state of the system * running this test) to see if we can query version of running * Upstart instance. */ ret = upstart_get_version_sync (NULL, upstart, &version); TEST_EQ (ret, 0); nih_message ("Running instance version: '%s'", version); assert0 (fnmatch ("init (upstart*)", version, 0x0)); STOP_UPSTART (upstart_pid); TEST_DBUS_END (dbus_pid); /*******************************************************************/ if (orig_xdg_runtime_dir) { /* restore */ setenv ("XDG_RUNTIME_DIR", orig_xdg_runtime_dir, 1); } else { assert0 (unsetenv ("XDG_RUNTIME_DIR")); } session_file = get_session_file (xdg_runtime_dir, upstart_pid); unlink (session_file); /* Remove the directory tree the Session Init created */ path = NIH_MUST (nih_sprintf (NULL, "%s/upstart/sessions", xdg_runtime_dir)); assert0 (rmdir (path)); path = NIH_MUST (nih_sprintf (NULL, "%s/upstart", xdg_runtime_dir)); assert0 (rmdir (path)); assert0 (rmdir (xdg_runtime_dir)); }
void test_cgroup_new (void) { nih_local char *parent = NULL; CGroup *cgroup; TEST_FUNCTION ("cgroup_new"); parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FEATURE ("no parent, controller"); TEST_ALLOC_FAIL { cgroup = cgroup_new (NULL, "cpuset"); if (test_alloc_failed) { TEST_EQ_P (cgroup, NULL); continue; } TEST_NE_P (cgroup, NULL); TEST_ALLOC_SIZE (cgroup, sizeof (CGroup)); TEST_ALLOC_PARENT (cgroup, NULL); TEST_EQ_STR (cgroup->controller, "cpuset"); TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("cpuset")); TEST_ALLOC_PARENT (cgroup->controller, cgroup); TEST_LIST_EMPTY (&cgroup->names); nih_free (cgroup); } TEST_FEATURE ("parent, controller"); TEST_ALLOC_FAIL { cgroup = cgroup_new (parent, "perf_event"); if (test_alloc_failed) { TEST_EQ_P (cgroup, NULL); continue; } TEST_NE_P (cgroup, NULL); TEST_ALLOC_SIZE (cgroup, sizeof (CGroup)); TEST_ALLOC_PARENT (cgroup, parent); TEST_EQ_STR (cgroup->controller, "perf_event"); TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("perf_event")); TEST_ALLOC_PARENT (cgroup->controller, cgroup); TEST_LIST_EMPTY (&cgroup->names); nih_free (cgroup); } }
void test_cgroup_job_start (void) { char confdir[PATH_MAX]; char logdir[PATH_MAX]; char flagfile[PATH_MAX]; nih_local char *cmd = NULL; pid_t dbus_pid = 0; pid_t upstart_pid = 0; char **output; size_t lines; size_t len; nih_local char *logfile = NULL; nih_local char *logfile_name = NULL; nih_local char *contents = NULL; if (geteuid ()) { printf ("INFO: skipping %s tests as not running as root\n", __func__); fflush (NULL); return; } TEST_GROUP ("cgroup manager handling"); TEST_FILENAME (confdir); TEST_EQ (mkdir (confdir, 0755), 0); TEST_FILENAME (logdir); TEST_EQ (mkdir (logdir, 0755), 0); TEST_FILENAME (flagfile); /* Use the "secret" interface */ TEST_EQ (setenv ("UPSTART_CONFDIR", confdir, 1), 0); TEST_EQ (setenv ("UPSTART_LOGDIR", logdir, 1), 0); TEST_DBUS (dbus_pid); /*******************************************************************/ TEST_FEATURE ("Ensure startup job does not start until cgmanager available"); contents = nih_sprintf (NULL, "start on startup\n" "\n" "cgroup memory mem-%s\n" "\n" "exec echo hello\n", __func__); TEST_NE_P (contents, NULL); CREATE_FILE (confdir, "cgroup.conf", contents); logfile_name = NIH_MUST (nih_sprintf (NULL, "%s/%s", logdir, "cgroup.log")); start_upstart_common (&upstart_pid, FALSE, FALSE, confdir, logdir, NULL); cmd = nih_sprintf (NULL, "%s status %s 2>&1", get_initctl (), "cgroup"); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 1); /* job should *NOT* start on startup */ TEST_EQ_STR (output[0], "cgroup stop/waiting"); nih_free (output); TEST_FALSE (file_exists (logfile_name)); cmd = nih_sprintf (NULL, "%s notify-cgroup-manager-address %s 2>&1", get_initctl (), CGMANAGER_DBUS_SOCK); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 0); WAIT_FOR_FILE (logfile_name); logfile = nih_file_read (NULL, logfile_name, &len); TEST_NE_P (logfile, NULL); TEST_EQ_STR (logfile, "hello\r\n"); DELETE_FILE (confdir, "cgroup.conf"); assert0 (unlink (logfile_name)); /*******************************************************************/ TEST_FEATURE ("Ensure bogus cgroups don't crash init"); contents = nih_sprintf (NULL, "cgroup name\n" "\n" "exec echo hello\n"); TEST_NE_P (contents, NULL); CREATE_FILE (confdir, "cgroup-name.conf", contents); logfile_name = NIH_MUST (nih_sprintf (NULL, "%s/%s", logdir, "cgroup-name.log")); cmd = nih_sprintf (NULL, "%s status %s 2>&1", get_initctl (), "cgroup-name"); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 1); /* job is not running yet */ TEST_EQ_STR (output[0], "cgroup-name stop/waiting"); nih_free (output); TEST_FALSE (file_exists (logfile_name)); cmd = nih_sprintf (NULL, "%s start %s 2>&1", get_initctl (), "cgroup-name"); TEST_NE_P (cmd, NULL); RUN_COMMAND (NULL, cmd, &output, &lines); TEST_EQ (lines, 1); TEST_EQ_STR (output[0], "initctl: Job failed to start"); DELETE_FILE (confdir, "cgroup-name.conf"); /*******************************************************************/ STOP_UPSTART (upstart_pid); TEST_DBUS_END (dbus_pid); TEST_EQ (rmdir (confdir), 0); TEST_EQ (rmdir (logdir), 0); /*******************************************************************/ }
void test_cgroup_setting_new (void) { CGroupSetting *setting; nih_local char *parent= NULL; parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FUNCTION ("cgroup_setting_new"); TEST_FEATURE ("no parent, key, no value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (NULL, "foo", NULL); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, NULL); TEST_EQ_STR (setting->key, "foo"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("foo")); TEST_ALLOC_PARENT (setting->key, setting); nih_free (setting); } TEST_FEATURE ("parent, key, no value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (parent, "hello world", NULL); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, parent); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); nih_free (setting); } TEST_FEATURE ("no parent, key, value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (NULL, "hello world", "a value"); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, NULL); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); TEST_EQ_STR (setting->value, "a value"); TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value")); TEST_ALLOC_PARENT (setting->value, setting); nih_free (setting); } TEST_FEATURE ("parent, key, value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (parent, "hello world", "a value"); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, parent); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); TEST_EQ_STR (setting->value, "a value"); TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value")); TEST_ALLOC_PARENT (setting->value, setting); nih_free (setting); } }
void test_array_append (void) { char **array, **args, **ret; size_t len; TEST_FUNCTION ("nih_str_array_append"); args = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "this")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "is")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "a")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "test")); /* Check that we can append one array onto the end of the other, * and that the array is extended and each new element copied * into the new array. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { len = 0; TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&array, NULL, &len, "foo")); NIH_MUST (nih_str_array_add (&array, NULL, &len, "bar")); } ret = nih_str_array_append (&array, NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (array[0], "foo"); TEST_EQ_STR (array[1], "bar"); TEST_EQ_P (array[2], NULL); nih_free (array); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 6); TEST_EQ_STR (array[0], "foo"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "bar"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "this"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "is"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_STR (array[4], "a"); TEST_ALLOC_PARENT (array[4], array); TEST_EQ_STR (array[5], "test"); TEST_ALLOC_PARENT (array[5], array); TEST_EQ_P (array[6], NULL); nih_free (array); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&array, NULL, NULL, "foo")); NIH_MUST (nih_str_array_add (&array, NULL, NULL, "bar")); } ret = nih_str_array_append (&array, NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_STR (array[0], "foo"); TEST_EQ_STR (array[1], "bar"); TEST_EQ_P (array[2], NULL); nih_free (array); continue; } TEST_NE_P (ret, NULL); TEST_EQ_STR (array[0], "foo"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "bar"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "this"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "is"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_STR (array[4], "a"); TEST_ALLOC_PARENT (array[4], array); TEST_EQ_STR (array[5], "test"); TEST_ALLOC_PARENT (array[5], array); TEST_EQ_P (array[6], NULL); nih_free (array); } /* Check that we can pass a NULL array to get a copy of it, with * the returned length containing the new length. */ TEST_FEATURE ("with NULL array and length"); TEST_ALLOC_FAIL { len = 0; array = NULL; ret = nih_str_array_append (&array, NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (array, NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can pass a NULL array to get a copy of it, without * passing the length in. */ TEST_FEATURE ("with NULL array and no length"); TEST_ALLOC_FAIL { array = NULL; ret = nih_str_array_append (&array, NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array, NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } nih_free (args); }
void test_array_copy (void) { char **array, **args; size_t len; TEST_FUNCTION ("nih_str_array_copy"); args = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "this")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "is")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "a")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "test")); /* Check that we can make a copy of an array, with each element * a copy of the last. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { len = 0; array = nih_str_array_copy (NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ (len, 4); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { array = nih_str_array_copy (NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } nih_free (args); /* Check that we can make a copy of an array with a single NULL * element and have the same returned. */ TEST_FEATURE ("with zero-length array"); args = NIH_MUST (nih_str_array_new (NULL)); TEST_ALLOC_FAIL { len = 0; array = nih_str_array_copy (NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ (len, 0); TEST_EQ_P (array[0], NULL); nih_free (array); } nih_free (args); }
void test_array_addp (void) { char **array, **ret; char *ptr1 = NULL; char *ptr2 = NULL; size_t len; TEST_FUNCTION ("nih_str_array_addn"); /* Check that we can call the function with a NULL array pointer, * and get one allocated automatically. */ TEST_FEATURE ("with no array given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); } array = NULL; len = 0; ret = nih_str_array_addp (&array, NULL, &len, ptr1); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array, NULL); TEST_EQ (len, 0); nih_free (ptr1); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); } /* Check that we can append allocated blocks to a * NULL-terminated array, and that the blocks are automatically * reparented. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); len = 0; ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); } ret = nih_str_array_addp (&array, NULL, &len, ptr1); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (array[0], NULL); nih_free (array); nih_free (ptr1); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); len = 0; ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); assert (nih_str_array_addp (&array, NULL, NULL, ptr1)); ptr2 = nih_alloc (NULL, 512); memset (ptr2, ' ', 512); } ret = nih_str_array_addp (&array, NULL, NULL, ptr2); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array[0], ptr1); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); nih_free (ptr2); continue; } TEST_NE_P (ret, NULL); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], ptr2); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[2], NULL); nih_free (array); nih_free (ptr1); nih_free (ptr2); } }
void test_operator_environment (void) { EventOperator *root, *oper1, *oper2, *oper3, *oper4, *oper5, *oper6; Event *event1, *event2, *event3; char **env, **ptr; size_t len; TEST_FUNCTION ("event_operator_environment"); root = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper1 = event_operator_new (root, EVENT_AND, NULL, NULL); oper2 = event_operator_new (root, EVENT_AND, NULL, NULL); oper3 = event_operator_new (root, EVENT_MATCH, "foo", NULL); oper4 = event_operator_new (root, EVENT_MATCH, "bar", NULL); oper5 = event_operator_new (root, EVENT_MATCH, "frodo", NULL); oper6 = event_operator_new (root, EVENT_MATCH, "bilbo", NULL); nih_tree_add (&root->node, &oper1->node, NIH_TREE_LEFT); nih_tree_add (&root->node, &oper2->node, NIH_TREE_RIGHT); nih_tree_add (&oper1->node, &oper3->node, NIH_TREE_LEFT); nih_tree_add (&oper1->node, &oper4->node, NIH_TREE_RIGHT); nih_tree_add (&oper2->node, &oper5->node, NIH_TREE_LEFT); nih_tree_add (&oper2->node, &oper6->node, NIH_TREE_RIGHT); root->value = TRUE; oper1->value = TRUE; oper3->value = TRUE; oper3->event = event1 = event_new (NULL, "foo", NULL); event_block (oper3->event); NIH_MUST (nih_str_array_add (&oper3->event->env, oper3->event, NULL, "FOO=APPLE")); NIH_MUST (nih_str_array_add (&oper3->event->env, oper3->event, NULL, "TEA=YES")); oper4->value = TRUE; oper4->event = event2 = event_new (NULL, "bar", NULL); event_block (oper4->event); NIH_MUST (nih_str_array_add (&oper4->event->env, oper4->event, NULL, "BAR=ORANGE")); NIH_MUST (nih_str_array_add (&oper4->event->env, oper4->event, NULL, "COFFEE=NO")); oper6->value = TRUE; oper6->event = event3 = event_new (NULL, "bilbo", NULL); event_block (oper6->event); NIH_MUST (nih_str_array_add (&oper6->event->env, oper6->event, NULL, "FRODO=BAGGINS")); NIH_MUST (nih_str_array_add (&oper6->event->env, oper6->event, NULL, "BILBO=WIBBLE")); /* Check that the environment from each of the events is appended * to the passed array; except for the event that was matched but not * in the true tree. */ TEST_FEATURE ("with environment table"); TEST_ALLOC_FAIL { env = NULL; len = 0; ptr = event_operator_environment (root, &env, NULL, &len, NULL); if (test_alloc_failed) { TEST_EQ_P (ptr, NULL); if (env) nih_free (env); continue; } TEST_NE_P (env, NULL); TEST_ALLOC_SIZE (env, sizeof (char *) * 5); TEST_EQ (len, 4); TEST_ALLOC_PARENT (env[0], env); TEST_EQ_STR (env[0], "FOO=APPLE"); TEST_ALLOC_PARENT (env[1], env); TEST_EQ_STR (env[1], "TEA=YES"); TEST_ALLOC_PARENT (env[2], env); TEST_EQ_STR (env[2], "BAR=ORANGE"); TEST_ALLOC_PARENT (env[3], env); TEST_EQ_STR (env[3], "COFFEE=NO"); TEST_EQ_P (env[4], NULL); nih_free (env); } /* Check that if we also give the name of an environment variable, * this will contain a space-separated list of the event names. */ TEST_FEATURE ("with environment variable for event list"); TEST_ALLOC_FAIL { env = NULL; len = 0; ptr = event_operator_environment (root, &env, NULL, &len, "UPSTART_EVENTS"); if (test_alloc_failed) { TEST_EQ_P (ptr, NULL); if (env) nih_free (env); continue; } TEST_NE_P (env, NULL); TEST_ALLOC_SIZE (env, sizeof (char *) * 6); TEST_EQ (len, 5); TEST_ALLOC_PARENT (env[0], env); TEST_EQ_STR (env[0], "FOO=APPLE"); TEST_ALLOC_PARENT (env[1], env); TEST_EQ_STR (env[1], "TEA=YES"); TEST_ALLOC_PARENT (env[2], env); TEST_EQ_STR (env[2], "BAR=ORANGE"); TEST_ALLOC_PARENT (env[3], env); TEST_EQ_STR (env[3], "COFFEE=NO"); TEST_ALLOC_PARENT (env[4], env); TEST_EQ_STR (env[4], "UPSTART_EVENTS=foo bar"); TEST_EQ_P (env[5], NULL); nih_free (env); } /* Check that if no events are matched the environment table only * has an empty events list. */ TEST_FEATURE ("with no matches"); TEST_ALLOC_FAIL { env = NULL; len = 0; ptr = event_operator_environment (oper5, &env, NULL, &len, "UPSTART_EVENTS"); if (test_alloc_failed) { TEST_EQ_P (ptr, NULL); if (env) nih_free (env); continue; } TEST_NE_P (env, NULL); TEST_ALLOC_SIZE (env, sizeof (char *) * 2); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_EQ_STR (env[0], "UPSTART_EVENTS="); TEST_EQ_P (env[1], NULL); nih_free (env); } nih_free (root); nih_free (event1); nih_free (event2); nih_free (event3); }
void test_operator_handle (void) { EventOperator *oper1, *oper2, *oper3, *oper4, *oper5; char *env1[2], *env2[3], *env[2]; Event *event; int ret; TEST_FUNCTION ("event_operator_handle"); oper1 = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper2 = event_operator_new (NULL, EVENT_AND, NULL, NULL); oper3 = event_operator_new (NULL, EVENT_MATCH, "foo", NULL); oper4 = event_operator_new (NULL, EVENT_MATCH, "bar", NULL); oper5 = event_operator_new (NULL, EVENT_MATCH, "baz", NULL); oper5->env = env1; oper5->env[0] = "BAR=$WIBBLE"; oper5->env[1] = NULL; nih_tree_add (&oper1->node, &oper2->node, NIH_TREE_LEFT); nih_tree_add (&oper2->node, &oper3->node, NIH_TREE_LEFT); nih_tree_add (&oper2->node, &oper4->node, NIH_TREE_RIGHT); nih_tree_add (&oper1->node, &oper5->node, NIH_TREE_RIGHT); /* Check that a non-matching event doesn't touch the tree. */ TEST_FEATURE ("with non-matching event"); event = event_new (NULL, "frodo", NULL); ret = event_operator_handle (oper1, event, NULL); TEST_EQ (ret, FALSE); TEST_EQ (oper1->value, FALSE); TEST_EQ (oper2->value, FALSE); TEST_EQ (oper3->value, FALSE); TEST_EQ_P (oper3->event, NULL); TEST_EQ (oper4->value, FALSE); TEST_EQ_P (oper4->event, NULL); TEST_EQ (oper5->value, FALSE); TEST_EQ_P (oper5->event, NULL); TEST_EQ (event->blockers, 0); /* Check that matching an event in the tree results in the event * being referenced and blocked, and stored in the operator. * The tree value should not be updated since the expression is not * TRUE. */ TEST_FEATURE ("with matching event"); event = event_new (NULL, "foo", NULL); ret = event_operator_handle (oper1, event, NULL); TEST_EQ (ret, TRUE); TEST_EQ (oper1->value, FALSE); TEST_EQ (oper2->value, FALSE); TEST_EQ (oper3->value, TRUE); TEST_EQ_P (oper3->event, event); TEST_EQ (oper4->value, FALSE); TEST_EQ_P (oper4->event, NULL); TEST_EQ (oper5->value, FALSE); TEST_EQ_P (oper5->event, NULL); TEST_EQ (event->blockers, 1); /* Check that a duplicate matching event in the tree is not * referenced or blocked since the tree already matched the first. */ TEST_FEATURE ("with duplicate matching event"); event = event_new (NULL, "foo", NULL); TEST_FREE_TAG (oper3->event); ret = event_operator_handle (oper1, event, NULL); TEST_EQ (ret, FALSE); TEST_EQ (oper1->value, FALSE); TEST_EQ (oper2->value, FALSE); TEST_EQ (oper3->value, TRUE); TEST_NE_P (oper3->event, event); TEST_NOT_FREE (oper3->event); TEST_EQ (oper4->value, FALSE); TEST_EQ_P (oper4->event, NULL); TEST_EQ (oper5->value, FALSE); TEST_EQ_P (oper5->event, NULL); TEST_EQ (event->blockers, 0); nih_free (event); /* Check that matching an event in the tree results in the event * being referenced and blocked, and stored in the operator. * Since the event tips the balance, it should update the expression. */ TEST_FEATURE ("with matching event and complete expression"); event = event_new (NULL, "bar", NULL); ret = event_operator_handle (oper1, event, NULL); TEST_EQ (ret, TRUE); TEST_EQ (oper1->value, TRUE); TEST_EQ (oper2->value, TRUE); TEST_EQ (oper3->value, TRUE); TEST_NE_P (oper3->event, NULL); TEST_EQ (oper4->value, TRUE); TEST_EQ_P (oper4->event, event); TEST_EQ (oper5->value, FALSE); TEST_EQ_P (oper5->event, NULL); TEST_EQ (event->blockers, 1); event_operator_reset (oper1); /* Check that an environment array is passed through and used to * match the expression. */ TEST_FEATURE ("with environment"); event = event_new (NULL, "baz", NULL); event->env = env2; event->env[0] = "FOO=bar"; event->env[1] = "BAR=baz"; event->env[2] = NULL; env[0] = "WIBBLE=baz"; env[1] = NULL; ret = event_operator_handle (oper1, event, env); TEST_EQ (ret, TRUE); TEST_EQ (oper1->value, TRUE); TEST_EQ (oper2->value, FALSE); TEST_EQ (oper3->value, FALSE); TEST_EQ_P (oper4->event, NULL); TEST_EQ (oper4->value, FALSE); TEST_EQ_P (oper4->event, NULL); TEST_EQ (oper5->value, TRUE); TEST_EQ_P (oper5->event, event); TEST_EQ (event->blockers, 1); event_operator_reset (oper1); nih_free (oper1); nih_free (oper2); nih_free (oper3); nih_free (oper4); nih_free (oper5); event_poll (); }
void test_operator_copy (void) { EventOperator *oper = NULL, *copy; EventOperator *oper1 = NULL, *oper2 = NULL, *copy1, *copy2; TEST_FUNCTION ("event_operator_copy"); event_init (); /* Check that we can copy a plain event operator, the value should * be copied as well, and the other fields left as NULL. */ TEST_FEATURE ("with EVENT_OR"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper->value = TRUE; } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_OR); TEST_EQ (copy->value, TRUE); TEST_EQ_P (copy->name, NULL); TEST_EQ_P (copy->env, NULL); TEST_EQ_P (copy->event, NULL); nih_free (copy); nih_free (oper); } /* Check that we can copy and EVENT_MATCH operator which does not * have any environment or matched event. */ TEST_FEATURE ("with EVENT_MATCH and no environment or event"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); oper->value = TRUE; } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_MATCH); TEST_EQ (copy->value, TRUE); TEST_EQ_STR (copy->name, "test"); TEST_ALLOC_PARENT (copy->name, copy); TEST_EQ_P (copy->env, NULL); TEST_EQ_P (copy->event, NULL); nih_free (copy); nih_free (oper); } /* Check that environment to an EVENT_MATCH operator are also copied, * and each entry within the array copied too. */ TEST_FEATURE ("with EVENT_MATCH and environment"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); oper->value = TRUE; NIH_MUST (nih_str_array_add (&oper->env, oper, NULL, "FOO=foo")); NIH_MUST (nih_str_array_add (&oper->env, oper, NULL, "BAR=bar")); } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_MATCH); TEST_EQ (copy->value, TRUE); TEST_EQ_STR (copy->name, "test"); TEST_ALLOC_PARENT (copy->name, copy); TEST_ALLOC_PARENT (copy->env, copy); TEST_ALLOC_SIZE (copy->env, sizeof (char *) * 3); TEST_ALLOC_PARENT (copy->env[0], copy->env); TEST_ALLOC_PARENT (copy->env[1], copy->env); TEST_EQ_STR (copy->env[0], "FOO=foo"); TEST_EQ_STR (copy->env[1], "BAR=bar"); TEST_EQ_P (copy->env[2], NULL); TEST_EQ_P (copy->event, NULL); nih_free (copy); nih_free (oper); } /* Check that if the EVENT_MATCH operator has a referenced event, * the event is copied and referenced a second time. */ TEST_FEATURE ("with EVENT_MATCH and referenced event"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); oper->value = TRUE; oper->event = event_new (oper, "test", NULL); event_block (oper->event); } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_EQ_P (copy->node.left, NULL); TEST_EQ_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_MATCH); TEST_EQ (copy->value, TRUE); TEST_EQ_STR (copy->name, "test"); TEST_ALLOC_PARENT (copy->name, copy); TEST_EQ_P (copy->env, NULL); TEST_EQ_P (copy->event, oper->event); TEST_EQ (copy->event->blockers, 2); nih_free (copy); nih_free (oper); } /* Check that if the operator has children, these are copied as * well, including their state. */ TEST_FEATURE ("with children"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { oper = event_operator_new (NULL, EVENT_OR, NULL, NULL); oper->value = TRUE; oper1 = event_operator_new (NULL, EVENT_MATCH, "foo", NULL); oper1->value = TRUE; oper1->event = event_new (oper1, "foo", NULL); event_block (oper1->event); nih_tree_add (&oper->node, &oper1->node, NIH_TREE_LEFT); oper2 = event_operator_new (NULL, EVENT_MATCH, "bar", NULL); oper2->value = TRUE; oper2->event = event_new (oper2, "foo", NULL); event_block (oper2->event); nih_tree_add (&oper->node, &oper2->node, NIH_TREE_RIGHT); } copy = event_operator_copy (NULL, oper); if (test_alloc_failed) { TEST_EQ_P (copy, NULL); nih_free (oper); TEST_EQ (oper1->event->blockers, 1); nih_free (oper1); TEST_EQ (oper2->event->blockers, 1); nih_free (oper2); continue; } TEST_ALLOC_SIZE (copy, sizeof (EventOperator)); TEST_EQ_P (copy->node.parent, NULL); TEST_NE_P (copy->node.left, NULL); TEST_NE_P (copy->node.right, NULL); TEST_EQ (copy->type, EVENT_OR); TEST_EQ (copy->value, TRUE); TEST_EQ_P (copy->name, NULL); TEST_EQ_P (copy->env, NULL); copy1 = (EventOperator *)copy->node.left; TEST_ALLOC_SIZE (copy1, sizeof (EventOperator)); TEST_ALLOC_PARENT (copy1, copy); TEST_EQ_P (copy1->node.parent, ©->node); TEST_EQ_P (copy1->node.left, NULL); TEST_EQ_P (copy1->node.right, NULL); TEST_EQ (copy1->type, EVENT_MATCH); TEST_EQ (copy1->value, TRUE); TEST_EQ_STR (copy1->name, "foo"); TEST_ALLOC_PARENT (copy1->name, copy1); TEST_EQ_P (copy1->env, NULL); TEST_EQ_P (copy1->event, oper1->event); TEST_EQ (copy1->event->blockers, 2); nih_free (copy1); copy2 = (EventOperator *)copy->node.right; TEST_ALLOC_SIZE (copy2, sizeof (EventOperator)); TEST_ALLOC_PARENT (copy2, copy); TEST_EQ_P (copy2->node.parent, ©->node); TEST_EQ_P (copy2->node.left, NULL); TEST_EQ_P (copy2->node.right, NULL); TEST_EQ (copy2->type, EVENT_MATCH); TEST_EQ (copy2->value, TRUE); TEST_EQ_STR (copy2->name, "bar"); TEST_ALLOC_PARENT (copy2->name, copy2); TEST_EQ_P (copy2->env, NULL); TEST_EQ_P (copy2->event, oper2->event); TEST_EQ (copy2->event->blockers, 2); nih_free (copy2); nih_free (copy); nih_free (oper1); nih_free (oper2); nih_free (oper); } event_poll (); }