diff --git a/Projects/cs448p4/ExpectedLogs.txt b/Projects/cs448p4/ExpectedLogs.txt new file mode 100644 index 0000000..1b017d3 --- /dev/null +++ b/Projects/cs448p4/ExpectedLogs.txt @@ -0,0 +1,135 @@ +Test Case 1 (Handout example) + + Log: + W:0,T1,1,1,5,-1 + R:1,T1,2,2,0 + W:2,T1,2,2,3,1 + R:3,T1,1,5,2 + C:4,T1,3 + R:5,T2,1,5,-1 + W:6,T2,1,5,2,5 + C:7,T2,6 + +Test Case 2 (Three transactions) + + Log: + R:0,T1,6,6,-1 + R:1,T2,4,4,-1 + R:2,T3,9,9,-1 + W:3,T1,7,7,2,0 + W:4,T2,2,2,4,1 + R:5,T3,6,6,2 + W:6,T1,5,5,8,3 + W:7,T3,1,1,9,5 + C:8,T3,7 + W:9,T1,6,6,2,6 + C:10,T1,9 + R:11,T2,5,8,4 + W:12,T2,7,2,3,11 + C:13,T2,12 + +Test Case 3 (Deadlocks) + + Log: + W:0,T1,4,4,1,-1 + W:1,T2,5,5,2,-1 + W:2,T3,6,6,3,-1 + R:3,T1,1,1,0 + R:4,T2,1,1,1 + R:5,T3,2,2,2 + R:6,T2,2,2,4 + A:7,T3,5 + W:8,T2,2,2,3,6 + C:9,T2,8 + W:10,T1,1,1,2,3 + C:11,T1,10 + +Test Case 4 (No Conflicts) + + Log: + R:0,T1,1,1,-1 + R:1,T2,1,1,-1 + R:2,T1,2,2,0 + R:3,T2,2,2,1 + R:4,T1,3,3,2 + R:5,T2,3,3,3 + W:6,T1,4,4,1,4 + W:7,T2,5,5,2,5 + C:8,T1,6 + C:9,T2,7 + +Test Case 5: Multiple Deadlocks OR if deadlock detection finds T1 & T2 deadlock first: + + Log: Log: + R:0,T1,1,1,-1 R:0,T1,1,1,-1 + R:1,T2,2,2,-1 R:1,T2,2,2,-1 + R:2,T3,1,1,-1 R:2,T3,1,1,-1 + R:3,T2,3,3,1 R:3,T2,3,3,1 + A:4,T3,2 A:4,T2,3 + A:5,T2,3 W:5,T3,3,3,4,2 + W:6,T1,2,2,1,0 W:6,T1,2,2,1,0 + C:7,T1,6 C:7,T3,5 + C:8,T1,6 + +Test Case 6: Larger deadlock cycle + + Log: + R:0,T1,1,1,-1 + R:1,T2,2,2,-1 + R:2,T3,3,3,-1 + R:3,T4,4,4,-1 + A:4,T4,3 + W:5,T3,4,4,3,2 + C:6,T3,5 + W:7,T2,3,3,2,1 + C:8,T2,7 + W:9,T1,2,2,1,0 + C:10,T1,9 + +Test Case 7: Small deadlock cycle + + Log: + W:0,T1,1,1,2,-1 + W:1,T2,2,2,5,-1 + A:2,T2,1 + R:3,T1,2,2,0 + C:4,T1,3 + +Test Case 8: Three transaction with deadlock cycle + + Log: + R:0,T1,6,6,-1 + R:1,T2,4,4,-1 + R:2,T3,9,9,-1 + W:3,T1,7,7,2,0 + W:4,T2,2,2,4,1 + R:5,T3,6,6,2 + R:6,T2,5,5,4 + W:7,T3,1,1,9,5 + A:8,T2,6 + C:9,T3,7 + W:10,T1,2,2,8,3 + W:11,T1,6,6,2,10 + C:12,T1,11 + +Test Case 9: Small transactions without deadlock cycle + + Log: + W:0,T1,1,1,2,-1 + W:1,T2,3,3,5,-1 + R:2,T1,2,2,0 + R:3,T2,4,4,1 + C:4,T1,2 + C:5,T2,3 + +Test Case 10: Handout example with Deadlock + + Log: + W:0,T1,1,1,5,-1 + R:1,T2,2,2,-1 + R:2,T1,2,2,0 + A:3,T2,1 + W:4,T1,2,2,3,2 + R:5,T1,1,5,4 + C:6,T1,5 + diff --git a/Projects/cs448p4/p4-handout.pdf b/Projects/cs448p4/p4-handout.pdf new file mode 100644 index 0000000..233e9dc Binary files /dev/null and b/Projects/cs448p4/p4-handout.pdf differ diff --git a/Projects/cs448p4/pom.xml b/Projects/cs448p4/pom.xml new file mode 100644 index 0000000..953a83d --- /dev/null +++ b/Projects/cs448p4/pom.xml @@ -0,0 +1,92 @@ + + + + 4.0.0 + + edu.cs.purdue + cs448p4 + 1.0-SNAPSHOT + + cs448p4 + https://www.cs.purdue.edu/homes/bb/cs448f19/ + + + 10 + UTF-8 + ${java.version} + ${java.version} + + + + + junit + junit + 4.11 + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + ${java.version} + + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + maven-assembly-plugin + + + + + test.TestDriver + + + + jar-with-dependencies + + + + + + + diff --git a/Projects/cs448p4/src/main/java/CC/CC.java b/Projects/cs448p4/src/main/java/CC/CC.java new file mode 100644 index 0000000..62ceddd --- /dev/null +++ b/Projects/cs448p4/src/main/java/CC/CC.java @@ -0,0 +1,25 @@ +package CC; +import java.util.List; + +public class CC +{ + + /** + * Notes: + * - Execute all given transactions, using locking. + * - Each element in the transactions List represents all operations performed by one transaction, in order. + * - No operation in a transaction can be executed out of order, but operations may be interleaved with other + * transactions if allowed by the locking. + * - The index of the transaction in the list is equivalent to the transaction ID. + * - Print the log to the console at the end of the method. + * - Return the new db state after executing the transactions. + * @param db the initial status of the db + * @param transactions the schedule, which basically is a {@link List} of transactions. + * @return the final status of the db + */ + public static int[] executeSchedule(int[] db, List transactions) + { + //TODO + return null ; + } +} diff --git a/Projects/cs448p4/src/main/java/CC/Project.java b/Projects/cs448p4/src/main/java/CC/Project.java new file mode 100644 index 0000000..9bcdf55 --- /dev/null +++ b/Projects/cs448p4/src/main/java/CC/Project.java @@ -0,0 +1,52 @@ +package CC; + +import java.util.Arrays; +import java.util.List; + +public class Project +{ + + public static int[] newDB() + { + return new int[]{0,1,2,3,4,5,6,7,8,9}; + } + + public static void main(String[] args) + { + //Test Cases + //1) Simple testcase (handout) + List tc1 = Arrays.asList(new String[]{"W(1,5);R(2);W(2,3);R(1);C","R(1);W(1,2);C"}); + //2) Three transactions + List tc2 = Arrays.asList(new String[]{"R(6);W(7,2);W(5,8);W(6,2);C","R(4);W(2,4);R(5);W(7,3);C","R(9);R(6);W(1,9);C"}); + //3) Deadlocks + List tc3 = Arrays.asList(new String[]{"W(4,1);R(1);W(1,2);C","W(5,2);R(1);R(2);W(2,3);C","W(6,3);R(2);W(2,4);C"}); + //4) No conflicts + List tc4 = Arrays.asList(new String[]{"R(1);R(2);R(3);W(4,1);C","R(1);R(2);R(3);W(5,2);C"}); + //5) Multiple Deadlocks (handout) + List tc5 = Arrays.asList(new String[]{"R(1);W(2,1);C","R(2);R(3);W(1,2);C","R(1);W(3,4);C"}); + //6) Larger Deadlock Cycle + List tc6 = Arrays.asList(new String[]{"R(1);W(2,1);C","R(2);W(3,2);C","R(3);W(4,3);C","R(4);W(1,4);C"}); + //7) Small Deadlock Cycle + List tc7 = Arrays.asList(new String[]{"W(1,2);R(2);C","W(2,5);R(1);C"}); + //8) Three Transactions Deadlock Cycle + List tc8 = Arrays.asList(new String[]{"R(6);W(7,2);W(2,8);W(6,2);C","R(4);W(2,4);R(5);W(7,3);C","R(9);R(6);W(1,9);C"}); + //9) Small Transactions without Deadlock Cycle + List tc9 = Arrays.asList(new String[]{"W(1,2);R(2);C","W(3,5);R(4);C"}); + //10) Testcase with Deadlock Cycle + List tc10 = Arrays.asList(new String[]{"W(1,5);R(2);W(2,3);R(1);C","R(2);R(1);W(1,2);C"}); + + //Consult the ExpectedOutputs.txt for the expected DB state and log + + System.out.println("Schedule 1: Handout Test Case:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc1)) + "\n"); + System.out.println("Schedule 2: Three Transactions Test Case:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc2)) + "\n"); + System.out.println("Schedule 3: Deadlocks Test Case:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc3)) + "\n"); + System.out.println("Schedule 4: No Conflicts Test Case:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc4)) + "\n"); + System.out.println("Schedule 5: Multiple Deadlocks Test Case:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc5)) + "\n"); + System.out.println("Schedule 6: Larger Deadlock Cycle Test Case:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc6)) + "\n"); + System.out.println("Schedule 7: Testcase with two transactions and a deadlock\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc7)) + "\n"); + System.out.println("Schedule 8: Testcase with three transactions and a deadlock:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc8)) + "\n"); + System.out.println("Schedule 9: Testcase with two transactions and no deadlocks:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc9)) + "\n"); + System.out.println("Schedule 10: Testcase with deadlock between two transactions:\n\t" + Arrays.toString(CC.executeSchedule(newDB(),tc10)) + "\n"); + + } +} diff --git a/Projects/cs448p4/src/test/java/tests/CCTest.java b/Projects/cs448p4/src/test/java/tests/CCTest.java new file mode 100644 index 0000000..cf0d569 --- /dev/null +++ b/Projects/cs448p4/src/test/java/tests/CCTest.java @@ -0,0 +1,224 @@ +package tests; + +import static org.junit.Assert.*; + +import java.io.IOException; + + +import CC.*; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import java.util.Arrays; +import java.util.List; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class CCTest { + + public final static boolean OK = true; + public final static boolean FAIL = false; + + public static int[] newDB() + { + return new int[]{0,1,2,3,4,5,6,7,8,9}; + } + + /** + * Schedule 1. Simple testcase with 2 transactions. + * This testcase is shown in the handout, Part 2. + */ + @Test + public void test_A_Simple() + { + // expected output from the given Schedule + int expectedOutput[] = {0, 2, 3, 3, 4, 5, 6, 7, 8, 9}; + + // input: T1, T2 + List tc1 = Arrays.asList(new String[]{"W(1,5);R(2);W(2,3);R(1);C","R(1);W(1,2);C"}); + + // Here we are returning the state of the database after executing Schedule 1 + int methodOutput[] = CC.executeSchedule(newDB(),tc1); + + // Here we are checking whether method output matched with the expected output + // if both match it will pass the test, otherwise it will show an error message + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 2. Testcase with three transactions and no deadlock. + */ + @Test + public void test_B_ThreeTransactions() + { + + int expectedOutput[] = {0, 9, 4, 3, 4, 8, 2, 3, 8, 9}; + + //Testcases + //2) Three transactions + List tc2 = Arrays.asList(new String[]{"R(6);W(7,2);W(5,8);W(6,2);C","R(4);W(2,4);R(5);W(7,3);C","R(9);R(6);W(1,9);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc2); + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 3. Testcase with three transactions and a deadlock. + */ + @Test + public void test_C_Deadlocks() + { + + int expectedOutput[] = {0, 2, 3, 3, 1, 2, 6, 7, 8, 9}; + + //Testcases + //3) Deadlocks + List tc3 = Arrays.asList(new String[]{"W(4,1);R(1);W(1,2);C","W(5,2);R(1);R(2);W(2,3);C","W(6,3);R(2);W(2,4);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc3); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 4. Testcase with multiple deadlocks. + * This testcase is shown in the handout, Part 3 (Deadlock Detection/Handling). + */ + @Test + public void test_D_NoConflicts() + { + + int expectedOutput[] = {0, 1, 2, 3, 1, 2, 6, 7, 8, 9}; + + //Testcases + //4) No conflicts + List tc4 = Arrays.asList(new String[]{"R(1);R(2);R(3);W(4,1);C","R(1);R(2);R(3);W(5,2);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc4); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 5. Testcase with multiple deadlocks. + * This testcase is shown in the handout, Part 3 (Deadlock Detection/Handling). + */ + @Test + public void test_E_MultipleDeadlocks() + { + // In the Schedule 5 there can be two possible outcomes depending of how you handle deadlocks. + int expectedOutput[] = {0, 1, 1, 3, 4, 5, 6, 7, 8, 9}; + + //Testcases + //5) Multiple Deadlocks + List tc5 = Arrays.asList(new String[]{"R(1);W(2,1);C","R(2);R(3);W(1,2);C","R(1);W(3,4);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc5); + + try{ + // if T3 is aborted, and then T2 + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + }catch (AssertionError e) { + // if we abort T2 + int expectedOutput_anth[] = {0, 1, 1, 4, 4, 5, 6, 7, 8, 9}; + assertArrayEquals("output did not match expected result",expectedOutput_anth, methodOutput); + } + } + + /** + * Schedule 6. Testcase with large number of transactions (4) and a deadlock. + */ + @Test + public void test_F_LargerDeadlock() + { + int expectedOutput[] = {0, 1, 1, 2, 3, 5, 6, 7, 8, 9}; + + //Testcases + //6) Larger Deadlock Cycle + List tc6 = Arrays.asList(new String[]{"R(1);W(2,1);C","R(2);W(3,2);C","R(3);W(4,3);C","R(4);W(1,4);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc6); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 7. Testcase with small transactions (2) and a deadlock. + */ + @Test + public void test_G_SmallDeadlock() + { + int expectedOutput[] = {0, 2, 2, 3, 4, 5, 6, 7, 8, 9}; + + //Testcases + //7) Small Deadlock Cycle + List tc7 = Arrays.asList(new String[]{"W(1,2);R(2);C","W(2,5);R(1);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc7); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 8. Testcase with three transactions (2) and a deadlock. + */ + @Test + public void test_H_ThreeTransactionsDeadlock() + { + int expectedOutput[] = {0, 9, 8, 3, 4, 5, 2, 2, 8, 9}; + + //Testcases + //8) Three Transactions Deadlock + List tc8 = Arrays.asList(new String[]{"R(6);W(7,2);W(2,8);W(6,2);C","R(4);W(2,4);R(5);W(7,3);C","R(9);R(6);W(1,9);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc8); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 9. Testcase with small transactions (2) and no deadlocks. + */ + @Test + public void test_I_SmallTransactionsNoDeadlock() + { + int expectedOutput[] = {0, 2, 2, 5, 4, 5, 6, 7, 8, 9}; + + //Testcases + //9) Small Transactions without Deadlock Testcase: + List tc9 = Arrays.asList(new String[]{"W(1,2);R(2);C","W(3,5);R(4);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc9); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } + + /** + * Schedule 10. Testcase with deadlock between two transactions. + */ + @Test + public void test_J_TestCaseDeadlockDeadlock() + { + int expectedOutput[] = {0, 5, 3, 3, 4, 5, 6, 7, 8, 9}; + + //Testcases + //10) Testcase with Deadlock: + List tc10 = Arrays.asList(new String[]{"W(1,5);R(2);W(2,3);R(1);C","R(2);R(1);W(1,2);C"}); + + int methodOutput[] = CC.executeSchedule(newDB(),tc10); + + assertArrayEquals("output did not match expected result",expectedOutput, methodOutput); + + } +} diff --git a/Projects/cs448p4/src/test/java/tests/TestDriver.java b/Projects/cs448p4/src/test/java/tests/TestDriver.java new file mode 100644 index 0000000..db917c9 --- /dev/null +++ b/Projects/cs448p4/src/test/java/tests/TestDriver.java @@ -0,0 +1,16 @@ +package tests; +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; + +public class TestDriver { + public static void main(String[] args) { + Result result = JUnitCore.runClasses(tests.CCTest.class); + + for (Failure failure : result.getFailures()) { + System.out.println(failure.toString()); + } + + System.out.println(result.wasSuccessful()); + } +}