blob: 853a5504de63d3fc102758c295c032d0e4adc823 [file] [log] [blame]
package com.jetbrains.env;
import com.google.common.collect.Lists;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.util.SystemProperties;
import com.intellij.util.ui.UIUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import org.hamcrest.Matchers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Assume;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
/**
* @author traff
*/
public abstract class PyEnvTestCase extends UsefulTestCase {
private static final Logger LOG = Logger.getInstance(PyEnvTestCase.class.getName());
private static final String TAGS_FILE = "tags.txt";
private static final String PYCHARM_PYTHON_ENVS = "PYCHARM_PYTHON_ENVS";
private static final String PYCHARM_PYTHON_VIRTUAL_ENVS = "PYCHARM_PYTHON_VIRTUAL_ENVS";
protected static final boolean IS_ENV_CONFIGURATION = System.getProperty("pycharm.env") != null;
public static final boolean RUN_REMOTE = SystemProperties.getBooleanProperty("pycharm.run_remote", false);
public static final boolean RUN_LOCAL = SystemProperties.getBooleanProperty("pycharm.run_local", true);
/**
* Tags that should exist between all tags, available on all interpreters for test to run.
* See {@link #PyEnvTestCase(String...)}
*/
@Nullable
private final String[] myRequiredTags;
/**
* @param requiredTags tags that should exist on some interpreter for this test to run.
* if some of these tags do not exist on any interpreter, all test methods would be skipped using
* {@link org.junit.Assume}.
* See <a href="http://junit.sourceforge.net/javadoc/org/junit/Assume.html">Assume manual</a>.
* Check [IDEA-122939] and [TW-25043] as well.
*/
@SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
protected PyEnvTestCase(@NotNull final String... requiredTags) {
myRequiredTags = requiredTags.length > 0 ? requiredTags.clone() : null;
PyTestCase.initPlatformPrefix();
}
@Override
public void setUp() throws Exception {
super.setUp();
if (myRequiredTags != null) { // Ensure all tags exist between available interpreters
Assume.assumeThat(
"Can't find some tags between all available interpreter, test (all methods) will be skipped",
getAvailableTags(),
Matchers.hasItems(myRequiredTags)
);
}
}
/**
* @return all tags available between all interpreters
*/
@NotNull
private static Collection<String> getAvailableTags() {
final Collection<String> allAvailableTags = new HashSet<String>();
for (final String pythonRoot : getPythonRoots()) {
allAvailableTags.addAll(loadEnvTags(pythonRoot));
}
return allAvailableTags;
}
@Override
protected void invokeTestRunnable(@NotNull final Runnable runnable) throws Exception {
if (runInWriteAction()) {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
public void run() {
ApplicationManager.getApplication().runWriteAction(runnable);
}
});
}
else {
runnable.run();
}
}
@Override
protected boolean runInDispatchThread() {
return false;
}
protected boolean runInWriteAction() {
return false;
}
public void runPythonTest(final PyTestTask testTask) {
runTest(testTask, getTestName(false));
}
public void runTest(@NotNull PyTestTask testTask, @NotNull String testName) {
if (notEnvConfiguration()) {
fail("Running under teamcity but not by Env configuration. Skipping.");
return;
}
List<String> roots = getPythonRoots();
if (roots.size() == 0) {
String msg = testName +
": environments are not defined. Skipping. \nSpecify either " +
PYCHARM_PYTHON_ENVS +
" or " +
PYCHARM_PYTHON_VIRTUAL_ENVS +
" environment variable.";
LOG.warn(msg);
System.out.println(msg);
return;
}
doRunTests(testTask, testName, roots);
}
protected void doRunTests(PyTestTask testTask, String testName, List<String> roots) {
if (RUN_LOCAL) {
PyEnvTaskRunner taskRunner = new PyEnvTaskRunner(roots);
taskRunner.runTask(testTask, testName);
}
}
public static boolean notEnvConfiguration() {
return UsefulTestCase.IS_UNDER_TEAMCITY && !IS_ENV_CONFIGURATION;
}
public static List<String> getPythonRoots() {
List<String> roots = Lists.newArrayList();
String envs = System.getenv(PYCHARM_PYTHON_ENVS);
if (envs != null) {
roots.addAll(Lists.newArrayList(envs.split(File.pathSeparator)));
}
String virtualEnvs = System.getenv(PYCHARM_PYTHON_VIRTUAL_ENVS);
if (virtualEnvs != null) {
roots.addAll(readVirtualEnvRoots(virtualEnvs));
}
return roots;
}
protected static List<String> readVirtualEnvRoots(@NotNull String envs) {
List<String> result = Lists.newArrayList();
String[] roots = envs.split(File.pathSeparator);
for (String root : roots) {
File virtualEnvRoot = new File(root);
File[] virtualenvs = virtualEnvRoot.listFiles();
if (virtualenvs != null) {
for (File f : virtualenvs) {
result.add(f.getAbsolutePath());
}
} else {
LOG.error(root + " is not a directory of doesn't exist");
}
}
return result;
}
public static List<String> loadEnvTags(String env) {
List<String> envTags;
try {
File parent = new File(env);
if (parent.isFile()) {
parent = parent.getParentFile();
}
envTags = com.intellij.openapi.util.io.FileUtil.loadLines(new File(parent, TAGS_FILE));
}
catch (IOException e) {
envTags = Lists.newArrayList();
}
return envTags;
}
public static String joinStrings(Collection<String> roots, String rootsName) {
return roots.size() > 0 ? rootsName + StringUtil.join(roots, ", ") + "\n" : "";
}
}