/** Helper functions to run tests. */ public class Helpers implements play.mvc.Http.Status, play.mvc.Http.HeaderNames { public static String GET = "GET"; public static String POST = "POST"; public static String PUT = "PUT"; public static String DELETE = "DELETE"; public static String HEAD = "HEAD"; // -- public static Class<? extends WebDriver> HTMLUNIT = HtmlUnitDriver.class; public static Class<? extends WebDriver> FIREFOX = FirefoxDriver.class; // -- @SuppressWarnings(value = "unchecked") private static Result invokeHandler( play.api.mvc.Handler handler, FakeRequest fakeRequest, long timeout) { if (handler instanceof play.core.j.JavaAction) { play.api.mvc.Action action = (play.api.mvc.Action) handler; return wrapScalaResult(action.apply(fakeRequest.getWrappedRequest()), timeout); } else { throw new RuntimeException("This is not a JavaAction and can't be invoked this way."); } } /** * Default Timeout (milliseconds) for fake requests issued by these Helpers. This value is * determined from System property <b>test.timeout</b>. The default value is <b>30000</b> (30 * seconds). */ public static final long DEFAULT_TIMEOUT = Long.getLong("test.timeout", 30000L); private static Result wrapScalaResult( scala.concurrent.Future<play.api.mvc.Result> result, long timeout) { if (result == null) { return null; } else { final play.api.mvc.Result scalaResult = Promise.wrap(result).get(timeout); return new Result() { public play.api.mvc.Result toScala() { return scalaResult; } }; } } // -- /** Call an action method while decorating it with the right @With interceptors. */ public static Result callAction(HandlerRef actionReference) { return callAction(actionReference, DEFAULT_TIMEOUT); } public static Result callAction(HandlerRef actionReference, long timeout) { return callAction(actionReference, fakeRequest(), timeout); } /** Call an action method while decorating it with the right @With interceptors. */ public static Result callAction(HandlerRef actionReference, FakeRequest fakeRequest) { return callAction(actionReference, fakeRequest, DEFAULT_TIMEOUT); } public static Result callAction( HandlerRef actionReference, FakeRequest fakeRequest, long timeout) { play.api.mvc.HandlerRef handlerRef = (play.api.mvc.HandlerRef) actionReference; return invokeHandler(handlerRef.handler(), fakeRequest, timeout); } /** Build a new GET / fake request. */ public static FakeRequest fakeRequest() { return new FakeRequest(); } /** Build a new fake request. */ public static FakeRequest fakeRequest(String method, String uri) { return new FakeRequest(method, uri); } /** Build a new fake request corresponding to a given route call */ public static FakeRequest fakeRequest(Call call) { return fakeRequest(call.method(), call.url()); } /** Build a new fake application. */ public static FakeApplication fakeApplication() { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), new HashMap<String, Object>(), new ArrayList<String>(), null); } /** Build a new fake application. */ public static FakeApplication fakeApplication(GlobalSettings global) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), new HashMap<String, Object>(), new ArrayList<String>(), global); } /** A fake Global */ public static GlobalSettings fakeGlobal() { return new GlobalSettings(); } /** Constructs a in-memory (h2) database configuration to add to a FakeApplication. */ public static Map<String, String> inMemoryDatabase() { return inMemoryDatabase("default"); } /** Constructs a in-memory (h2) database configuration to add to a FakeApplication. */ public static Map<String, String> inMemoryDatabase(String name) { return inMemoryDatabase(name, Collections.<String, String>emptyMap()); } /** Constructs a in-memory (h2) database configuration to add to a FakeApplication. */ public static Map<String, String> inMemoryDatabase(String name, Map<String, String> options) { return Scala.asJava(play.api.test.Helpers.inMemoryDatabase(name, Scala.asScala(options))); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, new ArrayList<String>(), null); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration, GlobalSettings global) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, new ArrayList<String>(), global); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration, List<String> additionalPlugin) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, additionalPlugin, null); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration, List<String> additionalPlugin, GlobalSettings global) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, additionalPlugin, global); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration, List<String> additionalPlugins, List<String> withoutPlugins) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, additionalPlugins, withoutPlugins, null); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration, List<String> additionalPlugins, List<String> withoutPlugins, GlobalSettings global) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, additionalPlugins, withoutPlugins, global); } /** Extracts the Status code of this Result value. */ public static int status(Result result) { return result.toScala().header().status(); } /** Extracts the Location header of this Result value if this Result is a Redirect. */ public static String redirectLocation(Result result) { return header(LOCATION, result); } /** Extracts the Flash values of this Result value. */ public static Flash flash(Result result) { return JavaResultExtractor.getFlash(result); } /** Extracts the Session of this Result value. */ public static Session session(Result result) { return JavaResultExtractor.getSession(result); } /** Extracts a Cookie value from this Result value */ public static Cookie cookie(String name, Result result) { return JavaResultExtractor.getCookies(result).get(name); } /** Extracts the Cookies (an iterator) from this result value. */ public static Cookies cookies(Result result) { return play.core.j.JavaResultExtractor.getCookies(result); } /** Extracts an Header value of this Result value. */ public static String header(String header, Result result) { return JavaResultExtractor.getHeaders(result).get(header); } /** Extracts all Headers of this Result value. */ public static Map<String, String> headers(Result result) { return JavaResultExtractor.getHeaders(result); } /** Extracts the Content-Type of this Content value. */ public static String contentType(Content content) { return content.contentType(); } /** Extracts the Content-Type of this Result value. */ public static String contentType(Result result) { String h = header(CONTENT_TYPE, result); if (h == null) return null; if (h.contains(";")) { return h.substring(0, h.indexOf(";")).trim(); } else { return h.trim(); } } /** Extracts the Charset of this Result value. */ public static String charset(Result result) { String h = header(CONTENT_TYPE, result); if (h == null) return null; if (h.contains("; charset=")) { return h.substring(h.indexOf("; charset=") + 10, h.length()).trim(); } else { return null; } } /** Extracts the content as bytes. */ public static byte[] contentAsBytes(Result result) { return contentAsBytes(result, DEFAULT_TIMEOUT); } public static byte[] contentAsBytes(Result result, long timeout) { return JavaResultExtractor.getBody(result, timeout); } /** Extracts the content as bytes. */ public static byte[] contentAsBytes(Content content) { return content.body().getBytes(); } /** Extracts the content as String. */ public static String contentAsString(Content content) { return content.body(); } /** Extracts the content as String. */ public static String contentAsString(Result result) { return contentAsString(result, DEFAULT_TIMEOUT); } public static String contentAsString(Result result, long timeout) { try { String charset = charset(result); if (charset == null) { charset = "utf-8"; } return new String(contentAsBytes(result, timeout), charset); } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } @SuppressWarnings(value = "unchecked") public static Result routeAndCall(FakeRequest fakeRequest, long timeout) { try { return routeAndCall( (Class<? extends Routes>) FakeRequest.class.getClassLoader().loadClass("Routes"), fakeRequest, timeout); } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } public static Result routeAndCall( Class<? extends Routes> router, FakeRequest fakeRequest, long timeout) { try { Routes routes = (Routes) router .getClassLoader() .loadClass(router.getName() + "$") .getDeclaredField("MODULE$") .get(null); if (routes.routes().isDefinedAt(fakeRequest.getWrappedRequest())) { return invokeHandler( routes.routes().apply(fakeRequest.getWrappedRequest()), fakeRequest, timeout); } else { return null; } } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } public static Result route(FakeRequest fakeRequest) { return route(fakeRequest, DEFAULT_TIMEOUT); } public static Result route(FakeRequest fakeRequest, long timeout) { return route(play.Play.application(), fakeRequest, timeout); } public static Result route(Application app, FakeRequest fakeRequest) { return route(app, fakeRequest, DEFAULT_TIMEOUT); } public static Result route(Application app, FakeRequest fakeRequest, long timeout) { final scala.Option<scala.concurrent.Future<play.api.mvc.Result>> opt = play.api.test.Helpers.jRoute(app.getWrappedApplication(), fakeRequest.fake); return wrapScalaResult(Scala.orNull(opt), timeout); } public static Result route(Application app, FakeRequest fakeRequest, byte[] body) { return route(app, fakeRequest, body, DEFAULT_TIMEOUT); } public static Result route(Application app, FakeRequest fakeRequest, byte[] body, long timeout) { return wrapScalaResult( Scala.orNull( play.api.test.Helpers.jRoute( app.getWrappedApplication(), fakeRequest.getWrappedRequest(), body)), timeout); } public static Result route(FakeRequest fakeRequest, byte[] body) { return route(fakeRequest, body, DEFAULT_TIMEOUT); } public static Result route(FakeRequest fakeRequest, byte[] body, long timeout) { return route(play.Play.application(), fakeRequest, body, timeout); } /** Starts a new application. */ public static void start(FakeApplication fakeApplication) { play.api.Play.start(fakeApplication.getWrappedApplication()); } /** Stops an application. */ public static void stop(FakeApplication fakeApplication) { play.api.Play.stop(); } /** Executes a block of code in a running application. */ public static void running(FakeApplication fakeApplication, final Runnable block) { synchronized (PlayRunners$.MODULE$.mutex()) { try { start(fakeApplication); block.run(); } finally { stop(fakeApplication); } } } /** * Creates a new Test server listening on port defined by configuration setting "testserver.port" * (defaults to 19001). */ public static TestServer testServer() { return testServer(play.api.test.Helpers.testServerPort()); } /** * Creates a new Test server listening on port defined by configuration setting "testserver.port" * (defaults to 19001) and using the given FakeApplication. */ public static TestServer testServer(FakeApplication app) { return testServer(play.api.test.Helpers.testServerPort(), app); } /** Creates a new Test server. */ public static TestServer testServer(int port) { return new TestServer(port, fakeApplication()); } /** Creates a new Test server. */ public static TestServer testServer(int port, FakeApplication app) { return new TestServer(port, app); } /** Starts a Test server. */ public static void start(TestServer server) { server.start(); } /** Stops a Test server. */ public static void stop(TestServer server) { server.stop(); } /** Executes a block of code in a running server. */ public static void running(TestServer server, final Runnable block) { synchronized (PlayRunners$.MODULE$.mutex()) { try { start(server); block.run(); } finally { stop(server); } } } /** Executes a block of code in a running server, with a test browser. */ public static void running( TestServer server, Class<? extends WebDriver> webDriver, final Callback<TestBrowser> block) { running(server, play.api.test.WebDriverFactory.apply(webDriver), block); } /** Executes a block of code in a running server, with a test browser. */ public static void running( TestServer server, WebDriver webDriver, final Callback<TestBrowser> block) { synchronized (PlayRunners$.MODULE$.mutex()) { TestBrowser browser = null; TestServer startedServer = null; try { start(server); startedServer = server; browser = testBrowser(webDriver); block.invoke(browser); } catch (Error e) { throw e; } catch (RuntimeException re) { throw re; } catch (Throwable t) { throw new RuntimeException(t); } finally { if (browser != null) { browser.quit(); } if (startedServer != null) { stop(startedServer); } } } } /** Creates a Test Browser. */ public static TestBrowser testBrowser() { return testBrowser(HTMLUNIT); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(int port) { return testBrowser(HTMLUNIT, port); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(Class<? extends WebDriver> webDriver) { return testBrowser(webDriver, Helpers$.MODULE$.testServerPort()); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(Class<? extends WebDriver> webDriver, int port) { try { return new TestBrowser(webDriver, "http://localhost:" + port); } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } /** Creates a Test Browser. */ public static TestBrowser testBrowser(WebDriver of, int port) { return new TestBrowser(of, "http://localhost:" + port); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(WebDriver of) { return testBrowser(of, Helpers$.MODULE$.testServerPort()); } }
/** * PoliciesCache retains PolicyDocument objects for inserted Files, and reloads them if file * modification time changes. * * @author Greg Schueler <a href="mailto:[email protected]">[email protected]</a> */ public class PoliciesCache implements Iterable<PolicyCollection> { static final long DIR_LIST_CHECK_DELAY = Long.getLong(PoliciesCache.class.getName() + ".DirListCheckDelay", 60000); static final long FILE_CHECK_DELAY = Long.getLong(PoliciesCache.class.getName() + ".FileCheckDelay", 60000); private static final Logger logger = Logger.getLogger(PoliciesCache.class); static final FilenameFilter filenameFilter = new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".aclpolicy"); } }; private Set<File> warned = new HashSet<File>(); private Map<File, CacheItem> cache = new HashMap<File, CacheItem>(); private DocumentBuilder builder; private File rootDir; public PoliciesCache(File rootDir) throws ParserConfigurationException { this.rootDir = rootDir; DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); builder = domFactory.newDocumentBuilder(); builder.setErrorHandler(null); } private static class CacheItem { PolicyCollection policyCollection; Long cacheTime; Long modTime; private CacheItem(PolicyCollection policyCollection, Long modTime) { this.policyCollection = policyCollection; this.modTime = modTime; this.cacheTime = System.currentTimeMillis(); } public void touch(Long time) { this.cacheTime = time; } } long lastDirListCheckTime = 0; private File[] lastDirList; private File[] listDirFiles() { if (System.currentTimeMillis() - lastDirListCheckTime > DIR_LIST_CHECK_DELAY) { doListDir(); } return lastDirList; } private void doListDir() { lastDirList = rootDir.listFiles(filenameFilter); lastDirListCheckTime = System.currentTimeMillis(); } public synchronized void add(final File file) throws PoliciesParseException { getDocument(file); } private PolicyCollection createEntry(final File file) throws PoliciesParseException { try { return new YamlPolicyCollection(file); } catch (ParserException e1) { throw new PoliciesParseException("YAML syntax error: " + e1.toString(), e1); } catch (Exception e1) { throw new PoliciesParseException(e1); } } public synchronized PolicyCollection getDocument(final File file) throws PoliciesParseException { // cacheTotal++; CacheItem entry = cache.get(file); long checkTime = System.currentTimeMillis(); if (null == entry || ((checkTime - entry.cacheTime) > FILE_CHECK_DELAY)) { final long lastmod = file.lastModified(); if (null == entry || lastmod > entry.modTime) { if (!file.exists()) { CacheItem remove = cache.remove(file); entry = null; // cacheRemove++; } else { // cacheMiss++; PolicyCollection entry1 = createEntry(file); if (null != entry1) { entry = new CacheItem(entry1, lastmod); cache.put(file, entry); } else { cache.remove(file); entry = null; } } } else { // cacheUnmodifiedHit++; entry.touch(checkTime); } } else { // cacheHit++; } return null != entry ? entry.policyCollection : null; } public Iterator<PolicyCollection> iterator() { final File[] files = listDirFiles(); return new cacheIterator( null != files ? Arrays.asList(files).iterator() : new ArrayList<File>().iterator()); } private Map<File, Long> cooldownset = Collections.synchronizedMap(new HashMap<File, Long>()); /** * Iterator over the PoliciesDocuments for the cache's files. It skips files that cannot be * loaded. */ private class cacheIterator implements Iterator<PolicyCollection> { Iterator<File> intIter; private File nextFile; private PolicyCollection nextDocument; public cacheIterator(final Iterator<File> intIter) { this.intIter = intIter; nextFile = this.intIter.hasNext() ? this.intIter.next() : null; loadNextDocument(); } private void loadNextDocument() { while (hasNextFile() && null == nextDocument) { File nextFile2 = getNextFile(); Long aLong = cooldownset.get(nextFile2); if (null != aLong && nextFile2.lastModified() == aLong.longValue()) { logger.debug( "Skip parsing of: " + nextFile2 + ". Reason: parse error cooldown until modified"); continue; } else if (null != aLong) { // clear cooldownset.remove(nextFile2); } try { nextDocument = getDocument(nextFile2); } catch (PoliciesParseException e) { logger.error( "ERROR unable to parse aclpolicy: " + nextFile2 + ". Reason: " + e.getMessage()); logger.debug( "ERROR unable to parse aclpolicy: " + nextFile2 + ". Reason: " + e.getMessage(), e); cache.remove(nextFile2); cooldownset.put(nextFile2, nextFile2.lastModified()); } } } private File getNextFile() { File next = nextFile; nextFile = intIter.hasNext() ? intIter.next() : null; return next; } private PolicyCollection getNextDocument() { PolicyCollection doc = nextDocument; nextDocument = null; loadNextDocument(); return doc; } public boolean hasNextFile() { return null != nextFile; } public boolean hasNext() { return null != nextDocument; } public PolicyCollection next() { return getNextDocument(); } public void remove() {} } }
/** Helper functions to run tests. */ public class Helpers implements play.mvc.Http.Status, play.mvc.Http.HeaderNames { public static String GET = "GET"; public static String POST = "POST"; public static String PUT = "PUT"; public static String DELETE = "DELETE"; public static String HEAD = "HEAD"; // -- public static Class<? extends WebDriver> HTMLUNIT = HtmlUnitDriver.class; public static Class<? extends WebDriver> FIREFOX = FirefoxDriver.class; // -- @SuppressWarnings(value = "unchecked") private static Result invokeHandler( play.api.mvc.Handler handler, Request requestBuilder, long timeout) { if (handler instanceof play.api.mvc.Action) { play.api.mvc.Action action = (play.api.mvc.Action) handler; return wrapScalaResult(action.apply(requestBuilder._underlyingRequest()), timeout); } else if (handler instanceof JavaHandler) { return invokeHandler( ((JavaHandler) handler) .withComponents( Play.application().injector().instanceOf(JavaHandlerComponents.class)), requestBuilder, timeout); } else { throw new RuntimeException("This is not a JavaAction and can't be invoked this way."); } } /** * Default Timeout (milliseconds) for fake requests issued by these Helpers. This value is * determined from System property <b>test.timeout</b>. The default value is <b>30000</b> (30 * seconds). */ public static final long DEFAULT_TIMEOUT = Long.getLong("test.timeout", 30000L); private static Result wrapScalaResult( scala.concurrent.Future<play.api.mvc.Result> result, long timeout) { if (result == null) { return null; } else { final play.api.mvc.Result scalaResult = Promise.wrap(result).get(timeout); return scalaResult.asJava(); } } // -- /** Calls a Callable which invokes a Controller or some other method with a Context */ public static <V> V invokeWithContext(RequestBuilder requestBuilder, Callable<V> callable) { try { Context.current.set(new Context(requestBuilder)); return callable.call(); } catch (Exception e) { throw new RuntimeException(e); } finally { Context.current.remove(); } } /** Build a new GET / fake request. */ public static RequestBuilder fakeRequest() { return fakeRequest("GET", "/"); } /** Build a new fake request. */ public static RequestBuilder fakeRequest(String method, String uri) { return new RequestBuilder().method(method).uri(uri); } /** Build a new fake request corresponding to a given route call */ public static RequestBuilder fakeRequest(Call call) { return fakeRequest(call.method(), call.url()); } /** Build a new fake application. */ public static FakeApplication fakeApplication() { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), new HashMap<String, Object>(), null); } /** * Build a new fake application. * * @deprecated Use dependency injection (since 2.5.0) */ @Deprecated public static FakeApplication fakeApplication(GlobalSettings global) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), new HashMap<String, Object>(), global); } /** * A fake Global. * * @deprecated Use dependency injection (since 2.5.0) */ @Deprecated public static GlobalSettings fakeGlobal() { return new GlobalSettings(); } /** Constructs a in-memory (h2) database configuration to add to a FakeApplication. */ public static Map<String, String> inMemoryDatabase() { return inMemoryDatabase("default"); } /** Constructs a in-memory (h2) database configuration to add to a FakeApplication. */ public static Map<String, String> inMemoryDatabase(String name) { return inMemoryDatabase(name, Collections.<String, String>emptyMap()); } /** Constructs a in-memory (h2) database configuration to add to a FakeApplication. */ public static Map<String, String> inMemoryDatabase(String name, Map<String, String> options) { return Scala.asJava(play.api.test.Helpers.inMemoryDatabase(name, Scala.asScala(options))); } /** Build a new fake application. */ public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration); } /** * Build a new fake application. * * @deprecated Use the version without GlobalSettings (since 2.5.0) */ @Deprecated public static FakeApplication fakeApplication( Map<String, ? extends Object> additionalConfiguration, GlobalSettings global) { return new FakeApplication( new java.io.File("."), Helpers.class.getClassLoader(), additionalConfiguration, global); } /** * Extracts the content as a {@link akka.util.ByteString}. * * <p>This method is only capable of extracting the content of results with strict entities. To * extract the content of results with streamed entities, use {@link #contentAsBytes(Result, * Materializer)}. * * @param result The result to extract the content from. * @return The content of the result as a ByteString. * @throws UnsupportedOperationException if the result does not have a strict entity. */ public static ByteString contentAsBytes(Result result) { if (result.body() instanceof HttpEntity.Strict) { return ((HttpEntity.Strict) result.body()).data(); } else { throw new UnsupportedOperationException( "Tried to extract body from a non strict HTTP entity without a materializer, use the version of this method that accepts a materializer instead"); } } /** * Extracts the content as a {@link akka.util.ByteString}. * * @param result The result to extract the content from. * @param mat The materialiser to use to extract the body from the result stream. * @return The content of the result as a ByteString. */ public static ByteString contentAsBytes(Result result, Materializer mat) { return contentAsBytes(result, mat, DEFAULT_TIMEOUT); } /** * Extracts the content as a {@link akka.util.ByteString}. * * @param result The result to extract the content from. * @param mat The materialiser to use to extract the body from the result stream. * @param timeout The amount of time, in milliseconds, to wait for the body to be produced. * @return The content of the result as a ByteString. */ public static ByteString contentAsBytes(Result result, Materializer mat, long timeout) { try { return result .body() .consumeData(mat) .thenApply(Function.identity()) .toCompletableFuture() .get(timeout, TimeUnit.MILLISECONDS); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } } /** Extracts the content as bytes. */ public static ByteString contentAsBytes(Content content) { return ByteString.fromString(content.body()); } /** Extracts the content as a String. */ public static String contentAsString(Content content) { return content.body(); } /** * Extracts the content as a String. * * <p>This method is only capable of extracting the content of results with strict entities. To * extract the content of results with streamed entities, use {@link #contentAsString(Result, * Materializer)}. * * @param result The result to extract the content from. * @return The content of the result as a String. * @throws UnsupportedOperationException if the result does not have a strict entity. */ public static String contentAsString(Result result) { return contentAsBytes(result).decodeString(result.charset().orElse("utf-8")); } /** * Extracts the content as a String. * * @param result The result to extract the content from. * @param mat The materialiser to use to extract the body from the result stream. * @return The content of the result as a String. */ public static String contentAsString(Result result, Materializer mat) { return contentAsBytes(result, mat, DEFAULT_TIMEOUT) .decodeString(result.charset().orElse("utf-8")); } /** * Extracts the content as a String. * * @param result The result to extract the content from. * @param mat The materialiser to use to extract the body from the result stream. * @param timeout The amount of time, in milliseconds, to wait for the body to be produced. * @return The content of the result as a String. */ public static String contentAsString(Result result, Materializer mat, long timeout) { return contentAsBytes(result, mat, timeout).decodeString(result.charset().orElse("utf-8")); } @SuppressWarnings(value = "unchecked") public static Result routeAndCall(RequestBuilder requestBuilder, long timeout) { try { return routeAndCall( (Class<? extends Router>) RequestBuilder.class.getClassLoader().loadClass("Routes"), requestBuilder, timeout); } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } public static Result routeAndCall( Class<? extends Router> router, RequestBuilder requestBuilder, long timeout) { try { Request request = requestBuilder.build(); Router routes = (Router) router .getClassLoader() .loadClass(router.getName() + "$") .getDeclaredField("MODULE$") .get(null); if (routes.routes().isDefinedAt(request._underlyingRequest())) { return invokeHandler(routes.routes().apply(request._underlyingRequest()), request, timeout); } else { return null; } } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } public static Result routeAndCall(Router router, RequestBuilder requestBuilder) { return routeAndCall(router, requestBuilder, DEFAULT_TIMEOUT); } public static Result routeAndCall(Router router, RequestBuilder requestBuilder, long timeout) { try { Request request = requestBuilder.build(); if (router.routes().isDefinedAt(request._underlyingRequest())) { return invokeHandler(router.routes().apply(request._underlyingRequest()), request, timeout); } else { return null; } } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } public static Result route(Call call) { return route(fakeRequest(call)); } public static Result route(Call call, long timeout) { return route(fakeRequest(call), timeout); } public static Result route(Application app, Call call) { return route(app, fakeRequest(call)); } public static Result route(Application app, Call call, long timeout) { return route(app, fakeRequest(call), timeout); } public static Result route(RequestBuilder requestBuilder) { return route(requestBuilder, DEFAULT_TIMEOUT); } public static Result route(RequestBuilder requestBuilder, long timeout) { return route(play.Play.application(), requestBuilder, timeout); } public static Result route(Application app, RequestBuilder requestBuilder) { return route(app, requestBuilder, DEFAULT_TIMEOUT); } @SuppressWarnings("unchecked") public static Result route(Application app, RequestBuilder requestBuilder, long timeout) { final scala.Option<scala.concurrent.Future<play.api.mvc.Result>> opt = play.api.test.Helpers.jRoute( app.getWrappedApplication(), requestBuilder.build()._underlyingRequest(), requestBuilder.body()); return wrapScalaResult(Scala.orNull(opt), timeout); } /** Starts a new application. */ public static void start(Application application) { play.api.Play.start(application.getWrappedApplication()); } /** Stops an application. */ public static void stop(Application application) { play.api.Play.stop(application.getWrappedApplication()); } /** Executes a block of code in a running application. */ public static void running(Application application, final Runnable block) { synchronized (PlayRunners$.MODULE$.mutex()) { try { start(application); block.run(); } finally { stop(application); } } } /** * Creates a new Test server listening on port defined by configuration setting "testserver.port" * (defaults to 19001). */ public static TestServer testServer() { return testServer(play.api.test.Helpers.testServerPort()); } /** * Creates a new Test server listening on port defined by configuration setting "testserver.port" * (defaults to 19001) and using the given FakeApplication. */ public static TestServer testServer(Application app) { return testServer(play.api.test.Helpers.testServerPort(), app); } /** Creates a new Test server. */ public static TestServer testServer(int port) { return new TestServer(port, fakeApplication()); } /** Creates a new Test server. */ public static TestServer testServer(int port, Application app) { return new TestServer(port, app); } /** Starts a Test server. */ public static void start(TestServer server) { server.start(); } /** Stops a Test server. */ public static void stop(TestServer server) { server.stop(); } /** Executes a block of code in a running server. */ public static void running(TestServer server, final Runnable block) { synchronized (PlayRunners$.MODULE$.mutex()) { try { start(server); block.run(); } finally { stop(server); } } } /** Executes a block of code in a running server, with a test browser. */ public static void running( TestServer server, Class<? extends WebDriver> webDriver, final Consumer<TestBrowser> block) { running(server, play.api.test.WebDriverFactory.apply(webDriver), block); } /** Executes a block of code in a running server, with a test browser. */ public static void running( TestServer server, WebDriver webDriver, final Consumer<TestBrowser> block) { synchronized (PlayRunners$.MODULE$.mutex()) { TestBrowser browser = null; TestServer startedServer = null; try { start(server); startedServer = server; browser = testBrowser(webDriver, server.port()); block.accept(browser); } finally { if (browser != null) { browser.quit(); } if (startedServer != null) { stop(startedServer); } } } } /** Creates a Test Browser. */ public static TestBrowser testBrowser() { return testBrowser(HTMLUNIT); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(int port) { return testBrowser(HTMLUNIT, port); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(Class<? extends WebDriver> webDriver) { return testBrowser(webDriver, Helpers$.MODULE$.testServerPort()); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(Class<? extends WebDriver> webDriver, int port) { try { return new TestBrowser(webDriver, "http://localhost:" + port); } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw new RuntimeException(t); } } /** Creates a Test Browser. */ public static TestBrowser testBrowser(WebDriver of, int port) { return new TestBrowser(of, "http://localhost:" + port); } /** Creates a Test Browser. */ public static TestBrowser testBrowser(WebDriver of) { return testBrowser(of, Helpers$.MODULE$.testServerPort()); } }
public class SGTestNGListener extends TestListenerAdapter { protected String testMethodName; protected String suiteName; protected String buildNumber; protected String version; protected ScriptingContainer container; private Process process = null; private Process process2 = null; private String logstashLogPath; private String logstashLogPath2; private static final boolean enableLogstash = Boolean.parseBoolean(System.getProperty("iTests.enableLogstash", "false")); protected static final String CREDENTIALS_FOLDER = System.getProperty( "iTests.credentialsFolder", SGTestHelper.getSGTestRootDir() + "/src/main/resources/credentials"); private static File propsFile = new File(CREDENTIALS_FOLDER + "/logstash/logstash.properties"); protected String logstashHost; private static long testInvocationCounter = 1; private static final long maxCount = Long.getLong("sgtest.webui.numberOfTestRetries", 3) + 1; public SGTestNGListener() { if (enableLogstash) { LogUtils.log("in SGTestNGListener constructor"); } } @Override public void onStart(ITestContext iTestContext) { suiteName = System.getProperty("iTests.suiteName", "sgtest"); LogUtils.log("suite number is now (on start) - " + suiteName); if (enableLogstash) { buildNumber = System.getProperty("iTests.buildNumber"); LogUtils.log("build number is now (on start) - " + buildNumber); version = System.getProperty("cloudifyVersion"); } } private void initLogstash2(ITestResult tr) { initLogstashHost(); String simpleClassName = tr.getTestClass().getRealClass().getSimpleName(); String pathToLogstash = SGTestHelper.getSGTestRootDir().replace("\\", "/") + "/src/main/resources/logstash"; String confFilePath2 = pathToLogstash + "/logstash-shipper-client-2.conf"; String backupFilePath2 = pathToLogstash + "/logstash-shipper-client-2-" + simpleClassName + ".conf"; File backupFile2 = new File(backupFilePath2); LogUtils.log( "trying to start logstash agent number 2. simple class name is " + simpleClassName); if (backupFile2.exists()) { LogUtils.log("the file " + backupFilePath2 + " already exists. not starting logstash"); } if (!isAfter(tr) && !backupFile2.exists()) { try { // backupFilePath2 = IOUtils.backupFile(confFilePath2); LogUtils.log("copying file " + confFilePath2 + " to " + backupFilePath2); IOUtils.copyFile(confFilePath2, backupFilePath2); IOUtils.replaceTextInFile(backupFilePath2, "<path_to_build>", SGTestHelper.getBuildDir()); IOUtils.replaceTextInFile( backupFilePath2, "<suite_number>", "suite_" + System.getProperty("iTests.suiteId", "0")); IOUtils.replaceTextInFile( backupFilePath2, "<path_to_test_class_folder>", SGTestHelper.getSGTestRootDir().replace("\\", "/") + "/../" + suiteName + "/" + tr.getTestClass().getName()); IOUtils.replaceTextInFile(backupFilePath2, "<suite_name>", suiteName); IOUtils.replaceTextInFile(backupFilePath2, "<test_name>", simpleClassName); IOUtils.replaceTextInFile(backupFilePath2, "<build_number>", buildNumber); IOUtils.replaceTextInFile(backupFilePath2, "<version>", version); IOUtils.replaceTextInFile(backupFilePath2, "<host>", logstashHost); String logstashJarPath = DeploymentUtils.getLocalRepository() + "net/logstash/1.2.2/logstash-1.2.2.jar"; logstashLogPath2 = pathToLogstash + "/logstash-" + simpleClassName + "-2.txt"; String cmdLine = "java -jar " + logstashJarPath + " agent -f " + backupFilePath2 + " -l " + logstashLogPath2; final String[] parts = cmdLine.split(" "); final ProcessBuilder pb = new ProcessBuilder(parts); LogUtils.log("Executing Command line: " + cmdLine); process2 = pb.start(); } catch (IOException e) { e.printStackTrace(); } } } private void initLogstash(String testName) { initLogstashHost(); String pathToLogstash = SGTestHelper.getSGTestRootDir().replace("\\", "/") + "/src/main/resources/logstash"; String confFilePath = pathToLogstash + "/logstash-shipper-client.conf"; String fixedTestName = testName.substring(0, testName.length() - 2); String backupFilePath = pathToLogstash + "/logstash-shipper-client-" + fixedTestName + ".conf"; if (process == null) { try { LogUtils.log("copying file " + confFilePath + " to " + backupFilePath); IOUtils.copyFile(confFilePath, backupFilePath); // backupFilePath = IOUtils.backupFile(confFilePath); IOUtils.replaceTextInFile( backupFilePath, "<path_to_test_folder>", SGTestHelper.getSGTestRootDir().replace("\\", "/") + "/../" + suiteName + "/" + testName); IOUtils.replaceTextInFile(backupFilePath, "<suite_name>", suiteName); IOUtils.replaceTextInFile(backupFilePath, "<test_name>", testName); IOUtils.replaceTextInFile(backupFilePath, "<build_number>", buildNumber); IOUtils.replaceTextInFile(backupFilePath, "<version>", version); IOUtils.replaceTextInFile(backupFilePath, "<host>", logstashHost); String logstashJarPath = DeploymentUtils.getLocalRepository() + "net/logstash/1.2.2/logstash-1.2.2.jar"; logstashLogPath = pathToLogstash + "/logstash-" + fixedTestName + ".txt"; String cmdLine = "java -jar " + logstashJarPath + " agent -f " + backupFilePath + " -l " + logstashLogPath; final String[] parts = cmdLine.split(" "); final ProcessBuilder pb = new ProcessBuilder(parts); LogUtils.log("Executing Command line: " + cmdLine); TimeUnit.SECONDS.sleep(1); process = pb.start(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void beforeConfiguration(ITestResult tr) { if (enableLogstash) { super.beforeConfiguration(tr); if (suiteName == null) { // this is in case the suite has a @BeforeSuite method. which is invoked before // the onStart is. suiteName = System.getProperty("iTests.suiteName", "sgtest"); buildNumber = System.getProperty("iTests.buildNumber"); LogUtils.log("build number is now - " + buildNumber); version = System.getProperty("cloudifyVersion"); } } } @Override public void onConfigurationSuccess(ITestResult iTestResult) { super.onConfigurationSuccess(iTestResult); String testName = iTestResult.getTestClass().getName(); String configurationName = iTestResult.getMethod().toString().split("\\(|\\)")[0]; if (isAfter(iTestResult) && !enableLogstash) { DumpUtils.copyBeforeConfigurationsLogToTestDir(testName, suiteName); testName = testMethodName; } if (suiteName == null) { // this is in case the suite has a @BeforeSuite method. which is invoked before // the onStart is. suiteName = System.getProperty("iTests.suiteName", "sgtest"); } LogUtils.log("Configuration Succeeded: " + configurationName); if (enableLogstash && iTestResult.getMethod().isBeforeClassConfiguration()) { initLogstash2(iTestResult); } String newmanTestFolder = System.getProperty("newman.test.path"); if (newmanTestFolder != null) { File testFolder = new File(newmanTestFolder); ZipUtils.unzipArchive(testFolder); try { copyAllFilesToLogDir(testFolder, testFolder); } catch (IOException e) { LogUtils.log("Failed to copy all log files - caught " + e, e); } } else { ZipUtils.unzipArchive(testMethodName, suiteName); } if (enableLogstash && isAfter(iTestResult) && !iTestResult.getMethod().isAfterClassConfiguration() && !iTestResult.getMethod().isAfterSuiteConfiguration()) { testName = testMethodName; } write2LogFile(iTestResult, DumpUtils.createTestFolder(testName, suiteName)); if (isAfter(iTestResult)) { if (enableLogstash) { if (process != null) { killLogstashAgent(1, logstashLogPath); } if (process2 != null && iTestResult.getMethod().isAfterClassConfiguration()) { killLogstashAgent(2, logstashLogPath2); } } } } @Override public void onConfigurationFailure(ITestResult iTestResult) { super.onConfigurationFailure(iTestResult); String testName = iTestResult.getTestClass().getName(); String configurationName = iTestResult.getMethod().toString().split("\\(|\\)")[0]; if (!enableLogstash && isAfter(iTestResult)) { DumpUtils.copyBeforeConfigurationsLogToTestDir(testName, suiteName); testName = testMethodName; } if (suiteName == null) { // this is in case the suite has a @BeforeSuite method. which is invoked before // the onStart is. suiteName = System.getProperty("iTests.suiteName", "sgtest"); } LogUtils.log("Configuration Failed: " + configurationName, iTestResult.getThrowable()); if (enableLogstash && iTestResult.getMethod().isBeforeClassConfiguration()) { initLogstash2(iTestResult); } String newmanTestFolder = System.getProperty("newman.test.path"); if (newmanTestFolder != null) { File testFolder = new File(newmanTestFolder); ZipUtils.unzipArchive(testFolder); try { copyAllFilesToLogDir(testFolder, testFolder); } catch (IOException e) { LogUtils.log("Failed to copy all log files"); } } else { ZipUtils.unzipArchive(testMethodName, suiteName); } if (enableLogstash && isAfter(iTestResult) && !iTestResult.getMethod().isAfterClassConfiguration() && !iTestResult.getMethod().isAfterSuiteConfiguration()) { testName = testMethodName; } File testFolder = DumpUtils.createTestFolder(testName, suiteName); write2LogFile(iTestResult, testFolder); write2ErrorTxtFile(iTestResult, testFolder); if (isAfter(iTestResult)) { if (enableLogstash) { if (process != null) { killLogstashAgent(1, logstashLogPath); } if (process2 != null && iTestResult.getMethod().isAfterClassConfiguration()) { killLogstashAgent(2, logstashLogPath2); } } } } @Override public void onConfigurationSkip(ITestResult iTestResult) { super.onConfigurationFailure(iTestResult); String testName = iTestResult.getTestClass().getName(); String configurationName = iTestResult.getMethod().toString().split("\\(|\\)")[0]; if (!enableLogstash && isAfter(iTestResult)) { DumpUtils.copyBeforeConfigurationsLogToTestDir(testName, suiteName); testName = testMethodName; } LogUtils.log("Configuration Skipped: " + configurationName, iTestResult.getThrowable()); if (enableLogstash && iTestResult.getMethod().isBeforeClassConfiguration()) { initLogstash2(iTestResult); } String newmanTestFolder = System.getProperty("newman.test.path"); if (newmanTestFolder != null) { File testFolder = new File(newmanTestFolder); ZipUtils.unzipArchive(testFolder); try { copyAllFilesToLogDir(testFolder, testFolder); } catch (IOException e) { LogUtils.log("Failed to copy all log files"); } } else { ZipUtils.unzipArchive(testMethodName, suiteName); } if (enableLogstash && isAfter(iTestResult) && !iTestResult.getMethod().isAfterClassConfiguration() && !iTestResult.getMethod().isAfterSuiteConfiguration()) { testName = testMethodName; } write2LogFile(iTestResult, DumpUtils.createTestFolder(testName, suiteName)); if (isAfter(iTestResult)) { if (enableLogstash) { if (process != null) { killLogstashAgent(1, logstashLogPath); } if (process2 != null && iTestResult.getMethod().isAfterClassConfiguration()) { killLogstashAgent(2, logstashLogPath2); } } } } @Override public void onTestStart(ITestResult iTestResult) { super.onTestStart(iTestResult); String testName = TestNGUtils.constructTestMethodName(iTestResult); LogUtils.log("Test Start: " + testName); if (enableLogstash) { initLogstash(testName); } } @Override public void onTestFailure(ITestResult iTestResult) { if (suiteName.toLowerCase().contains("webui")) { if (testInvocationCounter < maxCount) { testInvocationCounter++; iTestResult.setAttribute("retry", true); } else { LogUtils.log("Number of retries expired."); iTestResult.setStatus(ITestResult.FAILURE); // reset count testInvocationCounter = 1; testMethodName = TestNGUtils.constructTestMethodName(iTestResult); LogUtils.log("Test Failed: " + testMethodName, iTestResult.getThrowable()); File testFolder = DumpUtils.createTestFolder(testMethodName, suiteName); write2LogFile(iTestResult, testFolder); write2ErrorTxtFile(iTestResult, testFolder); } } else { testMethodName = TestNGUtils.constructTestMethodName(iTestResult); LogUtils.log("Test Failed: " + testMethodName, iTestResult.getThrowable()); File testFolder = DumpUtils.createTestFolder(testMethodName, suiteName); write2LogFile(iTestResult, testFolder); write2ErrorTxtFile(iTestResult, testFolder); } super.onTestFailure(iTestResult); } @Override public void onTestSkipped(ITestResult iTestResult) { super.onTestSkipped(iTestResult); testMethodName = TestNGUtils.constructTestMethodName(iTestResult); LogUtils.log("Test Skipped: " + testMethodName, iTestResult.getThrowable()); write2LogFile(iTestResult, DumpUtils.createTestFolder(testMethodName, suiteName)); } @Override public void onTestSuccess(ITestResult iTestResult) { super.onTestSuccess(iTestResult); if (suiteName.toLowerCase().contains("webui")) { testInvocationCounter = 1; } testMethodName = TestNGUtils.constructTestMethodName(iTestResult); LogUtils.log("Test Passed: " + testMethodName); write2LogFile(iTestResult, DumpUtils.createTestFolder(testMethodName, suiteName)); } @Override public void onFinish(ITestContext testContext) { super.onFinish(testContext); if (suiteName == null) suiteName = System.getProperty("iTests.suiteName", "sgtest"); LogUtils.log("Finishing Suite: " + suiteName.toLowerCase()); if (suiteName.toLowerCase().contains("webui")) { onFinishWebUITests(testContext); } try { SGTestNGReporter.reset(); } catch (Exception e) { // ignore } } private void onFinishWebUITests(ITestContext testContext) { // List of test results which we will delete later because of duplication or because the test // eventually passed List<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>(); // collect all id's from passed test Set<Integer> passedTestIds = new HashSet<Integer>(); for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) { passedTestIds.add(getTestId(passedTest)); } Set<Integer> failedTestIds = new HashSet<Integer>(); for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) { int failedTestId = getTestId(failedTest); // if this test failed before mark as to be deleted // or delete this failed test if there is at least one passed version if (failedTestIds.contains(failedTestId) || passedTestIds.contains(failedTestId)) { testsToBeRemoved.add(failedTest); } else { failedTestIds.add(failedTestId); } } // finally delete all tests that are marked for (Iterator<ITestResult> iterator = testContext.getFailedTests().getAllResults().iterator(); iterator.hasNext(); ) { ITestResult testResult = iterator.next(); if (testsToBeRemoved.contains(testResult)) { iterator.remove(); } } } // returns an ID for each test result private int getTestId(ITestResult result) { int id = result.getTestClass().getName().hashCode(); id = 31 * id + result.getMethod().getMethodName().hashCode(); id = 31 * id + (result.getParameters() != null ? Arrays.hashCode(result.getParameters()) : 0); return id; } private void write2LogFile(ITestResult iTestResult, File testFolder) { BufferedWriter out = null; try { if (testFolder == null) { LogUtils.log("Can not write to file test folder is null"); return; } String output = SGTestNGReporter.getOutput(); if (StringUtils.isEmpty(output)) { LogUtils.log("nothing to write to log file"); return; } String parameters = TestNGUtils.extractParameters(iTestResult); File testLogFile = new File( testFolder.getAbsolutePath() + "/" + iTestResult.getName() + "(" + parameters + ").log"); if (!testLogFile.createNewFile()) { LogUtils.log( "Failed to create log file [" + testLogFile + "];\n log output: " + Reporter.getOutput()); return; } FileWriter fstream = new FileWriter(testLogFile); out = new BufferedWriter(fstream); out.write(output); } catch (Exception e) { LogUtils.log("Failed to write to log file result - " + iTestResult, e); } finally { SGTestNGReporter.reset(); if (out != null) { try { out.close(); } catch (IOException e) { LogUtils.log("Failed closing stream", e); // ignore } } } } private void write2ErrorTxtFile(ITestResult iTestResult, File testFolder) { if (testFolder == null) { LogUtils.log("Can not write error.txt - test folder is null"); return; } //noinspection ThrowableResultOfMethodCallIgnored if (iTestResult.getThrowable() == null) { LogUtils.log("nothing to write to error.txt - throwable is null"); return; } // trim if too long //noinspection ThrowableResultOfMethodCallIgnored String errorMsg = iTestResult.getThrowable().toString(); if (errorMsg.length() > 120) { errorMsg = errorMsg.substring(0, 120 - 3) + "..."; } File errorTxtFile = new File(testFolder.getAbsolutePath(), "error.txt"); PrintWriter out = null; try { out = new PrintWriter(new BufferedWriter(new FileWriter(errorTxtFile, true))); out.println(errorMsg); } catch (IOException ioe) { LogUtils.log("Failed to write contents into error.txt file", ioe); } finally { if (out != null) { out.close(); } } } private boolean isAfter(ITestResult iTestResult) { ITestNGMethod method = iTestResult.getMethod(); return (method.isAfterClassConfiguration() || method.isAfterMethodConfiguration() || method.isAfterSuiteConfiguration() || method.isAfterTestConfiguration()); } private void killLogstashAgent(int logAgentNumber, String logstashLogPath) { FileObject listendir; CustomFileListener listener = new CustomFileListener(); long TIMEOUT_BETWEEN_FILE_QUERYING = 1000; long LOOP_TIMEOUT_IN_MILLIS = 10 * 1000; try { FileSystemManager fileSystemManager = VFS.getManager(); listendir = fileSystemManager.resolveFile(logstashLogPath); } catch (FileSystemException e) { e.printStackTrace(); return; } DefaultFileMonitor fm = new DefaultFileMonitor(listener); fm.setRecursive(true); fm.addFile(listendir); fm.setDelay(TIMEOUT_BETWEEN_FILE_QUERYING); fm.start(); LogUtils.log("waiting to destroy logger"); long startTimeMillis = System.currentTimeMillis(); while (true) { if (!listener.isProcessUp()) { break; } listener.setProcessUp(false); try { TimeUnit.MILLISECONDS.sleep(LOOP_TIMEOUT_IN_MILLIS); } catch (InterruptedException e) { e.printStackTrace(); } } long endTimeMillis = System.currentTimeMillis(); LogUtils.log("destroying logstash agent " + logAgentNumber); LogUtils.log("waited " + (endTimeMillis - startTimeMillis) / 1000 + " seconds"); fm.stop(); // File logstashOutputFile = new File(logstashLogPath); if (logAgentNumber == 1) { process.destroy(); process = null; } else { process2.destroy(); process2 = null; } // try { // TimeUnit.SECONDS.sleep(5); // // LogUtils.log("returning logstash config file to initial state"); // if(logAgentNumber == 1){ // IOUtils.replaceFileWithMove(new File(confFilePath), new File(backupFilePath)); // FileUtils.deleteQuietly(new File(backupFilePath)); // } // else{ // IOUtils.replaceFileWithMove(new File(confFilePath2), new // File(backupFilePath2)); // FileUtils.deleteQuietly(new File(backupFilePath2)); // // } // } catch (IOException e) { // e.printStackTrace(); // } catch (InterruptedException e) { // e.printStackTrace(); // } // if(logstashOutputFile.exists()){ // FileUtils.deleteQuietly(logstashOutputFile); // } } private void initLogstashHost() { if (logstashHost != null) { return; } Properties props; try { props = IOUtils.readPropertiesFromFile(propsFile); } catch (final Exception e) { throw new IllegalStateException("Failed reading properties file : " + e.getMessage()); } logstashHost = props.getProperty("logstash_server_host"); } private void copyAllFilesToLogDir(File node, File parent) throws IOException { if (!node.getAbsoluteFile().equals(parent.getAbsoluteFile()) && node.isFile() && !node.getParentFile().equals(parent)) { String fileNamePrefix = node.getName().substring(0, node.getName().lastIndexOf('.')); String fileNameSuffix = node.getName().substring(node.getName().lastIndexOf('.')); String newFilePath = node.getParentFile().getAbsolutePath() + File.separator + fileNamePrefix.replace(".", "_") + fileNameSuffix; File newNode = new File(newFilePath); if (node.renameTo(newNode)) { FileUtils.copyFileToDirectory(newNode, parent); } } if (node.isDirectory()) { String[] subNote = node.list(); for (String filename : subNote) { copyAllFilesToLogDir(new File(node, filename), parent); } if (!node.equals(parent)) { FileUtils.deleteDirectory(node); } } } }
/** * Test suite for distributing JUnit3 tests. Simply add tests to this suite just like you would for * regular JUnit3 suites, and these tests will be executed in parallel on the grid. Note that if * there are no other grid nodes, this suite will still ensure parallel test execution within single * JVM. * * <p>Below is an example of distributed JUnit3 test suite: * * <pre name="code" class="java"> * public class GridJunit3ExampleTestSuite { * // Standard JUnit3 static suite method. * public static TestSuite suite() { * TestSuite suite = new GridJunit3TestSuite("Example Grid Test Suite"); * * // Add tests. * suite.addTestSuite(TestA.class); * suite.addTestSuite(TestB.class); * suite.addTestSuite(TestC.class); * * return suite; * } * } * </pre> * * If you have four tests A, B, C, and D, and if you need to run A and B sequentially, then you * should create a nested test suite with test A and B as follows: * * <pre name="code" class="java"> * public class GridJunit3ExampleTestSuite { * // Standard JUnit3 static suite method. * public static TestSuite suite() { * TestSuite suite = new GridJunit3TestSuite("Example Grid Test Suite"); * * // Nested test suite to run tests A and B sequentially. * TestSuite nested = new TestSuite("Example Nested Sequential Suite"); * * nested.addTestSuite(TestA.class); * nested.addTestSuite(TestB.class); * * // Add tests A and B. * suite.addTest(nested); * * // Add other tests. * suite.addTestSuite(TestC.class); * * return suite; * } * } * </pre> * * <p>Note that you can also grid-enable existing JUnit3 tests using {@link * GridifyTest @GridifyTest} annotation which you can attach to your {@code suite()} methods of * existing test suite. Refer to {@link GridifyTest @GridifyTest} documentation for more * information. * * <p>Also note that some tests can only be executed locally mostly due to some environment issues. * However they still can benefit from parallel execution with other tests. GridGain supports it via * {@link GridJunit3LocalTestSuite} suites that can be added to {@code GridJunit3TestSuite}. Refer * to {@link GridJunit3LocalTestSuite} documentation for more information. * * <h1 class="header">Logging</h1> * * When running distributed JUnit, all the logging that is done to {@link System#out} or {@link * System#err} is preserved. GridGain will accumulate all logging that is done on remote nodes, send * them back to originating node and associate all log statements with their corresponding tests. * This way, for example, if you are running tests from and IDEA or Eclipse (or any other IDE) you * would still see the logs as if it was a local run. However, since remote nodes keep all log * statements done within a single individual test case in memory, you must make sure that enough * memory is allocated on every node and that individual test cases do not spit out gigabytes of log * statements. Also note, that logs will be sent back to originating node upon completion of every * test, so don't be alarmed if you don't see any log statements for a while and then all of them * appear at once. * * <p>GridGain achieves such log transparency via reassigning {@link System#out} or {@link * System#err} to internal {@link PrintStream} implementation. However, when using {@code Log4J} (or * any other logging framework) within your tests you must make sure that it is configured with * {@link ConsoleAppender} and that {@link ConsoleAppender#setFollow(boolean)} attribute is set to * {@code true}. Logging to files is not supported yet and is planned for next point release. * * <p> * * <h1 class="header">Test Suite Nesting</h1> * * {@code GridJunit3TestSuite} instances can be nested within each other as deep as needed. However * all nested distributed test suites will be treated just like regular JUnit test suites, and not * as distributed test suites. This approach becomes convenient when you have several distributed * test suites that you would like to be able to execute separately in distributed fashion, but at * the same time you would like to be able to execute them as a part of larger distributed suites. * * <p> * * <h1 class="header">Configuration</h1> * * To run distributed JUnit tests you need to start other instances of GridGain. You can do so by * running {@code GRIDGAIN_HOME/bin/ggjunit.{sh|bat}} script, which will start default * configuration. If configuration other than default is required, then use regular {@code * GRIDGAIN_HOME/bin/ggstart.{sh|bat}} script and pass your own Spring XML configuration file as a * parameter to the script. * * <p>You can use the following configuration parameters to configure distributed test suite * locally. Note that many parameters can be overridden by setting corresponding VM parameters * defined in {@link GridTestVmParameters} at VM startup. * * <table class="doctable"> * <tr> * <th>GridConfiguration Method</th> * <th>Default Value</th> * <th>Description</th> * </tr> * <tr> * <td>{@link #setDisabled(boolean) setDisabled(boolean)}</td> * <td>{@code false}</td> * <td> * If {@code true} then GridGain will be turned off and suite will run locally. * This value can be overridden by setting {@link GridTestVmParameters#GRIDGAIN_DISABLED} VM * parameter to {@code true}. This parameter comes handy when you would like to * turn off GridGain without changing the actual code. * </td> * </tr> * <tr> * <td>{@link #setConfigurationPath(String) setConfigurationPath(String)}</td> * <td>{@link #DFLT_JUNIT_CONFIG DFLT_JUNIT_CONFIG}</td> * <td> * Optional path to GridGain Spring XML configuration file for running JUnit tests. This * property can be overridden by setting {@link GridTestVmParameters#GRIDGAIN_CONFIG} VM * parameter. Note that the value can be either absolute value or relative to * ${GRIDGAIN_HOME} installation folder. * </td> * </tr> * <tr> * <td>{@link #setRouterClassName(String) setRouterClassName(String)}</td> * <td>{@link #DFLT_JUNIT_ROUTER DFLT_JUNIT_ROUTER}</td> * <td> * Optional name of test router class that implements {@link GridTestRouter} interface. * If not provided, then tests will be routed in round-robin fashion using default * {@link GridTestRouterAdapter}. The value of this parameter can be overridden by setting * {@link GridTestVmParameters#GRIDGAIN_TEST_ROUTER} VM parameter to the name of your * own customer router class. * </td> * </tr> * <tr> * <td>{@link #setRouterClass(Class) setRouterClass(Class)}</td> * <td>{@code null}</td> * <td> * Same as {@link #setRouterClassName(String) setRouterClassName(String)}, but sets the * actual class instead of the name. * </td> * </tr> * <tr> * <td>{@link #setTimeout(long) setTimeout(long)}</td> * <td>{@code 0} which means that tests will never timeout.</td> * <td> * Maximum timeout value in milliseconds after which test suite will return without * waiting for the remaining tests to complete. This value can be overridden by setting * {@link GridTestVmParameters#GRIDGAIN_TEST_TIMEOUT} VM parameter to the timeout value * for the tests. * </td> * </tr> * </table> * * @author 2005-2011 Copyright (C) GridGain Systems, Inc. * @version 3.1.1c.19062011 */ public class GridJunit3TestSuite extends TestSuite { /** * Default GridGain configuration file for JUnits (value is {@code * config/junit/junit-spring.xml}). */ public static final String DFLT_JUNIT_CONFIG = "config/junit/junit-spring.xml"; /** * Default JUnit test router (value is {@link GridTestRouterAdapter * GridTestRouterAdapter.class.getName()}). */ public static final String DFLT_JUNIT_ROUTER = GridTestRouterAdapter.class.getName(); /** */ private final Collection<String> locTests = new HashSet<String>(); /** JUnit3 JavaAssist proxy. */ private final GridJunit3ProxyFactory factory = new GridJunit3ProxyFactory(); /** Flag indicating whether grid was started in this suite. */ private boolean selfStarted; /** Junit3 Spring configuration path. */ private String cfgPath = System.getProperty(GRIDGAIN_CONFIG.name()) == null ? DFLT_JUNIT_CONFIG : System.getProperty(GRIDGAIN_CONFIG.name()); /** * Check if GridGain is disabled by checking {@link GridTestVmParameters#GRIDGAIN_DISABLED} system * property. */ private boolean isDisabled = Boolean.getBoolean(GRIDGAIN_DISABLED.name()); /** JUnit test router class name. */ private String routerClsName = System.getProperty(GRIDGAIN_TEST_ROUTER.name()) == null ? DFLT_JUNIT_ROUTER : System.getProperty(GRIDGAIN_TEST_ROUTER.name()); /** JUnit test router class. */ private Class<? extends GridTestRouter> routerCls; /** * Local suite in case if grid is disabled or if this is a nested suite within other distributed * suite. */ private TestSuite copy; /** JUnit grid name. */ private String gridName; /** Test timeout. */ private long timeout = Long.getLong(GRIDGAIN_TEST_TIMEOUT.name()) == null ? 0 : Long.getLong(GRIDGAIN_TEST_TIMEOUT.name()); /** */ private ClassLoader clsLdr; /** Empty test suite. */ public GridJunit3TestSuite() { if (copy == null) { copy = new TestSuite(); } } /** @param name Test suite name. */ public GridJunit3TestSuite(String name) { super(name); if (copy == null) { copy = new TestSuite(name); } } /** * Test suite for one class. * * @param cls Class for test suite. */ public GridJunit3TestSuite(Class<? extends TestCase> cls) { super(cls); if (copy == null) { copy = new TestSuite(cls); } } /** * Test suite for a given test class with specified test name. * * @param cls Test class. * @param name Test name. */ public GridJunit3TestSuite(Class<? extends TestCase> cls, String name) { super(cls, name); if (copy == null) { copy = new TestSuite(cls, name); } } /** * Copies non-distributed test suite into distributed one. * * @param suite Test suite to copy. */ public GridJunit3TestSuite(TestSuite suite) { super(suite.getName()); if (copy == null) { copy = new TestSuite(suite.getName()); } for (int i = 0; i < suite.testCount(); i++) { addTest(suite.testAt(i)); } } /** * Empty test suite with given class loader. * * @param clsLdr Tests class loader. */ public GridJunit3TestSuite(ClassLoader clsLdr) { this(); assert clsLdr != null; this.clsLdr = clsLdr; } /** * @param name Test suite name. * @param clsLdr Tests class loader. */ public GridJunit3TestSuite(String name, ClassLoader clsLdr) { this(name); assert clsLdr != null; this.clsLdr = clsLdr; } /** * Test suite for one class. * * @param cls Class for test suite. * @param clsLdr Tests class loader. */ public GridJunit3TestSuite(Class<? extends TestCase> cls, ClassLoader clsLdr) { this(cls); assert clsLdr != null; this.clsLdr = clsLdr; } /** * Test suite for a given test class with specified test name. * * @param cls Test class. * @param name Test name. * @param clsLdr Tests class loader. */ public GridJunit3TestSuite(Class<? extends TestCase> cls, String name, ClassLoader clsLdr) { this(cls, name); assert clsLdr != null; this.clsLdr = clsLdr; } /** * Copies non-distributed test suite into distributed one. * * @param suite Test suite to copy. * @param clsLdr Tests class loader. */ public GridJunit3TestSuite(TestSuite suite, ClassLoader clsLdr) { this(suite); assert clsLdr != null; this.clsLdr = clsLdr; } /** * Sets path to GridGain configuration file. By default {@code * {GRIDGAIN_HOME}/config/junit/junit-spring.xml} is used. * * @param cfgPath Path to GridGain configuration file. */ public void setConfigurationPath(String cfgPath) { this.cfgPath = cfgPath; } /** * Gets path to GridGain configuration file. By default {@code * {GRIDGAIN_HOME}/config/junit/junit-spring.xml} is used. * * @return Path to GridGain configuration file. */ public String getConfigurationPath() { return cfgPath; } /** * Disables GridGain. If set to {@code true} then this suite will execute locally as if GridGain * was not in a picture at all. * * @param disabled If set to {@code true} then this suite will execute locally as if GridGain was * not in a picture at all. */ public void setDisabled(boolean disabled) { isDisabled = disabled; } /** * Gets flag indicating whether GridGain should be enabled or not. If set to {@code true} then * this suite will execute locally as if GridGain was not in a picture at all. * * @return Flag indicating whether GridGain should be enabled or not. If set to {@code true} then * this suite will execute locally as if GridGain was not in a picture at all. */ public boolean isDisabled() { return isDisabled; } /** * Sets name of class for routing JUnit tests. By default {@link #DFLT_JUNIT_ROUTER} class name is * used. * * @param routerClsName Junit test router class name. */ public void setRouterClassName(String routerClsName) { this.routerClsName = routerClsName; } /** * Gets JUnit test router class name. * * @return JUnit test router class name. */ public String getRouterClassName() { return routerClsName; } /** * Sets router class. By default {@link GridTestRouterAdapter} is used. * * @param routerCls Router class to use for test routing. */ public void setRouterClass(Class<? extends GridTestRouter> routerCls) { this.routerCls = routerCls; } /** * Gets router class used for test routing. * * @return Router class used for test routing. */ public Class<? extends GridTestRouter> getRouterClass() { return routerCls; } /** * Gets identical suite for local (non-distributed) execution. * * @return Local suite. */ public TestSuite getLocalCopy() { return copy; } /** {@inheritDoc} */ @Override public void setName(String name) { if (copy != null) { copy.setName(name); } super.setName(name); } /** * Gets timeout for running distributed test suite. * * @return Timeout for tests. */ public long getTimeout() { return timeout; } /** * Sets timeout for running distributed test suite. By default, test execution does not expire. * * @param timeout Timeout for tests. */ public void setTimeout(long timeout) { this.timeout = timeout; } /** {@inheritDoc} */ @Override public Test testAt(int index) { return isDisabled ? copy.testAt(index) : super.testAt(index); } /** {@inheritDoc} */ @Override public int testCount() { return isDisabled ? copy.testCount() : super.testCount(); } /** {@inheritDoc} */ @Override public Enumeration<Test> tests() { return isDisabled ? copy.tests() : super.tests(); } /** * The added suite will be always executed locally, but in parallel with other locally or remotely * running tests. This comes handy for tests that cannot be distributed for some environmental * reasons, but still would benefit from parallel execution. * * <p>Note, that local suites will be executed on local node even if grid topology only allows * remote nodes. * * @param localSuite Test to execute locally in parallel with other local or distributed tests. */ @SuppressWarnings({"TypeMayBeWeakened"}) public void addTest(GridJunit3LocalTestSuite localSuite) { if (!locTests.contains(localSuite.getName())) { locTests.add(localSuite.getName()); } addTest((Test) localSuite); } /** * Adds a test to be executed on the grid. In case of test suite, all tests inside of test suite * will be executed sequentially on some remote node. * * @param test Test to add. */ @Override public void addTest(Test test) { if (copy == null) { copy = new TestSuite(getName()); } // Add test to the list of local ones. if (test instanceof GridJunit3LocalTestSuite) { String testName = ((TestSuite) test).getName(); if (!locTests.contains(testName)) { locTests.add(testName); } } if (test instanceof GridJunit3TestSuite) { copy.addTest(((GridJunit3TestSuite) test).copy); super.addTest(new GridJunit3TestSuiteProxy(((GridJunit3TestSuite) test).copy, factory)); } else if (test instanceof GridJunit3TestSuiteProxy) { copy.addTest(((GridJunit3TestSuiteProxy) test).getOriginal()); super.addTest(test); } else if (test instanceof GridJunit3TestCaseProxy) { copy.addTest(((GridJunit3TestCaseProxy) test).getGridGainJunit3OriginalTestCase()); super.addTest(test); } else if (test instanceof TestSuite) { copy.addTest(test); super.addTest(new GridJunit3TestSuiteProxy((TestSuite) test, factory)); } else { assert test instanceof TestCase : "Test must be either instance of TestSuite or TestCase: " + test; copy.addTest(test); super.addTest(factory.createProxy((TestCase) test)); } } /** * Creates JUnit test router. Note that router must have a no-arg constructor. * * @return JUnit router instance. */ @SuppressWarnings({"unchecked"}) private GridTestRouter createRouter() { try { if (routerCls == null) { routerCls = (Class<? extends GridTestRouter>) Class.forName(routerClsName); } else { routerClsName = routerCls.getName(); } return routerCls.newInstance(); } catch (ClassNotFoundException e) { throw new GridRuntimeException("Failed to initialize JUnit router: " + routerClsName, e); } catch (IllegalAccessException e) { throw new GridRuntimeException("Failed to initialize JUnit router: " + routerClsName, e); } catch (InstantiationException e) { throw new GridRuntimeException("Failed to initialize JUnit router: " + routerClsName, e); } } /** * Runs all tests belonging to this test suite on the grid. * * @param result Test result collector. */ @Override public void run(TestResult result) { if (isDisabled) { copy.run(result); } else { GridTestRouter router = createRouter(); Grid grid = startGrid(); try { List<GridTaskFuture<?>> futs = new ArrayList<GridTaskFuture<?>>(testCount()); List<GridJunit3SerializableTest> tests = new ArrayList<GridJunit3SerializableTest>(testCount()); for (int i = 0; i < testCount(); i++) { Test junit = testAt(i); GridJunit3SerializableTest test; if (junit instanceof TestSuite) { test = new GridJunit3SerializableTestSuite((TestSuite) junit); } else { assert junit instanceof TestCase : "Test must be either TestSuite or TestCase: " + junit; test = new GridJunit3SerializableTestCase((TestCase) junit); } tests.add(test); if (clsLdr == null) { clsLdr = U.detectClassLoader(junit.getClass()); } futs.add( grid.execute( new GridJunit3Task(junit.getClass(), clsLdr), new GridJunit3Argument(router, test, locTests.contains(test.getName())), timeout)); } for (int i = 0; i < testCount(); i++) { GridTaskFuture<?> fut = futs.get(i); GridJunit3SerializableTest origTest = tests.get(i); try { GridJunit3SerializableTest resTest = (GridJunit3SerializableTest) fut.get(); origTest.setResult(resTest); origTest.getTest().run(result); } catch (GridException e) { handleFail(result, origTest, e); } } } finally { stopGrid(); } } } /** * Handles test fail. * * @param result Test result. * @param origTest Original JUnit test. * @param e Exception thrown from grid. */ private void handleFail(TestResult result, GridJunit3SerializableTest origTest, Throwable e) { // Simulate that all tests were run. origTest.getTest().run(result); // For the tests suite we assume that all tests failed because // entire test suite execution failed and there is no way to get // broken tests. if (origTest.getTest() instanceof GridJunit3TestSuiteProxy) { TestSuite suite = (((TestSuite) origTest.getTest())); for (int j = 0; j < suite.testCount(); j++) { result.addError(suite.testAt(j), e); } } else if (origTest.getTest() instanceof GridJunit3TestCaseProxy) { result.addError(origTest.getTest(), e); } } /** * Starts Grid instance. Note that if grid is already started, then it will be looked up and * returned from this method. * * @return Started grid. */ private Grid startGrid() { Properties props = System.getProperties(); gridName = props.getProperty(GRIDGAIN_NAME.name()); if (!props.containsKey(GRIDGAIN_NAME.name()) || G.state(gridName) != GridFactoryState.STARTED) { selfStarted = true; // Set class loader for the spring. ClassLoader curCl = Thread.currentThread().getContextClassLoader(); // Add no-op logger to remove no-appender warning. Appender app = new NullAppender(); Logger.getRootLogger().addAppender(app); try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); Grid grid = G.start(cfgPath); gridName = grid.name(); System.setProperty(GRIDGAIN_NAME.name(), grid.name()); return grid; } catch (GridException e) { throw new GridRuntimeException("Failed to start grid: " + cfgPath, e); } finally { Logger.getRootLogger().removeAppender(app); Thread.currentThread().setContextClassLoader(curCl); } } return G.grid(gridName); } /** Stops grid only if it was started by this test suite. */ private void stopGrid() { // Only stop grid if it was started here. if (selfStarted) { G.stop(gridName, true); } } }