Merge lp:~lifeless/ubuntu/lucid/glib2.0/subunit into lp:ubuntu/lucid/glib2.0

Proposed by Robert Collins
Status: Rejected
Rejected by: James Westby
Proposed branch: lp:~lifeless/ubuntu/lucid/glib2.0/subunit
Merge into: lp:ubuntu/lucid/glib2.0
Diff against target: 288 lines (+256/-1)
4 files modified
debian/changelog (+6/-0)
debian/control (+2/-1)
debian/patches/80-gtester-subunit.patch (+247/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~lifeless/ubuntu/lucid/glib2.0/subunit
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+20879@code.launchpad.net

Description of the change

This adds a patch approved upstream but pending a release, for use in the dx team test suites.

To post a comment you must log in.
48. By Robert Collins

Adjust package recommends.

Revision history for this message
James Westby (james-w) wrote :

glib2.0 is not going to be under active development going forward,
so seb128 said he isn't going to invest the time in merging this.

Thanks,

James

Revision history for this message
Robert Collins (lifeless) wrote :

So where should people put improvements to the gnome testing
infrastructure now ?

Revision history for this message
James Westby (james-w) wrote :

On Wed, 04 Aug 2010 00:18:45 -0000, Robert Collins <email address hidden> wrote:
> So where should people put improvements to the gnome testing
> infrastructure now ?

Maybe I misunderstood the comment, so I suggest you contact seb to
discuss it with him.

<seb128> james_w, can you delete the glib2.0 one on
http://qa.ubuntu.com/reports/sponsoring/index.html as well?
<seb128> it's deprecated

Thanks,

James

Unmerged revisions

48. By Robert Collins

Adjust package recommends.

47. By Robert Collins

Add subunit support to gtester-report.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2010-02-22 15:00:46 +0000
3+++ debian/changelog 2010-03-08 08:18:33 +0000
4@@ -1,3 +1,9 @@
5+glib2.0 (2.23.4-1ubuntu2) lucid; urgency=low
6+
7+ * Add subunit support to gtester-report.
8+
9+ -- Robert Collins <robert@canonical.com> Mon, 08 Mar 2010 15:58:19 +1100
10+
11 glib2.0 (2.23.4-1ubuntu1) lucid; urgency=low
12
13 * Resync on Debian
14
15=== modified file 'debian/control'
16--- debian/control 2010-02-22 15:00:46 +0000
17+++ debian/control 2010-03-08 08:18:33 +0000
18@@ -66,7 +66,8 @@
19 pkg-config (>= 0.14.0),
20 zlib1g-dev
21 Recommends: python
22-Suggests: libglib2.0-doc
23+Suggests: libglib2.0-doc,
24+ python-subunit
25 Replaces: libglib1.3-dev
26 Conflicts: libglib1.3-dev
27 Description: Development files for the GLib library
28
29=== added file 'debian/patches/80-gtester-subunit.patch'
30--- debian/patches/80-gtester-subunit.patch 1970-01-01 00:00:00 +0000
31+++ debian/patches/80-gtester-subunit.patch 2010-03-08 08:18:33 +0000
32@@ -0,0 +1,247 @@
33+# Upstream: https://bugzilla.gnome.org/show_bug.cgi?id=611869
34+# Description: adds subunit support to gtester-report
35+=== modified file 'a/glib/gtester-report'
36+--- a/glib/gtester-report 2009-12-19 00:57:03 +0000
37++++ b/glib/gtester-report 2010-03-05 04:42:43 +0000
38+@@ -17,7 +17,19 @@
39+ # License along with this library; if not, write to the
40+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
41+ # Boston, MA 02111-1307, USA.
42++import datetime
43++import optparse
44+ import sys, re, xml.dom.minidom
45++
46++try:
47++ import subunit
48++ from subunit import iso8601
49++ from testtools.content import Content, ContentType
50++ mime_utf8 = ContentType('text', 'plain', {'charset': 'utf8'})
51++except ImportError:
52++ subunit = None
53++
54++
55+ pkginstall_configvars = {
56+ #@PKGINSTALL_CONFIGVARS_IN24LINES@ # configvars are substituted upon script installation
57+ }
58+@@ -144,8 +156,25 @@
59+ self.last_binary.random_seed = node_as_text (rseed)
60+ self.process_children (node)
61+
62+-# HTML report generation class
63+-class ReportWriter (TreeProcess):
64++
65++class ReportWriter(object):
66++ """Base class for reporting."""
67++
68++ def __init__(self, binary_list):
69++ self.binaries = binary_list
70++
71++ def _error_text(node):
72++ """Get a string representing the error children of node."""
73++ rlist = list_children(node, 'error')
74++ txt = ''
75++ for enode in rlist:
76++ txt += node_as_text (enode)
77++ if txt and txt[-1] != '\n':
78++ txt += '\n'
79++ return txt
80++
81++
82++class HTMLReportWriter(ReportWriter):
83+ # Javascript/CSS snippet to toggle element visibility
84+ cssjs = r'''
85+ <style type="text/css" media="screen">
86+@@ -186,9 +215,8 @@
87+ }
88+ --></script>
89+ '''
90+- def __init__ (self, binary_list):
91+- TreeProcess.__init__ (self)
92+- self.binaries = binary_list
93++ def __init__(self, binary_list):
94++ ReportWriter.__init__(self, binary_list)
95+ self.bcounter = 0
96+ self.tcounter = 0
97+ self.total_tcounter = 0
98+@@ -219,12 +247,7 @@
99+ self.oprint ('<td>%s %s</td> <td align="right">%s</td> \n' % (html_indent_string (4), path, duration))
100+ perflist = list_children (node, 'performance')
101+ if result != 'success':
102+- rlist = list_children (node, 'error')
103+- txt = ''
104+- for enode in rlist:
105+- txt += node_as_text (enode)
106+- if txt and txt[-1] != '\n':
107+- txt += '\n'
108++ txt = self._error_text(node)
109+ txt = re.sub (r'"', r'\\"', txt)
110+ txt = re.sub (r'\n', r'\\n', txt)
111+ txt = re.sub (r'&', r'&amp;', txt)
112+@@ -313,46 +336,132 @@
113+ self.oprint ('</body>\n')
114+ self.oprint ('</html>\n')
115+
116++
117++class SubunitWriter(ReportWriter):
118++ """Reporter to output a subunit stream."""
119++
120++ def printout(self):
121++ reporter = subunit.TestProtocolClient(sys.stdout)
122++ for binary in self.binaries:
123++ for tc in binary.testcases:
124++ test = GTestCase(tc, binary)
125++ test.run(reporter)
126++
127++
128++class GTestCase(object):
129++ """A representation of a gtester test result as a pyunit TestCase."""
130++
131++ def __init__(self, case, binary):
132++ """Create a GTestCase for case `case` from binary program `binary`."""
133++ self._case = case
134++ self._binary = binary
135++ # the name of the case - e.g. /dbusmenu/glib/objects/menuitem/props_boolstr
136++ self._path = attribute_as_text(self._case, 'path')
137++
138++ def id(self):
139++ """What test is this? Returns the gtester path for the testcase."""
140++ return self._path
141++
142++ def _get_details(self):
143++ """Calculate a details dict for the test - attachments etc."""
144++ details = {}
145++ result = attribute_as_text(self._case, 'result', 'status')
146++ details['filename'] = Content(mime_utf8, lambda:[self._binary.file])
147++ details['random_seed'] = Content(mime_utf8,
148++ lambda:[self._binary.random_seed])
149++ if self._get_outcome() == 'addFailure':
150++ # Extract the error details. Skips have no details because its not
151++ # skip like unittest does, instead the runner just bypasses N test.
152++ txt = self._error_text(self._case)
153++ details['error'] = Content(mime_utf8, lambda:[txt])
154++ if self._get_outcome() == 'addSuccess':
155++ # Sucessful tests may have performance metrics.
156++ perflist = list_children(self._case, 'performance')
157++ if perflist:
158++ presults = []
159++ for perf in perflist:
160++ pmin = bool (int (attribute_as_text (perf, 'minimize')))
161++ pmax = bool (int (attribute_as_text (perf, 'maximize')))
162++ pval = float (attribute_as_text (perf, 'value'))
163++ txt = node_as_text (perf)
164++ txt = 'Performance(' + (pmin and 'minimized' or 'maximized'
165++ ) + '): ' + txt.strip() + '\n'
166++ presults += [(pval, txt)]
167++ presults.sort()
168++ perf_details = [e[1] for e in presults]
169++ details['performance'] = Content(mime_utf8, lambda:perf_details)
170++ return details
171++
172++ def _get_outcome(self):
173++ if int(attribute_as_text(self._case, 'skipped') + '0'):
174++ return 'addSkip'
175++ outcome = attribute_as_text(self._case, 'result', 'status')
176++ if outcome == 'success':
177++ return 'addSuccess'
178++ else:
179++ return 'addFailure'
180++
181++ def run(self, result):
182++ time = datetime.datetime.utcnow().replace(tzinfo=iso8601.Utc())
183++ result.time(time)
184++ result.startTest(self)
185++ try:
186++ outcome = self._get_outcome()
187++ details = self._get_details()
188++ # Only provide a duration IFF outcome == 'addSuccess' - the main
189++ # parser claims bogus results otherwise: in that case emit time as
190++ # zero perhaps.
191++ if outcome == 'addSuccess':
192++ duration = float(node_as_text(self._case, 'duration'))
193++ duration = duration * 1000000
194++ timedelta = datetime.timedelta(0, 0, duration)
195++ time = time + timedelta
196++ result.time(time)
197++ getattr(result, outcome)(self, details=details)
198++ finally:
199++ result.stopTest(self)
200++
201++
202++
203+ # main program handling
204+-def parse_files_and_args ():
205+- from sys import argv, stdin
206+- files = []
207+- arg_iter = sys.argv[1:].__iter__()
208+- rest = len (sys.argv) - 1
209+- for arg in arg_iter:
210+- rest -= 1
211+- if arg == '--help' or arg == '-h':
212+- print_help ()
213+- sys.exit (0)
214+- elif arg == '--version' or arg == '-v':
215+- print_help (False)
216+- sys.exit (0)
217+- else:
218+- files = files + [ arg ]
219+- return files
220+-
221+-def print_help (with_help = True):
222+- import os
223+- print "gtester-report (GLib utils) version", pkginstall_configvars.get ('glib-version', '0.0-uninstalled')
224+- if not with_help:
225+- return
226+- print "Usage: %s [OPTIONS] <gtester-log.xml>" % os.path.basename (sys.argv[0])
227+- print "Generate HTML reports from the XML log files generated by gtester."
228+- print "Options:"
229+- print " --help, -h print this help message"
230+- print " --version, -v print version info"
231++def parse_opts():
232++ """Parse program options.
233++
234++ :return: An options object and the program arguments.
235++ """
236++ parser = optparse.OptionParser()
237++ parser.version = pkginstall_configvars.get ('glib-version', '0.0-uninstalled')
238++ parser.usage = "%prog [OPTIONS] <gtester-log.xml>"
239++ parser.description = "Generate HTML reports from the XML log files generated by gtester."
240++ parser.epilog = "gtester-report (GLib utils) version %s."% (parser.version,)
241++ parser.add_option("-v", "--version", action="store_true", dest="version", default=False,
242++ help="Show program version.")
243++ parser.add_option("-s", "--subunit", action="store_true", dest="subunit", default=False,
244++ help="Output subunit [See https://launchpad.net/subunit/"
245++ " Needs python-subunit]")
246++ options, files = parser.parse_args()
247++ if options.version:
248++ print parser.epilog
249++ return None, None
250++ if len(files) != 1:
251++ parser.error("Must supply a log file to parse.")
252++ if options.subunit and subunit is None:
253++ parser.error("python-subunit is not installed.")
254++ return options, files
255++
256+
257+ def main():
258+- from sys import argv, stdin
259+- files = parse_files_and_args()
260+- if len (files) != 1:
261+- print_help (True)
262+- sys.exit (1)
263++ options, files = parse_opts()
264++ if options is None:
265++ return 0
266+ xd = xml.dom.minidom.parse (files[0])
267+ rr = ReportReader()
268+ rr.trampoline (xd)
269+- rw = ReportWriter (rr.binary_list())
270+- rw.printout()
271++ if not options.subunit:
272++ HTMLReportWriter(rr.binary_list()).printout()
273++ else:
274++ SubunitWriter(rr.binary_list()).printout()
275++
276+
277+ if __name__ == '__main__':
278+ main()
279+
280
281=== modified file 'debian/patches/series'
282--- debian/patches/series 2010-02-22 15:00:46 +0000
283+++ debian/patches/series 2010-03-08 08:18:33 +0000
284@@ -5,3 +5,4 @@
285 05-dont-fail-a-couple-of-tests-when-running-as-root.patch
286 60_wait-longer-for-threads-to-die.patch
287 71_gio_launch_handler.patch
288+80-gtester-subunit.patch

Subscribers

People subscribed via source and target branches

to all changes: