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, true); 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, true); 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, true); 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, true); 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, true); 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()); } } }