+
+ @Rule
+ public ExpectedException expectedEx = ExpectedException.none();
+
+ @Test
+ public void testAcquireLockNullOwner() throws LockException {
+ MySqlLockManager lockManager = new MySqlLockManager();
+ expectedEx.expect(LockRuntimeException.class);
+ lockManager.acquireLock(null, null, 0);
+ }
+
+ @Test
+ public void testIsLocked() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Mockito.doThrow(new SQLException()).when(lockManager).loadLockRecord(Mockito.any(Connection.class), Mockito.anyString());
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(Mockito.mock(Connection.class));
+ lockManager.setConnectionFactory(connectionFactory);
+ expectedEx.expect(LockRuntimeException.class);
+ lockManager.isLocked(" ");
+ }
+
+ @Test
+ public void testGetLockOwnerExceptionFlow() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Mockito.doThrow(new SQLException()).when(lockManager).loadLockRecord(Mockito.any(Connection.class), Mockito.anyString());
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(Mockito.mock(Connection.class));
+ lockManager.setConnectionFactory(connectionFactory);
+ expectedEx.expect(LockRuntimeException.class);
+ lockManager.getLockOwner(" ");
+ }
+
+ @Test
+ public void testGetLockOwnerNull() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Mockito.doReturn(null).when(lockManager).loadLockRecord(Mockito.any(Connection.class), Mockito.anyString());
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(Mockito.mock(Connection.class));
+ lockManager.setConnectionFactory(connectionFactory);
+ assertNull(lockManager.getLockOwner(" "));
+ }
+
+ @Test
+ public void testGetLockOwnerExpired() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ LockRecord lockRecord = Mockito.mock(LockRecord.class);
+ Mockito.when(lockRecord.getTimeout()).thenReturn(1L);
+ Mockito.when(lockRecord.getUpdated()).thenReturn(System.currentTimeMillis()-100);
+ Mockito.when(lockRecord.getOwner()).thenReturn("OWNER");
+ Mockito.doReturn(lockRecord).when(lockManager).loadLockRecord(Mockito.any(Connection.class), Mockito.anyString());
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Connection connection = Mockito.mock(Connection.class);
+ PreparedStatement statement = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet.next()).thenReturn(true);
+ Mockito.when(resultSet.getTimestamp(1)).thenReturn(new Timestamp(System.currentTimeMillis()));
+ Mockito.when(statement.executeQuery()).thenReturn(resultSet);
+ Mockito.when(connection.prepareStatement(SqlLockManager.SQL_CURRENT_TIMESTAMP)).thenReturn(statement);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(connection);
+ lockManager.setConnectionFactory(connectionFactory);
+ assertNull(lockManager.getLockOwner(" "));
+ }
+
+ @Test
+ public void testGetLockOwnerNotExpired() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ LockRecord lockRecord = Mockito.mock(LockRecord.class);
+ Mockito.when(lockRecord.getTimeout()).thenReturn(1L);
+ Mockito.when(lockRecord.getUpdated()).thenReturn(System.currentTimeMillis()+10000);
+ Mockito.when(lockRecord.getOwner()).thenReturn("OWNER");
+ Mockito.doReturn(lockRecord).when(lockManager).loadLockRecord(Mockito.any(Connection.class), Mockito.anyString());
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Connection connection = Mockito.mock(Connection.class);
+ PreparedStatement statement = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet.next()).thenReturn(true);
+ Mockito.when(resultSet.getTimestamp(1)).thenReturn(new Timestamp(System.currentTimeMillis()));
+ Mockito.when(statement.executeQuery()).thenReturn(resultSet);
+ Mockito.when(connection.prepareStatement(SqlLockManager.SQL_CURRENT_TIMESTAMP)).thenReturn(statement);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(connection);
+ lockManager.setConnectionFactory(connectionFactory);
+ assertEquals("OWNER", lockManager.getLockOwner(" "));
+ }
+
+ @Test
+ public void testLoadLockRecord() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ lockManager.setTableName("TABLE_NAME");
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Connection connection = Mockito.mock(Connection.class);
+ PreparedStatement statement = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet.next()).thenReturn(true);
+ Mockito.when(resultSet.getString(2)).thenReturn("OWNER");
+ Mockito.when(resultSet.getLong(3)).thenReturn(0L);
+ Mockito.when(resultSet.getLong(4)).thenReturn(0L);
+ Mockito.when(resultSet.getLong(5)).thenReturn(0L);
+ Mockito.when(statement.executeQuery()).thenReturn(resultSet);
+ Mockito.when(connection.prepareStatement(String.format(SqlLockManager.SQL_LOAD_LOCK_RECORD, "TABLE_NAME"))).thenReturn(statement);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(connection);
+ lockManager.setConnectionFactory(connectionFactory);
+ assertTrue(lockManager.loadLockRecord(connection, "") instanceof LockRecord);
+ }
+
+ @Test
+ public void testAddLockRecord() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ lockManager.setTableName("TABLE_NAME");
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Connection connection = Mockito.mock(Connection.class);
+ PreparedStatement statement2 = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet2 = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet2.next()).thenReturn(true);
+ Mockito.when(resultSet2.getTimestamp(1)).thenReturn(new Timestamp(System.currentTimeMillis()));
+ Mockito.when(statement2.executeQuery()).thenReturn(resultSet2);
+ Mockito.when(connection.prepareStatement(SqlLockManager.SQL_CURRENT_TIMESTAMP)).thenReturn(statement2);
+
+ PreparedStatement statement = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet.next()).thenReturn(true);
+ Mockito.when(resultSet.getString(2)).thenReturn("OWNER");
+ Mockito.when(resultSet.getLong(3)).thenReturn(0L);
+ Mockito.when(resultSet.getLong(4)).thenReturn(0L);
+ Mockito.when(resultSet.getLong(5)).thenReturn(0L);
+ Mockito.when(statement.executeQuery()).thenReturn(resultSet);
+ Mockito.when(connection.prepareStatement(String.format(SqlLockManager.SQL_INSERT_LOCK_RECORD, "TABLE_NAME"))).thenReturn(statement);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(connection);
+ lockManager.setConnectionFactory(connectionFactory);
+ lockManager.addLockRecord(connection, "", "", 0L);
+ Mockito.verify(statement).executeUpdate();
+ }
+
+ @Test
+ public void testUpdateLockRecord() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ lockManager.setTableName("TABLE_NAME");
+ JdbcConnectionFactory connectionFactory = Mockito.mock(JdbcConnectionFactory.class);
+ Connection connection = Mockito.mock(Connection.class);
+ PreparedStatement statement2 = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet2 = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet2.next()).thenReturn(true);
+ Mockito.when(resultSet2.getTimestamp(1)).thenReturn(new Timestamp(-1));
+ Mockito.when(statement2.executeQuery()).thenReturn(resultSet2);
+ Mockito.when(connection.prepareStatement(SqlLockManager.SQL_CURRENT_TIMESTAMP)).thenReturn(statement2);
+
+ PreparedStatement statement = Mockito.mock(PreparedStatement.class);
+ ResultSet resultSet = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet.next()).thenReturn(true);
+ Mockito.when(resultSet.getString(2)).thenReturn("OWNER");
+ Mockito.when(resultSet.getLong(3)).thenReturn(0L);
+ Mockito.when(resultSet.getLong(4)).thenReturn(0L);
+ Mockito.when(resultSet.getLong(5)).thenReturn(0L);
+ Mockito.when(statement.executeQuery()).thenReturn(resultSet);
+ Mockito.when(connection.prepareStatement(String.format(SqlLockManager.SQL_UPDATE_LOCK_RECORD, "TABLE_NAME"))).thenReturn(statement);
+ Mockito.when(connectionFactory.openDbConnection()).thenReturn(connection);
+ lockManager.setConnectionFactory(connectionFactory);
+ lockManager.updateLockRecord(connection, "", "", 0L);
+ Mockito.verify(statement).executeUpdate();
+ }
+
+ @Test
+ public void testEnterCriticalSectionLockRuntimeException() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Connection connection = Mockito.mock(Connection.class);
+ CallableStatement callableStatement = Mockito.mock(CallableStatement.class);
+ Mockito.when(connection.prepareCall("SELECT COALESCE(GET_LOCK(?,?),0)")).thenReturn(callableStatement);
+ expectedEx.expect(LockRuntimeException.class);
+ expectedEx.expectMessage("Cannot obtain critical section lock for resource [null].");
+ lockManager.enterCriticalSection(connection, null);
+ }
+
+ @Test
+ public void testEnterCriticalSectionLockRuntimeException2() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Connection connection = Mockito.mock(Connection.class);
+ Mockito.when(connection.prepareCall("SELECT COALESCE(GET_LOCK(?,?),0)")).thenThrow(new SQLException());
+ expectedEx.expect(LockRuntimeException.class);
+ expectedEx.expectMessage("Cannot obtain critical section lock for resource [null].");
+ expectedEx.expectCause(isA(SQLException.class));
+ lockManager.enterCriticalSection(connection, null);
+ }
+
+ @Test
+ public void testEnterCriticalSection() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Connection connection = Mockito.mock(Connection.class);
+ CallableStatement callableStatement = Mockito.mock(CallableStatement.class);
+ Mockito.when(callableStatement.execute()).thenReturn(true);
+ ResultSet resultSet = Mockito.mock(ResultSet.class);
+ Mockito.when(resultSet.getInt(1)).thenReturn(1);
+ Mockito.when(resultSet.next()).thenReturn(true);
+ Mockito.when(callableStatement.getResultSet()).thenReturn(resultSet);
+ Mockito.when(connection.prepareCall("SELECT COALESCE(GET_LOCK(?,?),0)")).thenReturn(callableStatement);
+ lockManager.enterCriticalSection(connection, null);
+ Mockito.verify(callableStatement).close();
+ }
+
+ @Test
+ public void testLeaveCriticalSection() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Connection connection = Mockito.mock(Connection.class);
+ CallableStatement callableStatement = Mockito.mock(CallableStatement.class);
+ Mockito.when(connection.prepareCall("SELECT RELEASE_LOCK(?)")).thenReturn(callableStatement);
+ lockManager.leaveCriticalSection(connection, null);
+ Mockito.verify(callableStatement).close();
+ }
+
+ @Test
+ public void testLeaveCriticalSectionExceptionFlow() throws SQLException {
+ MySqlLockManager lockManager = Mockito.spy(new MySqlLockManager());
+ Connection connection = Mockito.mock(Connection.class);
+ Mockito.when(connection.prepareCall("SELECT RELEASE_LOCK(?)")).thenThrow(new SQLException());
+ expectedEx.expect(LockRuntimeException.class);
+ lockManager.leaveCriticalSection(connection, null);
+ expectedEx.expectMessage("Error releasing critical section lock.");
+ expectedEx.expectCause(isA(SQLException.class));
+ }