libnm: merge branch 'th/libnm-no-dbus-codegen-3'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/324
This commit is contained in:
Thomas Haller
2019-11-07 13:23:01 +01:00
23 changed files with 681 additions and 455 deletions

View File

@@ -600,6 +600,9 @@ permission_changed (NMClient *client,
if (got_permissions (nmc)) {
/* Defer the printing, so that we have a chance to process the other
* permission-changed signals. */
g_signal_handlers_disconnect_by_func (nmc->client,
G_CALLBACK (permission_changed),
nmc);
g_idle_remove_by_data (nmc);
g_idle_add (print_permissions, nmc);
}
@@ -616,7 +619,7 @@ show_nm_permissions (NmCli *nmc)
/* The client didn't get the permissions reply yet. Subscribe to changes. */
g_signal_connect (nmc->client, NM_CLIENT_PERMISSION_CHANGED,
G_CALLBACK (permission_changed), nmc);
G_CALLBACK (permission_changed), nmc);
if (nmc->timeout == -1)
nmc->timeout = 10;

View File

@@ -91,11 +91,13 @@ import itertools
import subprocess
import shlex
import re
import fcntl
import dbus
import time
import random
import dbus.service
import dbus.mainloop.glib
import io
###############################################################################
@@ -173,26 +175,52 @@ class Util:
@staticmethod
def popen_wait(p, timeout = 0):
if Util.python_has_version(3, 3):
if timeout == 0:
return p.poll()
try:
return p.wait(timeout)
except subprocess.TimeoutExpired:
return None
(res, b_stdout, b_stderr) = Util.popen_wait_read(p, timeout = timeout, read_std_pipes = False)
return res
@staticmethod
def popen_wait_read(p, timeout = 0, read_std_pipes = True):
start = NM.utils_get_timestamp_msec()
delay = 0.0005
b_stdout = b''
b_stderr = b''
res = None
while True:
if read_std_pipes:
b_stdout += Util.buffer_read(p.stdout)
b_stderr += Util.buffer_read(p.stderr)
if p.poll() is not None:
return p.returncode
res = p.returncode
break
if timeout == 0:
return None
break
assert(timeout > 0)
remaining = timeout - ((NM.utils_get_timestamp_msec() - start) / 1000.0)
if remaining <= 0:
return None
break
delay = min(delay * 2, remaining, 0.05)
time.sleep(delay)
return (res, b_stdout, b_stderr)
@staticmethod
def buffer_read(buf):
b = b''
while True:
try:
b1 = buf.read()
except io.BlockingIOError:
b1 = b''
except IOError:
b1 = b''
if not b1:
return b
b += b1
@staticmethod
def buffer_set_nonblock(buf):
fd = buf.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
@staticmethod
def random_job(jobs):
@@ -459,10 +487,14 @@ class AsyncProcess():
def start(self):
if not hasattr(self, '_p'):
self._p_start_timestamp = NM.utils_get_timestamp_msec()
self._p_stdout_buf = b''
self._p_stderr_buf = b''
self._p = subprocess.Popen(self._args,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
env = self._env)
Util.buffer_set_nonblock(self._p.stdout)
Util.buffer_set_nonblock(self._p.stderr)
def _timeout_remaining_time(self):
# note that we call this during poll() and wait_and_complete().
@@ -476,7 +508,11 @@ class AsyncProcess():
def poll(self, timeout = 0):
self.start()
return_code = Util.popen_wait(self._p, timeout)
(return_code, b_stdout, b_stderr) = Util.popen_wait_read(self._p, timeout)
self._p_stdout_buf += b_stdout
self._p_stderr_buf += b_stderr
if return_code is None \
and self._timeout_remaining_time() <= 0:
raise Exception("process is still running after timeout: %s" % (' '.join(self._args)))
@@ -488,11 +524,16 @@ class AsyncProcess():
p = self._p
self._p = None
return_code = Util.popen_wait(p, max(0, self._timeout_remaining_time()) / 1000)
(return_code, b_stdout, b_stderr) = Util.popen_wait_read(p, max(0, self._timeout_remaining_time()) / 1000)
(stdout, stderr) = (p.stdout.read(), p.stderr.read())
p.stdout.close()
p.stderr.close()
stdout = self._p_stdout_buf + b_stdout + stdout
stderr = self._p_stderr_buf + b_stderr + stderr
del self._p_stdout_buf
del self._p_stderr_buf
if return_code is None:
print(stdout)
print(stderr)
@@ -670,6 +711,7 @@ class TestNmcli(NmTestBase):
env['TERM'] = 'linux'
env['ASAN_OPTIONS'] = 'detect_leaks=0'
env['XDG_CONFIG_HOME'] = PathConfiguration.srcdir()
env['NM_TEST_CALLING_NUM'] = str(calling_num)
if fatal_warnings is _DEFAULT_ARG or fatal_warnings:
env['G_DEBUG'] = 'fatal-warnings'

View File

@@ -511,16 +511,15 @@ nm_client_wwan_hardware_get_enabled (NMClient *client)
* Determines whether WiMAX is enabled.
*
* Returns: %TRUE if WiMAX is enabled
*
* Deprecated: 1.22 This function always returns FALSE because WiMax is no longer supported
**/
gboolean
nm_client_wimax_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
if (!nm_client_get_nm_running (client))
return FALSE;
return nm_manager_wimax_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
return FALSE;
}
/**
@@ -529,16 +528,13 @@ nm_client_wimax_get_enabled (NMClient *client)
* @enabled: %TRUE to enable WiMAX
*
* Enables or disables WiMAX devices.
*
* Deprecated: 1.22 This function does nothing because WiMax is no longer supported
**/
void
nm_client_wimax_set_enabled (NMClient *client, gboolean enabled)
{
g_return_if_fail (NM_IS_CLIENT (client));
if (!nm_client_get_nm_running (client))
return;
nm_manager_wimax_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
}
/**
@@ -548,16 +544,15 @@ nm_client_wimax_set_enabled (NMClient *client, gboolean enabled)
* Determines whether the WiMAX hardware is enabled.
*
* Returns: %TRUE if the WiMAX hardware is enabled
*
* Deprecated: 1.22 This function always returns FALSE because WiMax is no longer supported
**/
gboolean
nm_client_wimax_hardware_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
if (!nm_client_get_nm_running (client))
return FALSE;
return nm_manager_wimax_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
return FALSE;
}
/**
@@ -3540,13 +3535,10 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, FALSE);
break;
case PROP_WIMAX_ENABLED:
g_value_set_boolean (value, nm_client_wimax_get_enabled (self));
g_value_set_boolean (value, FALSE);
break;
case PROP_WIMAX_HARDWARE_ENABLED:
if (priv->manager)
g_object_get_property (G_OBJECT (priv->manager), pspec->name, value);
else
g_value_set_boolean (value, FALSE);
g_value_set_boolean (value, FALSE);
break;
case PROP_ACTIVE_CONNECTIONS:
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_active_connections (self)));
@@ -3643,11 +3635,12 @@ set_property (GObject *object, guint prop_id,
case PROP_NETWORKING_ENABLED:
case PROP_WIRELESS_ENABLED:
case PROP_WWAN_ENABLED:
case PROP_WIMAX_ENABLED:
case PROP_CONNECTIVITY_CHECK_ENABLED:
if (priv->manager)
g_object_set_property (G_OBJECT (priv->manager), pspec->name, value);
break;
case PROP_WIMAX_ENABLED:
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4015,7 +4008,7 @@ nm_client_class_init (NMClientClass *client_class)
*
* Whether WiMAX functionality is enabled.
*
* The property setter is a synchronous D-Bus call. This is deprecated since 1.22.
* Deprecated: 1.22: WiMAX is no longer supported and this always returns FALSE. The setter has no effect.
*/
obj_properties[PROP_WIMAX_ENABLED] =
g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, "", "",
@@ -4027,6 +4020,8 @@ nm_client_class_init (NMClientClass *client_class)
* NMClient:wimax-hardware-enabled:
*
* Whether the WiMAX hardware is enabled.
*
* Deprecated: 1.22: WiMAX is no longer supported and this always returns FALSE.
**/
obj_properties[PROP_WIMAX_HARDWARE_ENABLED] =
g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, "", "",

