package jetbrains.mps.lang.test.runtime;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.awt.datatransfer.StringSelection;
import jetbrains.mps.tool.environment.Environment;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.project.Project;
import java.lang.reflect.InvocationTargetException;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.ide.ThreadUtils;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.model.SModelReference;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import junit.framework.Assert;
import jetbrains.mps.util.MacrosFactory;
import java.io.File;
import org.apache.log4j.Level;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.project.ProjectManager;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.module.ReloadableModule;
import java.awt.GraphicsEnvironment;
import java.awt.datatransfer.Clipboard;
import java.awt.Toolkit;
import jetbrains.mps.project.PathMacrosProvider;
import java.util.Map;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.internal.collections.runtime.IMapping;
import jetbrains.mps.core.tool.environment.util.CanonicalPath;
import jetbrains.mps.core.tool.environment.util.MapPathMacrosProvider;
import jetbrains.mps.project.PathMacros;
public class TransformationTestRunner implements TestRunner {
private static final Logger LOG = LogManager.getLogger(TransformationTestRunner.class);
private static final String PATH_MACRO_PREFIX = "path.macro.";
private static final StringSelection EMPTY_CLIPBOARD_CONTENT = new StringSelection("");
private final Environment myEnvironment;
public TransformationTestRunner(@NotNull Environment environment) {
myEnvironment = environment;
}
public void initTest(@NotNull final TransformationTest test, @NotNull String projectPath, String modelName) throws Exception {
initTest(test, projectPath, modelName, false);
}
public void initTest(@NotNull final TransformationTest test, @NotNull String projectPath, String modelName, boolean reopenProject) throws Exception {
clearSystemClipboard();
readSystemMacro();
final Project testProject = openTestProject(projectPath, reopenProject);
doInitTest(test, testProject, modelName);
myEnvironment.flushAllEvents();
}
protected void doInitTest(@NotNull final TransformationTest test, @NotNull final Project testProject, final String modelName) throws InterruptedException, InvocationTargetException {
if (LOG.isInfoEnabled()) {
LOG.info("Initializing the test");
}
test.setProject(testProject);
TestModelSaver modelSaver = BaseTransformationTest.CACHE;
TransformationTest cachedTest = modelSaver.getTest();
SModel cachedModel = check_ovzmet_a0f0l(cachedTest);
SModel cachedTransientModel = check_ovzmet_a0g0l(cachedTest);
String cachedModelName = check_ovzmet_a0h0l(check_ovzmet_a0a7a11(cachedModel));
if (cachedModelName != null && cachedModelName.equals(modelName)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Using the cached model");
}
test.setModelDescriptor(cachedModel);
test.setTransientModelDescriptor(cachedTransientModel);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Recaching the model again");
}
Exception exception = ThreadUtils.runInUIThreadAndWait(new Runnable() {
public void run() {
testProject.getModelAccess().executeCommand(new Runnable() {
@Override
public void run() {
initialize(test, modelName);
}
private void initialize(final TransformationTest test, final String modelName) {
SModel modelDescriptor = findModel(testProject.getRepository(), modelName);
test.setModelDescriptor(modelDescriptor);
test.init();
}
});
}
});
if (exception != null) {
throw new RuntimeException(exception);
}
modelSaver.clean();
modelSaver.setTest(test);
}
}
/*package*/ SModel findModel(SRepository repo, String modelName) {
// method expects model read, otherwise why SModel as return value
SModelReference modelRef = PersistenceFacade.getInstance().createModelReference(modelName);
SModel modelDescriptor = modelRef.resolve(repo);
if (modelDescriptor == null) {
Assert.fail(String.format("Can't find model %s in supplied repository %s.", modelName, repo));
}
return modelDescriptor;
}
protected Project openTestProject(String projectPathName, boolean reopenProject) {
String expandedProjectPath = MacrosFactory.getGlobal().expandPath(projectPathName);
File projectToOpen = new File(expandedProjectPath);
if ((expandedProjectPath == null || expandedProjectPath.length() == 0)) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Project path is empty");
}
Project openedProject = anyOpenedProject();
if (reopenProject) {
openedProject.dispose();
}
} else {
if (reopenProject) {
Project openedProject = myEnvironment.openProject(projectToOpen);
openedProject.dispose();
}
}
return myEnvironment.openProject(projectToOpen);
}
/**
* hacky place to run transformation tests with cached project
*/
private Project anyOpenedProject() {
for (Project project : ListSequence.fromList(ProjectManager.getInstance().getOpenedProjects())) {
if (project != null && !(project.isDisposed())) {
return project;
}
}
Assert.fail("MPS Project was not specified in the test class, no opened project was found.");
return null;
}
public void runTest(@NotNull final TransformationTest projectTest, final String className, final String methodName, boolean runInCommand) throws Throwable {
if (LOG.isInfoEnabled()) {
LOG.info("Running the test " + methodName);
}
final Wrappers._T<Class> clazz = new Wrappers._T<Class>();
final Throwable[] error = new Throwable[1];
projectTest.getProject().getModelAccess().runReadAction(new Runnable() {
public void run() {
final SModule module = projectTest.getModelDescriptor().getModule();
if (!(module instanceof ReloadableModule)) {
error[0] = new IllegalArgumentException("module" + module + " is not reloadable -- cannot run tests in it");
return;
}
try {
clazz.value = ((ReloadableModule) module).getOwnClass(className);
} catch (Throwable t) {
error[0] = t;
}
}
});
if (error[0] != null) {
throw error[0];
}
final Object obj = clazz.value.newInstance();
clazz.value.getField("myModel").set(obj, projectTest.getTransientModelDescriptor());
clazz.value.getField("myProject").set(obj, projectTest.getProject());
if (runInCommand) {
ThreadUtils.runInUIThreadAndWait(new Runnable() {
public void run() {
projectTest.getProject().getModelAccess().executeCommand(new Runnable() {
public void run() {
error[0] = TransformationTestRunner.this.tryToRunTest(clazz.value, methodName, obj);
}
});
}
});
myEnvironment.flushAllEvents();
} else {
error[0] = TransformationTestRunner.this.tryToRunTest(clazz.value, methodName, obj);
}
if (error[0] != null) {
if (LOG.isInfoEnabled()) {
LOG.info("Test failed");
}
throw error[0];
}
if (LOG.isInfoEnabled()) {
LOG.info("Test passed");
}
}
private static void clearSystemClipboard() {
if (GraphicsEnvironment.isHeadless()) {
return;
}
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(EMPTY_CLIPBOARD_CONTENT, EMPTY_CLIPBOARD_CONTENT);
}
/**
* to enable such macros as ${charisma}; see MPS-10568
*/
private static PathMacrosProvider readSystemMacro() {
final Map<String, String> macros = MapSequence.fromMap(new HashMap<String, String>());
for (IMapping<Object, Object> property : MapSequence.fromMap(System.getProperties())) {
if (property.key() instanceof String && property.value() instanceof String) {
String key = (String) property.key();
String value = (String) property.value();
if ((key != null && key.length() > 0) && key.startsWith(PATH_MACRO_PREFIX)) {
CanonicalPath path = new CanonicalPath(value);
if (path.isValidDirectory()) {
MapSequence.fromMap(macros).put(key.substring(PATH_MACRO_PREFIX.length()), path.getValue());
}
}
}
}
MapPathMacrosProvider provider = new MapPathMacrosProvider(macros);
PathMacros.getInstance().addMacrosProvider(provider);
return provider;
}
private Throwable tryToRunTest(Class clazz, String methodName, Object obj) {
Throwable exception = null;
try {
clazz.getMethod(methodName).invoke(obj);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
exception = e.getTargetException();
}
return exception;
}
private static SModel check_ovzmet_a0f0l(TransformationTest checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getModelDescriptor();
}
return null;
}
private static SModel check_ovzmet_a0g0l(TransformationTest checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getTransientModelDescriptor();
}
return null;
}
private static String check_ovzmet_a0h0l(SModelReference checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.toString();
}
return null;
}
private static SModelReference check_ovzmet_a0a7a11(SModel checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getReference();
}
return null;
}
}