package tests.testPersistence.test;
/*Generated by MPS */
import jetbrains.mps.MPSLaunch;
import jetbrains.mps.lang.test.runtime.BaseTransformationTest;
import org.junit.Test;
import jetbrains.mps.lang.test.runtime.BaseTestBody;
import jetbrains.mps.persistence.PersistenceUtil;
import jetbrains.mps.smodel.persistence.def.ModelPersistence;
import java.io.ByteArrayInputStream;
import jetbrains.mps.util.FileUtil;
import java.io.IOException;
import junit.framework.Assert;
import jetbrains.mps.smodel.adapter.structure.concept.SConceptAdapterById;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.java.stub.JavaPackageNameStub;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import jetbrains.mps.smodel.SNodeId;
import jetbrains.mps.smodel.SNodePointer;
import java.io.InputStream;
import jetbrains.mps.smodel.loading.ModelLoadResult;
import jetbrains.mps.smodel.SModelHeader;
import jetbrains.mps.persistence.ByteArrayInputSource;
import jetbrains.mps.smodel.loading.ModelLoadingState;
import jetbrains.mps.extapi.model.SModelBase;
import jetbrains.mps.smodel.SModel;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.HashMap;
import java.util.List;
import jetbrains.mps.smodel.ImplicitImportsLegacyHolder;
import java.util.Comparator;
import java.util.Set;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import java.util.HashSet;
import jetbrains.mps.util.IterableUtil;
import java.util.Iterator;
import jetbrains.mps.util.SNodeOperations;
import java.util.Map;
import org.jetbrains.mps.openapi.model.SReference;
import org.jetbrains.mps.openapi.model.SModelReference;
import java.util.ArrayList;
import java.util.Collections;
@MPSLaunch
public class TestPersistence_Test extends BaseTransformationTest {
@Test
public void test_testLastVersionIndexing() throws Throwable {
initTest("${mps_home}", "r:8ef4c1fc-fb61-4d5c-806c-7a971cfb9392(tests.testPersistence.test@tests)", false);
runTest("tests.testPersistence.test.TestPersistence_Test$TestBody", "test_testLastVersionIndexing", true);
}
@Test
public void test_testPersistenceReadWrite() throws Throwable {
initTest("${mps_home}", "r:8ef4c1fc-fb61-4d5c-806c-7a971cfb9392(tests.testPersistence.test@tests)", false);
runTest("tests.testPersistence.test.TestPersistence_Test$TestBody", "test_testPersistenceReadWrite", true);
}
@Test
public void test_testPersistenceUpgrade() throws Throwable {
initTest("${mps_home}", "r:8ef4c1fc-fb61-4d5c-806c-7a971cfb9392(tests.testPersistence.test@tests)", false);
runTest("tests.testPersistence.test.TestPersistence_Test$TestBody", "test_testPersistenceUpgrade", true);
}
@MPSLaunch
public static class TestBody extends BaseTestBody {
public void test_testLastVersionIndexing() throws Exception {
TestPersistenceHelper helper = new TestPersistenceHelper(myProject.getRepository());
CollectCallback c = new CollectCallback();
String serialized = PersistenceUtil.saveModel(helper.getTestModel(), helper.getDefaultExt());
try {
ModelPersistence.index(new ByteArrayInputStream(serialized.getBytes(FileUtil.DEFAULT_CHARSET)), c);
} catch (IOException e) {
Assert.fail(e.getMessage());
}
Assert.assertTrue(c.myConcepts.contains(((SConceptAdapterById) MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept")).getId()));
Assert.assertTrue(c.myImports.contains(new JavaPackageNameStub("java.io").asModelReference(PersistenceFacade.getInstance().createModuleReference("6354ebe7-c22a-4a0f-ac54-50b52ab9b065(JDK)"))));
Assert.assertTrue(c.myExtRefs.contains(new SNodeId.Foreign("~System")));
Assert.assertTrue(c.myLocalRefs.contains(new SNodePointer("r:b44bed60-e0f0-4d48-bb29-e0fdb2041a66(tests.testPersistence.testModel)", "3895553186365322355").getNodeId()));
}
public void test_testPersistenceReadWrite() throws Exception {
// tests write and read in each supported persistence, check that model is not changed after write/read cycle
TestPersistenceHelper helper = new TestPersistenceHelper(myProject.getRepository());
for (int i = TestPersistenceHelper.START_PERSISTENCE_TEST_VERSION; i <= ModelPersistence.LAST_VERSION; ++i) {
PersistenceUtil.InMemoryStreamDataSource dataSource = new PersistenceUtil.InMemoryStreamDataSource();
helper.saveTestModelInPersistence(dataSource, i);
InputStream contentStream = dataSource.getContentAsStream();
byte[] content = null;
try {
int contentSize = contentStream.available();
content = new byte[contentSize];
contentStream.read(content);
} catch (IOException e) {
Assert.fail(e.getMessage());
}
ModelLoadResult result = ModelPersistence.readModel(SModelHeader.create(i), new ByteArrayInputSource(content), ModelLoadingState.FULLY_LOADED);
Assert.assertTrue(result.getState() == ModelLoadingState.FULLY_LOADED);
this.assertDeepModelEquals(helper.getTestModel().getSModel(), result.getModel());
result.getModel().dispose();
}
}
public void test_testPersistenceUpgrade() throws Exception {
TestPersistenceHelper helper = new TestPersistenceHelper(myProject.getRepository());
// tests that it's possible to upgrade to the latest persistence from any supported persistence
for (int fromVersion = TestPersistenceHelper.START_PERSISTENCE_TEST_VERSION; fromVersion < ModelPersistence.LAST_VERSION; fromVersion++) {
// prepare data source in requested version
PersistenceUtil.InMemoryStreamDataSource notUpgradedData = new PersistenceUtil.InMemoryStreamDataSource();
helper.saveTestModelInPersistence(notUpgradedData, fromVersion);
// load model from source version
String notUpgradedContent = notUpgradedData.getContent(FileUtil.DEFAULT_CHARSET_NAME);
SModelBase notUpgradedModel = ((SModelBase) PersistenceUtil.loadModel(notUpgradedContent));
// save model in last persistence
PersistenceUtil.InMemoryStreamDataSource upgradedData = new PersistenceUtil.InMemoryStreamDataSource();
ModelPersistence.saveModel(notUpgradedModel.getSModel(), upgradedData, ModelPersistence.LAST_VERSION);
// load model in last persistence from saved
String upgradedContent = upgradedData.getContent(FileUtil.DEFAULT_CHARSET_NAME);
SModelBase upgradedModel = ((SModelBase) PersistenceUtil.loadModel(upgradedContent));
// do test
this.assertDeepModelEquals(notUpgradedModel.getSModel(), upgradedModel.getSModel());
notUpgradedModel.getSModel().dispose();
upgradedModel.getSModel().dispose();
}
}
public void assertDeepModelEquals(SModel expectedModel, SModel actualModel) {
this.assertSameImports(expectedModel, actualModel);
this.assertSameModelImports(expectedModel, actualModel);
this.assertSameLanguageAspects(expectedModel, actualModel);
this.assertSameNodesCollections("root", expectedModel.getRootNodes(), actualModel.getRootNodes());
}
public void assertSameNodesCollections(String objectName, Iterable<SNode> expected, Iterable<SNode> actual) {
HashMap<org.jetbrains.mps.openapi.model.SNodeId, SNode> actualIdToNodeMap = new HashMap<org.jetbrains.mps.openapi.model.SNodeId, SNode>();
for (SNode actualNode : actual) {
actualIdToNodeMap.put(actualNode.getNodeId(), actualNode);
}
for (SNode expectedNode : expected) {
org.jetbrains.mps.openapi.model.SNodeId rootId = expectedNode.getNodeId();
SNode actualNode = actualIdToNodeMap.get(rootId);
Assert.assertNotNull("Not found expected " + objectName + " " + expectedNode, actualNode);
this.assertDeepNodeEquals(expectedNode, actualNode);
actualIdToNodeMap.remove(rootId);
}
Assert.assertTrue("Found not expected " + objectName + " " + actualIdToNodeMap, actualIdToNodeMap.isEmpty());
}
public void assertSameModelImports(SModel expectedModel, SModel actualModel) {
TestPersistenceHelper.assertListsEqual(this.getImportedModelUIDs(expectedModel), this.getImportedModelUIDs(actualModel), "model import");
}
public void assertSameLanguageAspects(SModel expectedModel, SModel actualModel) {
List<SModel.ImportElement> expectedLanguageAspects = expectedModel.getImplicitImportsSupport().getAdditionalModelVersions();
List<SModel.ImportElement> actualLanguageAspects = actualModel.getImplicitImportsSupport().getAdditionalModelVersions();
for (SModel.ImportElement expectedEl : expectedLanguageAspects) {
boolean found = false;
for (SModel.ImportElement actualEl : actualLanguageAspects) {
if (actualEl.getModelReference().equals(expectedEl.getModelReference())) {
found = true;
break;
}
}
if (!(found)) {
Assert.fail("Not found expected language aspect " + expectedEl.getModelReference());
}
}
for (SModel.ImportElement actualEl : actualLanguageAspects) {
boolean found = false;
for (SModel.ImportElement expectedEl : expectedLanguageAspects) {
if (actualEl.getModelReference().equals(expectedEl.getModelReference())) {
found = true;
break;
}
}
if (!(found)) {
Assert.fail("Unexpected language aspect " + actualEl.getModelReference());
}
}
}
public void assertSameImports(SModel expectedModel, SModel actualModel) {
final ImplicitImportsLegacyHolder is1 = expectedModel.getImplicitImportsSupport();
final ImplicitImportsLegacyHolder is2 = actualModel.getImplicitImportsSupport();
is1.calculateImplicitImports();
is2.calculateImplicitImports();
TestPersistenceHelper.assertListsEqual(is1.getAdditionalModelVersions(), is2.getAdditionalModelVersions(), new Comparator<SModel.ImportElement>() {
@Override
public int compare(SModel.ImportElement import1, SModel.ImportElement import2) {
return (import1.getModelReference().equals(import2.getModelReference()) ? 0 : 1);
}
}, "import");
}
public void assertDeepNodeEquals(SNode expectedNode, SNode actualNode) {
Assert.assertEquals(this.getErrorString("concept", expectedNode, actualNode), expectedNode.getConcept().getQualifiedName(), actualNode.getConcept().getQualifiedName());
this.assertPropertyEquals(expectedNode, actualNode);
this.assertReferenceEquals(expectedNode, actualNode);
this.assertDeepChildrenEquals(expectedNode, actualNode);
}
public void assertDeepChildrenEquals(SNode expectedNode, SNode actualNode) {
Set<SContainmentLink> roles = new HashSet<SContainmentLink>();
for (SNode child : expectedNode.getChildren()) {
roles.add(child.getContainmentLink());
}
for (SNode child : actualNode.getChildren()) {
roles.add(child.getContainmentLink());
}
for (SContainmentLink role : roles) {
Iterable<? extends SNode> expectedChildren = expectedNode.getChildren(role);
Iterable<? extends SNode> actualChildren = actualNode.getChildren(role);
int esize = IterableUtil.asCollection(expectedChildren).size();
int asize = IterableUtil.asCollection(actualChildren).size();
Assert.assertEquals(this.getErrorString("child count in role " + role, expectedNode, actualNode), esize, asize);
Iterator<? extends SNode> actualIterator = actualChildren.iterator();
for (SNode expectedChild : expectedChildren) {
SNode actualChild = actualIterator.next();
Assert.assertEquals(this.getErrorString("children in role " + role, expectedNode, actualNode), expectedChild.getNodeId(), actualChild.getNodeId());
this.assertDeepNodeEquals(expectedChild, actualChild);
}
}
}
public void assertPropertyEquals(SNode expectedNode, SNode actualNode) {
HashSet<String> propertes = new HashSet<String>();
propertes.addAll(IterableUtil.asCollection(expectedNode.getPropertyNames()));
propertes.addAll(IterableUtil.asCollection(actualNode.getPropertyNames()));
for (String key : propertes) {
String expectedProperty = SNodeOperations.getProperties(expectedNode).get(key);
String actualProperty = SNodeOperations.getProperties(actualNode).get(key);
Assert.assertEquals(this.getErrorString("property " + key, expectedNode, actualNode), expectedProperty, actualProperty);
}
}
public String getErrorString(String text, SNode expectedNode, SNode actualNode) {
return "Different " + text + " for nodes " + expectedNode + " and " + actualNode + ".";
}
public void assertReferenceEquals(SNode expectedNode, SNode actualNode) {
Set<String> roles = new HashSet<String>();
roles.addAll(SNodeOperations.getReferenceRoles(expectedNode));
roles.addAll(SNodeOperations.getReferenceRoles(actualNode));
Map<String, Set<SReference>> expRoleToReferenceMap = this.createRoleToReferenceMap(expectedNode);
Map<String, Set<SReference>> actRoleToReferenceMap = this.createRoleToReferenceMap(actualNode);
for (String role : roles) {
Assert.assertEquals(this.getErrorString("different number of referents in role " + role, expectedNode, actualNode), expRoleToReferenceMap.get(role).size(), actRoleToReferenceMap.get(role).size());
SReference expectedReference = expectedNode.getReference(role);
SReference actualReference = actualNode.getReference(role);
this.assertReferenceEquals(this.getErrorString("reference in role " + role, expectedNode, actualNode), expectedReference, actualReference);
}
}
public Map<String, Set<SReference>> createRoleToReferenceMap(SNode expectedNode) {
Map<String, Set<SReference>> expRoleToReferenceMap = new HashMap<String, Set<SReference>>();
for (SReference ref : expectedNode.getReferences()) {
if (expRoleToReferenceMap.get(ref.getRole()) == null) {
expRoleToReferenceMap.put(ref.getRole(), new HashSet<SReference>());
}
expRoleToReferenceMap.get(ref.getRole()).add(ref);
}
return expRoleToReferenceMap;
}
public void assertReferenceEquals(String errorString, SReference expectedReference, SReference actualReference) {
if (expectedReference == null) {
Assert.assertNull(errorString, actualReference);
return;
}
Assert.assertNotNull(errorString, actualReference);
// assertIdEqualsOrBothNull(errorString, expectedReference.getTargetNode(), actualReference.getTargetNode());
Assert.assertEquals(errorString, ((jetbrains.mps.smodel.SReference) expectedReference).getResolveInfo(), ((jetbrains.mps.smodel.SReference) actualReference).getResolveInfo());
Assert.assertEquals(errorString, expectedReference.getRole(), actualReference.getRole());
Assert.assertEquals(errorString, expectedReference.getTargetNodeId(), actualReference.getTargetNodeId());
}
public void assertIdEqualsOrBothNull(String errorString, SNode expectedNode, SNode actualNode) {
if (expectedNode == null) {
Assert.assertNull(errorString, actualNode);
return;
}
Assert.assertNotNull(errorString, actualNode);
Assert.assertEquals(errorString, expectedNode.getNodeId(), actualNode.getNodeId());
}
public List<SModelReference> getImportedModelUIDs(SModel sModel) {
List<SModelReference> references = new ArrayList<SModelReference>();
for (SModel.ImportElement importElement : sModel.importedModels()) {
references.add(importElement.getModelReference());
}
return Collections.unmodifiableList(references);
}
}
}