View File

@@ -245,11 +245,14 @@ void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled);
gboolean nm_client_wwan_hardware_get_enabled (NMClient *client);
NM_DEPRECATED_IN_1_22
gboolean nm_client_wimax_get_enabled (NMClient *client);
NM_DEPRECATED_IN_1_22
_NM_DEPRECATED_SYNC_METHOD
void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled);
NM_DEPRECATED_IN_1_22
gboolean nm_client_wimax_hardware_get_enabled (NMClient *client);
NM_AVAILABLE_IN_1_10

View File

@@ -1066,6 +1066,10 @@ nm_device_get_managed (NMDevice *device)
* Since: 1.2
*
* Deprecated: 1.22, use nm_device_set_managed_async() or GDBusConnection
*
* This function is deprecated because it calls a synchronous D-Bus method
* and modifies the content of the NMClient cache client side. Also, it does
* not emit a property changed signal.
**/
void
nm_device_set_managed (NMDevice *device, gboolean managed)
@@ -1108,6 +1112,9 @@ nm_device_get_autoconnect (NMDevice *device)
* Enables or disables automatic activation of the #NMDevice.
*
* Deprecated: 1.22, use nm_device_set_autoconnect_async() or GDBusConnection
*
* This function is deprecated because it calls a synchronous D-Bus method
* and modifies the content of the NMClient cache client side.
**/
void
nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect)

View File

@@ -77,11 +77,13 @@ NMDeviceCapabilities nm_device_get_capabilities (NMDevice *device);
gboolean nm_device_get_managed (NMDevice *device);
NM_AVAILABLE_IN_1_2
NM_DEPRECATED_IN_1_22
_NM_DEPRECATED_SYNC_METHOD
void nm_device_set_managed (NMDevice *device, gboolean managed);
gboolean nm_device_get_autoconnect (NMDevice *device);
NM_DEPRECATED_IN_1_22
_NM_DEPRECATED_SYNC_METHOD
void nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect);

View File

@@ -8,6 +8,9 @@
#include "nm-libnm-utils.h"
#include "nm-glib-aux/nm-time-utils.h"
#include "nm-libnm-core-intern/nm-common-macros.h"
/*****************************************************************************/
volatile int _nml_dbus_log_level = 0;
@@ -43,6 +46,7 @@ _nml_dbus_log (NMLDBusLogLevel level,
gs_free char *msg = NULL;
va_list args;
const char *prefix = "";
gint64 ts;
/* we only call _nml_dbus_log() after nml_dbus_log_enabled(), which already does
* an atomic access to the variable. Since the value is only initialized once and
@@ -84,7 +88,13 @@ _nml_dbus_log (NMLDBusLogLevel level,
break;
}
g_printerr ("libnm-dbus: %s%s\n", prefix, msg);
ts = nm_utils_clock_gettime_ns (CLOCK_BOOTTIME);
g_printerr ("libnm-dbus: %s[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s\n",
prefix,
ts / NM_UTILS_NS_PER_SECOND,
(ts / (NM_UTILS_NS_PER_SECOND / 10000)) % 10000,
msg);
}
/*****************************************************************************/
@@ -649,3 +659,85 @@ nm_utils_fixup_product_string (const char *desc)
return desc_full;
}
/*****************************************************************************/
NMClientPermission
nm_permission_to_client (const char *nm)
{
static const struct {
const char *name;
NMClientPermission perm;
} list[] = {
{ NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK },
{ NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK },
{ NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK },
{ NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS },
{ NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI },
{ NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX },
{ NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN },
{ NM_AUTH_PERMISSION_NETWORK_CONTROL, NM_CLIENT_PERMISSION_NETWORK_CONTROL },
{ NM_AUTH_PERMISSION_RELOAD, NM_CLIENT_PERMISSION_RELOAD },
{ NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS },
{ NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME },
{ NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN },
{ NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM },
{ NM_AUTH_PERMISSION_SLEEP_WAKE, NM_CLIENT_PERMISSION_SLEEP_WAKE },
{ NM_AUTH_PERMISSION_WIFI_SCAN, NM_CLIENT_PERMISSION_WIFI_SCAN },
{ NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN },
{ NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED },
};
gssize idx;
#if NM_MORE_ASSERTS > 10
{
static gboolean checked = FALSE;
int i, j;
if (!checked) {
checked = TRUE;
for (i = 0; i < G_N_ELEMENTS (list); i++) {
nm_assert (list[i].perm != NM_CLIENT_PERMISSION_NONE);
nm_assert (list[i].name && list[i].name[0]);
if (i > 0) {
if (strcmp (list[i - 1].name, list[i].name) >= 0) {
g_error ("list is not sorted by name: #%d (%s) should be after #%d (%s)",
i - 1, list[i - 1].name, i, list[i].name);
}
}
for (j = i + 1; j < G_N_ELEMENTS (list); j++) {
nm_assert (list[i].perm != list[j].perm);
}
}
}
}
#endif
if (nm) {
idx = nm_utils_array_find_binary_search (list,
sizeof (list[0]),
G_N_ELEMENTS (list),
&nm,
nm_strcmp_p_with_data,
NULL);
if (idx >= 0)
return list[idx].perm;
}
return NM_CLIENT_PERMISSION_NONE;
}
NMClientPermissionResult
nm_permission_result_to_client (const char *nm)
{
if (!nm)
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
if (nm_streq (nm, "yes"))
return NM_CLIENT_PERMISSION_RESULT_YES;
if (nm_streq (nm, "no"))
return NM_CLIENT_PERMISSION_RESULT_NO;
if (nm_streq (nm, "auth"))
return NM_CLIENT_PERMISSION_RESULT_AUTH;
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
}

View File

