@Test
public void testLoadReader() throws Exception {

    RuleDatabase db = new RuleDatabase();
    db.nextBlockedHosts = db.blockedHosts.get();
    Configuration.Item item = new Configuration.Item();
    item.location = "<some random file>";
    item.state = Configuration.Item.STATE_IGNORE;
    // Ignore. Does nothing
    assertTrue(db.loadReader(item, new StringReader("example.com")));
    assertTrue(db.isEmpty());
    assertFalse(db.isBlocked("example.com"));
    // Deny, the host should be blocked now.
    item.state = Configuration.Item.STATE_DENY;
    assertTrue(db.loadReader(item, new StringReader("example.com")));
    assertFalse(db.isEmpty());
    assertTrue(db.isBlocked("example.com"));
    // Reallow again, the entry should disappear.
    item.state = Configuration.Item.STATE_ALLOW;
    assertTrue(db.loadReader(item, new StringReader("example.com")));
    assertTrue(db.isEmpty());
    assertFalse(db.isBlocked("example.com"));
    // Check multiple lines
    item.state = Configuration.Item.STATE_DENY;
    assertFalse(db.isBlocked("example.com"));
    assertFalse(db.isBlocked("foo.com"));
    assertTrue(db.loadReader(item, new StringReader("example.com\n127.0.0.1 foo.com")));
    assertFalse(db.isEmpty());
    assertTrue(db.isBlocked("example.com"));
    assertTrue(db.isBlocked("foo.com"));
    // Interrupted test
    Thread.currentThread().interrupt();
    try {
        db.loadReader(item, new StringReader("example.com"));
        fail("Interrupted thread did not cause reader to be interrupted");
    } catch (InterruptedException e) {
    }
    // Test with an invalid line before a valid one.
    item.state = Configuration.Item.STATE_DENY;
    assertTrue(db.loadReader(item, new StringReader("invalid line\notherhost.com")));
    assertTrue(db.isBlocked("otherhost.com"));
    // Allow again
    item.state = Configuration.Item.STATE_ALLOW;
    assertTrue(db.loadReader(item, new StringReader("invalid line\notherhost.com")));
    assertFalse(db.isBlocked("otherhost.com"));
    // Reader can't read, we are aborting.
    Reader reader = Mockito.mock(Reader.class);
    doThrow(new IOException()).when(reader).read((char[]) any());
    doThrow(new IOException()).when(reader).read((char[]) any(), anyInt(), anyInt());
    doThrow(new IOException()).when(reader).read(any(CharBuffer.class));
    assertFalse(db.loadReader(item, reader));
}