diff options
author | Jens Georg <mail@jensge.org> | 2022-06-19 20:01:45 +0200 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2022-06-19 20:06:12 +0200 |
commit | 67a109cc7e219c5be7a23fd4318db5d0758b05cc (patch) | |
tree | b420bb660dbd8b6461e67647503f8ad519fdc0d3 /tests | |
parent | 532e46739f8e160bdd9d38f21c46129d7e4d628e (diff) | |
download | gupnp-67a109cc7e219c5be7a23fd4318db5d0758b05cc.tar.gz |
ContextManager: Handle filter events properly
If the filter is changed, announce all changed to contexts as well
This means if the filter is changed, causing a known device not to match
anymore, it will signal "context-unavailable" and drop all managed
devices attached to that context.
Likewise, for filter changes that cause contexts to not being filtered
out any more, "context-available" will be signalled.
Fixes #36
Fixes #37
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test-context-manager.c | 209 |
1 files changed, 197 insertions, 12 deletions
diff --git a/tests/test-context-manager.c b/tests/test-context-manager.c index ac42c6a..c10cf65 100644 --- a/tests/test-context-manager.c +++ b/tests/test-context-manager.c @@ -35,7 +35,12 @@ test_context_manager_manage () GError *error = NULL; GUPnPContext *ctx = gupnp_context_new ("lo", 0, &error); - g_assert_null (error); + g_assert_no_error (error); + g_assert_nonnull (ctx); + + GUPnPContext *ctx2 = gupnp_context_new ("lo", 0, &error); + g_assert_no_error (error); + g_assert_nonnull (ctx2); GUPnPControlPoint *cp = gupnp_control_point_new (ctx, "upnp::rootdevice"); @@ -53,6 +58,13 @@ test_context_manager_manage () // Check that the context manager has kept a reference on cp g_assert_nonnull (weak); + // Annunce ctx2, which does not have a bound cp + g_signal_emit_by_name (cm, "context-unavailable", ctx2, NULL); + + // Check that the context manager dropped the reference if the + // context is gone + g_assert_nonnull (weak); + g_signal_emit_by_name (cm, "context-unavailable", ctx, NULL); // Check that the context manager dropped the reference if the @@ -73,20 +85,48 @@ test_context_manager_manage () // Check that the context manager has kept a reference on cp g_assert_nonnull (weak); + // Unannunce ctx2, which does not have a bound root device + g_signal_emit_by_name (cm, "context-unavailable", ctx2, NULL); + + // Check that the context manager dropped the reference if the + // context is gone + g_assert_nonnull (weak); + g_signal_emit_by_name (cm, "context-unavailable", ctx, NULL); // Check that the context manager dropped the reference if the // context is gone g_assert_null (weak); + // Check that tearing down the context manager tears down the managed devices + cp = gupnp_control_point_new (ctx, "upnp::rootdevice"); + rd = gupnp_root_device_new (ctx, "TestDevice.xml", DATA_PATH, &error); + gpointer weak_cp = cp; + gpointer weak_rd = rd; + + g_object_add_weak_pointer (G_OBJECT (cp), &weak_cp); + g_object_add_weak_pointer (G_OBJECT (rd), &weak_rd); + + gupnp_context_manager_manage_control_point (GUPNP_CONTEXT_MANAGER (cm), + cp); + gupnp_context_manager_manage_root_device (GUPNP_CONTEXT_MANAGER (cm), + rd); + g_object_unref (cp); + g_object_unref (rd); g_object_unref (cm); + + g_assert_null (weak_cp); + g_assert_null (weak_rd); + g_object_unref (ctx); + g_object_unref (ctx2); } typedef struct _EnableDisableTestData { GUPnPContext *expected_context; - gboolean triggered; + gboolean available_triggered; + gboolean unavailable_triggered; } EnableDisableTestData; void @@ -97,7 +137,18 @@ on_context_available (GUPnPContextManager *cm, EnableDisableTestData *d = user_data; g_assert (d->expected_context == ctx); - d->triggered = TRUE; + d->available_triggered = TRUE; +} + +void +on_context_unavailable (GUPnPContextManager *cm, + GUPnPContext *ctx, + gpointer user_data) +{ + EnableDisableTestData *d = user_data; + + g_assert (d->expected_context == ctx); + d->unavailable_triggered = TRUE; } void @@ -119,10 +170,10 @@ test_context_manager_filter_enable_disable () NULL); EnableDisableTestData context_available_triggered = { .expected_context = ctx, - .triggered = FALSE + .available_triggered = FALSE, + .unavailable_triggered = FALSE }; - const char *iface = gssdp_client_get_interface (GSSDP_CLIENT (ctx)); g_assert_no_error (error); @@ -141,42 +192,172 @@ test_context_manager_filter_enable_disable () "context-available", G_CALLBACK (on_context_available), &context_available_triggered); + g_signal_connect (cm, + "context-unavailable", + G_CALLBACK (on_context_unavailable), + &context_available_triggered); g_signal_emit_by_name (cm, "context-available", ctx, NULL); - g_assert (context_available_triggered.triggered); + g_assert (context_available_triggered.available_triggered); // Enable context filter. Since it is empty, we should still see the event - context_available_triggered.triggered = FALSE; + context_available_triggered.available_triggered = FALSE; gupnp_context_filter_set_enabled (cf, TRUE); g_assert (gupnp_context_filter_get_enabled (cf)); g_signal_emit_by_name (cm, "context-available", ctx, NULL); - g_assert (context_available_triggered.triggered); + g_assert (context_available_triggered.available_triggered); // Enable context filter. Since it is empty, we should still see the event - context_available_triggered.triggered = FALSE; + context_available_triggered.available_triggered = FALSE; gupnp_context_filter_set_enabled (cf, TRUE); g_assert (gupnp_context_filter_get_enabled (cf)); g_signal_emit_by_name (cm, "context-available", ctx, NULL); - g_assert (context_available_triggered.triggered); + g_assert (context_available_triggered.available_triggered); // Filter is enabled and not empty, we should get it since it matches - context_available_triggered.triggered = FALSE; + context_available_triggered.available_triggered = FALSE; g_assert (gupnp_context_filter_get_enabled (cf)); gupnp_context_filter_add_entry (cf, iface); g_assert_false (gupnp_context_filter_is_empty (cf)); g_signal_emit_by_name (cm, "context-available", ctx, NULL); - g_assert (context_available_triggered.triggered); + g_assert (context_available_triggered.available_triggered); + + // Filter that does not match the triggered context, but is disabled + context_available_triggered.available_triggered = FALSE; + gupnp_context_filter_set_enabled (cf, FALSE); + gupnp_context_filter_clear (cf); + + g_assert_false (gupnp_context_filter_get_enabled (cf)); + gupnp_context_filter_add_entry (cf, "wl0ps2"); + g_assert_false (gupnp_context_filter_is_empty (cf)); + + g_signal_emit_by_name (cm, "context-available", ctx, NULL); + g_assert (context_available_triggered.available_triggered); + + // Now enable the filter. We should get the context-unavailable signal + context_available_triggered.available_triggered = FALSE; + gupnp_context_filter_set_enabled (cf, TRUE); + g_assert (context_available_triggered.unavailable_triggered); + g_assert_false (gssdp_client_get_active (GSSDP_CLIENT (ctx))); + + // Now disable the filter. We should get the context-available signal + context_available_triggered.available_triggered = FALSE; + context_available_triggered.unavailable_triggered = FALSE; + gupnp_context_filter_set_enabled (cf, FALSE); + g_assert (context_available_triggered.available_triggered); + g_assert_false (context_available_triggered.unavailable_triggered); + g_assert (gssdp_client_get_active (GSSDP_CLIENT (ctx))); g_clear_object (&ctx); g_clear_error (&error); } +void +test_context_manager_filter_add_remove () +{ + GError *error = NULL; + + GUPnPContext *ctx = g_initable_new (GUPNP_TYPE_CONTEXT, + NULL, + &error, + "host-ip", + "127.0.0.1", + + "network", + "Free WiFi!", + + "active", + FALSE, + NULL); + EnableDisableTestData context_available_triggered = { + .expected_context = ctx, + .available_triggered = FALSE, + .unavailable_triggered = FALSE + }; + + const char *iface = gssdp_client_get_interface (GSSDP_CLIENT (ctx)); + + g_assert_no_error (error); + g_assert_nonnull (ctx); + + TestContextManager *cm = + g_object_new (test_context_manager_get_type (), NULL); + + // Check that the context filter is off and empty by default + GUPnPContextFilter *cf = gupnp_context_manager_get_context_filter ( + GUPNP_CONTEXT_MANAGER (cm)); + g_assert_false (gupnp_context_filter_get_enabled (cf)); + g_assert (gupnp_context_filter_is_empty (cf)); + + g_signal_emit_by_name (cm, "context-available", ctx, NULL); + + g_signal_connect (cm, + "context-available", + G_CALLBACK (on_context_available), + &context_available_triggered); + g_signal_connect (cm, + "context-unavailable", + G_CALLBACK (on_context_unavailable), + &context_available_triggered); + + gupnp_context_filter_set_enabled (cf, TRUE); + g_assert (gupnp_context_filter_get_enabled (cf)); + g_assert_false (context_available_triggered.available_triggered); + g_assert_false (context_available_triggered.unavailable_triggered); + + context_available_triggered.available_triggered = FALSE; + context_available_triggered.unavailable_triggered = FALSE; + gupnp_context_filter_add_entry (cf, "wl3ps3"); + g_assert_false (gupnp_context_filter_is_empty (cf)); + g_assert_false (context_available_triggered.available_triggered); + g_assert (context_available_triggered.unavailable_triggered); + g_assert_false (gssdp_client_get_active (GSSDP_CLIENT (ctx))); + + // Adding the same entry should not trigger any event + context_available_triggered.available_triggered = FALSE; + context_available_triggered.unavailable_triggered = FALSE; + gupnp_context_filter_add_entry (cf, "wl3ps3"); + g_assert_false (gupnp_context_filter_is_empty (cf)); + g_assert_false (context_available_triggered.available_triggered); + g_assert_false (context_available_triggered.unavailable_triggered); + + // Adding an entry that allows the known interface + context_available_triggered.available_triggered = FALSE; + context_available_triggered.unavailable_triggered = FALSE; + gupnp_context_filter_add_entry (cf, iface); + g_assert_false (gupnp_context_filter_is_empty (cf)); + g_assert (context_available_triggered.available_triggered); + g_assert_false (context_available_triggered.unavailable_triggered); + g_assert (gssdp_client_get_active (GSSDP_CLIENT (ctx))); + + // Check that the manager gives up managed objects if a context + // because it disappears from filtering + GUPnPControlPoint *cp = + gupnp_control_point_new (ctx, "upnp::rootdevice"); + gpointer weak = cp; + + g_object_add_weak_pointer (G_OBJECT (cp), &weak); + + gupnp_context_manager_manage_control_point (GUPNP_CONTEXT_MANAGER (cm), + cp); + g_object_unref (cp); + + context_available_triggered.available_triggered = FALSE; + context_available_triggered.unavailable_triggered = FALSE; + gupnp_context_filter_remove_entry (cf, iface); + g_assert_false (gupnp_context_filter_is_empty (cf)); + g_assert_false (context_available_triggered.available_triggered); + g_assert (context_available_triggered.unavailable_triggered); + g_assert_false (gssdp_client_get_active (GSSDP_CLIENT (ctx))); + g_assert_null (weak); +} + int main (int argc, char *argv[]) { @@ -184,8 +365,12 @@ main (int argc, char *argv[]) g_test_add_func ("/context-manager/manage", test_context_manager_manage); + g_test_add_func ("/context_manager/filter/enable_disable", test_context_manager_filter_enable_disable); + g_test_add_func ("/context_manager/filter/add_remove", + test_context_manager_filter_add_remove); + return g_test_run (); } |