← Back to team overview

ayatana-commits team mailing list archive

[Branch ~dbusmenu-team/dbusmenu/trunk] Rev 62: Adding in the benchmarking tools for dbusmenu.

 

Merge authors:
  Aurélien Gâteau (agateau)
  Ted Gould (ted)
------------------------------------------------------------
revno: 62 [merge]
committer: Ted Gould <ted@xxxxxxxx>
branch nick: trunk
timestamp: Thu 2010-02-04 11:39:04 -0800
message:
  Adding in the benchmarking tools for dbusmenu.
added:
  tools/dbusmenu-bench
  tools/testapp/
  tools/testapp/CMakeLists.txt
  tools/testapp/Makefile.am
  tools/testapp/main.c
modified:
  .bzrignore
  configure.ac
  tools/Makefile.am


--
lp:dbusmenu
https://code.launchpad.net/~dbusmenu-team/dbusmenu/trunk

Your team ayatana-commits is subscribed to branch lp:dbusmenu.
To unsubscribe from this branch go to https://code.launchpad.net/~dbusmenu-team/dbusmenu/trunk/+edit-subscription.
=== modified file '.bzrignore'
--- .bzrignore	2009-12-21 21:08:03 +0000
+++ .bzrignore	2010-02-04 19:35:15 +0000
@@ -57,3 +57,4 @@
 tests/test-glib-objects
 tests/test-glib-objects-test
 tests/test-glib-objects.xml
+tools/testapp/dbusmenu-testapp

=== modified file 'configure.ac'
--- configure.ac	2010-01-12 14:42:30 +0000
+++ configure.ac	2010-02-04 19:34:58 +0000
@@ -105,6 +105,7 @@
 libdbusmenu-gtk/Makefile
 libdbusmenu-gtk/dbusmenu-gtk.pc
 tools/Makefile
+tools/testapp/Makefile
 tests/Makefile
 ])
 

=== modified file 'tools/Makefile.am'
--- tools/Makefile.am	2009-10-05 14:12:45 +0000
+++ tools/Makefile.am	2010-02-04 19:34:58 +0000
@@ -1,6 +1,10 @@
 
+SUBDIRS = testapp
+
 libexec_PROGRAMS = dbusmenu-dumper
 
+libexec_SCRIPTS = dbusmenu-bench
+
 dbusmenu_dumper_SOURCES = \
 	dbusmenu-dumper.c
 
@@ -12,3 +16,4 @@
 	../libdbusmenu-glib/libdbusmenu-glib.la \
 	$(DBUSMENUGLIB_LIBS)
 
+EXTRA_DIST = dbusmenu-bench

