package test.wsdl.multithread;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.axis.AxisFault;
import org.apache.axis.components.logger.LogFactory;
import org.apache.commons.logging.Log;
import samples.addr.Address;
import samples.addr.AddressBook;
import samples.addr.AddressBookSOAPBindingStub;
import samples.addr.AddressBookServiceLocator;
import samples.addr.Phone;
import samples.addr.StateType;
import javax.xml.rpc.ServiceException;
import java.net.ConnectException;
/**
* This test calls the stub multiple times from multiple threads. Before the
* stub was made threadsafe, there was a good chance this test would fail with an
* IllegalStateException or "javax.xml.rpc.ServiceException: Number of parameters
* passed in (2) doesn't match the number of IN/INOUT parameters (4) from the
* addParameter() calls" or something else just as cryptic.
*/
public class MultithreadTestCase extends TestCase {
private static Log log =
LogFactory.getLog(MultithreadTestCase.class.getName());
private AddressBook binding;
private static int successCount = 0;
static synchronized void addSuccess()
{
successCount++;
}
public MultithreadTestCase(String name) {
super(name);
}
private String printAddress (Address ad) {
String out;
if (ad == null)
out = "\t[ADDRESS NOT FOUND!]";
else
out ="\t" + ad.getStreetNum () + " " + ad.getStreetName () + "\n\t" + ad.getCity () + ", " + ad.getState () + " " + ad.getZip () + "\n\t" + printPhone (ad.getPhoneNumber ());
return out;
} // printAddress
private String printPhone (Phone ph)
{
String out;
if (ph == null)
out = "[PHONE NUMBER NOT FOUND!]";
else
out ="Phone: (" + ph.getAreaCode () + ") " + ph.getExchange () + "-" + ph.getNumber ();
return out;
} // printPhone
private AssertionFailedError error = null;
private synchronized void setError(AssertionFailedError error) {
if (this.error == null) {
this.error = error;
}
} // setError
private static int var = 0;
public class Run implements Runnable {
public void run() {
try {
for (int i = 0; i < 4; ++i) {
Address address = new Address();
Phone phone = new Phone();
address.setStreetNum(var++);
address.setStreetName("2");
address.setCity("3");
address.setState(StateType.TX);
address.setZip(var++);
phone.setAreaCode(11);
phone.setExchange("22");
phone.setNumber("33");
address.setPhoneNumber(phone);
binding.addEntry("hi", address);
Address addressRet = binding.getAddressFromName("hi");
// succeeded, count it.
addSuccess();
}
} catch (Throwable t) {
// There are bound to be connection refused exceptions when the
// server socket is busy) in a multithreaded environment. I
// don't want to deal with those. Only grab exceptions that are
// likely to have something to do with bad AXIS runtime.
if (!(t instanceof AxisFault &&
((AxisFault) t).detail instanceof ConnectException)) {
// Log a stack trace as we may not be so lucky next time!
log.fatal("Throwable caught: ", t);
setError(new AssertionFailedError("Throwable caught: " + t));
}
}
} // run
} // class Run
public void testMultithreading() {
try {
binding = new AddressBookServiceLocator().getAddressBook();
}
catch (ServiceException jre) {
throw new AssertionFailedError("ServiceException caught: " + jre);
}
assertTrue("binding is null", binding != null);
((AddressBookSOAPBindingStub) binding).setMaintainSession(true);
int NUM_THREADS = 50;
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; ++i) {
threads[i] = new Thread(new Run());
threads[i].start();
}
for (int i = 0; i < NUM_THREADS; ++i) {
try {
threads[i].join();
}
catch (InterruptedException ie) {
}
}
System.out.println("Had " + successCount +
" successes (of a possible " +
(NUM_THREADS * 4) + ")");
if (error != null) {
throw error;
}
} // testMultithreading
public static void main(String[] args) {
MultithreadTestCase testCase = new MultithreadTestCase("MultithreadTestCase");
testCase.testMultithreading();
}
} // class MultithreadTestCase
|