blob: 8545b7903559d71b0fe20e1d665587e0863ba7dd [file] [log] [blame]
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.junit;
import java.util.HashMap;
import java.util.Map;
/**
* A message queue to pass data between {@link JUnitShell} and
* {@link com.google.gwt.junit.server.JUnitHostImpl} in a thread-safe manner.
*
* <p>
* The public methods are called by the servlet to find out what test to execute
* next, and to report the results of the last test to run.
* </p>
*
* <p>
* The protected methods are called by the shell to fetch test results and drive
* the next test the client should run.
* </p>
*/
public class JUnitMessageQueue {
/**
* Maps the name of a test class to the method that should be run. Access must
* be synchronized.
*/
private final Map nameMap = new HashMap();
/**
* Maps the name of a test class to the last results to be reported. Access
* must be synchronized.
*/
private final Map resultsMap = new HashMap();
/**
* Only instantiatable within this package.
*/
JUnitMessageQueue() {
}
/**
* Called by the servlet to query for for the next method to test.
*
* @param testClassName The name of the test class.
* @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 String getNextTestName(String testClassName, long timeout) {
synchronized (nameMap) {
long stopTime = System.currentTimeMillis() + timeout;
while (!nameMap.containsKey(testClassName)) {
long timeToWait = stopTime - System.currentTimeMillis();
if (timeToWait < 1) {
return null;
}
try {
nameMap.wait(timeToWait);
} catch (InterruptedException e) {
// just abort
return null;
}
}
return (String) nameMap.remove(testClassName);
}
}
/**
* Called by the servlet to report the results of the last test to run.
*
* @param testClassName The name of the test class.
* @param t The exception thrown by the last test, or <code>null</code> if
* the test completed without error.
*/
public void reportResults(String testClassName, Throwable t) {
synchronized (resultsMap) {
resultsMap.put(testClassName, t);
}
}
/**
* Called by the shell to fetch the results of a completed test.
*
* @param testClassName The name of the test class.
* @return An exception thrown from a failed test, or <code>null</code> if
* the test completed without error.
*/
Throwable getResult(String testClassName) {
synchronized (resultsMap) {
return (Throwable) resultsMap.remove(testClassName);
}
}
/**
* Called by the shell to see if the servlet has begun running the current
* test.
*
* @param testClassName
* @return <code>true</code> if the servlet has not yet fetched the next
* test name, otherwise <code>false</code>.
*/
boolean hasNextTestName(String testClassName) {
synchronized (nameMap) {
return nameMap.containsKey(testClassName);
}
}
/**
* Called by the shell to see if the currently-running test has completed.
*
* @param testClassName The name of the test class.
* @return If the test has completed, <code>true</code>, otherwise
* <code>false</code>.
*/
boolean hasResult(String testClassName) {
synchronized (resultsMap) {
return resultsMap.containsKey(testClassName);
}
}
/**
* 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.
*/
void setNextTestName(String testClassName, String testName) {
synchronized (nameMap) {
nameMap.put(testClassName, testName);
nameMap.notifyAll();
}
}
}