Enhancements to modelled STS-tests
[simantics/platform.git] / bundles / org.simantics.tests.modelled.ui / src / org / simantics / tests / modelled / ui / STSTestSuiteModel.java
1 package org.simantics.tests.modelled.ui;
2
3 import java.io.BufferedReader;
4 import java.io.StringReader;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.List;
8 import java.util.regex.Pattern;
9 import java.util.stream.Collectors;
10
11 import org.eclipse.swt.graphics.Image;
12 import org.simantics.Simantics;
13 import org.simantics.db.ReadGraph;
14 import org.simantics.db.Resource;
15 import org.simantics.db.common.request.ReadRequest;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.layer0.Layer0;
18 import org.simantics.scl.compiler.commands.CommandSession;
19 import org.simantics.scl.compiler.commands.TestScriptExecutor;
20 import org.simantics.scl.compiler.module.coverage.CombinedCoverage;
21 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
22 import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;
23 import org.simantics.scl.compiler.module.repository.ModuleRepository;
24 import org.simantics.scl.osgi.SCLOsgi;
25 import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
26 import org.simantics.tests.modelled.ontology.TestsResource;
27 import org.simantics.tests.modelled.utils.ModelledSTSSuite;
28 import org.simantics.tests.modelled.utils.ModelledSTSTest;
29 import org.simantics.tests.modelled.utils.STSSuiteTestCollector;
30
31 public class STSTestSuiteModel {
32
33     static class STSTest {
34         
35         private final ModelledSTSTest test;
36         
37         private final STSSuite parent;
38         private boolean executed = false;
39         private long duration;
40         private boolean failed = false;
41         private boolean isRunning = false;
42         private List<String> output = new ArrayList<>();
43         
44         public STSTest(ModelledSTSTest test, STSSuite parent) {
45             this.test = test;
46             this.parent = parent;
47         }
48         
49         public String getName() {
50             return test.getName();
51         }
52         
53         public String getLabel() {
54             StringBuilder sb = new StringBuilder();
55             sb.append(getName());
56             if (executed || failed)
57                 sb.append(" (").append(duration).append(" ms)");
58             return sb.toString();
59         }
60         
61         public String getDefinition() {
62             return test.getCode();
63         }
64
65         public STSSuite getParent() {
66             return parent;
67         }
68
69         public void execute(CommandSession session) {
70             isRunning = true;
71             
72             TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(getDefinition())), new AbstractSCLReportingHandler() {
73                 
74                 @Override
75                 public void print(String text) {
76                     appendOutput(text + "\n");
77                 }
78                 
79                 @Override
80                 public void printCommand(String command) {
81                     appendOutput("> " + command + "\n");
82                 }
83                 
84                 @Override
85                 public void printError(String error) {
86                     appendOutput(error + "\n");
87                 }
88             }, true);
89             long start = System.currentTimeMillis();
90             try {
91                 if (parent != null)
92                     parent.startedCount++;
93                 executor.execute();
94                 executed = true;
95             } catch (Throwable t) {
96                 t.printStackTrace();
97                 if (parent != null)
98                     parent.failureCount++;
99                 failed = true;
100             } finally {
101                 isRunning = false;
102                 long end = System.currentTimeMillis();
103                 duration = end - start;
104             }
105
106         }
107
108         protected void appendOutput(String text) {
109             output.add(text);
110         }
111
112         public List<String> getOutput() {
113             return output;
114         }
115
116         public void setCoverage(CombinedCoverage coverage) {
117             test.setCoverage(coverage);
118         }
119         
120         public CombinedCoverage getCoverage() {
121             return test.getCoverage();
122         }
123
124         public int getPriority() {
125             return test.getPriority();
126         }
127
128         @Override
129         public String toString() {
130             return getName() + " [priority=" + getPriority() + ", executed=" + executed + ", duration=" + duration + "]";
131         }
132
133         public boolean isIgnored() {
134             return test.isIgnored();
135         }
136     }
137
138     static class STSSuite {
139
140         private ModelledSTSSuite suite;
141         private STSTest[] children;
142         private int startedCount;
143         private int errorCount;
144         private int failureCount;
145         public int ignoredCount;
146         
147         public STSSuite(ModelledSTSSuite suite) {
148             this.suite = suite;
149         }
150
151         public STSTest[] getChildren() {
152             if (children == null)
153                 children = suite.getSortedChildren().stream().map(modelledTest  -> new STSTest(modelledTest, this)).collect(Collectors.toList()).toArray(new STSTest[suite.getChildren().size()]);
154             return children;
155         }
156
157         public String getName() {
158             return suite.getName();
159         }
160
161         public String getLabel() {
162             StringBuilder sb = new StringBuilder();
163             sb.append(getName());
164             long totalTime = 0; 
165             if (getChildren() != null) {
166                 for (STSTest test : getChildren()) {
167                     if (test.executed || test.failed) {
168                         totalTime += test.duration;
169                     }
170                 }
171             }
172             if (totalTime != 0)
173                 sb.append(" (").append(totalTime).append(" ms)");
174             return sb.toString();
175         }
176
177         public boolean isRunning() {
178             if (getChildren() != null) {
179                 for (STSTest test: getChildren()) {
180                     if (test.isRunning) {
181                         return true;
182                     }
183                 }
184             }
185             return false;
186         }
187
188         public boolean executed() {
189             if (getChildren() != null) {
190                 for (STSTest test: getChildren()) {
191                     if (!test.executed) {
192                         return false;
193                     }
194                 }
195             }
196             return true;
197         }
198
199         public boolean failed() {
200             if (getChildren() != null) {
201                 for (STSTest test: getChildren()) {
202                     if (test.failed) {
203                         return true;
204                     }
205                 }
206             }
207             return false;
208         }
209
210         public CombinedCoverage getCoverage() {
211             return suite.getCoverage();
212         }
213     }
214
215     
216     private STSSuite suite;
217     private STSTest test;
218     private final List<STSExecutionListener> listeners = new ArrayList<>();
219     
220     public STSTestSuiteModel() {
221     }
222     
223     public void addListener(STSExecutionListener listener) {
224         listeners.add(listener);
225     }
226     
227     public void removeListener(STSExecutionListener listener) {
228         listeners.remove(listener);
229     }
230
231     public Object[] getElements() {
232         if (suite != null)
233             return new Object[] {suite};
234         else if (test != null)
235             return new Object[] {test};
236         else return null;
237     }
238
239     public void execute() {
240         
241         ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY);
242         if (suite != null) {
243             repo.setAdvisor(new ModuleCompilationOptionsAdvisor() {
244                 
245                 @Override
246                 public ModuleCompilationOptions getOptions(String moduleName) {
247                     boolean coverage = false;
248                     for (Pattern p : suite.suite.getModuleNameFilterPatterns()) {
249                         if (p.matcher(moduleName.toLowerCase()).find()) {
250                             coverage = true;
251                             break;
252                         }
253                     }
254                     return new ModuleCompilationOptions(coverage);
255                 }
256             });
257         }
258         CommandSession session = new CommandSession(repo, null);
259         if (suite != null) {
260             executeSuite(session);
261         } else if (test != null) {
262             executeTest(session);
263         }
264     }
265     
266     private void testExecuted() {
267         listeners.forEach(listener -> {
268             listener.testExecuted();
269         });
270     }
271     
272     private void executeSuite(CommandSession session) {
273         for (STSTest test : suite.getChildren()) {
274             if (test.isIgnored()) {
275                 testExecuted();
276                 test.getParent().ignoredCount++;
277                 continue;
278             }
279             test.execute(session);
280             STSSuiteTestCollector.setSuiteCoverage(test.test, suite.suite, session);
281             testExecuted();
282         }
283     }
284
285     private void executeTest(CommandSession session) {
286         test.execute(session);
287         testExecuted();
288         STSSuiteTestCollector.setTestCoverage(test.test, session);
289     }
290
291     public boolean hasChildren(Object element) {
292         if (element instanceof STSTest) {
293             return false;
294         } else if (element instanceof STSSuite) {
295             STSSuite suite = (STSSuite) element;
296             return (suite.getChildren() != null ? suite.getChildren().length > 0 : false);
297         } else {
298             throw new IllegalArgumentException(element.toString());
299         }
300     }
301
302     public Object getParent(Object element) {
303         if (element instanceof STSTest) {
304             return ((STSTest) element).getParent();
305         } else if (element instanceof STSSuite) {
306             return null;
307         } else {
308             throw new IllegalArgumentException(element.toString());
309         }
310     }
311
312     public Object[] getChildren(Object parentElement) {
313         if (parentElement instanceof STSTest) {
314             return null;
315         } else if (parentElement instanceof STSSuite) {
316             STSSuite suite = (STSSuite) parentElement;
317             return suite.getChildren();
318         } else {
319             throw new IllegalArgumentException(parentElement.toString());
320         }
321     }
322
323     public String getText(Object element) {
324         if (element instanceof STSTest)
325             return ((STSTest)element).getLabel();
326         else if (element instanceof STSSuite)
327             return ((STSSuite)element).getLabel();
328         else
329             throw new IllegalArgumentException(element.toString());
330     }
331
332     public Image getImage(Object element) {
333         if (element instanceof STSSuite) {
334             STSSuite suite = (STSSuite) element;
335             if (suite.isRunning())
336                 return STSTestSuiteProvider.suiteRunningIcon;
337             else if (suite.executed())
338                 return STSTestSuiteProvider.suiteOkIcon;
339             else if (suite.failed())
340                 return STSTestSuiteProvider.suiteFailIcon;
341             else
342                 return STSTestSuiteProvider.suiteIcon;
343         } else if (element instanceof STSTest) {
344             STSTest test = (STSTest) element;
345             if (test.isRunning)
346                 return STSTestSuiteProvider.testRunningIcon;
347             else if (test.executed)
348                 return STSTestSuiteProvider.testOkIcon;
349             else if (test.failed)
350                 return STSTestSuiteProvider.testFailIcon;
351             else
352                 return STSTestSuiteProvider.testIcon;
353         }
354         return null;
355     }
356
357     public void updateInput(Resource root) {
358         suite = null;
359         test = null;
360         try {
361             Simantics.getSession().syncRequest(new ReadRequest() {
362                 
363                 @Override
364                 public void run(ReadGraph graph) throws DatabaseException {
365                     Layer0 L0 = Layer0.getInstance(graph);
366                     TestsResource TESTS = TestsResource.getInstance(graph);
367                     if (graph.isInstanceOf(root, TESTS.STSTest)) {
368                         test = new STSTest(STSSuiteTestCollector.toModelledTest(graph, root), null);
369                     } else if (graph.isInstanceOf(root, TESTS.STSSuite)) {
370                         List<ModelledSTSTest> tests = new ArrayList<>();
371                         for (Resource test : graph.getObjects(root, L0.ConsistsOf))
372                             tests.add(STSSuiteTestCollector.toModelledTest(graph, test));
373                         
374                         suite = new STSSuite(STSSuiteTestCollector.toModelledSuite(graph, root, tests));
375                     } else {
376                         throw new IllegalArgumentException(root.toString());
377                     }
378                 }
379             });
380         } catch (DatabaseException e) {
381             e.printStackTrace();
382         }
383     }
384
385     public List<String> getOutput(Object element) {
386         if (element instanceof STSTest) {
387             STSTest test = (STSTest) element;
388             return test.getOutput();
389         }
390         return Collections.emptyList();
391     }
392
393     public int getStartedCount() {
394         if (suite != null)
395             return suite.startedCount;
396         else
397             return 0;
398     }
399
400     public int getIgnoredCount() {
401         if (suite != null)
402             return suite.ignoredCount;
403         return 0;
404     }
405
406     public int getTotalCount() {
407         if (suite != null && suite.getChildren() != null)
408             return suite.getChildren().length;
409         else if (test != null)
410             return 1;
411         else
412             return 0;
413     }
414
415     public int getErrorCount() {
416         if (suite != null)
417             return suite.errorCount;
418         return 0;
419     }
420
421     public int getFailureCount() {
422         if (suite != null)
423             return suite.failureCount;
424         return 0;
425     }
426
427     public int getAssumptionFailureCount() {
428         return 0;
429     }
430
431     public boolean isStopped() {
432         if (suite != null)
433             return !suite.isRunning();
434         else
435             return test.isRunning;
436     }
437 }
438