[GRASS-SVN] r61145 - in sandbox/wenzeslaus/gunittest: . testsuite
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jul 3 18:26:39 PDT 2014
Author: wenzeslaus
Date: 2014-07-03 18:26:39 -0700 (Thu, 03 Jul 2014)
New Revision: 61145
Added:
sandbox/wenzeslaus/gunittest/reporters.py
Modified:
sandbox/wenzeslaus/gunittest/invoker.py
sandbox/wenzeslaus/gunittest/main.py
sandbox/wenzeslaus/gunittest/testsuite/test_checkers.py
Log:
gunittest: move report generation to a separate class and file, add separated text and html stdoutand stderr
Modified: sandbox/wenzeslaus/gunittest/invoker.py
===================================================================
--- sandbox/wenzeslaus/gunittest/invoker.py 2014-07-03 23:10:12 UTC (rev 61144)
+++ sandbox/wenzeslaus/gunittest/invoker.py 2014-07-04 01:26:39 UTC (rev 61145)
@@ -11,6 +11,7 @@
TestProgram.USAGE = USAGE_AS_MAIN
from loader import GrassTestLoader, discover_modules
+from reporters import GrassTestFilesReporter
import utils
import grass.script.setup as gsetup
@@ -38,6 +39,8 @@
self.clean_outputs = clean_outputs
self.clean_before = clean_before
self.testsuite_dir = testsuite_dir
+ # reporter is created for each call of run_in_location()
+ self.reporter = None
def _create_mapset(self, gisdbase, location, module):
"""Create mapset according to informations in module.
@@ -64,12 +67,43 @@
os.path.join(mapset_dir))
return mapset, mapset_dir
+ def _run_test_module(self, module, results_dir, gisdbase, location):
+ cwd = os.path.join(results_dir, module.tested_dir, module.name)
+ utils.ensure_dir(os.path.abspath(cwd))
+ # TODO: put this to constructor and copy here again
+ env = os.environ.copy()
+ mapset, mapset_dir = self._create_mapset(gisdbase, location, module)
+ gisrc = gsetup.write_gisrc(gisdbase, location, mapset)
+ env['GISRC'] = gisrc
+
+ stdout_path = os.path.join(cwd, 'stdout.txt')
+ stderr_path = os.path.join(cwd, 'stderr.txt')
+ stdout = open(stdout_path, 'w')
+ stderr = open(stderr_path, 'w')
+
+ # TODO: we might clean the directory here before test if non-empty
+ # TODO: use some grass function to run?
+ p = subprocess.Popen([sys.executable, module.abs_file_path],
+ cwd=cwd, env=env,
+ stdout=stdout, stderr=stderr)
+ returncode = p.wait()
+ stdout.close()
+ stderr.close()
+ self.reporter.add_test_results(module=module, cwd=cwd,
+ returncode=returncode,
+ stdout=stdout_path, stderr=stderr_path)
+ # TODO: add some try-except or with for better error handling
+ os.remove(gisrc)
+ # TODO: only if clean up
+ if self.clean_mapsets:
+ shutil.rmtree(mapset_dir)
+
def run_in_location(self, gisdbase, location, location_shortcut,
results_dir):
if os.path.abspath(results_dir) == os.path.abspath(self.start_dir):
raise RuntimeError("Results root directory should not be the same"
" as discovery start directory")
- main_start_time = datetime.datetime.now()
+ self.reporter = GrassTestFilesReporter(results_dir=results_dir)
# TODO: move constants out of loader class or even module
modules = discover_modules(start_dir=self.start_dir,
@@ -80,62 +114,9 @@
all_locations_value=GrassTestLoader.all_tests_value,
universal_location_value=GrassTestLoader.universal_tests_value,
import_modules=False)
- # TODO: no directory cleaning (self.clean_before)? now cleaned by caller
- utils.ensure_dir(os.path.abspath(results_dir))
- main_index = open(os.path.join(results_dir, 'index.html'), 'w')
- main_index.write('<html><body>'
- '<h1>Test results</h1>'
- '{time:%Y-%m-%d %H:%M:%S}'
- '<ul>'.format(time=main_start_time))
+
for module in modules:
- cwd = os.path.join(results_dir, module.tested_dir, module.name)
- utils.ensure_dir(os.path.abspath(cwd))
- # TODO: put this to constructor and copy here again
- env = os.environ.copy()
- mapset, mapset_dir = self._create_mapset(gisdbase, location, module)
- gisrc = gsetup.write_gisrc(gisdbase, location, mapset)
- env['GISRC'] = gisrc
+ self._run_test_module(module=module, results_dir=results_dir,
+ gisdbase=gisdbase, location=location)
- # TODO: we don't do any HTML escaping, use txt file
- stdout = open(os.path.join(cwd, 'stdout.html'), 'w')
- stderr = open(os.path.join(cwd, 'stderr.html'), 'w')
- stdout.write('<html><body><h1>%s</h1><pre>' % (module.name + ' stdout'))
- stderr.write('<html><body><h1>%s</h1><pre>' % (module.name + ' stderr'))
- stdout.flush() # we need to flush to write our changes before stdout
- stderr.flush()
-
- # TODO: we might clean the directory here before test if non-empty
- # TODO: use some grass function to run?
- p = subprocess.Popen([sys.executable, module.abs_file_path],
- cwd=cwd, env=env,
- stdout=stdout, stderr=stderr)
- returncode = p.wait()
- stdout.flush()
- stderr.flush()
- stdout.write('</pre></body></html>')
- stderr.write('</pre></body></html>')
- file_index_path = os.path.join(cwd, 'index.html')
- if returncode:
- sys.stderr.write('{d}/{m} failed (see {f})\n'.format(d=module.tested_dir,
- m=module.name,
- f=file_index_path))
- main_index.write('<li><a href="{d}/{m}/index.html">{d}/{m}</a>'.format(d=module.tested_dir, m=module.name))
- file_index = open(file_index_path, 'w')
- file_index.write('<html><body>'
- '<ul>'
- '<li><a href="stdout.html">standard output (stdout)</a>'
- '<li><a href="stderr.html">standard error output (stderr)</a>'
- '<li><a href="testcodecoverage/index.html">code coverage</a>'
- '</ul>'
- '</body></html>')
- stdout.close()
- stderr.close()
- file_index.close()
- # TODO: add some try-except or with for better error handling
- os.remove(gisrc)
- # TODO: only if clean up
- if self.clean_mapsets:
- shutil.rmtree(mapset_dir)
- main_index.write('</ul>'
- '</body></html>')
- main_index.close()
+ self.reporter.finish()
Modified: sandbox/wenzeslaus/gunittest/main.py
===================================================================
--- sandbox/wenzeslaus/gunittest/main.py 2014-07-03 23:10:12 UTC (rev 61144)
+++ sandbox/wenzeslaus/gunittest/main.py 2014-07-04 01:26:39 UTC (rev 61145)
@@ -104,7 +104,7 @@
if not os.path.exists(gisdbase):
sys.stderr.write("GISDBASE <%s> does not exist\n" % gisdbase)
sys.exit(1)
- results_dir = 'testresults'
+ results_dir = 'testreport'
utils.silent_rmtree(results_dir) # TODO: too brute force?
invoker = GrassTestFilesInvoker(start_dir='.')
Added: sandbox/wenzeslaus/gunittest/reporters.py
===================================================================
--- sandbox/wenzeslaus/gunittest/reporters.py (rev 0)
+++ sandbox/wenzeslaus/gunittest/reporters.py 2014-07-04 01:26:39 UTC (rev 61145)
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+
+import os
+import sys
+import datetime
+import xml.sax.saxutils as saxutils
+
+import utils
+
+
+def html_escape(text):
+ """Escape ``'&'``, ``'<'``, and ``'>'`` in a string of data."""
+ return saxutils.escape(text)
+
+
+def html_unescape(text):
+ """Unescape ``'&'``, ``'<'``, and ``'>'`` in a string of data."""
+ return saxutils.unescape(text)
+
+
+def color_error_line(line):
+ if line.startswith('ERROR: '):
+ # TODO: use CSS class
+ # ignoring the issue with \n at the end, HTML don't mind
+ line = '<span style="color: red">' + line + "</span>"
+ if line.startswith('WARNING: '):
+ # TODO: use CSS class
+ # ignoring the issue with \n at the end, HTML don't mind
+ line = '<span style="color: blue">' + line + "</span>"
+ return line
+
+
+class GrassTestFilesReporter(object):
+
+ def __init__(self, results_dir):
+ # TODO: no directory cleaning (self.clean_before)? now cleaned by caller
+ utils.ensure_dir(os.path.abspath(results_dir))
+
+ # having all variables public although not really part of API
+ self.main_index = open(os.path.join(results_dir, 'index.html'), 'w')
+ # this might be moved to some report start method
+ self.main_start_time = datetime.datetime.now()
+ self.main_index.write('<html><body>'
+ '<h1>Test results</h1>'
+ '{time:%Y-%m-%d %H:%M:%S}'
+ '<ul>'.format(time=self.main_start_time))
+
+ def finish(self):
+ self.main_index.write('</ul>'
+ '</body></html>')
+ self.main_index.close()
+
+ def add_test_results(self, module, cwd, returncode, stdout, stderr):
+ self.main_index.write(
+ '<li><a href="{d}/{m}/index.html">{d}/{m}</a>'.format(
+ d=module.tested_dir, m=module.name))
+ # TODO: we don't do any HTML escaping, use txt file
+ stdout_html = open(os.path.join(cwd, 'stdout.html'), 'w')
+ stderr_html = open(os.path.join(cwd, 'stderr.html'), 'w')
+ stdout_html.write('<html><body><h1>%s</h1><pre>' % (module.name + ' stdout'))
+ stderr_html.write('<html><body><h1>%s</h1><pre>' % (module.name + ' stderr'))
+
+ with open(stdout) as text:
+ for line in text:
+ stdout_html.write(color_error_line(html_escape(line)))
+ with open(stderr) as text:
+ for line in text:
+ stderr_html.write(color_error_line(html_escape(line)))
+
+ stdout_html.write('</pre></body></html>')
+ stderr_html.write('</pre></body></html>')
+ stdout_html.close()
+ stderr_html.close()
+
+ file_index_path = os.path.join(cwd, 'index.html')
+ file_index = open(file_index_path, 'w')
+ file_index.write('<html><body>'
+ '<ul>'
+ '<li><a href="stdout.html">standard output (stdout)</a>'
+ '<li><a href="stderr.html">standard error output (stderr)</a>'
+ '<li><a href="testcodecoverage/index.html">code coverage</a>'
+ '</ul>'
+ '</body></html>')
+ file_index.close()
+
+ if returncode:
+ sys.stderr.write('{d}/{m} failed (see {f})\n'.format(d=module.tested_dir,
+ m=module.name,
+ f=file_index_path))
Property changes on: sandbox/wenzeslaus/gunittest/reporters.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Modified: sandbox/wenzeslaus/gunittest/testsuite/test_checkers.py
===================================================================
--- sandbox/wenzeslaus/gunittest/testsuite/test_checkers.py 2014-07-03 23:10:12 UTC (rev 61144)
+++ sandbox/wenzeslaus/gunittest/testsuite/test_checkers.py 2014-07-04 01:26:39 UTC (rev 61145)
@@ -315,4 +315,4 @@
if __name__ == '__main__':
from gunittest.main import test
- test()
\ No newline at end of file
+ test()
More information about the grass-commit
mailing list