/* * Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved. */ package jsystem.treeui; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.SplashScreen; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import javax.swing.UIManager; import jsystem.framework.FrameworkOptions; import jsystem.framework.JSystemProperties; import jsystem.framework.TestRunnerFrame; import jsystem.framework.GeneralEnums.CmdExecutor; import jsystem.framework.common.CommonResources; import jsystem.framework.fixture.FixtureManager; import jsystem.framework.launcher.StartRunner; import jsystem.framework.report.JSystemListeners; import jsystem.framework.report.RunnerListenersManager; import jsystem.framework.scenario.Scenario; import jsystem.framework.scenario.ScenariosManager; import jsystem.guiMapping.JsystemMapping; import jsystem.runner.ErrorLevel; import jsystem.runner.agent.server.RunnerEngine; import jsystem.runner.agent.server.RunnerEngineImpl; import jsystem.treeui.client.JSystemAgentClientsPool; import jsystem.treeui.client.RunnerEngineManager; import jsystem.treeui.error.ErrorPanel; import jsystem.treeui.images.ImageCenter; import jsystem.treeui.suteditor.planner.SystemObjectBrowserUtils; import jsystem.treeui.threads.AutoSaveThread; import jsystem.treeui.utilities.ApplicationUtilities; import jsystem.upgrade.UpgradeManager; import jsystem.utils.ClassSearchUtil; import jsystem.utils.FileLock; import jsystem.utils.FileUtils; import jsystem.utils.PerformanceUtil; import jsystem.utils.StringUtils; import junit.framework.Test; import junit.framework.TestResult; import junit.runner.BaseTestRunner; import com.jgoodies.looks.plastic.Plastic3DLookAndFeel; /** * TestRunner This class implements the main entry This class holds the tree * view and receives updates from the view */ public class TestRunner extends BaseTestRunner implements StartRunner { /** * Events that can be passed to the main controller of the view */ public static final int RUN_EVENT = 0; public static final int STOP_EVENT = 1; public static final int PAUSE_EVENT = 2; public static final int REFRESH_EVENT = 3; public static final int REPEAT_EVENT = 5; public static final int CONNECT_TO_AGENT = 6; public static final int CONTINUE_EVENT = 15; private static Logger log = Logger.getLogger(TestRunner.class.getName()); private static TestRunner runner; public static TestTreeView treeView; public void startRunner(String[] args) { TestRunnerFrame.guiMainFrame = null; JSystemProperties.getInstance(); processSplashScreen(); log.fine("Tree TestRunner is starting"); try { UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); } catch (Exception e) { log.log(Level.SEVERE, "Error setting UI Look and Feel"); } JSystemProperties.getInstance().setJsystemRunner(true); // Let the user select tests dir // if not selected exit runner. try { String path = JSystemProperties.getInstance().getPreference(FrameworkOptions.TESTS_CLASS_FOLDER); if ((path = ApplicationUtilities.chooseClassesDirectory(path, true)) == null) { System.exit(1); } else { RunnerEngineImpl.setTestsPath(path); } JSystemProperties.getCurrentTestsPath(); } catch (Throwable e) { // we are in the runner and a project was not selected. // exiting the runner System.exit(1); } try { GuiResourcesManager.getInstance().init(); } catch (Throwable e1) { log.log(Level.SEVERE, "Fail to init GUI resource file", e1); } UIManager.put("Button.background", new Color(0xf6, 0xf6, 0xf6)); UIManager.put("Frame.background", new Color(0xf6, 0xf6, 0xf6)); UIManager.put("Label.background", new Color(0xf6, 0xf6, 0xf6)); UIManager.put("Panel.background", new Color(0xf6, 0xf6, 0xf6)); UIManager.put("OptionPane.background", new Color(0xf6, 0xf6, 0xf6)); UIManager.put("ScrollPane.background", new Color(0xf6, 0xf6, 0xf6)); UIManager.put("Table.background", new Color(0xf6, 0xf6, 0xf6)); try { RunnerEngineManager.initRunnerEngine(RunnerEngineManager.LOCAL_AGNET); updateLock(); } catch (Throwable e) { e.printStackTrace(); System.exit(1); } try { JSystemAgentClientsPool.initPoolFromRepositoryFile(); } catch (Throwable e) { log.log(Level.SEVERE, "Fail to init agents pool", e); } try { UpgradeManager.upgrade(true); } catch (Exception e) { log.log(Level.WARNING, "Fail to upgrading old scenarios", e); } try { // shutting down scenario change events // while runner is loading ScenariosManager.setDirtyStateEventsSilent(true); treeView = new TestTreeView(this); TestRunnerFrame.guiMainFrame = treeView; treeView.init(); } catch (Throwable e) { log.log(Level.SEVERE, "Failed initiating main view", e); System.exit(1); } finally { // turning on events ScenariosManager.setDirtyStateEventsSilent(false); } treeView.configureView(TestTreeView.VIEW_IDLE); JSystemListeners lm = RunnerListenersManager.getInstance(); FixtureManager.getInstance().addListener(lm); // if we have command line parameters this means that we are running // using a command // line executor engine. See what is the type of the executor. if (args != null && args.length > 0) { String executor = JSystemProperties.getInstance().getPreference(FrameworkOptions.CMD_LINE_EXECUTER); if (CmdExecutor.SIMPLE_EXECUTOR.toString().equalsIgnoreCase(executor)) { RunnerCmdExecutor runCmd = new RunnerCmdExecutor(args); runCmd.init(); } else { RunnerAdvancedCmdExecuter runCmd = new RunnerAdvancedCmdExecuter(args); runCmd.init(); } } runnerStartAdditionalOperations(); } private void runnerStartAdditionalOperations() { try { AutoSaveThread.getInstance().startThread(); } catch (Exception e) { log.log(Level.SEVERE, "ERROR getting instance of AutoSaveThread manager."); log.log(Level.SEVERE, StringUtils.getStackTrace(e)); } // Extract JSystem script file for "if" condition from the jsystemAnt // jar String destination = null; try { // Extract the script file from the jsystemAnt jar file String userDir = System.getProperty("user.dir"); String runnerLib; if (userDir.contains("jsystemApp")) { runnerLib = System.getenv("RUNNER_ROOT") + File.separator + "lib" + File.separator; } else { runnerLib = System.getProperty("user.dir") + File.separator + "lib" + File.separator; } String antJarFile = runnerLib + "jsystemAnt.jar"; // destination = runnerLib + "scripts"+File.separator; // APPLIED MATERIALS support for if. - should make no change to the // default behaviour destination = System.getProperty("user.dir") + File.separator + "scripts" + File.separator; new File(destination).mkdirs(); FileUtils.extractOneZipFile("ifScriptCondition.js", new File(antJarFile), new File(destination)); } catch (IOException e) { log.log(Level.WARNING, "Fail to locate script file for if execution: " + destination); } } public void exit() { try { RunnerEngineManager.getRunnerEngine().close(); } catch (Exception e) { log.warning("Failed disconnecting on exit " + e.getMessage()); } if (RunnerListenersManager.hadFailure) { log.info("System exit 101"); System.exit(101); } else if (RunnerListenersManager.hadWarning) { log.info("System exit 102"); System.exit(102); } else { log.info("System exit 0"); System.exit(0); } } /** * This method will be called from the view to update the controller of view * events * * @param event * - evnts triggered on the view * @param data * - data (if any) */ public void handleEvent(int event, Object data) { switch (event) { case RUN_EVENT: treeView.configureView(TestTreeView.VIEW_WAIT_FOR_PAUSE); treeView.getTableController().expandAll(); runSuite(); treeView.configureView(TestTreeView.VIEW_RUNNING); break; case CONTINUE_EVENT: treeView.configureView(TestTreeView.VIEW_RUNNING); try { RunnerEngineManager.getRunnerEngine().resume(); } catch (Exception e) { ErrorPanel.showErrorDialog("Failed resuming execution", e, ErrorLevel.Error); } break; case STOP_EVENT: treeView.setRepeat(false); try { RunnerEngine engine = RunnerEngineManager.getRunnerEngine(); GracefulStopListener cancel = new GracefulStopListener(engine); WaitDialog.launchWaitDialog(JsystemMapping.getInstance().getGracefulDialog(), cancel, JsystemMapping .getInstance().getStopImmediatelyButton()); engine.gracefulStop(); } catch (Exception e) { ErrorPanel.showErrorDialog("Failed stopping execution", e, ErrorLevel.Error); } break; case PAUSE_EVENT: treeView.configureView(TestTreeView.VIEW_WAIT_FOR_PAUSE); try { RunnerEngineManager.getRunnerEngine().pause(); } catch (Exception e) { ErrorPanel.showErrorDialog("Failed pausing execution", e, ErrorLevel.Error); } break; case REFRESH_EVENT: handleRefresh(); break; case REPEAT_EVENT: try { RunnerEngineManager.getRunnerEngine().enableRepeat((Boolean) data); } catch (Exception e) { ErrorPanel.showErrorDialog("Failed pausing execution", e, ErrorLevel.Error); } break; case CONNECT_TO_AGENT: try { FileLock lock = FileLock.getFileLock(CommonResources.LOCK_FILE); lock.releaseLock(); RunnerEngineManager.initRunnerEngine("" + data); RemoteAgentUIComponents.refreshAgentList(); treeView.registerOnAgentEvents(); } catch (Exception e) { ErrorPanel.showErrorDialog("Failed connecting to " + data, e, ErrorLevel.Error); } finally { try { updateLock(); } catch (Exception e) { log.warning("Failed updating file lock. " + e.getMessage()); } } break; } } private void runSuite() { JSystemProperties.getInstance().rereadPropertiesFile(); Scenario scenario = null; try { scenario = ScenariosManager.getInstance().getCurrentScenario(); scenario.setStatusNotRunning(); } catch (Exception e) { treeView.setRepeat(false); treeView.configureView(TestTreeView.VIEW_IDLE); JOptionPane.showMessageDialog(treeView, "Fail to load tests:\n" + StringUtils.getStackTrace(e), "Fail to load tests", JOptionPane.ERROR_MESSAGE); return; } if (scenario.getTests().size() == 0) { treeView.setRepeat(false); treeView.configureView(TestTreeView.VIEW_IDLE); JOptionPane.showMessageDialog(treeView, "Please add one or more tests to the scenario.", "No tests selected", JOptionPane.INFORMATION_MESSAGE); } int numberOfCycles = treeView.getNumberOfCycles(); if (numberOfCycles < 1) { treeView.setNumberOfCycles(0); } treeView.setNumberOfLeftCycles(0); if (treeView.isRepeat()) { treeView.setNumberOfLeftCycles(treeView.getNumberOfCycles()); } ExecutionWorker runWorker = new ExecutionWorker(treeView); runWorker.execute(); } /** * This method handles the refresh event on the controller side. Implement * the non UI operations that will be done on refresh */ private void handleRefresh() { try { RunnerEngineManager.getRunnerEngine().refresh(); } catch (Exception e) { ErrorPanel.showErrorDialog("Failed refreshing engine", e, ErrorLevel.Error); } int index = PerformanceUtil.startMeasure(); treeView.refreshInternals(); TestTreeView.treeController.refreshView(); TestTreeView.treeController.expandTree(); treeView.refreshOpenReportsButton(); treeView.tableController.refresh(); PerformanceUtil.endMeasure(index, "Refreshing scenario"); SystemObjectBrowserUtils.startCollectSOs(); } /** * */ private void updateLock() throws Exception { FileLock lock = FileLock.getFileLock(CommonResources.LOCK_FILE); if (RunnerEngineManager.getRunnerEngine() instanceof RunnerEngineImpl) { while (true) { if (!lock.grabLock()) { int res = JOptionPane.showOptionDialog(null, "Another JRunner instance is using the same directory\n" + "Running two JRunners on the same directory will cause logs problems\n" + "Close the other JRunner instance and press on 'Check Again' or 'exit'.", "A JRunner instance is already active", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, ImageCenter.getInstance().getImage(ImageCenter.ICON_INFO), new String[] { "Check Again", "Exit" }, "Check Again"); if (res == 1) { exit(); } } else { return; } } } else { lock.releaseLock(); } } /** * getting the SplashScreen object in runtime, and creating a new thread * that will take the splash screen and write on it the required * information. the splash will be closed when the application is up. */ private void processSplashScreen() { (new Thread() { public void run() { SplashScreen ss = SplashScreen.getSplashScreen(); if (ss != null) { try { Graphics2D g2d = ss.createGraphics(); // Set text color black and font type sansserif // Set string location just above the separator line g2d.setColor(new Color(0x23, 0x1f, 0x20)); g2d.setFont(new Font("arial", Font.BOLD, 14)); String version = "Version "; version += ClassSearchUtil.getPropertyFromClassPath( "META-INF/maven/org.jsystemtest/jsystemApp/pom.properties", "version"); g2d.drawString(version, 101, 209); ss.update(); // Set wait message g2d.setColor(new Color(0x50, 0x93, 0xca)); g2d.setFont(new Font("arial", Font.BOLD, 14)); g2d.drawString("JSystem initializing, please wait...", 101, 230); ss.update(); // Set copyright message g2d.setColor(new Color(0x23, 0x1f, 0x20)); g2d.setFont(new Font("arial", Font.PLAIN, 10)); g2d.drawString(" Copyright 2005-2016 Ignis Software Tools Ltd. All rights reserved.", 101, 330); ss.update(); for (int j = 0; true; j++) { if (j % 2 == 0) { g2d.setColor(new Color(0xf6, 0xf6, 0xf6)); } else { g2d.setColor(new Color(0xa8, 0xb7, 0xe2)); } /** * create the runing square's */ for (int i = 0; i < 10; i++) { g2d.fillRect(101 + (i * 20), 264, 10, 10); ss.update(); Thread.sleep(200); } } } catch (Exception e) { log.log(Level.FINE, "Splash Screen Closed"); } } else { log.log(Level.WARNING, "Splash screen not found"); } } }).start(); try { Thread.sleep(1000); } catch (InterruptedException e1) { return; } } protected TestResult createTestResult() { return new TestResult(); } public void testStarted(String s) { // ignore } public void testEnded(String s) { // ignore } public void testFailed(int i, Test test, Throwable throwable) { // ignore } protected void runFailed(String s) { // handeled by the runner } public static void main(String[] args) { runner = new TestRunner(); runner.startRunner(args); } public static Logger getLog() { return log; } public static void setLog(Logger log) { TestRunner.log = log; } }