From 38ec3267afdbb87e946d374882bd87c54c44bb59 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Wed, 29 Jun 2016 19:17:03 +0300 Subject: [PATCH] PY-18538 Do not pass tox folder to test runners by default (user may pass custom folder) Runner shall use current folder if no folder provided, or use one provided by user --- python/helpers/pycharm/_jb_tox_runner.py | 18 +++-- python/helpers/pycharm/utrunner.py | 3 + python/testData/toxtest/toxDoubleRun/setup.py | 14 ++++ .../toxDoubleRun/test/unit/__init__.py | 1 + .../test/unit/test_single_test.py | 5 ++ python/testData/toxtest/toxDoubleRun/tox.ini | 10 +++ .../testSrc/com/jetbrains/env/PyToxTest.java | 69 ++++++++++++------- 7 files changed, 84 insertions(+), 36 deletions(-) create mode 100644 python/testData/toxtest/toxDoubleRun/setup.py create mode 100644 python/testData/toxtest/toxDoubleRun/test/unit/__init__.py create mode 100644 python/testData/toxtest/toxDoubleRun/test/unit/test_single_test.py create mode 100644 python/testData/toxtest/toxDoubleRun/tox.ini diff --git a/python/helpers/pycharm/_jb_tox_runner.py b/python/helpers/pycharm/_jb_tox_runner.py index 2b82041edb79..57abbc16596e 100644 --- a/python/helpers/pycharm/_jb_tox_runner.py +++ b/python/helpers/pycharm/_jb_tox_runner.py @@ -81,27 +81,26 @@ class _MySession(tox_session.Session): class _Unit2(object): - def fix(self, command, dir_to_run, bin): + def fix(self, command, bin): if command[0] == "unit2": - return [bin, os.path.join(helpers_dir, "utrunner.py"), dir_to_run] + command[1:] + ["true"] + return [bin, os.path.join(helpers_dir, "utrunner.py")] + command[1:] + ["true"] elif command == ["python", "-m", "unittest", "discover"]: - return [bin, os.path.join(helpers_dir, "utrunner.py"), dir_to_run, "true"] + return [bin, os.path.join(helpers_dir, "utrunner.py"), "true"] return None class _PyTest(object): - def fix(self, command, dir_to_run, bin): + def fix(self, command, bin): if command[0] != "py.test": return None - normal_path = os.path.normpath(dir_to_run) + os.sep - return [bin, os.path.join(helpers_dir, "pytestrunner.py"), "-p", "pytest_teamcity", normal_path] + command[1:] + return [bin, os.path.join(helpers_dir, "pytestrunner.py"), "-p", "pytest_teamcity"] + command[1:] class _Nose(object): - def fix(self, command, dir_to_run, bin): + def fix(self, command, bin): if command[0] != "nosetests": return None - return [bin, os.path.join(helpers_dir, "noserunner.py"), dir_to_run] + command[1:] + return [bin, os.path.join(helpers_dir, "noserunner.py")] + command[1:] _RUNNERS = [_Unit2(), _PyTest(), _Nose()] @@ -116,10 +115,9 @@ for env, tmp_config in config.envconfigs.items(): continue for fixer in _RUNNERS: _env = config.envconfigs[env] - dir_to_run = str(_env.changedir) for i, command in enumerate(commands): if command: - fixed_command = fixer.fix(command, dir_to_run, str(_env.envpython)) + fixed_command = fixer.fix(command, str(_env.envpython)) if fixed_command: commands[i] = fixed_command tmp_config.commands = commands diff --git a/python/helpers/pycharm/utrunner.py b/python/helpers/pycharm/utrunner.py index 180dada8d602..f387e2c824d4 100644 --- a/python/helpers/pycharm/utrunner.py +++ b/python/helpers/pycharm/utrunner.py @@ -122,6 +122,9 @@ if __name__ == "__main__": all = unittest.TestSuite() pure_unittest = True + if len(sys.argv) == 2: # If folder not provided, we need pretend folder is current + sys.argv.insert(1, ".") + options = {} for arg in sys.argv[1:-1]: arg = arg.strip() diff --git a/python/testData/toxtest/toxDoubleRun/setup.py b/python/testData/toxtest/toxDoubleRun/setup.py new file mode 100644 index 000000000000..9b877e657e2a --- /dev/null +++ b/python/testData/toxtest/toxDoubleRun/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/python + +import os + +from setuptools import setup +from setuptools import find_packages + +package = 'python_package_template' +setup_dir = os.path.dirname(os.path.abspath(__file__)) + +setup(name=package, + version="!", + include_package_data=True, + ) diff --git a/python/testData/toxtest/toxDoubleRun/test/unit/__init__.py b/python/testData/toxtest/toxDoubleRun/test/unit/__init__.py new file mode 100644 index 000000000000..3ccf298fdf6c --- /dev/null +++ b/python/testData/toxtest/toxDoubleRun/test/unit/__init__.py @@ -0,0 +1 @@ +__author__ = 'rpocase' diff --git a/python/testData/toxtest/toxDoubleRun/test/unit/test_single_test.py b/python/testData/toxtest/toxDoubleRun/test/unit/test_single_test.py new file mode 100644 index 000000000000..97c7c48803d0 --- /dev/null +++ b/python/testData/toxtest/toxDoubleRun/test/unit/test_single_test.py @@ -0,0 +1,5 @@ +from time import sleep + + +def test_empty_class(): + sleep(1) diff --git a/python/testData/toxtest/toxDoubleRun/tox.ini b/python/testData/toxtest/toxDoubleRun/tox.ini new file mode 100644 index 000000000000..f3f4cf26f680 --- /dev/null +++ b/python/testData/toxtest/toxDoubleRun/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py27 + + +[testenv] +commands =py.test test/unit + + +deps = pytest + diff --git a/python/testSrc/com/jetbrains/env/PyToxTest.java b/python/testSrc/com/jetbrains/env/PyToxTest.java index cf8eb44b615e..ab4fec20c309 100644 --- a/python/testSrc/com/jetbrains/env/PyToxTest.java +++ b/python/testSrc/com/jetbrains/env/PyToxTest.java @@ -29,7 +29,6 @@ import org.jetbrains.annotations.Nullable; import org.junit.Assert; import org.junit.Test; -import java.io.IOException; import java.util.*; /** @@ -46,7 +45,7 @@ public final class PyToxTest extends PyEnvTestCase { * Simply ensure tox runner works */ @Test - public void testToxSimpleRun() throws IOException { + public void testToxSimpleRun() { runPythonTest(new MyPyProcessWithConsoleTestTask("/toxtest/toxSimpleRun/", 2, new MyTestProcessRunner(), Arrays.asList( @@ -54,15 +53,15 @@ public final class PyToxTest extends PyEnvTestCase { Pair.create("py26", new InterpreterExpectations( "AttributeError: 'module' object has no attribute 'skip'", false)), Pair.create("py27", new InterpreterExpectations("", true)) - ) - )); + ), + Integer.MAX_VALUE)); } /** * Check tox nose runner */ @Test - public void testToxNose() throws IOException { + public void testToxNose() { runPythonTest(new MyPyProcessWithConsoleTestTask("/toxtest/toxNose/", 1, new MyTestProcessRunner(), Arrays.asList( @@ -71,8 +70,8 @@ public final class PyToxTest extends PyEnvTestCase { // Does not support 3.4 Pair.create("py32", new InterpreterExpectations("SyntaxError", false)), Pair.create("py34", new InterpreterExpectations("SyntaxError", false)) - ) - ) + ), + Integer.MAX_VALUE) ); } @@ -80,7 +79,7 @@ public final class PyToxTest extends PyEnvTestCase { * Check tox pytest runner */ @Test - public void testToxPyTest() throws IOException { + public void testToxPyTest() { runPythonTest(new MyPyProcessWithConsoleTestTask("/toxtest/toxPyTest/", 1, new MyTestProcessRunner(), Arrays.asList( @@ -89,8 +88,8 @@ public final class PyToxTest extends PyEnvTestCase { // Does not support 3.4 Pair.create("py32", new InterpreterExpectations("SyntaxError", false)), Pair.create("py34", new InterpreterExpectations("SyntaxError", false)) - ) - ) + ), + Integer.MAX_VALUE) ); } @@ -98,7 +97,7 @@ public final class PyToxTest extends PyEnvTestCase { * Check tox unit runner */ @Test - public void testToxUnitTest() throws IOException { + public void testToxUnitTest() { runPythonTest(new MyPyProcessWithConsoleTestTask("/toxtest/toxUnitTest/", 1, new MyTestProcessRunner(), Arrays.asList( @@ -107,8 +106,8 @@ public final class PyToxTest extends PyEnvTestCase { // Does not support 3.4 Pair.create("py32", new InterpreterExpectations("SyntaxError", false)), Pair.create("py34", new InterpreterExpectations("SyntaxError", false)) - ) - ) + ), + Integer.MAX_VALUE) ); } @@ -124,18 +123,31 @@ public final class PyToxTest extends PyEnvTestCase { Pair.create("py27", new InterpreterExpectations("ython 2.7", true)), Pair.create("py32", new InterpreterExpectations("", true)), Pair.create("py34", new InterpreterExpectations("", true)) - ) - ) + ), + Integer.MAX_VALUE) ); + } + /** + * Ensures test is not launched 2 times because folder added 2 times + */ + @Test + public void testDoubleRun() throws Exception { + runPythonTest(new MyPyProcessWithConsoleTestTask("/toxtest/toxDoubleRun/", 1, + new MyTestProcessRunner(), + Collections.singletonList( + Pair.create("py27", new InterpreterExpectations("", true)) + ), + 1) + ); } /** * Big test which should run on any interpreter and check its output */ @Test - public void testToxSuccessTest() throws IOException { + public void testToxSuccessTest() { runPythonTest(new MyPyProcessWithConsoleTestTask("/toxtest/toxSuccess/", 1, new MyTestProcessRunner(), Arrays.asList( @@ -144,8 +156,8 @@ public final class PyToxTest extends PyEnvTestCase { // Should have output Pair.create("py32", new InterpreterExpectations("I am 3.2", true)), Pair.create("py34", new InterpreterExpectations("I am 3.4", true)) - ) - ) + ), + Integer.MAX_VALUE) ); } @@ -154,20 +166,23 @@ public final class PyToxTest extends PyEnvTestCase { @NotNull private final Map myInterpreters = new HashMap<>(); private final int myMinimumSuccessTestCount; + private final int myMaximumSuccessTestCount; @NotNull private final MyTestProcessRunner myRunner; /** - * @param relativeTestDataPath TODO: DOC * @param minimumSuccessTestCount how many success tests should be * @param interpreterExpectations interpreter_name -] expected result + * @param maximumTestCount max number of success tests */ private MyPyProcessWithConsoleTestTask(@Nullable final String relativeTestDataPath, final int minimumSuccessTestCount, @NotNull final MyTestProcessRunner runner, - @NotNull final Collection> interpreterExpectations) { + @NotNull final Iterable> interpreterExpectations, + final int maximumTestCount) { super(relativeTestDataPath, SdkCreationType.EMPTY_SDK); myMinimumSuccessTestCount = minimumSuccessTestCount; + myMaximumSuccessTestCount = maximumTestCount; myRunner = runner; for (final Pair interpreterExpectation : interpreterExpectations) { myInterpreters.put(interpreterExpectation.first, interpreterExpectation.second); @@ -218,15 +233,20 @@ public final class PyToxTest extends PyEnvTestCase { if (interpreterSuite.getChildren().size() == 1 && interpreterSuite.getChildren().get(0).getName().endsWith("SKIP")) { // The only reason it may be skipped is it does not exist and skip_missing_interpreters = True final String output = getTestOutput(interpreterSuite); - Assert.assertThat("Test marked skipped but not because interpreter not found", output, Matchers.containsString("InterpreterNotFound")); + Assert.assertThat("Test marked skipped but not because interpreter not found", output, + Matchers.containsString("InterpreterNotFound")); } // Interpretr run success, //At least one interpreter tests should passed - Assert.assertThat(String.format("No test passed, should %s at least", myMinimumSuccessTestCount), - new SMRootTestsCounter(interpreterSuite.getRoot()).getPassedTestsCount(), + final int numberOfTests = new SMRootTestsCounter(interpreterSuite.getRoot()).getPassedTestsCount(); + Assert.assertThat(String.format("Not enough test passed, should %s at least", myMinimumSuccessTestCount), + numberOfTests, Matchers.greaterThanOrEqualTo(myMinimumSuccessTestCount)); + Assert.assertThat(String.format("Too many tests passed, should %s maximum", myMaximumSuccessTestCount), + numberOfTests, + Matchers.lessThanOrEqualTo(myMaximumSuccessTestCount)); // Check expected output final String message = String.format("Interpreter %s does not have expected string in output. \n ", interpreterName) + @@ -265,9 +285,6 @@ public final class PyToxTest extends PyEnvTestCase { } private static final class MyTestProcessRunner extends PyAbstractTestProcessRunner { - /** - * @param testPath testPath relative to community path - */ private MyTestProcessRunner() { super(PyToxConfigurationFactory.INSTANCE, PyToxConfiguration.class, 0); }