@@ -8,6 +8,7 @@
#include "nm-types.h"
#include "nm-glib-aux/nm-ref-string.h"
#include "nm-client.h"
/*****************************************************************************/
@@ -17,6 +18,12 @@
/*****************************************************************************/
NMClientPermission nm_permission_to_client (const char *nm);
NMClientPermissionResult nm_permission_result_to_client (const char *nm);
/*****************************************************************************/
typedef enum {
_NML_DBUS_LOG_LEVEL_INITIALIZED = 0x01,
@@ -124,9 +131,7 @@ _nml_coerce_property_object_path (NMRefString *path)
{
if (!path)
return NULL;
if (nm_streq (path->str, "/"))
return NULL;
return path->str;
return nm_dbus_path_not_empty (path->str);
}
static inline const char *const*

View File

@@ -254,59 +254,6 @@ object_creation_failed (NMObject *object, const char *failed_path)
}
}
static NMClientPermission
nm_permission_to_client (const char *nm)
{
if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK))
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK;
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI))
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI;
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN))
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN;
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX))
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX;
else if (!strcmp (nm, NM_AUTH_PERMISSION_SLEEP_WAKE))
return NM_CLIENT_PERMISSION_SLEEP_WAKE;
else if (!strcmp (nm, NM_AUTH_PERMISSION_NETWORK_CONTROL))
return NM_CLIENT_PERMISSION_NETWORK_CONTROL;
else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED))
return NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED;
else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN))
return NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN;
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM))
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM;
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN))
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN;
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME))
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME;
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS))
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS;
else if (!strcmp (nm, NM_AUTH_PERMISSION_RELOAD))
return NM_CLIENT_PERMISSION_RELOAD;
else if (!strcmp (nm, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK))
return NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK;
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS))
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS;
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK))
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK;
else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SCAN))
return NM_CLIENT_PERMISSION_WIFI_SCAN;
return NM_CLIENT_PERMISSION_NONE;
}
static NMClientPermissionResult
nm_permission_result_to_client (const char *nm)
{
if (!strcmp (nm, "yes"))
return NM_CLIENT_PERMISSION_RESULT_YES;
else if (!strcmp (nm, "no"))
return NM_CLIENT_PERMISSION_RESULT_NO;
else if (!strcmp (nm, "auth"))
return NM_CLIENT_PERMISSION_RESULT_AUTH;
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
}
static void
update_permissions (NMManager *self, GVariant *permissions)
{

View File

@@ -10,8 +10,9 @@
#include "nm-test-libnm-utils.h"
static GMainLoop *loop = NULL;
static NMTstcServiceInfo *sinfo;
static struct {
GMainLoop *loop;
} gl = { };
/*****************************************************************************/
@@ -24,68 +25,6 @@ loop_quit (gpointer user_data)
/*****************************************************************************/
static NMClient *
_nm_client_new_sync (void)
{
NMClient *client;
guint source_1;
GError *error = NULL;
source_1 = g_idle_add (nmtst_g_source_assert_not_called, NULL);
client = g_object_new (NM_TYPE_CLIENT, NULL);
g_assert (NM_IS_CLIENT (client));
if (!g_initable_init (G_INITABLE (client), NULL, &error))
g_assert_not_reached ();
g_assert_no_error (error);
nm_clear_g_source (&source_1);
return client;
}
typedef struct {
GMainLoop *loop;
NMClient *client;
} NewSyncInsideDispatchedData;
static gboolean
_nm_client_new_sync_inside_dispatched_do (gpointer user_data)
{
NewSyncInsideDispatchedData *d = user_data;
g_assert (d->loop);
g_assert (!d->client);
d->client = _nm_client_new_sync ();
g_main_loop_quit (d->loop);
return G_SOURCE_CONTINUE;
}
static NMClient *
_nm_client_new_sync_inside_dispatched (void)
{
NewSyncInsideDispatchedData d = { };
guint source_1;
d.loop = g_main_loop_new (NULL, FALSE);
source_1 = g_idle_add (_nm_client_new_sync_inside_dispatched_do, &d);
g_main_loop_run (d.loop);
g_assert (NM_IS_CLIENT (d.client));
nm_clear_g_source (&source_1);
g_main_loop_unref (d.loop);
return d.client;
}
/*****************************************************************************/
static void
devices_notify_cb (NMClient *c,
GParamSpec *pspec,
@@ -109,7 +48,8 @@ devices_notify_cb (NMClient *c,
static void
test_device_added (void)
{
NMClient *client;
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
const GPtrArray *devices;
NMDevice *device;
gboolean notified = FALSE;
@@ -119,8 +59,7 @@ test_device_added (void)
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
devices = nm_client_get_devices (client);
g_assert (devices->len == 0);
@@ -151,9 +90,6 @@ test_device_added (void)
nm_device_delete (device, NULL, &error);
g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_SOFTWARE);
g_clear_error (&error);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
}
/*****************************************************************************/
@@ -190,6 +126,8 @@ devices_sai_notify_cb (NMClient *c,
const GPtrArray *devices;
NMDevice *device;
g_assert_cmpstr (pspec->name, ==, "devices");
devices = nm_client_get_devices (c);
g_assert (devices);
g_assert_cmpint (devices->len, ==, 1);
@@ -205,18 +143,17 @@ devices_sai_notify_cb (NMClient *c,
static void
test_device_added_signal_after_init (void)
{
NMClient *client;
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
const GPtrArray *devices;
NMDevice *device;
guint result = 0;
GError *error = NULL;
sinfo = nmtstc_service_init ();
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
devices = nm_client_get_devices (client);
g_assert (devices->len == 0);
@@ -253,9 +190,6 @@ test_device_added_signal_after_init (void)
device = g_ptr_array_index (devices, 0);
g_assert (device);
g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
}
/*****************************************************************************/
@@ -355,19 +289,19 @@ wifi_ap_remove_notify_cb (NMDeviceWifi *w,
static void
test_wifi_ap_added_removed (void)
{
NMClient *client;
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
NMDeviceWifi *wifi;
WifiApInfo info = { loop, FALSE, FALSE, 0, 0 };
WifiApInfo info = { gl.loop, FALSE, FALSE, 0, 0 };
GVariant *ret;
GError *error = NULL;
char *expected_path = NULL;
gs_free char *expected_path = NULL;
sinfo = nmtstc_service_init ();
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
/*************************************/
/* Add the wifi device */
@@ -406,8 +340,8 @@ test_wifi_ap_added_removed (void)
info.quit_count++;
/* Wait for libnm to find the AP */
info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
g_main_loop_run (loop);
info.quit_id = g_timeout_add_seconds (5, loop_quit, gl.loop);
g_main_loop_run (gl.loop);
g_assert (info.signaled);
g_assert (info.notified);
@@ -445,8 +379,8 @@ test_wifi_ap_added_removed (void)
info.quit_count++;
/* Wait for libnm to find the AP */
info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
g_main_loop_run (loop);
info.quit_id = g_timeout_add_seconds (5, loop_quit, gl.loop);
g_main_loop_run (gl.loop);
g_assert (info.signaled);
g_assert (info.notified);
@@ -454,10 +388,6 @@ test_wifi_ap_added_removed (void)
g_signal_handlers_disconnect_by_func (wifi, wifi_ap_remove_notify_cb, &info);
g_free (info.ap_path);
g_free (expected_path);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
}
/*****************************************************************************/
@@ -516,26 +446,12 @@ da_devices_notify_cb (NMClient *c,
da_check_quit (info);
}
static void
new_client_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
NMClient **out_client = user_data;
GError *error = NULL;
*out_client = nm_client_new_finish (result, &error);
g_assert_no_error (error);
g_assert (*out_client != NULL);
g_main_loop_quit (loop);
}
static void
test_devices_array (void)
{
NMClient *client = NULL;
DaInfo info = { loop };
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
DaInfo info = { gl.loop };
NMDevice *wlan0, *eth0, *eth1, *device;
const GPtrArray *devices;
GError *error = NULL;
@@ -545,10 +461,7 @@ test_devices_array (void)
if (!nmtstc_service_available (sinfo))
return;
/* Make sure that we test the async codepath in at least one test... */
nm_client_new_async (NULL, new_client_cb, &client);
g_main_loop_run (loop);
g_assert (client != NULL);
client = nmtstc_client_new (TRUE);
/*************************************/
/* Add some devices */
@@ -598,8 +511,8 @@ test_devices_array (void)
info.quit_count = 2;
/* Wait for libnm to notice the changes */
info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
g_main_loop_run (loop);
info.quit_id = g_timeout_add_seconds (5, loop_quit, gl.loop);
g_main_loop_run (gl.loop);
g_assert_cmpint (info.quit_count, ==, 0);
g_signal_handlers_disconnect_by_func (client, da_device_removed_cb, &info);
@@ -617,9 +530,6 @@ test_devices_array (void)
device = nm_client_get_device_by_iface (client, "eth1");
g_assert (NM_IS_DEVICE_ETHERNET (device));
g_assert (device == eth1);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
}
static void
@@ -630,20 +540,20 @@ nm_running_changed (GObject *client,
int *running_changed = user_data;
(*running_changed)++;
g_main_loop_quit (loop);
g_main_loop_quit (gl.loop);
}
static void
test_client_nm_running (void)
{
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client1 = NULL;
gs_unref_object NMClient *client2 = NULL;
guint quit_id;
int running_changed = 0;
GError *error = NULL;
client1 = nm_client_new (NULL, &error);
g_assert_no_error (error);
client1 = nmtstc_client_new (TRUE);
g_assert (!nm_client_get_nm_running (client1));
g_assert_cmpstr (nm_client_get_version (client1), ==, NULL);
@@ -663,8 +573,7 @@ test_client_nm_running (void)
if (!nmtstc_service_available (sinfo))
return;
client2 = nm_client_new (NULL, &error);
g_assert_no_error (error);
client2 = nmtstc_client_new (FALSE);
/* client2 should know that NM is running, but the previously-created
* client1 hasn't gotten the news yet.
@@ -674,8 +583,8 @@ test_client_nm_running (void)
g_signal_connect (client1, "notify::" NM_CLIENT_NM_RUNNING,
G_CALLBACK (nm_running_changed), &running_changed);
quit_id = g_timeout_add_seconds (5, loop_quit, loop);
g_main_loop_run (loop);
quit_id = g_timeout_add_seconds (5, loop_quit, gl.loop);
g_main_loop_run (gl.loop);
g_assert_cmpint (running_changed, ==, 1);
g_assert (nm_client_get_nm_running (client1));
g_source_remove (quit_id);
@@ -685,8 +594,8 @@ test_client_nm_running (void)
g_assert (nm_client_get_nm_running (client1));
quit_id = g_timeout_add_seconds (5, loop_quit, loop);
g_main_loop_run (loop);
quit_id = g_timeout_add_seconds (5, loop_quit, gl.loop);
g_main_loop_run (gl.loop);
g_assert_cmpint (running_changed, ==, 2);
g_assert (!nm_client_get_nm_running (client1));
g_source_remove (quit_id);
@@ -697,6 +606,9 @@ typedef struct {
NMActiveConnection *ac;
int remaining;
NMDevice *device;
gulong ac_signal_id;
} TestACInfo;
static void
@@ -786,18 +698,17 @@ device_ac_changed_cb (GObject *device,
static void
test_active_connections (void)
{
NMClient *client;
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
NMDevice *device;
NMConnection *conn;
TestACInfo info = { loop, NULL, 0 };
GError *error = NULL;
TestACInfo info = { gl.loop, NULL, 0 };
sinfo = nmtstc_service_init ();
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
/* Tell the test service to add a new device */
device = nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0");
@@ -814,30 +725,25 @@ test_active_connections (void)
/* Two signals plus activate_cb */
info.remaining = 3;
g_main_loop_run (loop);
g_main_loop_run (gl.loop);
g_signal_handlers_disconnect_by_func (client, client_acs_changed_cb, &info);
g_signal_handlers_disconnect_by_func (device, device_ac_changed_cb, &info);
g_assert (info.ac != NULL);
g_object_unref (info.ac);
g_object_unref (client);
g_clear_object (&client);
/* Ensure that we can correctly resolve the recursive property link between the
* AC and the Device in a newly-created client.
*/
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
assert_ac_and_device (client);
g_object_unref (client);
g_clear_object (&client);
client = NULL;
nm_client_new_async (NULL, new_client_cb, &client);
g_main_loop_run (loop);
client = nmtstc_client_new (TRUE);
assert_ac_and_device (client);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
g_clear_object (&client);
}
static void
@@ -865,9 +771,12 @@ client_devices_changed_cb (GObject *client,
g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0.1");
if (!nm_device_get_active_connection (device)) {
g_assert (info->ac_signal_id == 0);
info->remaining++;
g_signal_connect (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION,
G_CALLBACK (device_ac_changed_cb), info);
info->device = device;
g_object_add_weak_pointer (G_OBJECT (device), (gpointer *) &info->device);
info->ac_signal_id = g_signal_connect (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION,
G_CALLBACK (device_ac_changed_cb), info);
}
info->remaining--;
@@ -916,20 +825,19 @@ activate_cb (GObject *object,
static void
test_activate_virtual (void)
{
NMClient *client;
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
NMConnection *conn;
NMSettingConnection *s_con;
NMSettingVlan *s_vlan;
TestACInfo info = { loop, NULL, 0 };
TestConnectionInfo conn_info = { loop, NULL };
GError *error = NULL;
TestACInfo info = { gl.loop, NULL, 0 };
TestConnectionInfo conn_info = { gl.loop, NULL };
sinfo = nmtstc_service_init ();
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0");
@@ -945,7 +853,7 @@ test_activate_virtual (void)
nm_client_add_connection_async (client, conn, TRUE,
NULL, add_connection_cb, &conn_info);
g_main_loop_run (loop);
g_main_loop_run (gl.loop);
g_object_unref (conn);
conn = NM_CONNECTION (conn_info.remote);
@@ -965,72 +873,27 @@ test_activate_virtual (void)
*/
info.remaining = 3;
g_main_loop_run (loop);
g_main_loop_run (gl.loop);
g_signal_handlers_disconnect_by_func (client, client_acs_changed_cb, &info);
g_signal_handlers_disconnect_by_func (client, client_devices_changed_cb, &info);
g_assert (info.ac != NULL);
g_clear_object (&info.ac);
g_object_unref (info.ac);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
}
static void
activate_failed_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
NMClient *client = NM_CLIENT (object);
NMActiveConnection *ac;
GError *error = NULL;
ac = nm_client_add_and_activate_connection_finish (client, result, &error);
g_assert (ac == NULL);
g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_OBJECT_CREATION_FAILED);
g_clear_error (&error);
g_main_loop_quit (loop);
}
static void
test_activate_failed (void)
{
NMClient *client;
NMDevice *device;
NMConnection *conn;
GError *error = NULL;
sinfo = nmtstc_service_init ();
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
device = nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0");
/* Note that test-networkmanager-service.py checks for this exact name */
conn = nmtst_create_minimal_connection ("object-creation-failed-test", NULL,
NM_SETTING_WIRED_SETTING_NAME, NULL);
nm_client_add_and_activate_connection_async (client, conn, device, NULL,
NULL, activate_failed_cb, NULL);
g_main_loop_run (loop);
g_object_unref (conn);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
if (info.device) {
g_object_remove_weak_pointer (G_OBJECT (info.device), (gpointer *) &info.device);
nm_clear_g_signal_handler (info.device, &info.ac_signal_id);
}
}
static void
test_device_connection_compatibility (void)
{
NMClient *client;
NMDevice *device1, *device2;
NMConnection *conn;
nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL;
gs_unref_object NMClient *client = NULL;
gs_unref_object NMConnection *conn = NULL;
NMDevice *device1;
NMDevice *device2;
NMSettingWired *s_wired;
GError *error = NULL;
const char *subchannels[] = { "0.0.8000", "0.0.8001", "0.0.8002", NULL };
@@ -1043,8 +906,7 @@ test_device_connection_compatibility (void)
if (!nmtstc_service_available (sinfo))
return;
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
client = nmtstc_client_new (TRUE);
/* Create two devices */
device1 = nmtstc_service_add_wired_device (sinfo, client, "eth0", hw_addr1, subchannels);
@@ -1092,11 +954,6 @@ test_device_connection_compatibility (void)
nm_device_connection_compatible (device1, conn, &error);
g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION);
g_clear_error (&error);
g_object_unref (conn);
g_object_unref (client);
g_clear_pointer (&sinfo, nmtstc_service_cleanup);
}
/*****************************************************************************/
@@ -1179,9 +1036,7 @@ test_connection_invalid (void)
FALSE,
&path2);
client = nmtst_get_rand_bool ()
? _nm_client_new_sync ()
: _nm_client_new_sync_inside_dispatched ();
client = nmtstc_client_new (TRUE);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1216,7 +1071,7 @@ test_connection_invalid (void)
FALSE,
&path3);
nmtst_main_loop_run (loop, 1000);
nmtst_main_loop_run (gl.loop, 1000);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1252,7 +1107,7 @@ test_connection_invalid (void)
variant,
FALSE);
nmtst_main_loop_run (loop, 100);
nmtst_main_loop_run (gl.loop, 100);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1290,7 +1145,7 @@ test_connection_invalid (void)
variant,
FALSE);
nmtst_main_loop_run (loop, 100);
nmtst_main_loop_run (gl.loop, 100);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1325,7 +1180,7 @@ test_connection_invalid (void)
connection,
FALSE);
nmtst_main_loop_run (loop, 100);
nmtst_main_loop_run (gl.loop, 100);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1367,7 +1222,7 @@ test_connection_invalid (void)
connection,
FALSE);
nmtst_main_loop_run (loop, 100);
nmtst_main_loop_run (gl.loop, 100);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1409,7 +1264,7 @@ test_connection_invalid (void)
connection,
FALSE);
nmtst_main_loop_run (loop, 100);
nmtst_main_loop_run (gl.loop, 100);
connections = nm_client_get_connections (client);
g_assert (connections);
@@ -1448,7 +1303,7 @@ main (int argc, char **argv)
nmtst_init (&argc, &argv, TRUE);
loop = g_main_loop_new (NULL, FALSE);
gl.loop = g_main_loop_new (NULL, FALSE);
g_test_add_func ("/libnm/device-added", test_device_added);
g_test_add_func ("/libnm/device-added-signal-after-init", test_device_added_signal_after_init);
@@ -1457,7 +1312,6 @@ main (int argc, char **argv)
g_test_add_func ("/libnm/client-nm-running", test_client_nm_running);
g_test_add_func ("/libnm/active-connections", test_active_connections);
g_test_add_func ("/libnm/activate-virtual", test_activate_virtual);
g_test_add_func ("/libnm/activate-failed", test_activate_failed);
g_test_add_func ("/libnm/device-connection-compatibility", test_device_connection_compatibility);
g_test_add_func ("/libnm/connection/invalid", test_connection_invalid);

