001
014
015 package com.liferay.portal.kernel.test.rule;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.transaction.Isolation;
020 import com.liferay.portal.kernel.transaction.Propagation;
021 import com.liferay.portal.kernel.transaction.TransactionConfig;
022 import com.liferay.portal.kernel.transaction.Transactional;
023
024 import java.lang.reflect.Method;
025
026 import java.util.ArrayDeque;
027 import java.util.Deque;
028
029 import org.junit.After;
030 import org.junit.AfterClass;
031 import org.junit.Assert;
032 import org.junit.Before;
033 import org.junit.BeforeClass;
034 import org.junit.Test;
035
036
039 public class BaseTransactionalTestRuleTest {
040
041 @BeforeClass
042 public static void setUpClass1() throws ReflectiveOperationException {
043 assertTransactionConfig();
044 }
045
046 @BeforeClass
047 @Transactional
048 public static void setUpClass2() throws ReflectiveOperationException {
049 assertTransactionConfig();
050 }
051
052 @BeforeClass
053 @Transactional(propagation = Propagation.REQUIRES_NEW)
054 public static void setUpClass3() throws ReflectiveOperationException {
055 assertTransactionConfig();
056 }
057
058 @AfterClass
059 public static void tearDownClass1() throws ReflectiveOperationException {
060 assertTransactionConfig();
061 }
062
063 @AfterClass
064 @Transactional
065 public static void tearDownClass2() throws ReflectiveOperationException {
066 assertTransactionConfig();
067 }
068
069 @AfterClass
070 @Transactional(
071 isolation = Isolation.REPEATABLE_READ, readOnly = true,
072 rollbackFor = {Exception.class}
073 )
074 public static void tearDownClass3() throws ReflectiveOperationException {
075 assertTransactionConfig();
076 }
077
078 @Before
079 public void setUp1() throws ReflectiveOperationException {
080 assertTransactionConfig();
081 }
082
083 @Before
084 @Transactional
085 public void setUp2() throws ReflectiveOperationException {
086 assertTransactionConfig();
087 }
088
089 @Before
090 @Transactional(enabled = false)
091 public void setUp3() throws ReflectiveOperationException {
092 assertTransactionConfig();
093 }
094
095 @After
096 public void tearDown1() throws ReflectiveOperationException {
097 assertTransactionConfig();
098 }
099
100 @After
101 @Transactional
102 public void tearDown2() throws ReflectiveOperationException {
103 assertTransactionConfig();
104 }
105
106 @After
107 @Transactional(noRollbackFor = {Exception.class}, timeout = 10)
108 public void tearDown3() throws ReflectiveOperationException {
109 assertTransactionConfig();
110 }
111
112 @Test
113 public void test1() throws ReflectiveOperationException {
114 assertTransactionConfig();
115 }
116
117 @Test
118 @Transactional
119 public void test2() throws ReflectiveOperationException {
120 assertTransactionConfig();
121 }
122
123 @Test
124 @Transactional(
125 noRollbackForClassName = "RuntimeException",
126 propagation = Propagation.SUPPORTS
127 )
128 public void test3() throws ReflectiveOperationException {
129 assertTransactionConfig();
130 }
131
132 protected static void assertTransactionConfig()
133 throws ReflectiveOperationException {
134
135 Thread currentThread = Thread.currentThread();
136
137 StackTraceElement[] stackTraceElements = currentThread.getStackTrace();
138
139 StackTraceElement stackTraceElement = stackTraceElements[2];
140
141 Method method = BaseTransactionalTestRuleTest.class.getMethod(
142 stackTraceElement.getMethodName());
143
144 Deque<TransactionConfig> transactionConfigs =
145 transactionConfigThreadLocal.get();
146
147 TransactionConfig transactionConfig = transactionConfigs.peek();
148
149 Transactional transactional = method.getAnnotation(Transactional.class);
150
151 if (transactional == null) {
152 Assert.assertEquals(
153 TransactionConfig.Factory.create(
154 Propagation.SUPPORTS,
155 new Class<?>[] {
156 PortalException.class, SystemException.class
157 }),
158 transactionConfig);
159
160 return;
161 }
162
163 Assert.assertEquals(
164 TransactionConfig.Factory.create(
165 transactional.isolation(), transactional.propagation(),
166 transactional.readOnly(), transactional.timeout(),
167 transactional.rollbackFor(),
168 transactional.rollbackForClassName(),
169 transactional.noRollbackFor(),
170 transactional.noRollbackForClassName()),
171 transactionConfig);
172 }
173
174 protected static final ThreadLocal<Deque<TransactionConfig>>
175 transactionConfigThreadLocal =
176 new ThreadLocal<Deque<TransactionConfig>>() {
177
178 @Override
179 protected Deque<TransactionConfig> initialValue() {
180 return new ArrayDeque<>();
181 }
182
183 };
184
185 }