use of com.twitter.distributedlog.exceptions.BKTransmitException in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testAbortShouldNotFlush.
/**
* Abort a segment log writer should just abort pending writes and not flush buffered data.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testAbortShouldNotFlush() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
// Use another lock to wait for writer releasing lock
ZKDistributedLock lock0 = createLock("/test/lock-" + runtime.getMethodName(), zkc0, false);
Future<ZKDistributedLock> lockFuture0 = lock0.asyncAcquire();
// add 10 records
int numRecords = 10;
List<Future<DLSN>> futureList = new ArrayList<Future<DLSN>>(numRecords);
for (int i = 0; i < numRecords; i++) {
futureList.add(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(i)));
}
assertEquals("Last tx id should be " + (numRecords - 1), numRecords - 1, writer.getLastTxId());
assertEquals("Last acked tx id should be -1", -1L, writer.getLastTxIdAcknowledged());
assertEquals("Last DLSN should be " + DLSN.InvalidDLSN, DLSN.InvalidDLSN, writer.getLastDLSN());
assertEquals("Position should be " + numRecords, 10, writer.getPositionWithinLogSegment());
// close the writer should flush buffered data and release lock
abortWriterAndLock(writer, lock);
Await.result(lockFuture0);
lock0.checkOwnership();
assertEquals("Last tx id should still be " + (numRecords - 1), numRecords - 1, writer.getLastTxId());
assertEquals("Last acked tx id should still be " + (numRecords - 1), -1L, writer.getLastTxIdAcknowledged());
assertEquals("Last DLSN should still be " + DLSN.InvalidDLSN, DLSN.InvalidDLSN, writer.getLastDLSN());
assertEquals("Position should still be " + numRecords, 10, writer.getPositionWithinLogSegment());
for (int i = 0; i < numRecords; i++) {
try {
Await.result(futureList.get(i));
fail("Should be aborted record " + i + " with transmit exception");
} catch (WriteCancelledException wce) {
assertTrue("Record " + i + " should be aborted because of ledger fenced", wce.getCause() instanceof BKTransmitException);
BKTransmitException bkte = (BKTransmitException) wce.getCause();
assertEquals("Record " + i + " should be aborted", BKException.Code.InterruptedException, bkte.getBKResultCode());
}
}
// check no entries were written
LedgerHandle lh = getLedgerHandle(writer);
LedgerHandle readLh = openLedgerNoRecovery(lh);
assertTrue("Ledger " + lh.getId() + " should not be closed", readLh.isClosed());
assertEquals("There should be no entries in ledger " + lh.getId(), LedgerHandle.INVALID_ENTRY_ID, readLh.getLastAddConfirmed());
}
use of com.twitter.distributedlog.exceptions.BKTransmitException in project distributedlog by twitter.
the class TestFailureAndRecovery method testAllBookieFailure.
/**
* Test that if enough bookies fail to prevent an ensemble,
* writes the bookkeeper will fail. Test that when once again
* an ensemble is available, it can continue to write.
*/
@Test(timeout = 60000)
public void testAllBookieFailure() throws Exception {
BookieServer bookieToFail = bkutil.newBookie();
BookieServer replacementBookie = null;
try {
int ensembleSize = numBookies + 1;
assertEquals("Begin: New bookie didn't start", ensembleSize, bkutil.checkBookiesUp(ensembleSize, 10));
// ensure that the journal manager has to use all bookies,
// so that a failure will fail the journal manager
DistributedLogConfiguration conf = new DistributedLogConfiguration();
conf.setEnsembleSize(ensembleSize);
conf.setWriteQuorumSize(ensembleSize);
conf.setAckQuorumSize(ensembleSize);
long txid = 1;
DLMTestUtil.BKLogPartitionWriteHandlerAndClients bkdlmAndClients = createNewBKDLM(conf, "distrlog-allbookiefailure");
BKLogSegmentWriter out = bkdlmAndClients.getWriteHandler().startLogSegment(txid);
for (long i = 1; i <= 3; i++) {
LogRecord op = DLMTestUtil.getLogRecordInstance(txid++);
out.write(op);
}
FutureUtils.result(out.flushAndCommit());
bookieToFail.shutdown();
assertEquals("New bookie didn't die", numBookies, bkutil.checkBookiesUp(numBookies, 10));
try {
for (long i = 1; i <= 3; i++) {
LogRecord op = DLMTestUtil.getLogRecordInstance(txid++);
out.write(op);
txid++;
}
FutureUtils.result(out.flushAndCommit());
fail("should not get to this stage");
} catch (BKTransmitException bkte) {
LOG.debug("Error writing to bookkeeper", bkte);
assertEquals("Invalid exception message", BKException.Code.NotEnoughBookiesException, bkte.getBKResultCode());
}
replacementBookie = bkutil.newBookie();
assertEquals("Replacement: New bookie didn't start", numBookies + 1, bkutil.checkBookiesUp(numBookies + 1, 10));
out = bkdlmAndClients.getWriteHandler().startLogSegment(txid);
for (long i = 1; i <= 3; i++) {
LogRecord op = DLMTestUtil.getLogRecordInstance(txid++);
out.write(op);
}
FutureUtils.result(out.flushAndCommit());
} catch (Exception e) {
LOG.error("Exception in test", e);
throw e;
} finally {
if (replacementBookie != null) {
replacementBookie.shutdown();
}
bookieToFail.shutdown();
if (bkutil.checkBookiesUp(numBookies, 30) != numBookies) {
LOG.warn("Not all bookies from this test shut down, expect errors");
}
}
}
use of com.twitter.distributedlog.exceptions.BKTransmitException in project distributedlog by twitter.
the class TestAsyncReaderWriter method testCloseAndCompleteLogSegmentWhenStreamIsInError.
@Test(timeout = 60000)
public void testCloseAndCompleteLogSegmentWhenStreamIsInError() throws Exception {
String name = "distrlog-close-and-complete-logsegment-when-stream-is-in-error";
DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
confLocal.loadConf(testConf);
confLocal.setOutputBufferSize(0);
confLocal.setImmediateFlushEnabled(true);
BKDistributedLogManager dlm = (BKDistributedLogManager) createNewDLM(confLocal, name);
BKAsyncLogWriter writer = (BKAsyncLogWriter) (dlm.startAsyncLogSegmentNonPartitioned());
long txId = 1L;
for (int i = 0; i < 5; i++) {
Await.result(writer.write(DLMTestUtil.getLogRecordInstance(txId++)));
}
BKLogSegmentWriter logWriter = writer.getCachedLogWriter();
// fence the ledger
dlm.getWriterBKC().get().openLedger(logWriter.getLogSegmentId(), BookKeeper.DigestType.CRC32, confLocal.getBKDigestPW().getBytes(UTF_8));
try {
Await.result(writer.write(DLMTestUtil.getLogRecordInstance(txId++)));
fail("Should fail write to a fenced ledger with BKTransmitException");
} catch (BKTransmitException bkte) {
// expected
}
try {
writer.closeAndComplete();
fail("Should fail to complete a log segment when its ledger is fenced");
} catch (BKTransmitException bkte) {
// expected
}
List<LogSegmentMetadata> segments = dlm.getLogSegments();
assertEquals(1, segments.size());
assertTrue(segments.get(0).isInProgress());
dlm.close();
}
use of com.twitter.distributedlog.exceptions.BKTransmitException in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testCloseShouldFailIfLedgerFenced.
/**
* Close the writer when ledger is fenced: it should release the lock, fail on flushing data and throw exception
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testCloseShouldFailIfLedgerFenced() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
// Use another lock to wait for writer releasing lock
ZKDistributedLock lock0 = createLock("/test/lock-" + runtime.getMethodName(), zkc0, false);
Future<ZKDistributedLock> lockFuture0 = lock0.asyncAcquire();
// add 10 records
int numRecords = 10;
List<Future<DLSN>> futureList = new ArrayList<Future<DLSN>>(numRecords);
for (int i = 0; i < numRecords; i++) {
futureList.add(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(i)));
}
assertEquals("Last tx id should be " + (numRecords - 1), numRecords - 1, writer.getLastTxId());
assertEquals("Last acked tx id should be -1", -1L, writer.getLastTxIdAcknowledged());
assertEquals("Last DLSN should be " + DLSN.InvalidDLSN, DLSN.InvalidDLSN, writer.getLastDLSN());
assertEquals("Position should be " + numRecords, 10, writer.getPositionWithinLogSegment());
// fence the ledger
fenceLedger(getLedgerHandle(writer));
// close the writer: it should release the lock, fail on flushing data and throw exception
try {
closeWriterAndLock(writer, lock);
fail("Close a log segment writer when ledger is fenced should throw exception");
} catch (BKTransmitException bkte) {
assertEquals("Inconsistent rc is thrown", BKException.Code.LedgerFencedException, bkte.getBKResultCode());
}
Await.result(lockFuture0);
lock0.checkOwnership();
assertEquals("Last tx id should still be " + (numRecords - 1), numRecords - 1, writer.getLastTxId());
assertEquals("Last acked tx id should still be " + (numRecords - 1), -1L, writer.getLastTxIdAcknowledged());
assertEquals("Last DLSN should still be " + DLSN.InvalidDLSN, DLSN.InvalidDLSN, writer.getLastDLSN());
assertEquals("Position should still be " + numRecords, 10, writer.getPositionWithinLogSegment());
for (int i = 0; i < numRecords; i++) {
try {
Await.result(futureList.get(i));
fail("Should be aborted record " + i + " with transmit exception");
} catch (BKTransmitException bkte) {
assertEquals("Record " + i + " should be aborted", BKException.Code.LedgerFencedException, bkte.getBKResultCode());
}
}
// check no entries were written
LedgerHandle lh = getLedgerHandle(writer);
LedgerHandle readLh = openLedgerNoRecovery(lh);
assertTrue("Ledger " + lh.getId() + " should be closed", readLh.isClosed());
assertEquals("There should be no entries in ledger " + lh.getId(), LedgerHandle.INVALID_ENTRY_ID, readLh.getLastAddConfirmed());
}
use of com.twitter.distributedlog.exceptions.BKTransmitException in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testNondurableWriteAfterLedgerIsFenced.
/**
* Non durable write should fail if the log segment is fenced.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testNondurableWriteAfterLedgerIsFenced() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
confLocal.setDurableWriteEnabled(false);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
// fence the ledger
fenceLedger(getLedgerHandle(writer));
LogRecord record = DLMTestUtil.getLogRecordInstance(1);
record.setControl();
try {
Await.result(writer.asyncWrite(record));
fail("Should fail the writer if the log segment is already fenced");
} catch (BKTransmitException bkte) {
// expected
assertEquals(BKException.Code.LedgerFencedException, bkte.getBKResultCode());
}
try {
Await.result(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(2)));
fail("Should fail the writer if the log segment is already fenced");
} catch (WriteException we) {
// expected
}
abortWriterAndLock(writer, lock);
}
Aggregations