[GRASS-SVN] r61003 - sandbox/wenzeslaus/gunittest
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jun 26 20:30:25 PDT 2014
Author: wenzeslaus
Date: 2014-06-26 20:30:25 -0700 (Thu, 26 Jun 2014)
New Revision: 61003
Modified:
sandbox/wenzeslaus/gunittest/case.py
sandbox/wenzeslaus/gunittest/checkers.py
sandbox/wenzeslaus/gunittest/gmodules.py
Log:
gunittest: MD5 sums for files (not tested); declarations for special run modules functions
Modified: sandbox/wenzeslaus/gunittest/case.py
===================================================================
--- sandbox/wenzeslaus/gunittest/case.py 2014-06-27 00:44:19 UTC (rev 61002)
+++ sandbox/wenzeslaus/gunittest/case.py 2014-06-27 03:30:25 UTC (rev 61003)
@@ -12,13 +12,14 @@
@author Vaclav Petras
"""
-
+import os
import unittest
from unittest.util import safe_repr
from .gmodules import call_module
from .checkers import (check_text_ellipsis,
- text_to_keyvalue, compare_keyvalue, diff_keyvalue)
+ text_to_keyvalue, compare_keyvalue, diff_keyvalue,
+ file_md5, files_equal_md5)
# the following lines are for code coverage
@@ -47,6 +48,7 @@
reference)
self.fail(self._formatMessage(msg, standardMsg))
+ # TODO: we can have also more general function without the subset reference
def assertCommandKeyValue(self, module, parameters, reference, sep,
msg=None):
if isinstance(reference, basestring):
@@ -100,6 +102,89 @@
parameters=parameters,
reference=reference, msg=msg, sep='=')
+ def assertFileExists(self, filename, msg=None, skip_size_check=False):
+ """
+
+ .. note:
+ By default this also checks if the file size is greater than 0
+ since we rarely want a file to be empty.
+ """
+ if not os.path.isfile(filename):
+ standardMsg = 'File %s does not exist' % filename
+ self.fail(self._formatMessage(msg, standardMsg))
+ if not os.path.getsize(filename):
+ standardMsg = 'File %s is empty' % filename
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertFileMd5(self, filename, md5, msg=None):
+ self.assertFileExists(filename, msg=msg)
+ if not file_md5(filename) == md5:
+ standardMsg = 'File %s does not have the right MD5 sum' % filename
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertFilesEqualMd5(self, filename, reference_filename, msg=None):
+ self.assertFileExists(filename, msg=msg)
+ # nothing for ref, missing ref_filename is an error not a test failure
+ if not files_equal_md5(filename, reference_filename):
+ stdmsg = 'Files %s and %s don\'t have the same MD5 sums' % (filename,
+ reference_filename)
+ self.fail(self._formatMessage(msg, stdmsg))
+
+ # TODO: this function might be useful but it is questionable if it is really needed
+ # TODO: name run_module/test_module/assert_module/call_module?
+ # TODO: implemet this function
+ # TODO: this should be the function used for valgrind or profiling or debug
+ # TODO: how these functions will behave when doing some benchmark with stdin/stdout?
+ # TODO: should call fail instead of raising? probably not, it is not assert but...
+ # maybe we should measure time but the real benchmarks with stdin/stdout
+ # should be done by some other function
+ # can accept stdin
+ # logs merged stdout and stderr
+ # raises when modules returns non-zero (should raise after logging)
+ def run_module(self, module, stdin=None, **kwargs):
+ """Run module and save stdout and stderr.
+
+ This function should be used when you expect the module to succeed
+ and you are testing outputs of the module other than stdout.
+ For example, if you are interested in raster map it produced.
+ The advantage of this function is that it gives you a posibility to
+ examine the output of the module.
+
+ This is not appropriate for the cases when you want module standard output.
+ For this cases use call_module function which will give you stdout
+ separated without stderr and will raise an exception with stderr in
+ case of error.
+
+ .. note::
+ There should be only one call of this method per test method.
+
+ :returns: None
+ """
+ # this probably will not not use call_module because it should
+ # enable valgrid, profiling, debug for the module, ...
+ # for now call_module is good enough
+ output = call_module(module, stdin, merge_stderr=True, **kwargs)
+ # TODO: log output (stdout+stderr) to some file
+ # TODO: log also stdin and parameters
+
+ # can accept stdin
+ # returns stdout
+ # logs stderr
+ # raises when modules returns non-zero (should raise after logging)
+ def read_module(self, module, stdin=None, **kwargs):
+ """
+
+ Similar to `run_module` but returns stdout. It logs only stderr.
+
+ .. note::
+ There should be only one call of this method per test method.
+ """
+ # TODO: this cannot be implemented using call_module for sure
+ # since it needs to get stdout and stderr separately
+ # for now call_module is good enough
+ output = call_module(module, stdin, merge_stderr=False, **kwargs)
+ return output
+
# the following lines are for code coverage
def endcov(cov):
cov.stop()
Modified: sandbox/wenzeslaus/gunittest/checkers.py
===================================================================
--- sandbox/wenzeslaus/gunittest/checkers.py 2014-06-27 00:44:19 UTC (rev 61002)
+++ sandbox/wenzeslaus/gunittest/checkers.py 2014-06-27 03:30:25 UTC (rev 61003)
@@ -489,6 +489,32 @@
optionflags=doctest.ELLIPSIS)
+import hashlib
+
+# optimal size depends on file system and maybe on hasher.block_size
+_BUFFER_SIZE = 2**16
+
+
+# TODO: accept also open file object
+def file_md5(filename):
+ hasher = hashlib.md5()
+ with open(filename, 'rb') as f:
+ buf = f.read(_BUFFER_SIZE)
+ while len(buf) > 0:
+ hasher.update(buf)
+ buf = f.read(_BUFFER_SIZE)
+ return hasher.hexdigest()
+
+
+def text_file_md5(filename, exclude_lines=None,
+ prepend_lines=None, append_lines=None):
+ raise NotImplementedError("Implement, or use file_md5() function instead")
+
+
+def files_equal_md5(filename_a, filename_b):
+ return file_md5(filename_a) == file_md5(filename_b)
+
+
def main(): # pragma: no cover
ret = doctest.testmod()
return ret.failed
Modified: sandbox/wenzeslaus/gunittest/gmodules.py
===================================================================
--- sandbox/wenzeslaus/gunittest/gmodules.py 2014-06-27 00:44:19 UTC (rev 61002)
+++ sandbox/wenzeslaus/gunittest/gmodules.py 2014-06-27 03:30:25 UTC (rev 61003)
@@ -115,6 +115,10 @@
:raises CalledModuleError: if module return code is non-zero
:raises ValueError: if the parameters are not correct
+
+ .. note::
+ The data read is buffered in memory, so do not use this method
+ if the data size is large or unlimited.
"""
# TODO: remove this:
do_doctest_gettext_workaround()
More information about the grass-commit
mailing list