GDBus: Remove cached value if a property is invalidated
[platform/upstream/glib.git] / gio / tests / gdbus-proxy.c
index f9e1743..17752fe 100644 (file)
@@ -46,13 +46,13 @@ test_methods (GDBusConnection *connection,
 
   /* check that we can invoke a method */
   error = NULL;
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "HelloWorld",
-                                            g_variant_new ("(s)", "Hey"),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1,
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "HelloWorld",
+                                   g_variant_new ("(s)", "Hey"),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1,
+                                   NULL,
+                                   &error);
   g_assert_no_error (error);
   g_assert (result != NULL);
   g_assert_cmpstr (g_variant_get_type_string (result), ==, "(s)");
@@ -61,13 +61,13 @@ test_methods (GDBusConnection *connection,
   g_variant_unref (result);
 
   /* Check that we can completely recover the returned error */
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "HelloWorld",
-                                            g_variant_new ("(s)", "Yo"),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1,
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "HelloWorld",
+                                   g_variant_new ("(s)", "Yo"),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1,
+                                   NULL,
+                                   &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR);
   g_assert (g_dbus_error_is_remote_error (error));
   g_assert (g_dbus_error_is_remote_error (error));
@@ -81,13 +81,13 @@ test_methods (GDBusConnection *connection,
 
   /* Check that we get a timeout if the method handling is taking longer than timeout */
   error = NULL;
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "Sleep",
-                                            g_variant_new ("(i)", 500 /* msec */),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            100 /* msec */,
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "Sleep",
+                                   g_variant_new ("(i)", 500 /* msec */),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   100 /* msec */,
+                                   NULL,
+                                   &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
   g_assert (!g_dbus_error_is_remote_error (error));
   g_assert (result == NULL);
@@ -97,13 +97,13 @@ test_methods (GDBusConnection *connection,
   g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, -1);
 
   /* the default timeout is 25000 msec so this should work */
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "Sleep",
-                                            g_variant_new ("(i)", 500 /* msec */),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1, /* use proxy default (e.g. -1 -> e.g. 25000 msec) */
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "Sleep",
+                                   g_variant_new ("(i)", 500 /* msec */),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1, /* use proxy default (e.g. -1 -> e.g. 25000 msec) */
+                                   NULL,
+                                   &error);
   g_assert_no_error (error);
   g_assert (result != NULL);
   g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
@@ -112,13 +112,13 @@ test_methods (GDBusConnection *connection,
   /* now set the proxy-default timeout to 250 msec and try the 500 msec call - this should FAIL */
   g_dbus_proxy_set_default_timeout (proxy, 250);
   g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, 250);
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "Sleep",
-                                            g_variant_new ("(i)", 500 /* msec */),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1, /* use proxy default (e.g. 250 msec) */
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "Sleep",
+                                   g_variant_new ("(i)", 500 /* msec */),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1, /* use proxy default (e.g. 250 msec) */
+                                   NULL,
+                                   &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
   g_assert (!g_dbus_error_is_remote_error (error));
   g_assert (result == NULL);
@@ -150,13 +150,11 @@ test_properties (GDBusConnection *connection,
    *
    * No need to test all properties - GVariant has already been tested
    */
-  variant = g_dbus_proxy_get_cached_property (proxy, "y", &error);
-  g_assert_no_error (error);
+  variant = g_dbus_proxy_get_cached_property (proxy, "y");
   g_assert (variant != NULL);
   g_assert_cmpint (g_variant_get_byte (variant), ==, 1);
   g_variant_unref (variant);
-  variant = g_dbus_proxy_get_cached_property (proxy, "o", &error);
-  g_assert_no_error (error);
+  variant = g_dbus_proxy_get_cached_property (proxy, "o");
   g_assert (variant != NULL);
   g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "/some/path");
   g_variant_unref (variant);
