3 new revisions:
Revision: 73982a8643a5
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 13:52:35 2012
Log: result building: Build combined results lazily. Reduces memory
consump...
http://code.google.com/p/robotframework/source/detail?r=73982a8643a5
Revision: 1082c9352c10
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 15:05:14 2012
Log: Result building: Omit keywords if building only report....
http://code.google.com/p/robotframework/source/detail?r=1082c9352c10
Revision: 32635aed62d8
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 15:23:00 2012
Log: Refactored result parsing after latest enhancements....
http://code.google.com/p/robotframework/source/detail?r=32635aed62d8
==============================================================================
Revision: 73982a8643a5
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 13:52:35 2012
Log: result building: Build combined results lazily. Reduces memory
consumption a little.
http://code.google.com/p/robotframework/source/detail?r=73982a8643a5
Modified:
/src/robot/result/executionresult.py
/src/robot/result/resultbuilder.py
=======================================
--- /src/robot/result/executionresult.py Wed Mar 14 05:58:57 2012
+++ /src/robot/result/executionresult.py Fri Oct 19 13:52:35 2012
@@ -64,7 +64,7 @@
class CombinedResult(Result):
- def __init__(self, *others):
+ def __init__(self, others):
Result.__init__(self)
for other in others:
self.add_result(other)
=======================================
--- /src/robot/result/resultbuilder.py Sat Jun 30 16:02:25 2012
+++ /src/robot/result/resultbuilder.py Fri Oct 19 13:52:35 2012
@@ -33,7 +33,7 @@
if not sources:
raise DataError('One or more data source needed.')
if len(sources) > 1:
- return CombinedResult(*[ExecutionResult(src) for src in sources])
+ return CombinedResult(ExecutionResult(src) for src in sources)
source = ETSource(sources[0])
try:
return ExecutionResultBuilder(source).build(Result(sources[0]))
==============================================================================
Revision: 1082c9352c10
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 15:05:14 2012
Log: Result building: Omit keywords if building only report.
Update issue 1261
Status: Started
Changed the code so that if only report is generated, keywords in output.xml
are nor processed at all. I want to still refactor the code a little and
thus I don't close this issue yet.
The performance impact of the change is pretty huge. In the case mentioned
in the original description, total time is now 1 minute and maximum memory
63 MB.
http://code.google.com/p/robotframework/source/detail?r=1082c9352c10
Modified:
/src/robot/reporting/resultwriter.py
/src/robot/result/resultbuilder.py
=======================================
--- /src/robot/reporting/resultwriter.py Mon Jun 25 07:41:07 2012
+++ /src/robot/reporting/resultwriter.py Fri Oct 19 15:05:14 2012
@@ -81,7 +81,11 @@
@property
def result(self):
if self._result is None:
- self._result = ExecutionResult(*self._data_sources)
+ include_keywords = bool(self._settings.log or
+ self._settings.output or
+ self._settings.xunit)
+ self._result =
ExecutionResult(include_keywords=include_keywords,
+ *self._data_sources)
self._result.configure(self._settings.status_rc,
self._settings.suite_config,
self._settings.statistics_config)
=======================================
--- /src/robot/result/resultbuilder.py Fri Oct 19 13:52:35 2012
+++ /src/robot/result/resultbuilder.py Fri Oct 19 15:05:14 2012
@@ -22,10 +22,13 @@
from .executionresult import Result, CombinedResult
-def ExecutionResult(*sources):
+def ExecutionResult(*sources, **options):
"""Constructs :class:`Result` object based on execution result xml
file(s).
:param sources: The Robot Framework output xml file(s).
+ :param options: Configuration options passed to
+ :py:class:`~ExecutionResultBuilder` as keyword
arguments.
+ New in 2.7.5.
:returns: :py:class:`~.executionresult.Result` instance.
See :py:mod:`robot.result` for usage example.
@@ -33,10 +36,10 @@
if not sources:
raise DataError('One or more data source needed.')
if len(sources) > 1:
- return CombinedResult(ExecutionResult(src) for src in sources)
+ return CombinedResult(ExecutionResult(src, **options) for src in
sources)
source = ETSource(sources[0])
try:
- return ExecutionResultBuilder(source).build(Result(sources[0]))
+ return ExecutionResultBuilder(source,
**options).build(Result(sources[0]))
except IOError, err:
error = err.strerror
except:
@@ -46,16 +49,35 @@
class ExecutionResultBuilder(object):
- def __init__(self, source):
+ def __init__(self, source, include_keywords=True):
self._source = source \
if isinstance(source, ETSource) else ETSource(source)
+ self._include_keywords = include_keywords
def build(self, result):
handler = XmlElementHandler(result)
# Faster attribute lookup inside for loop
start, end = handler.start, handler.end
with self._source as source:
- for event, elem in ET.iterparse(source,
events=('start', 'end')):
+ for event, elem in self._get_context(source):
start(elem) if event == 'start' else end(elem)
SuiteTeardownFailureHandler(result.generator).visit_suite(result.suite)
return result
+
+ def _get_context(self, source):
+ context = ET.iterparse(source, events=('start', 'end'))
+ if not self._include_keywords:
+ context = self._omit_keywords(context)
+ return context
+
+ def _omit_keywords(self, context):
+ kws = 0
+ for event, elem in context:
+ if event == 'start' and elem.tag == 'kw':
+ kws += 1
+ if not kws:
+ yield event, elem
+ else:
+ elem.clear()
+ if event == 'end' and elem.tag == 'kw':
+ kws -= 1
==============================================================================
Revision: 32635aed62d8
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 15:23:00 2012
Log: Refactored result parsing after latest enhancements.
Update issue 1261
Status: Done
Refactored the code a little. Issue ought to be done.
http://code.google.com/p/robotframework/source/detail?r=32635aed62d8
Modified:
/src/robot/result/resultbuilder.py
/src/robot/result/xmlelementhandlers.py
=======================================
--- /src/robot/result/resultbuilder.py Fri Oct 19 15:05:14 2012
+++ /src/robot/result/resultbuilder.py Fri Oct 19 15:23:00 2012
@@ -36,15 +36,21 @@
if not sources:
raise DataError('One or more data source needed.')
if len(sources) > 1:
- return CombinedResult(ExecutionResult(src, **options) for src in
sources)
- source = ETSource(sources[0])
+ return _combined_result(sources, options)
+ return _single_result(sources[0], options)
+
+def _combined_result(sources, options):
+ return CombinedResult(ExecutionResult(src, **options) for src in
sources)
+
+def _single_result(source, options):
+ ets = ETSource(source)
try:
- return ExecutionResultBuilder(source,
**options).build(Result(sources[0]))
+ return ExecutionResultBuilder(ets, **options).build(Result(source))
except IOError, err:
error = err.strerror
except:
error = get_error_message()
- raise DataError("Reading XML source '%s' failed: %s" %
(unicode(source), error))
+ raise DataError("Reading XML source '%s' failed: %s" % (unicode(ets),
error))
class ExecutionResultBuilder(object):
@@ -56,19 +62,21 @@
def build(self, result):
handler = XmlElementHandler(result)
- # Faster attribute lookup inside for loop
- start, end = handler.start, handler.end
with self._source as source:
- for event, elem in self._get_context(source):
- start(elem) if event == 'start' else end(elem)
+ self._parse(source, handler.start, handler.end)
SuiteTeardownFailureHandler(result.generator).visit_suite(result.suite)
return result
- def _get_context(self, source):
+ def _parse(self, source, start, end):
context = ET.iterparse(source, events=('start', 'end'))
if not self._include_keywords:
context = self._omit_keywords(context)
- return context
+ for event, elem in context:
+ if event == 'start':
+ start(elem)
+ else:
+ end(elem)
+ elem.clear()
def _omit_keywords(self, context):
kws = 0
=======================================
--- /src/robot/result/xmlelementhandlers.py Tue Jun 26 02:53:35 2012
+++ /src/robot/result/xmlelementhandlers.py Fri Oct 19 15:23:00 2012
@@ -27,7 +27,6 @@
def end(self, elem):
result, handler = self._stack.pop()
handler.end(elem, result)
- elem.clear()
class _Handler(object):