|
16 | 16 | // under the License. |
17 | 17 | package com.cloud.utils; |
18 | 18 |
|
| 19 | +import java.io.IOException; |
| 20 | +import java.lang.reflect.Field; |
| 21 | +import java.sql.Connection; |
| 22 | +import java.sql.PreparedStatement; |
| 23 | +import java.sql.ResultSet; |
| 24 | +import java.sql.SQLException; |
| 25 | +import java.sql.Statement; |
| 26 | +import java.util.HashMap; |
| 27 | +import java.util.Map; |
| 28 | + |
19 | 29 | import javax.persistence.Column; |
| 30 | +import javax.persistence.Table; |
| 31 | +import javax.sql.DataSource; |
20 | 32 |
|
| 33 | +import org.junit.After; |
21 | 34 | import org.junit.Assert; |
| 35 | +import org.junit.Before; |
22 | 36 | import org.junit.Ignore; |
23 | 37 | import org.junit.Test; |
| 38 | +import org.junit.runner.RunWith; |
| 39 | +import org.mockito.Mock; |
| 40 | +import org.mockito.Mockito; |
| 41 | +import org.mockito.runners.MockitoJUnitRunner; |
24 | 42 |
|
25 | 43 | import com.cloud.utils.db.DbUtil; |
| 44 | +import com.cloud.utils.db.TransactionLegacy; |
26 | 45 |
|
| 46 | +@RunWith(MockitoJUnitRunner.class) |
27 | 47 | public class DbUtilTest { |
28 | 48 |
|
| 49 | + @Mock |
| 50 | + Connection connection; |
| 51 | + |
| 52 | + @Mock |
| 53 | + PreparedStatement preparedStatement; |
| 54 | + |
| 55 | + @Mock |
| 56 | + Statement statement; |
| 57 | + |
| 58 | + @Mock |
| 59 | + ResultSet resultSet; |
| 60 | + |
| 61 | + @Mock |
| 62 | + DataSource dataSource; |
| 63 | + |
| 64 | + DataSource backup; |
| 65 | + |
| 66 | + Map<String, Connection> connectionMapBackup = null; |
| 67 | + |
| 68 | + Map<String, Connection> connectionMap = null; |
| 69 | + |
| 70 | + @Table(name = "test_table") |
29 | 71 | static class Testbean { |
30 | 72 | String noAnnotation; |
31 | 73 | @Column() |
@@ -78,4 +120,152 @@ public void isPersistable() throws SecurityException, NoSuchFieldException { |
78 | 120 | .getDeclaredField("instanceField"))); |
79 | 121 | } |
80 | 122 |
|
| 123 | + class Bar { |
| 124 | + |
| 125 | + } |
| 126 | + |
| 127 | + @Test |
| 128 | + public void getTableName() { |
| 129 | + Assert.assertEquals("test_table", DbUtil.getTableName(Testbean.class)); |
| 130 | + Assert.assertEquals("Bar", DbUtil.getTableName(Bar.class)); |
| 131 | + } |
| 132 | + |
| 133 | + @SuppressWarnings("unchecked") |
| 134 | + @Before |
| 135 | + public void setup() throws SecurityException, NoSuchFieldException, |
| 136 | + IllegalArgumentException, IllegalAccessException { |
| 137 | + Field globalLocks = DbUtil.class |
| 138 | + .getDeclaredField("s_connectionForGlobalLocks"); |
| 139 | + globalLocks.setAccessible(true); |
| 140 | + connectionMapBackup = (Map<String, Connection>) globalLocks.get(null); |
| 141 | + connectionMap = new HashMap<String, Connection>(); |
| 142 | + globalLocks.set(null, connectionMap); |
| 143 | + |
| 144 | + Field dsField = TransactionLegacy.class.getDeclaredField("s_ds"); |
| 145 | + dsField.setAccessible(true); |
| 146 | + backup = (DataSource) dsField.get(null); |
| 147 | + dsField.set(null, dataSource); |
| 148 | + } |
| 149 | + |
| 150 | + @After |
| 151 | + public void cleanup() throws SecurityException, NoSuchFieldException, |
| 152 | + IllegalArgumentException, IllegalAccessException { |
| 153 | + Field globalLocks = DbUtil.class |
| 154 | + .getDeclaredField("s_connectionForGlobalLocks"); |
| 155 | + globalLocks.setAccessible(true); |
| 156 | + globalLocks.set(null, connectionMapBackup); |
| 157 | + |
| 158 | + Field dsField = TransactionLegacy.class.getDeclaredField("s_ds"); |
| 159 | + dsField.setAccessible(true); |
| 160 | + dsField.set(null, backup); |
| 161 | + } |
| 162 | + |
| 163 | + @Test |
| 164 | + public void getGlobalLock() throws SQLException { |
| 165 | + Mockito.when(dataSource.getConnection()).thenReturn(connection); |
| 166 | + Mockito.when(connection.prepareStatement(Mockito.anyString())) |
| 167 | + .thenReturn(preparedStatement); |
| 168 | + Mockito.when(preparedStatement.executeQuery()).thenReturn(resultSet); |
| 169 | + Mockito.when(resultSet.first()).thenReturn(true); |
| 170 | + Mockito.when(resultSet.getInt(1)).thenReturn(1); |
| 171 | + Assert.assertTrue(DbUtil.getGlobalLock("TEST", 600)); |
| 172 | + |
| 173 | + Mockito.verify(connection).prepareStatement(Mockito.anyString()); |
| 174 | + Mockito.verify(preparedStatement).close(); |
| 175 | + Mockito.verify(resultSet).close(); |
| 176 | + } |
| 177 | + |
| 178 | + @Test |
| 179 | + public void getGlobalLockTimeout() throws SQLException { |
| 180 | + Mockito.when(dataSource.getConnection()).thenReturn(connection); |
| 181 | + Mockito.when(connection.prepareStatement(Mockito.anyString())) |
| 182 | + .thenReturn(preparedStatement); |
| 183 | + Mockito.when(preparedStatement.executeQuery()).thenReturn(resultSet); |
| 184 | + Mockito.when(resultSet.first()).thenReturn(true); |
| 185 | + Mockito.when(resultSet.getInt(1)).thenReturn(0); |
| 186 | + Assert.assertFalse(DbUtil.getGlobalLock("TEST", 600)); |
| 187 | + |
| 188 | + Mockito.verify(connection).prepareStatement(Mockito.anyString()); |
| 189 | + Mockito.verify(preparedStatement).close(); |
| 190 | + Mockito.verify(resultSet).close(); |
| 191 | + Mockito.verify(connection).close(); |
| 192 | + |
| 193 | + // if any error happens, the connection map must be cleared |
| 194 | + Assert.assertTrue(connectionMap.isEmpty()); |
| 195 | + } |
| 196 | + |
| 197 | + @Test |
| 198 | + public void closeNull() { |
| 199 | + DbUtil.closeStatement((Statement) null); |
| 200 | + DbUtil.closeConnection((Connection) null); |
| 201 | + DbUtil.closeResultSet((ResultSet) null); |
| 202 | + // no exception should be thrown |
| 203 | + } |
| 204 | + |
| 205 | + @Test |
| 206 | + public void closeConnection() throws IOException, SQLException { |
| 207 | + DbUtil.closeConnection(connection); |
| 208 | + Mockito.verify(connection).close(); |
| 209 | + } |
| 210 | + |
| 211 | + @Test |
| 212 | + public void closeConnectionFail() throws IOException, SQLException { |
| 213 | + Mockito.doThrow(new SQLException("it is all right")).when(connection) |
| 214 | + .close(); |
| 215 | + DbUtil.closeConnection(connection); |
| 216 | + Mockito.verify(connection).close(); |
| 217 | + } |
| 218 | + |
| 219 | + @Test |
| 220 | + public void closeStatement() throws IOException, SQLException { |
| 221 | + DbUtil.closeStatement(statement); |
| 222 | + Mockito.verify(statement).close(); |
| 223 | + } |
| 224 | + |
| 225 | + @Test |
| 226 | + public void closeStatementFail() throws IOException, SQLException { |
| 227 | + Mockito.doThrow(new SQLException("it is all right")).when(statement) |
| 228 | + .close(); |
| 229 | + DbUtil.closeStatement(statement); |
| 230 | + Mockito.verify(statement).close(); |
| 231 | + } |
| 232 | + |
| 233 | + @Test |
| 234 | + public void closeResultSet() throws IOException, SQLException { |
| 235 | + DbUtil.closeResultSet(resultSet); |
| 236 | + Mockito.verify(resultSet).close(); |
| 237 | + } |
| 238 | + |
| 239 | + @Test |
| 240 | + public void closeResultSetFail() throws IOException, SQLException { |
| 241 | + Mockito.doThrow(new SQLException("it is all right")).when(resultSet) |
| 242 | + .close(); |
| 243 | + DbUtil.closeResultSet(resultSet); |
| 244 | + Mockito.verify(resultSet).close(); |
| 245 | + } |
| 246 | + |
| 247 | + @Test |
| 248 | + @Ignore |
| 249 | + //can not be performed since assertion embedded in this branch of execution |
| 250 | + public void releaseGlobalLockNotexisting() throws SQLException { |
| 251 | + Assert.assertFalse(DbUtil.releaseGlobalLock("notexisting")); |
| 252 | + Mockito.verify(dataSource, Mockito.never()).getConnection(); |
| 253 | + } |
| 254 | + |
| 255 | + @Test |
| 256 | + public void releaseGlobalLock() throws SQLException { |
| 257 | + Mockito.when(connection.prepareStatement(Mockito.anyString())) |
| 258 | + .thenReturn(preparedStatement); |
| 259 | + Mockito.when(preparedStatement.executeQuery()).thenReturn(resultSet); |
| 260 | + Mockito.when(resultSet.first()).thenReturn(true); |
| 261 | + Mockito.when(resultSet.getInt(1)).thenReturn(1); |
| 262 | + connectionMap.put("testLock", connection); |
| 263 | + Assert.assertTrue(DbUtil.releaseGlobalLock("testLock")); |
| 264 | + |
| 265 | + Mockito.verify(resultSet).close(); |
| 266 | + Mockito.verify(preparedStatement).close(); |
| 267 | + Mockito.verify(connection).close(); |
| 268 | + Assert.assertFalse(connectionMap.containsKey("testLock")); |
| 269 | + } |
| 270 | + |
81 | 271 | } |
0 commit comments