@Test
  public void itLogsServerErrors() throws Exception {
    header.setRcode(Rcode.REFUSED);

    Name name = Name.fromString("John Wayne.");
    Record question = Record.newRecord(name, 65530, 43210);

    Message query = Message.newQuery(question);

    Message response = mock(Message.class);
    when(response.getHeader()).thenReturn(header);
    when(response.getSectionArray(Section.ANSWER)).thenReturn(null);
    when(response.getQuestion()).thenReturn(question);

    when(nameServer.query(
            any(Message.class), any(InetAddress.class), any(DNSAccessRecord.Builder.class)))
        .thenThrow(new RuntimeException("Aw snap!"));

    FakeAbstractProtocol abstractProtocol = new FakeAbstractProtocol(client, query.toWire());
    abstractProtocol.setNameServer(nameServer);
    abstractProtocol.run();

    verify(accessLogger)
        .info(
            "144140678.000 qtype=DNS chi=192.168.23.45 ttms=345.123 xn=65535 fqdn=John\\032Wayne. type=TYPE65530 class=CLASS43210 rcode=SERVFAIL rtype=- rloc=\"-\" rdtl=- rerr=\"Server Error:RuntimeException:Aw snap!\" ttl=\"-\" ans=\"-\"");
  }
  @Before
  public void before() throws Exception {
    // force the xn field in the request
    Random random = mock(Random.class);
    Mockito.when(random.nextInt(0xffff)).thenReturn(65535);
    whenNew(Random.class).withNoArguments().thenReturn(random);

    mockStatic(System.class);
    when(System.currentTimeMillis()).thenReturn(144140678000L).thenReturn(144140678345L);
    when(System.nanoTime()).thenReturn(100000000L, 100000000L + 345123000L);

    mockStatic(Logger.class);
    when(Logger.getLogger("com.comcast.cdn.traffic_control.traffic_router.core.access"))
        .thenReturn(accessLogger);

    header = new Header();
    header.setID(65535);
    header.setFlag(Flags.QR);

    client = Inet4Address.getByAddress(new byte[] {(byte) 192, (byte) 168, 23, 45});
    nameServer = mock(NameServer.class);
  }
  @Test
  public void itLogsARecordQueries() throws Exception {
    header.setRcode(Rcode.NOERROR);

    Name name = Name.fromString("www.example.com.");
    Record question = Record.newRecord(name, Type.A, DClass.IN, 0L);
    Message query = Message.newQuery(question);

    query.getHeader().getRcode();

    byte[] queryBytes = query.toWire();

    whenNew(Message.class).withArguments(queryBytes).thenReturn(query);

    InetAddress resolvedAddress = Inet4Address.getByName("192.168.8.9");

    Record answer = new ARecord(name, DClass.IN, 3600L, resolvedAddress);
    Record[] answers = new Record[] {answer};

    Message response = mock(Message.class);
    when(response.getHeader()).thenReturn(header);
    when(response.getSectionArray(Section.ANSWER)).thenReturn(answers);
    when(response.getQuestion()).thenReturn(question);

    InetAddress client = Inet4Address.getByName("192.168.23.45");
    when(nameServer.query(
            any(Message.class), any(InetAddress.class), any(DNSAccessRecord.Builder.class)))
        .thenReturn(response);

    FakeAbstractProtocol abstractProtocol = new FakeAbstractProtocol(client, queryBytes);
    abstractProtocol.setNameServer(nameServer);

    abstractProtocol.run();

    verify(accessLogger)
        .info(
            "144140678.000 qtype=DNS chi=192.168.23.45 ttms=345.123 xn=65535 fqdn=www.example.com. type=A class=IN rcode=NOERROR rtype=- rloc=\"-\" rdtl=- rerr=\"-\" ttl=\"3600\" ans=\"192.168.8.9\"");
  }