From 4789a20d317a245e03096df441baba1ab338c1f0 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Mon, 5 Jun 2017 15:14:49 +0300 Subject: [PATCH] Enhancements to modelled tests * Single test has now an isolated and own SCL CommandSession * Tests can depend on one another and the SCL variables are available for the depenent tests * Added support for declaring SCL variables under the test definition (suitable e.g. for large literals for comparison) refs #7277 Change-Id: I5089bca479f681b42ee955851ab50ce24a3158a3 --- .../graph/Tests.pgraph | 15 +- .../graph/TestsUI.pgraph | 14 +- .../scl/Simantics/TestsUI.scl | 5 + .../tests/modelled/ui/STSCounterPanel.java | 7 + .../tests/modelled/ui/STSTestEditor.java | 6 + .../tests/modelled/ui/STSTestRunnerView.java | 31 +++- .../tests/modelled/ui/STSTestSuiteModel.java | 149 +++++++++++------- .../scl/Simantics/Tests.scl | 5 +- .../tests/modelled/TestsGraphUtils.java | 15 ++ .../modelled/junit/v2/ModelledSTSRunner.java | 31 ++-- .../junit/v2/ModelledSTSSuiteRunner.java | 46 +++--- .../junit/v2/ModelledSTSTestRunner.java | 43 ++--- .../modelled/utils/ModelledSTSSuite.java | 51 +++++- .../tests/modelled/utils/ModelledSTSTest.java | 108 ++++++++++++- .../modelled/utils/STSSuiteTestCollector.java | 103 ++++++------ 15 files changed, 439 insertions(+), 190 deletions(-) diff --git a/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph b/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph index 8364abd18..e3aa1f61f 100644 --- a/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph +++ b/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph @@ -31,6 +31,7 @@ TESTS.STSTest -- TESTS.STSSuite.moduleNameFilter --> L0.String () createSTSSuiteAction res = do syncWrite (\() -> createSTSSuite res) + () + +createSTSVariableAction :: Resource -> () +createSTSVariableAction res = do + syncWrite(\() -> createSTSVariable res) () \ No newline at end of file diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java index e93c793e7..d4d58129d 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java @@ -28,6 +28,7 @@ import org.eclipse.swt.widgets.Text; */ public class STSCounterPanel extends Composite { protected Text numberOfErrors; + protected Text numberOfSkipped; protected Text numberOfFailures; protected Text numberOfRuns; protected int total; @@ -46,6 +47,7 @@ public class STSCounterPanel extends Composite { setLayout(gridLayout); numberOfRuns= createLabel("Runs:", null, " 0/0 "); //$NON-NLS-1$ + numberOfSkipped = createLabel("Skipped:", null," 0 "); numberOfErrors= createLabel("Errors:", fErrorIcon, " 0 "); //$NON-NLS-1$ numberOfFailures= createLabel("Failures:", fFailureIcon, " 0 "); //$NON-NLS-1$ @@ -129,6 +131,11 @@ public class STSCounterPanel extends Composite { assumptionFailedCount= assumptionFailureCount; } + public void setIgnoredValue(int value) { + numberOfSkipped.setText(Integer.toString(value)); + redraw(); + } + public void setErrorValue(int value) { numberOfErrors.setText(Integer.toString(value)); redraw(); 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 21bb5e4d7..ea00d8f07 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 @@ -4,5 +4,11 @@ import org.simantics.scl.ui.editor2.SCLModuleEditor2; public class STSTestEditor extends SCLModuleEditor2 { + + @Override + public void setFocus() { + // TODO Auto-generated method stub + super.setFocus(); + } } diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java index 203f28325..b8b809449 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java @@ -7,6 +7,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.jface.layout.TreeColumnLayout; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ColumnWeightData; @@ -32,6 +33,9 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.part.PageBook; @@ -54,19 +58,21 @@ public class STSTestRunnerView { private Composite counterComposite; @PostConstruct - void createView(Composite parent) { + void createView(MPart part, Composite parent) { GridLayout gridLayout= new GridLayout(); gridLayout.marginWidth= 0; gridLayout.marginHeight= 0; parent.setLayout(gridLayout); - counterComposite= createProgressCountPanel(parent); + counterComposite = createProgressCountPanel(parent); counterComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); counterComposite.pack(); SashForm sashForm = createSashForm(parent); sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); + +// IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); } private SashForm createSashForm(Composite parent) { @@ -335,6 +341,26 @@ public class STSTestRunnerView { treeViewer.setContentProvider(provider); treeViewer.setLabelProvider(provider); + + Menu menu = new Menu(treeViewer.getControl()); + + MenuItem item1 = new MenuItem(menu, SWT.PUSH); + item1.setText("Stop"); + item1.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(Event event) { + TreeSelection selec = (TreeSelection) treeViewer.getSelection(); + if (!selec.isEmpty()) { + Object elem = selec.getFirstElement(); + provider.getModel().interrupt(); + + } + } + }); + + treeViewer.getControl().setMenu(menu); + viewerbook.showPage(treeViewer.getTree()); @@ -388,6 +414,7 @@ public class STSTestRunnerView { counterPanel.setTotal(totalCount); counterPanel.setRunValue(startedCount, ignoredCount, assumptionFailureCount); + counterPanel.setIgnoredValue(ignoredCount); counterPanel.setErrorValue(errorCount); counterPanel.setFailureValue(failureCount); 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 976efa2c2..b6cda3fdc 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 @@ -1,13 +1,16 @@ package org.simantics.tests.modelled.ui; -import java.io.BufferedReader; -import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; -import java.util.regex.Pattern; +import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.swt.graphics.Image; import org.simantics.Simantics; import org.simantics.db.ReadGraph; @@ -15,22 +18,21 @@ import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; 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.coverage.CombinedCoverage; -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.osgi.SCLOsgi; +import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler; +import org.simantics.scl.runtime.reporting.SCLReportingHandler; import org.simantics.tests.modelled.ontology.TestsResource; import org.simantics.tests.modelled.utils.ModelledSTSSuite; import org.simantics.tests.modelled.utils.ModelledSTSTest; +import org.simantics.tests.modelled.utils.ModelledSTSTest.CommandSessionVariable; import org.simantics.tests.modelled.utils.STSSuiteTestCollector; public class STSTestSuiteModel { - static class STSTest { + private Map> storedVars = new HashMap<>(); + + class STSTest { private final ModelledSTSTest test; @@ -66,31 +68,41 @@ public class STSTestSuiteModel { return parent; } - public void execute(CommandSession session) { + public void execute() { isRunning = true; - - TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(getDefinition())), new AbstractSCLReportingHandler() { - - @Override - public void print(String text) { - appendOutput(text + "\n"); - } - - @Override - public void printCommand(String command) { - appendOutput("> " + command + "\n"); - } - - @Override - public void printError(String error) { - appendOutput(error + "\n"); - } - }, true); long start = System.currentTimeMillis(); + Object old = SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER); try { if (parent != null) parent.startedCount++; - executor.execute(); + + SCLContext.getCurrent().put(SCLReportingHandler.REPORTING_HANDLER, new AbstractSCLReportingHandler() { + + @Override + public void print(String text) { + appendOutput(text + "\n"); + } + + @Override + public void printCommand(String command) { + appendOutput("> " + command + "\n"); + } + + @Override + public void printError(String error) { + appendOutput(error + "\n"); + } + }); + List resolvedVars = new ArrayList<>(); + for (String deps : test.getDependencies()) { + List vars = storedVars.get(deps); + if (vars != null) + resolvedVars.addAll(vars); + } + + List vars = test.run(resolvedVars); + storedVars.put(test.getName(), vars); + executed = true; } catch (Throwable t) { t.printStackTrace(); @@ -101,8 +113,9 @@ public class STSTestSuiteModel { isRunning = false; long end = System.currentTimeMillis(); duration = end - start; + + SCLContext.getCurrent().put(SCLReportingHandler.REPORTING_HANDLER, old); } - } protected void appendOutput(String text) { @@ -135,7 +148,7 @@ public class STSTestSuiteModel { } } - static class STSSuite { + class STSSuite { private ModelledSTSSuite suite; private STSTest[] children; @@ -216,6 +229,7 @@ public class STSTestSuiteModel { private STSSuite suite; private STSTest test; private final List listeners = new ArrayList<>(); + private Job currentJob; public STSTestSuiteModel() { } @@ -237,30 +251,47 @@ public class STSTestSuiteModel { } public void execute() { - - ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY); - if (suite != null) { - repo.setAdvisor(new ModuleCompilationOptionsAdvisor() { + String command; + if (suite != null) + command = suite.getName(); + else + command = test.getName(); + if (currentJob != null) + currentJob.cancel(); + currentJob = new Job(command) { + @Override + protected IStatus run(IProgressMonitor monitor) { + if (suite != null) { + executeSuite(); + } else if (test != null) { + executeTest(); + } + return Status.OK_STATUS; + } + + @Override + protected void canceling() { + Thread thread = getThread(); + if(thread != null) + thread.interrupt(); - @Override - public ModuleCompilationOptions getOptions(String moduleName) { - boolean coverage = false; - for (Pattern p : suite.suite.getModuleNameFilterPatterns()) { - if (p.matcher(moduleName.toLowerCase()).find()) { - coverage = true; - break; - } - } - return new ModuleCompilationOptions(coverage); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); } - }); - } - CommandSession session = new CommandSession(repo, null); - if (suite != null) { - executeSuite(session); - } else if (test != null) { - executeTest(session); - } + + thread = getThread(); + if(thread != null) + thread.stop(); + } + }; + currentJob.schedule(); + } + + public void interrupt() { + if (currentJob != null) + currentJob.cancel(); } private void testExecuted() { @@ -269,23 +300,21 @@ public class STSTestSuiteModel { }); } - private void executeSuite(CommandSession session) { + private void executeSuite() { for (STSTest test : suite.getChildren()) { if (test.isIgnored()) { testExecuted(); test.getParent().ignoredCount++; continue; } - test.execute(session); - STSSuiteTestCollector.setSuiteCoverage(test.test, suite.suite, session); + test.execute(); testExecuted(); } } - private void executeTest(CommandSession session) { - test.execute(session); + private void executeTest() { + test.execute(); testExecuted(); - STSSuiteTestCollector.setTestCoverage(test.test, session); } public boolean hasChildren(Object element) { diff --git a/bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl b/bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl index fe80e1303..ce3cfb154 100644 --- a/bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl +++ b/bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl @@ -1,5 +1,6 @@ include "Simantics/DB" importJava "org.simantics.tests.modelled.TestsGraphUtils" where - createSTSTest :: Resource -> Resource - createSTSSuite :: Resource -> () + createSTSTest :: Resource -> Resource + createSTSSuite :: Resource -> Resource + createSTSVariable :: Resource -> Resource diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java index e9ce7d06f..c5253bd5a 100644 --- a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java @@ -31,9 +31,24 @@ public class TestsGraphUtils { private static final String STS_TEST_PREFIX = "STSTest"; private static final String STS_SUITE_PREFIX = "STSSuite"; + private static final String STS_VARIABLE_PREFIX = "STSVariable"; private TestsGraphUtils() {} + public static Resource createSTSVariable(WriteGraph graph, Resource parent) throws DatabaseException { + String name = NameUtils.findFreshEscapedName(graph, STS_VARIABLE_PREFIX, parent); + Resource stsVariable = graph.newResource(); + + Layer0 L0 = Layer0.getInstance(graph); + TestsResource TESTS = TestsResource.getInstance(graph); + + graph.claim(parent, L0.ConsistsOf, L0.PartOf, stsVariable); + graph.claim(stsVariable, L0.InstanceOf, TESTS.STSVariable); + graph.claimLiteral(stsVariable, L0.HasName, name, Bindings.STRING); + graph.claimLiteral(stsVariable, TESTS.STSVariable_definition, "", Bindings.STRING); + return stsVariable; + } + public static Resource createSTSTest(WriteGraph graph, Resource parent) throws DatabaseException { String name = NameUtils.findFreshEscapedName(graph, STS_TEST_PREFIX, parent); Resource stsTest = graph.newResource(); 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 index c74f6efae..e77224b58 100644 --- 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 @@ -1,7 +1,8 @@ package org.simantics.tests.modelled.junit.v2; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; import org.eclipse.core.runtime.NullProgressMonitor; import org.junit.runner.Description; @@ -12,28 +13,30 @@ 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.ModelledSTSSuite; import org.simantics.tests.modelled.utils.STSSuiteTestCollector; public class ModelledSTSRunner extends ParentRunner { - private CommandSession commandSession; + private final List children; - public ModelledSTSRunner(Class testClass) throws Exception { + public ModelledSTSRunner(Class testClass) throws InitializationError { super(testClass); - initialize0(); + try { + initialize0(); + Collection suites = STSSuiteTestCollector.collectTests(); + children = new ArrayList<>(suites.size()); + for (ModelledSTSSuite suite : suites) { + children.add(new ModelledSTSSuiteRunner(suite)); + } + } catch (Exception e) { + throw new InitializationError(e); + } } @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()); + return children; } @Override @@ -55,7 +58,6 @@ public class ModelledSTSRunner extends ParentRunner { @Override protected void runChild(ModelledSTSSuiteRunner child, RunNotifier notifier) { - child.setCommandSesssion(commandSession); child.run(notifier); // TODO: Add coverage reporting to ModelledSTSRunner // CombinedCoverage cover = child.getCoverage(); @@ -70,7 +72,6 @@ public class ModelledSTSRunner extends ParentRunner { private void initialize0() throws Exception { AcornTests.newSimanticsWorkspace(null, null); - this.commandSession = new CommandSession(SCLOsgi.MODULE_REPOSITORY, null); initialize(); } 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 index a568976cc..5b7a8ef0a 100644 --- 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 @@ -1,26 +1,32 @@ package org.simantics.tests.modelled.junit.v2; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; 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.junit.runners.model.InitializationError; 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; +import org.simantics.tests.modelled.utils.ModelledSTSTest; +import org.simantics.tests.modelled.utils.ModelledSTSTest.CommandSessionVariable; public class ModelledSTSSuiteRunner extends ParentRunner { private final ModelledSTSSuite suite; - private CommandSession commandSession; + private final List children; + private Map> storedVariables; - public ModelledSTSSuiteRunner(ModelledSTSSuite suite) throws Exception { + public ModelledSTSSuiteRunner(ModelledSTSSuite suite) throws InitializationError { super(ModelledSTSSuiteRunner.class); this.suite = suite; + this.children = new ArrayList<>(suite.getChildren().size()); + for (ModelledSTSTest test : suite.getSortedChildren()) { + children.add(new ModelledSTSTestRunner(test)); + } } @Override @@ -30,7 +36,7 @@ public class ModelledSTSSuiteRunner extends ParentRunner @Override protected List getChildren() { - return suite.getChildren().stream().map(test -> new ModelledSTSTestRunner(test)).collect(Collectors.toList()); + return children; } @Override @@ -44,15 +50,21 @@ public class ModelledSTSSuiteRunner extends ParentRunner if (isIgnored(child)) { notifier.fireTestIgnored(description); } else { - notifier.fireTestStarted(description); try { - child.run(getCommandSession()); + List variables = new ArrayList<>(); + for (String dep : child.getTest().getDependencies()) { + List storedVars = storedVariables.get(dep); + if (storedVars != null) { + variables.addAll(storedVars); + } + } + List newVars = child.runWithVars(variables); + storedVariables.put(child.getTest().getName(), newVars); notifier.fireTestFinished(description); - STSSuiteTestCollector.setSuiteCoverage(child.getTest(), suite, getCommandSession()); - } catch (Throwable e) { + } catch (Exception e) { notifier.fireTestFailure(new Failure(description, e)); } - } + } } @Override @@ -60,16 +72,6 @@ public class ModelledSTSSuiteRunner extends ParentRunner 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 index a2acbfcb8..5f8ea6c16 100644 --- 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 @@ -1,18 +1,14 @@ package org.simantics.tests.modelled.junit.v2; -import java.io.BufferedReader; -import java.io.StringReader; +import java.io.IOException; +import java.util.List; import org.junit.runner.Description; import org.junit.runner.Runner; +import org.junit.runner.notification.Failure; 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; +import org.simantics.tests.modelled.utils.ModelledSTSTest.CommandSessionVariable; public class ModelledSTSTestRunner extends Runner { @@ -23,41 +19,20 @@ public class ModelledSTSTestRunner extends Runner { this.test = test; } - public String getName() { - return test.getName(); - } - @Override public Description getDescription() { if (description == null) - description = Description.createTestDescription(ModelledSTSTestRunner.class, getName()); + description = Description.createTestDescription(ModelledSTSTestRunner.class, test.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); - } + public List runWithVars(List vars) throws IOException { + return test.run(vars); } - + @Override public void run(RunNotifier notifier) { - notifier.fireTestStarted(getDescription()); - try { - run(new CommandSession(SCLOsgi.MODULE_REPOSITORY, null)); - } finally { - notifier.fireTestFinished(getDescription()); - } + throw new UnsupportedOperationException(); } public boolean isIgnored() { 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 index b856787cf..7ccb3ccd3 100644 --- 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 @@ -1,10 +1,15 @@ package org.simantics.tests.modelled.utils; import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; 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; @@ -19,10 +24,12 @@ public class ModelledSTSSuite { private List moduleNameFilterPatterns = new ArrayList<>(); private CoverageBuilder coverageBuilder; + private Map variables; - ModelledSTSSuite(String name, List children, String moduleNameFilter) { + ModelledSTSSuite(String name, List children, String moduleNameFilter, Map variables) { this.name = name; this.children = children; + this.variables = variables; this.moduleNameFilter = moduleNameFilter; for (String s : moduleNameFilter.split(",")) { try { @@ -42,8 +49,46 @@ public class ModelledSTSSuite { return children; } + static Comparator comparator = (test1, test2) -> compareTests(test1, test2); + public List getSortedChildren() { - return new ArrayList<>(children).stream().sorted(ModelledSTSSuite::compareTests).collect(Collectors.toList()); + Set testsWithDeps = new HashSet<>(); + // This TreeMap sorts the tests with the comparator + TreeMap sortedTests = new TreeMap<>(comparator); + for (ModelledSTSTest test : getChildren()) { + Set testDependencies = test.getDependencies(); + if (testDependencies.isEmpty()) { + // First tests that have no dependencies + sortedTests.put(test, test.getName()); + } else { + // These are resolved later + testsWithDeps.add(test); + } + } + + // Construct a LinkedList that is returned as a result + LinkedList results = new LinkedList<>(sortedTests.keySet()); + +// Set temp = new HashSet<>(testsWithDeps); + // Now resolve tests with dependencies + for (ModelledSTSTest testWithDep : testsWithDeps) { + boolean satisfied = true; + for (String dep : testWithDep.getDependencies()) { + if (!sortedTests.containsValue(dep)) { + satisfied = false; + } else { + testWithDep.resolveDependency(dep); + } + } + if (satisfied) { + results.addLast(testWithDep); + sortedTests.put(testWithDep, testWithDep.getName()); + } else { + // Not satisfied + System.out.println(testWithDep.getName() + " not satisfied"); + } + } + return results; } private static int compareTests(ModelledSTSTest test1, ModelledSTSTest test2) { 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 index 00d825d2e..3430696b8 100644 --- 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 @@ -1,6 +1,26 @@ package org.simantics.tests.modelled.utils; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import org.simantics.scl.compiler.commands.CommandSession; +import org.simantics.scl.compiler.commands.TestScriptExecutor; import org.simantics.scl.compiler.module.coverage.CombinedCoverage; +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.types.Type; +import org.simantics.scl.compiler.types.Types; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.reporting.SCLReportingHandler; public class ModelledSTSTest { @@ -8,14 +28,20 @@ public class ModelledSTSTest { private final String code; private final int priority; private final boolean ignored; - + private Set dependencies; + private Set unresolvedDependencies; + private CombinedCoverage coverage; + private Map variables; - ModelledSTSTest(String name, String code, int priority, boolean ignored) { + ModelledSTSTest(String name, String code, int priority, boolean ignored, Set dependencies, Map variables) { this.name = name; this.code = code; this.priority = priority; this.ignored = ignored; + this.dependencies = dependencies; + this.unresolvedDependencies = new HashSet<>(dependencies); + this.variables = variables; } public String getName() { @@ -31,7 +57,7 @@ public class ModelledSTSTest { } public boolean isIgnored() { - return ignored; + return (ignored || !unresolvedDependencies.isEmpty()); } public void setCoverage(CombinedCoverage coverage) { @@ -41,4 +67,80 @@ public class ModelledSTSTest { public CombinedCoverage getCoverage() { return coverage; } + + public static class CommandSessionVariable { + + private final String name; + private final Type type; + private final Object value; + + public CommandSessionVariable(String name, Type type, Object value) { + this.name = name; + this.type = type; + this.value = value; + } + + public String getName() { + return name; + } + + public Type getType() { + return type; + } + + public Object getValue() { + return value; + } + } + + public List run(List vars) throws IOException { + ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY); + repo.setAdvisor(new ModuleCompilationOptionsAdvisor() { + + @Override + public ModuleCompilationOptions getOptions(String moduleName) { + // TODO: default to false + boolean coverage = true; + // TODO: add moduleName filters back +// for (Pattern p : getModuleNameFilterPatterns()) { +// if (p.matcher(moduleName.toLowerCase()).find()) { +// coverage = true; +// break; +// } +// } + return new ModuleCompilationOptions(coverage); + } + }); + + SCLReportingHandler handler = (SCLReportingHandler) SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER); + CommandSession session = new CommandSession(repo, handler); + + for (CommandSessionVariable var : vars) + session.setVariable(var.getName(), var.getType(), var.getValue()); + + for (Map.Entry entry : variables.entrySet()) + session.setVariable(entry.getKey(), Types.STRING, entry.getValue()); + + new TestScriptExecutor(session, new BufferedReader(new StringReader(code)), handler, true).execute(); + STSSuiteTestCollector.setTestCoverage(this, session); + + // Return variables from this session + List result = new ArrayList<>(); + for (String var : session.getVariables()) + result.add(new CommandSessionVariable(var, session.getVariableType(var), session.getVariableValue(var))); + + return result; + } + + public Set getDependencies() { + return dependencies; + } + + public Set getUnresolvedDependencies() { + return unresolvedDependencies; + } + + public boolean resolveDependency(String testDep) { + return unresolvedDependencies.remove(testDep); + } } 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 index 10530e185..8917d1646 100644 --- 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 @@ -1,10 +1,12 @@ package org.simantics.tests.modelled.utils; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; -import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.regex.Pattern; import org.simantics.Simantics; @@ -32,66 +34,84 @@ public class STSSuiteTestCollector { /** * 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 + * @throws DatabaseException * */ - private static Collection collectTestsFromGraph() { - try { - Collection suitess = Simantics.getSession().syncRequest(new UniqueRead>() { + public static Collection collectTests() throws DatabaseException { + 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); + @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("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)); + 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); - } + 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(); - } + return suites; + } + }); + return suitess; } public static ModelledSTSTest toModelledTest(ReadGraph graph, Resource test) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); TestsResource TESTS = TestsResource.getInstance(graph); - String testName = graph.getRelatedValue(test, Layer0.getInstance(graph).HasName, Bindings.STRING); + String testName = graph.getRelatedValue(test, L0.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); + + String dependencies = graph.getPossibleRelatedValue(test, TESTS.dependencies, Bindings.STRING); + String[] actualDeps = dependencies.isEmpty() ? new String[0] : dependencies.split(","); + + // collect variables + Collection stsVariables = graph.getObjects(test, L0.ConsistsOf); + Map variables = new HashMap<>(stsVariables.size()); + for (Resource stsVariable : stsVariables) { + String name = graph.getRelatedValue(stsVariable, L0.HasName, Bindings.STRING); + String value = graph.getRelatedValue(stsVariable, TESTS.STSVariable_definition); + variables.put(name, value); + } + return new ModelledSTSTest(testName, code, priority != null ? priority : -1, ignored != null ? ignored : false, new HashSet<>(Arrays.asList(actualDeps)), variables); } 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); + + Layer0 L0 = Layer0.getInstance(graph); + Collection stsVariables = graph.sync(new ObjectsWithType(suite, L0.ConsistsOf, TESTS.STSVariable)); + Map variables = new HashMap<>(stsVariables.size()); + for (Resource stsVariable : stsVariables) { + String name = graph.getRelatedValue(stsVariable, L0.HasName, Bindings.STRING); + String value = graph.getRelatedValue(stsVariable, TESTS.STSVariable_definition); + variables.put(name, value); + } + return new ModelledSTSSuite(suiteName, children, moduleNameFilter, variables); } public static void setTestCoverage(ModelledSTSTest test, CommandSession session) { @@ -102,11 +122,6 @@ public class STSSuiteTestCollector { 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(); -- 2.47.1