[apycotlib] add ScriptRunner to run custom files as checks, (closes #2882718)
The new checker can be derived to run any file provided the user writes a custom filename_filter method. The method has three parameters and two roles:
- the first parameter (dirpath) is the path being explored;
- the second parameter (dirname) is a list of directory names, the function must remove from the list the directories which should not be explored by os.walk;
- the third parameter (filenames) is a list of files. The user should yield a list of files which should be run by the checker.
This method uses the syntax of os.walk (see python doc).
Add corresponding tests and example recipe.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/_apycotlib/checkers/scenarios.py Mon Oct 07 11:03:46 2013 +0200
@@ -0,0 +1,32 @@
+import os
+from commands import getstatusoutput
+from apycotlib import SUCCESS, FAILURE, ERROR
+from apycotlib.checkers import AbstractFilteredFileChecker
+from apycotlib import register
+
+class ScriptRunner(AbstractFilteredFileChecker):
+ """
+ run files accepted by the filter
+ """
+ id = 'script_runner'
+ def do_check(self, test):
+ if self.options.get('filename_filter') is not None:
+ self.filename_filter = self.options.get('filename_filter')
+ super(ScriptRunner, self).do_check(test)
+
+ def check_file(self, filepath):
+ try:
+ self.writer.debug("running : " + filepath, path=filepath)
+ status, out = getstatusoutput(filepath)
+ if status != 0:
+ self.writer.error(out, path=filepath)
+ return FAILURE
+ self.writer.info(out, path=filepath)
+ return SUCCESS
+ except Exception, error:
+ self.writer.error(error.msg, path=filepath)
+ return ERROR
+
+register('checker', ScriptRunner)
+
+
--- a/_apycotlib/narvalactions.py Thu Sep 12 11:26:26 2013 +0200
+++ b/_apycotlib/narvalactions.py Mon Oct 07 11:03:46 2013 +0200
@@ -1,6 +1,6 @@
from apycotlib import atest, writer, ERROR
from apycotlib import preprocessors # trigger registration
-from apycotlib.checkers import python # trigger registration
+from apycotlib.checkers import python, scenarios # trigger registration
class apycot_environment(object):
def __init__(self, plan):
--- a/recipes.py Thu Sep 12 11:26:26 2013 +0200
+++ b/recipes.py Mon Oct 07 11:03:46 2013 +0200
@@ -25,3 +25,37 @@
def create_full_recipe(session):
return session.create_entity('Recipe', name=u'apycot.recipe.full',
script=full_script)
+
+scenario_runner_script = u'''
+import os
+from apycotlib import narvalactions as na
+from apycotlib.checkers.scenarios import ScriptRunner
+
+class ScenarioChecker(ScriptRunner):
+ id = "scenario_checker"
+ def filename_filter(self, dirpath, dirnames, filenames):
+ """
+ this function takes parameters from os.walk and has two objectives:
+ - from the dirnames, prune folders you do not want to explore
+ using dirnames.remove(x)
+ - remove all the filenames which should not be run from filenames in
+ the same way.
+ """
+ for dirname in dirnames[:]:
+ if dirname in ('.hg', '.git', '.svn'):
+ dirnames.remove(dirname)
+ for filename in filenames[:]:
+ if not (filename.endswith('.py') and filename.startswith('scenario_')):
+ filenames.remove(filename)
+
+register('checker', ScenarioChecker)
+
+with na.apycot_environment(plan) as test:
+ na.install_environment(test)
+ checker, status = test.run_checker('scenario_checker')
+'''
+
+def create_scenrario_filter_recipe(session):
+ return session.create_entity('Recipe', name=u'apycot.recipe.scenario_runner',
+ script=scenario_runner_script)
+
--- a/test/unittest_checkers.py Thu Sep 12 11:26:26 2013 +0200
+++ b/test/unittest_checkers.py Mon Oct 07 11:03:46 2013 +0200
@@ -39,8 +39,6 @@
if exists(path):
shutil.rmtree(path)
-
-
class FileCheckerTest(TestCase):
def __init__(self, checker, files, method_name):
TestCase.__init__(self, method_name)
@@ -164,6 +162,53 @@
python_syntax.best_status = 'partial'
addTest(FileCheckerTest(python_syntax, ['extentionfilter/'], 'chks_test_dir_partial'))
+ # check providing a custom file filter function
+ class CorrectFilter(PythonSyntaxChecker):
+ id = 'correct_filter'
+ def filename_filter(self, dirpath, dirnames, filenames):
+ for filename in filenames:
+ if not filename.endswith('.py'):
+ filenames.remove(filename)
+
+ python_syntax = CorrectFilter(WRITER)
+ addTest(FileCheckerTest(python_syntax, ['extentionfilter/'], 'chks_test_dir_success'))
+
+ class IncorrectFilter(PythonSyntaxChecker):
+ id = 'incorrect_filter'
+ def filename_filter(self, dirpath, dirnames, filenames):
+ for filename in filenames:
+ if not 'badsyntax' in filename:
+ filenames.remove(filename)
+
+ python_syntax = IncorrectFilter(WRITER)
+ addTest(FileCheckerTest(python_syntax, ['extentionfilter/'], 'chks_test_dir_failure'))
+
+ class CorrectDirFilter(PythonSyntaxChecker):
+ id = 'correct_dir_filter'
+ def filename_filter(self, dirpath, dirnames, filenames):
+ for dirname in dirnames[:]:
+ if 'bad' in dirname:
+ dirnames.remove(dirname)
+ for filename in filenames:
+ if 'bad' in filename:
+ filenames.remove(filename)
+
+ python_syntax = CorrectDirFilter(WRITER)
+ addTest(FileCheckerTest(python_syntax, ['syntax_dir/'], 'chks_test_dir_success'))
+
+ class IncorrectDirFilter(PythonSyntaxChecker):
+ id = 'incorrect_dir_filter'
+ def filename_filter(self, dirpath, dirnames, filenames):
+ for dirname in dirnames[:]:
+ if 'goodsyntax' in dirname:
+ dirnames.remove(dirname)
+ for filename in filenames:
+ if 'bad' in filename:
+ filenames.remove(filename)
+
+ python_syntax = IncorrectDirFilter(WRITER)
+ addTest(FileCheckerTest(python_syntax, ['syntax_dir/'], 'chks_test_dir_failure'))
+
##### PyUnitTestChecker #####
python_unit = PyUnitTestChecker(WRITER)
addTest(ModuleCheckerTest(python_unit, ['goodpkg'], 'chks_test_success'))