mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 01:48:00 +02:00
Add a test application for autostart on Windows implementation
The test application performs several individual tests to detect possible problems with the autostart support under Windows. Connections are tested with the standard scope, a 'custom' scope, the 'install path' scope and the 'user' scope. Signed-off-by: Ralf Habacker <ralf.habacker@freenet.de>
This commit is contained in:
parent
556eb2ea1a
commit
b1dd6fa7a6
4 changed files with 393 additions and 3 deletions
11
test/data/valid-config-files/listen-autolaunch-win.conf.in
Normal file
11
test/data/valid-config-files/listen-autolaunch-win.conf.in
Normal 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>
|
||||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
363
test/name-test/test-autolaunch-win.c
Normal file
363
test/name-test/test-autolaunch-win.c
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue