From 4bcaa34bc2f0a2ba6c54ff99d3cb9188259426bb Mon Sep 17 00:00:00 2001 From: Joss Armstrong Date: Thu, 7 Feb 2019 13:32:20 +0000 Subject: [PATCH] Coverage for lockmanager.sql.optimistic package Increased coverage from 54% to 95% Issue-ID: APPC-1400 Change-Id: Ic71a090ff9e292a9d9856f50561f348a77653e4f Signed-off-by: Joss Armstrong --- .../impl/sql/optimistic/SqlLockManager.java | 30 +-- .../impl/sql/optimistic/TestMySqlLockManager.java | 204 ++++++++++++++++++++- 2 files changed, 219 insertions(+), 15 deletions(-) diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/onap/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/onap/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java index 04d573186..40ee213f0 100644 --- a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/onap/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/onap/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java @@ -5,6 +5,8 @@ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications Copyright (C) 2019 Ericsson * ============================================================================= * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,12 +37,12 @@ import org.onap.appc.lockmanager.impl.sql.Messages; abstract class SqlLockManager extends JdbcLockManager { - private static final String SQL_LOAD_LOCK_RECORD = "SELECT * FROM %s WHERE RESOURCE_ID=?"; - private static final String SQL_INSERT_LOCK_RECORD = "INSERT INTO %s (RESOURCE_ID, OWNER_ID, UPDATED, TIMEOUT, VER) VALUES (?, ?, ?, ?, ?)"; - private static final String SQL_UPDATE_LOCK_RECORD = "UPDATE %s SET OWNER_ID=?, UPDATED=?, TIMEOUT=?, VER=? WHERE RESOURCE_ID=? AND VER=?"; + static final String SQL_LOAD_LOCK_RECORD = "SELECT * FROM %s WHERE RESOURCE_ID=?"; + static final String SQL_INSERT_LOCK_RECORD = "INSERT INTO %s (RESOURCE_ID, OWNER_ID, UPDATED, TIMEOUT, VER) VALUES (?, ?, ?, ?, ?)"; + static final String SQL_UPDATE_LOCK_RECORD = "UPDATE %s SET OWNER_ID=?, UPDATED=?, TIMEOUT=?, VER=? WHERE RESOURCE_ID=? AND VER=?"; // private static final String SQL_DELETE_LOCK_RECORD = "DELETE FROM %s WHERE RESOURCE_ID=? AND VER=?"; - private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; - private static final String SQL_LOAD_LOCK_RECORD_WITH_OWNER = "SELECT * FROM LOCK_MANAGEMENT WHERE RESOURCE_ID = ? AND OWNER = ? "; + static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; + static final String SQL_LOAD_LOCK_RECORD_WITH_OWNER = "SELECT * FROM LOCK_MANAGEMENT WHERE RESOURCE_ID = ? AND OWNER = ? "; private String sqlLoadLockRecord; private String sqlInsertLockRecord; @@ -79,13 +81,13 @@ abstract class SqlLockManager extends JdbcLockManager { @Override public boolean isLocked(String resource) { - Connection connection=openDbConnection(); + Connection connection = openDbConnection(); try { - LockRecord lockRecord=loadLockRecord(connection,resource); - if(lockRecord==null){ + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord == null){ return false; }else{ - if(lockRecord.getOwner()==null){ + if(lockRecord.getOwner() == null){ return false; }else if(isLockExpired(lockRecord, connection)){ return false; @@ -102,10 +104,10 @@ abstract class SqlLockManager extends JdbcLockManager { @Override public String getLockOwner(String resource) { - Connection connection=openDbConnection(); + Connection connection = openDbConnection(); try { - LockRecord lockRecord=loadLockRecord(connection,resource); - if(lockRecord==null || lockRecord.getOwner() ==null ){ + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord == null || lockRecord.getOwner() == null ){ return null; }else{ if(isLockExpired(lockRecord, connection)){ @@ -116,7 +118,7 @@ abstract class SqlLockManager extends JdbcLockManager { } } catch (SQLException e) { throw new LockRuntimeException(Messages.EXP_CHECK_LOCK.format(resource)); - }finally { + } finally { closeDbConnection(connection); } } @@ -216,7 +218,7 @@ abstract class SqlLockManager extends JdbcLockManager { return res; } - protected LockRecord loadLockRecord(Connection connection, String resource,String owner) throws SQLException { + protected LockRecord loadLockRecord(Connection connection, String resource, String owner) throws SQLException { LockRecord res = null; try(PreparedStatement statement = connection.prepareStatement(SQL_LOAD_LOCK_RECORD_WITH_OWNER)) { statement.setString(1, resource); diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/onap/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/onap/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java index daf4584a7..617092314 100644 --- a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/onap/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/onap/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java @@ -5,6 +5,8 @@ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications Copyright (C) 2019 Ericsson * ============================================================================= * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,13 +25,26 @@ package org.onap.appc.lockmanager.impl.sql.optimistic; +import org.onap.appc.dao.util.api.JdbcConnectionFactory; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; import org.onap.appc.lockmanager.api.LockException; +import org.onap.appc.lockmanager.api.LockRuntimeException; import org.onap.appc.lockmanager.impl.sql.JdbcLockManager; import org.onap.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests; import org.onap.appc.lockmanager.impl.sql.Synchronizer; - +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import java.sql.Timestamp; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.concurrent.*; public class TestMySqlLockManager extends MySqlLockManagerBaseTests { @@ -226,4 +241,191 @@ public class TestMySqlLockManager extends MySqlLockManagerBaseTests { future1.cancel(true); } } + + @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 testIsDuplicatePkError() throws SQLException { + SqlLockManager lockManager = new SqlLockManager() {}; + SQLException sqlException = Mockito.mock(SQLException.class); + Mockito.when(sqlException.getSQLState()).thenReturn("23xxx"); + assertTrue(lockManager.isDuplicatePkError(sqlException)); + } + + @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 testLoadLockRecord3arg() 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(SqlLockManager.SQL_LOAD_LOCK_RECORD_WITH_OWNER)).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(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_UPDATE_LOCK_RECORD, "TABLE_NAME"))).thenReturn(statement); + Mockito.when(connectionFactory.openDbConnection()).thenReturn(connection); + lockManager.setConnectionFactory(connectionFactory); + assertFalse(lockManager.updateLockRecord(connection, "", "", 0L, 0L)); + } } -- 2.16.6