]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java
Added missing org.simantics.db.{tests,testing} plug-ins.
[simantics/platform.git] / bundles / org.simantics.db.testing / src / org / simantics / db / testing / base / SCLScriptTestBase.java
diff --git a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java
new file mode 100644 (file)
index 0000000..26e916f
--- /dev/null
@@ -0,0 +1,156 @@
+package org.simantics.db.testing.base;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.osgi.framework.BundleContext;
+import org.simantics.db.testing.cases.FreshDatabaseTest;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.compiler.testing.TestRunnable;
+import org.simantics.scl.compiler.testing.repository.TestRepository;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.osgi.internal.Activator;
+import org.simantics.scl.osgi.internal.ServiceBasedModuleSourceRepository;
+import org.simantics.scl.osgi.internal.ServiceBasedTestRepository;
+
+import gnu.trove.map.hash.THashMap;
+
+/**
+ * Utilizies {@link TestRepository} for collecting SCL tests from bundles
+ * 
+ * @author Jani
+ *
+ */
+public class SCLScriptTestBase extends FreshDatabaseTest {
+
+    private Map<String, TestRunnable> testRunnables = new THashMap<String, TestRunnable>();
+    
+    @Rule public TestName testName = new TestName();
+    
+    /**
+     * Constructor that initially searches for all SCL test scripts and stores
+     * them into a Map for later access
+     */
+    public SCLScriptTestBase() {
+        super();
+        BundleContext context = Activator.getContext();
+        List<TestRunnable> runnables = new ArrayList<TestRunnable>();
+        context.getService(context.getServiceReference(TestRepository.class)).collectTests(runnables);
+        for (TestRunnable runnable : runnables) {
+            testRunnables.put(runnable.getName(), runnable);
+        }
+    }
+    
+    /**
+     * Simplest method for running a SCL test
+     */
+    protected void test() {
+        test(-1);
+    }
+    
+    /**
+     * Executes a test case with given timeout as seconds. When time runs out one
+     * can assume a deadlock has happened. The process is killed after the timeout
+     * in order to keep the possible multiple tests running.
+     * 
+     * @param timeout allowed execution time given in seconds
+     */
+    protected void test(int timeout) {
+        testImpl(timeout);
+    }
+    
+    /**
+     * Executes a test case with given timeout as seconds
+     * 
+     * @param timeout allowed execution time given in seconds
+     */
+    private void testImpl(int timeout) {
+        SCLOsgi.SOURCE_REPOSITORY = new ServiceBasedModuleSourceRepository(Activator.getContext());
+        SCLOsgi.MODULE_REPOSITORY = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY);
+        SCLOsgi.TEST_REPOSITORY = new ServiceBasedTestRepository(Activator.getContext());
+                
+        String testName = resolveTestName();
+        TestRunnable runnable = testRunnables.get(testName);
+        
+        if (timeout > -1) {
+            Timer timer = new Timer();
+            timer.schedule(new TimerTask() {
+
+                @Override
+                public void run() {
+                    String processName = ManagementFactory.getRuntimeMXBean().getName();
+                    System.out.println("PID: " + processName);
+                    String PID = processName.split("@")[0];
+                    String command = "taskkill /F /PID " + PID;
+                    System.out.println("Command: " + command);
+                    try {
+                        Runtime.getRuntime().exec(command);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+                
+            }, timeout*1000);
+            try {
+                runnable.run();
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                timer.cancel();
+            }
+        } else {
+            try {
+                runnable.run();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    /**
+     * Resolves the full test name based on the names of classes that extends this
+     * SCLScriptTestBase class.<br><br>
+     * 
+     * For example if our tests locate in <code>sclTests/Simantics/Regression/FirstTest.sts</code>
+     * the class hierarchy would be:
+     * 
+     * <ul>
+     *   <li><code>SCLScriptTestBase</code>
+     *     <ul>
+     *       <li><code>Simantics</code>
+     *         <ul>
+     *           <li><code>Regression</code></li>
+     *         </ul>
+     *       </li>
+     *     </ul>
+     *   </li>
+     * </ul>
+     * And the script file name is the same than JUnit method name.
+     * 
+     * @return full testName
+     */
+    private String resolveTestName() {
+        StringBuilder sb = new StringBuilder();
+        Class<?> clazz = this.getClass();
+        while (true) {
+            if (!(clazz.getName() == SCLScriptTestBase.class.getName())) {
+                String[] classNameParts = clazz.getName().split("\\.");
+                sb.insert(0, "/");
+                sb.insert(0, classNameParts[classNameParts.length - 1]);
+                clazz = clazz.getSuperclass();
+            } else {
+                sb.append(testName.getMethodName());
+                break;
+            }
+        }
+        return sb.toString();
+    }
+
+}