Search in sources :

Example 56 with LogEntryProto

use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.

the class TestLogSegment method testTruncate.

@Test
public void testTruncate() throws Exception {
    final long term = 1;
    final long start = 1000;
    LogSegment segment = LogSegment.newOpenSegment(null, start, null);
    for (int i = 0; i < 100; i++) {
        LogEntryProto entry = LogProtoUtils.toLogEntryProto(new SimpleOperation("m" + i).getLogEntryContent(), term, i + start);
        segment.appendToOpenSegment(entry, LogSegment.Op.WRITE_CACHE_WITHOUT_STATE_MACHINE_CACHE);
    }
    // truncate an open segment (remove 1080~1099)
    long newSize = segment.getLogRecord(start + 80).getOffset();
    segment.truncate(start + 80);
    Assert.assertEquals(80, segment.numOfEntries());
    checkLogSegment(segment, start, start + 79, false, newSize, term);
    // truncate a closed segment (remove 1050~1079)
    newSize = segment.getLogRecord(start + 50).getOffset();
    segment.truncate(start + 50);
    Assert.assertEquals(50, segment.numOfEntries());
    checkLogSegment(segment, start, start + 49, false, newSize, term);
    // truncate all the remaining entries
    segment.truncate(start);
    Assert.assertEquals(0, segment.numOfEntries());
    checkLogSegment(segment, start, start - 1, false, SegmentedRaftLogFormat.getHeaderLength(), term);
}
Also used : LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) StateMachineLogEntryProto(org.apache.ratis.proto.RaftProtos.StateMachineLogEntryProto) SimpleOperation(org.apache.ratis.RaftTestUtil.SimpleOperation) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 57 with LogEntryProto

use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.

the class TestSegmentedRaftLog method testServerShutdownOnTimeoutIOException.

@Test(expected = TimeoutIOException.class)
public void testServerShutdownOnTimeoutIOException() throws Throwable {
    RaftServerConfigKeys.Log.StateMachineData.setSync(properties, true);
    final TimeDuration syncTimeout = TimeDuration.valueOf(100, TimeUnit.MILLISECONDS);
    RaftServerConfigKeys.Log.StateMachineData.setSyncTimeout(properties, syncTimeout);
    final int numRetries = 2;
    RaftServerConfigKeys.Log.StateMachineData.setSyncTimeoutRetry(properties, numRetries);
    final LogEntryProto entry = prepareLogEntry(0, 0, null, true);
    final StateMachine sm = new BaseStateMachine() {

        @Override
        public CompletableFuture<Void> write(LogEntryProto entry) {
            getLifeCycle().transition(LifeCycle.State.STARTING);
            getLifeCycle().transition(LifeCycle.State.RUNNING);
            // the future never completes
            return new CompletableFuture<>();
        }

        @Override
        public void notifyLogFailed(Throwable cause, LogEntryProto entry) {
            LOG.info("Test StateMachine: Ratis log failed notification received as expected.", cause);
            LOG.info("Test StateMachine: Transition to PAUSED state.");
            Assert.assertNotNull(entry);
            getLifeCycle().transition(LifeCycle.State.PAUSING);
            getLifeCycle().transition(LifeCycle.State.PAUSED);
        }
    };
    // TimeoutIOException
    Throwable ex = null;
    try (SegmentedRaftLog raftLog = new SegmentedRaftLog(memberId, null, sm, null, null, storage, () -> -1, properties)) {
        raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
        // SegmentedRaftLogWorker should catch TimeoutIOException
        CompletableFuture<Long> f = raftLog.appendEntry(entry);
        // Wait for async writeStateMachineData to finish
        try {
            f.get();
        } catch (ExecutionException e) {
            ex = e.getCause();
        }
    }
    Assert.assertNotNull(ex);
    Assert.assertSame(LifeCycle.State.PAUSED, sm.getLifeCycleState());
    throw ex;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) StateMachine(org.apache.ratis.statemachine.StateMachine) BaseStateMachine(org.apache.ratis.statemachine.impl.BaseStateMachine) BaseStateMachine(org.apache.ratis.statemachine.impl.BaseStateMachine) TimeDuration(org.apache.ratis.util.TimeDuration) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 58 with LogEntryProto

use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.

the class TestSegmentedRaftLog method testSegmentedRaftLogStateMachineData.

@Test
public void testSegmentedRaftLogStateMachineData() throws Exception {
    final SegmentRange range = new SegmentRange(0, 10, 1, true);
    final List<LogEntryProto> entries = prepareLogEntries(range, null, true, new ArrayList<>());
    final SimpleStateMachine4Testing sm = new SimpleStateMachine4Testing();
    try (SegmentedRaftLog raftLog = new SegmentedRaftLog(memberId, null, sm, null, null, storage, () -> -1, properties)) {
        raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
        int next = 0;
        long flush = -1;
        assertIndices(raftLog, flush, next);
        raftLog.appendEntry(entries.get(next++));
        assertIndices(raftLog, flush, next);
        raftLog.appendEntry(entries.get(next++));
        assertIndices(raftLog, flush, next);
        raftLog.appendEntry(entries.get(next++));
        assertIndicesMultipleAttempts(raftLog, flush += 3, next);
        sm.blockFlushStateMachineData();
        raftLog.appendEntry(entries.get(next++));
        sm.blockWriteStateMachineData();
        final Thread t = startAppendEntryThread(raftLog, entries.get(next++));
        TimeUnit.SECONDS.sleep(1);
        assertTrue(t.isAlive());
        sm.unblockWriteStateMachineData();
        assertIndices(raftLog, flush, next);
        TimeUnit.SECONDS.sleep(1);
        assertIndices(raftLog, flush, next);
        sm.unblockFlushStateMachineData();
        assertIndicesMultipleAttempts(raftLog, flush + 2, next);
        // raftLog.appendEntry(entry).get() won't return
        // until sm.unblockFlushStateMachineData() was called.
        t.join();
    }
}
Also used : SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 59 with LogEntryProto

