use of org.apache.ratis.grpc.client.RaftOutputStream in project incubator-ratis by apache.
the class TestRaftStream method testKillLeader.
/**
* Write while leader is killed
*/
@Test
public void testKillLeader() throws Exception {
LOG.info("Running testChangeLeader");
GrpcConfigKeys.OutputStream.setBufferSize(prop, SizeInBytes.valueOf(4));
cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(NUM_SERVERS, prop);
cluster.start();
final RaftServerImpl leader = waitForLeader(cluster);
final AtomicBoolean running = new AtomicBoolean(true);
final AtomicReference<Boolean> success = new AtomicReference<>();
final AtomicInteger result = new AtomicInteger(0);
final CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
LOG.info("Writer thread starts");
int count = 0;
try (RaftOutputStream out = new RaftOutputStream(prop, ClientId.randomId(), cluster.getGroup(), leader.getId())) {
while (running.get()) {
out.write(toBytes(count++));
Thread.sleep(10);
}
success.set(true);
result.set(count);
} catch (Exception e) {
LOG.info("Got exception when writing", e);
success.set(false);
} finally {
latch.countDown();
}
}).start();
// force change the leader
Thread.sleep(500);
RaftTestUtil.waitAndKillLeader(cluster, true);
final RaftServerImpl newLeader = waitForLeader(cluster);
Assert.assertNotEquals(leader.getId(), newLeader.getId());
Thread.sleep(500);
running.set(false);
latch.await(5, TimeUnit.SECONDS);
LOG.info("Writer success? " + success.get());
Assert.assertTrue(success.get());
// total number of tx should be >= result + 2, where 2 means two NoOp from
// leaders. It may be larger than result+2 because the client may resend
// requests and we do not have retry cache on servers yet.
LOG.info("last applied index: {}. total number of requests: {}", newLeader.getState().getLastAppliedIndex(), result.get());
Assert.assertTrue(newLeader.getState().getLastAppliedIndex() >= result.get() + 1);
}
use of org.apache.ratis.grpc.client.RaftOutputStream in project incubator-ratis by apache.
the class TestRaftStream method testSimpleWrite.
@Test
public void testSimpleWrite() throws Exception {
final int numRequests = 500;
LOG.info("Running testSimpleWrite, numRequests=" + numRequests);
// default 64K is too large for a test
GrpcConfigKeys.OutputStream.setBufferSize(prop, SizeInBytes.valueOf(4));
cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(NUM_SERVERS, prop);
cluster.start();
RaftServerImpl leader = waitForLeader(cluster);
try (RaftOutputStream out = new RaftOutputStream(prop, ClientId.randomId(), cluster.getGroup(), leader.getId())) {
for (int i = 0; i < numRequests; i++) {
// generate requests
out.write(toBytes(i));
}
}
// check the leader's raft log
final RaftLog raftLog = leader.getState().getLog();
final AtomicInteger i = new AtomicInteger();
checkLog(raftLog, numRequests, () -> toBytes(i.getAndIncrement()));
}
use of org.apache.ratis.grpc.client.RaftOutputStream in project incubator-ratis by apache.
the class TestRaftStream method testWriteWithOffset.
@Test
public void testWriteWithOffset() throws Exception {
LOG.info("Running testWriteWithOffset");
GrpcConfigKeys.OutputStream.setBufferSize(prop, SizeInBytes.valueOf(ByteValue.BUFFERSIZE));
cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(NUM_SERVERS, prop);
cluster.start();
RaftServerImpl leader = waitForLeader(cluster);
RaftOutputStream out = new RaftOutputStream(prop, ClientId.randomId(), cluster.getGroup(), leader.getId());
byte[] b1 = new byte[ByteValue.BUFFERSIZE / 2];
Arrays.fill(b1, (byte) 1);
byte[] b2 = new byte[ByteValue.BUFFERSIZE];
Arrays.fill(b2, (byte) 2);
byte[] b3 = new byte[ByteValue.BUFFERSIZE * 2 + ByteValue.BUFFERSIZE / 2];
Arrays.fill(b3, (byte) 3);
byte[] b4 = new byte[ByteValue.BUFFERSIZE * 4];
Arrays.fill(b3, (byte) 4);
byte[] expected = new byte[ByteValue.BUFFERSIZE * 8];
byte[][] data = new byte[][] { b1, b2, b3, b4 };
final Random random = new Random();
int totalSize = 0;
for (byte[] b : data) {
System.arraycopy(b, 0, expected, totalSize, b.length);
totalSize += b.length;
int written = 0;
while (written < b.length) {
int toWrite = random.nextInt(b.length - written) + 1;
LOG.info("write {} bytes", toWrite);
out.write(b, written, toWrite);
written += toWrite;
}
}
out.close();
final RaftLog log = leader.getState().getLog();
// 0.5 + 1 + 2.5 + 4 = 8
Assert.assertEquals(8, leader.getState().getLastAppliedIndex());
Assert.assertEquals(8, log.getLastCommittedIndex());
TermIndex[] entries = log.getEntries(1, 9);
byte[] actual = new byte[ByteValue.BUFFERSIZE * 8];
totalSize = 0;
for (TermIndex e : entries) {
byte[] eValue = log.get(e.getIndex()).getSmLogEntry().getData().toByteArray();
Assert.assertEquals(ByteValue.BUFFERSIZE, eValue.length);
System.arraycopy(eValue, 0, actual, totalSize, eValue.length);
totalSize += eValue.length;
}
Assert.assertArrayEquals(expected, actual);
}
use of org.apache.ratis.grpc.client.RaftOutputStream in project incubator-ratis by apache.
the class TestRaftStream method testWriteAndFlush.
@Test
public void testWriteAndFlush() throws Exception {
LOG.info("Running testWriteAndFlush");
GrpcConfigKeys.OutputStream.setBufferSize(prop, SizeInBytes.valueOf(ByteValue.BUFFERSIZE));
cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(NUM_SERVERS, prop);
cluster.start();
RaftServerImpl leader = waitForLeader(cluster);
RaftOutputStream out = new RaftOutputStream(prop, ClientId.randomId(), cluster.getGroup(), leader.getId());
int[] lengths = new int[] { 1, 500, 1023, 1024, 1025, 2048, 3000, 3072 };
ByteValue[] values = new ByteValue[lengths.length];
for (int i = 0; i < values.length; i++) {
values[i] = new ByteValue(lengths[i], (byte) 9);
}
List<byte[]> expectedTxs = new ArrayList<>();
for (ByteValue v : values) {
byte[] data = v.genData();
expectedTxs.addAll(v.getTransactions());
out.write(data);
out.flush();
// make sure after the flush the data has been committed
Assert.assertEquals(expectedTxs.size(), leader.getState().getLastAppliedIndex());
}
out.close();
try {
out.write(0);
fail("The OutputStream has been closed");
} catch (IOException ignored) {
}
LOG.info("Start to check leader's log");
final AtomicInteger index = new AtomicInteger(0);
checkLog(leader.getState().getLog(), expectedTxs.size(), () -> expectedTxs.get(index.getAndIncrement()));
}
Aggregations