public static final void loadLevelTree(int resource, Context context) { if (mLoaded) return; XmlResourceParser parser = context.getResources().getXml(resource); levels.clear(); Level currentLevel = null; try { int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { if (parser.getName().equals("level")) { String titleString = null; Long index = null; for (int i = 0; i < parser.getAttributeCount(); i++) { if (parser.getAttributeName(i).equals("index")) { index = Long.getLong(parser.getAttributeValue(i)); } if (parser.getAttributeName(i).equals("title")) { titleString = parser.getAttributeValue(i); } } currentLevel = new Level(index, titleString); levels.add(currentLevel); } if (parser.getName().equals("enemy") && currentLevel != null) { Integer type = null; Integer quantity = null; Long spawnDelay = null; Long minInterval = null; for (int i = 0; i < parser.getAttributeCount(); i++) { if (parser.getAttributeName(i).equals("type")) { type = Integer.getInteger(parser.getAttributeValue(i)); } if (parser.getAttributeName(i).equals("quantity")) { quantity = Integer.getInteger(parser.getAttributeValue(i)); } if (parser.getAttributeName(i).equals("spawnDelay")) { spawnDelay = Long.getLong(parser.getAttributeValue(i)); } if (parser.getAttributeName(i).equals("minInterval")) { minInterval = Long.getLong(parser.getAttributeValue(i)); } } EnemyEntry enemyEntry = new EnemyEntry(type, quantity, spawnDelay, minInterval); currentLevel.enemyEntries.add(enemyEntry); } } eventType = parser.next(); } } catch (Exception e) { DebugLog.e("LevelTree", e.getStackTrace().toString()); } finally { parser.close(); } mLoaded = true; }
@Override public Object createEntry(String data) { ContentValues values = new ContentValues(); int endTitle = data.indexOf(";"); int endUser = data.indexOf(";", endTitle + 1); int endStartTime = data.indexOf(";", endUser + 1); int endEndTime = data.indexOf(";", endStartTime + 1); int endDescription = data.indexOf(";", endEndTime + 1); String title = data.substring(0, endTitle); String user = data.substring(endTitle + 1, endUser); Long starttime = Long.getLong(data.substring(endUser + 1, endStartTime)); Long endtime = Long.getLong(data.substring(endStartTime + 1, endEndTime)); String description = (data.substring(endEndTime + 1, endDescription)); String profilePicURI = (data.substring(endDescription + 1, data.length())); // TODO start and endtime check starttime = System.currentTimeMillis(); endtime = System.currentTimeMillis(); if (";".equals(profilePicURI)) profilePicURI = ""; values.put(MySQLiteHelper.COLUMN_TIMESTAMP, System.currentTimeMillis()); values.put(MySQLiteHelper.COLUMN_TITLE, title); values.put(MySQLiteHelper.COLUMN_USERNAME, user); values.put(MySQLiteHelper.COLUMN_STARTTIME, starttime); values.put(MySQLiteHelper.COLUMN_ENDTIME, endtime); values.put(MySQLiteHelper.COLUMN_DESCRIPTION, description); values.put(MySQLiteHelper.COLUMN_PICPROFILEURI, profilePicURI); long insertId = database.insert(MySQLiteHelper.TABLE_EVENTS, null, values); String[] allColumnNames = dbHelper.getAllColumnNames(MySQLiteHelper.TABLE_EVENTS); Cursor cursor = database.query( MySQLiteHelper.TABLE_EVENTS, allColumnNames, MySQLiteHelper.COLUMN_ID + " = " + insertId, null, null, null, null); Event event = null; if (cursor.moveToFirst()) event = cursorToEvent(cursor); cursor.close(); return event; }
/** * Method to configure the factory (and validation layer) from the environment properties, before * any Catalog instance is created */ private void configure() { lenientFields = Boolean.parseBoolean( System.getProperty( "org.apache.oodt.cas.filemgr.catalog.datasource.lenientFields", "false")); if (!lenientFields) { String validationLayerFactoryClass = System.getProperty( "filemgr.validationLayer.factory", "org.apache.oodt.cas.filemgr.validation.DataSourceValidationLayerFactory"); validationLayer = GenericFileManagerObjectFactory.getValidationLayerFromFactory( validationLayerFactoryClass); } fieldIdStr = Boolean.getBoolean("org.apache.oodt.cas.filemgr.catalog.datasource.quoteFields"); pageSize = Integer.getInteger("org.apache.oodt.cas.filemgr.catalog.datasource.pageSize", VAL); cacheUpdateMinutes = Long.getLong("org.apache.oodt.cas.filemgr.catalog.datasource.cacheUpdateMinutes", VAL1); productIdString = Boolean.parseBoolean( System.getProperty( "org.apache.oodt.cas.filemgr.catalog.datasource.productId.string", "false")); orderedValues = Boolean.parseBoolean( System.getProperty("org.apache.oodt.cas.filemgr.catalog.datasource.orderedValues")); }
@Override public long getItemId(int position) { try { return Long.getLong(reviewItems.get(position).getId()); } catch (Exception e) { return 0; } // return 0; }
/** * This class is a "stoppable" cover for {@link CountDownLatch}. * * @author jpenney */ public class StoppableCountDownLatch { /** This is how often waiters will wake up to check for cancellation */ static final long RETRY_TIME = Long.getLong("gemfire.stoppable-retry-interval", 2000).longValue(); /** The underlying latch */ private final CountDownLatch latch; /** The cancellation criterion */ private final CancelCriterion stopper; /** * @param count the number of times {@link #countDown} must be invoked before threads can pass * through {@link #await()} * @throws IllegalArgumentException if {@code count} is negative */ public StoppableCountDownLatch(CancelCriterion stopper, int count) { Assert.assertTrue(stopper != null); this.latch = new CountDownLatch(count); this.stopper = stopper; } /** @throws InterruptedException */ public void await() throws InterruptedException { for (; ; ) { stopper.checkCancelInProgress(null); if (latch.await(RETRY_TIME, TimeUnit.MILLISECONDS)) { break; } } } /** * @param msTimeout how long to wait in milliseconds * @return true if it was unlatched * @throws InterruptedException */ public boolean await(long msTimeout) throws InterruptedException { stopper.checkCancelInProgress(null); return latch.await(msTimeout, TimeUnit.MILLISECONDS); } public synchronized void countDown() { latch.countDown(); } /** @return the current count */ public long getCount() { return latch.getCount(); } /** @return a string identifying this latch, as well as its state */ @Override public String toString() { return "(Stoppable) " + latch.toString(); } }
/** * Default convenience implementation of {@link RetentionStrategy} for slaves provisioned from * {@link Cloud}. * * <p>If a slave is idle for 10 mins, this retention strategy will remove the slave. This can be * used as-is for a {@link Node} provisioned by cloud to implement the auto-scaling semantics, it * can be subtyped to tweak the behavior, or it can be used as an example. * * <p>TODO {@link CloudRetentionStrategy} seems to be a better implementation. * * @author Kohsuke Kawaguchi * @since 1.510 */ public class CloudSlaveRetentionStrategy<T extends Computer> extends RetentionStrategy<T> { @Override @GuardedBy("hudson.model.Queue.lock") public long check(T c) { if (!c.isConnecting() && c.isAcceptingTasks()) { if (isIdleForTooLong(c)) { try { Node n = c.getNode(); if (n != null) // rare, but n==null if the node is deleted and being checked roughly at the // same time kill(n); } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to remove " + c.getDisplayName(), e); } } } return checkCycle(); } /** * Remove the node. * * <p>To actually deallocate the resource tied to this {@link Node}, implement {@link * Computer#onRemoved()}. */ protected void kill(Node n) throws IOException { Jenkins.getInstance().removeNode(n); } /** When do we check again next time? */ protected long checkCycle() { return getIdleMaxTime() / 10; } /** Has this computer been idle for too long? */ protected boolean isIdleForTooLong(T c) { return System.currentTimeMillis() - c.getIdleStartMilliseconds() > getIdleMaxTime(); } /** If the computer has been idle longer than this time, we'll kill the slave. */ protected long getIdleMaxTime() { return TIMEOUT; } // for debugging, it's convenient to be able to reduce this time public static long TIMEOUT = Long.getLong( CloudSlaveRetentionStrategy.class.getName() + ".timeout", TimeUnit2.MINUTES.toMillis(10)); private static final Logger LOGGER = Logger.getLogger(CloudSlaveRetentionStrategy.class.getName()); }
public KubernetesIaas(IaasProvider iaasProvider) { super(iaasProvider); partitionValidator = new KubernetesPartitionValidator(); payload = new ArrayList<NameValuePair>(); podActivationTimeout = Long.getLong("stratos.pod.activation.timeout"); if (podActivationTimeout == null) { podActivationTimeout = DEFAULT_POD_ACTIVATION_TIMEOUT; if (log.isInfoEnabled()) { log.info("Pod activation timeout was set: " + podActivationTimeout); } } }
private void runTerminalChangeTask(Map<String, Object> map) { // 5.2調用存儲過程,進行數據統計 logger.info("Exec proc_terminalChangeTask use param:{}", map); try { manager = new TerminalChangeTaskManagerImpl(); manager.update("proc_terminalChangeTask", map); } catch (SQLException e) { logger.error( "{}\n MASSAGE : {} \n CAUSE :{} \n CLASS : {}\n", new Object[] {"執行終端升級任務定制功能--存儲過程时,报错:", e.getMessage(), e.getCause(), e.getClass()}); updateTaskStatus(Long.getLong(String.valueOf(map.get("nmTerminalChangeIdTaskId"))), 5); manager = null; System.exit(1); } finally { manager = null; } }
public static Long getListeningPort(Context context) { String listeningPort = LocalPreferences.getString( context, LocalPreferences.PREF_PORT, LocalPreferences.PREF_PORT_DEFAULT); Long port = null; try { port = Long.getLong(listeningPort, 2222); } catch (NumberFormatException e) { port = 2222L; } if (port < LocalPreferences.PORT_MIN || port > LocalPreferences.PORT_MAX) { port = 2222L; } return port; }
/** @throws AuthenticationException */ @SuppressWarnings("unused") @Override public void authenticate() throws AuthenticationException { Usuario user; Map<Integer, Integer> recursosOperacoes = new HashMap<Integer, Integer>(); try { user = usuarioDAO.findById(Long.getLong(identity.getId())); if (user != null) { List<UsuarioRecurso> recursosUsuario = usuarioRecursoDAO.findByUsuario(user.getId()); if (recursosUsuario != null) { Iterator<UsuarioRecurso> it = recursosUsuario.iterator(); while (it.hasNext()) { UsuarioRecurso usuarioRecurso = it.next(); recursosOperacoes.put( usuarioRecurso.getUsuarioRecursosPK().getRecursos(), usuarioRecurso.getOperacao()); } } else { throw new AuthenticationException( rb.getString("login.usuario.nao.existe"), new Exception()); } } else { throw new AuthenticationException( rb.getString("login.usuario.nao.existe"), new Exception()); } } catch (Exception ex) { throw new AuthenticationException(rb.getString("login.usuario.nao.existe"), ex); } if (!user.getAminesia().isEmpty() && user.getSenha().equals(user.getAminesia().substring(21, 27))) { throw new AuthenticationException(rb.getString("login.alteracao.por.email")); } this.identity.setAttribute("Nome", user.getNome()); this.identity.setAttribute("Papel", Roles.getRole(user.getPapel()).get(0)); this.identity.setAttribute("Recurso", recursosOperacoes); }
public class RandomPolicyAdapter implements PolicyAdapter { public static final Long ADAPT_SEED = Long.getLong("starnet.adapt.seed", System.nanoTime()); public static Random _numberGenerator = new Random(); RoutingPolicy[] _policies; RoutingPolicy _current; RandomPolicyAdapter(RoutingPolicy[] policies) { _policies = policies; adaptPolicy(); } public RoutingPolicy adaptPolicy() { _current = _policies[_numberGenerator.nextInt(_policies.length)]; return _current; } public RoutingPolicy getCurrentPolicy() { return _current; } }
/** * Convenience - getLocalHome().findByTransportOrderIdAndSortNumberGT(id, sortNumber) with * exception mapping. */ public static java.util.Collection findByTransportOrderIdAndSortNumberGT(long id, long sortNumber) throws net.metaship.generic.LocalException { if ("findByPrimaryKey".equals("findByTransportOrderIdAndSortNumberGT")) { java.util.Collection r = null; int maxRetry = Integer.getInteger("ims.orderload.retry", 10); long delay = Long.getLong("ims.orderload.delayms", 100); String logCode = "findByTransportOrderIdAndSortNumberGT(id, sortNumber)-" + System.currentTimeMillis(); for (int i = 1; i <= maxRetry; i++) { try { r = getLocalHome().findByTransportOrderIdAndSortNumberGT(id, sortNumber); if (i > 1) { log.warn(logCode + " loading succeeded on attempt #" + i); } return r; } catch (javax.ejb.FinderException fx) { if (i >= maxRetry) { log.error(logCode + " loading failed after " + i + " attempts!"); throw new net.metaship.generic.LocalException(fx); } try { Thread.sleep(delay); } catch (InterruptedException ie) { } } catch (javax.naming.NamingException nx) { throw new net.metaship.generic.LocalException(nx); } } } try { return getLocalHome().findByTransportOrderIdAndSortNumberGT(id, sortNumber); } catch (javax.naming.NamingException nx) { throw new net.metaship.generic.LocalException(nx); } catch (javax.ejb.FinderException fx) { throw new net.metaship.generic.LocalException(fx); } }
/** Convenience - getLocalHome().findByPrimaryKey(pk) with exception mapping. */ public static net.metaship.intermodal.depot.ejb.ServiceAreaLocal findByPrimaryKey( net.metaship.intermodal.depot.ejb.ServiceAreaPK pk) throws net.metaship.generic.LocalException { if ("findByPrimaryKey".equals("findByPrimaryKey")) { net.metaship.intermodal.depot.ejb.ServiceAreaLocal r = null; int maxRetry = Integer.getInteger("ims.orderload.retry", 10); long delay = Long.getLong("ims.orderload.delayms", 100); String logCode = "findByPrimaryKey(pk)-" + System.currentTimeMillis(); for (int i = 1; i <= maxRetry; i++) { try { r = getLocalHome().findByPrimaryKey(pk); if (i > 1) { log.warn(logCode + " loading succeeded on attempt #" + i); } return r; } catch (javax.ejb.FinderException fx) { if (i >= maxRetry) { log.error(logCode + " loading failed after " + i + " attempts!"); throw new net.metaship.generic.LocalException(fx); } try { Thread.sleep(delay); } catch (InterruptedException ie) { } } catch (javax.naming.NamingException nx) { throw new net.metaship.generic.LocalException(nx); } } } try { return getLocalHome().findByPrimaryKey(pk); } catch (javax.naming.NamingException nx) { throw new net.metaship.generic.LocalException(nx); } catch (javax.ejb.FinderException fx) { throw new net.metaship.generic.LocalException(fx); } }
/** 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()); } }
/** * Determines the <code>Long</code> value of the system property whose name was specified in the * constructor. * * <p>If there is no property of the specified name, or if the property does not have the correct * numeric format, then a <code>Long</code> object representing the default value that was * specified in the constructor is returned, or <code>null</code> if no default value was * specified. * * @return the <code>Long</code> value of the property. */ public Long run() { Long value = Long.getLong(theProp); if ((value == null) && defaultSet) return new Long(defaultVal); return value; }
/** * A helper thread which does some computation in the background and displays incremental results * using JavaScript. This is appropriate when the computation may be slow—too slow to do * synchronously within the initial HTTP request—and has no side effects (since it may be canceled * if the user simply browses to another page while it is running). * * <ol> * <li>Write a {@code <script>} section defining {@code function display(data)}. (Call {@code * ts_refresh($('someid'))} if using a {@code sortable} table.) * <li>Use {@code <l:progressiveRendering handler="${it.something()}" callback="display"/>} from * your Jelly page to display a progress bar and initialize JavaScript infrastructure. (The * callback attribute can take arbitrary JavaScript expression to be evaluated in the browser * so long as it produces a function object.) * <li>Implement {@code something()} to create an instance of your subclass of {@code * ProgressiveRendering}. * <li>Perform your work in {@link #compute}. * <li>Periodically check {@link #canceled}. * <li>As results become available, call {@link #progress}. * <li>Make {@link #data} produce whatever JSON you want to send to the page to be displayed. * </ol> * * {@code ui-samples-plugin} demonstrates all this. * * @since 1.484 */ public abstract class ProgressiveRendering { private static final Logger LOG = Logger.getLogger(ProgressiveRendering.class.getName()); /** * May be set to a number of milliseconds to sleep in {@link #canceled}, useful for watching what * are normally fast computations. */ private static final Long DEBUG_SLEEP = Long.getLong("jenkins.util.ProgressiveRendering.DEBUG_SLEEP"); private static final int CANCELED = -1; private static final int ERROR = -2; private double status = 0; private long lastNewsTime; /** just for logging */ private final String uri; private long start; /** Constructor for subclasses. */ protected ProgressiveRendering() { StaplerRequest currentRequest = Stapler.getCurrentRequest(); uri = currentRequest != null ? currentRequest.getRequestURI() : "?"; } /** For internal use. */ @SuppressWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE") public final void start() { final SecurityContext securityContext = SecurityContextHolder.getContext(); executorService() .submit( new Runnable() { public void run() { lastNewsTime = start = System.currentTimeMillis(); SecurityContext orig = SecurityContextHolder.getContext(); try { SecurityContextHolder.setContext(securityContext); compute(); if (status != CANCELED && status != ERROR) { status = 1; } } catch (Exception x) { LOG.log(Level.WARNING, "failed to compute " + uri, x); status = ERROR; } finally { SecurityContextHolder.setContext(orig); LOG.log( Level.FINE, "{0} finished in {1}msec with status {2}", new Object[] {uri, System.currentTimeMillis() - start, status}); } } }); } /** * Actually do the work. * * <p>The security context will be that in effect when the web request was made. * * @throws Exception whenever you like; the progress bar will indicate that an error occurred but * details go to the log only */ protected abstract void compute() throws Exception; /** * Provide current data to the web page for display. * * <p>While this could be an aggregate of everything that has been computed so far, more likely * you want to supply only that data that is new since the last call (maybe just {@code {}} or * {@code []}), so that the page can incrementally update bits of HTML rather than refreshing * everything. * * <p>You may want to make your implementation {@code synchronized}, so that it can track what was * sent on a previous call, in which case any code running in {@link #compute} which modifies * these fields should also <em>temporarily</em> be synchronized on the same monitor such as * {@code this}. * * @return any JSON data you like */ protected abstract @Nonnull JSON data(); /** * Indicate what portion of the work has been done. (Once {@link #compute} returns, the work is * assumed to be complete regardless of this method.) * * @param completedFraction estimated portion of work now done, from 0 (~ 0%) to 1 (~ 100%) */ protected final void progress(double completedFraction) { if (completedFraction < 0 || completedFraction > 1) { throw new IllegalArgumentException(completedFraction + " should be in [0,1]"); } status = completedFraction; } /** * Checks whether the task has been canceled. If the rendering page fails to send a heartbeat * within a certain amount of time, the user is assumed to have moved on. Therefore {@link * #compute} should periodically say: {@code if (canceled()) return;} * * @return true if user seems to have abandoned us, false if we should still run */ protected final boolean canceled() { if (DEBUG_SLEEP != null) { try { Thread.sleep(DEBUG_SLEEP); } catch (InterruptedException x) { } } if (status == ERROR) { return true; // recent call to data() failed } long now = System.currentTimeMillis(); long elapsed = now - lastNewsTime; if (elapsed > timeout()) { status = CANCELED; LOG.log( Level.FINE, "{0} canceled due to {1}msec inactivity after {2}msec", new Object[] {uri, elapsed, now - start}); return true; } else { return false; } } /** For internal use. */ @JavaScriptMethod public final JSONObject news() { lastNewsTime = System.currentTimeMillis(); JSONObject r = new JSONObject(); try { r.put("data", data()); } catch (RuntimeException x) { LOG.log(Level.WARNING, "failed to update " + uri, x); status = ERROR; } r.put( "status", status == 1 ? "done" : status == CANCELED ? "canceled" : status == ERROR ? "error" : status); lastNewsTime = System.currentTimeMillis(); LOG.log(Level.FINER, "news from {0}", uri); return r; } /** * May be overridden to provide an alternate executor service. * * @return by default, {@link Timer#get} */ protected ExecutorService executorService() { return Timer.get(); } /** * May be overridden to control the inactivity timeout. If no request from the browser is received * within this time, the next call to {@link #canceled} will be true. * * @return timeout in milliseconds; by default, 15000 (~ 15 seconds) */ protected long timeout() { return 15000; } }
/** Implementation of AsyncContext interface that holds the state of request-response cycle. */ public class HttpChannelState { private static final Logger LOG = Log.getLogger(HttpChannelState.class); private static final long DEFAULT_TIMEOUT = Long.getLong("org.eclipse.jetty.server.HttpChannelState.DEFAULT_TIMEOUT", 30000L); /** The state of the HttpChannel,used to control the overall lifecycle. */ public enum State { IDLE, // Idle request DISPATCHED, // Request dispatched to filter/servlet THROWN, // Exception thrown while DISPATCHED ASYNC_WAIT, // Suspended and waiting ASYNC_WOKEN, // Dispatch to handle from ASYNC_WAIT ASYNC_IO, // Dispatched for async IO COMPLETING, // Response is completable COMPLETED, // Response is completed UPGRADED // Request upgraded the connection } /** The actions to take as the channel moves from state to state. */ public enum Action { DISPATCH, // handle a normal request dispatch ASYNC_DISPATCH, // handle an async request dispatch ERROR_DISPATCH, // handle a normal error WRITE_CALLBACK, // handle an IO write callback READ_CALLBACK, // handle an IO read callback COMPLETE, // Complete the response TERMINATED, // No further actions WAIT, // Wait for further events } /** The state of the servlet async API. */ public enum Async { STARTED, // AsyncContext.startAsync() has been called DISPATCH, // AsyncContext.dispatch() has been called COMPLETE, // AsyncContext.complete() has been called EXPIRING, // AsyncContext timeout just happened EXPIRED, // AsyncContext timeout has been processed ERRORING, // An error just happened ERRORED // The error has been processed } private final boolean DEBUG = LOG.isDebugEnabled(); private final Locker _locker = new Locker(); private final HttpChannel _channel; private List<AsyncListener> _asyncListeners; private State _state; private Async _async; private boolean _initial; private boolean _asyncReadPossible; private boolean _asyncReadUnready; private boolean _asyncWrite; // TODO refactor same as read private long _timeoutMs = DEFAULT_TIMEOUT; private AsyncContextEvent _event; protected HttpChannelState(HttpChannel channel) { _channel = channel; _state = State.IDLE; _async = null; _initial = true; } public State getState() { try (Locker.Lock lock = _locker.lock()) { return _state; } } public void addListener(AsyncListener listener) { try (Locker.Lock lock = _locker.lock()) { if (_asyncListeners == null) _asyncListeners = new ArrayList<>(); _asyncListeners.add(listener); } } public void setTimeout(long ms) { try (Locker.Lock lock = _locker.lock()) { _timeoutMs = ms; } } public long getTimeout() { try (Locker.Lock lock = _locker.lock()) { return _timeoutMs; } } public AsyncContextEvent getAsyncContextEvent() { try (Locker.Lock lock = _locker.lock()) { return _event; } } @Override public String toString() { try (Locker.Lock lock = _locker.lock()) { return toStringLocked(); } } public String toStringLocked() { return String.format( "%s@%x{s=%s a=%s i=%b r=%s w=%b}", getClass().getSimpleName(), hashCode(), _state, _async, _initial, _asyncReadPossible ? (_asyncReadUnready ? "PU" : "P!U") : (_asyncReadUnready ? "!PU" : "!P!U"), _asyncWrite); } private String getStatusStringLocked() { return String.format("s=%s i=%b a=%s", _state, _initial, _async); } public String getStatusString() { try (Locker.Lock lock = _locker.lock()) { return getStatusStringLocked(); } } /** @return Next handling of the request should proceed */ protected Action handling() { try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("handling {}", toStringLocked()); switch (_state) { case IDLE: _initial = true; _state = State.DISPATCHED; return Action.DISPATCH; case COMPLETING: return Action.COMPLETE; case COMPLETED: return Action.TERMINATED; case ASYNC_WOKEN: if (_asyncReadPossible) { _state = State.ASYNC_IO; _asyncReadUnready = false; return Action.READ_CALLBACK; } if (_asyncWrite) { _state = State.ASYNC_IO; _asyncWrite = false; return Action.WRITE_CALLBACK; } if (_async != null) { Async async = _async; switch (async) { case COMPLETE: _state = State.COMPLETING; return Action.COMPLETE; case DISPATCH: _state = State.DISPATCHED; _async = null; return Action.ASYNC_DISPATCH; case EXPIRED: case ERRORED: _state = State.DISPATCHED; _async = null; return Action.ERROR_DISPATCH; case STARTED: case EXPIRING: case ERRORING: return Action.WAIT; default: throw new IllegalStateException(getStatusStringLocked()); } } return Action.WAIT; case ASYNC_IO: case ASYNC_WAIT: case DISPATCHED: case UPGRADED: default: throw new IllegalStateException(getStatusStringLocked()); } } } public void startAsync(AsyncContextEvent event) { final List<AsyncListener> lastAsyncListeners; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("startAsync {}", toStringLocked()); if (_state != State.DISPATCHED || _async != null) throw new IllegalStateException(this.getStatusStringLocked()); _async = Async.STARTED; _event = event; lastAsyncListeners = _asyncListeners; _asyncListeners = null; } if (lastAsyncListeners != null) { Runnable callback = new Runnable() { @Override public void run() { for (AsyncListener listener : lastAsyncListeners) { try { listener.onStartAsync(event); } catch (Exception e) { // TODO Async Dispatch Error LOG.warn(e); } } } @Override public String toString() { return "startAsync"; } }; runInContext(event, callback); } } /** * Signal that the HttpConnection has finished handling the request. For blocking connectors,this * call may block if the request has been suspended (startAsync called). * * @return next actions be handled again (eg because of a resume that happened before unhandle was * called) */ protected Action unhandle() { Action action; AsyncContextEvent schedule_event = null; boolean read_interested = false; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("unhandle {}", toStringLocked()); switch (_state) { case COMPLETING: case COMPLETED: return Action.TERMINATED; case THROWN: _state = State.DISPATCHED; return Action.ERROR_DISPATCH; case DISPATCHED: case ASYNC_IO: break; default: throw new IllegalStateException(this.getStatusStringLocked()); } if (_async != null) { _initial = false; switch (_async) { case COMPLETE: _state = State.COMPLETING; _async = null; action = Action.COMPLETE; break; case DISPATCH: _state = State.DISPATCHED; _async = null; action = Action.ASYNC_DISPATCH; break; case STARTED: if (_asyncReadUnready && _asyncReadPossible) { _state = State.ASYNC_IO; _asyncReadUnready = false; action = Action.READ_CALLBACK; } else if (_asyncWrite) // TODO refactor same as read { _asyncWrite = false; _state = State.ASYNC_IO; action = Action.WRITE_CALLBACK; } else { schedule_event = _event; read_interested = _asyncReadUnready; _state = State.ASYNC_WAIT; action = Action.WAIT; } break; case EXPIRING: // onTimeout callbacks still being called, so just WAIT _state = State.ASYNC_WAIT; action = Action.WAIT; break; case EXPIRED: // onTimeout handling is complete, but did not dispatch as // we were handling. So do the error dispatch here _state = State.DISPATCHED; _async = null; action = Action.ERROR_DISPATCH; break; case ERRORED: _state = State.DISPATCHED; _async = null; action = Action.ERROR_DISPATCH; break; default: throw new IllegalStateException(this.getStatusStringLocked()); } } else { _state = State.COMPLETING; action = Action.COMPLETE; } } if (schedule_event != null) scheduleTimeout(schedule_event); if (read_interested) _channel.asyncReadFillInterested(); return action; } public void dispatch(ServletContext context, String path) { boolean dispatch = false; AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("dispatch {} -> {}", toStringLocked(), path); boolean started = false; event = _event; switch (_async) { case STARTED: started = true; break; case EXPIRING: case ERRORING: case ERRORED: break; default: throw new IllegalStateException(this.getStatusStringLocked()); } _async = Async.DISPATCH; if (context != null) _event.setDispatchContext(context); if (path != null) _event.setDispatchPath(path); if (started) { switch (_state) { case DISPATCHED: case ASYNC_IO: case ASYNC_WOKEN: break; case ASYNC_WAIT: _state = State.ASYNC_WOKEN; dispatch = true; break; default: LOG.warn("async dispatched when complete {}", this); break; } } } cancelTimeout(event); if (dispatch) scheduleDispatch(); } protected void onTimeout() { final List<AsyncListener> listeners; AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onTimeout {}", toStringLocked()); if (_async != Async.STARTED) return; _async = Async.EXPIRING; event = _event; listeners = _asyncListeners; } final AtomicReference<Throwable> error = new AtomicReference<Throwable>(); if (listeners != null) { Runnable task = new Runnable() { @Override public void run() { for (AsyncListener listener : listeners) { try { listener.onTimeout(event); } catch (Throwable x) { LOG.warn(x + " while invoking onTimeout listener " + listener); LOG.debug(x); if (error.get() == null) error.set(x); else error.get().addSuppressed(x); } } } @Override public String toString() { return "onTimeout"; } }; runInContext(event, task); } Throwable th = error.get(); boolean dispatch = false; try (Locker.Lock lock = _locker.lock()) { switch (_async) { case EXPIRING: _async = th == null ? Async.EXPIRED : Async.ERRORING; break; case COMPLETE: case DISPATCH: if (th != null) { LOG.ignore(th); th = null; } break; default: throw new IllegalStateException(); } if (_state == State.ASYNC_WAIT) { _state = State.ASYNC_WOKEN; dispatch = true; } } if (th != null) { if (LOG.isDebugEnabled()) LOG.debug("Error after async timeout {}", this, th); onError(th); } if (dispatch) { if (LOG.isDebugEnabled()) LOG.debug("Dispatch after async timeout {}", this); scheduleDispatch(); } } public void complete() { // just like resume, except don't set _dispatched=true; boolean handle = false; AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("complete {}", toStringLocked()); boolean started = false; event = _event; switch (_async) { case STARTED: started = true; break; case EXPIRING: case ERRORING: case ERRORED: break; case COMPLETE: return; default: throw new IllegalStateException(this.getStatusStringLocked()); } _async = Async.COMPLETE; if (started && _state == State.ASYNC_WAIT) { handle = true; _state = State.ASYNC_WOKEN; } } cancelTimeout(event); if (handle) runInContext(event, _channel); } public void errorComplete() { try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("error complete {}", toStringLocked()); _async = Async.COMPLETE; _event.setDispatchContext(null); _event.setDispatchPath(null); } cancelTimeout(); } protected void onError(Throwable failure) { final List<AsyncListener> listeners; final AsyncContextEvent event; final Request baseRequest = _channel.getRequest(); int code = HttpStatus.INTERNAL_SERVER_ERROR_500; String reason = null; if (failure instanceof BadMessageException) { BadMessageException bme = (BadMessageException) failure; code = bme.getCode(); reason = bme.getReason(); } else if (failure instanceof UnavailableException) { if (((UnavailableException) failure).isPermanent()) code = HttpStatus.NOT_FOUND_404; else code = HttpStatus.SERVICE_UNAVAILABLE_503; } try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onError {} {}", toStringLocked(), failure); // Set error on request. if (_event != null) { if (_event.getThrowable() != null) throw new IllegalStateException("Error already set", _event.getThrowable()); _event.addThrowable(failure); _event.getSuppliedRequest().setAttribute(ERROR_STATUS_CODE, code); _event.getSuppliedRequest().setAttribute(ERROR_EXCEPTION, failure); _event .getSuppliedRequest() .setAttribute( RequestDispatcher.ERROR_EXCEPTION_TYPE, failure == null ? null : failure.getClass()); _event.getSuppliedRequest().setAttribute(ERROR_MESSAGE, reason != null ? reason : null); } else { Throwable error = (Throwable) baseRequest.getAttribute(ERROR_EXCEPTION); if (error != null) throw new IllegalStateException("Error already set", error); baseRequest.setAttribute(ERROR_STATUS_CODE, code); baseRequest.setAttribute(ERROR_EXCEPTION, failure); baseRequest.setAttribute( RequestDispatcher.ERROR_EXCEPTION_TYPE, failure == null ? null : failure.getClass()); baseRequest.setAttribute(ERROR_MESSAGE, reason != null ? reason : null); } // Are we blocking? if (_async == null) { // Only called from within HttpChannel Handling, so much be dispatched, let's stay // dispatched! if (_state == State.DISPATCHED) { _state = State.THROWN; return; } throw new IllegalStateException(this.getStatusStringLocked()); } // We are Async _async = Async.ERRORING; listeners = _asyncListeners; event = _event; } if (listeners != null) { Runnable task = new Runnable() { @Override public void run() { for (AsyncListener listener : listeners) { try { listener.onError(event); } catch (Throwable x) { LOG.warn(x + " while invoking onError listener " + listener); LOG.debug(x); } } } @Override public String toString() { return "onError"; } }; runInContext(event, task); } boolean dispatch = false; try (Locker.Lock lock = _locker.lock()) { switch (_async) { case ERRORING: { // Still in this state ? The listeners did not invoke API methods // and the container must provide a default error dispatch. _async = Async.ERRORED; break; } case DISPATCH: case COMPLETE: { // The listeners called dispatch() or complete(). break; } default: { throw new IllegalStateException(toString()); } } if (_state == State.ASYNC_WAIT) { _state = State.ASYNC_WOKEN; dispatch = true; } } if (dispatch) { if (LOG.isDebugEnabled()) LOG.debug("Dispatch after error {}", this); scheduleDispatch(); } } protected void onComplete() { final List<AsyncListener> aListeners; final AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onComplete {}", toStringLocked()); switch (_state) { case COMPLETING: aListeners = _asyncListeners; event = _event; _state = State.COMPLETED; _async = null; break; default: throw new IllegalStateException(this.getStatusStringLocked()); } } if (event != null) { if (aListeners != null) { Runnable callback = new Runnable() { @Override public void run() { for (AsyncListener listener : aListeners) { try { listener.onComplete(event); } catch (Exception e) { LOG.warn(e + " while invoking onComplete listener " + listener); LOG.debug(e); } } } @Override public String toString() { return "onComplete"; } }; runInContext(event, callback); } event.completed(); } } protected void recycle() { cancelTimeout(); try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("recycle {}", toStringLocked()); switch (_state) { case DISPATCHED: case ASYNC_IO: throw new IllegalStateException(getStatusStringLocked()); case UPGRADED: return; default: break; } _asyncListeners = null; _state = State.IDLE; _async = null; _initial = true; _asyncReadPossible = _asyncReadUnready = false; _asyncWrite = false; _timeoutMs = DEFAULT_TIMEOUT; _event = null; } } public void upgrade() { cancelTimeout(); try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("upgrade {}", toStringLocked()); switch (_state) { case IDLE: case COMPLETED: break; default: throw new IllegalStateException(getStatusStringLocked()); } _asyncListeners = null; _state = State.UPGRADED; _async = null; _initial = true; _asyncReadPossible = _asyncReadUnready = false; _asyncWrite = false; _timeoutMs = DEFAULT_TIMEOUT; _event = null; } } protected void scheduleDispatch() { _channel.execute(_channel); } protected void scheduleTimeout(AsyncContextEvent event) { Scheduler scheduler = _channel.getScheduler(); if (scheduler != null && _timeoutMs > 0) event.setTimeoutTask(scheduler.schedule(event, _timeoutMs, TimeUnit.MILLISECONDS)); } protected void cancelTimeout() { final AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { event = _event; } cancelTimeout(event); } protected void cancelTimeout(AsyncContextEvent event) { if (event != null) event.cancelTimeoutTask(); } public boolean isIdle() { try (Locker.Lock lock = _locker.lock()) { return _state == State.IDLE; } } public boolean isExpired() { try (Locker.Lock lock = _locker.lock()) { return _async == Async.EXPIRED; } } public boolean isInitial() { try (Locker.Lock lock = _locker.lock()) { return _initial; } } public boolean isSuspended() { try (Locker.Lock lock = _locker.lock()) { return _state == State.ASYNC_WAIT || _state == State.DISPATCHED && _async == Async.STARTED; } } boolean isCompleting() { try (Locker.Lock lock = _locker.lock()) { return _state == State.COMPLETING; } } boolean isCompleted() { try (Locker.Lock lock = _locker.lock()) { return _state == State.COMPLETED; } } public boolean isAsyncStarted() { try (Locker.Lock lock = _locker.lock()) { if (_state == State.DISPATCHED) return _async != null; return _async == Async.STARTED || _async == Async.EXPIRING; } } public boolean isAsync() { try (Locker.Lock lock = _locker.lock()) { return !_initial || _async != null; } } public Request getBaseRequest() { return _channel.getRequest(); } public HttpChannel getHttpChannel() { return _channel; } public ContextHandler getContextHandler() { final AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { event = _event; } return getContextHandler(event); } ContextHandler getContextHandler(AsyncContextEvent event) { if (event != null) { Context context = ((Context) event.getServletContext()); if (context != null) return context.getContextHandler(); } return null; } public ServletResponse getServletResponse() { final AsyncContextEvent event; try (Locker.Lock lock = _locker.lock()) { event = _event; } return getServletResponse(event); } public ServletResponse getServletResponse(AsyncContextEvent event) { if (event != null && event.getSuppliedResponse() != null) return event.getSuppliedResponse(); return _channel.getResponse(); } void runInContext(AsyncContextEvent event, Runnable runnable) { ContextHandler contextHandler = getContextHandler(event); if (contextHandler == null) runnable.run(); else contextHandler.handle(_channel.getRequest(), runnable); } public Object getAttribute(String name) { return _channel.getRequest().getAttribute(name); } public void removeAttribute(String name) { _channel.getRequest().removeAttribute(name); } public void setAttribute(String name, Object attribute) { _channel.getRequest().setAttribute(name, attribute); } /* ------------------------------------------------------------ */ /** * Called to signal async read isReady() has returned false. This indicates that there is no * content available to be consumed and that once the channel enteres the ASYNC_WAIT state it will * register for read interest by calling {@link HttpChannel#asyncReadFillInterested()} either from * this method or from a subsequent call to {@link #unhandle()}. */ public void onReadUnready() { boolean interested = false; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onReadUnready {}", toStringLocked()); // We were already unready, this is not a state change, so do nothing if (!_asyncReadUnready) { _asyncReadUnready = true; _asyncReadPossible = false; // Assumes this has been checked in isReady() with lock held if (_state == State.ASYNC_WAIT) interested = true; } } if (interested) _channel.asyncReadFillInterested(); } /* ------------------------------------------------------------ */ /** * Called to signal that content is now available to read. If the channel is in ASYNC_WAIT state * and unready (ie isReady() has returned false), then the state is changed to ASYNC_WOKEN and * true is returned. * * @return True IFF the channel was unready and in ASYNC_WAIT state */ public boolean onReadPossible() { boolean woken = false; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onReadPossible {}", toStringLocked()); _asyncReadPossible = true; if (_state == State.ASYNC_WAIT && _asyncReadUnready) { woken = true; _state = State.ASYNC_WOKEN; } } return woken; } /* ------------------------------------------------------------ */ /** * Called to signal that the channel is ready for a callback. This is similar to calling {@link * #onReadUnready()} followed by {@link #onReadPossible()}, except that as content is already * available, read interest is never set. * * @return true if woken */ public boolean onReadReady() { boolean woken = false; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onReadReady {}", toStringLocked()); _asyncReadUnready = true; _asyncReadPossible = true; if (_state == State.ASYNC_WAIT) { woken = true; _state = State.ASYNC_WOKEN; } } return woken; } public boolean isReadPossible() { try (Locker.Lock lock = _locker.lock()) { return _asyncReadPossible; } } public boolean onWritePossible() { boolean handle = false; try (Locker.Lock lock = _locker.lock()) { if (DEBUG) LOG.debug("onWritePossible {}", toStringLocked()); _asyncWrite = true; if (_state == State.ASYNC_WAIT) { _state = State.ASYNC_WOKEN; handle = true; } } return handle; } }
@Transactional(readOnly = false) @RequestMapping( value = "/editperson", method = {RequestMethod.POST, RequestMethod.GET}) public void personsEditor( @RequestParam String oper, @RequestParam long ID, Person person, BindingResult result, HttpServletRequest request, HttpServletResponse response) throws IOException { if (result.hasErrors()) { response.sendError(400, result.toString()); return; } switch (oper) { case "add": { Counterparty counterparty = counterpartyRepository.findOne(ID); if (counterparty != null) { counterparty.addPerson(person); String headIDS = request.getParameter("headID_primary_key"); if (headIDS != null && !headIDS.isEmpty()) { try { Long headid = Long.getLong(headIDS); Person headPerson = personRepository.findOne(headid); person.setHead(headPerson); } catch (NumberFormatException e) { // do nothing } } personRepository.save(person); counterpartyRepository.save(counterparty); response.setStatus(200); } else { response.sendError(404, "NO COUNTERPART WITH ID " + ID + " FOUND"); } } break; case "edit": { Person prsn = personRepository.findOne(person.getId()); if (prsn != null && prsn.getVersion() <= person.getVersion()) { prsn.setSurname(person.getSurname()); prsn.setFirstName(person.getFirstName()); prsn.setMiddleName(person.getMiddleName()); prsn.setComments(person.getComments()); prsn.setDate_of_birth(person.getDate_of_birth()); String headIDS = request.getParameter("headID_primary_key"); if (headIDS != null && !headIDS.isEmpty()) { try { Long headid = Long.getLong(headIDS); Person headPerson = personRepository.findOne(headid); person.setHead(headPerson); } catch (NumberFormatException e) { // do nothing } } personRepository.save(prsn); response.setStatus(200); } else { response.sendError(404, "NO Agreement WITH ID " + person.getId() + " FOUND"); } } break; case "del": { Counterparty counterparty = counterpartyRepository.findOne(ID); if (counterparty != null) { Person prsn = personRepository.findOne(person.getId()); if (prsn != null) { counterparty.removePerson(prsn); personRepository.delete(prsn); counterpartyRepository.save(counterparty); response.setStatus(200); } else { response.sendError(404, "NO Agreement WITH ID " + person.getId() + " FOUND"); } } else { response.sendError(404, "NO COUNTERPART WITH ID " + ID + " FOUND"); } } break; default: response.sendError(406, "UNKNOWN OPERATION"); } }
/** * 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); } } }
/** 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()); } }
/** * Holds strong references to a set of remote objects, or live remote references to remote objects, * after they have been marshalled (as remote references) as parts of the arguments or the result of * a remote invocation. The purpose is to prevent remote objects or live remote references that * might otherwise be determined to be unreachable in this VM from being locally garbage collected * before the receiver has had an opportunity to register the unmarshalled remote references for * DGC. * * <p>The references are held strongly until an acknowledgment has been received that the receiver * has had an opportunity to process the remote references or until a timeout has expired. For * remote references sent as parts of the arguments of a remote invocation, the acknowledgment is * the beginning of the response indicating completion of the remote invocation. For remote * references sent as parts of the result of a remote invocation, a UID is included as part of the * result, and the acknowledgment is a transport-level "DGCAck" message containing that UID. * * @author Ann Wollrath * @author Peter Jones */ public class DGCAckHandler { /** timeout for holding references without receiving an acknowledgment */ private static final long dgcAckTimeout = // default 5 minutes AccessController.doPrivileged( (PrivilegedAction<Long>) () -> Long.getLong("sun.rmi.dgc.ackTimeout", 300000)); /** thread pool for scheduling delayed tasks */ private static final ScheduledExecutorService scheduler = AccessController.doPrivileged(new RuntimeUtil.GetInstanceAction()).getScheduler(); /** table mapping ack ID to handler */ private static final Map<UID, DGCAckHandler> idTable = Collections.synchronizedMap(new HashMap<UID, DGCAckHandler>()); private final UID id; private List<Object> objList = new ArrayList<>(); // null if released private Future<?> task = null; /** * Creates a new DGCAckHandler, associated with the specified UID if the argument is not null. * * <p>References added to this DGCAckHandler will be held strongly until its "release" method is * invoked or (after the "startTimer" method has been invoked) the timeout has expired. If the * argument is not null, then invoking the static "received" method with the specified UID is * equivalent to invoking this instance's "release" method. */ DGCAckHandler(UID id) { this.id = id; if (id != null) { assert !idTable.containsKey(id); idTable.put(id, this); } } /** Adds the specified reference to this DGCAckHandler. */ synchronized void add(Object obj) { if (objList != null) { objList.add(obj); } } /** * Starts the timer for this DGCAckHandler. After the timeout has expired, the references are * released even if the acknowledgment has not been received. */ synchronized void startTimer() { if (objList != null && task == null) { task = scheduler.schedule( new Runnable() { public void run() { if (id != null) { idTable.remove(id); } release(); } }, dgcAckTimeout, TimeUnit.MILLISECONDS); } } /** Releases the references held by this DGCAckHandler. */ synchronized void release() { if (task != null) { task.cancel(false); task = null; } objList = null; } /** Causes the DGCAckHandler associated with the specified UID to release its references. */ public static void received(UID id) { DGCAckHandler h = idTable.remove(id); if (h != null) { h.release(); } } }
/** * 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() {} } }
/** * @author Filip Hanik * @version 1.0 */ public class FairnessTest extends DefaultTestCase { public FairnessTest(String name) { super(name); } protected boolean run = true; protected long sleep = Long.getLong("sleep", 10).longValue(); protected long complete = Long.getLong("complete", 20000).longValue(); protected boolean printthread = Boolean.getBoolean("printthread"); CountDownLatch latch = null; protected void printThreadResults(TestThread[] threads, String name, int active, int expected) { long minfetch = Long.MAX_VALUE, maxfetch = Long.MIN_VALUE, totalfetch = 0; long maxwait = 0, minwait = Long.MAX_VALUE, totalwait = 0; for (int i = 0; i < threads.length; i++) { TestThread t = threads[i]; totalfetch += t.nroffetch; totalwait += t.totalwait; maxwait = Math.max(maxwait, t.maxwait); minwait = Math.min(minwait, t.minwait); minfetch = Math.min(minfetch, t.nroffetch); maxfetch = Math.max(maxfetch, t.nroffetch); if (FairnessTest.this.printthread) System.out.println( t.getName() + " : Nr-of-fetch:" + t.nroffetch + " Max fetch Time:" + t.maxwait / 1000000f + "ms. :Max close time:" + t.cmax / 1000000f + "ms."); } System.out.println( "[" + name + "] Max fetch:" + (maxfetch) + " Min fetch:" + (minfetch) + " Average fetch:" + (((float) totalfetch)) / (float) threads.length); System.out.println( "[" + name + "] Max wait:" + maxwait / 1000000f + "ms. Min wait:" + minwait / 1000000f + "ms. Average wait:" + (((((float) totalwait)) / (float) totalfetch) / 1000000f) + " ms."); System.out.println("[" + name + "] Max active:" + active + " Expected Active:" + expected); } public void testDBCPThreads20Connections10() throws Exception { System.out.println("[testDBCPThreads20Connections10] Starting fairness - DBCP"); init(); this.datasource.getPoolProperties().setMaxActive(10); this.threadcount = 20; this.transferProperties(); this.tDatasource.getConnection().close(); latch = new CountDownLatch(threadcount); long start = System.currentTimeMillis(); TestThread[] threads = new TestThread[threadcount]; for (int i = 0; i < threadcount; i++) { threads[i] = new TestThread(); threads[i].setName("tomcat-dbcp-" + i); threads[i].d = this.tDatasource; } for (int i = 0; i < threadcount; i++) { threads[i].start(); } if (!latch.await(complete + 1000, TimeUnit.MILLISECONDS)) { System.out.println("Latch timed out."); } this.run = false; long delta = System.currentTimeMillis() - start; printThreadResults( threads, "testDBCPThreads20Connections10", this.tDatasource.getNumActive(), 10); System.out.println("Test completed in: " + delta + "ms."); tearDown(); } public void testPoolThreads20Connections10() throws Exception { System.out.println( "[testPoolThreads20Connections10] Starting fairness - Tomcat JDBC - Non Fair"); init(); this.datasource.getPoolProperties().setMaxActive(10); this.datasource.getPoolProperties().setFairQueue(false); this.threadcount = 20; this.transferProperties(); this.datasource.getConnection().close(); latch = new CountDownLatch(threadcount); long start = System.currentTimeMillis(); TestThread[] threads = new TestThread[threadcount]; for (int i = 0; i < threadcount; i++) { threads[i] = new TestThread(); threads[i].setName("tomcat-pool-" + i); threads[i].d = this.datasource; } for (int i = 0; i < threadcount; i++) { threads[i].start(); } if (!latch.await(complete + 1000, TimeUnit.MILLISECONDS)) { System.out.println("Latch timed out."); } this.run = false; long delta = System.currentTimeMillis() - start; printThreadResults(threads, "testPoolThreads20Connections10", this.datasource.getSize(), 10); System.out.println("Test completed in: " + delta + "ms."); tearDown(); } public void testPoolThreads20Connections10Fair() throws Exception { System.out.println( "[testPoolThreads20Connections10Fair] Starting fairness - Tomcat JDBC - Fair"); init(); this.datasource.getPoolProperties().setMaxActive(10); this.datasource.getPoolProperties().setFairQueue(true); this.threadcount = 20; this.transferProperties(); this.datasource.getConnection().close(); latch = new CountDownLatch(threadcount); long start = System.currentTimeMillis(); TestThread[] threads = new TestThread[threadcount]; for (int i = 0; i < threadcount; i++) { threads[i] = new TestThread(); threads[i].setName("tomcat-pool-" + i); threads[i].d = this.datasource; } for (int i = 0; i < threadcount; i++) { threads[i].start(); } if (!latch.await(complete + 1000, TimeUnit.MILLISECONDS)) { System.out.println("Latch timed out."); } this.run = false; long delta = System.currentTimeMillis() - start; printThreadResults( threads, "testPoolThreads20Connections10Fair", this.datasource.getSize(), 10); System.out.println("Test completed in: " + delta + "ms."); tearDown(); } public void testPoolThreads20Connections10FairAsync() throws Exception { System.out.println( "[testPoolThreads20Connections10FairAsync] Starting fairness - Tomcat JDBC - Fair - Async"); init(); this.datasource.getPoolProperties().setMaxActive(10); this.datasource.getPoolProperties().setFairQueue(true); this.threadcount = 20; this.transferProperties(); this.datasource.getConnection().close(); latch = new CountDownLatch(threadcount); long start = System.currentTimeMillis(); TestThread[] threads = new TestThread[threadcount]; for (int i = 0; i < threadcount; i++) { threads[i] = new TestThread(); threads[i].setName("tomcat-pool-" + i); threads[i].async = true; threads[i].d = this.datasource; } for (int i = 0; i < threadcount; i++) { threads[i].start(); } if (!latch.await(complete + 1000, TimeUnit.MILLISECONDS)) { System.out.println("Latch timed out."); } this.run = false; long delta = System.currentTimeMillis() - start; printThreadResults( threads, "testPoolThreads20Connections10FairAsync", this.datasource.getSize(), 10); System.out.println("Test completed in: " + delta + "ms."); tearDown(); } // public void testC3P0Threads20Connections10() throws Exception { // System.out.println("[testC3P0Threads20Connections10] Starting fairness - C3P0"); // init(); // this.datasource.getPoolProperties().setMaxActive(10); // this.datasource.getPoolProperties().setFairQueue(false); // this.threadcount = 20; // this.transferPropertiesToC3P0(); // this.datasource.getConnection().close(); // latch = new CountDownLatch(threadcount); // long start = System.currentTimeMillis(); // TestThread[] threads = new TestThread[threadcount]; // for (int i=0; i<threadcount; i++) { // threads[i] = new TestThread(); // threads[i].setName("tomcat-pool-"+i); // threads[i].d = this.c3p0Datasource; // // } // for (int i=0; i<threadcount; i++) { // threads[i].start(); // } // if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) { // System.out.println("Latch timed out."); // } // this.run = false; // long delta = System.currentTimeMillis() - start; // // printThreadResults(threads,"testC3P0Threads20Connections10",c3p0Datasource.getNumConnectionsAllUsers(),10); // tearDown(); // // } public class TestThread extends Thread { protected DataSource d; protected String query = null; protected long sleep = 10; protected boolean async = false; long minwait = Long.MAX_VALUE, maxwait = -1, totalwait = 0, totalcmax = 0, cmax = -1, nroffetch = 0, totalruntime = 0; @Override public void run() { try { long now = System.currentTimeMillis(); while (FairnessTest.this.run) { if ((System.currentTimeMillis() - now) >= FairnessTest.this.complete) break; long start = System.nanoTime(); Connection con = null; try { if (async) { Future<Connection> cf = ((DataSourceProxy) d).getConnectionAsync(); con = cf.get(); } else { con = d.getConnection(); } long delta = System.nanoTime() - start; totalwait += delta; maxwait = Math.max(delta, maxwait); minwait = Math.min(delta, minwait); nroffetch++; if (query != null) { Statement st = con.createStatement(); ResultSet rs = st.executeQuery(query); while (rs.next()) {} rs.close(); st.close(); } try { if (FairnessTest.this.sleep > 0) sleep(FairnessTest.this.sleep); } catch (InterruptedException x) { interrupted(); } } finally { long cstart = System.nanoTime(); if (con != null) try { con.close(); } catch (Exception x) { x.printStackTrace(); } long cdelta = System.nanoTime() - cstart; totalcmax += cdelta; cmax = Math.max(cdelta, cmax); } totalruntime += (System.nanoTime() - start); } } catch (Exception x) { x.printStackTrace(); } finally { FairnessTest.this.latch.countDown(); } if (System.getProperty("print-thread-stats") != null) { System.out.println( "[" + getName() + "] " + "\n\tMax time to retrieve connection:" + maxwait / 1000000f + " ms." + "\n\tTotal time to retrieve connection:" + totalwait / 1000000f + " ms." + "\n\tAverage time to retrieve connection:" + totalwait / 1000000f / nroffetch + " ms." + "\n\tMax time to close connection:" + cmax / 1000000f + " ms." + "\n\tTotal time to close connection:" + totalcmax / 1000000f + " ms." + "\n\tAverage time to close connection:" + totalcmax / 1000000f / nroffetch + " ms." + "\n\tRun time:" + totalruntime / 1000000f + " ms." + "\n\tNr of fetch:" + nroffetch); } } } }
/** * {@link Trigger} that checks for SCM updates periodically. * * @author Kohsuke Kawaguchi */ public class SCMTrigger extends Trigger<SCMedItem> { @DataBoundConstructor public SCMTrigger(String scmpoll_spec) throws ANTLRException { super(scmpoll_spec); } @Override public void run() { run(null); } /** * Run the SCM trigger with additional build actions. Used by SubversionRepositoryStatus to * trigger a build at a specific revisionn number. * * @param additionalActions * @since 1.375 */ public void run(Action[] additionalActions) { if (Hudson.getInstance().isQuietingDown()) return; // noop DescriptorImpl d = getDescriptor(); LOGGER.fine("Scheduling a polling for " + job); if (d.synchronousPolling) { LOGGER.fine( "Running the trigger directly without threading, " + "as it's already taken care of by Trigger.Cron"); new Runner(additionalActions).run(); } else { // schedule the polling. // even if we end up submitting this too many times, that's OK. // the real exclusion control happens inside Runner. LOGGER.fine("scheduling the trigger to (asynchronously) run"); d.queue.execute(new Runner(additionalActions)); d.clogCheck(); } } @Override public DescriptorImpl getDescriptor() { return (DescriptorImpl) super.getDescriptor(); } @Override public Collection<? extends Action> getProjectActions() { return Collections.singleton(new SCMAction()); } /** Returns the file that records the last/current polling activity. */ public File getLogFile() { return new File(job.getRootDir(), "scm-polling.log"); } @Extension public static class DescriptorImpl extends TriggerDescriptor { /** * Used to control the execution of the polling tasks. * * <p>This executor implementation has a semantics suitable for polling. Namely, no two threads * will try to poll the same project at once, and multiple polling requests to the same job will * be combined into one. Note that because executor isn't aware of a potential workspace lock * between a build and a polling, we may end up using executor threads unwisely --- they may * block. */ private final transient SequentialExecutionQueue queue = new SequentialExecutionQueue(Executors.newSingleThreadExecutor()); /** * Whether the projects should be polled all in one go in the order of dependencies. The default * behavior is that each project polls for changes independently. */ public boolean synchronousPolling = false; /** Max number of threads for SCM polling. 0 for unbounded. */ private int maximumThreads; public DescriptorImpl() { load(); resizeThreadPool(); } public boolean isApplicable(Item item) { return item instanceof SCMedItem; } public ExecutorService getExecutor() { return queue.getExecutors(); } /** Returns true if the SCM polling thread queue has too many jobs than it can handle. */ public boolean isClogged() { return queue.isStarving(STARVATION_THRESHOLD); } /** Checks if the queue is clogged, and if so, activate {@link AdministrativeMonitorImpl}. */ public void clogCheck() { AdministrativeMonitor.all().get(AdministrativeMonitorImpl.class).on = isClogged(); } /** Gets the snapshot of {@link Runner}s that are performing polling. */ public List<Runner> getRunners() { return Util.filter(queue.getInProgress(), Runner.class); } /** Gets the snapshot of {@link SCMedItem}s that are being polled at this very moment. */ public List<SCMedItem> getItemsBeingPolled() { List<SCMedItem> r = new ArrayList<SCMedItem>(); for (Runner i : getRunners()) r.add(i.getTarget()); return r; } public String getDisplayName() { return Messages.SCMTrigger_DisplayName(); } /** * Gets the number of concurrent threads used for polling. * * @return 0 if unlimited. */ public int getPollingThreadCount() { return maximumThreads; } /** * Sets the number of concurrent threads used for SCM polling and resizes the thread pool * accordingly * * @param n number of concurrent threads, zero or less means unlimited, maximum is 100 */ public void setPollingThreadCount(int n) { // fool proof if (n < 0) n = 0; if (n > 100) n = 100; maximumThreads = n; resizeThreadPool(); } /** Update the {@link ExecutorService} instance. */ /*package*/ synchronized void resizeThreadPool() { queue.setExecutors( (maximumThreads == 0 ? Executors.newCachedThreadPool() : Executors.newFixedThreadPool(maximumThreads))); } @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { String t = json.optString("pollingThreadCount", null); if (t == null || t.length() == 0) setPollingThreadCount(0); else setPollingThreadCount(Integer.parseInt(t)); // Save configuration save(); return true; } public FormValidation doCheckPollingThreadCount(@QueryParameter String value) { if (value != null && "".equals(value.trim())) return FormValidation.ok(); return FormValidation.validateNonNegativeInteger(value); } } @Extension public static final class AdministrativeMonitorImpl extends AdministrativeMonitor { private boolean on; public boolean isActivated() { return on; } } /** * Associated with {@link AbstractBuild} to show the polling log that triggered that build. * * @since 1.376 */ public static class BuildAction implements Action { public final AbstractBuild build; public BuildAction(AbstractBuild build) { this.build = build; } /** Polling log that triggered the build. */ public File getPollingLogFile() { return new File(build.getRootDir(), "polling.log"); } public String getIconFileName() { return "clipboard.gif"; } public String getDisplayName() { return Messages.SCMTrigger_BuildAction_DisplayName(); } public String getUrlName() { return "pollingLog"; } /** Sends out the raw polling log output. */ public void doPollingLog(StaplerRequest req, StaplerResponse rsp) throws IOException { rsp.setContentType("text/plain;charset=UTF-8"); // Prevent jelly from flushing stream so Content-Length header can be added afterwards FlushProofOutputStream out = new FlushProofOutputStream(rsp.getCompressedOutputStream(req)); getPollingLogText().writeLogTo(0, out); out.close(); } public AnnotatedLargeText getPollingLogText() { return new AnnotatedLargeText<BuildAction>( getPollingLogFile(), Charset.defaultCharset(), true, this); } /** Used from <tt>polling.jelly</tt> to write annotated polling log to the given output. */ public void writePollingLogTo(long offset, XMLOutput out) throws IOException { // TODO: resurrect compressed log file support getPollingLogText().writeHtmlTo(offset, out.asWriter()); } } /** Action object for {@link Project}. Used to display the last polling log. */ public final class SCMAction implements Action { public AbstractProject<?, ?> getOwner() { return job.asProject(); } public String getIconFileName() { return "clipboard.gif"; } public String getDisplayName() { return Messages.SCMTrigger_getDisplayName(job.getScm().getDescriptor().getDisplayName()); } public String getUrlName() { return "scmPollLog"; } public String getLog() throws IOException { return Util.loadFile(getLogFile()); } /** * Writes the annotated log to the given output. * * @since 1.350 */ public void writeLogTo(XMLOutput out) throws IOException { new AnnotatedLargeText<SCMAction>(getLogFile(), Charset.defaultCharset(), true, this) .writeHtmlTo(0, out.asWriter()); } } private static final Logger LOGGER = Logger.getLogger(SCMTrigger.class.getName()); /** {@link Runnable} that actually performs polling. */ public class Runner implements Runnable { /** When did the polling start? */ private volatile long startTime; private Action[] additionalActions; public Runner() { additionalActions = new Action[0]; } public Runner(Action[] actions) { if (actions == null) { additionalActions = new Action[0]; } else { additionalActions = actions; } } /** Where the log file is written. */ public File getLogFile() { return SCMTrigger.this.getLogFile(); } /** For which {@link Item} are we polling? */ public SCMedItem getTarget() { return job; } /** When was this polling started? */ public long getStartTime() { return startTime; } /** Human readable string of when this polling is started. */ public String getDuration() { return Util.getTimeSpanString(System.currentTimeMillis() - startTime); } private boolean runPolling() { try { // to make sure that the log file contains up-to-date text, // don't do buffering. StreamTaskListener listener = new StreamTaskListener(getLogFile()); try { PrintStream logger = listener.getLogger(); long start = System.currentTimeMillis(); logger.println("Started on " + DateFormat.getDateTimeInstance().format(new Date())); boolean result = job.poll(listener).hasChanges(); logger.println( "Done. Took " + Util.getTimeSpanString(System.currentTimeMillis() - start)); if (result) logger.println("Changes found"); else logger.println("No changes"); return result; } catch (Error e) { e.printStackTrace(listener.error("Failed to record SCM polling")); LOGGER.log(Level.SEVERE, "Failed to record SCM polling", e); throw e; } catch (RuntimeException e) { e.printStackTrace(listener.error("Failed to record SCM polling")); LOGGER.log(Level.SEVERE, "Failed to record SCM polling", e); throw e; } finally { listener.close(); } } catch (IOException e) { LOGGER.log(Level.SEVERE, "Failed to record SCM polling", e); return false; } } public void run() { String threadName = Thread.currentThread().getName(); Thread.currentThread().setName("SCM polling for " + job); try { startTime = System.currentTimeMillis(); if (runPolling()) { AbstractProject p = job.asProject(); String name = " #" + p.getNextBuildNumber(); SCMTriggerCause cause; try { cause = new SCMTriggerCause(getLogFile()); } catch (IOException e) { LOGGER.log(WARNING, "Failed to parse the polling log", e); cause = new SCMTriggerCause(); } if (p.scheduleBuild(p.getQuietPeriod(), cause, additionalActions)) { LOGGER.info("SCM changes detected in " + job.getName() + ". Triggering " + name); } else { LOGGER.info( "SCM changes detected in " + job.getName() + ". Job is already in the queue"); } } } finally { Thread.currentThread().setName(threadName); } } private SCMedItem job() { return job; } // as per the requirement of SequentialExecutionQueue, value equality is necessary @Override public boolean equals(Object that) { return that instanceof Runner && job() == ((Runner) that).job(); } @Override public int hashCode() { return job.hashCode(); } } public static class SCMTriggerCause extends Cause { /** * Only used while ths cause is in the queue. Once attached to the build, we'll move this into a * file to reduce the memory footprint. */ private String pollingLog; public SCMTriggerCause(File logFile) throws IOException { // TODO: charset of this log file? this(FileUtils.readFileToString(logFile)); } public SCMTriggerCause(String pollingLog) { this.pollingLog = pollingLog; } /** @deprecated Use {@link #SCMTriggerCause(String)}. */ public SCMTriggerCause() { this(""); } @Override public void onAddedTo(AbstractBuild build) { BuildAction oldAction = build.getAction(BuildAction.class); if (oldAction != null) { build.getActions().remove(oldAction); } try { BuildAction a = new BuildAction(build); FileUtils.writeStringToFile(a.getPollingLogFile(), pollingLog); build.addAction(a); } catch (IOException e) { LOGGER.log(WARNING, "Failed to persist the polling log", e); } pollingLog = null; } @Override public String getShortDescription() { return Messages.SCMTrigger_SCMTriggerCause_ShortDescription(); } @Override public boolean equals(Object o) { return o instanceof SCMTriggerCause; } @Override public int hashCode() { return 3; } } /** How long is too long for a polling activity to be in the queue? */ public static long STARVATION_THRESHOLD = Long.getLong( SCMTrigger.class.getName() + ".starvationThreshold", TimeUnit2.HOURS.toMillis(1)); }
/** * {@link BuildWrapper} that terminates a build if it's taking too long. * * @author Kohsuke Kawaguchi */ public class BuildTimeoutWrapper extends BuildWrapper { public static long MINIMUM_TIMEOUT_MILLISECONDS = Long.getLong( BuildTimeoutWrapper.class.getName() + ".MINIMUM_TIMEOUT_MILLISECONDS", 3 * 60 * 1000); private /* final */ BuildTimeOutStrategy strategy; /** Fail the build rather than aborting it */ public boolean failBuild; /** Writing the build description when timeout occurred. */ public boolean writingDescription; @DataBoundConstructor public BuildTimeoutWrapper( BuildTimeOutStrategy strategy, boolean failBuild, boolean writingDescription) { this.strategy = strategy; this.failBuild = failBuild; this.writingDescription = writingDescription; } @Override public Environment setUp( final AbstractBuild build, Launcher launcher, final BuildListener listener) throws IOException, InterruptedException { class EnvironmentImpl extends Environment { final class TimeoutTimerTask extends SafeTimerTask { private final AbstractBuild build; private final BuildListener listener; // Did the task timeout? public boolean timeout = false; private TimeoutTimerTask(AbstractBuild build, BuildListener listener) { this.build = build; this.listener = listener; } public void doRun() { // timed out long effectiveTimeoutMinutes = MINUTES.convert(effectiveTimeout, MILLISECONDS); String msg; if (failBuild) { msg = Messages.Timeout_Message(effectiveTimeoutMinutes, Messages.Timeout_Failed()); } else { msg = Messages.Timeout_Message(effectiveTimeoutMinutes, Messages.Timeout_Aborted()); } listener.getLogger().println(msg); if (writingDescription) { try { build.setDescription(msg); } catch (IOException e) { listener.getLogger().println("failed to write to the build description!"); } } timeout = true; Executor e = build.getExecutor(); if (e != null) e.interrupt(failBuild ? Result.FAILURE : Result.ABORTED); } } private final TimeoutTimerTask task; private final long effectiveTimeout = strategy.getTimeOut(build); public EnvironmentImpl() { task = new TimeoutTimerTask(build, listener); Trigger.timer.schedule(task, effectiveTimeout); } @Override public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { task.cancel(); return (!task.timeout || !failBuild); } } return new EnvironmentImpl(); } protected Object readResolve() { if ("elastic".equalsIgnoreCase(timeoutType)) { strategy = new ElasticTimeOutStrategy( timeoutPercentage, timeoutMinutesElasticDefault != null ? timeoutMinutesElasticDefault.intValue() : 60, 3); } else if ("likelyStuck".equalsIgnoreCase(timeoutType)) { strategy = new LikelyStuckTimeOutStrategy(); } else if (strategy == null) { strategy = new AbsoluteTimeOutStrategy(timeoutMinutes); } return this; } @Override public Descriptor<BuildWrapper> getDescriptor() { return DESCRIPTOR; } @Extension public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); public static final class DescriptorImpl extends BuildWrapperDescriptor { DescriptorImpl() { super(BuildTimeoutWrapper.class); } public String getDisplayName() { return Messages.Descriptor_DisplayName(); } public boolean isApplicable(AbstractProject<?, ?> item) { return true; } } public BuildTimeOutStrategy getStrategy() { return strategy; } public List<BuildTimeOutStrategyDescriptor> getStrategies() { return Jenkins.getInstance().getDescriptorList(BuildTimeOutStrategy.class); } // --- legacy attributes, kept for backward compatibility public transient int timeoutMinutes; public transient int timeoutPercentage; public transient String timeoutType; public transient Integer timeoutMinutesElasticDefault; }
public static long getBlockSize() { return Long.getLong(BLOCK_SIZE, 0x1000); }
/** * Constructs an instance for controlling a local process. * * @param arguments details about the controllable process * @param pid process id identifying the process to control * @throws IllegalArgumentException if pid is not a positive integer */ public FileProcessController(final FileControllerParameters arguments, final int pid) { this(arguments, pid, Long.getLong(STATUS_TIMEOUT_PROPERTY, 60 * 1000), TimeUnit.MILLISECONDS); }
/** * {@link com.github.zhongl.api.Actor} is thread-bound {@link Runnable} executor. * * @author <a href="mailto:[email protected]">zhongl<a> */ @ThreadSafe public abstract class Actor { public static final long TIMEOUT = Long.getLong("ipage.actor.poll.timeout", 500L); private final Core core; private final long timeout; private final BlockingQueue<Runnable> tasks; // TODO monitor private final Runnable SHUTDOWN = new Runnable() { public void run() { core.running = false; } }; protected Actor(String name) { this(name, TIMEOUT); } protected Actor(String name, long timeout) { checkArgument(timeout >= 0); this.timeout = timeout; this.tasks = new LinkedBlockingQueue<Runnable>(); core = new Core(name); } public synchronized void start() { if (core.isAlive()) return; core.start(); } public synchronized void stop() { if (!core.isAlive()) return; try { tasks.put(SHUTDOWN); core.join(); } catch (InterruptedException ignored) { } } protected final <T> Future<T> submit(Callable<T> task) { final FutureTask futureTask = new FutureTask(task); tasks.offer(futureTask); return futureTask; } /** Overwrite this method for some time-sensitive stuff. */ protected void heartbeat() throws Throwable {} protected boolean onInterruptedBy(Throwable t) { return true; } private class Core extends Thread { @GuardedBy("this") private Boolean running = true; public Core(String name) { super(name); } @Override public void run() { while (running) { try { Runnable task = tasks.poll(timeout, MILLISECONDS); heartbeat(); if (task == null) continue; task.run(); } catch (Throwable t) { running = onInterruptedBy(t); } } } } }
/** * Base class for JSR166 Junit TCK tests. Defines some constants, utility methods and classes, as * well as a simple framework for helping to make sure that assertions failing in generated threads * cause the associated test that generated them to itself fail (which JUnit does not otherwise * arrange). The rules for creating such tests are: * * <ol> * <li>All assertions in code running in generated threads must use the forms {@link #threadFail}, * {@link #threadAssertTrue}, {@link #threadAssertEquals}, or {@link #threadAssertNull}, (not * {@code fail}, {@code assertTrue}, etc.) It is OK (but not particularly recommended) for * other code to use these forms too. Only the most typically used JUnit assertion methods are * defined this way, but enough to live with. * <li>If you override {@link #setUp} or {@link #tearDown}, make sure to invoke {@code * super.setUp} and {@code super.tearDown} within them. These methods are used to clear and * check for thread assertion failures. * <li>All delays and timeouts must use one of the constants {@code SHORT_DELAY_MS}, {@code * SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS}, {@code LONG_DELAY_MS}. The idea here is that a * SHORT is always discriminable from zero time, and always allows enough time for the small * amounts of computation (creating a thread, calling a few methods, etc) needed to reach a * timeout point. Similarly, a SMALL is always discriminable as larger than SHORT and smaller * than MEDIUM. And so on. These constants are set to conservative values, but even so, if * there is ever any doubt, they can all be increased in one spot to rerun tests on slower * platforms. * <li>All threads generated must be joined inside each test case method (or {@code fail} to do * so) before returning from the method. The {@code joinPool} method can be used to do this * when using Executors. * </ol> * * <p><b>Other notes</b> * * <ul> * <li>Usually, there is one testcase method per JSR166 method covering "normal" operation, and * then as many exception-testing methods as there are exceptions the method can throw. * Sometimes there are multiple tests per JSR166 method when the different "normal" behaviors * differ significantly. And sometimes testcases cover multiple methods when they cannot be * tested in isolation. * <li>The documentation style for testcases is to provide as javadoc a simple sentence or two * describing the property that the testcase method purports to test. The javadocs do not say * anything about how the property is tested. To find out, read the code. * <li>These tests are "conformance tests", and do not attempt to test throughput, latency, * scalability or other performance factors (see the separate "jtreg" tests for a set intended * to check these for the most central aspects of functionality.) So, most tests use the * smallest sensible numbers of threads, collection sizes, etc needed to check basic * conformance. * <li>The test classes currently do not declare inclusion in any particular package to simplify * things for people integrating them in TCK test suites. * <li>As a convenience, the {@code main} of this class (JSR166TestCase) runs all JSR166 unit * tests. * </ul> */ public class JSR166TestCase extends TestCase { private static final boolean useSecurityManager = Boolean.getBoolean("jsr166.useSecurityManager"); protected static final boolean expensiveTests = Boolean.getBoolean("jsr166.expensiveTests"); /** * If true, report on stdout all "slow" tests, that is, ones that take more than profileThreshold * milliseconds to execute. */ private static final boolean profileTests = Boolean.getBoolean("jsr166.profileTests"); /** * The number of milliseconds that tests are permitted for execution without being reported, when * profileTests is set. */ private static final long profileThreshold = Long.getLong("jsr166.profileThreshold", 100); protected void runTest() throws Throwable { if (profileTests) runTestProfiled(); else super.runTest(); } protected void runTestProfiled() throws Throwable { // Warmup run, notably to trigger all needed classloading. super.runTest(); long t0 = System.nanoTime(); try { super.runTest(); } finally { long elapsedMillis = millisElapsedSince(t0); if (elapsedMillis >= profileThreshold) System.out.printf("%n%s: %d%n", toString(), elapsedMillis); } } /** Runs all JSR166 unit tests using junit.textui.TestRunner */ public static void main(String[] args) { if (useSecurityManager) { System.err.println("Setting a permissive security manager"); Policy.setPolicy(permissivePolicy()); System.setSecurityManager(new SecurityManager()); } int iters = (args.length == 0) ? 1 : Integer.parseInt(args[0]); Test s = suite(); for (int i = 0; i < iters; ++i) { junit.textui.TestRunner.run(s); System.gc(); System.runFinalization(); } System.exit(0); } public static TestSuite newTestSuite(Object... suiteOrClasses) { TestSuite suite = new TestSuite(); for (Object suiteOrClass : suiteOrClasses) { if (suiteOrClass instanceof TestSuite) suite.addTest((TestSuite) suiteOrClass); else if (suiteOrClass instanceof Class) suite.addTest(new TestSuite((Class<?>) suiteOrClass)); else throw new ClassCastException("not a test suite or class"); } return suite; } /** Collects all JSR166 unit tests as one suite. */ public static Test suite() { return newTestSuite( AtomicDoubleTest.suite(), AtomicDoubleArrayTest.suite(), CompletableFutureTest.suite(), ConcurrentHashMapV8Test.suite(), CountedCompleterTest.suite(), DoubleAdderTest.suite(), ForkJoinPoolTest.suite(), ForkJoinTaskTest.suite(), LongAdderTest.suite(), RecursiveTaskTest.suite(), RecursiveActionTest.suite(), StampedLockTest.suite(), ThreadLocalRandomTest.suite()); } // Delays for timing-dependent tests, in milliseconds. public static long SHORT_DELAY_MS; public static long SMALL_DELAY_MS; public static long MEDIUM_DELAY_MS; public static long LONG_DELAY_MS; /** * Returns the shortest timed delay. This could be reimplemented to use for example a Property. */ protected long getShortDelay() { return 50; } /** Sets delays as multiples of SHORT_DELAY. */ protected void setDelays() { SHORT_DELAY_MS = getShortDelay(); SMALL_DELAY_MS = SHORT_DELAY_MS * 5; MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10; LONG_DELAY_MS = SHORT_DELAY_MS * 200; } /** * Returns a timeout in milliseconds to be used in tests that verify that operations block or time * out. */ long timeoutMillis() { return SHORT_DELAY_MS / 4; } /** Returns a new Date instance representing a time delayMillis milliseconds in the future. */ Date delayedDate(long delayMillis) { return new Date(System.currentTimeMillis() + delayMillis); } /** The first exception encountered if any threadAssertXXX method fails. */ private final AtomicReference<Throwable> threadFailure = new AtomicReference<Throwable>(null); /** * Records an exception so that it can be rethrown later in the test harness thread, triggering a * test case failure. Only the first failure is recorded; subsequent calls to this method from * within the same test have no effect. */ public void threadRecordFailure(Throwable t) { threadFailure.compareAndSet(null, t); } public void setUp() { setDelays(); } /** * Extra checks that get done for all test cases. * * <p>Triggers test case failure if any thread assertions have failed, by rethrowing, in the test * harness thread, any exception recorded earlier by threadRecordFailure. * * <p>Triggers test case failure if interrupt status is set in the main thread. */ public void tearDown() throws Exception { Throwable t = threadFailure.getAndSet(null); if (t != null) { if (t instanceof Error) throw (Error) t; else if (t instanceof RuntimeException) throw (RuntimeException) t; else if (t instanceof Exception) throw (Exception) t; else { AssertionFailedError afe = new AssertionFailedError(t.toString()); afe.initCause(t); throw afe; } } if (Thread.interrupted()) throw new AssertionFailedError("interrupt status set in main thread"); } /** * Just like fail(reason), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadFail(String reason) { try { fail(reason); } catch (AssertionFailedError t) { threadRecordFailure(t); fail(reason); } } /** * Just like assertTrue(b), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadAssertTrue(boolean b) { try { assertTrue(b); } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } } /** * Just like assertFalse(b), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadAssertFalse(boolean b) { try { assertFalse(b); } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } } /** * Just like assertNull(x), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadAssertNull(Object x) { try { assertNull(x); } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } } /** * Just like assertEquals(x, y), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadAssertEquals(long x, long y) { try { assertEquals(x, y); } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } } /** * Just like assertEquals(x, y), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadAssertEquals(Object x, Object y) { try { assertEquals(x, y); } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } catch (Throwable t) { threadUnexpectedException(t); } } /** * Just like assertSame(x, y), but additionally recording (using threadRecordFailure) any * AssertionFailedError thrown, so that the current testcase will fail. */ public void threadAssertSame(Object x, Object y) { try { assertSame(x, y); } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } } /** Calls threadFail with message "should throw exception". */ public void threadShouldThrow() { threadFail("should throw exception"); } /** Calls threadFail with message "should throw" + exceptionName. */ public void threadShouldThrow(String exceptionName) { threadFail("should throw " + exceptionName); } /** * Records the given exception using {@link #threadRecordFailure}, then rethrows the exception, * wrapping it in an AssertionFailedError if necessary. */ public void threadUnexpectedException(Throwable t) { threadRecordFailure(t); t.printStackTrace(); if (t instanceof RuntimeException) throw (RuntimeException) t; else if (t instanceof Error) throw (Error) t; else { AssertionFailedError afe = new AssertionFailedError("unexpected exception: " + t); afe.initCause(t); throw afe; } } /** * Delays, via Thread.sleep, for the given millisecond delay, but if the sleep is shorter than * specified, may re-sleep or yield until time elapses. */ static void delay(long millis) throws InterruptedException { long startTime = System.nanoTime(); long ns = millis * 1000 * 1000; for (; ; ) { if (millis > 0L) Thread.sleep(millis); else // too short to sleep Thread.yield(); long d = ns - (System.nanoTime() - startTime); if (d > 0L) millis = d / (1000 * 1000); else break; } } /** Waits out termination of a thread pool or fails doing so. */ void joinPool(ExecutorService exec) { try { exec.shutdown(); assertTrue( "ExecutorService did not terminate in a timely manner", exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)); } catch (SecurityException ok) { // Allowed in case test doesn't have privs } catch (InterruptedException ie) { fail("Unexpected InterruptedException"); } } /** * Checks that thread does not terminate within the default millisecond delay of {@code * timeoutMillis()}. */ void assertThreadStaysAlive(Thread thread) { assertThreadStaysAlive(thread, timeoutMillis()); } /** Checks that thread does not terminate within the given millisecond delay. */ void assertThreadStaysAlive(Thread thread, long millis) { try { // No need to optimize the failing case via Thread.join. delay(millis); assertTrue(thread.isAlive()); } catch (InterruptedException ie) { fail("Unexpected InterruptedException"); } } /** * Checks that the threads do not terminate within the default millisecond delay of {@code * timeoutMillis()}. */ void assertThreadsStayAlive(Thread... threads) { assertThreadsStayAlive(timeoutMillis(), threads); } /** Checks that the threads do not terminate within the given millisecond delay. */ void assertThreadsStayAlive(long millis, Thread... threads) { try { // No need to optimize the failing case via Thread.join. delay(millis); for (Thread thread : threads) assertTrue(thread.isAlive()); } catch (InterruptedException ie) { fail("Unexpected InterruptedException"); } } /** Checks that future.get times out, with the default timeout of {@code timeoutMillis()}. */ void assertFutureTimesOut(Future future) { assertFutureTimesOut(future, timeoutMillis()); } /** Checks that future.get times out, with the given millisecond timeout. */ void assertFutureTimesOut(Future future, long timeoutMillis) { long startTime = System.nanoTime(); try { future.get(timeoutMillis, MILLISECONDS); shouldThrow(); } catch (TimeoutException success) { } catch (Exception e) { threadUnexpectedException(e); } finally { future.cancel(true); } assertTrue(millisElapsedSince(startTime) >= timeoutMillis); } /** Fails with message "should throw exception". */ public void shouldThrow() { fail("Should throw exception"); } /** Fails with message "should throw " + exceptionName. */ public void shouldThrow(String exceptionName) { fail("Should throw " + exceptionName); } /** The number of elements to place in collections, arrays, etc. */ public static final int SIZE = 20; // Some convenient Integer constants public static final Integer zero = new Integer(0); public static final Integer one = new Integer(1); public static final Integer two = new Integer(2); public static final Integer three = new Integer(3); public static final Integer four = new Integer(4); public static final Integer five = new Integer(5); public static final Integer six = new Integer(6); public static final Integer seven = new Integer(7); public static final Integer eight = new Integer(8); public static final Integer nine = new Integer(9); public static final Integer m1 = new Integer(-1); public static final Integer m2 = new Integer(-2); public static final Integer m3 = new Integer(-3); public static final Integer m4 = new Integer(-4); public static final Integer m5 = new Integer(-5); public static final Integer m6 = new Integer(-6); public static final Integer m10 = new Integer(-10); /** * Runs Runnable r with a security policy that permits precisely the specified permissions. If * there is no current security manager, the runnable is run twice, both with and without a * security manager. We require that any security manager permit getPolicy/setPolicy. */ public void runWithPermissions(Runnable r, Permission... permissions) { SecurityManager sm = System.getSecurityManager(); if (sm == null) { r.run(); Policy savedPolicy = Policy.getPolicy(); try { Policy.setPolicy(permissivePolicy()); System.setSecurityManager(new SecurityManager()); runWithPermissions(r, permissions); } finally { System.setSecurityManager(null); Policy.setPolicy(savedPolicy); } } else { Policy savedPolicy = Policy.getPolicy(); AdjustablePolicy policy = new AdjustablePolicy(permissions); Policy.setPolicy(policy); try { r.run(); } finally { policy.addPermission(new SecurityPermission("setPolicy")); Policy.setPolicy(savedPolicy); } } } /** Runs a runnable without any permissions. */ public void runWithoutPermissions(Runnable r) { runWithPermissions(r); } /** A security policy where new permissions can be dynamically added or all cleared. */ public static class AdjustablePolicy extends java.security.Policy { Permissions perms = new Permissions(); AdjustablePolicy(Permission... permissions) { for (Permission permission : permissions) perms.add(permission); } void addPermission(Permission perm) { perms.add(perm); } void clearPermissions() { perms = new Permissions(); } public PermissionCollection getPermissions(CodeSource cs) { return perms; } public PermissionCollection getPermissions(ProtectionDomain pd) { return perms; } public boolean implies(ProtectionDomain pd, Permission p) { return perms.implies(p); } public void refresh() {} } /** Returns a policy containing all the permissions we ever need. */ public static Policy permissivePolicy() { return new AdjustablePolicy // Permissions j.u.c. needs directly ( new RuntimePermission("modifyThread"), new RuntimePermission("getClassLoader"), new RuntimePermission("setContextClassLoader"), // Permissions needed to change permissions! new SecurityPermission("getPolicy"), new SecurityPermission("setPolicy"), new RuntimePermission("setSecurityManager"), // Permissions needed by the junit test harness new RuntimePermission("accessDeclaredMembers"), new PropertyPermission("*", "read"), new java.io.FilePermission("<<ALL FILES>>", "read")); } /** Sleeps until the given time has elapsed. Throws AssertionFailedError if interrupted. */ void sleep(long millis) { try { delay(millis); } catch (InterruptedException ie) { AssertionFailedError afe = new AssertionFailedError("Unexpected InterruptedException"); afe.initCause(ie); throw afe; } } /** * Spin-waits up to the specified number of milliseconds for the given thread to enter a wait * state: BLOCKED, WAITING, or TIMED_WAITING. */ void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) { long startTime = System.nanoTime(); for (; ; ) { Thread.State s = thread.getState(); if (s == Thread.State.BLOCKED || s == Thread.State.WAITING || s == Thread.State.TIMED_WAITING) return; else if (s == Thread.State.TERMINATED) fail("Unexpected thread termination"); else if (millisElapsedSince(startTime) > timeoutMillis) { threadAssertTrue(thread.isAlive()); return; } Thread.yield(); } } /** * Waits up to LONG_DELAY_MS for the given thread to enter a wait state: BLOCKED, WAITING, or * TIMED_WAITING. */ void waitForThreadToEnterWaitState(Thread thread) { waitForThreadToEnterWaitState(thread, LONG_DELAY_MS); } /** * Returns the number of milliseconds since time given by startNanoTime, which must have been * previously returned from a call to {@link System.nanoTime()}. */ static long millisElapsedSince(long startNanoTime) { return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); } /** Returns a new started daemon Thread running the given runnable. */ Thread newStartedThread(Runnable runnable) { Thread t = new Thread(runnable); t.setDaemon(true); t.start(); return t; } /** * Waits for the specified time (in milliseconds) for the thread to terminate (using {@link * Thread#join(long)}), else interrupts the thread (in the hope that it may terminate later) and * fails. */ void awaitTermination(Thread t, long timeoutMillis) { try { t.join(timeoutMillis); } catch (InterruptedException ie) { threadUnexpectedException(ie); } finally { if (t.getState() != Thread.State.TERMINATED) { t.interrupt(); fail("Test timed out"); } } } /** * Waits for LONG_DELAY_MS milliseconds for the thread to terminate (using {@link * Thread#join(long)}), else interrupts the thread (in the hope that it may terminate later) and * fails. */ void awaitTermination(Thread t) { awaitTermination(t, LONG_DELAY_MS); } // Some convenient Runnable classes public abstract class CheckedRunnable implements Runnable { protected abstract void realRun() throws Throwable; public final void run() { try { realRun(); } catch (Throwable t) { threadUnexpectedException(t); } } } public abstract class RunnableShouldThrow implements Runnable { protected abstract void realRun() throws Throwable; final Class<?> exceptionClass; <T extends Throwable> RunnableShouldThrow(Class<T> exceptionClass) { this.exceptionClass = exceptionClass; } public final void run() { try { realRun(); threadShouldThrow(exceptionClass.getSimpleName()); } catch (Throwable t) { if (!exceptionClass.isInstance(t)) threadUnexpectedException(t); } } } public abstract class ThreadShouldThrow extends Thread { protected abstract void realRun() throws Throwable; final Class<?> exceptionClass; <T extends Throwable> ThreadShouldThrow(Class<T> exceptionClass) { this.exceptionClass = exceptionClass; } public final void run() { try { realRun(); threadShouldThrow(exceptionClass.getSimpleName()); } catch (Throwable t) { if (!exceptionClass.isInstance(t)) threadUnexpectedException(t); } } } public abstract class CheckedInterruptedRunnable implements Runnable { protected abstract void realRun() throws Throwable; public final void run() { try { realRun(); threadShouldThrow("InterruptedException"); } catch (InterruptedException success) { threadAssertFalse(Thread.interrupted()); } catch (Throwable t) { threadUnexpectedException(t); } } } public abstract class CheckedCallable<T> implements Callable<T> { protected abstract T realCall() throws Throwable; public final T call() { try { return realCall(); } catch (Throwable t) { threadUnexpectedException(t); return null; } } } public abstract class CheckedInterruptedCallable<T> implements Callable<T> { protected abstract T realCall() throws Throwable; public final T call() { try { T result = realCall(); threadShouldThrow("InterruptedException"); return result; } catch (InterruptedException success) { threadAssertFalse(Thread.interrupted()); } catch (Throwable t) { threadUnexpectedException(t); } return null; } } public static class NoOpRunnable implements Runnable { public void run() {} } public static class NoOpCallable implements Callable { public Object call() { return Boolean.TRUE; } } public static final String TEST_STRING = "a test string"; public static class StringTask implements Callable<String> { public String call() { return TEST_STRING; } } public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) { return new CheckedCallable<String>() { protected String realCall() { try { latch.await(); } catch (InterruptedException quittingTime) { } return TEST_STRING; } }; } public Runnable awaiter(final CountDownLatch latch) { return new CheckedRunnable() { public void realRun() throws InterruptedException { await(latch); } }; } public void await(CountDownLatch latch) { try { assertTrue(latch.await(LONG_DELAY_MS, MILLISECONDS)); } catch (Throwable t) { threadUnexpectedException(t); } } public void await(Semaphore semaphore) { try { assertTrue(semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS)); } catch (Throwable t) { threadUnexpectedException(t); } } // /** // * Spin-waits up to LONG_DELAY_MS until flag becomes true. // */ // public void await(AtomicBoolean flag) { // await(flag, LONG_DELAY_MS); // } // /** // * Spin-waits up to the specified timeout until flag becomes true. // */ // public void await(AtomicBoolean flag, long timeoutMillis) { // long startTime = System.nanoTime(); // while (!flag.get()) { // if (millisElapsedSince(startTime) > timeoutMillis) // throw new AssertionFailedError("timed out"); // Thread.yield(); // } // } public static class NPETask implements Callable<String> { public String call() { throw new NullPointerException(); } } public static class CallableOne implements Callable<Integer> { public Integer call() { return one; } } public class ShortRunnable extends CheckedRunnable { protected void realRun() throws Throwable { delay(SHORT_DELAY_MS); } } public class ShortInterruptedRunnable extends CheckedInterruptedRunnable { protected void realRun() throws InterruptedException { delay(SHORT_DELAY_MS); } } public class SmallRunnable extends CheckedRunnable { protected void realRun() throws Throwable { delay(SMALL_DELAY_MS); } } public class SmallPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { delay(SMALL_DELAY_MS); } catch (InterruptedException ok) { } } } public class SmallCallable extends CheckedCallable { protected Object realCall() throws InterruptedException { delay(SMALL_DELAY_MS); return Boolean.TRUE; } } public class MediumRunnable extends CheckedRunnable { protected void realRun() throws Throwable { delay(MEDIUM_DELAY_MS); } } public class MediumInterruptedRunnable extends CheckedInterruptedRunnable { protected void realRun() throws InterruptedException { delay(MEDIUM_DELAY_MS); } } public Runnable possiblyInterruptedRunnable(final long timeoutMillis) { return new CheckedRunnable() { protected void realRun() { try { delay(timeoutMillis); } catch (InterruptedException ok) { } } }; } public class MediumPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { delay(MEDIUM_DELAY_MS); } catch (InterruptedException ok) { } } } public class LongPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { delay(LONG_DELAY_MS); } catch (InterruptedException ok) { } } } /** For use as ThreadFactory in constructors */ public static class SimpleThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { return new Thread(r); } } public interface TrackedRunnable extends Runnable { boolean isDone(); } public static TrackedRunnable trackedRunnable(final long timeoutMillis) { return new TrackedRunnable() { private volatile boolean done = false; public boolean isDone() { return done; } public void run() { try { delay(timeoutMillis); done = true; } catch (InterruptedException ok) { } } }; } public static class TrackedShortRunnable implements Runnable { public volatile boolean done = false; public void run() { try { delay(SHORT_DELAY_MS); done = true; } catch (InterruptedException ok) { } } } public static class TrackedSmallRunnable implements Runnable { public volatile boolean done = false; public void run() { try { delay(SMALL_DELAY_MS); done = true; } catch (InterruptedException ok) { } } } public static class TrackedMediumRunnable implements Runnable { public volatile boolean done = false; public void run() { try { delay(MEDIUM_DELAY_MS); done = true; } catch (InterruptedException ok) { } } } public static class TrackedLongRunnable implements Runnable { public volatile boolean done = false; public void run() { try { delay(LONG_DELAY_MS); done = true; } catch (InterruptedException ok) { } } } public static class TrackedNoOpRunnable implements Runnable { public volatile boolean done = false; public void run() { done = true; } } public static class TrackedCallable implements Callable { public volatile boolean done = false; public Object call() { try { delay(SMALL_DELAY_MS); done = true; } catch (InterruptedException ok) { } return Boolean.TRUE; } } /** Analog of CheckedRunnable for RecursiveAction */ public abstract class CheckedRecursiveAction extends RecursiveAction { protected abstract void realCompute() throws Throwable; public final void compute() { try { realCompute(); } catch (Throwable t) { threadUnexpectedException(t); } } } /** Analog of CheckedCallable for RecursiveTask */ public abstract class CheckedRecursiveTask<T> extends RecursiveTask<T> { protected abstract T realCompute() throws Throwable; public final T compute() { try { return realCompute(); } catch (Throwable t) { threadUnexpectedException(t); return null; } } } /** For use as RejectedExecutionHandler in constructors */ public static class NoOpREHandler implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {} } /** * A CyclicBarrier that uses timed await and fails with AssertionFailedErrors instead of throwing * checked exceptions. */ public class CheckedBarrier extends CyclicBarrier { public CheckedBarrier(int parties) { super(parties); } public int await() { try { return super.await(2 * LONG_DELAY_MS, MILLISECONDS); } catch (TimeoutException e) { throw new AssertionFailedError("timed out"); } catch (Exception e) { AssertionFailedError afe = new AssertionFailedError("Unexpected exception: " + e); afe.initCause(e); throw afe; } } } void checkEmpty(BlockingQueue q) { try { assertTrue(q.isEmpty()); assertEquals(0, q.size()); assertNull(q.peek()); assertNull(q.poll()); assertNull(q.poll(0, MILLISECONDS)); assertEquals("[]", q.toString()); assertTrue(Arrays.equals(q.toArray(), new Object[0])); assertFalse(q.iterator().hasNext()); try { q.element(); shouldThrow(); } catch (NoSuchElementException success) { } try { q.iterator().next(); shouldThrow(); } catch (NoSuchElementException success) { } try { q.remove(); shouldThrow(); } catch (NoSuchElementException success) { } } catch (InterruptedException ie) { threadUnexpectedException(ie); } } @SuppressWarnings("unchecked") <T> T serialClone(T o) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(o); oos.flush(); oos.close(); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); T clone = (T) ois.readObject(); assertSame(o.getClass(), clone.getClass()); return clone; } catch (Throwable t) { threadUnexpectedException(t); return null; } } }
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); } } } }