=== added file 'tools/dbusmenu-bench'
--- tools/dbusmenu-bench	1970-01-01 00:00:00 +0000
+++ tools/dbusmenu-bench	2010-02-04 19:36:16 +0000
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+A library to communicate a menu object set accross DBus and
+track updates and maintain consistency.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+    Aurélien Gâteau <aurelien.gateau@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the 
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, 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 applicable version of the GNU Lesser General Public 
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public 
+License version 3 and version 2.1 along with this program.  If not, see 
+<http://www.gnu.org/licenses/>
+"""
+import time
+import sys
+from optparse import OptionParser
+from xml.etree import ElementTree as ET
+
+import dbus
+
+DBUS_INTERFACE = "org.ayatana.dbusmenu"
+DBUS_SERVICE = "org.dbusmenu.test"
+DBUS_PATH = "/MenuBar"
+
+
+class Chrono(object):
+    def __init__(self):
+        self._time = 0
+        self.restart()
+
+    def restart(self):
+        new_time = time.time()
+        delta = new_time - self._time
+        self._time = new_time
+        return delta
+
+    def elapsed(self):
+        return time.time() - self._time
+
+
+def dump_properties(properties, prepend=""):
+    for key, value in properties.items():
+        print "%s- %s: %s" % (prepend, key, value)
+
+
+def run_test_sequence(menu, dump=False):
+    """
+    Runs the test sequence and returns a dict of method_name: seconds
+    """
+    property_names = ["type", "label", "enabled", "icon-name"]
+    times = dict()
+    chrono = Chrono()
+    revision, layout = menu.GetLayout(dbus.Int32(0))
+    times["GetLayout"] = chrono.elapsed()
+    if dump:
+        print "revision:", revision
+        print "layout:"
+        print layout
+
+    # Get ids
+    tree = ET.fromstring(layout)
+    root_id = int(tree.attrib["id"])
+    child_element = tree.find("menu")
+    assert child_element is not None
+    child_id = int(child_element.attrib["id"])
+
+    chrono.restart()
+    children = menu.GetChildren(dbus.Int32(root_id), property_names)
+    times["GetChildren"] = chrono.elapsed()
+    if dump:
+        print "children:"
+        for child in children:
+            id, properties = child
+            print "- %d:" % id
+            dump_properties(properties, prepend=" ")
+
+    chrono.restart()
+    properties = menu.GetProperties(dbus.Int32(child_id), property_names)
+    times["GetProperties"] = chrono.elapsed()
+    if dump:
+        print "properties:"
+        dump_properties(properties)
+
+    return times
+
+
+def main():
+    parser = OptionParser(usage = "%prog [options]")
+
+    parser.add_option("-c", "--count", dest="count", type=int, default=1,
+                      help="repeat calls COUNT times", metavar="COUNT")
+    parser.add_option("-d", "--dump", dest="dump", action="store_true", default=False,
+                      help="dump call output to stdout")
+
+    (options, args) = parser.parse_args()
+
+    bus = dbus.SessionBus()
+    proxy = bus.get_object(DBUS_SERVICE, DBUS_PATH)
+    menu = dbus.Interface(proxy, dbus_interface=DBUS_INTERFACE)
+
+    if options.dump:
+        run_test_sequence(menu, dump=True)
+        return
+
+    cumulated_timings = dict()
+    for x in range(options.count):
+        timings = run_test_sequence(menu)
+        for name, timing in timings.items():
+            cumulated_timings[name] = cumulated_timings.get(name, 0) + timing
+
+    for name, timing in cumulated_timings.items():
+        print name, timing / options.count
+
+    return 0
+
+
+if __name__=="__main__":
+    sys.exit(main())
+# vi: ts=4 sw=4 et tw=0

=== added directory 'tools/testapp'
=== added file 'tools/testapp/CMakeLists.txt'
--- tools/testapp/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tools/testapp/CMakeLists.txt	2010-02-04 19:22:29 +0000
@@ -0,0 +1,29 @@
+find_package(PkgConfig REQUIRED)
+
+pkg_check_modules(DBUSMENUGLIB REQUIRED dbusmenu-glib)
+pkg_check_modules(GLIB REQUIRED glib-2.0)
+pkg_check_modules(JSONGLIB REQUIRED json-glib-1.0)
+
+set(glibapp_SRCS
+    main.c
+    )
+
+include_directories(
+    ${DBUSMENUGLIB_INCLUDE_DIRS}
+    ${GLIB_INCLUDE_DIRS}
+    ${JSONGLIB_INCLUDE_DIRS}
+    )
+
+link_directories(
+    ${DBUSMENUGLIB_LIBRARY_DIRS}
+    ${GLIB_LIBRARY_DIRS}
+    ${JSONGLIB_LIBRARY_DIRS}
+    )
+
+add_executable(dbusmenubench-glibapp ${glibapp_SRCS})
+
+target_link_libraries(dbusmenubench-glibapp
+    ${DBUSMENUGLIB_LIBRARIES}
+    ${GLIB_LIBARIES}
+    ${JSONGLIB_LIBRARIES}
+    )

=== added file 'tools/testapp/Makefile.am'
--- tools/testapp/Makefile.am	1970-01-01 00:00:00 +0000
+++ tools/testapp/Makefile.am	2010-02-04 19:34:58 +0000
@@ -0,0 +1,17 @@
+
+libexec_PROGRAMS = dbusmenu-testapp
+
+dbusmenu_testapp_SOURCES = \
+	main.c
+
+dbusmenu_testapp_CFLAGS = \
+	-I $(srcdir)/../.. \
+	$(DBUSMENUTESTS_CFLAGS) \
+	$(DBUSMENUGLIB_CFLAGS) \
+	-Wall -Werror
+
+dbusmenu_testapp_LDADD = \
+	$(builddir)/../../libdbusmenu-glib/libdbusmenu-glib.la \
+	$(builddir)/../../libdbusmenu-gtk/libdbusmenu-gtk.la \
+	$(DBUSMENUGTK_LIBS) \
+	$(DBUSMENUTESTS_LIBS)

=== added file 'tools/testapp/main.c'
--- tools/testapp/main.c	1970-01-01 00:00:00 +0000
+++ tools/testapp/main.c	2010-02-04 19:22:29 +0000
@@ -0,0 +1,153 @@
+/*
+A library to communicate a menu object set accross DBus and
+track updates and maintain consistency.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+    Aurélien Gâteau <aurelien.gateau@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the 
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, 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 applicable version of the GNU Lesser General Public 
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public 
+License version 3 and version 2.1 along with this program.  If not, see 
+<http://www.gnu.org/licenses/>
+*/
+#include <glib.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <json-glib/json-glib.h>
+
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#define USAGE "dbusmenubench-glibapp <path/to/menu.json>"
+
+static void
+set_props (DbusmenuMenuitem * mi, JsonObject * node)
+{
+	if (node == NULL) return;
+
+	GList * members = NULL;
+	for (members = json_object_get_members(node); members != NULL; members = g_list_next(members)) {
+		const gchar * member = members->data;
+
+		if (!g_strcmp0(member, "id")) { continue; }
+		if (!g_strcmp0(member, "submenu")) { continue; }
+
+		JsonNode * lnode = json_object_get_member(node, member);
+		if (JSON_NODE_TYPE(lnode) != JSON_NODE_VALUE) { continue; }
+
+		dbusmenu_menuitem_property_set(mi, member, json_node_get_string(lnode));
+	}
+
+	return;
+}
+
+static DbusmenuMenuitem *
+layout2menuitem (JsonNode * inlayout)
+{
+	if (inlayout == NULL) return NULL;
+	if (JSON_NODE_TYPE(inlayout) != JSON_NODE_OBJECT) return NULL;
+
+	JsonObject * layout = json_node_get_object(inlayout);
+
+	DbusmenuMenuitem * local = NULL;
+	if (json_object_has_member(layout, "id")) {
+		JsonNode * node = json_object_get_member(layout, "id");
+		g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_VALUE, NULL);
+		local = dbusmenu_menuitem_new_with_id(json_node_get_int(node));
+	} else {
+		local = dbusmenu_menuitem_new();
+	}
+
+	set_props(local, layout);
+
+	if (json_object_has_member(layout, "submenu")) {
+		JsonNode * node = json_object_get_member(layout, "submenu");
+		g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_ARRAY, local);
+		JsonArray * array = json_node_get_array(node);
+		guint count;
+		for (count = 0; count < json_array_get_length(array); count++) {
+			DbusmenuMenuitem * child = layout2menuitem(json_array_get_element(array, count));
+			if (child != NULL) {
+				dbusmenu_menuitem_child_append(local, child);
+			}
+		}
+	}
+
+	/* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
+	return local;
+}
+
+void init_menu(DbusmenuMenuitem *root, const char *filename)
+{
+	JsonParser * parser = json_parser_new();
+	GError * error = NULL;
+	if (!json_parser_load_from_file(parser, filename, &error)) {
+		g_debug("Failed parsing file %s because: %s", filename, error->message);
+		return;
+	}
+	JsonNode * root_node = json_parser_get_root(parser);
+	if (JSON_NODE_TYPE(root_node) != JSON_NODE_ARRAY) {
+		g_debug("Root node is not an array, fail.  It's an: %s", json_node_type_name(root_node));
+		return;
+	}
+
+	JsonArray * root_array = json_node_get_array(root_node);
+	int pos;
+	int count = json_array_get_length(root_array);
+	for (pos=0; pos < count; ++pos) {
+		DbusmenuMenuitem *child = layout2menuitem(json_array_get_element(root_array, pos));
+		dbusmenu_menuitem_child_append(root, child);
+	}
+}
+
+int main (int argc, char ** argv)
+{
+	g_type_init();
+
+	if (argc != 2) {
+		g_warning(USAGE);
+		return 1;
+	}
+	const char *filename = argv[1];
+
+	GError * error = NULL;
+	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+	DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+	guint nameret = 0;
+
+	if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
+		g_error("Unable to call to request name");
+		return 1;
+	}
+
+	if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		g_error("Unable to get name");
+		return 1;
+	}
+
+	DbusmenuServer *server = dbusmenu_server_new("/MenuBar");
+	DbusmenuMenuitem *root = dbusmenu_menuitem_new_with_id(0);
+	init_menu(root, filename);
+	dbusmenu_server_set_root(server, root);
+
+	g_main_loop_run(g_main_loop_new(NULL, FALSE));
+
+	return 0;
+}