View Javadoc
1   package com.atlassian.sal.core.rdbms;
2   
3   import io.atlassian.fugue.Option;
4   import com.atlassian.sal.api.rdbms.ConnectionCallback;
5   import com.atlassian.sal.api.rdbms.RdbmsException;
6   import com.atlassian.sal.spi.HostConnectionAccessor;
7   import org.junit.Before;
8   import org.junit.Rule;
9   import org.junit.Test;
10  import org.junit.rules.ExpectedException;
11  import org.mockito.Mock;
12  import org.mockito.Mockito;
13  import org.mockito.MockitoAnnotations;
14  
15  import java.sql.Connection;
16  import java.sql.SQLException;
17  
18  import static org.hamcrest.Matchers.nullValue;
19  import static org.hamcrest.core.Is.is;
20  import static org.junit.Assert.assertThat;
21  import static org.mockito.ArgumentMatchers.any;
22  import static org.mockito.Mockito.doThrow;
23  import static org.mockito.Mockito.never;
24  import static org.mockito.Mockito.verify;
25  import static org.mockito.Mockito.when;
26  
27  public class TestDefaultTransactionalExecutor {
28      @Rule
29      public ExpectedException expectedException = ExpectedException.none();
30  
31      private DefaultTransactionalExecutor transactionalExecutor;
32  
33      @Mock
34      private HostConnectionAccessor hostConnectionAccessor;
35      @Mock
36      private Connection connection;
37      @Mock
38      private ConnectionCallback<Object> callback;
39      @Mock
40      private Object result;
41  
42      private WrappedConnection wrappedConnection;
43  
44      private Throwable callbackThrows;
45  
46      @Before
47      public void setUp() {
48          MockitoAnnotations.initMocks(this);
49  
50          transactionalExecutor = new DefaultTransactionalExecutor(hostConnectionAccessor, false, false);
51  
52          callbackThrows = null;
53  
54          when(hostConnectionAccessor.execute(Mockito.anyBoolean(), Mockito.anyBoolean(), any())).thenAnswer(i -> {
55              ConnectionCallback callback = (ConnectionCallback) i.getArguments()[2];
56              return callback.execute(connection);
57          });
58  
59          // grab a hold of the wrapped connection each time
60          when(callback.execute(any(WrappedConnection.class))).thenAnswer(i -> {
61              wrappedConnection = (WrappedConnection) i.getArguments()[0];
62              if (callbackThrows != null) {
63                  throw callbackThrows;
64              } else {
65                  return result;
66              }
67          });
68      }
69  
70      @Test
71      public void testGetSchemaName() {
72          when(hostConnectionAccessor.getSchemaName()).thenReturn(Option.option("schema"));
73  
74          assertThat(transactionalExecutor.getSchemaName().get(), is("schema"));
75      }
76  
77      @Test
78      public void testChangeProperties() {
79          transactionalExecutor.readOnly();
80          assertThat(transactionalExecutor.readOnly, is(true));
81  
82          transactionalExecutor.readWrite();
83          assertThat(transactionalExecutor.readOnly, is(false));
84  
85          transactionalExecutor.newTransaction();
86          assertThat(transactionalExecutor.newTransaction, is(true));
87  
88          transactionalExecutor.existingTransaction();
89          assertThat(transactionalExecutor.newTransaction, is(false));
90      }
91  
92      @Test
93      public void testExecute() throws SQLException {
94          assertThat(transactionalExecutor.execute(callback), is(result));
95          assertThat(wrappedConnection.connection, nullValue());
96  
97          verify(callback).execute(any(WrappedConnection.class));
98          verify(connection, never()).commit();
99          verify(connection, never()).rollback();
100     }
101 
102     @Test
103     public void testExecuteFailsOnAutoCommit() throws SQLException {
104         when(connection.getAutoCommit()).thenReturn(true);
105 
106         expectedException.expect(IllegalStateException.class);
107 
108         transactionalExecutor.execute(callback);
109     }
110 
111     @Test
112     public void testExecuteAutoCommitFails() throws SQLException {
113         SQLException exception = new SQLException("horrible getAutoCommit error");
114         doThrow(exception).when(connection).getAutoCommit();
115 
116         expectedException.expect(RdbmsException.class);
117         expectedException.expectCause(is(exception));
118 
119         transactionalExecutor.execute(callback);
120         verify(callback, never()).execute(any(WrappedConnection.class));
121     }
122 
123     @Test
124     public void testExecuteFailsOnAutoCommitGetFail() throws SQLException {
125         when(connection.getAutoCommit()).thenThrow(new SQLException("horrible getAutoCommit exception"));
126 
127         expectedException.expect(RdbmsException.class);
128 
129         transactionalExecutor.execute(callback);
130     }
131 }