1 package org.apache.onami.persist;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.hamcrest.Matcher;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.internal.matchers.GreaterThan;
26
27 import javax.transaction.HeuristicMixedException;
28 import javax.transaction.HeuristicRollbackException;
29 import javax.transaction.NotSupportedException;
30 import javax.transaction.RollbackException;
31 import javax.transaction.SystemException;
32 import javax.transaction.UserTransaction;
33
34 import static java.lang.System.currentTimeMillis;
35 import static javax.transaction.Status.STATUS_ACTIVE;
36 import static javax.transaction.Status.STATUS_COMMITTED;
37 import static javax.transaction.Status.STATUS_COMMITTING;
38 import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
39 import static javax.transaction.Status.STATUS_NO_TRANSACTION;
40 import static javax.transaction.Status.STATUS_PREPARED;
41 import static javax.transaction.Status.STATUS_PREPARING;
42 import static javax.transaction.Status.STATUS_ROLLEDBACK;
43 import static javax.transaction.Status.STATUS_ROLLING_BACK;
44 import static javax.transaction.Status.STATUS_UNKNOWN;
45 import static org.hamcrest.CoreMatchers.is;
46 import static org.junit.Assert.assertThat;
47 import static org.mockito.Mockito.doReturn;
48 import static org.mockito.Mockito.doThrow;
49 import static org.mockito.Mockito.mock;
50 import static org.mockito.Mockito.times;
51 import static org.mockito.Mockito.verify;
52
53
54
55
56 public class UserTransactionFacadeTest
57 {
58
59 private UserTransactionFacade sut;
60
61 private UserTransaction txn;
62
63 @Before
64 public void setup()
65 throws Exception
66 {
67 txn = mock( UserTransaction.class );
68 sut = new UserTransactionFacade( txn );
69 }
70
71 @Test
72 public void beginOnTxn()
73 throws Exception
74 {
75 sut.begin();
76 verify( txn ).begin();
77 }
78
79 @Test( expected = RuntimeException.class )
80 public void beginWithNotSupportedException()
81 throws Exception
82 {
83 doThrow( new NotSupportedException() ).when( txn ).begin();
84 sut.begin();
85 }
86
87 @Test( expected = RuntimeException.class )
88 public void beginWithSystemException()
89 throws Exception
90 {
91 doThrow( new SystemException() ).when( txn ).begin();
92 sut.begin();
93 }
94
95 @Test
96 public void commitOnTxn()
97 throws Exception
98 {
99 sut.commit();
100 verify( txn ).commit();
101 }
102
103 @Test( expected = RuntimeException.class )
104 public void commitWithSecurityException()
105 throws Exception
106 {
107 doThrow( new SecurityException() ).when( txn ).commit();
108 sut.commit();
109 }
110
111 @Test( expected = RuntimeException.class )
112 public void commitWithIllegalStateException()
113 throws Exception
114 {
115 doThrow( new IllegalStateException() ).when( txn ).commit();
116 sut.commit();
117 }
118
119 @Test( expected = RuntimeException.class )
120 public void commitWithRollbackException()
121 throws Exception
122 {
123 doThrow( new RollbackException() ).when( txn ).commit();
124 sut.commit();
125 }
126
127 @Test( expected = RuntimeException.class )
128 public void commitWithHeuristicMixedException()
129 throws Exception
130 {
131 doThrow( new HeuristicMixedException() ).when( txn ).commit();
132 sut.commit();
133 }
134
135 @Test( expected = RuntimeException.class )
136 public void commitWithHeuristicRollbackException()
137 throws Exception
138 {
139 doThrow( new HeuristicRollbackException() ).when( txn ).commit();
140 sut.commit();
141 }
142
143 @Test( expected = RuntimeException.class )
144 public void commitWithSystemException()
145 throws Exception
146 {
147 doThrow( new SystemException() ).when( txn ).commit();
148 sut.commit();
149 }
150
151 @Test
152 public void rollbackOnTxn()
153 throws Exception
154 {
155 sut.rollback();
156 verify( txn ).rollback();
157 }
158
159 @Test( expected = RuntimeException.class )
160 public void rollbackWithIllegalStateException()
161 throws Exception
162 {
163 doThrow( new IllegalStateException() ).when( txn ).rollback();
164 sut.rollback();
165 }
166
167 @Test( expected = RuntimeException.class )
168 public void rollbackWithSecurityException()
169 throws Exception
170 {
171 doThrow( new SecurityException() ).when( txn ).rollback();
172 sut.rollback();
173 }
174
175 @Test( expected = RuntimeException.class )
176 public void rollbackWithSystemException()
177 throws Exception
178 {
179 doThrow( new SystemException() ).when( txn ).rollback();
180 sut.rollback();
181 }
182
183 @Test
184 public void setRollbackOnlyOnTxn()
185 throws Exception
186 {
187 sut.setRollbackOnly();
188 verify( txn ).setRollbackOnly();
189 }
190
191 @Test( expected = RuntimeException.class )
192 public void setRollbackOnlyWithIllegalStateException()
193 throws Exception
194 {
195 doThrow( new IllegalStateException() ).when( txn ).setRollbackOnly();
196 sut.setRollbackOnly();
197 }
198
199 @Test( expected = RuntimeException.class )
200 public void setRollbackOnlyWithSystemException()
201 throws Exception
202 {
203 doThrow( new SystemException() ).when( txn ).setRollbackOnly();
204 sut.setRollbackOnly();
205 }
206
207 @Test
208 public void getRollbackOnlyUsesStatusOfTransaction()
209 throws Exception
210 {
211 assertThatRollbackOnlyOf( STATUS_ACTIVE, is( false ) );
212 assertThatRollbackOnlyOf( STATUS_MARKED_ROLLBACK, is( true ) );
213 assertThatRollbackOnlyOf( STATUS_PREPARED, is( false ) );
214 assertThatRollbackOnlyOf( STATUS_COMMITTED, is( false ) );
215 assertThatRollbackOnlyOf( STATUS_ROLLEDBACK, is( true ) );
216 assertThatRollbackOnlyOf( STATUS_UNKNOWN, is( false ) );
217 assertThatRollbackOnlyOf( STATUS_NO_TRANSACTION, is( false ) );
218 assertThatRollbackOnlyOf( STATUS_PREPARING, is( false ) );
219 assertThatRollbackOnlyOf( STATUS_COMMITTING, is( false ) );
220 assertThatRollbackOnlyOf( STATUS_ROLLING_BACK, is( true ) );
221 }
222
223 @Test( expected = RuntimeException.class )
224 public void getRollbackOnlyWithSystemException()
225 throws Exception
226 {
227 doThrow( new SystemException() ).when( txn ).getStatus();
228 sut.getRollbackOnly();
229 }
230
231 @Test
232 public void getRollbackOnlyRetriesWhenStatusUnknown()
233 throws Exception
234 {
235 final long start = currentTimeMillis();
236 doReturn( STATUS_UNKNOWN ).when( txn ).getStatus();
237 sut.getRollbackOnly();
238 final long duration = currentTimeMillis() - start;
239
240 verify( txn, times( 9 ) ).getStatus();
241 assertThat( duration, is( greaterThan( 1000L ) ) );
242 }
243
244 @Test
245 public void isActiveUsesStatusOfTransaction()
246 throws Exception
247 {
248 assertThatIsActiveOf( STATUS_ACTIVE, is( true ) );
249 assertThatIsActiveOf( STATUS_MARKED_ROLLBACK, is( true ) );
250 assertThatIsActiveOf( STATUS_PREPARED, is( true ) );
251 assertThatIsActiveOf( STATUS_COMMITTED, is( true ) );
252 assertThatIsActiveOf( STATUS_ROLLEDBACK, is( true ) );
253 assertThatIsActiveOf( STATUS_UNKNOWN, is( true ) );
254 assertThatIsActiveOf( STATUS_NO_TRANSACTION, is( false ) );
255 assertThatIsActiveOf( STATUS_PREPARING, is( true ) );
256 assertThatIsActiveOf( STATUS_COMMITTING, is( true ) );
257 assertThatIsActiveOf( STATUS_ROLLING_BACK, is( true ) );
258 }
259
260 @Test( expected = RuntimeException.class )
261 public void isActiveWithSystemException()
262 throws Exception
263 {
264 doThrow( new SystemException() ).when( txn ).getStatus();
265 sut.isActive();
266 }
267
268 @Test
269 public void isActiveOnlyRetriesWhenStatusUnknown()
270 throws Exception
271 {
272 final long start = currentTimeMillis();
273 doReturn( STATUS_UNKNOWN ).when( txn ).getStatus();
274 sut.isActive();
275 final long duration = currentTimeMillis() - start;
276
277 verify( txn, times( 9 ) ).getStatus();
278 assertThat( duration, is( greaterThan( 1000L ) ) );
279 }
280
281 private void assertThatRollbackOnlyOf( int status, Matcher<Boolean> expected )
282 throws Exception
283 {
284 doReturn( status ).when( txn ).getStatus();
285 final boolean result = sut.getRollbackOnly();
286 assertThat( result, is( expected ) );
287 }
288
289 private void assertThatIsActiveOf( int status, Matcher<Boolean> expected )
290 throws Exception
291 {
292 doReturn( status ).when( txn ).getStatus();
293 final boolean result = sut.isActive();
294 assertThat( result, is( expected ) );
295 }
296
297 private Matcher<Long> greaterThan( long expected )
298 {
299 return new GreaterThan<Long>( expected );
300 }
301
302 }