View Javadoc
1   package org.apache.onami.persist;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * Test for {@link UserTransactionFacade}.
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 }