From d1bbce7d59303905b5ee5636ff2ad84191e70068 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Feb 2016 14:48:24 -0600 Subject: add a DBusMock test Fixture with helper functions to wait for arbitrary bus method calls --- tests/libdbusmock-fixture.h | 155 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 tests/libdbusmock-fixture.h (limited to 'tests/libdbusmock-fixture.h') diff --git a/tests/libdbusmock-fixture.h b/tests/libdbusmock-fixture.h new file mode 100644 index 0000000..ef42fbf --- /dev/null +++ b/tests/libdbusmock-fixture.h @@ -0,0 +1,155 @@ +/* + * Copyright 2014-2016 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + */ + +#pragma once + +#include "glib-fixture.h" + +#include + +/*** +**** +***/ + +class LibdbusmockFixture: public GlibFixture +{ +private: + + typedef GlibFixture super; + +protected: + + GDBusConnection * system_bus {}; + GDBusConnection * session_bus {}; + DbusTestService * service {}; + + void SetUp() override + { + + super::SetUp(); + + service = dbus_test_service_new(nullptr); + } + + void startDbusMock() + { + // start 'em up. + // make the system bus work off the mock bus too, since that's + // where the upower and screen are on the system bus... + + dbus_test_service_start_tasks(service); + g_setenv("DBUS_SYSTEM_BUS_ADDRESS", g_getenv("DBUS_SESSION_BUS_ADDRESS"), TRUE); + + session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); + ASSERT_NE(nullptr, session_bus); + g_dbus_connection_set_exit_on_close(session_bus, false); + g_object_add_weak_pointer(G_OBJECT(session_bus), (gpointer *)&session_bus); + + system_bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr); + ASSERT_NE(nullptr, system_bus); + g_dbus_connection_set_exit_on_close(system_bus, FALSE); + g_object_add_weak_pointer(G_OBJECT(system_bus), (gpointer *)&system_bus); + } + + void TearDown() override + { + g_clear_object(&service); + g_object_unref(session_bus); + g_object_unref(system_bus); + + // wait a little while for the scaffolding to shut down, + // but don't block on it forever... + unsigned int cleartry = 0; + while (((system_bus != nullptr) || (session_bus != nullptr)) && (cleartry < 50)) + { + g_usleep(100000); + while (g_main_pending(nullptr)) + g_main_iteration(nullptr, true); + cleartry++; + } + + super::TearDown(); + } + + bool wait_for_method_call(DbusTestDbusMock* mock, + DbusTestDbusMockObject* obj, + const gchar* method, + GVariant* params=nullptr, + guint timeout_msec=100) + { + if (params != nullptr) + g_variant_ref_sink(params); + + auto test_function = [mock, obj, method, params]() { + GError* error {}; + const auto called = dbus_test_dbus_mock_object_check_method_call(mock, + obj, + method, + params, + &error); + if (error != nullptr) { + g_critical("Error looking for method call '%s': %s", method, error->message); + g_clear_error(&error); + } + + return called; + }; + + const auto ret = wait_for(test_function, timeout_msec); + g_clear_pointer(¶ms, g_variant_unref); + return ret; + } + + void EXPECT_METHOD_CALLED_EVENTUALLY(DbusTestDbusMock* mock, + DbusTestDbusMockObject* obj, + const gchar* method, + GVariant* params=nullptr, + guint timeout_msec=1000) + { + EXPECT_TRUE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method; + } + + void EXPECT_METHOD_NOT_CALLED_EVENTUALLY(DbusTestDbusMock* mock, + DbusTestDbusMockObject* obj, + const gchar* method, + GVariant* params=nullptr, + guint timeout_msec=1000) + { + EXPECT_FALSE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method; + } + + void ASSERT_METHOD_CALLED_EVENTUALLY(DbusTestDbusMock* mock, + DbusTestDbusMockObject* obj, + const gchar* method, + GVariant* params=nullptr, + guint timeout_msec=1000) + { + ASSERT_TRUE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method; + } + + void ASSERT_METHOD_NOT_CALLED_EVENTUALLY(DbusTestDbusMock* mock, + DbusTestDbusMockObject* obj, + const gchar* method, + GVariant* params=nullptr, + guint timeout_msec=1000) + { + ASSERT_FALSE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method; + } +}; + -- cgit v1.2.3