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); } } }