From ec6f4883dc6fdffbd47e652e8cd4857c7d201adc 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 +++++++++++++++++++++++++++++++++++++++++++ tests/notification-fixture.h | 54 ++------------- 2 files changed, 162 insertions(+), 47 deletions(-) create mode 100644 tests/libdbusmock-fixture.h (limited to 'tests') diff --git a/tests/libdbusmock-fixture.h b/tests/libdbusmock-fixture.h new file mode 100644 index 0000000..14eab8f --- /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()) + g_main_iteration(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; + } +}; + diff --git a/tests/notification-fixture.h b/tests/notification-fixture.h index b6b446b..54e840b 100644 --- a/tests/notification-fixture.h +++ b/tests/notification-fixture.h @@ -19,7 +19,7 @@ #pragma once -#include "glib-fixture.h" +#include "libdbusmock-fixture.h" #include #include @@ -38,24 +38,18 @@ **** ***/ -//using namespace ayatana::indicator::datetime; - -class NotificationFixture: public GlibFixture +class NotificationFixture: public LibdbusmockFixture { private: - typedef GlibFixture super; + typedef LibdbusmockFixture super; + +protected: static constexpr char const * NOTIFY_BUSNAME {"org.freedesktop.Notifications"}; static constexpr char const * NOTIFY_INTERFACE {"org.freedesktop.Notifications"}; static constexpr char const * NOTIFY_PATH {"/org/freedesktop/Notifications"}; - //namespace uin = ayatana::indicator::notifications; - - //using namespace ayatana::indicator::datetime; - -protected: - static constexpr char const * HAPTIC_METHOD_VIBRATE_PATTERN {"VibratePattern"}; static constexpr int SCREEN_COOKIE {8675309}; @@ -90,9 +84,7 @@ protected: ayatana::indicator::datetime::Appointment appt; ayatana::indicator::datetime::Appointment ualarm; - GDBusConnection * system_bus = nullptr; - GDBusConnection * session_bus = nullptr; - DbusTestService * service = nullptr; + DbusTestDbusMock * as_mock = nullptr; DbusTestDbusMock * notify_mock = nullptr; DbusTestDbusMock * powerd_mock = nullptr; @@ -131,8 +123,6 @@ protected: ualarm.end = tomorrow; ualarm.alarms.push_back(ayatana::indicator::datetime::Alarm{"It's Tomorrow!", "", appt.begin}); - service = dbus_test_service_new(nullptr); - /// /// Add the AccountsService mock /// @@ -308,23 +298,7 @@ protected: g_assert_no_error (error); dbus_test_service_add_task(service, DBUS_TEST_TASK(haptic_mock)); - - // 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); + startDbusMock(); } void TearDown() override @@ -334,20 +308,6 @@ protected: g_clear_object(&powerd_mock); g_clear_object(¬ify_mock); g_clear_object(&as_mock); - 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()) - g_main_iteration(true); - cleartry++; - } super::TearDown(); } -- cgit v1.2.3