This patch updates the error reporting inside of JUnitShell to show which remoteweb targets
haven't responded when there is a timeout.
Patch by: zundel
Review by: fabbott(TBR)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2419 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/junit/JUnitMessageQueue.java b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
index 51dfe31..6c80cc8 100644
--- a/user/src/com/google/gwt/junit/JUnitMessageQueue.java
+++ b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.junit;
+import com.google.gwt.junit.client.TimeoutException;
import com.google.gwt.junit.client.impl.JUnitResult;
import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
@@ -23,6 +24,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* A message queue to pass data between {@link JUnitShell} and {@link
@@ -70,11 +72,6 @@
private Object resultsLock = new Object();
/**
- * The name of the module to execute.
- */
- private String testModule;
-
- /**
* The name of the test class to execute.
*/
private String testClass;
@@ -85,6 +82,11 @@
private String testMethod;
/**
+ * The name of the module to execute.
+ */
+ private String testModule;
+
+ /**
* The results for the current test method.
*/
private List<JUnitResult> testResult = new ArrayList<JUnitResult>();
@@ -119,6 +121,7 @@
public TestInfo getNextTestInfo(String clientId, String moduleName,
long timeout) {
synchronized (readTestLock) {
+ long startTime = System.currentTimeMillis();
long stopTime = System.currentTimeMillis() + timeout;
while (!testIsAvailableFor(clientId, moduleName)) {
long timeToWait = stopTime - System.currentTimeMillis();
@@ -128,8 +131,12 @@
try {
readTestLock.wait(timeToWait);
} catch (InterruptedException e) {
- // just abort
- return null;
+ double elapsed = (System.currentTimeMillis() - startTime) / 1000.0;
+ throw new TimeoutException("The servlet did not respond to the "
+ + "next query to test within "
+ + timeout + "ms.\n" + " Module Name: " + moduleName + "\n"
+ + " Client id: " + clientId + "\n"
+ + " Actual time elapsed: " + elapsed + " seconds.\n");
}
}
@@ -172,6 +179,44 @@
}
/**
+ * Returns a pretty printed list of clients that have not retrieved the
+ * current test. Used for error reporting.
+ *
+ * @return a string containing the list of clients that have not retrieved the
+ * current test.
+ */
+ String getUnretrievedClients() {
+ int lineCount = 0;
+ StringBuilder buf = new StringBuilder();
+ synchronized (readTestLock) {
+ Set<String> keys = clientTestRequests.keySet();
+
+ for (String key : keys) {
+ if (lineCount > 0) {
+ buf.append('\n');
+ }
+
+ if (clientTestRequests.get(key) <= currentTestIndex) {
+ buf.append(" - NO RESPONSE: ");
+ buf.append(key);
+ } else {
+ buf.append(" - (ok): ");
+ buf.append(key);
+ }
+ lineCount++;
+ }
+ int difference = numClients - keys.size();
+ if (difference > 0) {
+ if (lineCount > 0) {
+ buf.append('\n');
+ }
+ buf.append(" - " + difference + " client(s) haven't responded back to the servlet at all since the start of the test.");
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
* Called by the shell to see if the currently-running test has completed.
*
* @param moduleName the name of the test module
@@ -191,7 +236,7 @@
*/
boolean haveAllClientsRetrievedCurrentTest() {
synchronized (readTestLock) {
- // If a client hasn't yet contacted, it will have no entry
+ // If a client hasn't yet been contacted, it will have no entry
Collection<Integer> clientIndices = clientTestRequests.values();
if (clientIndices.size() < numClients) {
return false;
@@ -210,8 +255,9 @@
* Called by the shell to set the name of the next method to run for this test
* class.
*
- * @param testClassName The name of the test class.
- * @param testName The name of the method to run.
+ * @param testModule the name of the module to be run.
+ * @param testClass The name of the test class.
+ * @param testMethod The name of the method to run.
*/
void setNextTestName(String testModule, String testClass, String testMethod) {
synchronized (readTestLock) {
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 349dc10..d1ef7fb 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -165,6 +165,7 @@
throw new RuntimeException("Invalid shell arguments");
}
+
shell.messageQueue = new JUnitMessageQueue(shell.numClients);
if (!shell.startUp()) {
@@ -213,6 +214,11 @@
* started the test.
*/
private long testBeginTimeout;
+
+ /**
+ * The time the test actually began.
+ */
+ private long testBeginTime;
/**
* Enforce the singleton pattern. The call to {@link GWTShell}'s ctor forces
@@ -350,9 +356,12 @@
protected boolean notDone() {
if (!messageQueue.haveAllClientsRetrievedCurrentTest()
&& testBeginTimeout < System.currentTimeMillis()) {
+ double elapsed = (System.currentTimeMillis() - testBeginTime) / 1000.0;
throw new TimeoutException(
"The browser did not contact the server within "
- + TEST_BEGIN_TIMEOUT_MILLIS + "ms.");
+ + TEST_BEGIN_TIMEOUT_MILLIS + "ms.\n"
+ + messageQueue.getUnretrievedClients()
+ + "\n Actual time elapsed: " + elapsed + " seconds.\n");
}
if (messageQueue.hasResult(currentModule.getName())) {
@@ -426,7 +435,8 @@
try {
// Set a timeout period to automatically fail if the servlet hasn't been
// contacted; something probably went wrong (the module failed to load?)
- testBeginTimeout = System.currentTimeMillis() + TEST_BEGIN_TIMEOUT_MILLIS;
+ testBeginTime = System.currentTimeMillis();
+ testBeginTimeout = testBeginTime + TEST_BEGIN_TIMEOUT_MILLIS;
pumpEventLoop();
} catch (TimeoutException e) {
lastLaunchFailed = true;
diff --git a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
index 9c94904..8936cba 100644
--- a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
+++ b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
@@ -222,9 +222,10 @@
*/
private String getClientId() {
HttpServletRequest request = getThreadLocalRequest();
- String agent = request.getHeader("User-Agent");
String machine = request.getRemoteHost();
- return machine + " / " + agent;
+ String servletPath = request.getServletPath();
+ String agent = request.getHeader("User-Agent");
+ return machine + " / " + servletPath + " / " + agent;
}
private String getModuleName(String requestURI) {