1 package org.simantics.tests.modelled.ui;
3 import java.io.BufferedReader;
4 import java.io.StringReader;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.Collections;
9 import java.util.regex.Pattern;
10 import java.util.regex.PatternSyntaxException;
12 import org.eclipse.swt.graphics.Image;
13 import org.simantics.Simantics;
14 import org.simantics.databoard.Bindings;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.common.request.ReadRequest;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.layer0.Layer0;
20 import org.simantics.scl.compiler.commands.CommandSession;
21 import org.simantics.scl.compiler.commands.TestScriptExecutor;
22 import org.simantics.scl.compiler.module.Module;
23 import org.simantics.scl.compiler.module.coverage.CombinedCoverage;
24 import org.simantics.scl.compiler.module.coverage.CoverageBuilder;
25 import org.simantics.scl.compiler.module.coverage.CoverageUtils;
26 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
27 import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;
28 import org.simantics.scl.compiler.module.repository.ModuleRepository;
29 import org.simantics.scl.compiler.runtime.RuntimeModule;
30 import org.simantics.scl.osgi.SCLOsgi;
31 import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
32 import org.simantics.tests.modelled.ontology.TestsResource;
33 import org.simantics.utils.strings.AlphanumComparator;
35 public class STSTestSuiteModel {
37 static class STSTest {
39 private final Resource test;
40 private final STSSuite parent;
41 private final String definition;
42 private final String name;
43 private boolean executed = false;
44 private long duration;
45 private boolean failed = false;
46 private boolean isRunning = false;
47 private List<String> output = new ArrayList<>();
48 private CombinedCoverage coverage;
51 public STSTest(Resource test, STSSuite parent, String definition, String name, int executionPrioprity) {
54 this.definition = definition;
56 this.priority = executionPrioprity;
59 public String getName() {
63 public String getLabel() {
64 StringBuilder sb = new StringBuilder();
66 if (executed || failed)
67 sb.append(" (").append(duration).append(" ms)");
71 public String getDefinition() {
75 public STSSuite getParent() {
79 public void execute(CommandSession session) {
82 TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(definition)), new AbstractSCLReportingHandler() {
85 public void print(String text) {
86 appendOutput(text + "\n");
90 public void printCommand(String command) {
91 appendOutput("> " + command + "\n");
95 public void printError(String error) {
96 appendOutput(error + "\n");
99 long start = System.currentTimeMillis();
102 parent.startedCount++;
105 } catch (Throwable t) {
108 parent.failureCount++;
112 long end = System.currentTimeMillis();
113 duration = end - start;
118 protected void appendOutput(String text) {
122 public List<String> getOutput() {
126 public void setCoverage(CombinedCoverage coverage) {
127 this.coverage = coverage;
130 public CombinedCoverage getCoverage() {
135 public String toString() {
136 return name + " [priority=" + priority + ", executed=" + executed + ", duration=" + duration + "]";
140 static class STSSuite {
142 private List<Pattern> moduleNameFilterPatterns = new ArrayList<>();
143 private final Resource suite;
144 private final String name;
145 private STSTest[] children;
146 private int startedCount;
147 private int errorCount;
148 private int failureCount;
149 private CoverageBuilder coverageBuilder;
151 public STSSuite(Resource suite, String name, String moduleNameFilter) {
154 for (String s : moduleNameFilter.split(",")) {
156 s = s.trim().replaceAll("\\*", "\\\\w*").toLowerCase();
157 moduleNameFilterPatterns.add(Pattern.compile(s));
158 } catch (PatternSyntaxException e) {
164 public void children(STSTest[] children) {
165 this.children = children;
168 public STSTest[] getChildren() {
172 public String getName() {
176 public String getLabel() {
177 StringBuilder sb = new StringBuilder();
180 if (children != null) {
181 for (STSTest test : children) {
182 if (test.executed || test.failed) {
183 totalTime += test.duration;
188 sb.append(" (").append(totalTime).append(" ms)");
189 return sb.toString();
192 public boolean isRunning() {
193 boolean running = false;
194 if (children != null) {
195 for (STSTest test: children) {
196 if (test.isRunning) {
205 public boolean executed() {
206 boolean executed = true;
207 if (children != null) {
208 for (STSTest test: children) {
209 if (!test.executed) {
218 public boolean failed() {
219 boolean failed = false;
220 if (children != null) {
221 for (STSTest test: children) {
231 public void addCoverage(List<Module> modules) {
232 if (coverageBuilder == null) {
233 coverageBuilder = new CoverageBuilder();
235 for (Module module : modules)
236 coverageBuilder.addCoverage(module, true);
239 public CombinedCoverage getCoverage() {
240 if (coverageBuilder == null)
242 return coverageBuilder.getCoverage();
247 private STSSuite suite;
248 private STSTest test;
249 private final List<STSExecutionListener> listeners = new ArrayList<>();
251 public STSTestSuiteModel() {
254 public void addListener(STSExecutionListener listener) {
255 listeners.add(listener);
258 public void removeListener(STSExecutionListener listener) {
259 listeners.remove(listener);
262 public Object[] getElements() {
264 return new Object[] {suite};
265 else if (test != null)
266 return new Object[] {test};
270 public void execute() {
272 ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY);
274 repo.setAdvisor(new ModuleCompilationOptionsAdvisor() {
277 public ModuleCompilationOptions getOptions(String moduleName) {
278 boolean coverage = false;
279 for (Pattern p : suite.moduleNameFilterPatterns) {
280 if (p.matcher(moduleName.toLowerCase()).find()) {
285 return new ModuleCompilationOptions(coverage);
289 CommandSession session = new CommandSession(repo, null);
291 executeSuite(session);
292 } else if (test != null) {
293 executeTest(session);
297 private void testExecuted() {
298 listeners.forEach(listener -> {
299 listener.testExecuted();
303 private void executeSuite(CommandSession session) {
305 for (STSTest test : suite.getChildren()) {
306 test.execute(session);
308 Collection<RuntimeModule> runtimeModules = session.getRuntimeEnvironment().getRuntimeModules();
309 List<Module> modules = new ArrayList<>(runtimeModules.size());
310 for (RuntimeModule module : runtimeModules) {
311 for (Pattern p : suite.moduleNameFilterPatterns) {
312 if (p.matcher(module.getModule().getName().toLowerCase()).find()) {
313 modules.add(module.getModule());
317 test.setCoverage(CoverageUtils.getCoverage(modules));
318 suite.addCoverage(modules);
320 CoverageUtils.resetCoverage(modules);
327 private void executeTest(CommandSession session) {
329 test.execute(session);
332 Collection<RuntimeModule> runtimeModules = session.getRuntimeEnvironment().getRuntimeModules();
333 List<Module> modules = new ArrayList<>(runtimeModules.size());
334 for (RuntimeModule module : runtimeModules) {
335 modules.add(module.getModule());
337 test.setCoverage(CoverageUtils.getCoverage(modules));
339 CoverageUtils.resetCoverage(modules);
344 public boolean hasChildren(Object element) {
345 if (element instanceof STSTest) {
347 } else if (element instanceof STSSuite) {
348 STSSuite suite = (STSSuite) element;
349 return (suite.getChildren() != null ? suite.getChildren().length > 0 : false);
351 throw new IllegalArgumentException(element.toString());
355 public Object getParent(Object element) {
356 if (element instanceof STSTest) {
357 return ((STSTest) element).getParent();
358 } else if (element instanceof STSSuite) {
361 throw new IllegalArgumentException(element.toString());
365 public Object[] getChildren(Object parentElement) {
366 if (parentElement instanceof STSTest) {
368 } else if (parentElement instanceof STSSuite) {
369 STSSuite suite = (STSSuite) parentElement;
370 return suite.getChildren();
372 throw new IllegalArgumentException(parentElement.toString());
376 public String getText(Object element) {
377 if (element instanceof STSTest)
378 return ((STSTest)element).getLabel();
379 else if (element instanceof STSSuite)
380 return ((STSSuite)element).getLabel();
382 throw new IllegalArgumentException(element.toString());
385 public Image getImage(Object element) {
386 if (element instanceof STSSuite) {
387 STSSuite suite = (STSSuite) element;
388 if (suite.isRunning())
389 return STSTestSuiteProvider.suiteRunningIcon;
390 else if (suite.executed())
391 return STSTestSuiteProvider.suiteOkIcon;
392 else if (suite.failed())
393 return STSTestSuiteProvider.suiteFailIcon;
395 return STSTestSuiteProvider.suiteIcon;
396 } else if (element instanceof STSTest) {
397 STSTest test = (STSTest) element;
399 return STSTestSuiteProvider.testRunningIcon;
400 else if (test.executed)
401 return STSTestSuiteProvider.testOkIcon;
402 else if (test.failed)
403 return STSTestSuiteProvider.testFailIcon;
405 return STSTestSuiteProvider.testIcon;
410 public void updateInput(Resource root) {
414 Simantics.getSession().syncRequest(new ReadRequest() {
417 public void run(ReadGraph graph) throws DatabaseException {
418 Layer0 L0 = Layer0.getInstance(graph);
419 TestsResource TESTS = TestsResource.getInstance(graph);
420 if (graph.isInstanceOf(root, TESTS.STSTest)) {
421 String testName = graph.getRelatedValue2(root, L0.HasName, Bindings.STRING);
422 String definition = graph.getRelatedValue2(root, TESTS.STSTest_definition, Bindings.STRING);
423 Integer executionPrioprity = graph.getRelatedValue2(root, TESTS.STSTest_executionPriority, Bindings.INTEGER);
424 test = new STSTest(root, null, definition, testName, executionPrioprity);
425 } else if (graph.isInstanceOf(root, TESTS.STSSuite)) {
426 String suiteName = graph.getRelatedValue2(root, L0.HasName, Bindings.STRING);
427 String moduleNameFilter = graph.getPossibleRelatedValue2(root, TESTS.STSSuite_moduleNameFilter, Bindings.STRING);
428 suite = new STSSuite(root, suiteName, moduleNameFilter);
429 List<STSTest> tests = new ArrayList<>();
430 for (Resource test : graph.getObjects(root, L0.ConsistsOf)) {
431 String testName = graph.getRelatedValue2(test, L0.HasName, Bindings.STRING);
432 String definition = graph.getRelatedValue2(test, TESTS.STSTest_definition, Bindings.STRING);
433 Integer executionPrioprity = graph.getRelatedValue2(test, TESTS.STSTest_executionPriority, Bindings.INTEGER);
434 tests.add(new STSTest(test, suite, definition, testName, executionPrioprity));
436 Collections.sort(tests, (o1, o2) -> {
437 if (o1.priority < o2.priority)
439 else if (o1.priority > o2.priority)
441 else return AlphanumComparator.COMPARATOR.compare(o1.name, o2.name);
443 suite.children(tests.toArray(new STSTest[tests.size()]));
445 throw new IllegalArgumentException(root.toString());
449 } catch (DatabaseException e) {
454 public List<String> getOutput(Object element) {
455 if (element instanceof STSTest) {
456 STSTest test = (STSTest) element;
457 return test.getOutput();
459 return Collections.emptyList();
462 public int getStartedCount() {
464 return suite.startedCount;
469 public int getIgnoredCount() {
473 public int getTotalCount() {
474 if (suite != null && suite.getChildren() != null)
475 return suite.getChildren().length;
476 else if (test != null)
482 public int getErrorCount() {
484 return suite.errorCount;
488 public int getFailureCount() {
490 return suite.failureCount;
494 public int getAssumptionFailureCount() {
498 public boolean isStopped() {
500 return !suite.isRunning();
502 return test.isRunning;