mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-9727: Initial commit for tox configuration
* Tox configuration created * Tox helper added * Refactoting to support several runners
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# coding=utf-8
|
||||
"""
|
||||
Runs tox from current directory.
|
||||
It supports any runner, but well-known runners (py.test and unittest) are switched to our internal runners to provide better support
|
||||
"""
|
||||
import sys
|
||||
from tox import config as tox_config, session as tox_session
|
||||
from tox.session import Reporter
|
||||
|
||||
from tcmessages import TeamcityServiceMessages
|
||||
import os
|
||||
|
||||
helpers_dir = str(os.path.split(__file__)[0])
|
||||
|
||||
# List of local runners to use
|
||||
_RUNNERS = {"unit2": [os.path.join(helpers_dir, "utrunner.py"), os.getcwd(), "true"]}
|
||||
|
||||
teamcity = TeamcityServiceMessages()
|
||||
|
||||
|
||||
|
||||
class _Reporter(Reporter):
|
||||
def logaction_start(self, action):
|
||||
super(_Reporter, self).logaction_start(action)
|
||||
if action.activity == "getenv":
|
||||
teamcity.testSuiteStarted(action.id)
|
||||
self.current_suite = action.id
|
||||
|
||||
def logaction_finish(self, action):
|
||||
super(_Reporter, self).logaction_finish(action)
|
||||
if action.activity == "runtests":
|
||||
teamcity.testSuiteFinished(action.id)
|
||||
|
||||
|
||||
def error(self, msg):
|
||||
super(_Reporter, self).error(msg)
|
||||
name = teamcity.current_test_name()
|
||||
if name:
|
||||
teamcity.testError(name, msg)
|
||||
if name == teamcity.topmost_suite:
|
||||
teamcity.testSuiteFinished(name)
|
||||
else:
|
||||
sys.stderr.write(msg)
|
||||
|
||||
def skip(self, msg):
|
||||
super(_Reporter, self).skip(msg)
|
||||
name = teamcity.current_test_name()
|
||||
if name:
|
||||
teamcity.testFinished(name)
|
||||
|
||||
|
||||
|
||||
|
||||
config = tox_config.parseconfig()
|
||||
for env, tmp_config in config.envconfigs.items():
|
||||
if not tmp_config.setenv:
|
||||
tmp_config.setenv = dict()
|
||||
tmp_config.setenv.update({"_jb_do_not_call_enter_matrix": "1"})
|
||||
commands = tmp_config.commands
|
||||
if isinstance(commands, list) and len(commands) == 1:
|
||||
command_with_arguments = commands[0]
|
||||
if command_with_arguments[0] in _RUNNERS:
|
||||
command_with_arguments = _RUNNERS[command_with_arguments[0]]
|
||||
tmp_config.commands = [command_with_arguments]
|
||||
|
||||
session = tox_session.Session(config, Report=_Reporter)
|
||||
teamcity.testMatrixEntered()
|
||||
session.runcommand()
|
||||
@@ -7,6 +7,14 @@ class TeamcityServiceMessages:
|
||||
def __init__(self, output=sys.stdout, prepend_linebreak=False):
|
||||
self.output = output
|
||||
self.prepend_linebreak = prepend_linebreak
|
||||
self.test_stack = []
|
||||
"""
|
||||
Names of tests
|
||||
"""
|
||||
self.topmost_suite = None
|
||||
"""
|
||||
Last suite we entered in
|
||||
"""
|
||||
|
||||
def escapeValue(self, value):
|
||||
if sys.version_info[0] <= 2 and isinstance(value, unicode):
|
||||
@@ -28,21 +36,27 @@ class TeamcityServiceMessages:
|
||||
|
||||
def testSuiteStarted(self, suiteName, location=None):
|
||||
self.message('testSuiteStarted', name=suiteName, locationHint=location)
|
||||
self.test_stack.append(suiteName)
|
||||
self.topmost_suite = suiteName
|
||||
|
||||
def testSuiteFinished(self, suiteName):
|
||||
self.message('testSuiteFinished', name=suiteName)
|
||||
self.__pop_current_test()
|
||||
|
||||
def testStarted(self, testName, location=None):
|
||||
self.message('testStarted', name=testName, locationHint=location)
|
||||
self.test_stack.append(testName)
|
||||
|
||||
|
||||
def testFinished(self, testName, duration=None):
|
||||
self.message('testFinished', name=testName, duration=duration)
|
||||
self.__pop_current_test()
|
||||
|
||||
|
||||
def testIgnored(self, testName, message=''):
|
||||
self.message('testIgnored', name=testName, message=message)
|
||||
self.testFinished(testName)
|
||||
|
||||
|
||||
def testFailed(self, testName, message='', details='', expected='', actual='', duration=None):
|
||||
"""
|
||||
Marks test as failed. *CAUTION*: This method calls ``testFinished``, so you do not need
|
||||
@@ -56,10 +70,24 @@ class TeamcityServiceMessages:
|
||||
self.message('testFailed', name=testName, message=message, details=details)
|
||||
self.testFinished(testName, int(duration) if duration else None)
|
||||
|
||||
|
||||
def __pop_current_test(self):
|
||||
try:
|
||||
self.test_stack.pop()
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
def testError(self, testName, message='', details='', duration=None):
|
||||
self.message('testFailed', name=testName, message=message, details=details, error="true")
|
||||
self.testFinished(testName, int(duration) if duration else None)
|
||||
|
||||
|
||||
def current_test_name(self):
|
||||
"""
|
||||
:return: name of current test we are in
|
||||
"""
|
||||
return self.test_stack[-1] if len(self.test_stack) > 0 else None
|
||||
|
||||
def testStdOut(self, testName, out):
|
||||
self.message('testStdOut', name=testName, out=out)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
import traceback, sys
|
||||
from unittest import TestResult
|
||||
import datetime
|
||||
@@ -37,13 +38,18 @@ def smart_str(s):
|
||||
|
||||
|
||||
class TeamcityTestResult(TestResult):
|
||||
"""
|
||||
Set ``_jb_do_not_call_enter_matrix`` to prevent it from runnig "enter matrix"
|
||||
"""
|
||||
|
||||
def __init__(self, stream=sys.stdout, *args, **kwargs):
|
||||
TestResult.__init__(self)
|
||||
for arg, value in kwargs.items():
|
||||
setattr(self, arg, value)
|
||||
self.output = stream
|
||||
self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True)
|
||||
self.messages.testMatrixEntered()
|
||||
if not "_jb_do_not_call_enter_matrix" in os.environ:
|
||||
self.messages.testMatrixEntered()
|
||||
self.current_failed = False
|
||||
self.current_suite = None
|
||||
self.subtest_suite = None
|
||||
|
||||
@@ -38,6 +38,8 @@ def loadSource(fileName):
|
||||
cnt += 1
|
||||
moduleName = getModuleName(prefix, cnt)
|
||||
debug("/ Loading " + fileName + " as " + moduleName)
|
||||
if os.path.isdir(fileName):
|
||||
fileName = fileName + os.path.sep
|
||||
module = imp.load_source(moduleName, fileName)
|
||||
modules[moduleName] = module
|
||||
return module
|
||||
@@ -56,17 +58,15 @@ def walkModules(modulesAndPattern, dirname, names):
|
||||
# For default pattern see https://docs.python.org/2/library/unittest.html#test-discovery
|
||||
def loadModulesFromFolderRec(folder, pattern="test*.py"):
|
||||
modules = []
|
||||
if PYTHON_VERSION_MAJOR == 3:
|
||||
# fnmatch converts glob to regexp
|
||||
prog_list = [re.compile(fnmatch.translate(pat.strip())) for pat in pattern.split(',')]
|
||||
for root, dirs, files in os.walk(folder):
|
||||
for name in files:
|
||||
for prog in prog_list:
|
||||
if name.endswith(".py") and prog.match(name):
|
||||
modules.append(loadSource(os.path.join(root, name)))
|
||||
else: # actually for jython compatibility
|
||||
os.path.walk(folder, walkModules, (modules, pattern))
|
||||
|
||||
# fnmatch converts glob to regexp
|
||||
prog_list = [re.compile(fnmatch.translate(pat.strip())) for pat in pattern.split(',')]
|
||||
for root, dirs, files in os.walk(folder):
|
||||
files = [f for f in files if not f[0] == '.']
|
||||
dirs[:] = [d for d in dirs if not d[0] == '.']
|
||||
for name in files:
|
||||
for prog in prog_list:
|
||||
if name.endswith(".py") and prog.match(name):
|
||||
modules.append(loadSource(os.path.join(root, name)))
|
||||
return modules
|
||||
|
||||
testLoader = TestLoader()
|
||||
@@ -109,11 +109,11 @@ if __name__ == "__main__":
|
||||
a_splitted = a[0].split("_args_separator_") # ";" can't be used with bash, so we use "_args_separator_"
|
||||
if len(a_splitted) != 1:
|
||||
# means we have pattern to match against
|
||||
if a_splitted[0].endswith(os.path.sep):
|
||||
if os.path.isdir(a_splitted[0]):
|
||||
debug("/ from folder " + a_splitted[0] + ". Use pattern: " + a_splitted[1])
|
||||
modules = loadModulesFromFolderRec(a_splitted[0], a_splitted[1])
|
||||
else:
|
||||
if a[0].endswith(os.path.sep):
|
||||
if os.path.isdir(a[0]):
|
||||
debug("/ from folder " + a[0])
|
||||
modules = loadModulesFromFolderRec(a[0])
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user