Cleanup Queue not being safely closed in QueueTest

Fixes #7063
This commit is contained in:
Armin 2017-05-18 19:29:55 +02:00 committed by Armin Braun
parent 64397c66e3
commit b7f4fd7ebf

View file

@ -38,17 +38,16 @@ public class QueueTest {
@Test @Test
public void newQueue() throws IOException { public void newQueue() throws IOException {
Queue q = new TestQueue(TestSettings.volatileQueueSettings(10)); try (Queue q = new TestQueue(TestSettings.volatileQueueSettings(10))) {
q.open(); q.open();
assertThat(q.nonBlockReadBatch(1), is(equalTo(null))); assertThat(q.nonBlockReadBatch(1), is(equalTo(null)));
}
q.close();
} }
@Test @Test
public void singleWriteRead() throws IOException { public void singleWriteRead() throws IOException {
Queue q = new TestQueue(TestSettings.volatileQueueSettings(100)); try (Queue q = new TestQueue(TestSettings.volatileQueueSettings(100))) {
q.open(); q.open();
Queueable element = new StringElement("foobarbaz"); Queueable element = new StringElement("foobarbaz");
@ -59,13 +58,12 @@ public class QueueTest {
assertThat(b.getElements().size(), is(equalTo(1))); assertThat(b.getElements().size(), is(equalTo(1)));
assertThat(b.getElements().get(0).toString(), is(equalTo(element.toString()))); assertThat(b.getElements().get(0).toString(), is(equalTo(element.toString())));
assertThat(q.nonBlockReadBatch(1), is(equalTo(null))); assertThat(q.nonBlockReadBatch(1), is(equalTo(null)));
}
q.close();
} }
@Test @Test
public void singleWriteMultiRead() throws IOException { public void singleWriteMultiRead() throws IOException {
Queue q = new TestQueue(TestSettings.volatileQueueSettings(100)); try (Queue q = new TestQueue(TestSettings.volatileQueueSettings(100))) {
q.open(); q.open();
Queueable element = new StringElement("foobarbaz"); Queueable element = new StringElement("foobarbaz");
@ -76,17 +74,17 @@ public class QueueTest {
assertThat(b.getElements().size(), is(equalTo(1))); assertThat(b.getElements().size(), is(equalTo(1)));
assertThat(b.getElements().get(0).toString(), is(equalTo(element.toString()))); assertThat(b.getElements().get(0).toString(), is(equalTo(element.toString())));
assertThat(q.nonBlockReadBatch(2), is(equalTo(null))); assertThat(q.nonBlockReadBatch(2), is(equalTo(null)));
}
q.close();
} }
@Test @Test
public void multiWriteSamePage() throws IOException { public void multiWriteSamePage() throws IOException {
Queue q = new TestQueue(TestSettings.volatileQueueSettings(100)); try (Queue q = new TestQueue(TestSettings.volatileQueueSettings(100))) {
q.open(); q.open();
List<Queueable> elements = Arrays
List<Queueable> elements = Arrays.asList(new StringElement("foobarbaz1"), new StringElement("foobarbaz2"), new StringElement("foobarbaz3")); .asList(new StringElement("foobarbaz1"), new StringElement("foobarbaz2"),
new StringElement("foobarbaz3")
);
for (Queueable e : elements) { for (Queueable e : elements) {
q.write(e); q.write(e);
} }
@ -101,16 +99,15 @@ public class QueueTest {
assertThat(b.getElements().size(), is(equalTo(1))); assertThat(b.getElements().size(), is(equalTo(1)));
assertThat(b.getElements().get(0).toString(), is(equalTo(elements.get(2).toString()))); assertThat(b.getElements().get(0).toString(), is(equalTo(elements.get(2).toString())));
}
q.close();
} }
@Test @Test
public void writeMultiPage() throws IOException { public void writeMultiPage() throws IOException {
List<Queueable> elements = Arrays.asList(new StringElement("foobarbaz1"), new StringElement("foobarbaz2"), new StringElement("foobarbaz3"), new StringElement("foobarbaz4")); List<Queueable> elements = Arrays.asList(new StringElement("foobarbaz1"), new StringElement("foobarbaz2"), new StringElement("foobarbaz3"), new StringElement("foobarbaz4"));
int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(elements.get(0).serialize().length); int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(elements.get(0).serialize().length);
try (TestQueue q = new TestQueue(
TestQueue q = new TestQueue(TestSettings.volatileQueueSettings(2 * singleElementCapacity)); TestSettings.volatileQueueSettings(2 * singleElementCapacity))) {
q.open(); q.open();
for (Queueable e : elements) { for (Queueable e : elements) {
@ -145,8 +142,7 @@ public class QueueTest {
b = q.nonBlockReadBatch(10); b = q.nonBlockReadBatch(10);
assertThat(b, is(equalTo(null))); assertThat(b, is(equalTo(null)));
}
q.close();
} }
@ -154,8 +150,8 @@ public class QueueTest {
public void writeMultiPageWithInOrderAcking() throws IOException { public void writeMultiPageWithInOrderAcking() throws IOException {
List<Queueable> elements = Arrays.asList(new StringElement("foobarbaz1"), new StringElement("foobarbaz2"), new StringElement("foobarbaz3"), new StringElement("foobarbaz4")); List<Queueable> elements = Arrays.asList(new StringElement("foobarbaz1"), new StringElement("foobarbaz2"), new StringElement("foobarbaz3"), new StringElement("foobarbaz4"));
int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(elements.get(0).serialize().length); int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(elements.get(0).serialize().length);
try (TestQueue q = new TestQueue(
TestQueue q = new TestQueue(TestSettings.volatileQueueSettings(2 * singleElementCapacity)); TestSettings.volatileQueueSettings(2 * singleElementCapacity))) {
q.open(); q.open();
for (Queueable e : elements) { for (Queueable e : elements) {
@ -188,8 +184,7 @@ public class QueueTest {
b.close(); b.close();
assertThat(q.getHeadPage().isFullyAcked(), is(equalTo(true))); assertThat(q.getHeadPage().isFullyAcked(), is(equalTo(true)));
}
q.close();
} }
@Test @Test
@ -202,7 +197,7 @@ public class QueueTest {
TestSettings.volatileQueueSettings(2 * singleElementCapacity) TestSettings.volatileQueueSettings(2 * singleElementCapacity)
).checkpointMaxWrites(1024) // arbitrary high enough threshold so that it's not reached (default for TestSettings is 1) ).checkpointMaxWrites(1024) // arbitrary high enough threshold so that it's not reached (default for TestSettings is 1)
.build(); .build();
TestQueue q = new TestQueue(settings); try (TestQueue q = new TestQueue(settings)) {
q.open(); q.open();
assertThat(q.getHeadPage().getPageNum(), is(equalTo(0))); assertThat(q.getHeadPage().getPageNum(), is(equalTo(0)));
@ -277,8 +272,7 @@ public class QueueTest {
assertThat(c.getMinSeqNum(), is(equalTo(3L))); assertThat(c.getMinSeqNum(), is(equalTo(3L)));
assertThat(c.getFirstUnackedSeqNum(), is(equalTo(5L))); assertThat(c.getFirstUnackedSeqNum(), is(equalTo(5L)));
assertThat(c.getFirstUnackedPageNum(), is(equalTo(1))); assertThat(c.getFirstUnackedPageNum(), is(equalTo(1)));
}
q.close();
} }
@Test @Test
@ -296,8 +290,8 @@ public class QueueTest {
elements.add(new StringElement(String.format("%0" + digits + "d", i))); elements.add(new StringElement(String.format("%0" + digits + "d", i)));
} }
int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(elements.get(0).serialize().length); int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(elements.get(0).serialize().length);
try (TestQueue q = new TestQueue(
TestQueue q = new TestQueue(TestSettings.volatileQueueSettings(singleElementCapacity)); TestSettings.volatileQueueSettings(singleElementCapacity))) {
q.open(); q.open();
for (Queueable e : elements) { for (Queueable e : elements) {
@ -320,8 +314,7 @@ public class QueueTest {
} }
assertThat(q.getTailPages().size(), is(equalTo(0))); assertThat(q.getTailPages().size(), is(equalTo(0)));
}
q.close();
} }
} }
@ -334,10 +327,9 @@ public class QueueTest {
TestSettings.volatileQueueSettings(singleElementCapacity) TestSettings.volatileQueueSettings(singleElementCapacity)
).maxUnread(2) // 2 so we know the first write should not block and the second should ).maxUnread(2) // 2 so we know the first write should not block and the second should
.build(); .build();
TestQueue q = new TestQueue(settings); try (TestQueue q = new TestQueue(settings)) {
q.open(); q.open();
long seqNum = q.write(element); long seqNum = q.write(element);
assertThat(seqNum, is(equalTo(1L))); assertThat(seqNum, is(equalTo(1L)));
assertThat(q.isFull(), is(false)); assertThat(q.isFull(), is(false));
@ -373,8 +365,7 @@ public class QueueTest {
// since we did not ack and pages hold a single item // since we did not ack and pages hold a single item
assertThat(q.getTailPages().size(), is(equalTo(ELEMENT_COUNT))); assertThat(q.getTailPages().size(), is(equalTo(ELEMENT_COUNT)));
}
q.close();
} }
@Test @Test
@ -386,7 +377,7 @@ public class QueueTest {
TestSettings.volatileQueueSettings(256) // 256 is arbitrary, large enough to hold a few elements TestSettings.volatileQueueSettings(256) // 256 is arbitrary, large enough to hold a few elements
).maxUnread(2) ).maxUnread(2)
.build(); // 2 so we know the first write should not block and the second should .build(); // 2 so we know the first write should not block and the second should
TestQueue q = new TestQueue(settings); try (TestQueue q = new TestQueue(settings)) {
q.open(); q.open();
// perform first non-blocking write // perform first non-blocking write
@ -407,8 +398,9 @@ public class QueueTest {
Future<Long> future = executor.submit(write); Future<Long> future = executor.submit(write);
// spin wait until data is written and write blocks // spin wait until data is written and write blocks
while (!q.isFull()) { Thread.sleep(1); } while (!q.isFull()) {
Thread.sleep(1);
}
// read one element, which will unblock the last write // read one element, which will unblock the last write
Batch b = q.nonBlockReadBatch(1); Batch b = q.nonBlockReadBatch(1);
assertThat(b, is(notNullValue())); assertThat(b, is(notNullValue()));
@ -429,8 +421,7 @@ public class QueueTest {
assertThat(q.getHeadPage().getElementCount() > 0L, is(true)); assertThat(q.getHeadPage().getElementCount() > 0L, is(true));
assertThat(q.getHeadPage().unreadCount(), is(equalTo(1L))); assertThat(q.getHeadPage().unreadCount(), is(equalTo(1L)));
assertThat(q.unreadCount, is(equalTo(1L))); assertThat(q.unreadCount, is(equalTo(1L)));
}
q.close();
} }
@Test(timeout = 5000) @Test(timeout = 5000)
@ -441,8 +432,7 @@ public class QueueTest {
// allow 10 elements per page but only 100 events in total // allow 10 elements per page but only 100 events in total
Settings settings = TestSettings.volatileQueueSettings(singleElementCapacity * 10, singleElementCapacity * 100); Settings settings = TestSettings.volatileQueueSettings(singleElementCapacity * 10, singleElementCapacity * 100);
try (TestQueue q = new TestQueue(settings)) {
TestQueue q = new TestQueue(settings);
q.open(); q.open();
int ELEMENT_COUNT = 90; // should be able to write 99 events before getting full int ELEMENT_COUNT = 90; // should be able to write 99 events before getting full
@ -459,13 +449,13 @@ public class QueueTest {
ExecutorService executor = Executors.newFixedThreadPool(1); ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Long> future = executor.submit(write); Future<Long> future = executor.submit(write);
while (!q.isFull()) {
while (!q.isFull()) { Thread.sleep(10); } Thread.sleep(10);
}
assertThat(q.isFull(), is(true)); assertThat(q.isFull(), is(true));
executor.shutdown(); executor.shutdown();
q.close(); }
} }
@Test(timeout = 5000) @Test(timeout = 5000)
@ -518,11 +508,10 @@ public class QueueTest {
// allow 10 elements per page but only 100 events in total // allow 10 elements per page but only 100 events in total
Settings settings = TestSettings.volatileQueueSettings(singleElementCapacity * 10, singleElementCapacity * 100); Settings settings = TestSettings.volatileQueueSettings(singleElementCapacity * 10, singleElementCapacity * 100);
try (TestQueue q = new TestQueue(settings)) {
TestQueue q = new TestQueue(settings);
q.open(); q.open();
int ELEMENT_COUNT =
int ELEMENT_COUNT = 90; // should be able to write 90 events (9 pages) before getting full 90; // should be able to write 90 events (9 pages) before getting full
for (int i = 0; i < ELEMENT_COUNT; i++) { for (int i = 0; i < ELEMENT_COUNT; i++) {
long seqNum = q.write(element); long seqNum = q.write(element);
} }
@ -540,8 +529,9 @@ public class QueueTest {
ExecutorService executor = Executors.newFixedThreadPool(1); ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Long> future = executor.submit(write); Future<Long> future = executor.submit(write);
assertThat(future.isDone(), is(false)); assertThat(future.isDone(), is(false));
while (!q.isFull()) {
while (!q.isFull()) { Thread.sleep(10); } Thread.sleep(10);
}
assertThat(q.isFull(), is(true)); assertThat(q.isFull(), is(true));
assertThat(future.isDone(), is(false)); assertThat(future.isDone(), is(false));
@ -550,7 +540,7 @@ public class QueueTest {
assertThat(future.get(), is(equalTo(ELEMENT_COUNT + 1L))); assertThat(future.get(), is(equalTo(ELEMENT_COUNT + 1L)));
executor.shutdown(); executor.shutdown();
q.close(); }
} }
@Test(timeout = 5000) @Test(timeout = 5000)
@ -562,8 +552,7 @@ public class QueueTest {
// allow 10 elements per page but only 100 events in total // allow 10 elements per page but only 100 events in total
Settings settings = TestSettings.volatileQueueSettings(singleElementCapacity * 10, singleElementCapacity * 100); Settings settings = TestSettings.volatileQueueSettings(singleElementCapacity * 10, singleElementCapacity * 100);
try (TestQueue q = new TestQueue(settings)) {
TestQueue q = new TestQueue(settings);
q.open(); q.open();
int ELEMENT_COUNT = 90; // should be able to write 99 events before getting full int ELEMENT_COUNT = 90; // should be able to write 99 events before getting full
@ -580,9 +569,9 @@ public class QueueTest {
ExecutorService executor = Executors.newFixedThreadPool(1); ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Long> future = executor.submit(write); Future<Long> future = executor.submit(write);
while (!q.isFull()) {
while (!q.isFull()) { Thread.sleep(10); } Thread.sleep(10);
}
assertThat(q.isFull(), is(true)); assertThat(q.isFull(), is(true));
Batch b = q.readBatch(9); // read 90% of page (9 events) Batch b = q.readBatch(9); // read 90% of page (9 events)
@ -591,30 +580,35 @@ public class QueueTest {
assertThat(q.isFull(), is(true)); // queue should still be full assertThat(q.isFull(), is(true)); // queue should still be full
executor.shutdown(); executor.shutdown();
q.close(); }
} }
@Test @Test
public void testAckedCount() throws IOException { public void testAckedCount() throws IOException {
Settings settings = TestSettings.persistedQueueSettings(100, dataPath); Settings settings = TestSettings.persistedQueueSettings(100, dataPath);
Queue q = new Queue(settings); Batch b;
Queueable element1;
Queueable element2;
Queueable element3;
long firstSeqNum;
try(Queue q = new Queue(settings)) {
q.open(); q.open();
Queueable element1 = new StringElement("foobarbaz"); element1 = new StringElement("foobarbaz");
Queueable element2 = new StringElement("wowza"); element2 = new StringElement("wowza");
Queueable element3 = new StringElement("third"); element3 = new StringElement("third");
long firstSeqNum = q.write(element1); firstSeqNum = q.write(element1);
b = q.nonBlockReadBatch(1);
Batch b = q.nonBlockReadBatch(1);
assertThat(b.getElements().size(), is(equalTo(1))); assertThat(b.getElements().size(), is(equalTo(1)));
}
q.close(); long secondSeqNum;
long thirdSeqNum;
q = new Queue(settings); try(Queue q = new Queue(settings)){
q.open(); q.open();
long secondSeqNum = q.write(element2); secondSeqNum = q.write(element2);
long thirdSeqNum = q.write(element3); thirdSeqNum = q.write(element3);
b = q.nonBlockReadBatch(1); b = q.nonBlockReadBatch(1);
assertThat(b.getElements().size(), is(equalTo(1))); assertThat(b.getElements().size(), is(equalTo(1)));
@ -626,9 +620,9 @@ public class QueueTest {
assertThat(b.getElements().get(1), is(equalTo(element3))); assertThat(b.getElements().get(1), is(equalTo(element3)));
q.ack(Collections.singletonList(firstSeqNum)); q.ack(Collections.singletonList(firstSeqNum));
q.close(); }
q = new Queue(settings); try(Queue q = new Queue(settings)) {
q.open(); q.open();
b = q.nonBlockReadBatch(2); b = q.nonBlockReadBatch(2);
@ -638,8 +632,7 @@ public class QueueTest {
assertThat(q.getAckedCount(), equalTo(0L)); assertThat(q.getAckedCount(), equalTo(0L));
assertThat(q.getUnackedCount(), equalTo(0L)); assertThat(q.getUnackedCount(), equalTo(0L));
}
q.close();
} }
@Test(timeout = 5000) @Test(timeout = 5000)
@ -647,8 +640,7 @@ public class QueueTest {
// very small pages to maximize page creation // very small pages to maximize page creation
Settings settings = TestSettings.volatileQueueSettings(100); Settings settings = TestSettings.volatileQueueSettings(100);
try (TestQueue q = new TestQueue(settings)) {
TestQueue q = new TestQueue(settings);
q.open(); q.open();
int ELEMENT_COUNT = 10000; int ELEMENT_COUNT = 10000;
@ -688,15 +680,15 @@ public class QueueTest {
assertThat(q.isFullyAcked(), is(true)); assertThat(q.isFullyAcked(), is(true));
executor.shutdown(); executor.shutdown();
q.close(); }
} }
@Test @Test
public void fullyAckedHeadPageBeheadingTest() throws IOException { public void fullyAckedHeadPageBeheadingTest() throws IOException {
Queueable element = new StringElement("foobarbaz1"); Queueable element = new StringElement("foobarbaz1");
int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(element.serialize().length); int singleElementCapacity = ByteBufferPageIO.HEADER_SIZE + ByteBufferPageIO._persistedByteCount(element.serialize().length);
try (TestQueue q = new TestQueue(
TestQueue q = new TestQueue(TestSettings.volatileQueueSettings(2 * singleElementCapacity)); TestSettings.volatileQueueSettings(2 * singleElementCapacity))) {
q.open(); q.open();
Batch b; Batch b;
@ -724,8 +716,7 @@ public class QueueTest {
assertThat(q.getHeadPage().getPageNum(), is(equalTo(1))); assertThat(q.getHeadPage().getPageNum(), is(equalTo(1)));
assertThat(q.firstUnackedPageNum(), is(equalTo(1))); assertThat(q.firstUnackedPageNum(), is(equalTo(1)));
assertThat(q.isFullyAcked(), is(false)); assertThat(q.isFullyAcked(), is(false));
}
q.close();
} }
@Test @Test