package com.softwaremill.common.test.web.jboss; import org.apache.commons.io.FileUtils; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; import com.softwaremill.common.test.util.MessageWaiter; import com.softwaremill.common.test.web.jboss.server.JBossAS; import com.softwaremill.common.test.web.jboss.server.JBossASProvider; import com.softwaremill.common.test.web.selenium.ServerProperties; import java.io.File; import java.io.IOException; import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.testng.Assert.fail; /** * @author maciek * @author Pawel Wrzeszcz * @author Jaroslaw Kijanowski * @author Pawel Stawicki * @author Marcin Jekot */ public abstract class AbstractJBossRunner { private JBossAS jboss; protected final static SysoutLog log = new SysoutLog(); private boolean deploymentComplete = false; private static final int MILLISECONDS_IN_MINUTE = 60 * 1000; protected abstract ServerProperties getServerProperties(); protected abstract Deployment[] getDeployments(); private Process tailProcess; private boolean timedout; @BeforeSuite public void start() throws Exception { scheduleTimeout(); jboss = new JBossASProvider(getServerProperties()).createJBossASInstance(); undeploy(); // Clean old deployments tailProcess = jboss.start(); deploy(); } @AfterSuite(alwaysRun = true) public void shutdown() throws Exception { undeploy(); jboss.shutdown(); publishLog(); } private Process getTailProcess() throws IOException { if (tailProcess == null) { // this happens when jboss was already started tailProcess = Runtime.getRuntime().exec( new String[]{"tail", "-f", jboss.getServerLogPath()}); } return tailProcess; } private void deploy() throws Exception { for (Deployment deployment : getDeployments()) { deployment.deploy(jboss.getDeployDir()); if (deployment.getWaitForMessage() != null) { waitForMessageOrTimeout(deployment); if (timedout) { fail("Server startup/deploy timeout exceeded."); } } else { Thread.sleep(deployment.getWaitMillis()); } } deploymentComplete = true; // close the tail process so it doesn't overload tailProcess.getInputStream().close(); } private void waitForMessageOrTimeout(final Deployment deployment) throws Exception { final CountDownLatch latch = new CountDownLatch(1); new Thread(new Runnable() { @Override public void run() { try { new MessageWaiter(getTailProcess()).waitFor(deployment.getWaitForMessage()); latch.countDown(); } catch (IOException ex) { throw new RuntimeException(ex); } } }).start(); while (!timedout && !latch.await(50, MILLISECONDS)) { } } private void undeploy() throws Exception { for (Deployment deployment : getDeployments()) { deployment.undeploy(jboss.getDeployDir()); } } private void scheduleTimeout() { new Thread( new Runnable() { @Override public void run() { try { Thread.sleep(((long) getServerProperties().getDeploymentTimeoutMinutes()) * MILLISECONDS_IN_MINUTE); if (!deploymentComplete) { timedout = true; log.info("Server startup/deploy timeout exceeded."); } } catch (InterruptedException e) { // do nothing } catch (Exception e) { throw new RuntimeException(e); } } } ).start(); } protected void publishLog() throws IOException { File tmpLogFile = File.createTempFile("jboss_log", ".txt"); File logFile = new File(jboss.getServerLogPath()); FileUtils.copyFile(logFile, tmpLogFile); System.out.println("##teamcity[publishArtifacts '" + tmpLogFile.getAbsolutePath() + "']"); deleteLog(); } private void deleteLog() { boolean deleted = new File(jboss.getServerLogPath()).delete(); if (!deleted) { log.info("Unable to delete JBoss log"); } } }