/*********************************************************************************** * * Copyright (c) 2015 Kamil Baczkowicz * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * * Kamil Baczkowicz - initial API and implementation and/or initial documentation * */ package pl.baczkowicz.spy.daemon; import java.util.List; import java.util.Map; import javax.script.ScriptException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.baczkowicz.spy.common.generated.RunningMode; import pl.baczkowicz.spy.common.generated.ScriptDetails; import pl.baczkowicz.spy.common.generated.TestCasesSettings; import pl.baczkowicz.spy.exceptions.SpyException; import pl.baczkowicz.spy.exceptions.XMLException; import pl.baczkowicz.spy.scripts.BaseScriptManager; import pl.baczkowicz.spy.scripts.Script; import pl.baczkowicz.spy.testcases.TestCaseManager; import pl.baczkowicz.spy.testcases.TestCaseOptions; import pl.baczkowicz.spy.testcases.TestCaseResult; import pl.baczkowicz.spy.utils.ThreadingUtils; public abstract class BaseDaemon implements IDaemon { /** Diagnostic logger. */ private final static Logger logger = LoggerFactory.getLogger(BaseDaemon.class); protected BaseScriptManager scriptManager; protected TestCaseManager testCaseManager; public TestCaseResult runTestCase(final String testCaseLocation) { return runTestCase(testCaseLocation, null, null); } public TestCaseResult runTestCase(final String testCaseLocation, final Map<String, Object> args) { return runTestCase(testCaseLocation, args, null); } public TestCaseResult runTestCase(final String testCaseLocation, final Map<String, Object> args, final TestCaseOptions options) { if (options != null) { testCaseManager.setOptions(options); } return testCaseManager.addAndRunTestCase(testCaseLocation, args); } public Script runScript(final String scriptLocation) { return runScript(scriptLocation, false, null); } public Script runScript(final String scriptLocation, final boolean async, final Map<String, Object> args) { return scriptManager.addAndRunScript(scriptLocation, async, args); } public Object runScriptFunction(final String scriptLocation, final String functionName, final Map<String, Object> args) { try { Script script = scriptManager.getScriptObjectFromName(scriptLocation); // Check if the script has been run before if (script == null) { script = runScript(scriptLocation); } scriptManager.setVariable(script, "args", args); return scriptManager.invokeFunction(script, functionName); } catch (NoSuchMethodException | ScriptException e) { logger.error("Coundn't run function {} for script {}", functionName, scriptLocation, e); return null; } } public void stopScript(final Script script) { scriptManager.stopScript(script); } public void stopScript(final String scriptName) { final Script script = scriptManager.getScriptObjectFromName(scriptName); if (script != null) { scriptManager.stopScript(script); } else { logger.warn("Script {} doesn't exist, so can't stop it", scriptName); } } protected void stopScripts() { scriptManager.stopScripts(); } public boolean start(final String configurationFile) { try { initialise(); loadAndRun(configurationFile); return true; } catch (XMLException e) { logger.error("Cannot load the daemon's configuration", e); } catch (SpyException e) { logger.error("Error occurred while connecting to server", e); } return false; } /** * Tries to stop all running threads and close the connection. */ public void stop() { stopScripts(); waitAndStop(); } protected void runScripts(final List<ScriptDetails> scriptSettings, final TestCasesSettings testCasesSettings, final RunningMode runningMode) throws SpyException { runScripts(scriptSettings, testCasesSettings, runningMode, null); } protected void runScripts(final List<ScriptDetails> scriptSettings, final TestCasesSettings testCasesSettings, final RunningMode runningMode, final Map<String, Object> parameters) throws SpyException { scriptManager.addCustomParameters(parameters); // Run all configured scripts final List<Script> backgroundScripts = scriptManager.addScripts(scriptSettings); for (final Script script : backgroundScripts) { logger.info("About to start background script " + script.getName()); scriptManager.runScript(script, true); } // Run all tests, one by one if (testCasesSettings != null) { testCaseManager.getOptions().setAutoExport(testCasesSettings.isExportResults()); if (testCasesSettings.isRecordRepeatedSteps() != null) { testCaseManager.getOptions().setRecordRepeatedSteps(testCasesSettings.isRecordRepeatedSteps()); } if (testCasesSettings.getStepInterval() != null) { testCaseManager.getOptions().setStepInterval(testCasesSettings.getStepInterval()); } testCaseManager.loadTestCases(testCasesSettings.getLocation()); while (!canPublish()) { logger.debug("Client not connected yet - can't start test cases... [waiting another 1000ms]"); ThreadingUtils.sleep(1000); } testCaseManager.runAllTestCases(); } // If in 'scripts only' mode, exit when all scripts finished if (RunningMode.SCRIPTS_ONLY.equals(runningMode)) { waitAndStop(); } } protected void waitForScripts() { ThreadingUtils.sleep(1000); // Wait until all scripts have completed or got frozen while (scriptManager.areScriptsRunning()) { logger.debug("Scripts are still running... [waiting another 1000ms]"); ThreadingUtils.sleep(1000); } // Wait until all test cases have completed or got frozen while (testCaseManager.areTestCasesStillRunning()) { logger.debug("Test cases are still running... [waiting another 1000ms]"); ThreadingUtils.sleep(1000); } } protected void displayGoodbyeMessage() { ThreadingUtils.sleep(1000); for (final Thread thread : Thread.getAllStackTraces().keySet()) { logger.trace("Thread {} is still running", thread.getName()); } logger.info("All tasks completed - bye bye..."); } // ####### protected abstract void waitAndStop(); public abstract void initialise() throws XMLException; public abstract void loadAndRun(final String configurationFile) throws SpyException; public abstract boolean canPublish(); }