~jamesodhunt/upstart/bug-530779-tmp

« back to all changes in this revision

Viewing changes to test/test_util_common.c

  • Committer: James Hunt
  • Date: 2013-11-27 13:49:49 UTC
  • mfrom: (1538.2.40 upstart)
  • Revision ID: james.hunt@ubuntu.com-20131127134949-l16igbtl5q47ukj9
* Sync with lp:upstart.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include <sys/types.h>
40
40
#include <sys/stat.h>
41
41
#include <ctype.h>
 
42
#include <time.h>
42
43
 
43
44
#include <nih-dbus/dbus_error.h>
44
45
#include <nih-dbus/dbus_connection.h>
57
58
#error unable to find initctl binary as INITCTL_BINARY not defined
58
59
#endif /* INITCTL_BINARY */
59
60
 
 
61
static char *saved_xdg_config_home = NULL;
 
62
static char *saved_xdg_runtime_dir = NULL;
 
63
static char  test_xdg_config_home[PATH_MAX];
 
64
static char  test_xdg_runtime_dir[PATH_MAX];
 
65
 
 
66
/**
 
67
 * test_setup_called:
 
68
 *
 
69
 * Set to TRUE if test_setup() called.
 
70
 **/
 
71
static int test_setup_called = FALSE;
 
72
 
60
73
static void selfpipe_write (int n);
61
74
static void selfpipe_setup (void);
62
75
 
119
132
        TEST_EQ (running, TRUE);
120
133
}
121
134
 
 
135
/**
 
136
 * session_init_reexec:
 
137
 *
 
138
 * @pid: pid of Session Init.
 
139
 *
 
140
 * Cause the Session Init running as pid @pid to re-exec.
 
141
 **/
 
142
void
 
143
session_init_reexec (pid_t pid)
 
144
{
 
145
        nih_local NihDBusProxy *upstart = NULL;
 
146
        char                   *address;
 
147
        DBusConnection         *connection;
 
148
        DBusMessage            *method_call;
 
149
        DBusMessageIter         iter;
 
150
        DBusError               error;
 
151
 
 
152
        TEST_TRUE (pid);
 
153
 
 
154
        TEST_TRUE (set_upstart_session (pid));
 
155
        address = getenv ("UPSTART_SESSION");
 
156
 
 
157
        TEST_TRUE (address);
 
158
 
 
159
        connection = nih_dbus_connect (address, NULL);
 
160
        TEST_NE_P (connection, NULL);
 
161
 
 
162
        upstart = nih_dbus_proxy_new (NULL, connection,
 
163
                        NULL,
 
164
                        DBUS_PATH_UPSTART,
 
165
                        NULL, NULL);
 
166
        TEST_NE_P (upstart, NULL);
 
167
 
 
168
        method_call = dbus_message_new_method_call (upstart->name,
 
169
                        upstart->path,
 
170
                        "com.ubuntu.Upstart0_6", "Restart");
 
171
        TEST_NE_P (method_call, NULL);
 
172
 
 
173
        dbus_message_set_auto_start (method_call, upstart->auto_start);
 
174
 
 
175
        dbus_message_iter_init_append (method_call, &iter);
 
176
 
 
177
        /* Send the message, and wait for the reply. */
 
178
        dbus_error_init (&error);
 
179
 
 
180
        /* Don't bother checking reply - Upstart will sever the
 
181
         * connection anyway.
 
182
         */
 
183
        (void)dbus_connection_send_with_reply_and_block (upstart->connection, method_call, -1, &error);
 
184
 
 
185
        dbus_message_unref (method_call);
 
186
        dbus_connection_unref (connection);
 
187
}
 
188
 
122
189
/* TRUE to denote that Upstart is running in user session mode
123
190
 * (FALSE to denote it's using the users D-Bus session bus).
124
191
 */
162
229
         * within a reasonable period of time.
163
230
         */
