[GRASS-SVN] r61231 - in grass/trunk/lib/python: gunittest gunittest/testsuite pygrass/modules/interface
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jul 10 08:37:47 PDT 2014
Author: wenzeslaus
Date: 2014-07-10 08:37:47 -0700 (Thu, 10 Jul 2014)
New Revision: 61231
Modified:
grass/trunk/lib/python/gunittest/case.py
grass/trunk/lib/python/gunittest/gmodules.py
grass/trunk/lib/python/gunittest/testsuite/test_assertions.py
grass/trunk/lib/python/gunittest/testsuite/test_module_assertions.py
grass/trunk/lib/python/pygrass/modules/interface/module.py
Log:
gunittest: handle process manually since pygrass would raise an exception (introduced in r61229, alternative would be to use try-except, SimpleModule doctest is failing), clean up some module calls (use SimpleModule), improve CalledModuleError creation in pygrass
Modified: grass/trunk/lib/python/gunittest/case.py
===================================================================
--- grass/trunk/lib/python/gunittest/case.py 2014-07-10 09:35:01 UTC (rev 61230)
+++ grass/trunk/lib/python/gunittest/case.py 2014-07-10 15:37:47 UTC (rev 61231)
@@ -14,13 +14,14 @@
import os
import subprocess
+import time
import unittest
from unittest.util import safe_repr
from grass.pygrass.modules import Module
from grass.exceptions import CalledModuleError
-from .gmodules import call_module
+from .gmodules import call_module, SimpleModule
from .checkers import (check_text_ellipsis,
text_to_keyvalue, keyvalue_equals, diff_keyvalue,
file_md5, files_equal_md5)
@@ -444,25 +445,19 @@
:raises CalledModuleError: if the module failed
"""
module = _module_from_parameters(module, **kwargs)
+ _check_module_run_parameters(module)
- if module.run_:
- raise ValueError('Do not run the module manually, set run_=False')
- if not module.finish_:
- raise ValueError('This function will always finish module run,'
- ' set finish_=None or finish_=True.')
- # we expect most of the usages with stdout=PIPE
- # TODO: in any case capture PIPE always?
- if module.stdout_ is None:
- module.stdout_ = subprocess.PIPE
- elif module.stdout_ != subprocess.PIPE:
- raise ValueError('stdout_ can be only PIPE or None')
- if module.stderr_ is None:
- module.stderr_ = subprocess.PIPE
- elif module.stderr_ != subprocess.PIPE:
- raise ValueError('stderr_ can be only PIPE or None')
- # because we want to capture it
+ # do what module.run() with finish_=True would do
+ start = time.time()
module.run()
- if module.popen.returncode:
+ stdout, stderr = module.popen.communicate(input=module.stdin)
+ module.outputs['stdout'].value = stdout if stdout else ''
+ module.outputs['stderr'].value = stderr if stderr else ''
+ module.time = time.time() - start
+ if module.popen.poll():
+ # here exception raised by run() with finish_=True would be
+ # almost enough but we want some additional info to be included
+ # in the test report
errors = module.outputs['stderr'].value
# provide diagnostic at least in English locale
# TODO: standardized error code would be handy here
@@ -507,28 +502,19 @@
non-zero return code.
"""
module = _module_from_parameters(module, **kwargs)
+ _check_module_run_parameters(module)
- # TODO: merge stderr to stdout? if caller gives PIPE, for sure not
- if module.run_:
- raise ValueError('Do not run the module manually, set run_=False')
- if not module.finish_:
- raise ValueError('This function will always finish module run,'
- ' set finish_=None or finish_=True.')
- if module.stdout_ is None:
- module.stdout_ = subprocess.PIPE
- elif module.stdout_ != subprocess.PIPE:
- raise ValueError('stdout_ can be only PIPE or None')
- # because we want to capture it
- if module.stderr_ is None:
- module.stderr_ = subprocess.PIPE
- elif module.stderr_ != subprocess.PIPE:
- raise ValueError('stderr_ can be only PIPE or None')
- # because we want to capture it
-
+ # do what module.run() with finish_=True would do
+ start = time.time()
module.run()
+ stdout, stderr = module.popen.communicate(input=module.stdin)
+ module.outputs['stdout'].value = stdout if stdout else ''
+ module.outputs['stderr'].value = stderr if stderr else ''
+ module.time = time.time() - start
+ # TODO: these two lines should go to report in some better way
print module.outputs['stdout'].value
print module.outputs['stderr'].value
- if module.popen.returncode:
+ if module.popen.poll():
# TODO: message format
# TODO: stderr?
stdmsg = ('Running <{m.name}> module ended'
@@ -554,27 +540,19 @@
Works like `assertModule()` but expects module to fail.
"""
module = _module_from_parameters(module, **kwargs)
+ _check_module_run_parameters(module)
- if module.run_:
- raise ValueError('Do not run the module manually, set run_=False')
- if not module.finish_:
- raise ValueError('This function will always finish module run,'
- ' set finish_=None or finish_=True.')
- if module.stdout_ is None:
- module.stdout_ = subprocess.PIPE
- elif module.stdout_ != subprocess.PIPE:
- raise ValueError('stdout_ can be only PIPE or None')
- # because we want to capture it
- if module.stderr_ is None:
- module.stderr_ = subprocess.PIPE
- elif module.stderr_ != subprocess.PIPE:
- raise ValueError('stderr_ can be only PIPE or None')
- # because we want to capture it
-
+ # do what module.run() with finish_=True would do
+ start = time.time()
module.run()
+ stdout, stderr = module.popen.communicate(input=module.stdin)
+ module.outputs['stdout'].value = stdout if stdout else ''
+ module.outputs['stderr'].value = stderr if stderr else ''
+ module.time = time.time() - start
+ # TODO: these two lines should go to report in some better way
print module.outputs['stdout'].value
print module.outputs['stderr'].value
- if not module.popen.returncode:
+ if not module.popen.poll():
stdmsg = ('Running <%s> ended with zero (successful) return code'
' when expecting module to fail' % module.get_python())
self.fail(self._formatMessage(msg, stdmsg))
@@ -592,5 +570,25 @@
# allow to pass all parameters in one dictionary called parameters
if kwargs.keys() == ['parameters']:
kwargs = kwargs['parameters']
- module = Module(module, run_=False, **kwargs)
+ module = SimpleModule(module, **kwargs)
return module
+
+
+def _check_module_run_parameters(module):
+ # in this case module already run and we would start it again
+ if module.run_:
+ raise ValueError('Do not run the module manually, set run_=False')
+ if module.finish_:
+ raise ValueError('This function will always finish module run,'
+ ' set finish_=None or finish_=False.')
+ # we expect most of the usages with stdout=PIPE
+ # TODO: in any case capture PIPE always?
+ if module.stdout_ is None:
+ module.stdout_ = subprocess.PIPE
+ elif module.stdout_ != subprocess.PIPE:
+ raise ValueError('stdout_ can be only PIPE or None')
+ if module.stderr_ is None:
+ module.stderr_ = subprocess.PIPE
+ elif module.stderr_ != subprocess.PIPE:
+ raise ValueError('stderr_ can be only PIPE or None')
+ # because we want to capture it
Modified: grass/trunk/lib/python/gunittest/gmodules.py
===================================================================
--- grass/trunk/lib/python/gunittest/gmodules.py 2014-07-10 09:35:01 UTC (rev 61230)
+++ grass/trunk/lib/python/gunittest/gmodules.py 2014-07-10 15:37:47 UTC (rev 61231)
@@ -50,7 +50,7 @@
', it would be overriden' % banned)
kargs['stdout_'] = subprocess.PIPE
kargs['stderr_'] = subprocess.PIPE
- kargs['finish_'] = True
+ kargs['finish_'] = False
kargs['run_'] = False
Module.__init__(self, cmd, *args, **kargs)
Modified: grass/trunk/lib/python/gunittest/testsuite/test_assertions.py
===================================================================
--- grass/trunk/lib/python/gunittest/testsuite/test_assertions.py 2014-07-10 09:35:01 UTC (rev 61230)
+++ grass/trunk/lib/python/gunittest/testsuite/test_assertions.py 2014-07-10 15:37:47 UTC (rev 61231)
@@ -91,7 +91,7 @@
@classmethod
def setUpClass(cls):
cls.use_temp_region()
- cls.runModule(Module('g.region', rast='elevation', run_=False))
+ cls.runModule(SimpleModule('g.region', rast='elevation'))
@classmethod
def tearDownClass(cls):
@@ -99,7 +99,8 @@
def test_pygrass_module(self):
"""Test syntax with Module as module"""
- module = Module('r.info', map='elevation', flags='gr', run_=False)
+ module = Module('r.info', map='elevation', flags='gr',
+ run_=False, finish_=False)
self.assertCommandKeyValue(module,
reference=dict(min=55.58, max=156.33),
precision=0.01, sep='=')
@@ -132,7 +133,7 @@
def setUpClass(cls):
cls.use_temp_region()
# TODO: here we should actually not call self.runModule but call_module
- cls.runModule(Module('g.region', rast='elevation', run_=False))
+ cls.runModule(SimpleModule('g.region', rast='elevation'))
@classmethod
def tearDownClass(cls):
Modified: grass/trunk/lib/python/gunittest/testsuite/test_module_assertions.py
===================================================================
--- grass/trunk/lib/python/gunittest/testsuite/test_module_assertions.py 2014-07-10 09:35:01 UTC (rev 61230)
+++ grass/trunk/lib/python/gunittest/testsuite/test_module_assertions.py 2014-07-10 15:37:47 UTC (rev 61231)
@@ -4,32 +4,38 @@
import subprocess
from grass.pygrass.modules import Module
+from grass.gunittest.gmodules import SimpleModule
import grass.gunittest
from grass.gunittest.gmodules import CalledModuleError
class TestModuleAssertions(grass.gunittest.TestCase):
+ """Test assertions using PyGRASS Module"""
# pylint: disable=R0904
def setUp(self):
+ """Create two Module instances one correct and one with wrong map"""
self.rinfo = Module('r.info', map='elevation', flags='g',
- stdout_=subprocess.PIPE, run_=False)
+ stdout_=subprocess.PIPE, run_=False, finish_=False)
self.rinfo_wrong = copy.deepcopy(self.rinfo)
self.wrong_map = 'does_not_exists'
self.rinfo_wrong.inputs['map'].value = self.wrong_map
def test_runModule(self):
+ """Module used in runModule()"""
self.runModule(self.rinfo)
self.assertTrue(self.rinfo.outputs['stdout'].value)
self.assertRaises(CalledModuleError, self.runModule, self.rinfo_wrong)
def test_assertModule(self):
+ """Module used in assertModule()"""
self.assertModule(self.rinfo)
self.assertTrue(self.rinfo.outputs['stdout'].value)
self.assertRaises(self.failureException, self.assertModule, self.rinfo_wrong)
def test_assertModuleFail(self):
+ """Module used in assertModuleFail()"""
self.assertModuleFail(self.rinfo_wrong)
stderr = self.rinfo_wrong.outputs['stderr'].value
self.assertTrue(stderr)
@@ -37,5 +43,39 @@
self.assertRaises(self.failureException, self.assertModuleFail, self.rinfo)
+class TestSimpleModuleAssertions(grass.gunittest.TestCase):
+ """Test assertions using SimpleModule"""
+ # pylint: disable=R0904
+
+ def setUp(self):
+ """Create two SimpleModule instances one correct and one with wrong map
+ """
+ self.rinfo = SimpleModule('r.info', map='elevation', flags='g')
+ self.rinfo_wrong = copy.deepcopy(self.rinfo)
+ self.wrong_map = 'does_not_exists'
+ self.rinfo_wrong.inputs['map'].value = self.wrong_map
+
+ def test_runModule(self):
+ """SimpleModule used in runModule()"""
+ self.runModule(self.rinfo)
+ self.assertTrue(self.rinfo.outputs['stdout'].value)
+ self.assertRaises(CalledModuleError, self.runModule, self.rinfo_wrong)
+
+ def test_assertModule(self):
+ """SimpleModule used in assertModule()"""
+ self.assertModule(self.rinfo)
+ self.assertTrue(self.rinfo.outputs['stdout'].value)
+ self.assertRaises(self.failureException, self.assertModule, self.rinfo_wrong)
+
+ def test_assertModuleFail(self):
+ """SimpleModule used in assertModuleFail()"""
+ self.assertModuleFail(self.rinfo_wrong)
+ stderr = self.rinfo_wrong.outputs['stderr'].value
+ self.assertTrue(stderr)
+ self.assertIn(self.wrong_map, stderr)
+ self.assertRaises(self.failureException, self.assertModuleFail, self.rinfo)
+
+
+
if __name__ == '__main__':
grass.gunittest.test()
Modified: grass/trunk/lib/python/pygrass/modules/interface/module.py
===================================================================
--- grass/trunk/lib/python/pygrass/modules/interface/module.py 2014-07-10 09:35:01 UTC (rev 61230)
+++ grass/trunk/lib/python/pygrass/modules/interface/module.py 2014-07-10 15:37:47 UTC (rev 61231)
@@ -564,8 +564,9 @@
self.outputs['stderr'].value = stderr if stderr else ''
self.time = time.time() - start
if self.popen.poll():
- raise CalledModuleError(self.popen.returncode, self.get_bash(),
- {}, stderr)
+ raise CalledModuleError(returncode=self.popen.returncode,
+ code=self.get_bash(),
+ module=self.name, errors=stderr)
return self
###############################################################################
More information about the grass-commit
mailing list