@@ -166,25 +164,70 @@ test_properties (GDBusConnection *connection,
    * is received. Also check that the cache is updated.
    */
   variant2 = g_variant_new_byte (42);
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "FrobSetProperty",
-                                            g_variant_new ("(sv)",
-                                                           "y",
-                                                           variant2),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1,
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "FrobSetProperty",
+                                   g_variant_new ("(sv)",
+                                                  "y",
+                                                  variant2),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1,
+                                   NULL,
+                                   &error);
   g_assert_no_error (error);
   g_assert (result != NULL);
   g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
   g_variant_unref (result);
   _g_assert_signal_received (proxy, "g-properties-changed");
-  variant = g_dbus_proxy_get_cached_property (proxy, "y", &error);
-  g_assert_no_error (error);
+  variant = g_dbus_proxy_get_cached_property (proxy, "y");
   g_assert (variant != NULL);
   g_assert_cmpint (g_variant_get_byte (variant), ==, 42);
   g_variant_unref (variant);
+
+  g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (142));
+  variant = g_dbus_proxy_get_cached_property (proxy, "y");
+  g_assert (variant != NULL);
+  g_assert_cmpint (g_variant_get_byte (variant), ==, 142);
+  g_variant_unref (variant);
+
+  g_dbus_proxy_set_cached_property (proxy, "y", NULL);
+  variant = g_dbus_proxy_get_cached_property (proxy, "y");
+  g_assert (variant == NULL);
+
+  /* Check that the invalidation feature of the PropertiesChanged()
+   * signal works... First, check that we have a cached value of the
+   * property (from the initial GetAll() call)
+   */
+  variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated");
+  g_assert (variant != NULL);
+  g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "InitialValue");
+  g_variant_unref (variant);
+  /* now ask to invalidate the property - this causes a
+   *
+   *   PropertiesChanaged("com.example.Frob",
+   *                      {},
+   *                      ["PropertyThatWillBeInvalidated")
+   *
+   * signal to be emitted. This is received before the method reply
+   * for FrobInvalidateProperty *but* since the proxy was created in
+   * the same thread as we're doing this synchronous call, we'll get
+   * the method reply before...
+   */
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "FrobInvalidateProperty",
+                                   NULL,
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1,
+                                   NULL,
+                                   &error);
+  g_assert_no_error (error);
+  g_assert (result != NULL);
+  g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
+  g_variant_unref (result);
+  /* ... hence we wait for the g-properties-changed signal to be delivered */
+  _g_assert_signal_received (proxy, "g-properties-changed");
+  /* ... and now we finally, check that the cached value has been invalidated */
+  variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated");
+  g_assert (variant == NULL);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -222,9 +265,9 @@ test_proxy_signals_on_emit_signal_cb (GDBusProxy   *proxy,
   GVariant *result;
 
   error = NULL;
-  result = g_dbus_proxy_invoke_method_finish (proxy,
-                                              res,
-                                              &error);
+  result = g_dbus_proxy_call_finish (proxy,
+                                     res,
+                                     &error);
   g_assert_no_error (error);
   g_assert (result != NULL);
   g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
@@ -263,15 +306,15 @@ test_signals (GDBusConnection *connection,
                                         G_CALLBACK (test_proxy_signals_on_signal),
                                         s);
 
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "EmitSignal",
-                                            g_variant_new ("(so)",
-                                                           "Accept the next proposition you hear",
-                                                           "/some/path"),
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1,
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "EmitSignal",
+                                   g_variant_new ("(so)",
+                                                  "Accept the next proposition you hear",
+                                                  "/some/path"),
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1,
+                                   NULL,
+                                   &error);
   g_assert_no_error (error);
   g_assert (result != NULL);
   g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
@@ -296,16 +339,16 @@ test_signals (GDBusConnection *connection,
                                         "g-signal",
                                         G_CALLBACK (test_proxy_signals_on_signal),
                                         s);
