1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#!/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@canonical.com>
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 itertools
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"
PROBE_GET_LAYOUT = "GetLayout"
PROBE_GET_PROPERTIES = "GetProperties"
PROBE_GET_CHILDREN = "GetChildren"
PROBES = PROBE_GET_LAYOUT, PROBE_GET_PROPERTIES, PROBE_GET_CHILDREN
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 create_timing_dict():
return dict(zip(PROBES, itertools.repeat(0)))
def print_probe(prefix, name, value, timestamp):
value = int(value * 1000000)
print "%(prefix)s.%(name)s:%(value)d@%(timestamp)d" % locals()
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 = create_timing_dict()
min_timings = create_timing_dict()
max_timings = create_timing_dict()
for x in range(options.count):
timings = run_test_sequence(menu)
for name, timing in timings.items():
cumulated_timings[name] += timing
if min_timings[name] == 0 or min_timings[name] > timing:
min_timings[name] = timing
if max_timings[name] < timing:
max_timings[name] = timing
timestamp = int(time.time())
for name, timing in cumulated_timings.items():
print_probe("average", name, timing / options.count, timestamp)
for name, timing in min_timings.items():
print_probe("min", name, timing, timestamp)
for name, timing in max_timings.items():
print_probe("max", name, timing, timestamp)
return 0
if __name__=="__main__":
sys.exit(main())
# vi: ts=4 sw=4 et tw=0
|