package hudson;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.io.StringReader;
import java.io.IOException;
import java.net.SocketTimeoutException;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
/**
* @author Kohsuke Kawaguchi
*/
public class UDPBroadcastThreadTest {
@Rule public JenkinsRule j = new JenkinsRule();
/**
* Old unicast based clients should still be able to receive some reply,
* as we haven't changed the port.
*/
@Test public void legacy() throws Exception {
DatagramSocket s = new DatagramSocket();
sendQueryTo(s, InetAddress.getLocalHost());
s.setSoTimeout(15000); // to prevent test hang
try {
receiveAndVerify(s);
} catch (SocketTimeoutException x) {
Assume.assumeFalse(UDPBroadcastThread.udpHandlingProblem);
throw x;
}
}
/**
* Multicast based clients should be able to receive multiple replies.
*/
@Test public void multicast() throws Exception {
UDPBroadcastThread second = new UDPBroadcastThread(j.jenkins);
second.start();
UDPBroadcastThread third = new UDPBroadcastThread(j.jenkins);
third.start();
second.ready.block();
third.ready.block();
try {
DatagramSocket s = new DatagramSocket();
sendQueryTo(s, UDPBroadcastThread.MULTICAST);
s.setSoTimeout(15000); // to prevent test hang
// we should at least get two replies since we run two broadcasts
try {
receiveAndVerify(s);
receiveAndVerify(s);
} catch (SocketTimeoutException x) {
Assume.assumeFalse(UDPBroadcastThread.udpHandlingProblem);
throw x;
}
} finally {
third.interrupt();
second.interrupt();
}
}
private void sendQueryTo(DatagramSocket s, InetAddress dest) throws IOException {
DatagramPacket p = new DatagramPacket(new byte[1024],1024);
p.setAddress(dest);
p.setPort(UDPBroadcastThread.PORT);
s.send(p);
}
/**
* Reads a reply from the socket and makes sure its shape is in order.
*/
private void receiveAndVerify(DatagramSocket s) throws IOException, SAXException, ParserConfigurationException {
DatagramPacket p = new DatagramPacket(new byte[1024],1024);
s.receive(p);
String xml = new String(p.getData(), 0, p.getLength(), "UTF-8");
System.out.println(xml);
// make sure at least this XML parses
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.newSAXParser().parse(new InputSource(new StringReader(xml)),new DefaultHandler());
}
}