Merge branch 'test-autolaunch-win' into 'master'

Add autolaunch test on Windows

Closes #235

See merge request dbus/dbus!95
This commit is contained in:
Simon McVittie 2022-06-27 18:18:53 +00:00
commit 1aed6933c7
6 changed files with 545 additions and 39 deletions

View file

@ -2895,6 +2895,44 @@ static const char *cDBusDaemonMutex = "DBusDaemonMutex";
// named shm for dbus adress info (per user)
static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
/* custom command line parameter for autolaunching daemon */
static const char *autolaunch_custom_command_line_parameter = "";
/**
* Set command line parameters for the dbus daemon to start
* for an autolaunch session.
*
* The specified instance must be valid until the dbus-daemon
* is started.
*
* This function is not thread-safe, and can only be called from a
* single-threaded unit test.
*
* @param path string to use as command line parameter
*/
void _dbus_test_win_autolaunch_set_command_line_parameter (const char *path)
{
autolaunch_custom_command_line_parameter = path;
}
static HANDLE *autolaunch_handle_location;
/**
* Set location where to store process handle of an autostarted server
*
* This function is not thread-safe, and can only be called from a
* single-threaded unit test.
*
* After using the handle it must be closed with @ref CloseHandle().
*
* @param location Pointer where to store the handle
*/
void
_dbus_test_win_set_autolaunch_handle_location (HANDLE *location)
{
autolaunch_handle_location = location;
}
/**
* Return the hash of the installation root directory, which can be
* used to construct a per-installation-root scope for autolaunching
@ -3235,41 +3273,53 @@ _dbus_daemon_unpublish_session_bus_address (void)
return TRUE;
}
/**
* Get server bus address from shared memory segment provided by running dbus-daemon
*
* @param address initialized DBusString instance to store the retrieved address
* @param shm_name the name of the shared memory segment
* @param wait if TRUE wait maximum 2 seconds for the presence of the shared memory segment
* @return #TRUE the bus address was fetched from the shared memory segment
* @return #FALSE error during execution
*/
static dbus_bool_t
_dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
_dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name, dbus_bool_t wait)
{
HANDLE sharedMem;
HANDLE sharedMem = NULL;
char *shared_addr;
int i;
int max = 20; /* max 2 seconds */
dbus_bool_t retval = FALSE;
if (!wait)
max = 1;
// read shm
for(i=0;i<20;++i) {
for (i = 0; i < max; ++i)
{
// we know that dbus-daemon is available, so we wait until shm is available
sharedMem = OpenFileMappingA (FILE_MAP_READ, FALSE, _dbus_string_get_const_data (shm_name));
if (sharedMem == 0)
Sleep (100);
if ( sharedMem != 0)
break;
}
Sleep (100);
if (sharedMem != 0)
break;
}
if (sharedMem == 0)
return FALSE;
return FALSE;
shared_addr = MapViewOfFile (sharedMem, FILE_MAP_READ, 0, 0, 0);
if (!shared_addr)
return FALSE;
goto out;
_dbus_string_init (address);
retval = _dbus_string_append (address, shared_addr);
_dbus_string_append (address, shared_addr);
// cleanup
UnmapViewOfFile (shared_addr);
out:
CloseHandle (sharedMem);
return TRUE;
return retval;
}
static dbus_bool_t
@ -3283,7 +3333,7 @@ _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char
if (!_dbus_string_init (&mutex_name))
return FALSE;
if (!_dbus_get_mutex_name (&mutex_name,scope) ||
if (!_dbus_get_mutex_name (&mutex_name, scope) ||
/* not determinable */
_dbus_string_get_length (&mutex_name) == 0)
{
@ -3300,15 +3350,15 @@ _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char
// do checks
daemon = CreateMutexA (NULL, FALSE, _dbus_string_get_const_data (&mutex_name));
if(WaitForSingleObject (daemon, 10) != WAIT_TIMEOUT)
if (WaitForSingleObject (daemon, 10) != WAIT_TIMEOUT)
{
ReleaseMutex (daemon);
CloseHandle (daemon);
goto out;
}
// read shm
retval = _dbus_get_autolaunch_shm (address, shm_name);
// read shm, wait max 2 seconds
retval = _dbus_get_autolaunch_shm (address, shm_name, TRUE);
// cleanup
CloseHandle (daemon);
@ -3333,14 +3383,15 @@ _dbus_get_autolaunch_address (const char *scope,
LPSTR lpFile;
char dbus_exe_path[MAX_PATH];
DBusString dbus_args = _DBUS_STRING_INIT_INVALID;
const char * daemon_name = DBUS_DAEMON_NAME ".exe";
const char *daemon_name = DBUS_DAEMON_NAME ".exe";
DBusString shm_name;
HANDLE ready_event_handle = NULL;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (!_dbus_string_init (&shm_name))
{
_DBUS_SET_OOM(error);
_DBUS_SET_OOM (error);
return FALSE;
}
@ -3365,12 +3416,12 @@ _dbus_get_autolaunch_address (const char *scope,
if (_dbus_daemon_already_runs (address, &shm_name, scope))
{
_dbus_verbose ("found running dbus daemon for scope '%s' at %s\n",
scope ? scope : "", _dbus_string_get_const_data (&shm_name) );
scope ? scope : "", _dbus_string_get_const_data (&shm_name));
retval = TRUE;
goto out;
}
if (!SearchPathA (NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
if (!SearchPathA (NULL, daemon_name, NULL, sizeof (dbus_exe_path), dbus_exe_path, &lpFile))
{
// Look in directory containing dbus shared library
HMODULE hmod;
@ -3381,7 +3432,7 @@ _dbus_get_autolaunch_address (const char *scope,
"trying path where dbus shared library is located");
hmod = _dbus_win_get_dll_hmodule ();
rc = GetModuleFileNameA (hmod, dbus_module_path, sizeof(dbus_module_path));
rc = GetModuleFileNameA (hmod, dbus_module_path, sizeof (dbus_module_path));
if (rc <= 0)
{
dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not retrieve dbus shared library file name");
@ -3393,7 +3444,7 @@ _dbus_get_autolaunch_address (const char *scope,
char *ext_idx = strrchr (dbus_module_path, '\\');
if (ext_idx)
*ext_idx = '\0';
if (!SearchPathA (dbus_module_path, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
if (!SearchPathA (dbus_module_path, daemon_name, NULL, sizeof (dbus_exe_path), dbus_exe_path, &lpFile))
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Could not find dbus-daemon executable. "
@ -3407,11 +3458,10 @@ _dbus_get_autolaunch_address (const char *scope,
}
}
// Create process
ZeroMemory (&si, sizeof(si));
ZeroMemory (&si, sizeof (si));
si.cb = sizeof (si);
ZeroMemory (&pi, sizeof(pi));
ZeroMemory (&pi, sizeof (pi));
if (!_dbus_string_init (&dbus_args))
{
@ -3420,19 +3470,79 @@ _dbus_get_autolaunch_address (const char *scope,
goto out;
}
if (!_dbus_string_append_printf (&dbus_args, "\"%s\" --session", dbus_exe_path))
if (!_dbus_string_append_printf (&dbus_args, "\"%s\" %s", dbus_exe_path,
autolaunch_custom_command_line_parameter ? autolaunch_custom_command_line_parameter : "--session"))
{
dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, "Failed to append string to argument buffer");
_DBUS_SET_OOM (error);
retval = FALSE;
goto out;
}
// argv[i] = "--config-file=bus\\session.conf";
if(CreateProcessA (dbus_exe_path, _dbus_string_get_data (&dbus_args), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
ready_event_handle = _dbus_win_event_create_inheritable (error);
if (ready_event_handle == NULL)
goto out;
_dbus_verbose ("Creating connection readiness event: handle=%p\n", ready_event_handle);
if (!_dbus_string_append_printf (&dbus_args, " \"--ready-event-handle=%p\"", ready_event_handle))
{
_DBUS_SET_OOM (error);
goto out;
}
_dbus_verbose ("Starting dbus daemon with args: '%s'\n", _dbus_string_get_const_data (&dbus_args));
if (CreateProcessA (dbus_exe_path, _dbus_string_get_data (&dbus_args), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
DWORD status;
HANDLE events[2];
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);
retval = _dbus_get_autolaunch_shm (address, &shm_name);
_dbus_verbose ("Wait until dbus-daemon is ready for connections (event handle %p)\n", ready_event_handle);
events[0] = ready_event_handle;
events[1] = pi.hProcess;
status = WaitForMultipleObjects (2, events, FALSE, 30000);
switch (status)
{
case WAIT_OBJECT_0:
/* ready event signalled, everything is okay */
retval = TRUE;
break;
case WAIT_OBJECT_0 + 1:
/* dbus-daemon process has exited */
dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED, "dbus-daemon exited before signalling ready");
goto out;
case WAIT_FAILED:
_dbus_win_set_error_from_last_error (error, "Unable to wait for server readiness (handle %p)", ready_event_handle);
goto out;
case WAIT_TIMEOUT:
/* GetLastError() is not set */
dbus_set_error (error, DBUS_ERROR_TIMEOUT, "Timed out waiting for server readiness or exit (handle %p)", ready_event_handle);
goto out;
default:
/* GetLastError() is probably not set? */
dbus_set_error (error, DBUS_ERROR_FAILED, "Unknown result '%lu' while waiting for server readiness (handle %p)", status, ready_event_handle);
goto out;
}
_dbus_verbose ("Got signal that dbus-daemon with process id '%ld' is ready for connections\n", GetProcessId (pi.hProcess));
if (autolaunch_handle_location != NULL)
{
*autolaunch_handle_location = pi.hProcess;
_dbus_verbose ("Returning process handle of started server (handle=%p)\n", pi.hProcess);
}
else
{
CloseHandle (pi.hProcess);
}
/* do not wait for the appearance of shm, we can assume that it is present */
retval = _dbus_get_autolaunch_shm (address, &shm_name, FALSE);
if (retval == FALSE)
dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
}
@ -3448,10 +3558,12 @@ out:
_dbus_platform_rmutex_free (lock);
_dbus_string_free (&shm_name);
_dbus_string_free (&dbus_args);
if (ready_event_handle)
_dbus_win_event_free (ready_event_handle, NULL);
_DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
return retval;
}
}
/** Makes the file readable by every user in the system.
*

View file

@ -117,6 +117,10 @@ dbus_bool_t _dbus_daemon_publish_session_bus_address (const char *address,
DBUS_PRIVATE_EXPORT
DBusRMutex *_dbus_win_rmutex_named_new (const char* name);
DBUS_PRIVATE_EXPORT
void _dbus_test_win_autolaunch_set_command_line_parameter (const char *path);
DBUS_PRIVATE_EXPORT
void _dbus_test_win_set_autolaunch_handle_location (HANDLE *location);
#endif
/** @} end of sysdeps-win.h */

View file

@ -0,0 +1,11 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<type>session</type>
<listen>@TEST_LISTEN@</listen>
<policy context="default">
<allow send_destination="*" eavesdrop="true"/>
<allow eavesdrop="true"/>
<allow own="*"/>
</policy>
</busconfig>

View file

@ -1,6 +1,10 @@
add_definitions(${DBUS_INTERNAL_CLIENT_DEFINITIONS})
add_helper_executable(test-autolaunch test-autolaunch.c dbus-testutils)
if(WIN32)
add_test_executable(test-autolaunch-win test-autolaunch-win.c ${DBUS_INTERNAL_LIBRARIES} dbus-testutils)
else()
add_helper_executable(test-autolaunch test-autolaunch.c dbus-testutils)
endif()
add_session_test_executable(test-ids test-ids.c ${DBUS_INTERNAL_LIBRARIES})
add_session_test_executable(test-pending-call-disconnected test-pending-call-disconnected.c ${DBUS_INTERNAL_LIBRARIES})

View file

@ -72,7 +72,7 @@ if DBUS_ENABLE_EMBEDDED_TESTS
## we use noinst_PROGRAMS not check_PROGRAMS for TESTS so that we
## build even when not doing "make check"
noinst_PROGRAMS=test-pending-call-dispatch test-pending-call-timeout test-pending-call-disconnected test-threads-init test-ids test-shutdown test-privserver-client test-autolaunch
noinst_PROGRAMS=test-pending-call-dispatch test-pending-call-timeout test-pending-call-disconnected test-threads-init test-ids test-shutdown test-privserver-client
test_pending_call_dispatch_LDADD = \
$(CODE_COVERAGE_LIBS) \
@ -103,9 +103,21 @@ test_privserver_client_LDADD = \
$(CODE_COVERAGE_LIBS) \
../libdbus-testutils.la \
$(NULL)
if DBUS_WIN
noinst_PROGRAMS += test-autolaunch-win
test_autolaunch_win_SOURCES = test-autolaunch-win.c
test_autolaunch_win_LDADD = \
$(CODE_COVERAGE_LIBS) \
../libdbus-testutils.la \
$(NULL)
TESTS += test-autolaunch-win
else
noinst_PROGRAMS += test-autolaunch
test_autolaunch_SOURCES = test-autolaunch.c
test_autolaunch_LDADD = \
$(CODE_COVERAGE_LIBS) \
../libdbus-testutils.la \
$(NULL)
endif
endif

View file

@ -0,0 +1,363 @@
/*
* Copyright © 2018-2022 Ralf Habacker <ralf.habacker@freenet.de>
* SPDX-License-Identifier: MIT
*/
/**
* This test checks whether a client can connect to a dbus daemon configured
* for a default, user-defined and installation path related autostart and
* whether it can connect to a server having a different autolaunch
* configuration.
*/
#include "config.h"
#include "dbus/dbus-file.h"
#include "dbus/dbus-internals.h"
#include "dbus/dbus-sysdeps.h"
#include "dbus/dbus-test-tap.h"
#include "dbus/dbus-test.h"
#include "dbus/dbus.h"
#include "test/test-utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* dbus_bus_get does not work yet */
static dbus_bool_t use_bus_get = FALSE;
static int add_wait_time = 0;
#define oom() _dbus_test_fatal ("Out of memory")
/**
* helper function
*/
#define _dbus_error_set_from_message_with_location(a, b) __dbus_error_set_from_message_with_location (__FILE__, __LINE__, __FUNCTION__, a, b)
static void
__dbus_error_set_from_message_with_location (const char *file, int line, const char *function, DBusError *error, DBusMessage *message)
{
char *str = NULL;
dbus_message_get_args (message, NULL,
DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID);
dbus_set_error (error, dbus_message_get_error_name (message), "[%s(%d):%s] %s", file, line, function, str ? str : "");
}
static dbus_bool_t
call_method (DBusConnection *conn,
DBusError *error,
int timeout,
const char *interface,
const char *method_str)
{
DBusMessage *method;
DBusMessage *reply;
dbus_bool_t result = TRUE;
dbus_error_init (error);
method = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
interface,
method_str);
reply = dbus_connection_send_with_reply_and_block (conn, method, timeout, error);
dbus_message_unref (method);
if (reply == NULL)
{
dbus_set_error (error, DBUS_ERROR_FAILED, "Got no reply");
result = FALSE;
goto out;
}
if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
{
_dbus_error_set_from_message_with_location (error, reply);
result = FALSE;
goto out;
}
result = TRUE;
out:
_DBUS_ASSERT_ERROR_XOR_BOOL (error, result);
dbus_message_unref (reply);
return result;
}
static dbus_bool_t
_server_check_connection (DBusConnection *conn,
DBusError *error)
{
if (use_bus_get)
return call_method (conn, error, -1, DBUS_INTERFACE_PEER, "GetMachineId");
else
return call_method (conn, error, -1, DBUS_INTERFACE_DBUS, "Hello");
}
static HANDLE autolaunch_handle = NULL;
static dbus_bool_t
_server_shutdown (DBusConnection *conn,
const char *scope,
int timeout,
DBusError *error)
{
_dbus_assert (autolaunch_handle != NULL);
_dbus_test_diag ("Shutting down dbus-daemon (handle=%p)", autolaunch_handle);
if (!TerminateProcess (autolaunch_handle, 1))
_dbus_test_fatal ("Unable to terminate dbus-daemon (handle=%p) : %s",
/* this string is leaked, but we're crashing anyway */
autolaunch_handle, _dbus_win_error_string (GetLastError ()));
_dbus_test_diag ("Return value from closing autolaunch_handle is %d", CloseHandle (autolaunch_handle));
autolaunch_handle = NULL;
_dbus_test_win_set_autolaunch_handle_location (NULL);
return TRUE;
}
typedef enum
{
RUN_TEST_DEFAULT = 0,
RUN_TEST_EXPECT_CONNECTION_TO_FAIL = (1 << 0),
} RunTestFlags;
static dbus_bool_t
check_results (DBusConnection *conn,
DBusString *server_address,
DBusString *address,
const char *scope,
RunTestFlags flags,
DBusError *error)
{
if (add_wait_time)
_dbus_sleep_milliseconds (add_wait_time);
if (dbus_error_is_set (error))
_dbus_test_diag ("Error is set: %s %s", error->name, error->message);
if (conn == NULL)
{
if (!dbus_error_is_set (error))
_dbus_test_fatal ("Failed to autolaunch session bus and no error was set");
if (flags & RUN_TEST_EXPECT_CONNECTION_TO_FAIL)
return TRUE;
_dbus_test_diag ("autolaunch unexpectedly failed: %s: %s", error->name, error->message);
return FALSE;
}
else
{
if (dbus_error_is_set (error))
_dbus_test_fatal ("Successfully autolaunched session bus but error was set: %s: %s", error->name, error->message);
if (flags & RUN_TEST_EXPECT_CONNECTION_TO_FAIL)
{
_dbus_test_diag ("autolaunch unexpectedly succeeded");
return FALSE;
}
_dbus_test_diag ("Client connection succeeded - uses '%s'", _dbus_string_get_const_data (address));
}
if (add_wait_time)
_dbus_sleep_milliseconds (add_wait_time);
_dbus_test_diag ("Server returned bus address '%s'", _dbus_string_get_const_data (server_address));
if (!_server_check_connection (conn, error))
{
_dbus_test_diag ("Could not execute server function");
return FALSE;
}
else
_dbus_test_diag ("Calling server function succeeded");
return TRUE;
}
static dbus_bool_t
run_test (const char *server_scope, const char *scope, const char *test_data_dir, RunTestFlags flags)
{
DBusConnection *conn = NULL;
DBusError error;
DBusString server_address = _DBUS_STRING_INIT_INVALID;
DBusString address = _DBUS_STRING_INIT_INVALID;
DBusString session_parameter = _DBUS_STRING_INIT_INVALID;
dbus_bool_t result = FALSE;
TestMainContext *ctx;
_dbus_assert (test_data_dir);
ctx = test_main_context_get ();
dbus_error_init (&error);
if (!_dbus_string_init (&server_address))
oom ();
if (!_dbus_string_init (&address))
oom ();
_dbus_test_diag ("run test");
if (*server_scope != '\0')
{
if (!_dbus_string_append_printf (&server_address, "autolaunch:scope=%s", server_scope))
oom ();
}
else if (!_dbus_string_append_printf (&server_address, "autolaunch:"))
{
oom ();
}
if (*scope != '\0')
{
if (!_dbus_string_append_printf (&address, "autolaunch:scope=%s", scope))
oom ();
}
else if (!_dbus_string_append_printf (&address, "autolaunch:"))
{
oom ();
}
if (!_dbus_string_init (&session_parameter))
oom ();
/* We haven't implemented any form of escaping quotes,
* but Windows doesn't allow filenames to contain quotes
* so it shouldn't matter. */
_dbus_test_check (strchr (test_data_dir, '"') == NULL);
_dbus_test_check (strchr (_dbus_string_get_const_data (&server_address), '"') == NULL);
if (!_dbus_string_append_printf (&session_parameter, "\"--config-file=%s/%s\" \"--address=%s\"", test_data_dir, "valid-config-files/listen-autolaunch-win.conf", _dbus_string_get_const_data (&server_address)))
{
oom ();
}
_dbus_test_win_autolaunch_set_command_line_parameter (_dbus_string_get_const_data (&session_parameter));
_dbus_test_diag ("Autolaunch handle initially %p", autolaunch_handle);
_dbus_test_win_set_autolaunch_handle_location (&autolaunch_handle);
if (use_bus_get)
{
dbus_setenv ("DBUS_SESSION_BUS_ADDRESS", _dbus_string_get_const_data (&address));
_dbus_test_diag ("got env %s", getenv ("DBUS_SESSION_BUS_ADDRESS"));
conn = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
dbus_connection_set_exit_on_disconnect (conn, FALSE);
}
else
{
conn = dbus_connection_open_private (_dbus_string_get_const_data (&address), &error);
}
_dbus_test_diag ("After attempting to connect: autolaunch handle is %p", autolaunch_handle);
if (conn)
test_connection_setup (ctx, conn);
result = check_results (conn, &server_address, &address, scope, flags, &error);
if (conn)
{
_dbus_test_diag("Shutdown connection '%p'", conn);
test_connection_shutdown (ctx, conn);
dbus_connection_close (conn);
dbus_connection_unref (conn);
}
_server_shutdown (conn, scope, -1, &error);
_dbus_test_diag ("server has been shut down");
_dbus_string_free (&address);
_dbus_string_free (&server_address);
_dbus_string_free (&session_parameter);
test_main_context_unref (ctx);
return result;
}
static dbus_bool_t
run_test_okay (const char *scope, const char *test_data_dir)
{
return run_test (scope, scope, test_data_dir, RUN_TEST_DEFAULT);
}
static dbus_bool_t
_dbus_autolaunch_default_test (const char *test_data_dir)
{
return run_test_okay ("", test_data_dir);
}
static dbus_bool_t
_dbus_autolaunch_custom_scope_test (const char *test_data_dir)
{
return run_test_okay ("123", test_data_dir);
}
static dbus_bool_t
_dbus_autolaunch_install_path_scope_test (const char *test_data_dir)
{
return run_test_okay ("*install-path", test_data_dir);
}
static dbus_bool_t
_dbus_autolaunch_user_scope_test (const char *test_data_dir)
{
return run_test_okay ("*user", test_data_dir);
}
static dbus_bool_t
_dbus_autolaunch_loop_test (const char *test_data_dir, dbus_bool_t same_scope)
{
int i;
int max = 10;
for (i = 0; i < max; i++)
{
char s[2] = { i+'A', 0 };
if (!run_test_okay (same_scope ? "A" : s, test_data_dir))
_dbus_test_not_ok ("%d", max);
else
_dbus_test_ok ("%d", max);
if (add_wait_time)
_dbus_sleep_milliseconds (add_wait_time);
}
return TRUE;
}
static dbus_bool_t
_dbus_autolaunch_same_scope_loop_test (const char *test_data_dir)
{
return _dbus_autolaunch_loop_test (test_data_dir, TRUE);
}
static dbus_bool_t
_dbus_autolaunch_different_scope_loop_test (const char *test_data_dir)
{
return _dbus_autolaunch_loop_test (test_data_dir, FALSE);
}
static DBusTestCase tests[] = {
{ "default", _dbus_autolaunch_default_test },
{ "custom", _dbus_autolaunch_custom_scope_test },
{ "install-path", _dbus_autolaunch_install_path_scope_test },
{ "user", _dbus_autolaunch_user_scope_test },
{ "loop", _dbus_autolaunch_same_scope_loop_test },
{ "different-scope-loop", _dbus_autolaunch_different_scope_loop_test },
};
int
main (int argc,
char **argv)
{
return _dbus_test_main (argc, argv, _DBUS_N_ELEMENTS (tests), tests,
DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS,
NULL, NULL);
}