Fixes JUnit sessions to not use Cookies, which can be problematic.
- The session id is passed through RPC
- Session ids are now ints.
Suggested by: jlabanca
Review by: jlabanca
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7155 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 8f91977..7222b93 100644
--- a/user/src/com/google/gwt/junit/JUnitMessageQueue.java
+++ b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
@@ -15,15 +15,16 @@
*/
package com.google.gwt.junit;
-import com.google.gwt.dev.util.collect.HashSet;
-import com.google.gwt.dev.util.collect.IdentityHashMap;
import com.google.gwt.junit.client.TimeoutException;
import com.google.gwt.junit.client.impl.JUnitResult;
+import com.google.gwt.junit.client.impl.JUnitHost.ClientInfo;
import com.google.gwt.junit.client.impl.JUnitHost.TestBlock;
import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -46,17 +47,51 @@
public class JUnitMessageQueue {
/**
+ * Server-side client info that includes a description.
+ */
+ public static class ClientInfoExt extends ClientInfo {
+ /**
+ * A description of this client.
+ */
+ private final String desc;
+
+ public ClientInfoExt(int sessionId, String userAgent, String desc) {
+ super(sessionId, userAgent);
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+ }
+
+ /**
* Holds the state of an individual client.
*/
public static class ClientStatus {
- public int blockIndex = 0;
- public final String clientId;
- public String clientDesc;
- public boolean isNew = true;
+ private int blockIndex = 0;
+ private ClientInfoExt clientInfo;
+ private boolean isNew = true;
- public ClientStatus(String clientId, String clientDesc) {
- this.clientId = clientId;
- this.clientDesc = clientDesc;
+ public ClientStatus(ClientInfoExt clientInfo) {
+ this.clientInfo = clientInfo;
+ }
+
+ public String getDesc() {
+ return clientInfo.getDesc();
+ }
+
+ public int getId() {
+ return clientInfo.getSessionId();
+ }
+
+ @Override
+ public String toString() {
+ return clientInfo.getDesc();
+ }
+
+ public void updateClientInfo(ClientInfoExt clientInfo) {
+ this.clientInfo = clientInfo;
}
}
@@ -72,7 +107,7 @@
/**
* Records results for each client; must lock before accessing.
*/
- private final Map<String, ClientStatus> clientStatuses = new HashMap<String, ClientStatus>();
+ private final Map<Integer, ClientStatus> clientStatuses = new HashMap<Integer, ClientStatus>();
/**
* The lock used to synchronize access to clientStatuses.
@@ -117,19 +152,18 @@
/**
* Called by the servlet to query for for the next block to test.
*
- * @param clientId the ID of the client
- * @param userAgent the user agent property of the client
+ * @param clientInfo information about the client
* @param blockIndex the index of the test block to get
* @param timeout how long to wait for an answer
* @return the next test to run, or <code>null</code> if
* <code>timeout</code> is exceeded or the next test does not match
* <code>testClassName</code>
*/
- public TestBlock getTestBlock(String clientId, String clientDesc,
- String userAgent, int blockIndex, long timeout) throws TimeoutException {
+ public TestBlock getTestBlock(ClientInfoExt clientInfo, int blockIndex,
+ long timeout) throws TimeoutException {
synchronized (clientStatusesLock) {
- userAgents.add(userAgent);
- ClientStatus clientStatus = ensureClientStatus(clientId, clientDesc);
+ userAgents.add(clientInfo.getUserAgent());
+ ClientStatus clientStatus = ensureClientStatus(clientInfo);
clientStatus.blockIndex = blockIndex;
// The client has finished all of the tests.
@@ -145,8 +179,8 @@
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"
- + " Client id: " + clientId + "\n" + " Actual time elapsed: "
- + elapsed + " seconds.\n");
+ + " Client description: " + clientInfo.getDesc() + "\n"
+ + " Actual time elapsed: " + elapsed + " seconds.\n");
}
try {
clientStatusesLock.wait(timeToWait);
@@ -170,32 +204,36 @@
}
}
- public void reportFatalLaunch(String clientId, String clientDesc, String userAgent,
- JUnitResult result) {
+ /**
+ * Reports a failure from a client that cannot startup.
+ *
+ * @param clientInfo information about the client
+ * @param result the failure result
+ */
+ public void reportFatalLaunch(ClientInfoExt clientInfo, JUnitResult result) {
// Fatal launch error, cause this client to fail the whole block.
- ClientStatus clientStatus = ensureClientStatus(clientId, clientDesc);
+ ClientStatus clientStatus = ensureClientStatus(clientInfo);
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
for (TestInfo testInfo : testBlocks.get(clientStatus.blockIndex)) {
results.put(testInfo, result);
}
- reportResults(clientId, clientDesc, userAgent, results);
+ reportResults(clientInfo, results);
}
/**
* Called by the servlet to report the results of the last test to run.
*
- * @param clientId the ID of the client
- * @param userAgent the user agent property of the client
+ * @param clientInfo information about the client
* @param results the result of running the test block
*/
- public void reportResults(String clientId, String clientDesc, String userAgent,
+ public void reportResults(ClientInfoExt clientInfo,
Map<TestInfo, JUnitResult> results) {
synchronized (clientStatusesLock) {
if (results == null) {
throw new IllegalArgumentException("results cannot be null");
}
- userAgents.add(userAgent);
- ClientStatus clientStatus = ensureClientStatus(clientId, clientDesc);
+ userAgents.add(clientInfo.getUserAgent());
+ ClientStatus clientStatus = ensureClientStatus(clientInfo);
// Cache the test results.
for (Map.Entry<TestInfo, JUnitResult> entry : results.entrySet()) {
@@ -240,7 +278,7 @@
List<String> results = new ArrayList<String>();
for (ClientStatus clientStatus : clientStatuses.values()) {
if (clientStatus.isNew) {
- results.add(clientStatus.clientDesc);
+ results.add(clientStatus.getDesc());
// Record that this client is no longer new.
clientStatus.isNew = false;
}
@@ -323,7 +361,7 @@
} else {
buf.append(" - (ok): ");
}
- buf.append(clientStatus.clientDesc);
+ buf.append(clientStatus.getDesc());
++lineCount;
}
int difference = numClients - getNumClientsRetrievedTest(testInfo);
@@ -365,7 +403,7 @@
if (results != null) {
for (Map.Entry<ClientStatus, JUnitResult> entry : results.entrySet()) {
if (entry.getValue() == null) {
- buf.append(entry.getKey().clientDesc);
+ buf.append(entry.getKey().getDesc());
buf.append("\n");
itemCount++;
}
@@ -454,14 +492,15 @@
* @param clientId the id of the client
* @return the {@link ClientStatus} for the client
*/
- private ClientStatus ensureClientStatus(String clientId, String clientDesc) {
- ClientStatus clientStatus = clientStatuses.get(clientId);
+ private ClientStatus ensureClientStatus(ClientInfoExt clientInfo) {
+ int id = clientInfo.getSessionId();
+ ClientStatus clientStatus = clientStatuses.get(id);
if (clientStatus == null) {
- clientStatus = new ClientStatus(clientId, clientDesc);
- clientStatuses.put(clientId, clientStatus);
+ clientStatus = new ClientStatus(clientInfo);
+ clientStatuses.put(id, clientStatus);
} else {
- // Maybe update the description (ip might change if through a proxy).
- clientStatus.clientDesc = clientDesc;
+ // Maybe update the client info (IP might change if through a proxy).
+ clientStatus.updateClientInfo(clientInfo);
}
return clientStatus;
}
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 813c514..28d4bf3 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -1068,7 +1068,7 @@
// Let the user know the browser in which the failure happened.
if (exception != null) {
- String msg = "Remote test failed at " + client.clientDesc;
+ String msg = "Remote test failed at " + client.getDesc();
if (exception instanceof AssertionFailedError) {
String oldMessage = exception.getMessage();
if (oldMessage != null) {
diff --git a/user/src/com/google/gwt/junit/client/impl/ExceptionWrapper.java b/user/src/com/google/gwt/junit/client/impl/ExceptionWrapper.java
index 0226bab..d653ead 100644
--- a/user/src/com/google/gwt/junit/client/impl/ExceptionWrapper.java
+++ b/user/src/com/google/gwt/junit/client/impl/ExceptionWrapper.java
@@ -15,13 +15,13 @@
*/
package com.google.gwt.junit.client.impl;
-import com.google.gwt.user.client.rpc.IsSerializable;
+import java.io.Serializable;
/**
* A helper class for converting a generic {@link Throwable} into an Object that
* can be serialized for RPC.
*/
-public final class ExceptionWrapper implements IsSerializable {
+public final class ExceptionWrapper implements Serializable {
/**
* Corresponds to {@link Throwable#getCause()}.
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitHost.java b/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
index 2ccaa88..711b6da 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
@@ -16,9 +16,9 @@
package com.google.gwt.junit.client.impl;
import com.google.gwt.junit.client.TimeoutException;
-import com.google.gwt.user.client.rpc.IsSerializable;
import com.google.gwt.user.client.rpc.RemoteService;
+import java.io.Serializable;
import java.util.HashMap;
/**
@@ -28,11 +28,79 @@
public interface JUnitHost extends RemoteService {
/**
+ * Information about the client browser.
+ */
+ public static class ClientInfo implements Serializable {
+ /**
+ * This client's unique session id.
+ */
+ private int sessionId;
+
+ /**
+ * The GWT user.agent property of this client, e.g. "ie6", "safari", etc.
+ */
+ private String userAgent;
+
+ public ClientInfo(int sessionId, String userAgent) {
+ this.sessionId = sessionId;
+ this.userAgent = userAgent;
+ }
+
+ /**
+ * Constructor for serialization.
+ */
+ ClientInfo() {
+ }
+
+ public int getSessionId() {
+ return sessionId;
+ }
+
+ public String getUserAgent() {
+ return userAgent;
+ }
+ }
+
+ /**
+ * An initial response that sets the client session id.
+ */
+ public static class InitialResponse implements Serializable {
+ /**
+ * The unique client session id.
+ */
+ private int sessionId;
+
+ /**
+ * The first test block to run.
+ */
+ private TestBlock testBlock;
+
+ public InitialResponse(int sessionId, TestBlock testBlock) {
+ this.sessionId = sessionId;
+ this.testBlock = testBlock;
+ }
+
+ /**
+ * Constructor for serialization.
+ */
+ InitialResponse() {
+ }
+
+ public int getSessionId() {
+ return sessionId;
+ }
+
+ public TestBlock getTestBlock() {
+ return testBlock;
+ }
+ }
+
+ /**
* Returned from the server to tell the system what test to run next.
*/
- public static class TestBlock implements IsSerializable {
- private TestInfo[] tests;
+ public static class TestBlock implements Serializable {
private int index;
+ private TestInfo[] tests;
public TestBlock(TestInfo[] tests, int index) {
this.tests = tests;
@@ -57,7 +125,7 @@
/**
* Returned from the server to tell the system what test to run next.
*/
- public static class TestInfo implements IsSerializable {
+ public static class TestInfo implements Serializable {
private String testClass;
private String testMethod;
private String testModule;
@@ -112,11 +180,12 @@
* Gets a specific block of tests to run.
*
* @param blockIndex the index of the test block to retrieve
- * @param userAgent the user agent property of this client
- * @return the test block
+ * @param clientInfo the info for this client
+ * @return the initial response
* @throws TimeoutException if the wait for the next method times out.
*/
- TestBlock getTestBlock(int blockIndex, String userAgent) throws TimeoutException;
+ InitialResponse getTestBlock(int blockIndex, ClientInfo clientInfo)
+ throws TimeoutException;
/**
* Reports results for the last method run and gets the name of next method to
@@ -124,11 +193,11 @@
*
* @param results the results of executing the test
* @param blockIndex the index of the test block to retrieve
- * @param userAgent the user agent property of this client
+ * @param clientInfo the info for this client
* @return the next test block
* @throws TimeoutException if the wait for the next method times out.
*/
TestBlock reportResultsAndGetTestBlock(
- HashMap<TestInfo, JUnitResult> results, int blockIndex, String userAgent)
- throws TimeoutException;
+ HashMap<TestInfo, JUnitResult> results, int blockIndex,
+ ClientInfo clientInfo) throws TimeoutException;
}
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java b/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
index 88b7592..4700a85 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
@@ -15,6 +15,8 @@
*/
package com.google.gwt.junit.client.impl;
+import com.google.gwt.junit.client.impl.JUnitHost.ClientInfo;
+import com.google.gwt.junit.client.impl.JUnitHost.InitialResponse;
import com.google.gwt.junit.client.impl.JUnitHost.TestBlock;
import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -30,12 +32,11 @@
* Gets a specific block of tests to run.
*
* @param blockIndex the index of the test block to retrieve
- * @param userAgent the user agent property of this client
- * @param callBack the object that will receive the name of the next method to
- * run
+ * @param clientInfo the info for this client
+ * @param callBack the object that will receive the initial response
*/
- void getTestBlock(int blockIndex, String userAgent,
- AsyncCallback<TestBlock> callBack);
+ void getTestBlock(int blockIndex, ClientInfo clientInfo,
+ AsyncCallback<InitialResponse> callBack);
/**
* Reports results for the last method run and gets the name of next method to
@@ -43,10 +44,9 @@
*
* @param results the results of executing the test
* @param blockIndex the index of the test block to retrieve
- * @param userAgent the user agent property of this client
- * @param callBack the object that will receive the name of the next method to
- * run
+ * @param clientInfo the info for this client
+ * @param callBack the object that will receive the next test block
*/
void reportResultsAndGetTestBlock(HashMap<TestInfo, JUnitResult> results,
- int blockIndex, String userAgent, AsyncCallback<TestBlock> callBack);
+ int blockIndex, ClientInfo clientInfo, AsyncCallback<TestBlock> callBack);
}
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitResult.java b/user/src/com/google/gwt/junit/client/impl/JUnitResult.java
index 2f63e26..3918349 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitResult.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitResult.java
@@ -15,7 +15,7 @@
*/
package com.google.gwt.junit.client.impl;
-import com.google.gwt.user.client.rpc.IsSerializable;
+import java.io.Serializable;
/**
* Encapsulates the results of the execution of a single benchmark. A TestResult
@@ -28,7 +28,7 @@
* @see com.google.gwt.junit.JUnitMessageQueue
* @see com.google.gwt.junit.JUnitShell
*/
-public class JUnitResult implements IsSerializable {
+public class JUnitResult implements Serializable {
// Computed at the server, via HTTP header.
private transient String agent;
diff --git a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
index 7990a97..57063cc 100644
--- a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
+++ b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
@@ -18,6 +18,7 @@
import com.google.gwt.junit.JUnitFatalLaunchException;
import com.google.gwt.junit.JUnitMessageQueue;
import com.google.gwt.junit.JUnitShell;
+import com.google.gwt.junit.JUnitMessageQueue.ClientInfoExt;
import com.google.gwt.junit.client.TimeoutException;
import com.google.gwt.junit.client.impl.ExceptionWrapper;
import com.google.gwt.junit.client.impl.JUnitHost;
@@ -31,10 +32,9 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -57,7 +57,10 @@
*/
private static final int TIME_TO_WAIT_FOR_TESTNAME = 300000;
- private static final AtomicLong uniqueSessionId = new AtomicLong();
+ /**
+ * Monotonic increase counter to create unique client session ids.
+ */
+ private static final AtomicInteger uniqueSessionId = new AtomicInteger();
/**
* Tries to grab the GWTUnitTestShell sHost environment to communicate with
@@ -85,28 +88,32 @@
fld.set(obj, value);
}
- public TestBlock getTestBlock(int blockIndex, String userAgent)
+ public InitialResponse getTestBlock(int blockIndex, ClientInfo clientInfo)
throws TimeoutException {
- return getHost().getTestBlock(
- getClientId(getThreadLocalRequest(), getThreadLocalResponse()),
- getClientDesc(getThreadLocalRequest()), userAgent, blockIndex,
- TIME_TO_WAIT_FOR_TESTNAME);
+ ClientInfoExt clientInfoExt;
+ if (clientInfo.getSessionId() < 0) {
+ clientInfoExt = createNewClientInfo(clientInfo.getUserAgent());
+ } else {
+ clientInfoExt = createClientInfo(clientInfo);
+ }
+ TestBlock initialTestBlock = getHost().getTestBlock(clientInfoExt,
+ blockIndex, TIME_TO_WAIT_FOR_TESTNAME);
+ // Send back the updated session id.
+ return new InitialResponse(clientInfoExt.getSessionId(), initialTestBlock);
}
public TestBlock reportResultsAndGetTestBlock(
- HashMap<TestInfo, JUnitResult> results, int testBlock, String userAgent)
- throws TimeoutException {
+ HashMap<TestInfo, JUnitResult> results, int testBlock,
+ ClientInfo clientInfo) throws TimeoutException {
for (JUnitResult result : results.values()) {
initResult(getThreadLocalRequest(), result);
ExceptionWrapper ew = result.getExceptionWrapper();
result.setException(deserialize(ew));
}
JUnitMessageQueue host = getHost();
- String clientId = getClientId(getThreadLocalRequest(),
- getThreadLocalResponse());
- String clientDesc = getClientDesc(getThreadLocalRequest());
- host.reportResults(clientId, clientDesc, userAgent, results);
- return host.getTestBlock(clientId, clientDesc, userAgent, testBlock,
+ ClientInfoExt clientInfoExt = createClientInfo(clientInfo);
+ host.reportResults(clientInfoExt, results);
+ return host.getTestBlock(clientInfoExt, testBlock,
TIME_TO_WAIT_FOR_TESTNAME);
}
@@ -119,13 +126,27 @@
JUnitResult result = new JUnitResult();
initResult(request, result);
result.setException(new JUnitFatalLaunchException(requestPayload));
- getHost().reportFatalLaunch(getClientId(request, response),
- getClientDesc(request), null, result);
+ getHost().reportFatalLaunch(createNewClientInfo(null), result);
} else {
super.service(request, response);
}
}
+ private ClientInfoExt createClientInfo(ClientInfo clientInfo) {
+ assert (clientInfo.getSessionId() >= 0);
+ return new ClientInfoExt(clientInfo.getSessionId(),
+ clientInfo.getUserAgent(), getClientDesc(getThreadLocalRequest()));
+ }
+
+ private ClientInfoExt createNewClientInfo(String userAgent) {
+ return new ClientInfoExt(createSessionId(), userAgent,
+ getClientDesc(getThreadLocalRequest()));
+ }
+
+ private int createSessionId() {
+ return uniqueSessionId.getAndIncrement();
+ }
+
/**
* Deserializes an ExceptionWrapper back into a Throwable.
*/
@@ -232,30 +253,15 @@
return result;
}
+ /**
+ * Returns a client description for the current request.
+ */
private String getClientDesc(HttpServletRequest request) {
String machine = request.getRemoteHost();
String agent = request.getHeader("User-Agent");
return machine + " / " + agent;
}
- /**
- * Returns a "client id" for the current request.
- */
- private String getClientId(HttpServletRequest request,
- HttpServletResponse response) {
- Cookie[] cookies = request.getCookies();
- if (cookies != null) {
- for (Cookie cookie : cookies) {
- if ("gwt.junit.sessionCookie".equals(cookie.getName())) {
- return cookie.getValue();
- }
- }
- }
- String cookie = String.valueOf(uniqueSessionId.getAndIncrement());
- response.addCookie(new Cookie("gwt.junit.sessionCookie", cookie));
- return cookie;
- }
-
private void initResult(HttpServletRequest request, JUnitResult result) {
String agent = request.getHeader("User-Agent");
result.setAgent(agent);
diff --git a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
index c9eab71..bf3cb59 100644
--- a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
+++ b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
@@ -19,10 +19,11 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.UrlBuilder;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.junit.client.impl.JUnitHost.ClientInfo;
+import com.google.gwt.junit.client.impl.JUnitHost.InitialResponse;
import com.google.gwt.junit.client.impl.JUnitHost.TestBlock;
import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
@@ -40,11 +41,32 @@
*/
public abstract class GWTRunner implements EntryPoint {
+ private final class InitialResponseListener implements
+ AsyncCallback<InitialResponse> {
+
+ /**
+ * Delegate to the {@link TestBlockListener}.
+ */
+ public void onFailure(Throwable caught) {
+ testBlockListener.onFailure(caught);
+ }
+
+ /**
+ * Update our client info with the server-provided session id then delegate
+ * to the {@link TestBlockListener}.
+ */
+ public void onSuccess(InitialResponse result) {
+ clientInfo = new ClientInfo(result.getSessionId(),
+ clientInfo.getUserAgent());
+ testBlockListener.onSuccess(result.getTestBlock());
+ }
+ }
+
/**
* The RPC callback object for {@link GWTRunner#junitHost}. When
* {@link #onSuccess} is called, it's time to run the next test case.
*/
- private final class JUnitHostListener implements AsyncCallback<TestBlock> {
+ private final class TestBlockListener implements AsyncCallback<TestBlock> {
/**
* The number of times we've failed to communicate with the server on the
@@ -99,12 +121,12 @@
/**
* The singleton instance.
*/
- private static GWTRunner sInstance;
+ static GWTRunner sInstance;
/**
* A query param specifying my unique session cookie.
*/
- private static final String SESSIONCOOKIE_QUERY_PARAM = "gwt.junit.sessionCookie";
+ private static final String SESSIONID_QUERY_PARAM = "gwt.junit.sessionId";
/**
* A query param specifying the test class to run, for serverless mode.
@@ -132,6 +154,11 @@
}
/**
+ * This client's info.
+ */
+ private ClientInfo clientInfo;
+
+ /**
* The current block of tests to execute.
*/
private TestBlock currentBlock;
@@ -157,9 +184,14 @@
private final JUnitHostAsync junitHost = (JUnitHostAsync) GWT.create(JUnitHost.class);
/**
- * Handles all RPC responses.
+ * Handles all {@link InitialResponse InitialResponses}.
*/
- private final JUnitHostListener junitHostListener = new JUnitHostListener();
+ private final InitialResponseListener initialResponseListener = new InitialResponseListener();
+
+ /**
+ * Handles all {@link TestBlock TestBlocks}.
+ */
+ private final TestBlockListener testBlockListener = new TestBlockListener();
/**
* The maximum number of times to retry communication with the server per
@@ -187,12 +219,8 @@
}
public void onModuleLoad() {
- // Try to import a session cookie from the previous module.
- String value = Window.Location.getParameter(SESSIONCOOKIE_QUERY_PARAM);
- if (value != null) {
- Cookies.setCookie(SESSIONCOOKIE_QUERY_PARAM, value);
- }
-
+ clientInfo = new ClientInfo(parseQueryParamInteger(
+ SESSIONID_QUERY_PARAM, -1), getUserAgentProperty());
maxRetryCount = parseQueryParamInteger(RETRYCOUNT_QUERY_PARAM, -1);
currentBlock = checkForQueryParamTestToRun();
if (currentBlock != null) {
@@ -278,10 +306,10 @@
builder.setParameter(BLOCKINDEX_QUERY_PARAM,
Integer.toString(currentBlock.getIndex())).setPath(
newModule + pathSuffix);
- // Hand off the session cookie to the next module.
- String sessionCookie = Cookies.getCookie(SESSIONCOOKIE_QUERY_PARAM);
- if (sessionCookie != null) {
- builder.setParameter(SESSIONCOOKIE_QUERY_PARAM, sessionCookie);
+ // Hand off the session id to the next module.
+ if (clientInfo.getSessionId() >= 0) {
+ builder.setParameter(SESSIONID_QUERY_PARAM,
+ String.valueOf(clientInfo.getSessionId()));
}
Window.Location.replace(builder.buildString());
currentBlock = null;
@@ -348,12 +376,11 @@
private void syncToServer() {
if (currentBlock == null) {
int firstBlockIndex = parseQueryParamInteger(BLOCKINDEX_QUERY_PARAM, 0);
- junitHost.getTestBlock(firstBlockIndex, getUserAgentProperty(),
- junitHostListener);
+ junitHost.getTestBlock(firstBlockIndex, clientInfo,
+ initialResponseListener);
} else {
junitHost.reportResultsAndGetTestBlock(currentResults,
- currentBlock.getIndex() + 1, getUserAgentProperty(),
- junitHostListener);
+ currentBlock.getIndex() + 1, clientInfo, testBlockListener);
}
}
diff --git a/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java b/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java
index 1579d0e..2428df8 100644
--- a/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java
+++ b/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java
@@ -16,6 +16,7 @@
package com.google.gwt.junit;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.junit.JUnitMessageQueue.ClientInfoExt;
import com.google.gwt.junit.JUnitMessageQueue.ClientStatus;
import com.google.gwt.junit.client.impl.JUnitResult;
import com.google.gwt.junit.client.impl.JUnitHost.TestBlock;
@@ -24,7 +25,9 @@
import junit.framework.TestCase;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -91,25 +94,25 @@
// Add some clients in a few ways.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
- queue.reportFatalLaunch("client1", "desc1", "gecko", null);
- queue.reportResults("client2", "desc2", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(1, "gecko"), null);
+ queue.reportResults(createClientInfo(2, "safari"), createTestResults(0));
assertEquals(3, queue.getNumConnectedClients());
}
// Add duplicate clients.
{
- queue.getTestBlock("client3", "desc3", "ie6", 0, timeout);
- queue.reportFatalLaunch("client3", "desc3", "ie6", null);
- queue.reportResults("client4", "desc3", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(3, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(3, "ie6"), null);
+ queue.reportResults(createClientInfo(4, "safari"), createTestResults(0));
assertEquals(5, queue.getNumConnectedClients());
}
// Add existing clients.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
- queue.reportFatalLaunch("client1", "desc1", "gecko", null);
- queue.reportResults("client2", "desc2", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(1, "gecko"), null);
+ queue.reportResults(createClientInfo(2, "safari"), createTestResults(0));
assertEquals(5, queue.getNumConnectedClients());
}
}
@@ -134,7 +137,7 @@
// First client retrieves the first test block.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
assertEquals(1, queue.getNumClientsRetrievedTest(test0_0));
assertEquals(1, queue.getNumClientsRetrievedTest(test0_1));
assertEquals(1, queue.getNumClientsRetrievedTest(test0_2));
@@ -145,7 +148,7 @@
// Second client retrieves the first test block.
{
- queue.getTestBlock("client1", "desc1", "ie6", 0, timeout);
+ queue.getTestBlock(createClientInfo(1, "ie6"), 0, timeout);
assertEquals(2, queue.getNumClientsRetrievedTest(test0_0));
assertEquals(2, queue.getNumClientsRetrievedTest(test0_1));
assertEquals(2, queue.getNumClientsRetrievedTest(test0_2));
@@ -156,7 +159,7 @@
// First client retrieves the second test block.
{
- queue.getTestBlock("client0", "desc0", "ie6", 1, timeout);
+ queue.getTestBlock(createClientInfo(0, "ie6"), 1, timeout);
assertEquals(2, queue.getNumClientsRetrievedTest(test0_0));
assertEquals(2, queue.getNumClientsRetrievedTest(test0_1));
assertEquals(2, queue.getNumClientsRetrievedTest(test0_2));
@@ -167,7 +170,7 @@
// First client retrieves the second test block again.
{
- queue.getTestBlock("client0", "desc0", "ie6", 1, timeout);
+ queue.getTestBlock(createClientInfo(0, "ie6"), 1, timeout);
assertEquals(2, queue.getNumClientsRetrievedTest(test0_0));
assertEquals(2, queue.getNumClientsRetrievedTest(test0_1));
assertEquals(2, queue.getNumClientsRetrievedTest(test0_2));
@@ -194,21 +197,21 @@
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_0, result0);
- queue.reportResults("client0", "desc0", "ie6", results);
+ queue.reportResults(createClientInfo(0, "ie6"), results);
}
// Client 1 reports results for first test case.
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_0, result1);
- queue.reportResults("client1", "desc1", "ie6", results);
+ queue.reportResults(createClientInfo(1, "ie6"), results);
}
// Client 2 reports results for first test case.
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_0, result2);
- queue.reportResults("client2", "desc2", "ie6", results);
+ queue.reportResults(createClientInfo(2, "ie6"), results);
}
// Get the results
@@ -217,14 +220,19 @@
for (Entry<ClientStatus, JUnitResult> entry : results.entrySet()) {
ClientStatus client = entry.getKey();
JUnitResult result = entry.getValue();
- if ("client0".equals(client.clientId)) {
- assertEquals(result0, result);
- } else if ("client1".equals(client.clientId)) {
- assertEquals(result1, result);
- } else if ("client2".equals(client.clientId)) {
- assertEquals(result2, result);
- } else {
- fail("Unexpected client");
+ switch (client.getId()) {
+ case 0:
+ assertEquals(result0, result);
+ break;
+ case 1:
+ assertEquals(result1, result);
+ break;
+ case 2:
+ assertEquals(result2, result);
+ break;
+ default:
+ fail("Unexpected client");
+ break;
}
}
}
@@ -237,7 +245,7 @@
// Get the first test block.
{
- TestBlock block = queue.getTestBlock("client0", "desc0", "ie6", 0,
+ TestBlock block = queue.getTestBlock(createClientInfo(0, "ie6"), 0,
timeout);
assertEquals(testBlock0, block.getTests());
assertEquals(0, block.getIndex());
@@ -245,7 +253,7 @@
// Get the second test block.
{
- TestBlock block = queue.getTestBlock("client0", "desc0", "ie6", 1,
+ TestBlock block = queue.getTestBlock(createClientInfo(0, "ie6"), 1,
timeout);
assertEquals(testBlock1, block.getTests());
assertEquals(1, block.getIndex());
@@ -253,7 +261,7 @@
// Get the third test block.
{
- assertNull(queue.getTestBlock("client0", "desc0", "ie6", 2, timeout));
+ assertNull(queue.getTestBlock(createClientInfo(0, "ie6"), 2, timeout));
}
}
@@ -264,28 +272,28 @@
// Add some clients in a few ways.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
- queue.reportFatalLaunch("client1", "desc1", "gecko", null);
- queue.reportResults("client2", "desc2", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(1, "gecko"), null);
+ queue.reportResults(createClientInfo(2, "safari"), createTestResults(0));
assertSimilar(new String[] {"ie6", "gecko", "safari"},
queue.getUserAgents());
}
// Add duplicate clients.
{
- queue.getTestBlock("client3", "desc3", "ie7", 0, timeout);
- queue.reportFatalLaunch("client3", "desc3", "ie7", null);
- queue.reportResults("client4", "desc4", "gecko1_8", createTestResults(0));
- queue.getTestBlock("client3", "desc3", "ie7", 0, timeout);
+ queue.getTestBlock(createClientInfo(3, "ie7"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(3, "ie7"), null);
+ queue.reportResults(createClientInfo(4, "gecko1_8"), createTestResults(0));
+ queue.getTestBlock(createClientInfo(3, "ie7"), 0, timeout);
assertSimilar(new String[] {"ie6", "ie7", "gecko", "gecko1_8", "safari"},
queue.getUserAgents());
}
// Add existing clients.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
- queue.reportFatalLaunch("client1", "desc1", "gecko", null);
- queue.reportResults("client2", "desc2", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(1, "gecko"), null);
+ queue.reportResults(createClientInfo(2, "safari"), createTestResults(0));
assertSimilar(new String[] {"ie6", "ie7", "gecko", "gecko1_8", "safari"},
queue.getUserAgents());
}
@@ -312,7 +320,7 @@
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_0, new JUnitResult());
- queue.reportResults("client0", "desc0", "ie6", results);
+ queue.reportResults(createClientInfo(0, "ie6"), results);
assertFalse(queue.hasResults(test0_0));
assertFalse(queue.hasResults(test0_1));
assertFalse(queue.hasResults(test0_2));
@@ -325,7 +333,7 @@
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_0, new JUnitResult());
- queue.reportResults("client1", "desc1", "ie6", results);
+ queue.reportResults(createClientInfo(1, "ie6"), results);
assertFalse(queue.hasResults(test0_0));
assertFalse(queue.hasResults(test0_1));
assertFalse(queue.hasResults(test0_2));
@@ -338,7 +346,7 @@
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_1, new JUnitResult());
- queue.reportResults("client0", "desc0", "ie6", results);
+ queue.reportResults(createClientInfo(0, "ie6"), results);
assertFalse(queue.hasResults(test0_0));
assertFalse(queue.hasResults(test0_1));
assertFalse(queue.hasResults(test0_2));
@@ -351,7 +359,7 @@
{
Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
results.put(test0_0, new JUnitResult());
- queue.reportResults("client2", "desc2", "ie6", results);
+ queue.reportResults(createClientInfo(2, "ie6"), results);
assertTrue(queue.hasResults(test0_0));
assertFalse(queue.hasResults(test0_1));
assertFalse(queue.hasResults(test0_2));
@@ -370,12 +378,12 @@
JUnitResult junitResult = new JUnitResult();
junitResult.setException(new UnableToCompleteException());
results.put(testInfo, junitResult);
- queue.reportResults("client0", "desc0", "ie6", results);
+ queue.reportResults(createClientInfo(0, "ie6"), results);
results = new HashMap<TestInfo, JUnitResult>();
junitResult = new JUnitResult();
junitResult.setException(new JUnitFatalLaunchException());
results.put(testInfo, junitResult);
- queue.reportResults("client1", "desc1", "ff3",
+ queue.reportResults(createClientInfo(1, "ff3"),
createTestResults(ONE_TEST_PER_BLOCK));
assertTrue(queue.needsRerunning(testInfo));
@@ -385,8 +393,8 @@
junitResult = new JUnitResult();
junitResult.setException(new JUnitFatalLaunchException());
results.put(testInfo, junitResult);
- queue.reportResults("client0", "desc0", "ie6", results);
- queue.reportResults("client1", "desc1", "ff3",
+ queue.reportResults(createClientInfo(0, "ie6"), results);
+ queue.reportResults(createClientInfo(1, "ff3"),
createTestResults(ONE_TEST_PER_BLOCK));
assertFalse(queue.needsRerunning(testInfo));
}
@@ -398,11 +406,11 @@
// incomplete results
assertTrue(queue.needsRerunning(testInfo));
- queue.reportResults("client0", "desc0", "ff3", createTestResults(1));
+ queue.reportResults(createClientInfo(0, "ff3"), createTestResults(1));
assertTrue(queue.needsRerunning(testInfo));
// complete results
- queue.reportResults("client1", "desc1", "ie7", createTestResults(1));
+ queue.reportResults(createClientInfo(1, "ie7"), createTestResults(1));
assertFalse(queue.needsRerunning(testInfo));
}
@@ -413,9 +421,9 @@
// Add some clients in a few ways.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
- queue.reportFatalLaunch("client1", "desc1", "gecko", null);
- queue.reportResults("client2", "desc2", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(1, "gecko"), null);
+ queue.reportResults(createClientInfo(2, "safari"), createTestResults(0));
assertSimilar(new String[] {"desc0", "desc1", "desc2"},
queue.getNewClients());
assertEquals(0, queue.getNewClients().length);
@@ -423,19 +431,19 @@
// Add duplicate clients.
{
- queue.getTestBlock("client3", "desc3", "ie6", 0, timeout);
- queue.reportFatalLaunch("client3", "desc3", "ie6", null);
- queue.reportResults("client4", "desc4", "safari", createTestResults(0));
- queue.getTestBlock("client3", "desc3", "ie6", 0, timeout);
+ queue.getTestBlock(createClientInfo(3, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(3, "ie6"), null);
+ queue.reportResults(createClientInfo(4, "safari"), createTestResults(0));
+ queue.getTestBlock(createClientInfo(3, "ie6"), 0, timeout);
assertSimilar(new String[] {"desc3", "desc4"}, queue.getNewClients());
assertEquals(0, queue.getNewClients().length);
}
// Add existing clients.
{
- queue.getTestBlock("client0", "desc0", "ie6", 0, timeout);
- queue.reportFatalLaunch("client1", "desc1", "gecko", null);
- queue.reportResults("client2", "desc2", "safari", createTestResults(0));
+ queue.getTestBlock(createClientInfo(0, "ie6"), 0, timeout);
+ queue.reportFatalLaunch(createClientInfo(1, "gecko"), null);
+ queue.reportResults(createClientInfo(2, "safari"), createTestResults(0));
assertEquals(0, queue.getNewClients().length);
}
}
@@ -446,10 +454,10 @@
TestInfo testInfo = queue.getTestBlocks().get(0)[0];
assertFalse(queue.hasResults(testInfo));
- queue.reportResults("client0", "desc0", "ie6",
+ queue.reportResults(createClientInfo(0, "ie6"),
createTestResults(ONE_TEST_PER_BLOCK));
assertFalse(queue.hasResults(testInfo));
- queue.reportResults("client1", "desc1", "ff3",
+ queue.reportResults(createClientInfo(1, "ff3"),
createTestResults(ONE_TEST_PER_BLOCK));
assertTrue(queue.hasResults(testInfo));
@@ -465,7 +473,7 @@
JUnitResult junitResult = new JUnitResult();
junitResult.setException(new AssertionError());
results.put(testInfo, junitResult);
- queue.reportResults("client0", "desc0", "ff3", results);
+ queue.reportResults(createClientInfo(0, "ff3"), results);
assertTrue(queue.needsRerunning(testInfo));
Map<ClientStatus, JUnitResult> queueResults = queue.getResults(testInfo);
assertEquals(1, queueResults.size());
@@ -475,9 +483,9 @@
queue.removeResults(testInfo);
- queue.reportResults("client0", "desc0", "ff3",
+ queue.reportResults(createClientInfo(0, "ff3"),
createTestResults(ONE_TEST_PER_BLOCK));
- queue.reportResults("client1", "desc1", "ie6",
+ queue.reportResults(createClientInfo(1, "ie6"),
createTestResults(ONE_TEST_PER_BLOCK));
assertFalse(queue.needsRerunning(testInfo));
// check that the updated result appears now.
@@ -496,17 +504,12 @@
* @param actual the actual array
*/
private void assertSimilar(String[] expected, String[] actual) {
- assertEquals(expected.length, actual.length);
- for (int i = 0; i < expected.length; i++) {
- String expectedItem = expected[i];
- boolean matched = false;
- for (int j = 0; j < actual.length; j++) {
- if (expectedItem == actual[j]) {
- matched = true;
- }
- }
- assertTrue(matched);
- }
+ assertEquals(new HashSet<String>(Arrays.asList(expected)),
+ new HashSet<String>(Arrays.asList(actual)));
+ }
+
+ private ClientInfoExt createClientInfo(int sessionId, String userAgent) {
+ return new ClientInfoExt(sessionId, userAgent, "desc" + sessionId);
}
/**