package jetbrains.mps.ide.vcs.test.merge;
/*Generated by MPS */
import jetbrains.mps.testbench.BaseMpsTest;
import java.util.regex.Pattern;
import jetbrains.mps.smodel.adapter.structure.concept.SConceptAdapterById;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.tool.environment.Environment;
import java.io.File;
import jetbrains.mps.util.FileUtil;
import jetbrains.mps.project.Project;
import org.jetbrains.mps.openapi.module.ModelAccess;
import org.jetbrains.mps.openapi.module.SRepository;
import jetbrains.mps.smodel.DefaultSModel;
import org.jetbrains.mps.openapi.persistence.StreamDataSource;
import com.intellij.openapi.ui.TestDialog;
import org.junit.BeforeClass;
import jetbrains.mps.tool.environment.IdeaEnvironment;
import jetbrains.mps.tool.environment.EnvironmentConfig;
import org.junit.Assert;
import org.junit.AfterClass;
import org.junit.Before;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.smodel.CopyUtil;
import jetbrains.mps.smodel.DefaultSModelDescriptor;
import jetbrains.mps.vcs.platform.integration.ModelStorageProblemsListener;
import org.junit.After;
import org.junit.Test;
import jetbrains.mps.project.Solution;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import org.jetbrains.mps.openapi.model.EditableSModel;
import jetbrains.mps.smodel.ModuleRepositoryFacade;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId;
import jetbrains.mps.util.Reference;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
import org.jetbrains.annotations.Nullable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.newvfs.RefreshSession;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import jetbrains.mps.smodel.persistence.def.ModelPersistence;
import java.io.IOException;
/**
*
* @author Evgeny Gerashchenko
* @since 3/23/11
*/
public class DiskMemoryConflictsTest extends BaseMpsTest {
private static Pattern FIELD_DECLARATION_CONCEPT_ENTRY_MATCHING_PATTERN = Pattern.compile("\\s*<concept id=\"" + ((SConceptAdapterById) MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca68L, "jetbrains.mps.baseLanguage.structure.FieldDeclaration")).getId().getIdValue() + "\"([^\\/]+)/>");
private static Pattern CONCEPT_INDEX_MATCHING_PATTERN = Pattern.compile(".*index=\"([^/]+)\".*");
private static Pattern PROPERTY_VALUE_MATCHING_PATTERN = Pattern.compile(".*<property.*value=\"([^\"]+)\".*");
private static Environment ENV;
private static final File DESTINATION_PROJECT_DIR = new File(FileUtil.getTempDir(), "testConflicts");
private static final File PROJECT_LOCATION = new File("testbench/modules/simpleProject");
private static final File MODEL_FILE = getModelFile();
private static final String FIELD_DEFAULT_NAME = "theField";
private static final String FIELD_NAME_IN_FILE = "theFieldInFile";
private static final String FIELD_NAME_IN_MODEL = "theFieldInModel";
private static Project ourProject;
private static ModelAccess ourModelAccess;
private static SRepository ourRepository;
private DefaultSModel myModelBackup;
private StreamDataSource myOriginalModelDataSource;
private DiskMemoryConflictsTest.TestDialogImpl myMockDialog = null;
private TestDialog myOriginalDialog;
public DiskMemoryConflictsTest() {
}
@BeforeClass
public static void setup() {
ENV = IdeaEnvironment.getOrCreate(EnvironmentConfig.defaultConfig().withVcsPlugin());
ourProject = BaseMpsTest.openClonedProject(PROJECT_LOCATION, DESTINATION_PROJECT_DIR);
ourModelAccess = ourProject.getModelAccess();
Assert.assertNotNull(ourModelAccess);
ourRepository = ourProject.getRepository();
Assert.assertNotNull(ourRepository);
}
@AfterClass
public static void tearDown() {
BaseMpsTest.closeClonedProject(ourProject, DESTINATION_PROJECT_DIR);
ENV.release();
}
@Before
public void beforeTest() {
ourModelAccess.runReadAction(new Runnable() {
public void run() {
SModel model = getModel();
myModelBackup = (DefaultSModel) CopyUtil.copyModel(((DefaultSModelDescriptor) model).getSModel());
myOriginalModelDataSource = (StreamDataSource) model.getSource();
}
});
Assert.assertNotNull(myModelBackup);
Assert.assertNotNull(myOriginalModelDataSource);
myOriginalDialog = ModelStorageProblemsListener.setTestDialog(myMockDialog = new DiskMemoryConflictsTest.TestDialogImpl());
}
@After
public void afterTest() {
ModelStorageProblemsListener.setTestDialog(myOriginalDialog);
myMockDialog = null;
restoreModel();
checkInitialState();
myModelBackup = null;
myOriginalModelDataSource = null;
}
@Test
public void modifyDisk_chooseMemory() {
setFieldNameInModel(FIELD_NAME_IN_MODEL);
setFieldNameInFile(FIELD_NAME_IN_FILE);
myMockDialog.waitForShow(1);
refreshVfs();
Assert.assertTrue(myMockDialog.wasExecuted());
checkSynchronizedState(FIELD_NAME_IN_MODEL);
}
@Test
public void modifyDisk_chooseDisk() {
setFieldNameInModel(FIELD_NAME_IN_MODEL);
setFieldNameInFile(FIELD_NAME_IN_FILE);
myMockDialog.waitForShow(0);
refreshVfs();
Assert.assertTrue(myMockDialog.wasExecuted());
checkSynchronizedState(FIELD_NAME_IN_FILE);
}
@Test
public void deleteDisk_chooseMemory() {
setFieldNameInModel(FIELD_NAME_IN_MODEL);
DiskMemoryConflictsTest.delete();
myMockDialog.waitForShow(0);
refreshVfs();
Assert.assertTrue(myMockDialog.wasExecuted());
checkSynchronizedState(FIELD_NAME_IN_MODEL);
}
@Test
public void deleteDisk_chooseDisk() {
setFieldNameInModel(FIELD_NAME_IN_MODEL);
DiskMemoryConflictsTest.delete();
myMockDialog.waitForShow(1);
refreshVfs();
Assert.assertTrue(myMockDialog.wasExecuted());
}
private Solution getSolution() {
return (Solution) PersistenceFacade.getInstance().createModuleReference("c0209407-bdbc-42e5-9368-04e272725dd0(simpleProject)").resolve(ourRepository);
}
private EditableSModel getModel() {
return (EditableSModel) new ModuleRepositoryFacade(ourRepository).getModelByName("simpleModel");
}
private SNode getField() {
SNode node = SNodeOperations.getNode("r:21cf9f47-5464-40f2-9509-d94ba20bfe82(simpleModel)", "6010389230754495463");
SNode theField = Sequence.fromIterable(((Iterable<SNode>) BHReflection.invoke(node, SMethodTrimmedId.create("fields", MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept"), "4_LVZ3pC27C")))).first();
return theField;
}
private String processFieldNameInModel(final String nameToWrite) {
final String[] result = new String[1];
final Reference<Throwable> refThrowable = new Reference<Throwable>();
ourModelAccess.executeCommandInEDT(new Runnable() {
@Override
public void run() {
try {
SNode theField = getField();
Assert.assertNotNull(theField);
if (nameToWrite == null) {
result[0] = SPropertyOperations.getString(theField, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"));
} else {
SPropertyOperations.set(theField, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"), nameToWrite);
}
} catch (Throwable t) {
refThrowable.set(t);
}
}
});
DiskMemoryConflictsTest.waitEDT();
if (!(refThrowable.isNull())) {
throw new RuntimeException(refThrowable.get());
}
return result[0];
}
private void setFieldNameInModel(String value) {
processFieldNameInModel(value);
}
private String getFieldNameFromModel() {
return processFieldNameInModel(null);
}
private String processFieldNameInFile(final String nameToWrite) {
// File stuff
if (!(DiskMemoryConflictsTest.MODEL_FILE.exists())) {
return null;
}
List<String> lines = new ArrayList<String>();
try {
Scanner scanner = new Scanner(DiskMemoryConflictsTest.MODEL_FILE);
boolean fieldFound = false;
boolean nameFound = false;
Pattern fieldStartPattern = null;
try {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (fieldStartPattern == null) {
fieldStartPattern = parseFieldStartPattern(line);
} else if (!(fieldFound)) {
fieldFound = fieldStartPattern.matcher(line).matches();
} else if (!(nameFound)) {
Matcher matcher = PROPERTY_VALUE_MATCHING_PATTERN.matcher(line);
if (matcher.matches()) {
nameFound = true;
String fieldName = matcher.group(1);
if (nameToWrite == null) {
return fieldName;
}
line = line.replace(fieldName, nameToWrite);
}
}
lines.add(line);
}
} finally {
scanner.close();
}
long lastModifiedBefore = DiskMemoryConflictsTest.MODEL_FILE.lastModified();
PrintWriter w = new PrintWriter(DiskMemoryConflictsTest.MODEL_FILE);
for (String line : lines) {
w.println(line);
}
w.close();
if (DiskMemoryConflictsTest.MODEL_FILE.lastModified() == lastModifiedBefore) {
DiskMemoryConflictsTest.setLastModified(lastModifiedBefore + 1000);
}
DiskMemoryConflictsTest.setLastModified(lastModifiedBefore + 2000 + (int) (Math.random() * 100000));
} catch (FileNotFoundException e) {
Assert.fail();
}
return null;
}
private Pattern parseFieldStartPattern(String line) {
Matcher matcher = FIELD_DECLARATION_CONCEPT_ENTRY_MATCHING_PATTERN.matcher(line);
if (matcher.matches()) {
String conceptEntryContent = matcher.group(1);
Matcher conceptIndexMatcher = CONCEPT_INDEX_MATCHING_PATTERN.matcher(conceptEntryContent);
if (conceptIndexMatcher.matches()) {
String fdConceptIndex = conceptIndexMatcher.group(1);
return Pattern.compile(".*<node.*concept=\"" + fdConceptIndex + "\".*");
}
}
return null;
}
private String getFieldNameFromFile() {
return processFieldNameInFile(null);
}
private void setFieldNameInFile(String name) {
processFieldNameInFile(name);
}
private void checkInitialState() {
checkSynchronizedState(DiskMemoryConflictsTest.FIELD_DEFAULT_NAME);
}
private void checkSynchronizedState(@Nullable final String fieldName) {
Assert.assertEquals(fieldName, getFieldNameFromModel());
Assert.assertEquals(fieldName, getFieldNameFromFile());
final Reference<Throwable> refThrowable = new Reference<Throwable>();
ourModelAccess.runReadAction(new Runnable() {
public void run() {
try {
EditableSModel model = getModel();
if (fieldName == null) {
Assert.assertNull(model);
} else {
Assert.assertFalse(model.isChanged());
}
} catch (Throwable t) {
refThrowable.set(t);
}
}
});
if (!(refThrowable.isNull())) {
throw new RuntimeException(refThrowable.get());
}
}
private void refreshVfs() {
// AP: simple IFile#refresh will do, won't it?
VirtualFile vf = LocalFileSystem.getInstance().findFileByIoFile(DiskMemoryConflictsTest.MODEL_FILE);
if (vf == null || !(vf.exists())) {
vf = LocalFileSystem.getInstance().findFileByIoFile(DiskMemoryConflictsTest.MODEL_FILE.getParentFile());
}
RefreshSession rs = RefreshQueue.getInstance().createSession(false, true, null);
assert vf != null;
rs.addFile(vf);
rs.launch();
waitEDT();
}
private void restoreModel() {
final Reference<Throwable> refThrowable = new Reference<Throwable>();
// Restore model
ourModelAccess.executeCommandInEDT(new Runnable() {
@Override
public void run() {
try {
try {
ModelPersistence.saveModel(myModelBackup, myOriginalModelDataSource, myModelBackup.getSModelHeader().getPersistenceVersion());
} catch (IOException e) {
e.printStackTrace();
Assert.fail();
}
getSolution().updateModelsSet();
getModel().reloadFromSource();
} catch (Throwable t) {
refThrowable.set(t);
}
}
});
waitEDT();
if (!(refThrowable.isNull())) {
throw new RuntimeException(refThrowable.get());
}
}
private static File getModelFile() {
File modelFile = new File(DiskMemoryConflictsTest.DESTINATION_PROJECT_DIR, "solutions/simpleProject/simpleModel.mps");
try {
return modelFile.getCanonicalFile();
} catch (IOException ex) {
ex.printStackTrace();
}
return modelFile;
}
private static void setLastModified(long timeStamp) {
if (!(MODEL_FILE.setLastModified(timeStamp))) {
Assert.fail();
}
}
private static void delete() {
if (!(MODEL_FILE.delete())) {
Assert.fail();
}
}
private static void waitEDT() {
BaseMpsTest.getEnvironment().flushAllEvents();
}
private class TestDialogImpl implements TestDialog {
private boolean myExecuted;
private int myReturnValue;
public int show(String string) {
assert !(myExecuted);
myExecuted = true;
return myReturnValue;
}
public boolean wasExecuted() {
return myExecuted;
}
public void waitForShow(int nextShowValue) {
myReturnValue = nextShowValue;
myExecuted = false;
}
}
}