package net.windwards.dnsfrontend.frontend;
import junit.framework.Assert;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.windwards.dnsfrontend.api.Backend;
import net.windwards.dnsfrontend.api.BackendRepository;
import net.windwards.dnsfrontend.util.TestUtils;
import net.windwards.dnsfrontend.util.TestingBackend;
import org.junit.Test;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.Rcode;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class TestTaskKeeperImpl {
private class TaskKeeperImplWrapped extends TaskKeeperImpl {
public TaskKeeperImplWrapped(Ehcache cache) {
super(cache);
}
public Map<String, FuturePackage> getFutures() {
return this.futures;
}
}
@Test
public void unknownInsertIntoCache() throws Exception {
Ehcache cache = TestUtils.getEhcache();
TaskKeeperImplWrapped keeper = new TaskKeeperImplWrapped(cache);
keeper.setExpireTime(10);
keeper.setBackendRepository(new BackendRepository() {
@Override
public Backend lookup(int type) {
return new TestingBackend();
}
@Override public void stop() { }
});
keeper.start();
// Don't explode, plz
keeper.replyArrived(cache, new Element(new Name("foo."), TestUtils.getReplyRecord()));
}
@Test
public void replyArrivesInTime() throws Exception {
Ehcache cache = TestUtils.getEhcache();
TaskKeeperImplWrapped keeper = new TaskKeeperImplWrapped(cache);
keeper.setExpireTime(10);
keeper.setBackendRepository(new BackendRepository() {
@Override
public Backend lookup(int type) {
return new TestingBackend();
}
@Override public void stop() { }
});
keeper.start();
LinkedList<Message> replies = new LinkedList<Message>();
Query query = TestUtils.getQuery(replies);
ResolveTask task = new ResolveTask(query) {
@Override
public void run() {
try {
this.query.interpret();
this.ident = "A:foo.example.com.";
} catch (IOException ignored) {}
}
};
task.run();
keeper.keep(task);
Assert.assertNotNull(keeper.getFutures().get(task.getIdent()));
Thread.sleep(5);
keeper.replyArrived(cache, new Element(task.getIdent(), TestUtils.getReplyRecord()));
Assert.assertEquals(0, keeper.getFutures().size());
Assert.assertEquals(1, replies.size());
Assert.assertEquals(Rcode.NOERROR, replies.get(0).getRcode());
}
@Test
public void replyArrivesLate() throws Exception {
Ehcache cache = TestUtils.getEhcache();
TaskKeeperImplWrapped keeper = new TaskKeeperImplWrapped(cache);
keeper.setExpireTime(10);
keeper.setBackendRepository(new BackendRepository() {
@Override
public Backend lookup(int type) {
return new TestingBackend();
}
@Override public void stop() {}
});
keeper.start();
List<Message> replies = new LinkedList<Message>();
Query query = TestUtils.getQuery(replies);
ResolveTask task = new ResolveTask(query) {
@Override
public void run() {
try {
this.query.interpret();
this.ident = "A:foo.example.com.";
} catch (IOException ignored) {}
}
};
task.run();
keeper.keep(task);
Thread.sleep(15);
keeper.replyArrived(cache, new Element(task.getIdent(), TestUtils.getReplyRecord()));
Assert.assertEquals(0, keeper.getFutures().size());
Assert.assertEquals(1, replies.size());
Assert.assertEquals(Rcode.NXDOMAIN, replies.get(0).getRcode());
}
@Test
public void replyDoesNotArrive() throws Exception {
Ehcache cache = TestUtils.getEhcache();
TaskKeeperImplWrapped keeper = new TaskKeeperImplWrapped(cache);
keeper.setExpireTime(10);
keeper.setBackendRepository(new BackendRepository() {
@Override
public Backend lookup(int type) {
return new TestingBackend();
}
@Override public void stop() {};
});
keeper.start();
List<Message> replies = new LinkedList<Message>();
Query query = TestUtils.getQuery(replies);
ResolveTask task = new ResolveTask(query) {
@Override
public void run() {
try {
this.query.interpret();
this.ident = "foo.example.com.";
} catch (IOException ignored) {}
}
};
task.run();
keeper.keep(task);
Thread.sleep(15);
Assert.assertEquals(0, keeper.getFutures().size());
Assert.assertEquals(1, replies.size());
Assert.assertEquals(Rcode.NXDOMAIN, replies.remove(0).getRcode());
// Result should now be cached
Assert.assertNotNull(cache.get(task.getIdent()));
}
}