package net.sf.jdistunit.daemon;
import java.io.IOException;
import java.util.List;
import junit.framework.TestCase;
import net.sf.agentopia.util.OS;
import net.sf.agentopia.util.net.HostId;
import net.sf.jdistunit.platform.agent.ITestBox;
import net.sf.jdistunit.platform.agent.JDistUnitAgent;
import net.sf.jdistunit.platform.agent.TestBox;
/**
* An example test case using two previously started external servers.
*
* @author <a href="mailto:kain@land-of-kain.de">Kai Ruhl</a>
* @since 21 Oct 2009
*/
public class JDistUnitExampleTest extends TestCase {
/** External servers. Start before running the test case. */
public static String[] servers = {"ginko.vpn:15907", "eva.vpn:15907"};
/** The JDistUnit test box. */
private ITestBox testBox;
/**
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
// Create a new test box and connect to all servers.
testBox = new TestBox(new HostId("ginko.vpn:15900"));
for (String serverId : servers) {
final HostId hostId = new HostId(serverId);
testBox.connectToNetwork(hostId);
}
// Check that the home id is stringent.
final HostId homeId = testBox.getHomeId();
assertNotSame("localhost", homeId.getHostBasicName());
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
// Shut down test box.
if (null != testBox) {
testBox.shutdown();
testBox = null;
}
// Wait for ports to be freed by OS.
OS.sleep(2000);
}
/**
* Starts a home page test, but does not assess any results. After this
* method finishes, the agents have returned (hopefully!).
* <p>
* The method uses the test box created in the <code>setUp()</code> method,
* in conjunction with a test case in the form of a mobile agent (a custom
* written <code>HomepageTestAgent</code>, which is a subclass of
* <code>JDistUnitAgent</code>).
*
* @param requestCount The number of parallel requests to be started.
* @param timeOut The timeout (in milliseconds) after which the request is
* considered to be failed.
* @param threadTimeStep The time step between "parallel" thread starts.
* @throws IOException If any homepage access error occured.
*/
private void startHomePageTest(int requestCount, long timeOut, long threadTimeStep) throws IOException {
// Create agent (which includes the test action).
final JDistUnitAgent agent = new HomepageTestAgent();
agent.setRequestCount(requestCount);
agent.setTimeOut(timeOut);
// Set the test actions to be not quite as parallel, instead
// introducing a small pause. This is necessary because most web
// servers will reject DOS-attack like access patterns.
agent.setThreadTimeStep(threadTimeStep);
// Deploy the agent to the test box.
testBox.deployTestAgents(agent);
// Wait for result (maximum: 1 minute).
testBox.waitForResults(1);
}
/**
* Load tests access to a homepage.
* <p>
* Just 2 requests per host (started in 300 ms succession) are to be
* fulfilled within 30 seconds.
*
* @throws Exception If something failed.
*/
public void testHomepageLoad() throws Exception {
final int serverCount = servers.length;
final int requestCount = 2;
// Start load test.
startHomePageTest(requestCount, 30000L, 300L);
// Check that all agents returned.
final int returnedAgentCount = testBox.getReturnedAgentCount();
assertEquals(serverCount, returnedAgentCount);
// Make sure that all requests were run.
final int successCount = testBox.getNumberOfSuccesses();
final int failureCount = testBox.getNumberOfFailures();
final int starveCount = testBox.getNumberOfStarvations();
System.err.println(serverCount + " x " + requestCount + " requests = " + testBox.getNumberOfSuccesses() + " successes, " + testBox.getNumberOfFailures() + " failures, " + starveCount + " starvations.");
assertEquals(serverCount * requestCount, successCount + failureCount + starveCount);
// No exceptions should have occured.
List<Throwable> errorList = testBox.getErrorList();
assertNotNull(errorList);
if (!errorList.isEmpty()) {
errorList.get(0).printStackTrace();
OS.sleep(500);
}
assertTrue(errorList.isEmpty());
// Assess results (part 1: stress).
// I expect that all tests complete successfully.
assertEquals(0, failureCount);
assertEquals(0, starveCount);
assertEquals(serverCount * requestCount, successCount);
// Assess results (part 2: load).
// I expect that the average access time is below 5 seconds.
final long averageAccessTime = testBox.getPerformanceAverage();
assertTrue(averageAccessTime > 0);
assertTrue("Access time was to be < 2s, was " + averageAccessTime + " millis.", averageAccessTime < 2000);
}
/**
* Stress tests access to a homepage.
* <p>
* 1000 requests per host (started in 1 ms succession) are to be fulfilled
* within 10 seconds. This should definitely be too much stress for the poor
* webserver.
*
* @throws Exception If something failed.
*/
public void testHomepageStress() throws Exception {
final int serverCount = servers.length;
final int requestCount = 1000;
// Start load test.
startHomePageTest(requestCount, 10000L, 1L);
// Check that all agents returned.
final int returnedAgentCount = testBox.getReturnedAgentCount();
assertEquals(serverCount, returnedAgentCount);
// There should be at least some exceptions.
List<Throwable> errorList = testBox.getErrorList();
assertNotNull(errorList);
assertFalse(errorList.isEmpty());
// Make sure that all requests were run.
final int successCount = testBox.getNumberOfSuccesses();
final int failureCount = testBox.getNumberOfFailures();
final int starveCount = testBox.getNumberOfStarvations();
System.err.println(serverCount + " x " + requestCount + " requests = " + testBox.getNumberOfSuccesses() + " successes, " + testBox.getNumberOfFailures() + " failures, " + starveCount + " starvations.");
assertEquals(serverCount * requestCount, successCount + failureCount + starveCount);
// Assess results (part 1: stress).
// I expect that many tests fail due to timeout.
assertTrue(successCount > 0);
assertTrue(failureCount > 0);
assertTrue(failureCount + starveCount > successCount);
// Assess results (part 2: load).
// I expect that the access time (for the succeeding threads) is pretty
// high, even when considering web server caching.
final long averageAccessTime = testBox.getPerformanceAverage();
assertTrue(averageAccessTime > 0);
assertTrue("Access time was to be > 5s, was " + averageAccessTime + " millis.", averageAccessTime > 5000);
}
}