X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.tests.modelled.ui%2Fsrc%2Forg%2Fsimantics%2Ftests%2Fmodelled%2Fui%2FSTSTestSuiteModel.java;fp=bundles%2Forg.simantics.tests.modelled.ui%2Fsrc%2Forg%2Fsimantics%2Ftests%2Fmodelled%2Fui%2FSTSTestSuiteModel.java;h=188574e545d4d329a0fde8de1a9623bf7a6e0cb5;hp=0000000000000000000000000000000000000000;hb=3b5069d0d30e7de27f73d88d5e89d29052291a34;hpb=bf75fd9740858140eac90c18f0bca0aea3893248 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 new file mode 100644 index 000000000..188574e54 --- /dev/null +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java @@ -0,0 +1,504 @@ +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 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; +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; + +public class STSTestSuiteModel { + + static class STSTest { + + private final Resource 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) { + this.test = test; + this.parent = parent; + this.definition = definition; + this.name = name; + this.priority = executionPrioprity; + } + + public String getName() { + return name; + } + + public String getLabel() { + StringBuilder sb = new StringBuilder(); + sb.append(name); + if (executed || failed) + sb.append(" (").append(duration).append(" ms)"); + return sb.toString(); + } + + public String getDefinition() { + return definition; + } + + public STSSuite getParent() { + return parent; + } + + public void execute(CommandSession session) { + isRunning = true; + + TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(definition)), 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"); + } + }); + long start = System.currentTimeMillis(); + try { + if (parent != null) + parent.startedCount++; + executor.execute(); + executed = true; + } catch (Throwable t) { + t.printStackTrace(); + if (parent != null) + parent.failureCount++; + failed = true; + } finally { + isRunning = false; + long end = System.currentTimeMillis(); + duration = end - start; + } + + } + + protected void appendOutput(String text) { + output.add(text); + } + + public List getOutput() { + return output; + } + + public void setCoverage(CombinedCoverage coverage) { + this.coverage = coverage; + } + + public CombinedCoverage getCoverage() { + return coverage; + } + + @Override + public String toString() { + return name + " [priority=" + priority + ", executed=" + executed + ", duration=" + duration + "]"; + } + } + + static class STSSuite { + + private List moduleNameFilterPatterns = new ArrayList<>(); + private final Resource suite; + private final String name; + private STSTest[] children; + private int startedCount; + private int errorCount; + private int failureCount; + private CoverageBuilder coverageBuilder; + + public STSSuite(Resource suite, String name, String moduleNameFilter) { + 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() { + return children; + } + + public String getName() { + return name; + } + + public String getLabel() { + StringBuilder sb = new StringBuilder(); + sb.append(name); + long totalTime = 0; + if (children != null) { + for (STSTest test : children) { + if (test.executed || test.failed) { + totalTime += test.duration; + } + } + } + if (totalTime != 0) + sb.append(" (").append(totalTime).append(" ms)"); + return sb.toString(); + } + + public boolean isRunning() { + boolean running = false; + if (children != null) { + for (STSTest test: children) { + if (test.isRunning) { + running = true; + break; + } + } + } + return running; + } + + public boolean executed() { + boolean executed = true; + if (children != null) { + for (STSTest test: children) { + if (!test.executed) { + executed = false; + break; + } + } + } + return executed; + } + + public boolean failed() { + boolean failed = false; + if (children != null) { + for (STSTest test: children) { + if (test.failed) { + failed = true; + break; + } + } + } + return failed; + } + + 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(); + } + } + + + private STSSuite suite; + private STSTest test; + private final List listeners = new ArrayList<>(); + + public STSTestSuiteModel() { + } + + public void addListener(STSExecutionListener listener) { + listeners.add(listener); + } + + public void removeListener(STSExecutionListener listener) { + listeners.remove(listener); + } + + public Object[] getElements() { + if (suite != null) + return new Object[] {suite}; + else if (test != null) + return new Object[] {test}; + else return null; + } + + public void execute() { + + ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY); + if (suite != null) { + repo.setAdvisor(new ModuleCompilationOptionsAdvisor() { + + @Override + public ModuleCompilationOptions getOptions(String moduleName) { + boolean coverage = false; + for (Pattern p : suite.moduleNameFilterPatterns) { + if (p.matcher(moduleName.toLowerCase()).find()) { + coverage = true; + break; + } + } + return new ModuleCompilationOptions(coverage); + } + }); + } + CommandSession session = new CommandSession(repo, null); + if (suite != null) { + executeSuite(session); + } else if (test != null) { + executeTest(session); + } + } + + private void testExecuted() { + listeners.forEach(listener -> { + listener.testExecuted(); + }); + } + + 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()); + } + } + } + test.setCoverage(CoverageUtils.getCoverage(modules)); + suite.addCoverage(modules); + + CoverageUtils.resetCoverage(modules); + + 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); + + } + + + public boolean hasChildren(Object element) { + if (element instanceof STSTest) { + return false; + } else if (element instanceof STSSuite) { + STSSuite suite = (STSSuite) element; + return (suite.getChildren() != null ? suite.getChildren().length > 0 : false); + } else { + throw new IllegalArgumentException(element.toString()); + } + } + + public Object getParent(Object element) { + if (element instanceof STSTest) { + return ((STSTest) element).getParent(); + } else if (element instanceof STSSuite) { + return null; + } else { + throw new IllegalArgumentException(element.toString()); + } + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof STSTest) { + return null; + } else if (parentElement instanceof STSSuite) { + STSSuite suite = (STSSuite) parentElement; + return suite.getChildren(); + } else { + throw new IllegalArgumentException(parentElement.toString()); + } + } + + public String getText(Object element) { + if (element instanceof STSTest) + return ((STSTest)element).getLabel(); + else if (element instanceof STSSuite) + return ((STSSuite)element).getLabel(); + else + throw new IllegalArgumentException(element.toString()); + } + + public Image getImage(Object element) { + if (element instanceof STSSuite) { + STSSuite suite = (STSSuite) element; + if (suite.isRunning()) + return STSTestSuiteProvider.suiteRunningIcon; + else if (suite.executed()) + return STSTestSuiteProvider.suiteOkIcon; + else if (suite.failed()) + return STSTestSuiteProvider.suiteFailIcon; + else + return STSTestSuiteProvider.suiteIcon; + } else if (element instanceof STSTest) { + STSTest test = (STSTest) element; + if (test.isRunning) + return STSTestSuiteProvider.testRunningIcon; + else if (test.executed) + return STSTestSuiteProvider.testOkIcon; + else if (test.failed) + return STSTestSuiteProvider.testFailIcon; + else + return STSTestSuiteProvider.testIcon; + } + return null; + } + + public void updateInput(Resource root) { + suite = null; + test = null; + try { + Simantics.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + 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); + } 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; + if (o1.priority > o2.priority) + return 1; + return 0; + }); + suite.children(tests.toArray(new STSTest[tests.size()])); + } else { + throw new IllegalArgumentException(root.toString()); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + public List getOutput(Object element) { + if (element instanceof STSTest) { + STSTest test = (STSTest) element; + return test.getOutput(); + } + return Collections.emptyList(); + } + + public int getStartedCount() { + if (suite != null) + return suite.startedCount; + else + return 0; + } + + public int getIgnoredCount() { + return 0; + } + + public int getTotalCount() { + if (suite != null && suite.getChildren() != null) + return suite.getChildren().length; + else if (test != null) + return 1; + else + return 0; + } + + public int getErrorCount() { + if (suite != null) + return suite.errorCount; + return 0; + } + + public int getFailureCount() { + if (suite != null) + return suite.failureCount; + return 0; + } + + public int getAssumptionFailureCount() { + return 0; + } + + public boolean isStopped() { + if (suite != null) + return !suite.isRunning(); + else + return test.isRunning; + } +} +