package bftsmart.demo.bftmapjunit;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.HashMap;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import bftsmart.demo.bftmap.BFTMap;
public class KVClientTest {
private static Process replica0;
private static Process replica1;
private static Process replica2;
private static Process replica3;
private static String[] command = new String[5];
@BeforeClass
public static void startServers() {
try {
System.out.println("Starting the servers");
command[0] = "java";
command[1] = "-cp";
command[2] = "bin/BFT-SMaRt.jar:lib/slf4j-api-1.5.8.jar:lib/slf4j-jdk14-1.5.8.jar:lib/netty-3.1.1.GA.jar:lib/commons-codec-1.5.jar";
command[3] = "bftsmart.demo.bftmap.BFTMapServer";
command[4] = "0";
replica0 = new ProcessBuilder(command).redirectErrorStream(true).start();
ConsoleLogger log0 = new ConsoleLogger();;
log0.setIn(replica0.getInputStream());
log0.setOut(System.out);
log0.setIndex("0");
log0.start();
Thread.sleep(2000);
command[4] = "1";
replica1 = new ProcessBuilder(command).redirectErrorStream(true).start();
ConsoleLogger log1 = new ConsoleLogger();;
log1.setIn(replica1.getInputStream());
log1.setOut(System.out);
log1.setIndex("1");
log1.start();
Thread.sleep(2000);
command[4] = "2";
replica2 = new ProcessBuilder(command).redirectErrorStream(true).start();
ConsoleLogger log2 = new ConsoleLogger();;
log2.setIn(replica2.getInputStream());
log2.setOut(System.out);
log2.setIndex("2");
log2.start();
Thread.sleep(2000);
command[4] = "3";
replica3 = new ProcessBuilder(command).redirectErrorStream(true).start();
ConsoleLogger log3 = new ConsoleLogger();;
log3.setIn(replica3.getInputStream());
log3.setOut(System.out);
log3.setIndex("3");
log3.start();
System.out.println("Servers started");
} catch(IOException ioe) {
System.out.println("Exception during BFTMapInteractiveClient test: ");
System.out.println(ioe.getMessage());
} catch(InterruptedException ie) {
System.out.println("Exception during Thread sleep: " + ie.getMessage());
}
}
@AfterClass
public static void stopServers() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, IOException {
System.out.println("Stopping servers");
replica0.destroy();
replica1.destroy();
replica2.destroy();
replica3.destroy();
System.out.println("Servers stopped");
}
/**
* Test regular case where there is the creation of a table, insert of
* data and search for size of the table.
* No servers are killed nor behaves different than expected.
*/
@Test
public void testRegularCase() {
try{
Thread.sleep(1000);
BFTMap bftMap = new BFTMap(1001);
bftMap.put("TestTable1", new HashMap<String,byte[]>());
bftMap.putEntry("TestTable1", "key1", "value1".getBytes());
assertEquals("Main table size should be 1", 1, bftMap.size1("TestTable1"));
for(int i = 0; i < 100; i++) {
String key = "key" + (2+i);
String value = "value" + (2+i);
bftMap.putEntry("TestTable1", key, value.getBytes());
}
assertEquals("Main table size should be 101", 101, bftMap.size1("TestTable1"));
bftMap.putEntry("TestTable1", "key102", "value102".getBytes());
assertEquals("Main table size should be 102", 102, bftMap.size1("TestTable1"));
} catch(InterruptedException ie) {
System.out.println("Exception during Thread sleep: " + ie.getMessage());
}
}
/**
* - Crate table;
* - Insert data;
* - Kills a replica that is not a leader;
* - Insert data;
* - Verify if the size of the table is correct.
*/
@Test
public void testStopNonLeader() {
try{
Thread.sleep(1000);
BFTMap bftMap = new BFTMap(1001);
bftMap.put("TestTable2", new HashMap<String,byte[]>());
bftMap.putEntry("TestTable2", "key1", "value1".getBytes());
assertEquals("Main table size should be 1", 1, bftMap.size1("TestTable2"));
for(int i = 0; i < 200; i++) {
String key = "key" + (2+i);
String value = "value" + (2+i);
bftMap.putEntry("TestTable2", key, value.getBytes());
}
assertEquals("Main table size should be 201", 201, bftMap.size1("TestTable2"));
replica2.destroy(); // Killing a non-leader replica, replica2
for(int i = 0; i < 200; i++) {
String key = "key" + (202+i);
String value = "value" + (202+i);
bftMap.putEntry("TestTable2", key, value.getBytes());
}
assertEquals("Main table size should be 401", 401, bftMap.size1("TestTable2"));
} catch(InterruptedException ie) {
System.out.println("Exception during Thread sleep: " + ie.getMessage());
}
}
/**
* This test insert and retrieve data.
* During this process a replica that is not the leader is killed.
* After that the replica is started back.
* During the whole process messages keep being sent, to test if
* the application works as expected.
*/
@Test
public void testStopAndStartNonLeader() {
try{
Thread.sleep(5000);
BFTMap bftMap = new BFTMap(1001);
Thread.sleep(1000);
bftMap.put("TestTable3", new HashMap<String,byte[]>());
for(int i = 0; i < 65; i++) {
String key = "key" + (1+i);
String value = "value" + (1+i);
System.out.println(bftMap.putEntry("TestTable3", key, value.getBytes()));
}
assertEquals("Main table size should be 65", 65, bftMap.size1("TestTable3"));
replica1.destroy(); // Killing a non-leader replica, replica2
for(int i = 0; i < 35; i++) {
String key = "key" + (66+i);
String value = "value" + (66+i);
System.out.println(bftMap.putEntry("TestTable3", key, value.getBytes()));
}
assertEquals("Main table size should be 100", 100, bftMap.size1("TestTable3"));
command[4] = "1";
replica1 = new ProcessBuilder(command).redirectErrorStream(true).start(); // Starting replica2 back
ConsoleLogger log1 = new ConsoleLogger();;
log1.setIn(replica1.getInputStream());
log1.setOut(System.out);
log1.setIndex("11");
log1.start();
System.out.println("---------Sleep1: " + new java.util.Date());
Thread.sleep(20000);
System.out.println("---------Wakeup1: " + new java.util.Date());
for(int i = 0; i < 35; i++) {
String key = "key" + (101+i);
String value = "value" + (101+i);
System.out.println(bftMap.putEntry("TestTable3", key, value.getBytes()));
}
assertEquals("Main table size should be 135", 135, bftMap.size1("TestTable3"));
System.out.println("---------Sleep2: " + new java.util.Date());
Thread.sleep(10000);
System.out.println("---------Wakeup2: " + new java.util.Date());
replica2.destroy(); // Killing another non-leader replica, replica3
for(int i = 0; i < 35; i++) {
String key = "key" + (136+i);
String value = "value" + (136+i);
System.out.println(bftMap.putEntry("TestTable3", key, value.getBytes()));
}
assertEquals("Main table size should be 170", 170, bftMap.size1("TestTable3"));
} catch(InterruptedException ie) {
System.out.println("Exception during Thread sleep: " + ie.getMessage());
} catch(IOException ioe) {
System.out.println("Exception when starting replica 2: " + ioe.getMessage());
}
}
/**
* - Crate table;
* - Insert data;
* - Kills the leader replica;
* - Insert data;
* - Verify if the size of the table is correct.
*/
@Test
public void testStopLeader() {
try{
Thread.sleep(1000);
BFTMap bftMap = new BFTMap(1001);
Thread.sleep(1000);
bftMap.put("TestTable4", new HashMap<String,byte[]>());
bftMap.putEntry("TestTable4", "key1", "value1".getBytes());
assertEquals("Main table size should be 1", 1, bftMap.size1("TestTable4"));
for(int i = 0; i < 200; i++) {
String key = "key" + (2+i);
String value = "value" + (2+i);
bftMap.putEntry("TestTable4", key, value.getBytes());
}
assertEquals("Main table size should be 201", 201, bftMap.size1("TestTable4"));
replica0.destroy(); // Killing the leader, replica 0
for(int i = 0; i < 200; i++) {
String key = "key" + (202+i);
String value = "value" + (202+i);
bftMap.putEntry("TestTable4", key, value.getBytes());
}
assertEquals("Main table size should be 401", 401, bftMap.size1("TestTable4"));
} catch(InterruptedException ie) {
System.out.println("Exception during Thread sleep: " + ie.getMessage());
}
}
/**
* - Crate table;
* - Insert data;
* - Kills the leader replica;
* - Insert data;
* - Verify if the size of the table is correct;
* - Start the replica again;
* - Insert data;
* - Verify if the size of the table is correct;
* - Kills a second leader;
* - Insert data;
* - Verify if the size of the table is correct.
*/
@Test
public void testStopLeaders() {
try{
Thread.sleep(1000);
BFTMap bftMap = new BFTMap(1001);
Thread.sleep(1000);
bftMap.put("TestTable5", new HashMap<String,byte[]>());
for(int i = 0; i < 130; i++) {
String key = "key" + (1+i);
String value = "value" + (1+i);
bftMap.putEntry("TestTable5", key, value.getBytes());
}
assertEquals("Main table size should be 130", 130, bftMap.size1("TestTable5"));
replica0.destroy(); // Killing the leader, replica 0
for(int i = 0; i < 60; i++) {
String key = "key" + (131+i);
String value = "value" + (131+i);
bftMap.putEntry("TestTable5", key, value.getBytes());
}
assertEquals("Main table size should be 190", 190, bftMap.size1("TestTable5"));
command[4] = "0";
replica0 = new ProcessBuilder(command).redirectErrorStream(true).start(); // Starting replica0 back
ConsoleLogger log0 = new ConsoleLogger();;
log0.setIn(replica0.getInputStream());
log0.setOut(System.out);
log0.setIndex("01");
log0.start();
System.out.println("---------Sleep1: " + new java.util.Date());
Thread.sleep(20000);
System.out.println("---------Wakeup1: " + new java.util.Date());
for(int i = 0; i < 20; i++) {
String key = "key" + (191+i);
String value = "value" + (191+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 210", 210, bftMap.size1("TestTable5"));
System.out.println("---------Sleep2: " + new java.util.Date());
Thread.sleep(10000);
System.out.println("---------Wakeup2: " + new java.util.Date());
replica1.destroy(); // Killing another leader replica, replica1
for(int i = 0; i < 60; i++) {
String key = "key" + (211+i);
String value = "value" + (211+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 270", 270, bftMap.size1("TestTable5"));
command[4] = "1";
replica1 = new ProcessBuilder(command).redirectErrorStream(true).start(); // Starting replica0 back
ConsoleLogger log1 = new ConsoleLogger();;
log1.setIn(replica1.getInputStream());
log1.setOut(System.out);
log1.setIndex("11");
log1.start();
System.out.println("---------Sleep3: " + new java.util.Date());
Thread.sleep(20000);
System.out.println("---------Wakeup3: " + new java.util.Date());
for(int i = 0; i < 20; i++) {
String key = "key" + (271+i);
String value = "value" + (271+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 290", 290, bftMap.size1("TestTable5"));
System.out.println("---------Sleep4: " + new java.util.Date());
Thread.sleep(10000);
System.out.println("---------Wakeup4: " + new java.util.Date());
replica2.destroy(); // Killing another leader replica, replica1
for(int i = 0; i < 40; i++) {
String key = "key" + (291+i);
String value = "value" + (291+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 330", 330, bftMap.size1("TestTable5"));
command[4] = "2";
replica2 = new ProcessBuilder(command).redirectErrorStream(true).start(); // Starting replica0 back
ConsoleLogger log2 = new ConsoleLogger();;
log2.setIn(replica2.getInputStream());
log2.setOut(System.out);
log2.setIndex("21");
log2.start();
System.out.println("---------Sleep5: " + new java.util.Date());
Thread.sleep(20000);
System.out.println("---------Wakeup5: " + new java.util.Date());
for(int i = 0; i < 40; i++) {
String key = "key" + (331+i);
String value = "value" + (331+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 370", 370, bftMap.size1("TestTable5"));
System.out.println("---------Sleep6: " + new java.util.Date());
Thread.sleep(10000);
System.out.println("---------Wakeup6: " + new java.util.Date());
replica3.destroy(); // Killing another leader replica, replica1
for(int i = 0; i < 40; i++) {
String key = "key" + (371+i);
String value = "value" + (371+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 410", 410, bftMap.size1("TestTable5"));
command[4] = "3";
replica3 = new ProcessBuilder(command).redirectErrorStream(true).start(); // Starting replica0 back
ConsoleLogger log3 = new ConsoleLogger();;
log3.setIn(replica3.getInputStream());
log3.setOut(System.out);
log3.setIndex("31");
log3.start();
System.out.println("---------Sleep7: " + new java.util.Date());
Thread.sleep(20000);
System.out.println("---------Wakeup7: " + new java.util.Date());
for(int i = 0; i < 20; i++) {
String key = "key" + (411+i);
String value = "value" + (411+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 430", 430, bftMap.size1("TestTable5"));
System.out.println("---------Sleep8: " + new java.util.Date());
Thread.sleep(10000);
System.out.println("---------Wakeup8: " + new java.util.Date());
replica0.destroy(); // Killing another leader replica, replica1
for(int i = 0; i < 40; i++) {
String key = "key" + (431+i);
String value = "value" + (431+i);
System.out.println(bftMap.putEntry("TestTable5", key, value.getBytes()));
}
assertEquals("Main table size should be 470", 470, bftMap.size1("TestTable5"));
} catch(InterruptedException ie) {
System.out.println("Exception during Thread sleep: " + ie.getMessage());
} catch(IOException ioe) {
System.out.println("Exception when starting replica 2: " + ioe.getMessage());
}
}
}