use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.

the class TestSegmentedRaftLog method prepareLog.

private LogEntryProto[] prepareLog(List<SegmentRange> list) throws IOException {
    List<LogEntryProto> entryList = new ArrayList<>();
    for (SegmentRange range : list) {
        final File file = range.getFile(storage);
        final int size = (int) (range.end - range.start + 1);
        LogEntryProto[] entries = new LogEntryProto[size];
        try (SegmentedRaftLogOutputStream out = new SegmentedRaftLogOutputStream(file, false, segmentMaxSize, preallocatedSize, ByteBuffer.allocateDirect(bufferSize))) {
            for (int i = 0; i < size; i++) {
                SimpleOperation m = new SimpleOperation("m" + (i + range.start));
                entries[i] = LogProtoUtils.toLogEntryProto(m.getLogEntryContent(), range.term, i + range.start);
                out.write(entries[i]);
            }
        }
        Collections.addAll(entryList, entries);
    }
    return entryList.toArray(new LogEntryProto[entryList.size()]);
}
Also used : LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) ArrayList(java.util.ArrayList) SimpleOperation(org.apache.ratis.RaftTestUtil.SimpleOperation) File(java.io.File)

Example 60 with LogEntryProto

use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.

the class TestSegmentedRaftLog method testAppendEntriesWithInconsistency.

/**
 * Test append with inconsistent entries
 */
@Test
public void testAppendEntriesWithInconsistency() throws Exception {
    // prepare the log for truncation
    List<SegmentRange> ranges = prepareRanges(0, 5, 200, 0);
    List<LogEntryProto> entries = prepareLogEntries(ranges, null);
    final RetryCache retryCache = RetryCacheTestUtil.createRetryCache();
    try (SegmentedRaftLog raftLog = RetryCacheTestUtil.newSegmentedRaftLog(memberId, retryCache, storage, properties)) {
        raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
        entries.forEach(entry -> RetryCacheTestUtil.createEntry(retryCache, entry));
        // append entries to the raftlog
        entries.stream().map(raftLog::appendEntry).forEach(CompletableFuture::join);
    }
    // append entries whose first 100 entries are the same with existing log,
    // and the next 100 are with different term
    SegmentRange r1 = new SegmentRange(550, 599, 2, false);
    SegmentRange r2 = new SegmentRange(600, 649, 3, false);
    SegmentRange r3 = new SegmentRange(650, 749, 10, false);
    List<LogEntryProto> newEntries = prepareLogEntries(Arrays.asList(r1, r2, r3), null);
    try (SegmentedRaftLog raftLog = RetryCacheTestUtil.newSegmentedRaftLog(memberId, retryCache, storage, properties)) {
        raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
        LOG.info("newEntries[0] = {}", newEntries.get(0));
        final int last = newEntries.size() - 1;
        LOG.info("newEntries[{}] = {}", last, newEntries.get(last));
        raftLog.append(newEntries.toArray(new LogEntryProto[0])).forEach(CompletableFuture::join);
        checkFailedEntries(entries, 650, retryCache);
        checkEntries(raftLog, entries, 0, 650);
        checkEntries(raftLog, newEntries, 100, 100);
        Assert.assertEquals(newEntries.get(newEntries.size() - 1), getLastEntry(raftLog));
        Assert.assertEquals(newEntries.get(newEntries.size() - 1).getIndex(), raftLog.getFlushIndex());
    }
    // load the raftlog again and check
    try (SegmentedRaftLog raftLog = RetryCacheTestUtil.newSegmentedRaftLog(memberId, retryCache, storage, properties)) {
        raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
        checkEntries(raftLog, entries, 0, 650);
        checkEntries(raftLog, newEntries, 100, 100);
        Assert.assertEquals(newEntries.get(newEntries.size() - 1), getLastEntry(raftLog));
        Assert.assertEquals(newEntries.get(newEntries.size() - 1).getIndex(), raftLog.getFlushIndex());
        SegmentedRaftLogCache cache = raftLog.getRaftLogCache();
        Assert.assertEquals(5, cache.getNumOfSegments());
    }
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RetryCache(org.apache.ratis.server.RetryCache) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Aggregations

LogEntryProto (org.apache.ratis.proto.RaftProtos.LogEntryProto)61 Test (org.junit.Test)22 BaseTest (org.apache.ratis.BaseTest)20 SimpleOperation (org.apache.ratis.RaftTestUtil.SimpleOperation)15 CompletableFuture (java.util.concurrent.CompletableFuture)14 File (java.io.File)13 IOException (java.io.IOException)13 StateMachineLogEntryProto (org.apache.ratis.proto.RaftProtos.StateMachineLogEntryProto)12 RaftLog (org.apache.ratis.server.raftlog.RaftLog)12 RaftStorage (org.apache.ratis.server.storage.RaftStorage)11 ArrayList (java.util.ArrayList)10 RaftPeerId (org.apache.ratis.protocol.RaftPeerId)10 TermIndex (org.apache.ratis.server.protocol.TermIndex)9 LogEntryHeader (org.apache.ratis.server.raftlog.LogEntryHeader)7 RaftClient (org.apache.ratis.client.RaftClient)6 RaftProperties (org.apache.ratis.conf.RaftProperties)6 RaftGroupId (org.apache.ratis.protocol.RaftGroupId)6 RaftGroupMemberId (org.apache.ratis.protocol.RaftGroupMemberId)6 RaftServer (org.apache.ratis.server.RaftServer)6 RandomAccessFile (java.io.RandomAccessFile)5