package net.windwards.dnsfrontend.frontend;
import junit.framework.Assert;
import net.sf.ehcache.Ehcache;
import net.windwards.dnsfrontend.DNSFrontend;
import net.windwards.dnsfrontend.client.Client;
import net.windwards.dnsfrontend.client.Recipient;
import net.windwards.dnsfrontend.dialog.Request;
import net.windwards.dnsfrontend.dialog.Update;
import net.windwards.dnsfrontend.util.TestUtils;
import net.windwards.dnsfrontend.util.TestingConfiguration;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xbill.DNS.AAAARecord;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.DClass;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.Record;
import org.xbill.DNS.Section;
import org.xbill.DNS.Type;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class TestComplexSetup {
private TestingConfiguration conf1;
private TestingConfiguration conf2;
private Client client;
private DNSFrontend frontend1;
private DNSFrontend frontend2;
public static class TestingFrontend extends DNSFrontend {
@Override
protected void setupLogging() {
this.debug = true;
super.setupLogging();
}
@Override
protected Ehcache attachCache() {
return TestUtils.getEhcache();
}
}
@Before
public void setup() throws Exception {
conf1 = new TestingConfiguration("conf", "example.com.", 1800);
conf2 = new TestingConfiguration("conf", "example.com.", 1801);
conf2.setPort(Short.parseShort("5355"));
frontend1 = new TestingFrontend();
frontend1.setup(conf1);
frontend1.start();
frontend2 = new TestingFrontend();
frontend2.setup(conf2);
frontend2.start();
client = new Client() {
@Override
protected void log(String message) {
LoggerFactory.getLogger(TestComplexSetup.class).info(message);
}
};
client.connect();
}
@After
public void teardown() throws Exception{
client.disconnect();
frontend1.stop();
frontend2.stop();
}
@Test
public void test() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final Update update = new Update();
update.name = "foo";
update.family = "ipv4";
update.moniker = "conf";
update.address = "1.2.3.4";
client.addReceiver(new Recipient() {
@Override
public void receive(Request request) {
Logger logger = LoggerFactory.getLogger(TestComplexSetup.class);
try {
client.send(update);
logger.info("Sending update [update={}]", update);
} catch (Exception e) {
logger.error("Failed to send message", e);
return;
}
latch.countDown();
}
});
DatagramChannel channel1 = TestUtils.getDatagramChannel(conf1.getPort());
DatagramChannel channel2 = TestUtils.getDatagramChannel(conf2.getPort());
// Ask 2 for A rec
Message query = Message.newQuery(
Record.newRecord(new Name("foo.example.com."), Type.A, DClass.IN));
channel2.write(ByteBuffer.wrap(query.toWire()));
// Make sure only 2 replies
latch.await(2, TimeUnit.SECONDS);
Thread.sleep(100);
ByteBuffer buf = ByteBuffer.allocate(100);
channel2.read(buf);
Message message = new Message(buf.array());
Record answer = message.getSectionArray(Section.ANSWER)[0];
String addr = ((ARecord)answer).getAddress().getHostAddress();
Assert.assertEquals("1.2.3.4", addr);
Thread.sleep(50); // in case 1 is a bit slow
buf.clear();
int count = channel1.read(buf);
Assert.assertEquals(0, count); // There should be no noutput from 1
// Ask 1 for A rec
// Make sure it came from cache
update.address = "1.2.3.40"; // if our client is asked, would answer thus
channel1.write(ByteBuffer.wrap(query.toWire()));
Thread.sleep(50); // make sure our client would have time to answer
buf.clear();
channel1.read(buf);
message = new Message(buf.array());
answer = message.getSectionArray(Section.ANSWER)[0];
addr = ((ARecord)answer).getAddress().getHostAddress();
Assert.assertEquals("1.2.3.4", addr);
// Shut down frontend 2
// Make sure frontend 1 is still answering
frontend2.stop();
channel1.write(ByteBuffer.wrap(query.toWire()));
Thread.sleep(50); // make sure our client would have time to answer
buf.clear();
channel1.read(buf);
message = new Message(buf.array());
answer = message.getSectionArray(Section.ANSWER)[0];
addr = ((ARecord)answer).getAddress().getHostAddress();
Assert.assertEquals("1.2.3.4", addr);
// Start frontend 3
// Make sure frontend 3 can answer questions
}
}