]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java
26e916fc1bcdfa53ed8f0076155b33b3d7bf603e
[simantics/platform.git] / bundles / org.simantics.db.testing / src / org / simantics / db / testing / base / SCLScriptTestBase.java
1 package org.simantics.db.testing.base;
2
3 import java.io.IOException;
4 import java.lang.management.ManagementFactory;
5 import java.util.ArrayList;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Timer;
9 import java.util.TimerTask;
10
11 import org.junit.Rule;
12 import org.junit.rules.TestName;
13 import org.osgi.framework.BundleContext;
14 import org.simantics.db.testing.cases.FreshDatabaseTest;
15 import org.simantics.scl.compiler.module.repository.ModuleRepository;
16 import org.simantics.scl.compiler.testing.TestRunnable;
17 import org.simantics.scl.compiler.testing.repository.TestRepository;
18 import org.simantics.scl.osgi.SCLOsgi;
19 import org.simantics.scl.osgi.internal.Activator;
20 import org.simantics.scl.osgi.internal.ServiceBasedModuleSourceRepository;
21 import org.simantics.scl.osgi.internal.ServiceBasedTestRepository;
22
23 import gnu.trove.map.hash.THashMap;
24
25 /**
26  * Utilizies {@link TestRepository} for collecting SCL tests from bundles
27  * 
28  * @author Jani
29  *
30  */
31 public class SCLScriptTestBase extends FreshDatabaseTest {
32
33     private Map<String, TestRunnable> testRunnables = new THashMap<String, TestRunnable>();
34     
35     @Rule public TestName testName = new TestName();
36     
37     /**
38      * Constructor that initially searches for all SCL test scripts and stores
39      * them into a Map for later access
40      */
41     public SCLScriptTestBase() {
42         super();
43         BundleContext context = Activator.getContext();
44         List<TestRunnable> runnables = new ArrayList<TestRunnable>();
45         context.getService(context.getServiceReference(TestRepository.class)).collectTests(runnables);
46         for (TestRunnable runnable : runnables) {
47             testRunnables.put(runnable.getName(), runnable);
48         }
49     }
50     
51     /**
52      * Simplest method for running a SCL test
53      */
54     protected void test() {
55         test(-1);
56     }
57     
58     /**
59      * Executes a test case with given timeout as seconds. When time runs out one
60      * can assume a deadlock has happened. The process is killed after the timeout
61      * in order to keep the possible multiple tests running.
62      * 
63      * @param timeout allowed execution time given in seconds
64      */
65     protected void test(int timeout) {
66         testImpl(timeout);
67     }
68     
69     /**
70      * Executes a test case with given timeout as seconds
71      * 
72      * @param timeout allowed execution time given in seconds
73      */
74     private void testImpl(int timeout) {
75         SCLOsgi.SOURCE_REPOSITORY = new ServiceBasedModuleSourceRepository(Activator.getContext());
76         SCLOsgi.MODULE_REPOSITORY = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY);
77         SCLOsgi.TEST_REPOSITORY = new ServiceBasedTestRepository(Activator.getContext());
78                 
79         String testName = resolveTestName();
80         TestRunnable runnable = testRunnables.get(testName);
81         
82         if (timeout > -1) {
83             Timer timer = new Timer();
84             timer.schedule(new TimerTask() {
85
86                 @Override
87                 public void run() {
88                     String processName = ManagementFactory.getRuntimeMXBean().getName();
89                     System.out.println("PID: " + processName);
90                     String PID = processName.split("@")[0];
91                     String command = "taskkill /F /PID " + PID;
92                     System.out.println("Command: " + command);
93                     try {
94                         Runtime.getRuntime().exec(command);
95                     } catch (IOException e) {
96                         e.printStackTrace();
97                     }
98                 }
99                 
100             }, timeout*1000);
101             try {
102                 runnable.run();
103             } catch (Exception e) {
104                 e.printStackTrace();
105             } finally {
106                 timer.cancel();
107             }
108         } else {
109             try {
110                 runnable.run();
111             } catch (Exception e) {
112                 e.printStackTrace();
113             }
114         }
115     }
116     
117     /**
118      * Resolves the full test name based on the names of classes that extends this
119      * SCLScriptTestBase class.<br><br>
120      * 
121      * For example if our tests locate in <code>sclTests/Simantics/Regression/FirstTest.sts</code>
122      * the class hierarchy would be:
123      * 
124      * <ul>
125      *   <li><code>SCLScriptTestBase</code>
126      *     <ul>
127      *       <li><code>Simantics</code>
128      *         <ul>
129      *           <li><code>Regression</code></li>
130      *         </ul>
131      *       </li>
132      *     </ul>
133      *   </li>
134      * </ul>
135      * And the script file name is the same than JUnit method name.
136      * 
137      * @return full testName
138      */
139     private String resolveTestName() {
140         StringBuilder sb = new StringBuilder();
141         Class<?> clazz = this.getClass();
142         while (true) {
143             if (!(clazz.getName() == SCLScriptTestBase.class.getName())) {
144                 String[] classNameParts = clazz.getName().split("\\.");
145                 sb.insert(0, "/");
146                 sb.insert(0, classNameParts[classNameParts.length - 1]);
147                 clazz = clazz.getSuperclass();
148             } else {
149                 sb.append(testName.getMethodName());
150                 break;
151             }
152         }
153         return sb.toString();
154     }
155
156 }