From 0b63ef0ea8625d713b9f726c8d664fdbeb37481d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 6 Nov 2012 20:14:53 -0600 Subject: Reimplement test-service s.t. we actually test activating the service via dbus. Drop unneeded Xorg baggage. --- tests/gtest-dbus-helper.h | 418 ---------------------------------------------- 1 file changed, 418 deletions(-) delete mode 100644 tests/gtest-dbus-helper.h (limited to 'tests/gtest-dbus-helper.h') diff --git a/tests/gtest-dbus-helper.h b/tests/gtest-dbus-helper.h deleted file mode 100644 index c893606..0000000 --- a/tests/gtest-dbus-helper.h +++ /dev/null @@ -1,418 +0,0 @@ -/* -Copyright 2012 Canonical Ltd. - -Authors: - Charles Kerr - -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 . -*/ - -#ifndef INDICATOR_SERVICE_TEST_H -#define INDICATOR_SERVICE_TEST_H - -#include -#include -#include -#include - -#include -#include -#include -#include - -/*** -**** -***/ - -/** - * Convenience class for looking at a DbusmenuClient's items for testing - * - * Examples: - * - * // confirm that there are N menuitems of type T - * TEST_EQ (helper.count_type(T), N); - * - * // confirm that there are N visible menuitems - * TEST_EQ (helper.count_property_bool(DBUSMENU_MENUITEM_PROP_VISIBLE,true), N); - * - * // get a sorted list of all the menuitems of type T - * std::vector items = helper.find_type(T); - */ -class DbusmenuClientHelper -{ - public: - - DbusmenuClientHelper (DbusmenuClient * client_): client(client_) { - g_object_ref (G_OBJECT(client)); - } - ~DbusmenuClientHelper() { - g_object_unref(G_OBJECT(client)); - client = NULL; - } - - private: - - static void foreach_accumulate_func (DbusmenuMenuitem * mi, gpointer gset) { - static_cast*>(gset)->push_back (mi); - } - - public: - - std::vector - get_all_menuitems () const - { - std::vector items; - - DbusmenuMenuitem * root = dbusmenu_client_get_root (client); - if (root != NULL) - dbusmenu_menuitem_foreach (root, foreach_accumulate_func, &items); - - return items; - } - - private: - - template class PropertyPredicate: - public std::unary_function { - protected: - const std::string _key; - const value_type _value; - virtual value_type get_value(DbusmenuMenuitem * mi) const = 0; - public: - PropertyPredicate (const char * propertyName, value_type propertyValue): - _key(propertyName), _value(propertyValue) { } - bool operator()(const DbusmenuMenuitem* cmi) const { - // FIXME: remove const_cast after the dbusmenu_menuitem_propperty_get*() functions are constified - DbusmenuMenuitem * mi = const_cast(cmi); - return dbusmenu_menuitem_property_exist (mi, _key.c_str()) && (_value == get_value(mi)); - } - }; - - class StringPropertyPredicate: public PropertyPredicate { - protected: - virtual std::string get_value (DbusmenuMenuitem * mi) const { - return dbusmenu_menuitem_property_get(mi, _key.c_str()); - } - public: - StringPropertyPredicate (const char * propName, const char * propValue): - PropertyPredicate (propName, propValue) {} - }; - - class IntPropertyPredicate: public PropertyPredicate { - protected: - virtual int get_value (DbusmenuMenuitem * mi) const { - return dbusmenu_menuitem_property_get_int(mi, _key.c_str()); - } - public: - IntPropertyPredicate (const char * propName, int propValue): - PropertyPredicate (propName, propValue) {} - }; - - class BoolPropertyPredicate: public PropertyPredicate { - protected: - virtual bool get_value (DbusmenuMenuitem * mi) const { - return dbusmenu_menuitem_property_get_bool(mi, _key.c_str()); - } - public: - BoolPropertyPredicate (const char * propName, bool propValue): - PropertyPredicate (propName, propValue) {} - }; - - public: - - typedef std::vector menuitems_t; - - void - match_property (menuitems_t& items, const char * key, const char * value) const - { - const StringPropertyPredicate pred (key, value); - items.erase (std::remove_if (items.begin(), items.end(), std::not1(pred)), items.end()); - } - - void - match_property_int (menuitems_t& items, const char * key, int value) const - { - const IntPropertyPredicate pred (key, value); - items.erase (std::remove_if (items.begin(), items.end(), std::not1(pred)), items.end()); - } - - void - match_property_bool (menuitems_t& items, const char * key, bool value) const - { - const BoolPropertyPredicate pred (key, value); - items.erase (std::remove_if (items.begin(), items.end(), std::not1(pred)), items.end()); - } - - menuitems_t find_property (const char * prop_name, const char * prop_value) const - { - menuitems_t items; - g_return_val_if_fail (prop_name!=NULL, items); - g_return_val_if_fail (prop_value!=NULL, items); - - items = get_all_menuitems (); - match_property (items, prop_name, prop_value); - return items; - } - - menuitems_t find_property_int (const char * prop_name, int prop_value) const - { - std::vector items; - g_return_val_if_fail (prop_name!=NULL, items); - - items = get_all_menuitems (); - match_property_int (items, prop_name, prop_value); - return items; - } - - menuitems_t find_property_bool (const char * prop_name, bool prop_value) const - { - std::vector items; - g_return_val_if_fail (prop_name!=NULL, items); - - items = get_all_menuitems (); - match_property_bool (items, prop_name, prop_value); - return items; - } - - menuitems_t find_type (const char * type) const - { - return find_property (DBUSMENU_MENUITEM_PROP_TYPE, type); - } - - int count_property (const char * propName, const char * propValue) const - { - return find_property (propName, propValue).size(); - } - - int count_type (const char * type) const - { - return count_property (DBUSMENU_MENUITEM_PROP_TYPE, type); - } - - int count_property_int (const char * propName, int propValue) const - { - return find_property_int (propName, propValue).size(); - } - - int count_property_bool (const char * propName, bool propValue) const - { - return find_property_bool (propName, propValue).size(); - } - - private: - - DbusmenuClient * client; -}; - -/** - * Fixture class for using Google Test on an indicator-service's - * com.canonical.dbusmenu interface. - * - * The SetUp() function starts the service up, waits for it to - * be visible on the bus, then creates a DbusmenuClient and waits - * for its layout-changed signal. This way the test function - * is reached after the menu is available and populated. - * - * TearDown() cleans up the DBus scaffolding and stops the service. - */ -class IndicatorServiceTest : public ::testing::Test -{ - public: - - IndicatorServiceTest(const char * service_name_, - const char * menu_object_path_, - const char * executable_): - menu_client(0), - menu_helper(0), - test_service(0), - indicator_service_proxy(0), - handler_id(0), - executable(executable_), - service_name(service_name_), - menu_object_path(menu_object_path_) - { - // glib one-time init stuff - g_type_init(); - g_assert (g_thread_supported()); - mainloop = g_main_loop_new (NULL, FALSE); - } - - private: - - static void - on_layout_updated_static (DbusmenuClient * client, IndicatorServiceTest * self) - { - g_debug ("LAYOUT UPDATED"); - self->on_layout_updated (client); - } - void - on_layout_updated (DbusmenuClient * client) - { - ASSERT_EQ (client, menu_client); - ASSERT_NE (handler_id, 0); - ASSERT_TRUE (g_signal_handler_is_connected (client, handler_id)); - - // stop listening for this event - g_signal_handler_disconnect (client, handler_id); - handler_id = 0; - - ready(); - } - - private: - - static gboolean - on_timeout_static (gpointer self) - { - static_cast(self)->on_timeout(); - return false; - } - void - on_timeout() - { - ASSERT_NE (handler_id, 0ul); - g_source_remove (handler_id); - handler_id = 0; - ready(); - } - - protected: - - virtual void - SetUp() - { - ASSERT_EQ (NULL, test_service); - ASSERT_EQ (NULL, menu_helper); - ASSERT_EQ (NULL, indicator_service_proxy); - - test_service = dbus_test_service_new (NULL); - - // Start the executable and wait until it shows up on the bus. - // Unset the NO_WATCHERS env var to ensure that the service - // will shut down when there are no watchers... otherwise - // this task will never finish - g_unsetenv("INDICATOR_ALLOW_NO_WATCHERS"); - DbusTestProcess * indicator_service_task = dbus_test_process_new (executable.c_str()); - dbus_test_service_add_task (test_service, DBUS_TEST_TASK(indicator_service_task)); - g_object_unref (G_OBJECT(indicator_service_task)); - - // create a menu task that waits for our service before it runs - DbusTestTask * wait_task = dbus_test_task_new (); - dbus_test_task_set_wait_for (wait_task, service_name.c_str()); - dbus_test_service_add_task (test_service, wait_task); - g_object_unref (G_OBJECT(wait_task)); - - g_debug ("starting tasks"); - dbus_test_service_start_tasks(test_service); - - // at this point the indicator service is running, let's Watch it - // to ensure it stays alive for the duration of the test - GError * error = NULL; - GDBusConnection * bus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - indicator_service_proxy = g_dbus_proxy_new_sync (bus_connection, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - service_name.c_str(), - "/org/ayatana/indicator/service", - "org.ayatana.indicator.service", - NULL, - &error); - GVariant * result = g_dbus_proxy_call_sync (indicator_service_proxy, "Watch", - NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, NULL, &error); - guint a, b; - g_variant_get (result, "(uu)", &a, &b); - g_debug ("Sending 'Watch' to proxy %p yielded %u %u", indicator_service_proxy, a, b); - g_variant_unref (result); - EXPECT_EQ(NULL, error); - if (error != NULL) { - g_message ("%s Unable to Watch indicator-service : %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - g_object_unref (G_OBJECT(bus_connection)); - - menu_client = dbusmenu_client_new (service_name.c_str(), menu_object_path.c_str()); - menu_helper = new DbusmenuClientHelper (menu_client); - - // wait for a "layout-updated" signal before we let SetUp finish - wait_for_layout_update(); - } - - virtual void - TearDown() - { - ASSERT_EQ (handler_id, 0); - - // tear down the mainloop - ASSERT_TRUE (mainloop != NULL); - g_main_loop_unref (mainloop); - mainloop = NULL; - - // tear down the menu client - if (menu_helper != NULL) { - delete menu_helper; - menu_helper = NULL; - } - if (menu_client != NULL) { - g_object_unref(G_OBJECT(menu_client)); - menu_client = NULL; - } - - // tear down the indicator proxy - EXPECT_TRUE (G_IS_DBUS_PROXY(indicator_service_proxy)); - g_object_unref (G_OBJECT(indicator_service_proxy)); - indicator_service_proxy = NULL; - } - - void wait_for_layout_update() - { - ASSERT_EQ (handler_id, 0ul); - handler_id = g_signal_connect (menu_client, - DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, - G_CALLBACK(on_layout_updated_static), - this); - g_debug ("waiting for layout update..."); - g_main_loop_run (mainloop); - } - - void wait_seconds (int seconds) - { - ASSERT_EQ (handler_id, 0ul); - handler_id = g_timeout_add_seconds (seconds, on_timeout_static, this); - g_debug ("waiting %d seconds...", seconds); - g_main_loop_run (mainloop); - } - - protected: - - DbusmenuClient * menu_client; - DbusmenuClientHelper * menu_helper; - - private: - - void ready() - { - g_debug("done waiting"); - g_main_loop_quit (mainloop); - } - - GMainLoop * mainloop; - DbusTestService * test_service; - GDBusProxy * indicator_service_proxy; - gulong handler_id; - const std::string executable; - const std::string service_name; - const std::string menu_object_path; -}; - -#endif // #ifndef INDICATOR_SERVICE_TEST_H -- cgit v1.2.3