From e69def370cb323bfa35d028ff752253de92ed5e8 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 31 May 2016 00:38:15 +0300 Subject: [PATCH] Sandbox added for PyEnvTestCase * Tox tests produce too many files, it is better to store them in separate folder * ``_PYCHARM_FAST_SANDBOX`` (See changes) points to RAM disk in my box, and it increases speed --- .../com/jetbrains/env/PyEnvTestCase.java | 60 +++++++++++++++++-- .../testSrc/com/jetbrains/env/PyToxTest.java | 28 +++++---- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/python/testSrc/com/jetbrains/env/PyEnvTestCase.java b/python/testSrc/com/jetbrains/env/PyEnvTestCase.java index f9017ae808e2..72a46a20e7e4 100644 --- a/python/testSrc/com/jetbrains/env/PyEnvTestCase.java +++ b/python/testSrc/com/jetbrains/env/PyEnvTestCase.java @@ -18,16 +18,14 @@ import com.jetbrains.python.packaging.PyPackageManager; import org.hamcrest.Matchers; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.junit.Assert; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Rule; +import org.junit.*; import org.junit.rules.TestName; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -72,6 +70,10 @@ public abstract class PyEnvTestCase { myStaging = isStaging(description); } }; + /** + * See {@link #configureSandbox()} + */ + private File mySandboxRoot; protected boolean isStaging(Description description) { try { @@ -124,8 +126,42 @@ public abstract class PyEnvTestCase { Matchers.hasItems(myRequiredTags) ); } + configureSandbox(); } + @After + public void tearDown() throws Exception { + if (mySandboxRoot != null && mySandboxRoot.exists()) { + FileUtil.delete(mySandboxRoot); + } + } + + /** + * Creates sandbox folder which may be used by tests by calling {@link #wrapPathWithSandbox(String)}. + * Files are copied there and dropped after all. + * If
_PYCHARM_FAST_SANDBOX
env var is set, it uses this folder to create sandbox (good idea to use RAM disk). + * If not set, temp folder is used. + */ + private void configureSandbox() throws IOException { + final String sandboxRootPath = System.getenv().get("_PYCHARM_FAST_SANDBOX"); + if (sandboxRootPath != null) { + LOG.info(String.format("_PYCHARM_FAST_SANDBOX points to %s", sandboxRootPath)); + mySandboxRoot = new File(sandboxRootPath); + final File[] array = mySandboxRoot.listFiles(); + if (array != null) { + LOG.info(String.format("Flushing %s", mySandboxRoot)); + Arrays.stream(array).forEach(FileUtil::delete); + } + } + else { + LOG.info("No _PYCHARM_FAST_SANDBOX set"); + mySandboxRoot = FileUtil.createTempDirectory("PyEnvText", null, true); + } + mySandboxRoot.deleteOnExit(); + LOG.info(String.format("Sandbox is %s", mySandboxRoot.getAbsolutePath())); + } + + /** * @return all tags available between all interpreters */ @@ -151,6 +187,22 @@ public abstract class PyEnvTestCase { } } + + /** + * Copies files to sandbox which will be deleted after test. + * @param path source + * @return sandbox + */ + final String wrapPathWithSandbox(@NotNull final String path) throws IOException { + final File pathFile = new File(path); + assert pathFile.exists() : String.format("File %s does not exist", pathFile); + final File folderInSandbox = new File(mySandboxRoot, Long.toString(System.currentTimeMillis())); + assert folderInSandbox.mkdir() : "Failed to create " + folderInSandbox; + FileUtil.copyDir(pathFile, folderInSandbox, pathname -> !pathname.getName().endsWith(".pyc")); + return folderInSandbox.getAbsolutePath(); + } + + protected boolean runInDispatchThread() { return false; } diff --git a/python/testSrc/com/jetbrains/env/PyToxTest.java b/python/testSrc/com/jetbrains/env/PyToxTest.java index 1e46e5c52290..53a927d62634 100644 --- a/python/testSrc/com/jetbrains/env/PyToxTest.java +++ b/python/testSrc/com/jetbrains/env/PyToxTest.java @@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull; import org.junit.Assert; import org.junit.Test; +import java.io.IOException; import java.util.*; /** @@ -46,9 +47,10 @@ public final class PyToxTest extends PyEnvTestCase { * Simply ensure tox runner works */ @Test - public void testToxSimpleRun() { + public void testToxSimpleRun() throws IOException { runPythonTest(new MyPyProcessWithConsoleTestTask(2, - new MyTestProcessRunner("/testData/toxtest/toxSimpleRun/"), + new MyTestProcessRunner(wrapPathWithSandbox( + PythonHelpersLocator.getPythonCommunityPath() + "/testData/toxtest/toxSimpleRun/")), Arrays.asList( // Should fail, no skip in 26 Pair.create("py26", new InterpreterExpectations( @@ -63,9 +65,10 @@ public final class PyToxTest extends PyEnvTestCase { */ @Test @StagingOn(os = TestEnv.WINDOWS) - public void testToxNose() { + public void testToxNose() throws IOException { runPythonTest(new MyPyProcessWithConsoleTestTask(1, - new MyTestProcessRunner("/testData/toxtest/toxNose/"), + new MyTestProcessRunner(wrapPathWithSandbox( + PythonHelpersLocator.getPythonCommunityPath() + "/testData/toxtest/toxNose/")), Arrays.asList( Pair.create("py26", new InterpreterExpectations("", true)), Pair.create("py27", new InterpreterExpectations("", true)), @@ -82,9 +85,10 @@ public final class PyToxTest extends PyEnvTestCase { */ @Test @StagingOn(os = TestEnv.WINDOWS) - public void testToxPyTest() { + public void testToxPyTest() throws IOException { runPythonTest(new MyPyProcessWithConsoleTestTask(1, - new MyTestProcessRunner("/testData/toxtest/toxPyTest/"), + new MyTestProcessRunner(wrapPathWithSandbox( + PythonHelpersLocator.getPythonCommunityPath() + "/testData/toxtest/toxPyTest/")), Arrays.asList( Pair.create("py26", new InterpreterExpectations("", true)), Pair.create("py27", new InterpreterExpectations("", true)), @@ -101,9 +105,10 @@ public final class PyToxTest extends PyEnvTestCase { */ @Test @StagingOn(os = TestEnv.WINDOWS) - public void testToxUnitTest() { + public void testToxUnitTest() throws IOException { runPythonTest(new MyPyProcessWithConsoleTestTask(1, - new MyTestProcessRunner("/testData/toxtest/toxUnitTest/"), + new MyTestProcessRunner(wrapPathWithSandbox( + PythonHelpersLocator.getPythonCommunityPath() + "/testData/toxtest/toxUnitTest/")), Arrays.asList( Pair.create("py26", new InterpreterExpectations("", true)), Pair.create("py27", new InterpreterExpectations("", true)), @@ -120,9 +125,10 @@ public final class PyToxTest extends PyEnvTestCase { */ @Test @StagingOn(os = TestEnv.WINDOWS) - public void testToxSuccessTest() { + public void testToxSuccessTest() throws IOException { runPythonTest(new MyPyProcessWithConsoleTestTask(1, - new MyTestProcessRunner("/testData/toxtest/toxSuccess/"), + new MyTestProcessRunner(wrapPathWithSandbox( + PythonHelpersLocator.getPythonCommunityPath() + "/testData/toxtest/toxSuccess/")), Arrays.asList( Pair.create("py26", new InterpreterExpectations("I am 2.6", true)), Pair.create("py27", new InterpreterExpectations("I am 2.7", true)), @@ -245,7 +251,7 @@ public final class PyToxTest extends PyEnvTestCase { */ private MyTestProcessRunner(@NotNull final String testPath) { super(PyToxConfigurationFactory.INSTANCE, PyToxConfiguration.class, - PythonHelpersLocator.getPythonCommunityPath() + testPath, 0); + testPath, 0); } }