BAEL-855 stm (#1855)

* BAEL-855 code for the STM article

* BAEL-855 method ordering

* BAEL-855 Better test case

* BAEL-855 formatting

* BAEL-855 rename

* BAEL-855 change to expected

* Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-855_stm

# Conflicts:
#	libraries/pom.xml
This commit is contained in:
Tomasz Lelek
2017-05-16 16:53:47 +02:00
committed by pedja4
parent ee79ac3a02
commit ce43d80f8b
3 changed files with 213 additions and 15 deletions
@@ -0,0 +1,145 @@
package com.baeldung.stm;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.junit.Assert.assertTrue;
public class AccountTest {
@Test
public void givenAccount_whenDecrement_thenShouldReturnProperValue() {
//given
Account a = new Account(10);
//when
a.adjustBy(-5);
//then
assertThat(a.getBalance()).isEqualTo(5);
}
@Test(expected = IllegalArgumentException.class)
public void givenAccount_whenDecrementTooMuch_thenShouldThrow() {
//given
Account a = new Account(10);
//when
a.adjustBy(-11);
}
@Test
public void givenTwoThreads_whenBothApplyOperation_thenShouldThrow() throws InterruptedException {
//given
ExecutorService ex = Executors.newFixedThreadPool(2);
Account a = new Account(10);
CountDownLatch countDownLatch = new CountDownLatch(1);
AtomicBoolean exceptionThrown = new AtomicBoolean(false);
//when
ex.submit(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
a.adjustBy(-6);
} catch (IllegalArgumentException e) {
exceptionThrown.set(true);
}
});
ex.submit(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
a.adjustBy(-5);
} catch (IllegalArgumentException e) {
exceptionThrown.set(true);
}
});
countDownLatch.countDown();
ex.awaitTermination(1, TimeUnit.SECONDS);
ex.shutdown();
//then
assertTrue(exceptionThrown.get());
}
@Test
public void givenTwoAccounts_whenFailedWhileTransferring_thenShouldRollbackTransaction() {
//given
final Account a = new Account(10);
final Account b = new Account(10);
//when
a.transferTo(b, 5);
//then
assertThat(a.getBalance()).isEqualTo(5);
assertThat(b.getBalance()).isEqualTo(15);
//and
try {
a.transferTo(b, 20);
} catch (final IllegalArgumentException e) {
System.out.println("failed to transfer money");
}
//then
assertThat(a.getBalance()).isEqualTo(5);
assertThat(b.getBalance()).isEqualTo(15);
}
@Test
public void givenTwoThreads_whenBothTryToTransfer_thenShouldNotDeadlock() throws InterruptedException {
//given
ExecutorService ex = Executors.newFixedThreadPool(2);
final Account a = new Account(10);
final Account b = new Account(10);
CountDownLatch countDownLatch = new CountDownLatch(1);
//when
ex.submit(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
a.transferTo(b, 10);
});
ex.submit(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
b.transferTo(a, 1);
});
countDownLatch.countDown();
ex.awaitTermination(1, TimeUnit.SECONDS);
ex.shutdown();
//then
assertThat(a.getBalance()).isEqualTo(1);
assertThat(b.getBalance()).isEqualTo(19);
}
}