View File

@@ -8,12 +8,16 @@
#include <sys/types.h>
#include <signal.h>
#include "nm-glib-aux/nm-time-utils.h"
#include "nm-test-libnm-utils.h"
static NMTstcServiceInfo *sinfo;
static NMClient *client = NULL;
GDBusConnection *bus = NULL;
NMRemoteConnection *remote = NULL;
static struct {
NMTstcServiceInfo *sinfo;
NMClient *client;
GDBusConnection *bus;
NMRemoteConnection *remote;
} gl = { };
/*****************************************************************************/
@@ -25,17 +29,17 @@ add_cb (GObject *s,
gboolean *done = user_data;
GError *error = NULL;
remote = nm_client_add_connection_finish (client, result, &error);
gl.remote = nm_client_add_connection_finish (gl.client, result, &error);
g_assert_no_error (error);
*done = TRUE;
g_object_add_weak_pointer (G_OBJECT (remote), (void **) &remote);
g_object_add_weak_pointer (G_OBJECT (gl.remote), (void **) &gl.remote);
/* nm_client_add_connection_finish() adds a ref to @remote, but we
* want the weak pointer to be cleared as soon as @client drops its own ref.
* So drop ours.
*/
g_object_unref (remote);
g_object_unref (gl.remote);
}
#define TEST_CON_ID "blahblahblah"
@@ -44,32 +48,27 @@ static void
test_add_connection (void)
{
NMConnection *connection;
time_t start, now;
gboolean done = FALSE;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
connection = nmtst_create_minimal_connection (TEST_CON_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
nm_client_add_connection_async (client,
nm_client_add_connection_async (gl.client,
connection,
TRUE,
NULL,
add_cb,
&done);
start = time (NULL);
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
} while ((done == FALSE) && (now - start < 5));
g_assert (done == TRUE);
g_assert (remote != NULL);
nmtst_main_context_iterate_until (NULL, 5000, done);
g_assert (gl.remote != NULL);
/* Make sure the connection is the same as what we added */
g_assert (nm_connection_compare (connection,
NM_CONNECTION (remote),
NM_CONNECTION (gl.remote),
NM_SETTING_COMPARE_FLAG_EXACT) == TRUE);
g_object_unref (connection);
}
@@ -99,7 +98,7 @@ visible_changed_cb (GObject *object, GParamSpec *pspec, gboolean *done)
static void
connection_removed_cb (NMClient *s, NMRemoteConnection *connection, gboolean *done)
{
if (connection == remote)
if (connection == gl.remote)
*done = TRUE;
}
@@ -116,7 +115,6 @@ invis_has_settings_cb (NMSetting *setting,
static void
test_make_invisible (void)
{
time_t start, now;
const GPtrArray *conns;
int i;
GDBusProxy *proxy;
@@ -124,17 +122,17 @@ test_make_invisible (void)
gboolean has_settings = FALSE;
char *path;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
g_assert (remote != NULL);
g_assert (gl.remote != NULL);
/* Listen for the remove event when the connection becomes invisible */
g_signal_connect (remote, "notify::" NM_REMOTE_CONNECTION_VISIBLE, G_CALLBACK (visible_changed_cb), &visible_changed);
g_signal_connect (client, "connection-removed", G_CALLBACK (connection_removed_cb), &connection_removed);
g_signal_connect (gl.remote, "notify::" NM_REMOTE_CONNECTION_VISIBLE, G_CALLBACK (visible_changed_cb), &visible_changed);
g_signal_connect (gl.client, "connection-removed", G_CALLBACK (connection_removed_cb), &connection_removed);
path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote)));
proxy = g_dbus_proxy_new_sync (bus,
path = g_strdup (nm_connection_get_path (NM_CONNECTION (gl.remote)));
proxy = g_dbus_proxy_new_sync (gl.bus,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
NULL,
NM_DBUS_SERVICE,
@@ -153,29 +151,23 @@ test_make_invisible (void)
set_visible_cb, NULL);
/* Wait for the connection to be removed */
start = time (NULL);
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
} while ((!visible_changed || !connection_removed) && (now - start < 5));
g_assert (visible_changed == TRUE);
g_assert (connection_removed == TRUE);
nmtst_main_context_iterate_until (NULL, 5000, visible_changed && connection_removed);
g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (visible_changed_cb), &visible_changed);
g_signal_handlers_disconnect_by_func (client, G_CALLBACK (connection_removed_cb), &connection_removed);
g_signal_handlers_disconnect_by_func (gl.remote, G_CALLBACK (visible_changed_cb), &visible_changed);
g_signal_handlers_disconnect_by_func (gl.client, G_CALLBACK (connection_removed_cb), &connection_removed);
/* Ensure NMClient no longer has the connection */
conns = nm_client_get_connections (client);
conns = nm_client_get_connections (gl.client);
for (i = 0; i < conns->len; i++) {
NMConnection *candidate = NM_CONNECTION (conns->pdata[i]);
g_assert ((gpointer) remote != (gpointer) candidate);
g_assert ((gpointer) gl.remote != (gpointer) candidate);
g_assert (strcmp (path, nm_connection_get_path (candidate)) != 0);
}
/* And ensure the invisible connection no longer has any settings */
g_assert (remote);
nm_connection_for_each_setting_value (NM_CONNECTION (remote),
g_assert (gl.remote);
nm_connection_for_each_setting_value (NM_CONNECTION (gl.remote),
invis_has_settings_cb,
&has_settings);
g_assert (has_settings == FALSE);
@@ -197,7 +189,6 @@ vis_new_connection_cb (NMClient *foo,
static void
test_make_visible (void)
{
time_t start, now;
const GPtrArray *conns;
int i;
GDBusProxy *proxy;
@@ -205,17 +196,17 @@ test_make_visible (void)
char *path;
NMRemoteConnection *new = NULL;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
g_assert (remote != NULL);
g_assert (gl.remote != NULL);
/* Wait for the new-connection signal when the connection is visible again */
g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED,
g_signal_connect (gl.client, NM_CLIENT_CONNECTION_ADDED,
G_CALLBACK (vis_new_connection_cb), &new);
path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote)));
proxy = g_dbus_proxy_new_sync (bus,
path = g_strdup (nm_connection_get_path (NM_CONNECTION (gl.remote)));
proxy = g_dbus_proxy_new_sync (gl.bus,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
NULL,
NM_DBUS_SERVICE,
@@ -234,24 +225,19 @@ test_make_visible (void)
set_visible_cb, NULL);
/* Wait for the settings service to announce the connection again */
start = time (NULL);
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
} while ((new == NULL) && (now - start < 5));
nmtst_main_context_iterate_until (NULL, 5000, new);
/* Ensure the new connection is the same as the one we made visible again */
g_assert (new);
g_assert (new == remote);
g_assert (new == gl.remote);
g_signal_handlers_disconnect_by_func (client, G_CALLBACK (vis_new_connection_cb), &new);
g_signal_handlers_disconnect_by_func (gl.client, G_CALLBACK (vis_new_connection_cb), &new);
/* Ensure NMClient has the connection */
conns = nm_client_get_connections (client);
conns = nm_client_get_connections (gl.client);
for (i = 0; i < conns->len; i++) {
NMConnection *candidate = NM_CONNECTION (conns->pdata[i]);
if ((gpointer) remote == (gpointer) candidate) {
if ((gpointer) gl.remote == (gpointer) candidate) {
g_assert_cmpstr (path, ==, nm_connection_get_path (candidate));
g_assert_cmpstr (TEST_CON_ID, ==, nm_connection_get_id (candidate));
found = TRUE;
@@ -282,7 +268,7 @@ deleted_cb (GObject *proxy,
static void
removed_cb (NMClient *s, NMRemoteConnection *connection, gboolean *done)
{
if (connection == remote)
if (connection == gl.remote)
*done = TRUE;
}
@@ -290,27 +276,26 @@ static void
test_remove_connection (void)
{
NMRemoteConnection *connection;
time_t start, now;
const GPtrArray *conns;
int i;
GDBusProxy *proxy;
gboolean done = FALSE;
char *path;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
/* Find a connection to delete */
conns = nm_client_get_connections (client);
conns = nm_client_get_connections (gl.client);
g_assert_cmpint (conns->len, >, 0);
connection = NM_REMOTE_CONNECTION (conns->pdata[0]);
g_assert (connection);
g_assert (remote == connection);
g_assert (gl.remote == connection);
path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
g_signal_connect (client, "connection-removed", G_CALLBACK (removed_cb), &done);
g_signal_connect (gl.client, "connection-removed", G_CALLBACK (removed_cb), &done);
proxy = g_dbus_proxy_new_sync (bus,
proxy = g_dbus_proxy_new_sync (gl.bus,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
NULL,
NM_DBUS_SERVICE,
@@ -328,18 +313,10 @@ test_remove_connection (void)
NULL,
deleted_cb, NULL);
start = time (NULL);
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
if (done && !remote)
break;
} while (now - start < 5);
g_assert (done == TRUE);
g_assert (!remote);
nmtst_main_context_iterate_until (NULL, 5000, done && !gl.remote);
/* Ensure NMClient no longer has the connection */
conns = nm_client_get_connections (client);
conns = nm_client_get_connections (gl.client);
for (i = 0; i < conns->len; i++) {
NMConnection *candidate = NM_CONNECTION (conns->pdata[i]);
@@ -364,7 +341,7 @@ add_remove_cb (GObject *s,
gboolean *done = user_data;
gs_free_error GError *error = NULL;
connection = nm_client_add_connection_finish (client, result, &error);
connection = nm_client_add_connection_finish (gl.client, result, &error);
g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_OBJECT_CREATION_FAILED);
g_assert (connection == NULL);
@@ -374,43 +351,34 @@ add_remove_cb (GObject *s,
static void
test_add_remove_connection (void)
{
GVariant *ret;
gs_unref_variant GVariant *ret = NULL;
GError *error = NULL;
NMConnection *connection;
time_t start, now;
gs_unref_object NMConnection *connection = NULL;
gboolean done = FALSE;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
/* This will cause the test server to immediately delete the connection
* after creating it.
*/
ret = g_dbus_proxy_call_sync (sinfo->proxy,
ret = g_dbus_proxy_call_sync (gl.sinfo->proxy,
"AutoRemoveNextConnection",
NULL,
G_DBUS_CALL_FLAGS_NONE, -1,
NULL,
&error);
g_assert_no_error (error);
g_variant_unref (ret);
nmtst_assert_success (ret, error);
connection = nmtst_create_minimal_connection (TEST_ADD_REMOVE_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
nm_client_add_connection_async (client,
nm_client_add_connection_async (gl.client,
connection,
TRUE,
NULL,
add_remove_cb,
&done);
start = time (NULL);
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
} while ((done == FALSE) && (now - start < 5));
g_assert (done == TRUE);
g_object_unref (connection);
nmtst_main_context_iterate_until (NULL, 5000, done);
}
/*****************************************************************************/
@@ -423,7 +391,7 @@ add_bad_cb (GObject *s,
gboolean *done = user_data;
gs_free_error GError *error = NULL;
remote = nm_client_add_connection_finish (client, result, &error);
gl.remote = nm_client_add_connection_finish (gl.client, result, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
*done = TRUE;
@@ -432,31 +400,25 @@ add_bad_cb (GObject *s,
static void
test_add_bad_connection (void)
{
NMConnection *connection;
time_t start, now;
gs_unref_object NMConnection *connection = NULL;
gboolean done = FALSE;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
/* The test daemon doesn't support bond connections */
connection = nmtst_create_minimal_connection ("bad connection test", NULL, NM_SETTING_BOND_SETTING_NAME, NULL);
nm_client_add_connection_async (client,
nm_client_add_connection_async (gl.client,
connection,
TRUE,
NULL,
add_bad_cb,
&done);
g_object_unref (connection);
g_clear_object (&connection);
start = time (NULL);
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
} while ((done == FALSE) && (now - start < 5));
g_assert (done == TRUE);
g_assert (remote == NULL);
nmtst_main_context_iterate_until (NULL, 5000, done);
g_assert (gl.remote == NULL);
}
/*****************************************************************************/
@@ -469,7 +431,7 @@ save_hostname_cb (GObject *s,
gboolean *done = user_data;
gs_free_error GError *error = NULL;
nm_client_save_hostname_finish (client, result, &error);
nm_client_save_hostname_finish (gl.client, result, &error);
g_assert_no_error (error);
*done = TRUE;
@@ -478,27 +440,30 @@ save_hostname_cb (GObject *s,
static void
test_save_hostname (void)
{
time_t start, now;
gint64 until_ts;
gboolean done = FALSE;
GError *error = NULL;
if (!nmtstc_service_available (sinfo))
if (!nmtstc_service_available (gl.sinfo))
return;
/* test-networkmanager-service.py requires the hostname to contain a '.' */
nm_client_save_hostname (client, "foo", NULL, &error);
nm_client_save_hostname (gl.client, "foo", NULL, &error);
g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_HOSTNAME);
g_clear_error (&error);
nm_client_save_hostname_async (client, "example.com", NULL, save_hostname_cb, &done);
nm_client_save_hostname_async (gl.client, "example.com", NULL, save_hostname_cb, &done);
start = time (NULL);
do {
now = time (NULL);
until_ts = nm_utils_get_monotonic_timestamp_ms () + 5000;
while (TRUE) {
g_main_context_iteration (NULL, FALSE);
} while ((done == FALSE) && (now - start < 5));
g_assert (done == TRUE);
g_assert (remote == NULL);
if (done)
break;
if (nm_utils_get_monotonic_timestamp_ms () >= until_ts)
g_assert_not_reached ();
}
g_assert (gl.remote == NULL);
}
/*****************************************************************************/
@@ -515,14 +480,12 @@ main (int argc, char **argv)
nmtst_init (&argc, &argv, TRUE);
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error);
gl.bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
nmtst_assert_success (gl.bus, error);
sinfo = nmtstc_service_init ();
gl.sinfo = nmtstc_service_init ();
client = nm_client_new (NULL, &error);
g_assert_no_error (error);
g_assert (client != NULL);
gl.client = nmtstc_client_new (TRUE);
/* FIXME: these tests assume that they get run in order, but g_test_run()
* does not actually guarantee that!
@@ -537,9 +500,9 @@ main (int argc, char **argv)
ret = g_test_run ();
nmtstc_service_cleanup (sinfo);
g_object_unref (client);
g_object_unref (bus);
nm_clear_pointer (&gl.sinfo, nmtstc_service_cleanup);
g_clear_object (&gl.client);
g_clear_object (&gl.bus);
return ret;
}

View File

@@ -234,8 +234,9 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data)
if (!sadata->sinfo)
return;
sadata->client = nm_client_new (NULL, &error);
g_assert_no_error (error);
g_assert (g_main_context_get_thread_default () == NULL);
sadata->client = nmtstc_client_new (TRUE);
sadata->loop = g_main_loop_new (NULL, FALSE);
sadata->timeout_id = g_timeout_add_seconds (5, timeout_assert, NULL);

View File

@@ -206,3 +206,34 @@ nm_pdirect_equal (gconstpointer a, gconstpointer b)
&& s2
&& *s1 == *s2);
}
guint
nm_ppdirect_hash (gconstpointer p)
{
const void *const*const*s = p;
if (!s)
return nm_hash_static (396534869u);
if (!*s)
return nm_hash_static (1476102263u);
return nm_direct_hash (**s);
}
gboolean
nm_ppdirect_equal (gconstpointer a, gconstpointer b)
{
const void *const*const*s1 = a;
const void *const*const*s2 = b;
if (s1 == s2)
return TRUE;
if (!s1 || !s2)
return FALSE;
if (*s1 == *s2)
return TRUE;
if (!*s1 || !*s2)
return FALSE;
return **s1 == **s2;
}

View File

@@ -279,12 +279,20 @@ gboolean nm_pstr_equal (gconstpointer a, gconstpointer b);
/*****************************************************************************/
/* this hashes/compares the pointer value that we point to. Basically,
* (((const void *const*) a) == ((const void *const*) b)). */
* (*((const void *const*) a) == *((const void *const*) b)). */
guint nm_pdirect_hash (gconstpointer p);
gboolean nm_pdirect_equal (gconstpointer a, gconstpointer b);
/* this hashes/compares the direct pointer value by following pointers to
* pointers 2 times.
* (**((const void *const*const*) a) == **((const void *const*const*) b)). */
guint nm_ppdirect_hash (gconstpointer p);
gboolean nm_ppdirect_equal (gconstpointer a, gconstpointer b);
/*****************************************************************************/
#define NM_HASH_OBFUSCATE_PTR_FMT "%016" G_GINT64_MODIFIER "x"

View File

@@ -635,6 +635,13 @@ NM_G_ERROR_MSG (GError *error)
#define _NM_ENSURE_TYPE_CONST(type, value) ((const type) (value))
#endif
#if _NM_CC_SUPPORT_GENERIC
#define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) (_Generic ((((container *) NULL)->field), \
type: G_STRUCT_OFFSET (container, field)))
#else
#define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) G_STRUCT_OFFSET (container, field)
#endif
#if _NM_CC_SUPPORT_GENERIC
/* these macros cast (value) to
* - "const char **" (for "MC", mutable-const)
@@ -1261,6 +1268,17 @@ nm_clear_g_cancellable_disconnect (GCancellable *cancellable, gulong *cancellabl
/*****************************************************************************/
static inline const char *
nm_dbus_path_not_empty (const char *str)
{
nm_assert (!str || str[0] == '/');
return !str || (str[0] == '/' && str[1] == '\0')
? NULL
: str;
}
/*****************************************************************************/
/* GVariantType is basically a C string. But G_VARIANT_TYPE() is not suitable
* to initialize a static variable (because it evaluates a function check that
* the string is valid). Add an alternative macro that does the plain cast.

View File

@@ -180,8 +180,14 @@ _nm_ref_string_unref_non_null (NMRefString *rstr)
/* in the fast-path above, we already decremented the ref-count to zero.
* We need recheck that the ref-count is still zero. */
if (g_atomic_int_get (&rstr0->ref_count) == 0)
g_hash_table_remove (gl_hash, rstr0);
if (g_atomic_int_get (&rstr0->ref_count) == 0) {
if (!g_hash_table_remove (gl_hash, rstr0))
nm_assert_not_reached ();
} else {
#if NM_MORE_ASSERTS > 5
nm_assert (g_hash_table_lookup (gl_hash, rstr0) == rstr0);
#endif
}
G_UNLOCK (gl_lock);
}

View File

@@ -684,6 +684,30 @@ _nm_g_slice_free_fcn_define (32)
/*****************************************************************************/
static inline void
nm_g_set_error_take (GError **error, GError *error_take)
{
if (!error_take)
g_return_if_reached ();
if (!error) {
g_error_free (error_take);
return;
}
if (*error) {
g_error_free (error_take);
g_return_if_reached ();
}
*error = error_take;
}
#define nm_g_set_error_take_lazy(error, error_take_lazy) \
G_STMT_START { \
GError **_error = (error); \
\
if (_error) \
nm_g_set_error_take (_error, (error_take_lazy)); \
} G_STMT_END
/**
* NMUtilsError:
* @NM_UTILS_ERROR_UNKNOWN: unknown or unclassified error
@@ -901,6 +925,45 @@ nm_g_source_destroy_and_unref (GSource *source)
g_source_unref (source);
}
NM_AUTO_DEFINE_FCN0 (GSource *, _nm_auto_destroy_and_unref_gsource, nm_g_source_destroy_and_unref);
#define nm_auto_destroy_and_unref_gsource nm_auto(_nm_auto_destroy_and_unref_gsource)
NM_AUTO_DEFINE_FCN0 (GMainContext *, _nm_auto_pop_gmaincontext, g_main_context_pop_thread_default)
#define nm_auto_pop_gmaincontext nm_auto (_nm_auto_pop_gmaincontext)
static inline GMainContext *
nm_g_main_context_push_thread_default (GMainContext *context)
{
/* This function is to work together with nm_auto_pop_gmaincontext. */
if (G_UNLIKELY (!context))
context = g_main_context_default ();
g_main_context_push_thread_default (context);
return context;
}
static inline GMainContext *
nm_g_main_context_push_thread_default_if_necessary (GMainContext *context)
{
GMainContext *cur_context;
cur_context = g_main_context_get_thread_default ();
if (cur_context == context)
return NULL;
if (G_UNLIKELY (!cur_context)) {
cur_context = g_main_context_default ();
if (cur_context == context)
return NULL;
} else if (G_UNLIKELY (!context)) {
context = g_main_context_default ();
if (cur_context == context)
return NULL;
}
g_main_context_push_thread_default (context);
return context;
}
/*****************************************************************************/
static inline int

View File

@@ -67,3 +67,4 @@ void nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
GVariant *connection,
gboolean verify_connection);
NMClient *nmtstc_client_new (gboolean allow_iterate_main_context);

View File

@@ -406,3 +406,151 @@ nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("()")));
g_variant_unref (result);
}
/*****************************************************************************/
typedef struct {
GMainLoop *loop;
NMClient *client;
} NMTstcClientNewData;
static void
_nmtstc_client_new_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
NMTstcClientNewData *d = user_data;
gs_free_error GError *error = NULL;
g_assert (!d->client);
d->client = nm_client_new_finish (res,
nmtst_get_rand_bool () ? &error : NULL);
nmtst_assert_success (NM_IS_CLIENT (d->client), error);
g_main_loop_quit (d->loop);
}
static NMClient *
_nmtstc_client_new (gboolean sync)
{
gs_free GError *error = NULL;
NMClient *client;
/* Create a NMClient instance synchronously, and arbitrarily use either
* the sync or async constructor.
*
* Note that the sync and async construct differ in one important aspect:
* the async constructor iterates the current g_main_context_get_thread_default(),
* while the sync constructor does not! Aside from that, both should behave
* pretty much the same way. */
if (sync) {
nm_auto_destroy_and_unref_gsource GSource *source = NULL;
if (nmtst_get_rand_bool ()) {
/* the current main context must not be iterated! */
source = g_idle_source_new ();
g_source_set_callback (source, nmtst_g_source_assert_not_called, NULL, NULL);
g_source_attach (source, g_main_context_get_thread_default ());
}
if (nmtst_get_rand_bool ()) {
gboolean success;
client = g_object_new (NM_TYPE_CLIENT, NULL);
g_assert (NM_IS_CLIENT (client));
success = g_initable_init (G_INITABLE (client),
NULL,
nmtst_get_rand_bool () ? &error : NULL);
nmtst_assert_success (success, error);
} else {
client = nm_client_new (NULL,
nmtst_get_rand_bool () ? &error : NULL);
}
} else {
nm_auto_unref_gmainloop GMainLoop *loop = NULL;
NMTstcClientNewData d = { .loop = NULL, };
loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
d.loop = loop;
nm_client_new_async (NULL,
_nmtstc_client_new_cb,
&d);
g_main_loop_run (loop);
g_assert (NM_IS_CLIENT (d.client));
client = d.client;
}
nmtst_assert_success (NM_IS_CLIENT (client), error);
return client;
}
typedef struct {
GMainLoop *loop;
NMClient *client;
bool sync;
} NewSyncInsideDispatchedData;
static gboolean
_nmtstc_client_new_inside_loop_do (gpointer user_data)
{
NewSyncInsideDispatchedData *d = user_data;
g_assert (d->loop);
g_assert (!d->client);
d->client = nmtstc_client_new (d->sync);
g_main_loop_quit (d->loop);
return G_SOURCE_CONTINUE;
}
static NMClient *
_nmtstc_client_new_inside_loop (gboolean sync)
{
GMainContext *context = g_main_context_get_thread_default ();
nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new (context, FALSE);
NewSyncInsideDispatchedData d = {
.sync = sync,
.loop = loop,
};
nm_auto_destroy_and_unref_gsource GSource *source = NULL;
source = g_idle_source_new ();
g_source_set_callback (source, _nmtstc_client_new_inside_loop_do, &d, NULL);
g_source_attach (source, context);
g_main_loop_run (loop);
g_assert (NM_IS_CLIENT (d.client));
return d.client;
}
NMClient *
nmtstc_client_new (gboolean allow_iterate_main_context)
{
gboolean inside_loop;
gboolean sync;
if (!allow_iterate_main_context) {
sync = TRUE;
inside_loop = FALSE;
} else {
/* The caller allows to iterate the main context. That that point,
* we can both use the synchronous and the asynchronous initialization,
* both should yield the same result. Choose one randomly. */
sync = nmtst_get_rand_bool ();
inside_loop = ((nmtst_get_rand_uint32 () % 3) == 0);
}
if (inside_loop) {
/* Create the client on an idle handler of the current context.
* In practice, it should make no difference, which this check
* tries to prove. */
return _nmtstc_client_new_inside_loop (sync);
}
return _nmtstc_client_new (sync);
}

View File

@@ -1010,6 +1010,34 @@ _nmtst_main_loop_quit_on_notify (GObject *object, GParamSpec *pspec, gpointer us
}
#define nmtst_main_loop_quit_on_notify ((GCallback) _nmtst_main_loop_quit_on_notify)
static inline gboolean
_nmtst_main_context_iterate_until_timeout (gpointer user_data)
{
gboolean *p_had_pointer = user_data;
g_assert (!*p_had_pointer);
*p_had_pointer = TRUE;
return G_SOURCE_CONTINUE;
}
#define nmtst_main_context_iterate_until(context, timeout_ms, condition) \
G_STMT_START { \
nm_auto_destroy_and_unref_gsource GSource *_source = NULL; \
GMainContext *_context = (context); \
gboolean _had_timeout = FALSE; \
\
_source = g_timeout_source_new (timeout_ms); \
g_source_set_callback (_source, _nmtst_main_context_iterate_until_timeout, &_had_timeout, NULL); \
g_source_attach (_source, _context); \
\
while (TRUE) { \
if (condition) \
break; \
g_main_context_iteration (_context, TRUE); \
g_assert (!_had_timeout && #condition); \
} \
} G_STMT_END
/*****************************************************************************/
static inline const char *

View File

@@ -209,7 +209,7 @@ nm_checkpoint_manager_destroy (NMCheckpointManager *self,
g_return_val_if_fail (path && path[0] == '/', FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
if (nm_streq (path, "/")) {
if (!nm_dbus_path_not_empty (path)) {
nm_checkpoint_manager_destroy_all (self);
return TRUE;
}

View File

@@ -1543,7 +1543,7 @@ p2p_props_changed_cb (GDBusProxy *proxy,
if (g_variant_lookup (changed_properties, "Group", "&o", &path)) {
if (priv->group_proxy && g_strcmp0 (path, g_dbus_proxy_get_object_path (priv->group_proxy)) == 0) {
/* We already have the proxy, nothing to do. */
} else if (path && g_strcmp0 (path, "/") != 0) {
} else if (nm_dbus_path_not_empty (path)) {
if (priv->group_proxy != NULL) {
_LOGW ("P2P: Unexpected update of the group object path");
priv->group_proxy_acquired = FALSE;

View File

@@ -672,6 +672,7 @@ PRP_DEVICE_UDI = "Udi"
PRP_DEVICE_IFACE = "Interface"
PRP_DEVICE_DRIVER = "Driver"
PRP_DEVICE_STATE = "State"
PRP_DEVICE_STATE_REASON = "StateReason"
PRP_DEVICE_ACTIVE_CONNECTION = "ActiveConnection"
PRP_DEVICE_IP4_CONFIG = "Ip4Config"
PRP_DEVICE_IP6_CONFIG = "Ip6Config"
@@ -700,11 +701,14 @@ class Device(ExportedObj):
self.dhcp4_config = None
self.dhcp6_config = None
self.prp_state = NM.DeviceState.UNAVAILABLE
props = {
PRP_DEVICE_UDI: "/sys/devices/virtual/%s" % (iface),
PRP_DEVICE_IFACE: iface,
PRP_DEVICE_DRIVER: "virtual",
PRP_DEVICE_STATE: dbus.UInt32(NM.DeviceState.UNAVAILABLE),
PRP_DEVICE_STATE: dbus.UInt32(self.prp_state),
PRP_DEVICE_STATE_REASON: dbus.Struct((dbus.UInt32(self.prp_state), dbus.UInt32(NM.DeviceStateReason.NONE))),
PRP_DEVICE_ACTIVE_CONNECTION: ExportedObj.to_path(None),
PRP_DEVICE_IP4_CONFIG: ExportedObj.to_path(self.ip4_config),
PRP_DEVICE_IP6_CONFIG: ExportedObj.to_path(self.ip6_config),
@@ -1302,14 +1306,6 @@ class NetworkManager(ExportedObj):
ac = ActiveConnection(device, con_inst, None)
self.active_connection_add(ac)
if NmUtil.con_hash_get_id(con_hash) == 'object-creation-failed-test':
# FIXME: this is not the right test, to delete the active-connection
# before returning it. It's the wrong order of what NetworkManager
# would do.
self.active_connection_remove(ac)
return ExportedObj.to_path(ac)
return ExportedObj.to_path(ac)
def active_connection_add(self, ac):
@@ -1596,6 +1592,9 @@ class Connection(ExportedObj):
@dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}')
def GetSettings(self):
if hasattr(self, '_remove_next_connection_cb'):
self._remove_next_connection_cb()
raise BusErr.UnknownConnectionException("Connection not found")
if not self.visible:
raise BusErr.PermissionDeniedException()
return self.con_hash
@@ -1698,11 +1697,21 @@ class Settings(ExportedObj):
self.NewConnection(con_inst.path)
self._dbus_property_set(IFACE_SETTINGS, PRP_SETTINGS_CONNECTIONS, dbus.Array(self.get_connection_paths(), 'o'))
gl.manager.devices_available_connections_update()
if self.remove_next_connection:
self.remove_next_connection = False
self.delete_connection(con_inst)
gl.manager.devices_available_connections_update()
def cb():
if hasattr(con_inst, '_remove_next_connection_cb'):
del con_inst._remove_next_connection_cb
self.delete_connection(con_inst)
return False
# We will delete the connection right away on an idle handler. However,
# the test races with initializing the connection (calling GetSettings()).
# To avoid the race, we will check in GetSettings() whether the profile
# is about to be deleted, and delete it first.
con_inst._remove_next_connection_cb = cb
GLib.idle_add(cb)
return con_inst.path