164
231
        for (i = 0; i < loops; i++) {
165
 
        sleep (1);
 
232
                sleep (1);
166
233
 
167
234
                RUN_COMMAND (NULL, cmd, &output, &lines);
168
235
 
169
 
        if (lines < 1)
170
 
            continue;
171
 
 
172
 
        /* Look for the specific session */
173
 
        for (size_t line = 0; line < lines; lines++) {
174
 
 
175
 
            /* No pid in output */
176
 
            if (! isdigit(output[line][0]))
177
 
                continue;
178
 
 
179
 
            pid = (pid_t)atoi(output[line]);
180
 
            nih_assert (pid > 0);
181
 
 
182
 
            if (pid != session_init_pid)
183
 
                continue;
184
 
 
185
 
            /* look for separator between pid and value of
186
 
             * UPSTART_SESSION.
187
 
             */
188
 
            value = strstr (output[0], " ");
189
 
            if (! value)
190
 
                continue;
191
 
 
192
 
            /* jump over space */
193
 
            value  += 1;
194
 
            if (! value)
195
 
                continue;
196
 
 
197
 
            /* No socket address */
198
 
            if (strstr (value, "unix:abstract") == value) {
199
 
                got = TRUE;
200
 
                goto out;
201
 
            }
202
 
        }
 
236
                if (lines < 1)
 
237
                        continue;
 
238
 
 
239
                /* Look for the specific session */
 
240
                for (size_t line = 0; line < lines; lines++) {
 
241
 
 
242
                        /* No pid in output */
 
243
                        if (! isdigit(output[line][0]))
 
244
                                continue;
 
245
 
 
246
                        pid = (pid_t)atoi(output[line]);
 
247
                        nih_assert (pid > 0);
 
248
 
 
249
                        if (pid != session_init_pid)
 
250
                                continue;
 
251
 
 
252
                        /* look for separator between pid and value of
 
253
                         * UPSTART_SESSION.
 
254
                         */
 
255
                        value = strstr (output[0], " ");
 
256
                        if (! value)
 
257
                                continue;
 
258
 
 
259
                        /* jump over space */
 
260
                        value  += 1;
 
261
                        if (! value)
 
262
                                continue;
 
263
 
 
264
                        /* No socket address */
 
265
                        if (strstr (value, "unix:abstract") == value) {
 
266
                                got = TRUE;
 
267
                                goto out;
 
268
                        }
 
269
                }
203
270
        }
204
271
 
205
272
out:
269
336
}
270
337
 
271
338
/**
 
339
 * have_timed_waitpid
 
340
 *
 
341
 * Return TRUE if precise timing information is available for timing
 
342
 * tests.
 
343
 **/
 
344
int
 
345
have_timed_waitpid (void)
 
346
{
 
347
        struct timespec res;
 
348
 
 
349
        if (clock_getres (CLOCK_MONOTONIC_RAW, &res) < 0)
 
350
                return FALSE;
 
351
 
 
352
        return TRUE;
 
353
}
 
354
 
 
355
/**
272
356
 * timed_waitpid:
273
357
 *
274
358
 * @pid: pid to wait for,
349
433
{
350
434
        static char path[PATH_MAX + 1024] = { 0 };
351
435
        int         ret;
 
436
        int         env_valid;
 
437
 
 
438
        /* Sanity check calling environment */
 
439
        if (test_user_mode) {
 
440
                env_valid = getenv ("UPSTART_SESSION") ? TRUE : FALSE;
 
441
        } else {
 
442
                env_valid = getenv ("DBUS_SESSION_BUS_ADDRESS") ? TRUE : FALSE;
 
443
        }
 
444
 
 
445
        nih_assert (env_valid);
352
446
 