-  g_dbus_proxy_invoke_method (proxy,
-                              "EmitSignal",
-                              g_variant_new ("(so)",
-                                             "You will make a great programmer",
-                                             "/some/other/path"),
-                              G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                              -1,
-                              NULL,
-                              (GAsyncReadyCallback) test_proxy_signals_on_emit_signal_cb,
-                              &data);
+  g_dbus_proxy_call (proxy,
+                     "EmitSignal",
+                     g_variant_new ("(so)",
+                                    "You will make a great programmer",
+                                    "/some/other/path"),
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1,
+                     NULL,
+                     (GAsyncReadyCallback) test_proxy_signals_on_emit_signal_cb,
+                     &data);
   g_main_loop_run (data.internal_loop);
   g_main_loop_unref (data.internal_loop);
   g_assert_cmpstr (s->str,
@@ -324,13 +367,13 @@ test_bogus_method_return (GDBusConnection *connection,
   GError *error = NULL;
   GVariant *result;
 
-  result = g_dbus_proxy_invoke_method_sync (proxy,
-                                            "PairReturn",
-                                            NULL,
-                                            G_DBUS_INVOKE_METHOD_FLAGS_NONE,
-                                            -1,
-                                            NULL,
-                                            &error);
+  result = g_dbus_proxy_call_sync (proxy,
+                                   "PairReturn",
+                                   NULL,
+                                   G_DBUS_CALL_FLAGS_NONE,
+                                   -1,
+                                   NULL,
+                                   &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
   g_assert (result == NULL);
 }
@@ -352,6 +395,7 @@ static const gchar *frob_dbus_interface_xml =
   "    <method name='Sleep'>"
   "      <arg type='i' name='timeout' direction='in'/>"
   "    </method>"
+  "    <property name='y' type='y' access='readwrite'/>"
   "  </interface>"
   "</node>";
 static GDBusInterfaceInfo *frob_dbus_interface_info;
@@ -367,6 +411,12 @@ on_proxy_appeared (GDBusConnection *connection,
   test_properties (connection, name, name_owner, proxy);
   test_signals (connection, name, name_owner, proxy);
 
+  /* This is obviously wrong but expected interface is not set so we don't fail... */
+  g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_string ("error_me_out!"));
+  g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42));
+  g_dbus_proxy_set_cached_property (proxy, "does-not-exist", g_variant_new_string ("something"));
+  g_dbus_proxy_set_cached_property (proxy, "does-not-exist", NULL);
+
   /* Now repeat the method tests, with an expected interface set */
   g_dbus_proxy_set_interface_info (proxy, frob_dbus_interface_info);
   test_methods (connection, name, name_owner, proxy);
@@ -376,6 +426,24 @@ on_proxy_appeared (GDBusConnection *connection,
    */
   test_bogus_method_return (connection, name, name_owner, proxy);
 
+  /* Also check that we complain if setting a cached property of the wrong type */
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+    {
+      g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_string ("error_me_out!"));
+    }
+  g_test_trap_assert_stderr ("*Trying to set property y of type s but according to the expected interface the type is y*");
+  g_test_trap_assert_failed();
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+    {
+      g_dbus_proxy_set_cached_property (proxy, "does-not-exist", g_variant_new_string ("something"));
+    }
+  g_test_trap_assert_stderr ("*Trying to lookup property does-not-exist which isn't in expected interface com.example.Frob*");
+  g_test_trap_assert_failed();
+
+  /* this should work, however (since the type is correct) */
+  g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42));
+
   g_main_loop_quit (loop);
 }
 
@@ -411,7 +479,7 @@ test_proxy (void)
                                   NULL);
 
   /* this is safe; testserver will exit once the bus goes away */
-  g_assert (g_spawn_command_line_async ("./gdbus-testserver.py", NULL));
+  g_assert (g_spawn_command_line_async (SRCDIR "/gdbus-testserver.py", NULL));
 
   g_main_loop_run (loop);