From f03893d9b643eae3f03debf7a656edbfa5b9b501 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Fri, 12 May 2017 10:25:50 +0300 Subject: [PATCH] Enhancements to modelled STS-tests Some refactoring and streamlining for the modelled STS-tests: * Possibility to ignore certain tests * Streamlined JUnit execution of modelled tests * Removed duplicate code related to modelled STS test searching * Introduced Junit/Assert SCL-module for assertions in SCL tests * Changed STSTestEditor to extend SCLModuleEditor2 Change-Id: Ib64cf026f69e7490a6eb831afd88d909b80ed8b7 --- .../scl/GraphModuleSourceRepository.java | 2 +- .../module/coverage/CoverageUtils.java | 2 +- .../scl/Junit/Assert.scl | 20 ++ .../scl/ui/editor2/SCLModuleEditor2.java | 2 +- .../META-INF/MANIFEST.MF | 4 +- .../graph/Tests.pgraph | 34 ++- .../META-INF/MANIFEST.MF | 1 + .../graph/TestsUI.pgraph | 14 +- .../graph/images/testignored.gif | Bin 0 -> 947 bytes .../META-INF/MANIFEST.MF | 3 +- .../adapters.xml | 17 +- .../plugin.xml | 18 +- .../tests/modelled/ui/Activator.java | 4 +- .../tests/modelled/ui/STSEditorAdapter.java | 68 ++++++ .../modelled/ui/STSEditorInputFactory.java | 14 ++ .../tests/modelled/ui/STSTestEditor.java | 15 +- .../ui/STSTestEditorDocumentProvider.java | 11 +- .../tests/modelled/ui/STSTestEditorInput.java | 134 ++++++++++++ .../tests/modelled/ui/STSTestSuiteModel.java | 195 ++++++------------ .../modelled/ui/adapters/IsTestIgnored.java | 44 ++++ .../modelled/ui/rules/TestImageRule.java | 42 ++++ .../META-INF/MANIFEST.MF | 8 +- .../org.simantics.tests.modelled/adapters.xml | 28 +++ .../build.properties | 3 +- .../modelled/junit/RuntimeSTSRunner.java | 1 + .../modelled/junit/RuntimeSTSSuiteRunner.java | 9 +- .../modelled/junit/RuntimeSTSTestRunner.java | 1 + .../modelled/junit/RuntimeTestCollector.java | 9 +- .../modelled/junit/v2/ModelledSTSRunner.java | 81 ++++++++ .../junit/v2/ModelledSTSSuiteRunner.java | 77 +++++++ .../junit/v2/ModelledSTSTestRunner.java | 74 +++++++ .../modelled/utils/ModelledSTSSuite.java | 79 +++++++ .../tests/modelled/utils/ModelledSTSTest.java | 44 ++++ .../modelled/utils/STSSuiteTestCollector.java | 125 +++++++++++ .../feature.xml | 21 ++ 35 files changed, 1016 insertions(+), 188 deletions(-) create mode 100644 bundles/org.simantics.scl.runtime/scl/Junit/Assert.scl create mode 100644 bundles/org.simantics.tests.modelled.ui.ontology/graph/images/testignored.gif create mode 100644 bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorAdapter.java create mode 100644 bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorInputFactory.java create mode 100644 bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorInput.java create mode 100644 bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/adapters/IsTestIgnored.java create mode 100644 bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/rules/TestImageRule.java create mode 100644 bundles/org.simantics.tests.modelled/adapters.xml create mode 100644 bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSRunner.java create mode 100644 bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSSuiteRunner.java create mode 100644 bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSTestRunner.java create mode 100644 bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSSuite.java create mode 100644 bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java create mode 100644 bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/STSSuiteTestCollector.java diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java index c75f7a941..09f7694dd 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java @@ -71,7 +71,7 @@ public enum GraphModuleSourceRepository implements ModuleSourceRepository { } @Override public void removeListener(UpdateListener listener) { - listener = null; + this.listener = null; } @Override public boolean isDisposed() { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/coverage/CoverageUtils.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/coverage/CoverageUtils.java index 269e8f6af..a9e08af88 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/coverage/CoverageUtils.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/coverage/CoverageUtils.java @@ -75,7 +75,7 @@ public class CoverageUtils { } public static void resetCoverage(Collection modules) { - modules.forEach(module -> resetCoverage(module)); + modules.forEach(CoverageUtils::resetCoverage); } public static void resetCoverage(Module module) { diff --git a/bundles/org.simantics.scl.runtime/scl/Junit/Assert.scl b/bundles/org.simantics.scl.runtime/scl/Junit/Assert.scl new file mode 100644 index 000000000..6b0cd2d02 --- /dev/null +++ b/bundles/org.simantics.scl.runtime/scl/Junit/Assert.scl @@ -0,0 +1,20 @@ +importJava "org.junit.Assert" where + @JavaName assertEquals + @private + assertDoublesEquals :: String -> Double -> Double -> Double -> () + @JavaName assertEquals + @private + assertLongsEquals :: String -> Long -> Long -> () + + assertTrue :: String -> Boolean -> () + assertFalse :: String -> Boolean -> () + +class AssertEquals a where + assertEquals :: String -> a -> a -> () +instance AssertEquals Long where + assertEquals = assertLongsEquals + +class AssertEqualsTolerance a where + assertEqualsTolerance :: String -> a -> a -> a -> () +instance AssertEqualsTolerance Double where + assertEqualsTolerance = assertDoublesEquals diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java index 1398f2c07..100f49e25 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java @@ -15,7 +15,7 @@ import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment; public class SCLModuleEditor2 extends TextEditor { private boolean disposed = false; - ResourceManager resourceManager; + protected ResourceManager resourceManager; public SCLModuleEditor2() { super(); diff --git a/bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF index 66d1bc334..3d0a8ef9c 100644 --- a/bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF @@ -3,7 +3,9 @@ Bundle-ManifestVersion: 2 Bundle-Name: http://www.simantics.org/Tests Bundle-SymbolicName: org.simantics.tests.modelled.ontology Bundle-Version: 1.0.0.qualifier -Require-Bundle: org.simantics.layer0 +Require-Bundle: org.simantics.layer0, + org.simantics.selectionview.ontology;bundle-version="1.2.0", + org.simantics.modeling.ontology;bundle-version="1.2.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.simantics.tests.modelled.ontology Bundle-Vendor: Semantum Oy diff --git a/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph b/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph index 11b93d2d4..8364abd18 100644 --- a/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph +++ b/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph @@ -1,5 +1,6 @@ L0 = - +SEL = +MOD = TESTS = : L0.Ontology @L0.new @@ -9,12 +10,35 @@ TESTS.SCLMain : L0.SCLModule L0.SCLModule.definition _ : L0.String @L0.loadString "scl/SCLMain.scl" +TESTS.STSTest.definition -- TESTS.STSTest.definition --> L0.String -- TESTS.STSTest.executionPriority --> L0.Integer -- TESTS.STSSuite.moduleNameFilter --> L0.String -- TESTS.STSSuite.moduleNameFilter --> L0.String K+bef&$J~zd8epbMY zte`o$kuwWC7i0u3$q!vr5VNE#dR0aIn(BmgwMpyhQa3hcY--Nk(q6c|ySd!Ay~?Mj z)@x$D$A*5pEfZ{~H@VGibzRiqyu8b4O^?IsjXQQ;d$RM|)1B9zoqv4$&g*AS-~N2| z_Sf_Gzg~X$_4d=R_n&`%{QCRzw?E&0{`v9q&(B|f{{R0EcIhZF8UoY|0bsgP{K>+| z!0?|z2V^cNPcU#yVEE7Zhken4gUzh$LR$`QSm-RkWq)Oc$HqtOt*RLrcTQ|XPwvddMNE5xh!fVSr1|bc5us012kHv$HLnIZO-}EbkO|XlDBQp+CJ#T9fUM2-lXw z`x)IQ&y#qtXjQ1V%)EOJh7XSPGU^`c%H8;IWylidh!wG?og6N%%kX8H;a&dj+&nMQ OS9edBCpa)LSOWk+o2zL6 literal 0 HcmV?d00001 diff --git a/bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF index 776eea39e..cd48cdc86 100644 --- a/bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF @@ -16,7 +16,8 @@ Require-Bundle: org.eclipse.ui, org.simantics.tests.modelled;bundle-version="1.0.0", org.eclipse.e4.ui.model.workbench, org.simantics.scl.osgi, - org.simantics.browsing.ui.model + org.simantics.browsing.ui.model, + org.slf4j.api Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Vendor: Semantum Oy diff --git a/bundles/org.simantics.tests.modelled.ui/adapters.xml b/bundles/org.simantics.tests.modelled.ui/adapters.xml index 4827e6cc0..1dc8f8561 100644 --- a/bundles/org.simantics.tests.modelled.ui/adapters.xml +++ b/bundles/org.simantics.tests.modelled.ui/adapters.xml @@ -1,10 +1,13 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/bundles/org.simantics.tests.modelled.ui/plugin.xml b/bundles/org.simantics.tests.modelled.ui/plugin.xml index 883af2f9e..150c2939c 100644 --- a/bundles/org.simantics.tests.modelled.ui/plugin.xml +++ b/bundles/org.simantics.tests.modelled.ui/plugin.xml @@ -24,12 +24,18 @@ - - + + + + + + diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java index b3d8fc9d8..8cae1510b 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java @@ -6,6 +6,7 @@ import java.util.List; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Resource; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -41,8 +42,7 @@ public class Activator extends AbstractUIPlugin { */ public void stop(BundleContext context) throws Exception { plugin = null; - for (Image image : imagesToDispose) - image.dispose(); + imagesToDispose.forEach(Resource::dispose); super.stop(context); } diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorAdapter.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorAdapter.java new file mode 100644 index 000000000..363087f76 --- /dev/null +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorAdapter.java @@ -0,0 +1,68 @@ +package org.simantics.tests.modelled.ui; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.tests.modelled.ontology.TestsResource; +import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter; +import org.simantics.ui.workbench.editor.EditorAdapter; +import org.simantics.utils.ui.workbench.WorkbenchUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class STSEditorAdapter extends AbstractResourceEditorAdapter implements EditorAdapter { + + private static final Logger LOGGER = LoggerFactory.getLogger(STSEditorAdapter.class); + + public STSEditorAdapter() { + super("SCL Module Editor", null, 20); + } + + @Override + public boolean canHandle(ReadGraph g, Object input) + throws DatabaseException { + if(input instanceof IStructuredSelection) + input = ((IStructuredSelection)input).getFirstElement(); + if(!(input instanceof Resource)) { + if(input instanceof IAdaptable) { + input = ((IAdaptable)input).getAdapter(Resource.class); + if(input == null) + return false; + } + else + return false; + } + Resource resource = (Resource)input; + return g.isInstanceOf(resource, TestsResource.getInstance(g).STSTest); + } + + protected void openEditor(Resource input) throws Exception { + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + if(page == null) + return; + Simantics.getSession().asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + String uri = graph.getURI(input); + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + try { + WorkbenchUtils.openEditor("org.simantics.tests.ui.stsTestEditor", new STSTestEditorInput(uri)); + } catch (PartInitException e) { + LOGGER.error("Could not initialize part", e); + } + } + }); + } + }); + } + +} diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorInputFactory.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorInputFactory.java new file mode 100644 index 000000000..58d05b032 --- /dev/null +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSEditorInputFactory.java @@ -0,0 +1,14 @@ +package org.simantics.tests.modelled.ui; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; + +public class STSEditorInputFactory implements IElementFactory { + + @Override + public IAdaptable createElement(IMemento memento) { + return new STSTestEditorInput(memento.getTextData()); + } + +} diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java index cf8fd9c56..21bb5e4d7 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java @@ -1,17 +1,8 @@ package org.simantics.tests.modelled.ui; -import org.simantics.modeling.ui.componentTypeEditor.SCLModuleEditor; -import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew; +import org.simantics.scl.ui.editor2.SCLModuleEditor2; + +public class STSTestEditor extends SCLModuleEditor2 { -public class STSTestEditor extends SCLModuleEditor { - - - - @Override - protected void preInitialize() { - SCLSourceViewerConfigurationNew sourceViewerConfiguration = new SCLSourceViewerConfigurationNew(resourceManager); - setDocumentProvider(new STSTestEditorDocumentProvider(sourceViewerConfiguration)); - setSourceViewerConfiguration(sourceViewerConfiguration); - } } diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java index 10d7fb21b..0c6dbc934 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java @@ -7,7 +7,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.source.IAnnotationModel; import org.simantics.Simantics; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; @@ -23,21 +22,13 @@ import org.simantics.tests.modelled.ontology.TestsResource; import org.simantics.ui.workbench.ResourceEditorInput; import org.simantics.utils.logging.TimeLogger; +@Deprecated public class STSTestEditorDocumentProvider extends SCLModuleEditorDocumentProvider { public STSTestEditorDocumentProvider(SCLSourceViewerConfigurationNew sourceViewer) { super(sourceViewer); } - @Override - protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { - return null; - } - - @Override - protected void updateAnnotations() { - } - @Override protected IDocument createDocument(Object element) throws CoreException { ResourceEditorInput input = (ResourceEditorInput)element; diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorInput.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorInput.java new file mode 100644 index 000000000..d057daccb --- /dev/null +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorInput.java @@ -0,0 +1,134 @@ +package org.simantics.tests.modelled.ui; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +import org.eclipse.ui.IPersistableElement; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.scl.compiler.errors.Failable; +import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.options.ModuleCompilationOptions; +import org.simantics.scl.compiler.module.repository.ModuleRepository; +import org.simantics.scl.compiler.module.repository.UpdateListener; +import org.simantics.scl.compiler.source.ModuleSource; +import org.simantics.scl.compiler.source.TextualModuleSource; +import org.simantics.scl.ui.editor2.StandardSCLModuleEditorInput; +import org.simantics.tests.modelled.ontology.TestsResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class STSTestEditorInput extends StandardSCLModuleEditorInput { + + private static final Logger LOGGER = LoggerFactory.getLogger(STSTestEditorInput.class); + + public STSTestEditorInput(String moduleName) { + super(moduleName); + } + + @Override + public boolean exists() { + return true; + } + + @SuppressWarnings("unchecked") + @Override + public T getAdapter(Class adapter) { + if(adapter.equals(ModuleSource.class)) + try { + return (T) Simantics.getSession().syncRequest(new ReadSTSModuleSource(getModuleName())); + } catch (DatabaseException e) { + e.printStackTrace(); + } + if(adapter.equals(IPersistableElement.class)) + return (T)this; + return null; + } + + + private static class STSTextualModuleSource extends TextualModuleSource { + + private String moduleText; + + public STSTextualModuleSource(String stsModuleURI, String moduleText) { + super(stsModuleURI); + this.moduleText = moduleText; + } + + @Override + public void update(String newSourceText) { + try { + Simantics.getSession().syncRequest(new WriteSTSModuleSource(getModuleName(), newSourceText)); + } catch (DatabaseException e) { + LOGGER.error("", e); + } + } + + @Override + public Failable compileModule(ModuleRepository environment, UpdateListener listener, ModuleCompilationOptions options) { + return super.compileModule(environment, listener, options); + } + + @Override + public boolean isUpdateable() { + return true; + } + + @Override + protected Reader getSourceReader(UpdateListener listener) throws IOException { + return new StringReader(moduleText); + } + } + + static class ReadSTSModuleSource extends UnaryRead { + + public ReadSTSModuleSource(String moduleName) { + super(moduleName); + } + + @Override + public ModuleSource perform(ReadGraph graph) throws DatabaseException { + Resource moduleResource = graph.getPossibleResource(parameter); + if(moduleResource == null) + return null; + TestsResource TESTS = TestsResource.getInstance(graph); + if(!graph.isInstanceOf(moduleResource, TESTS.STSTest)) + return null; + String text = graph.getRelatedValue(moduleResource, TESTS.STSTest_definition); + return new STSTextualModuleSource(parameter, text); + } + } + + static class WriteSTSModuleSource extends WriteRequest { + private final String moduleURI; + private final String sourceText; + + public WriteSTSModuleSource(String moduleURI, String sourceText) { + this.moduleURI = moduleURI; + this.sourceText = sourceText; + } + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Resource moduleResource = graph.getPossibleResource(moduleURI); + if(moduleResource == null) + return; + TestsResource TESTS = TestsResource.getInstance(graph); + if(!graph.isInstanceOf(moduleResource, TESTS.STSTest)) + return; + graph.claimLiteral(moduleResource, TESTS.STSTest_definition, sourceText); + } + } + + @Override + public String getFactoryId() { + return "org.simantics.tests.modelled.ui.stseditor.inputFactory"; + } + +} diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java index 569f6fbdc..976efa2c2 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java @@ -3,15 +3,13 @@ package org.simantics.tests.modelled.ui; import java.io.BufferedReader; import java.io.StringReader; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; import org.eclipse.swt.graphics.Image; import org.simantics.Simantics; -import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; @@ -19,57 +17,49 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.commands.CommandSession; import org.simantics.scl.compiler.commands.TestScriptExecutor; -import org.simantics.scl.compiler.module.Module; import org.simantics.scl.compiler.module.coverage.CombinedCoverage; -import org.simantics.scl.compiler.module.coverage.CoverageBuilder; -import org.simantics.scl.compiler.module.coverage.CoverageUtils; import org.simantics.scl.compiler.module.options.ModuleCompilationOptions; import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor; import org.simantics.scl.compiler.module.repository.ModuleRepository; -import org.simantics.scl.compiler.runtime.RuntimeModule; import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler; import org.simantics.tests.modelled.ontology.TestsResource; -import org.simantics.utils.strings.AlphanumComparator; +import org.simantics.tests.modelled.utils.ModelledSTSSuite; +import org.simantics.tests.modelled.utils.ModelledSTSTest; +import org.simantics.tests.modelled.utils.STSSuiteTestCollector; public class STSTestSuiteModel { static class STSTest { - private final Resource test; + private final ModelledSTSTest test; + private final STSSuite parent; - private final String definition; - private final String name; private boolean executed = false; private long duration; private boolean failed = false; private boolean isRunning = false; private List output = new ArrayList<>(); - private CombinedCoverage coverage; - private int priority; - public STSTest(Resource test, STSSuite parent, String definition, String name, int executionPrioprity) { + public STSTest(ModelledSTSTest test, STSSuite parent) { this.test = test; this.parent = parent; - this.definition = definition; - this.name = name; - this.priority = executionPrioprity; } public String getName() { - return name; + return test.getName(); } public String getLabel() { StringBuilder sb = new StringBuilder(); - sb.append(name); + sb.append(getName()); if (executed || failed) sb.append(" (").append(duration).append(" ms)"); return sb.toString(); } public String getDefinition() { - return definition; + return test.getCode(); } public STSSuite getParent() { @@ -79,7 +69,7 @@ public class STSTestSuiteModel { public void execute(CommandSession session) { isRunning = true; - TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(definition)), new AbstractSCLReportingHandler() { + TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(getDefinition())), new AbstractSCLReportingHandler() { @Override public void print(String text) { @@ -95,7 +85,7 @@ public class STSTestSuiteModel { public void printError(String error) { appendOutput(error + "\n"); } - }); + }, true); long start = System.currentTimeMillis(); try { if (parent != null) @@ -124,61 +114,56 @@ public class STSTestSuiteModel { } public void setCoverage(CombinedCoverage coverage) { - this.coverage = coverage; + test.setCoverage(coverage); } public CombinedCoverage getCoverage() { - return coverage; + return test.getCoverage(); } - + + public int getPriority() { + return test.getPriority(); + } + @Override public String toString() { - return name + " [priority=" + priority + ", executed=" + executed + ", duration=" + duration + "]"; + return getName() + " [priority=" + getPriority() + ", executed=" + executed + ", duration=" + duration + "]"; + } + + public boolean isIgnored() { + return test.isIgnored(); } } static class STSSuite { - - private List moduleNameFilterPatterns = new ArrayList<>(); - private final Resource suite; - private final String name; + + private ModelledSTSSuite suite; private STSTest[] children; private int startedCount; private int errorCount; private int failureCount; - private CoverageBuilder coverageBuilder; + public int ignoredCount; - public STSSuite(Resource suite, String name, String moduleNameFilter) { + public STSSuite(ModelledSTSSuite suite) { this.suite = suite; - this.name = name; - for (String s : moduleNameFilter.split(",")) { - try { - s = s.trim().replaceAll("\\*", "\\\\w*").toLowerCase(); - moduleNameFilterPatterns.add(Pattern.compile(s)); - } catch (PatternSyntaxException e) { - e.printStackTrace(); - } - } - } - - public void children(STSTest[] children) { - this.children = children; } public STSTest[] getChildren() { + if (children == null) + children = suite.getSortedChildren().stream().map(modelledTest -> new STSTest(modelledTest, this)).collect(Collectors.toList()).toArray(new STSTest[suite.getChildren().size()]); return children; } public String getName() { - return name; + return suite.getName(); } public String getLabel() { StringBuilder sb = new StringBuilder(); - sb.append(name); + sb.append(getName()); long totalTime = 0; - if (children != null) { - for (STSTest test : children) { + if (getChildren() != null) { + for (STSTest test : getChildren()) { if (test.executed || test.failed) { totalTime += test.duration; } @@ -190,56 +175,40 @@ public class STSTestSuiteModel { } public boolean isRunning() { - boolean running = false; - if (children != null) { - for (STSTest test: children) { + if (getChildren() != null) { + for (STSTest test: getChildren()) { if (test.isRunning) { - running = true; - break; + return true; } } } - return running; + return false; } public boolean executed() { - boolean executed = true; - if (children != null) { - for (STSTest test: children) { + if (getChildren() != null) { + for (STSTest test: getChildren()) { if (!test.executed) { - executed = false; - break; + return false; } } } - return executed; + return true; } public boolean failed() { - boolean failed = false; - if (children != null) { - for (STSTest test: children) { + if (getChildren() != null) { + for (STSTest test: getChildren()) { if (test.failed) { - failed = true; - break; + return true; } } } - return failed; - } - - public void addCoverage(List modules) { - if (coverageBuilder == null) { - coverageBuilder = new CoverageBuilder(); - } - for (Module module : modules) - coverageBuilder.addCoverage(module, true); + return false; } public CombinedCoverage getCoverage() { - if (coverageBuilder == null) - return null; - return coverageBuilder.getCoverage(); + return suite.getCoverage(); } } @@ -276,7 +245,7 @@ public class STSTestSuiteModel { @Override public ModuleCompilationOptions getOptions(String moduleName) { boolean coverage = false; - for (Pattern p : suite.moduleNameFilterPatterns) { + for (Pattern p : suite.suite.getModuleNameFilterPatterns()) { if (p.matcher(moduleName.toLowerCase()).find()) { coverage = true; break; @@ -301,45 +270,23 @@ public class STSTestSuiteModel { } private void executeSuite(CommandSession session) { - for (STSTest test : suite.getChildren()) { - test.execute(session); - - Collection runtimeModules = session.getRuntimeEnvironment().getRuntimeModules(); - List modules = new ArrayList<>(runtimeModules.size()); - for (RuntimeModule module : runtimeModules) { - for (Pattern p : suite.moduleNameFilterPatterns) { - if (p.matcher(module.getModule().getName().toLowerCase()).find()) { - modules.add(module.getModule()); - } - } + if (test.isIgnored()) { + testExecuted(); + test.getParent().ignoredCount++; + continue; } - test.setCoverage(CoverageUtils.getCoverage(modules)); - suite.addCoverage(modules); - - CoverageUtils.resetCoverage(modules); - + test.execute(session); + STSSuiteTestCollector.setSuiteCoverage(test.test, suite.suite, session); testExecuted(); } - } - + private void executeTest(CommandSession session) { - test.execute(session); testExecuted(); - - Collection runtimeModules = session.getRuntimeEnvironment().getRuntimeModules(); - List modules = new ArrayList<>(runtimeModules.size()); - for (RuntimeModule module : runtimeModules) { - modules.add(module.getModule()); - } - test.setCoverage(CoverageUtils.getCoverage(modules)); - - CoverageUtils.resetCoverage(modules); - + STSSuiteTestCollector.setTestCoverage(test.test, session); } - public boolean hasChildren(Object element) { if (element instanceof STSTest) { @@ -418,29 +365,13 @@ public class STSTestSuiteModel { Layer0 L0 = Layer0.getInstance(graph); TestsResource TESTS = TestsResource.getInstance(graph); if (graph.isInstanceOf(root, TESTS.STSTest)) { - String testName = graph.getRelatedValue2(root, L0.HasName, Bindings.STRING); - String definition = graph.getRelatedValue2(root, TESTS.STSTest_definition, Bindings.STRING); - Integer executionPrioprity = graph.getRelatedValue2(root, TESTS.STSTest_executionPriority, Bindings.INTEGER); - test = new STSTest(root, null, definition, testName, executionPrioprity); + test = new STSTest(STSSuiteTestCollector.toModelledTest(graph, root), null); } else if (graph.isInstanceOf(root, TESTS.STSSuite)) { - String suiteName = graph.getRelatedValue2(root, L0.HasName, Bindings.STRING); - String moduleNameFilter = graph.getPossibleRelatedValue2(root, TESTS.STSSuite_moduleNameFilter, Bindings.STRING); - suite = new STSSuite(root, suiteName, moduleNameFilter); - List tests = new ArrayList<>(); - for (Resource test : graph.getObjects(root, L0.ConsistsOf)) { - String testName = graph.getRelatedValue2(test, L0.HasName, Bindings.STRING); - String definition = graph.getRelatedValue2(test, TESTS.STSTest_definition, Bindings.STRING); - Integer executionPrioprity = graph.getRelatedValue2(test, TESTS.STSTest_executionPriority, Bindings.INTEGER); - tests.add(new STSTest(test, suite, definition, testName, executionPrioprity)); - } - Collections.sort(tests, (o1, o2) -> { - if (o1.priority < o2.priority) - return -1; - else if (o1.priority > o2.priority) - return 1; - else return AlphanumComparator.COMPARATOR.compare(o1.name, o2.name); - }); - suite.children(tests.toArray(new STSTest[tests.size()])); + List tests = new ArrayList<>(); + for (Resource test : graph.getObjects(root, L0.ConsistsOf)) + tests.add(STSSuiteTestCollector.toModelledTest(graph, test)); + + suite = new STSSuite(STSSuiteTestCollector.toModelledSuite(graph, root, tests)); } else { throw new IllegalArgumentException(root.toString()); } @@ -467,6 +398,8 @@ public class STSTestSuiteModel { } public int getIgnoredCount() { + if (suite != null) + return suite.ignoredCount; return 0; } diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/adapters/IsTestIgnored.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/adapters/IsTestIgnored.java new file mode 100644 index 000000000..a58f3b3c3 --- /dev/null +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/adapters/IsTestIgnored.java @@ -0,0 +1,44 @@ +package org.simantics.tests.modelled.ui.adapters; + +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.model.images.ImageRule; +import org.simantics.browsing.ui.model.tests.Test; +import org.simantics.browsing.ui.model.visuals.VisualsRule; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.tests.modelled.ontology.TestsResource; + +public enum IsTestIgnored implements Test, VisualsRule, ImageRule { + + INSTANCE; + + public static IsTestIgnored get() { + return INSTANCE; + } + + @Override + public boolean isCompatible(Class contentType) { + return Resource.class.equals(contentType); + } + + @Override + public boolean test(ReadGraph graph, Object content) throws DatabaseException { + if (content instanceof Resource) { + Resource resource = (Resource) content; + TestsResource TESTS = TestsResource.getInstance(graph); + return graph.getPossibleRelatedValue2(resource, TESTS.ignore, Bindings.BOOLEAN); + } + return false; + } + + @Override + public Map getImage(ReadGraph graph, Object content) throws DatabaseException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/rules/TestImageRule.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/rules/TestImageRule.java new file mode 100644 index 000000000..a405ad59a --- /dev/null +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/rules/TestImageRule.java @@ -0,0 +1,42 @@ +package org.simantics.tests.modelled.ui.rules; + +import java.util.Collections; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.images.ImageRule; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.tests.modelled.ontology.TestsResource; +import org.simantics.tests.modelled.ui.ontology.TestsUIResource; + +public class TestImageRule implements ImageRule { + + private ImageDescriptor testImage; + private ImageDescriptor testIgnoredImage; + + public TestImageRule(ReadGraph graph) throws DatabaseException { + TestsUIResource TESTS = TestsUIResource.getInstance(graph); + testImage = graph.adapt(TESTS.testImage, ImageDescriptor.class); + testIgnoredImage = graph.adapt(TESTS.testIgnoredImage, ImageDescriptor.class); + } + + @Override + public boolean isCompatible(Class contentType) { + return Resource.class.equals(contentType); + } + + @Override + public Map getImage(ReadGraph graph, Object content) throws DatabaseException { + Resource resource = (Resource) content; + Boolean ignored = graph.getPossibleRelatedValue2(resource, TestsResource.getInstance(graph).ignore, + Bindings.BOOLEAN); + if (ignored != null && ignored) + return Collections.singletonMap(ColumnKeys.SINGLE, testIgnoredImage); + return Collections.singletonMap(ColumnKeys.SINGLE, testImage); + } + +} diff --git a/bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF index 042896151..8f1829479 100644 --- a/bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF @@ -8,9 +8,13 @@ Require-Bundle: org.simantics.tests.modelled.ontology, org.simantics.scl.osgi, org.simantics, org.junit, - org.simantics.modeling;bundle-version="1.1.1" + org.simantics.modeling;bundle-version="1.1.1", + org.slf4j.api, + org.simantics.db.testing Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: org.simantics.tests.modelled, - org.simantics.tests.modelled.junit + org.simantics.tests.modelled.junit, + org.simantics.tests.modelled.junit.v2, + org.simantics.tests.modelled.utils Bundle-Vendor: Semantum Oy diff --git a/bundles/org.simantics.tests.modelled/adapters.xml b/bundles/org.simantics.tests.modelled/adapters.xml new file mode 100644 index 000000000..5db414904 --- /dev/null +++ b/bundles/org.simantics.tests.modelled/adapters.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/bundles/org.simantics.tests.modelled/build.properties b/bundles/org.simantics.tests.modelled/build.properties index d7919bc50..5b7d10cf2 100644 --- a/bundles/org.simantics.tests.modelled/build.properties +++ b/bundles/org.simantics.tests.modelled/build.properties @@ -2,5 +2,6 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - scl/ + scl/,\ + adapters.xml src.includes = scl/ diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSRunner.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSRunner.java index 2311409f8..fe7d82f69 100644 --- a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSRunner.java +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSRunner.java @@ -8,6 +8,7 @@ import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runners.ParentRunner; +@Deprecated public abstract class RuntimeSTSRunner extends ParentRunner { public RuntimeSTSRunner(Class testClass) throws Exception { diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSSuiteRunner.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSSuiteRunner.java index 2acc58a79..90abe0e16 100644 --- a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSSuiteRunner.java +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/RuntimeSTSSuiteRunner.java @@ -8,6 +8,7 @@ import org.junit.runner.Description; import org.simantics.scl.compiler.commands.CommandSession; import org.simantics.scl.osgi.SCLOsgi; +@Deprecated public class RuntimeSTSSuiteRunner extends RuntimeSTSRunner { private final List children = new ArrayList<>(); @@ -35,6 +36,12 @@ public class RuntimeSTSSuiteRunner extends RuntimeSTSRunner c.setCommandSession(session)); children.addAll(testChildren); } + + @Override + protected boolean isIgnored(RuntimeSTSTestRunner child) { + // TODO Auto-generated method stub + return super.isIgnored(child); + } @Override public List getChildren() { @@ -44,7 +51,7 @@ public class RuntimeSTSSuiteRunner extends RuntimeSTSRunner perform(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); - + if (LOGGER.isInfoEnabled()) + LOGGER.info("Found {} shared ontologies from graph", sharedOntologies.size()); Set suites = new HashSet<>(); TestsResource TESTS = TestsResource.getInstance(graph); Layer0 L0 = Layer0.getInstance(graph); for (Resource sharedOntology : sharedOntologies) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Searching {} for modelled tests", graph.getURI(sharedOntology)); List stsSuites = ModelingUtils.searchByType(graph, sharedOntology, TESTS.STSSuite); for (Resource stsSuite : stsSuites) { try { diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSRunner.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSRunner.java new file mode 100644 index 000000000..c74f6efae --- /dev/null +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSRunner.java @@ -0,0 +1,81 @@ +package org.simantics.tests.modelled.junit.v2; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.junit.runner.Description; +import org.junit.runner.Result; +import org.junit.runner.notification.RunListener; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.ParentRunner; +import org.junit.runners.model.InitializationError; +import org.simantics.Simantics; +import org.simantics.db.testing.common.AcornTests; +import org.simantics.scl.compiler.commands.CommandSession; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.tests.modelled.utils.STSSuiteTestCollector; + +public class ModelledSTSRunner extends ParentRunner { + + private CommandSession commandSession; + + public ModelledSTSRunner(Class testClass) throws Exception { + super(testClass); + initialize0(); + } + + @Override + protected List getChildren() { + return STSSuiteTestCollector.collectTests().stream().map(suite -> { + try { + return new ModelledSTSSuiteRunner(suite); + } catch (Exception e) { + throw new RuntimeException(e); + } + }).collect(Collectors.toList()); + } + + @Override + protected Description describeChild(ModelledSTSSuiteRunner child) { + return child.getDescription(); + } + + @Override + public void run(RunNotifier notifier) { + notifier.addListener(new RunListener() { + + @Override + public void testRunFinished(Result result) throws Exception { + deinitialize0(); + } + }); + super.run(notifier); + } + + @Override + protected void runChild(ModelledSTSSuiteRunner child, RunNotifier notifier) { + child.setCommandSesssion(commandSession); + child.run(notifier); + // TODO: Add coverage reporting to ModelledSTSRunner +// CombinedCoverage cover = child.getCoverage(); +// CoverageBuilder b = new CoverageBuilder(); + } + + public void initialize() throws InitializationError { + } + + public void deinitialize() throws Exception { + } + + private void initialize0() throws Exception { + AcornTests.newSimanticsWorkspace(null, null); + this.commandSession = new CommandSession(SCLOsgi.MODULE_REPOSITORY, null); + initialize(); + } + + private void deinitialize0() throws Exception { + deinitialize(); + Simantics.shutdown(new NullProgressMonitor()); + } +} diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSSuiteRunner.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSSuiteRunner.java new file mode 100644 index 000000000..a568976cc --- /dev/null +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSSuiteRunner.java @@ -0,0 +1,77 @@ +package org.simantics.tests.modelled.junit.v2; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.runner.Description; +import org.junit.runner.notification.Failure; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.ParentRunner; +import org.simantics.scl.compiler.commands.CommandSession; +import org.simantics.scl.compiler.module.coverage.CombinedCoverage; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.tests.modelled.utils.ModelledSTSSuite; +import org.simantics.tests.modelled.utils.STSSuiteTestCollector; + +public class ModelledSTSSuiteRunner extends ParentRunner { + + private final ModelledSTSSuite suite; + private CommandSession commandSession; + + public ModelledSTSSuiteRunner(ModelledSTSSuite suite) throws Exception { + super(ModelledSTSSuiteRunner.class); + this.suite = suite; + } + + @Override + protected String getName() { + return suite.getName(); + } + + @Override + protected List getChildren() { + return suite.getChildren().stream().map(test -> new ModelledSTSTestRunner(test)).collect(Collectors.toList()); + } + + @Override + protected Description describeChild(ModelledSTSTestRunner child) { + return child.getDescription(); + } + + @Override + protected void runChild(ModelledSTSTestRunner child, RunNotifier notifier) { + Description description = describeChild(child); + if (isIgnored(child)) { + notifier.fireTestIgnored(description); + } else { + notifier.fireTestStarted(description); + try { + child.run(getCommandSession()); + notifier.fireTestFinished(description); + STSSuiteTestCollector.setSuiteCoverage(child.getTest(), suite, getCommandSession()); + } catch (Throwable e) { + notifier.fireTestFailure(new Failure(description, e)); + } + } + } + + @Override + protected boolean isIgnored(ModelledSTSTestRunner child) { + return child.isIgnored(); + } + + public void setCommandSesssion(CommandSession commandSession) { + this.commandSession = commandSession; + } + + public CommandSession getCommandSession() { + if (commandSession == null) + commandSession = new CommandSession(SCLOsgi.MODULE_REPOSITORY, null); + return commandSession; + } + + public CombinedCoverage getCoverage() { + return suite.getCoverage(); + } + +} diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSTestRunner.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSTestRunner.java new file mode 100644 index 000000000..a2acbfcb8 --- /dev/null +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/junit/v2/ModelledSTSTestRunner.java @@ -0,0 +1,74 @@ +package org.simantics.tests.modelled.junit.v2; + +import java.io.BufferedReader; +import java.io.StringReader; + +import org.junit.runner.Description; +import org.junit.runner.Runner; +import org.junit.runner.notification.RunNotifier; +import org.simantics.scl.compiler.commands.CommandSession; +import org.simantics.scl.compiler.commands.TestScriptExecutor; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.reporting.SCLReportingHandler; +import org.simantics.tests.modelled.utils.ModelledSTSTest; +import org.simantics.tests.modelled.utils.STSSuiteTestCollector; + +public class ModelledSTSTestRunner extends Runner { + + private Description description; + private ModelledSTSTest test; + + public ModelledSTSTestRunner(ModelledSTSTest test) { + this.test = test; + } + + public String getName() { + return test.getName(); + } + + @Override + public Description getDescription() { + if (description == null) + description = Description.createTestDescription(ModelledSTSTestRunner.class, getName()); + return description; + } + + /** + * This method is called from ModelledSTSSuite (ParentRunner) with the same + * CommandSession + * + * @param session + */ + public void run(CommandSession session) { + try (BufferedReader reader = new BufferedReader(new StringReader(test.getCode()))) { + SCLReportingHandler handler = (SCLReportingHandler) SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER); + new TestScriptExecutor(session, reader, handler, true).execute(); + STSSuiteTestCollector.setTestCoverage(test, session); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void run(RunNotifier notifier) { + notifier.fireTestStarted(getDescription()); + try { + run(new CommandSession(SCLOsgi.MODULE_REPOSITORY, null)); + } finally { + notifier.fireTestFinished(getDescription()); + } + } + + public boolean isIgnored() { + return test.isIgnored(); + } + + public int getPriority() { + return test.getPriority(); + } + + public ModelledSTSTest getTest() { + return test; + } +} diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSSuite.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSSuite.java new file mode 100644 index 000000000..b856787cf --- /dev/null +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSSuite.java @@ -0,0 +1,79 @@ +package org.simantics.tests.modelled.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; + +import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.coverage.CombinedCoverage; +import org.simantics.scl.compiler.module.coverage.CoverageBuilder; +import org.simantics.utils.strings.AlphanumComparator; + +public class ModelledSTSSuite { + + private String name; + private List children; + private String moduleNameFilter; + private List moduleNameFilterPatterns = new ArrayList<>(); + + private CoverageBuilder coverageBuilder; + + ModelledSTSSuite(String name, List children, String moduleNameFilter) { + this.name = name; + this.children = children; + this.moduleNameFilter = moduleNameFilter; + for (String s : moduleNameFilter.split(",")) { + try { + s = s.trim().replaceAll("\\*", "\\\\w*").toLowerCase(); + getModuleNameFilterPatterns().add(Pattern.compile(s)); + } catch (PatternSyntaxException e) { + e.printStackTrace(); + } + } + } + + public String getName() { + return name; + } + + public List getChildren() { + return children; + } + + public List getSortedChildren() { + return new ArrayList<>(children).stream().sorted(ModelledSTSSuite::compareTests).collect(Collectors.toList()); + } + + private static int compareTests(ModelledSTSTest test1, ModelledSTSTest test2) { + if (test1.getPriority() < test2.getPriority()) + return -1; + else if (test1.getPriority() > test2.getPriority()) + return 1; + else + return AlphanumComparator.COMPARATOR.compare(test1.getName(), test2.getName()); + } + + public String getModuleNameFilter() { + return moduleNameFilter; + } + + public void addCoverage(List modules) { + if (coverageBuilder == null) + coverageBuilder = new CoverageBuilder(); + for (Module module : modules) + coverageBuilder.addCoverage(module, true); + } + + public CombinedCoverage getCoverage() { + if (coverageBuilder == null) + return null; + return coverageBuilder.getCoverage(); + } + + public List getModuleNameFilterPatterns() { + return moduleNameFilterPatterns; + } + +} diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java new file mode 100644 index 000000000..00d825d2e --- /dev/null +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java @@ -0,0 +1,44 @@ +package org.simantics.tests.modelled.utils; + +import org.simantics.scl.compiler.module.coverage.CombinedCoverage; + +public class ModelledSTSTest { + + private final String name; + private final String code; + private final int priority; + private final boolean ignored; + + private CombinedCoverage coverage; + + ModelledSTSTest(String name, String code, int priority, boolean ignored) { + this.name = name; + this.code = code; + this.priority = priority; + this.ignored = ignored; + } + + public String getName() { + return name; + } + + public String getCode() { + return code; + } + + public int getPriority() { + return priority; + } + + public boolean isIgnored() { + return ignored; + } + + public void setCoverage(CombinedCoverage coverage) { + this.coverage = coverage; + } + + public CombinedCoverage getCoverage() { + return coverage; + } +} diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/STSSuiteTestCollector.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/STSSuiteTestCollector.java new file mode 100644 index 000000000..10530e185 --- /dev/null +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/STSSuiteTestCollector.java @@ -0,0 +1,125 @@ +package org.simantics.tests.modelled.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.regex.Pattern; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingUtils; +import org.simantics.scl.compiler.commands.CommandSession; +import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.coverage.CoverageUtils; +import org.simantics.scl.compiler.runtime.RuntimeModule; +import org.simantics.scl.runtime.tuple.Tuple0; +import org.simantics.tests.modelled.ontology.TestsResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class STSSuiteTestCollector { + + private static final Logger LOGGER = LoggerFactory.getLogger(STSSuiteTestCollector.class); + + /** + * TODO: The idea of this class was to collect all the tests from shared libraries and construct + * JUnit tests out of them programmatically and then run them with JUnit to get results + * + */ + private static Collection collectTestsFromGraph() { + try { + Collection suitess = Simantics.getSession().syncRequest(new UniqueRead>() { + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + + List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); + if (LOGGER.isInfoEnabled()) + LOGGER.info("Found {} shared ontologies from graph", sharedOntologies.size()); + Collection suites = new HashSet<>(); + TestsResource TESTS = TestsResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + for (Resource sharedOntology : sharedOntologies) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Searching {} for modelled tests", graph.getURI(sharedOntology)); + List stsSuites = ModelingUtils.searchByType(graph, sharedOntology, TESTS.STSSuite); + for (Resource stsSuite : stsSuites) { + try { + Collection tests = graph.syncRequest(new ObjectsWithType(stsSuite, L0.ConsistsOf, TESTS.STSTest)); + if (tests.isEmpty()) + continue; + + List testRunners = new ArrayList<>(tests.size()); + for (Resource test : tests) + testRunners.add(toModelledTest(graph, test)); + + suites.add(toModelledSuite(graph, stsSuite, testRunners)); + } catch (Exception e) { + LOGGER.error("", e); + } + } + } + return suites; + } + }); + return suitess; + } catch (DatabaseException e) { + LOGGER.error("Could not find modelled tests", e); + return Collections.emptyList(); + } + } + + + public static ModelledSTSTest toModelledTest(ReadGraph graph, Resource test) throws DatabaseException { + TestsResource TESTS = TestsResource.getInstance(graph); + String testName = graph.getRelatedValue(test, Layer0.getInstance(graph).HasName, Bindings.STRING); + String code = graph.getRelatedValue(test, TESTS.STSTest_definition, Bindings.STRING); + Integer priority = graph.getPossibleRelatedValue(test, TESTS.STSTest_executionPriority, Bindings.INTEGER); + Boolean ignored = graph.getPossibleRelatedValue(test, TESTS.ignore, Bindings.BOOLEAN); + return new ModelledSTSTest(testName, code, priority != null ? priority : -1, ignored != null ? ignored : false); + } + + public static ModelledSTSSuite toModelledSuite(ReadGraph graph, Resource suite, List children) throws DatabaseException { + TestsResource TESTS = TestsResource.getInstance(graph); + String suiteName = graph.getURI(suite); + String moduleNameFilter = graph.getPossibleRelatedValue2(suite, TESTS.STSSuite_moduleNameFilter, Bindings.STRING); + return new ModelledSTSSuite(suiteName, children, moduleNameFilter); + } + + public static void setTestCoverage(ModelledSTSTest test, CommandSession session) { + Collection runtimeModules = session.getRuntimeEnvironment().getRuntimeModules(); + List modules = new ArrayList<>(runtimeModules.size()); + for (RuntimeModule module : runtimeModules) + modules.add(module.getModule()); + test.setCoverage(CoverageUtils.getCoverage(modules)); + CoverageUtils.resetCoverage(modules); + } + + public static List collectTests() { + return new ArrayList<>(collectTestsFromGraph()); + } + + + public static void setSuiteCoverage(ModelledSTSTest test, ModelledSTSSuite suite, CommandSession session) { + Collection runtimeModules = session.getRuntimeEnvironment().getRuntimeModules(); + List modules = new ArrayList<>(runtimeModules.size()); + for (RuntimeModule module : runtimeModules) { + for (Pattern p : suite.getModuleNameFilterPatterns()) { + if (p.matcher(module.getModule().getName().toLowerCase()).find()) { + modules.add(module.getModule()); + } + } + } + test.setCoverage(CoverageUtils.getCoverage(modules)); + suite.addCoverage(modules); + CoverageUtils.resetCoverage(modules); + } +} diff --git a/features/org.simantics.tests.modelled.feature/feature.xml b/features/org.simantics.tests.modelled.feature/feature.xml index bb8f0a8d8..6c8e61413 100644 --- a/features/org.simantics.tests.modelled.feature/feature.xml +++ b/features/org.simantics.tests.modelled.feature/feature.xml @@ -31,4 +31,25 @@ version="0.0.0" unpack="false"/> + + + + + + -- 2.43.2