353
447
        ret = sprintf (path, "%s %s",
354
448
                        get_initctl_binary (),
420
514
 * @pid: PID of running instance,
421
515
 * @user: TRUE if upstart should run in User Session mode (FALSE to
422
516
 * use the users D-Bus session bus),
 
517
 * @inherit_env: if TRUE, inherit parent environment,
423
518
 * @confdir: full path to configuration directory,
424
519
 * @logdir: full path to log directory,
425
520
 * @extra: optional extra arguments.
427
522
 * Wrapper round _start_upstart() which specifies common options.
428
523
 **/
429
524
void
430
 
start_upstart_common (pid_t *pid, int user, const char *confdir,
431
 
                      const char *logdir, char * const *extra)
 
525
start_upstart_common (pid_t *pid, int user, int inherit_env,
 
526
                      const char *confdir, const char *logdir,
 
527
                      char * const *extra)
432
528
{
433
529
        nih_local char  **args = NULL;
434
530
 
449
545
        NIH_MUST (nih_str_array_add (&args, NULL, NULL,
450
546
                                "--no-sessions"));
451
547
 
452
 
        NIH_MUST (nih_str_array_add (&args, NULL, NULL,
453
 
                                "--no-inherit-env"));
 
548
        if (! inherit_env) {
 
549
                NIH_MUST (nih_str_array_add (&args, NULL, NULL,
 
550
                                        "--no-inherit-env"));
 
551
        }
454
552
 
455
553
        if (confdir) {
456
554
                NIH_MUST (nih_str_array_add (&args, NULL, NULL,
483
581
void
484
582
start_upstart (pid_t *pid)
485
583
{
486
 
        start_upstart_common (pid, FALSE, NULL, NULL, NULL);
 
584
        start_upstart_common (pid, FALSE, FALSE, NULL, NULL, NULL);
487
585
}
488
586
 
489
587
/**
763
861
 
764
862
        return ! stat (path, &st);
765
863
}
 
864
 
 
865
/**
 
866
 * test_common_setup:
 
867
 *
 
868
 * Perform test setup.
 
869
 *
 
870
 * Currently, only needed for those tests which require unique xdg
 
871
 * directories.
 
872
 *
 
873
 * If called, test must call test_common_cleanup() to cleanup.
 
874
 **/
 
875
void
 
876
test_common_setup (void)
 
877
{
 
878
        char  *xdg_config_home;
 
879
        char  *xdg_runtime_dir;
 
880
 
 
881
        /* Take care to avoid disrupting users environment by saving and
 
882
         * restoring these variable (assuming the tests all pass...).
 
883
         */
 
884
 
 
885
        xdg_config_home = getenv ("XDG_CONFIG_HOME");
 
886
        if (xdg_config_home) {
 
887
                nih_info ("Existing XDG_CONFIG_HOME found ('%s') - "
 
888
                                "saving for later restore",
 
889
                                xdg_config_home);
 
890
 
 
891
                saved_xdg_config_home = NIH_MUST (nih_strdup (NULL, xdg_config_home));
 
892
        }
 
893
 
 
894
        TEST_FILENAME (test_xdg_config_home);
 
895
        assert0 (mkdir (test_xdg_config_home, TEST_DIR_MODE));
 
896
        assert0 (setenv ("XDG_CONFIG_HOME", test_xdg_config_home, 1));
 
897
 
 
898
        nih_info ("Using test XDG_CONFIG_HOME='%s'", test_xdg_config_home);
 
899
 
 
900
        xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR");
 
901
        if (xdg_runtime_dir) {
 
902
                nih_info ("Existing XDG_RUNTIME_DIR found ('%s') - "
 
903
                                "saving for later restore",
 
904
                                xdg_runtime_dir);
 
905
 
 
906
                saved_xdg_runtime_dir = NIH_MUST (nih_strdup (NULL, xdg_runtime_dir));
 
907
        }
 
908
 
 
909
        TEST_FILENAME (test_xdg_runtime_dir);
 
910
        assert0 (mkdir (test_xdg_runtime_dir, TEST_DIR_MODE));
 
911
        assert0 (setenv ("XDG_RUNTIME_DIR", test_xdg_runtime_dir, 1));
 
912
 
 
913
        nih_info ("Using test XDG_RUNTIME_DIR='%s'", test_xdg_runtime_dir);
 
914
 
 
915
        test_setup_called = TRUE;
 
916
}
 
917
 
 
918
/**
 
919
 * test_common_cleanup:
 
920
 *
 
921
 * Perform cleanup of test setup.
 
922
 *
 
923
 * Currently, only needed for those tests which require unique xdg
 
924
 * directories.
 
925
 *
 
926
 * If called, test must already have called test_common_setup().
 
927
 **/
 
928
void
 
929
test_common_cleanup (void)
 
930
{
 
931
        nih_local char  *path = NULL;
 
932
        char            *xdg_config_home;
 
933
        char            *xdg_runtime_dir;
 
934
        struct stat      statbuf;
 
935
 
 
936
        if (! test_setup_called) {
 
937
                nih_error ("BUG: Called %s without first calling %s",
 
938
                                __func__, "test_common_setup()");
 
939
                abort ();
 
940
        }
 
941
 
 
942
        xdg_config_home = getenv ("XDG_CONFIG_HOME");
 
943
        xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR");
 
944
 
 
945
        if (saved_xdg_config_home) {
 
946
                nih_assert (test_xdg_config_home[0]);
 
947
                TEST_EQ_STR (test_xdg_config_home, xdg_config_home);
 
948
 
 
949
                if (stat (test_xdg_config_home, &statbuf)) {
 
950
                        nih_error ("A test has removed XDG_CONFIG_HOME '%s'", test_xdg_config_home);
 
951
                        abort ();
 
952
                }
 
953
 
 
954
                if (! S_ISDIR (statbuf.st_mode)) {
 
955
                        nih_error ("XDG_CONFIG_HOME '%s' no longer a directory", test_xdg_config_home);
 
956
                        abort ();
 
957
                }
 
958
 
 
959
                assert0 (rmdir (test_xdg_config_home));
 
960
 
 
961
                assert0 (setenv ("XDG_CONFIG_HOME", saved_xdg_config_home, 1));
 
962
                nih_info ("Restoring XDG_RUNTIME_DIR='%s'", saved_xdg_config_home);
 
963
                nih_free (saved_xdg_config_home);
 
964
                saved_xdg_config_home = NULL;
 
965
        }
 
966
 
 
967
        if (saved_xdg_runtime_dir) {
 
968
                nih_assert (test_xdg_runtime_dir[0]);
 
969
                TEST_EQ_STR (test_xdg_runtime_dir, xdg_runtime_dir);
 
970
 
 
971
                if (stat (test_xdg_runtime_dir, &statbuf)) {
 
972
                        nih_error ("A test has removed XDG_RUNTIME_DIR '%s'", test_xdg_runtime_dir);
 
973
                        abort ();
 
974
                }
 
975
 
 
976
                if (! S_ISDIR (statbuf.st_mode)) {
 
977
                        nih_error ("XDG_RUNTIME_DIR '%s' no longer a directory", test_xdg_runtime_dir);
 
978
                        abort ();
 
979
                }
 
980
 
 
981
                path = NIH_MUST (nih_sprintf (NULL, "%s/upstart/sessions", xdg_runtime_dir));
 
982
 
 
983
                if (! stat (path, &statbuf)) {
 
984
                        nih_local char *cmd = NULL;
 
985
 
 
986
                        /* Clean up if tests forgot to */
 
987
                        cmd = NIH_MUST (nih_sprintf (NULL, "rm %s/*.session 2>/dev/null", path));
 
988
                        system (cmd);
 
989
 
 
990
                        /* Remove the directory tree the first Session Init created */
 
991
                        assert0 (rmdir (path));
 
992
                        path = NIH_MUST (nih_sprintf (NULL, "%s/upstart", xdg_runtime_dir));
 
993
                        assert0 (rmdir (path));
 
994
                }
 
995
 
 
996
                assert0 (rmdir (test_xdg_runtime_dir));
 
997
 
 
998
                assert0 (setenv ("XDG_RUNTIME_DIR", saved_xdg_runtime_dir, 1));
 
999
                nih_info ("Restoring XDG_RUNTIME_DIR='%s'", saved_xdg_config_home);
 
1000
                nih_free (saved_xdg_runtime_dir);
 
1001
                saved_xdg_runtime_dir = NULL;
 
1002
 
 
1003
        }
 
1004
}