adding account unit test
This commit is contained in:
parent
12ef94be39
commit
c9453fe33a
|
@ -5,7 +5,6 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class AccountUnitTest {
|
public class AccountUnitTest {
|
||||||
|
@ -20,7 +19,8 @@ public class AccountUnitTest {
|
||||||
@Test
|
@Test
|
||||||
public void zeroBalanceInitializationTest() {
|
public void zeroBalanceInitializationTest() {
|
||||||
assertEquals(0, account.getBalance());
|
assertEquals(0, account.getBalance());
|
||||||
assertTrue(account.getTransactionDates().isEmpty());
|
assertEquals(0, account.getTransactionCount());
|
||||||
|
assertEquals(0, account.getCurrentThreadCASFailureCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -44,60 +44,55 @@ public class AccountUnitTest {
|
||||||
assertEquals(defaultBalance - moneyToWithdraw, account.getBalance());
|
assertEquals(defaultBalance - moneyToWithdraw, account.getBalance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void withdrawWithoutSufficientBalanceTest() {
|
|
||||||
assertThrows(RuntimeException.class, () -> account.withdraw(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void abaProblemTest() throws InterruptedException {
|
public void abaProblemTest() throws InterruptedException {
|
||||||
final int defaultBalance = 50;
|
final int defaultBalance = 50;
|
||||||
|
|
||||||
final int amountToWithdrawByThreadA = 20;
|
final int amountToWithdrawByThread1 = 20;
|
||||||
final int amountToWithdrawByThreadB = 10;
|
final int amountToWithdrawByThread2 = 10;
|
||||||
final int amountToDepositByThreadB = 10;
|
final int amountToDepositByThread2 = 10;
|
||||||
|
|
||||||
assertTrue(account.getTransactionDates().isEmpty());
|
assertEquals(0, account.getTransactionCount());
|
||||||
|
assertEquals(0, account.getCurrentThreadCASFailureCount());
|
||||||
account.deposit(defaultBalance);
|
account.deposit(defaultBalance);
|
||||||
assertEquals(1, account.getTransactionDates().size());
|
assertEquals(1, account.getTransactionCount());
|
||||||
|
|
||||||
|
Thread thread1 = new Thread(() -> {
|
||||||
|
|
||||||
|
// this will take longer due to the name of the thread
|
||||||
|
assertTrue(account.withdraw(amountToWithdrawByThread1));
|
||||||
|
|
||||||
|
// thread 1 fails to capture ABA problem
|
||||||
|
assertNotEquals(1, account.getCurrentThreadCASFailureCount());
|
||||||
|
|
||||||
Thread threadA = new Thread(() -> {
|
|
||||||
try {
|
|
||||||
// this will take longer due to the name of the thread
|
|
||||||
assertTrue(account.withdraw(amountToWithdrawByThreadA));
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}, "thread1");
|
}, "thread1");
|
||||||
|
|
||||||
Thread threadB = new Thread(() -> {
|
Thread thread2 = new Thread(() -> {
|
||||||
|
|
||||||
assertTrue(account.deposit(amountToDepositByThreadB));
|
assertTrue(account.deposit(amountToDepositByThread2));
|
||||||
assertEquals(defaultBalance + amountToDepositByThreadB, account.getBalance());
|
assertEquals(defaultBalance + amountToDepositByThread2, account.getBalance());
|
||||||
try {
|
|
||||||
// this will be fast due to the name of the thread
|
// this will be fast due to the name of the thread
|
||||||
assertTrue(account.withdraw(amountToWithdrawByThreadB));
|
assertTrue(account.withdraw(amountToWithdrawByThread2));
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// thread 1 didn't finish yet, so the original value will be in place for it
|
// thread 1 didn't finish yet, so the original value will be in place for it
|
||||||
assertEquals(defaultBalance, account.getBalance());
|
assertEquals(defaultBalance, account.getBalance());
|
||||||
|
|
||||||
|
assertEquals(0, account.getCurrentThreadCASFailureCount());
|
||||||
}, "thread2");
|
}, "thread2");
|
||||||
|
|
||||||
threadA.start();
|
thread1.start();
|
||||||
threadB.start();
|
thread2.start();
|
||||||
threadA.join();
|
thread1.join();
|
||||||
threadB.join();
|
thread2.join();
|
||||||
|
|
||||||
// compareAndSet operation succeeds for thread 1
|
// compareAndSet operation succeeds for thread 1
|
||||||
assertEquals(defaultBalance - amountToWithdrawByThreadA, account.getBalance());
|
assertEquals(defaultBalance - amountToWithdrawByThread1, account.getBalance());
|
||||||
|
|
||||||
//but there are other transactions
|
//but there are other transactions
|
||||||
assertNotEquals(2, account.getTransactionDates().size());
|
assertNotEquals(2, account.getTransactionCount());
|
||||||
|
|
||||||
// thread 2 did two modifications as well
|
// thread 2 did two modifications as well
|
||||||
assertEquals(4, account.getTransactionDates().size());
|
assertEquals(4, account.getTransactionCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue