@Override public void run() { try { log.debug("run!"); this.root.setState(SubstepTestState.RUNNING); eventsConsumer.onEvent(new StateChangedEvent(this.root)); RootNode resultNode = getRootNodeFromBytes(jmxClient.runAsBytes()); // lets wait for any notifications try { countDownLatch.await(); } catch (InterruptedException e) { if (countDownLatch.getCount() > 0) { log.error("premature interupted ex waiting for complete notification"); } } if (resultNode.getResult().getResult() == com.technophobia.substeps.execution.ExecutionResult.PASSED) { this.root.setState(SubstepTestState.PASSED); } else if (resultNode.getResult().getResult() == com.technophobia.substeps.execution.ExecutionResult.FAILED) { this.root.setState(SubstepTestState.FAILED); } eventsConsumer.onEvent(new StateChangedEvent(this.root)); log.debug("done run, shutting down!"); } finally { jmxClient.shutdown(); log.debug("shut down done!"); } }
@Override @NotNull public ExecutionResult execute( @NotNull final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException { log.debug("execute: about to call startProcess"); OSProcessHandler processHandler = startProcess(); ConsoleView consoleView = TextConsoleBuilderFactory.getInstance() .createBuilder(this.getEnvironment().getProject()) .getConsole(); consoleView.print("Starting substeps test...", ConsoleViewContentType.NORMAL_OUTPUT); SubstepsRunConfiguration runConfig = (SubstepsRunConfiguration) this.getEnvironment().getRunProfile(); boolean substepsServerLogsToConsole = true; if (substepsServerLogsToConsole) { consoleView.attachToProcess(processHandler); } else { Semaphore consoleSemaphore = new Semaphore(1, true); InputStreamConsumer consumer = new InputStreamConsumer( processHandler.getProcess().getInputStream(), log, false, consoleView, consoleSemaphore); final Thread t = new Thread(consumer); t.start(); InputStreamConsumer errorConsumer = new InputStreamConsumer( processHandler.getProcess().getErrorStream(), log, true, consoleView, consoleSemaphore); final Thread t2 = new Thread(errorConsumer); t2.start(); } processHandler.startNotify(); // // // // boolean exceptionThrown = false; // try { // this.log.info("waiting for process to start..."); // processStarted.await(30, TimeUnit.SECONDS); // // this.log.info("waited.."); // // if (!processStartedOk.get()) { // exceptionThrown = true; // throw new ExecutionException("Unable to launch VM process"); // } // // this.log.info("process started"); // } catch (final InterruptedException e) { // // e.printStackTrace(); // } // try { // Thread.currentThread().sleep(5000); // } catch (InterruptedException e) { // e.printStackTrace(); // } log.debug("startProcess called"); SubstepsRunnerConfigurationModel model = runConfig.getModel(); boolean actualRunnerStarted = false; // TODO - this is a bit messy, concerns not well separated SubstepsJMXClient jmxClient = null; try { jmxClient = new SubstepsJMXClient(); if (!jmxClient.init(jmxPort)) { log.error("jmx init failed"); processHandler.destroyProcess(); return new DefaultExecutionResult(); } SubstepsExecutionConfig substepsExecutionConfig = new SubstepsExecutionConfig(); substepsExecutionConfig.setFeatureFile(model.getPathToFeature()); String[] stepImplsArray = model .getStepImplentationClassNames(); // .toArray(new // String[model.getStepImplentationClassNames().size()]); substepsExecutionConfig.setDescription("Substeps Tests"); substepsExecutionConfig.setStepImplementationClassNames(stepImplsArray); substepsExecutionConfig.setSubStepsFileName(model.getSubStepDefinitionDirectory()); substepsExecutionConfig.setScenarioName(model.getScenarioName()); log.debug( "SubstepsExecutionConfig details\nFeature: " + model.getPathToFeature() + "\nsubstep dir: " + model.getSubStepDefinitionDirectory() + " scenarioName: " + model.getScenarioName()); for (String s : model.getStepImplentationClassNames()) { log.debug("step impl classname: " + s); } /* private String description; private String tags; private String nonFatalTags; private String subStepsFileName; private boolean strict = true; private boolean fastFailParseErrors = true; private Properties systemProperties; private String[] nonStrictKeywordPrecedence; private String[] stepImplementationClassNames; private String[] initialisationClass; private List<Class<?>> stepImplementationClasses; private Class<?>[] initialisationClasses; private String[] executionListeners; */ log.debug("preparing config"); byte[] bytes = jmxClient.prepareExecutionConfigAsBytes(substepsExecutionConfig); RootNode rn = getRootNodeFromBytes(bytes); log.debug("got root node description: " + rn.getDescription()); final SubstepsTestProxy unboundOutputRoot = new SubstepsTestProxy(rn); final SubstepsConsoleProperties consoleProperties = new SubstepsConsoleProperties(runConfig, executor); final SubstepsConsoleView substepsConsoleView = new SubstepsConsoleView( consoleView, consoleProperties, this.getEnvironment(), unboundOutputRoot); DefaultExecutionResult execResult = new DefaultExecutionResult( substepsConsoleView, processHandler, createActions(substepsConsoleView, processHandler, executor)); Disposer.register(this.getEnvironment().getProject(), substepsConsoleView); substepsConsoleView.initUI(); substepsConsoleView.attachToProcess(processHandler); unboundOutputRoot.setPrinter(substepsConsoleView.getPrinter()); Disposer.register(substepsConsoleView, unboundOutputRoot); SubstepsRunningModel runModel = new SubstepsRunningModel(unboundOutputRoot, consoleProperties); SubstepsListenersNotifier eventsConsumer = unboundOutputRoot.getEventsConsumer(); substepsConsoleView.attachToModel(runModel); RunningTestTracker.install(runModel); log.debug("rootNode result from prepare config: " + rn.getResult().getResult()); if (rn.getResult().getResult().isFailure()) { // bail out early unboundOutputRoot.setState(SubstepTestState.FAILED); eventsConsumer.onEvent(new StateChangedEvent(unboundOutputRoot)); jmxClient.shutdown(); log.debug("shut down done!"); } else { log.debug("config prepared"); List<SubstepsTestProxy> allTestNodes = unboundOutputRoot.getAllTests(); Map<Long, SubstepsTestProxy> proxyMap = new HashMap<>(); for (SubstepsTestProxy proxy : allTestNodes) { proxyMap.put(proxy.getExecutionNodeId(), proxy); } ActualRunner actualRunner = new ActualRunner(jmxClient, log, eventsConsumer, proxyMap, unboundOutputRoot); new Thread(actualRunner).start(); actualRunnerStarted = true; } return execResult; } finally { if (!actualRunnerStarted && jmxClient != null) { // if we've got to the end and not actually kicked off the runner, make sure we shut down. jmxClient.shutdown(); } } }