This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new fb00668ce7a Add more test cases on MySQLDatabasePrivilegeCheckerTest 
(#38126)
fb00668ce7a is described below

commit fb00668ce7a18c939ec8df071be5f7baae8dd3d0
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Feb 21 22:52:45 2026 +0800

    Add more test cases on MySQLDatabasePrivilegeCheckerTest (#38126)
---
 .../checker/MySQLDatabasePrivilegeCheckerTest.java | 218 ++++++++++++---------
 1 file changed, 130 insertions(+), 88 deletions(-)

diff --git 
a/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/checker/MySQLDatabasePrivilegeCheckerTest.java
 
b/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/checker/MySQLDatabasePrivilegeCheckerTest.java
index f0c9eaceb28..13c62e261d0 100644
--- 
a/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/checker/MySQLDatabasePrivilegeCheckerTest.java
+++ 
b/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/checker/MySQLDatabasePrivilegeCheckerTest.java
@@ -17,23 +17,31 @@
 
 package org.apache.shardingsphere.database.connector.mysql.checker;
 
+import 
org.apache.shardingsphere.database.connector.core.checker.DialectDatabasePrivilegeChecker;
 import 
org.apache.shardingsphere.database.connector.core.checker.PrivilegeCheckType;
 import 
org.apache.shardingsphere.database.connector.core.exception.CheckDatabaseEnvironmentFailedException;
 import 
org.apache.shardingsphere.database.connector.core.exception.MissingRequiredPrivilegeException;
-import org.junit.jupiter.api.BeforeEach;
+import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Answers;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.stream.Stream;
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -41,136 +49,170 @@ import static org.mockito.Mockito.when;
 @ExtendWith(MockitoExtension.class)
 class MySQLDatabasePrivilegeCheckerTest {
     
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "MySQL");
+    
+    private final DialectDatabasePrivilegeChecker checker = 
DatabaseTypedSPILoader.getService(DialectDatabasePrivilegeChecker.class, 
databaseType);
+    
     @Mock
-    private PreparedStatement preparedStatement;
+    private DataSource dataSource;
     
     @Mock
-    private ResultSet resultSet;
+    private Connection connection;
     
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private DataSource dataSource;
+    @Mock
+    private DatabaseMetaData databaseMetaData;
     
-    @BeforeEach
-    void setUp() throws SQLException {
-        
when(dataSource.getConnection().prepareStatement(anyString())).thenReturn(preparedStatement);
-    }
+    @Mock
+    private PreparedStatement preparedStatement;
     
-    @Test
-    void assertCheckPipelinePrivilegeWithParticularSuccess() throws 
SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT REPLICATION SLAVE, 
REPLICATION CLIENT ON *.* TO '%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.PIPELINE);
-        verify(preparedStatement).executeQuery();
-    }
+    @Mock
+    private ResultSet resultSet;
     
-    @Test
-    void assertCheckPipelinePrivilegeWithAllSuccess() throws SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("checkSuccessArguments")
+    void assertCheckSuccess(final String name, final PrivilegeCheckType 
privilegeCheckType, final int majorVersion, final String catalog, final String 
grantedPrivilege) throws SQLException {
+        mockShowGrantsQuery();
+        if (PrivilegeCheckType.XA == privilegeCheckType) {
+            mockXAMetaData(majorVersion);
+        }
+        if (PrivilegeCheckType.SELECT == privilegeCheckType) {
+            when(connection.getCatalog()).thenReturn(catalog);
+        }
         when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT ALL PRIVILEGES ON *.* 
TO '%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.PIPELINE);
+        when(resultSet.getString(1)).thenReturn(grantedPrivilege);
+        checker.check(dataSource, privilegeCheckType);
         verify(preparedStatement).executeQuery();
     }
     
-    @Test
-    void assertCheckPipelinePrivilegeWithLackPrivileges() throws SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        assertThrows(MissingRequiredPrivilegeException.class, () -> new 
MySQLDatabasePrivilegeChecker().check(dataSource, PrivilegeCheckType.PIPELINE));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("checkMissingPrivilegeArguments")
+    void assertCheckWithMissingPrivilege(final String name,
+                                         final PrivilegeCheckType 
privilegeCheckType, final int majorVersion, final String catalog, final boolean 
containsGrantRow) throws SQLException {
+        mockShowGrantsQuery();
+        if (PrivilegeCheckType.XA == privilegeCheckType) {
+            mockXAMetaData(majorVersion);
+        }
+        if (PrivilegeCheckType.SELECT == privilegeCheckType) {
+            when(connection.getCatalog()).thenReturn(catalog);
+        }
+        if (containsGrantRow) {
+            when(resultSet.next()).thenReturn(true, false);
+            when(resultSet.getString(1)).thenReturn("GRANT INSERT ON *.* TO 
'%'@'%'");
+        }
+        assertThrows(MissingRequiredPrivilegeException.class, () -> 
checker.check(dataSource, privilegeCheckType));
     }
     
     @Test
-    void assertCheckPipelinePrivilegeFailure() throws SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        when(resultSet.next()).thenThrow(new SQLException(""));
-        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> new 
MySQLDatabasePrivilegeChecker().check(dataSource, PrivilegeCheckType.PIPELINE));
+    void assertCheckFailureWhenConnectionAcquisitionFails() throws 
SQLException {
+        when(dataSource.getConnection()).thenThrow(SQLException.class);
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckXAPrivilegeWithParticularSuccessInMySQL8() throws 
SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        
when(dataSource.getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(8);
-        when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT XA_RECOVER_ADMIN ON *.* 
TO '%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.XA);
-        verify(preparedStatement).executeQuery();
+    void assertCheckFailureWhenExecuteQueryFails() throws SQLException {
+        mockConnectionAndPreparedStatement();
+        when(preparedStatement.executeQuery()).thenThrow(SQLException.class);
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertUnCheckXAPrivilegeInMySQL5() throws SQLException {
-        
when(dataSource.getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(5);
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.XA);
-        verify(preparedStatement, never()).executeQuery();
+    void assertCheckFailureWhenReadResultSetFails() throws SQLException {
+        mockShowGrantsQuery();
+        when(resultSet.next()).thenThrow(SQLException.class);
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckXAPrivilegeWithAllSuccessInMySQL8() throws SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        
when(dataSource.getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(8);
-        when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT ALL PRIVILEGES ON *.* 
TO '%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.XA);
-        verify(preparedStatement).executeQuery();
+    void assertCheckFailureWhenReadMySQLMajorVersionFails() throws 
SQLException {
+        when(dataSource.getConnection()).thenReturn(connection);
+        when(connection.getMetaData()).thenReturn(databaseMetaData);
+        
when(databaseMetaData.getDatabaseMajorVersion()).thenThrow(SQLException.class);
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.XA));
     }
     
     @Test
-    void assertCheckXAPrivilegeLackPrivilegesInMySQL8() throws SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        
when(dataSource.getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(8);
-        assertThrows(MissingRequiredPrivilegeException.class, () -> new 
MySQLDatabasePrivilegeChecker().check(dataSource, PrivilegeCheckType.XA));
+    void assertCheckFailureWhenCloseResultSetFails() throws SQLException {
+        mockShowGrantsQuery();
+        when(resultSet.next()).thenReturn(false);
+        doThrow(SQLException.class).when(resultSet).close();
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckXAPrivilegeFailureInMySQL8() throws SQLException {
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        
when(dataSource.getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(8);
-        when(resultSet.next()).thenThrow(new SQLException(""));
-        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> new 
MySQLDatabasePrivilegeChecker().check(dataSource, PrivilegeCheckType.XA));
+    void assertCheckFailureWhenClosePreparedStatementFails() throws 
SQLException {
+        mockShowGrantsQuery();
+        when(resultSet.next()).thenReturn(false);
+        doThrow(SQLException.class).when(preparedStatement).close();
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckSelectWithSelectPrivileges() throws SQLException {
-        when(dataSource.getConnection().getCatalog()).thenReturn("foo_db");
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT SELECT ON *.* TO 
'%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.SELECT);
-        verify(preparedStatement).executeQuery();
+    void assertCheckFailureWhenReadResultSetAndCloseResultSetFail() throws 
SQLException {
+        mockShowGrantsQuery();
+        when(resultSet.next()).thenThrow(new SQLException("mocked result set 
failure"));
+        doThrow(SQLException.class).when(resultSet).close();
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckSelectWithSelectOnDatabasePrivileges() throws SQLException 
{
-        when(dataSource.getConnection().getCatalog()).thenReturn("foo_db");
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT SELECT ON `FOO_DB`.* TO 
'%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.SELECT);
-        verify(preparedStatement).executeQuery();
+    void assertCheckFailureWhenReadResultSetAndClosePreparedStatementFail() 
throws SQLException {
+        mockShowGrantsQuery();
+        when(resultSet.next()).thenThrow(SQLException.class);
+        doThrow(SQLException.class).when(preparedStatement).close();
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckSelectWithAllPrivileges() throws SQLException {
-        when(dataSource.getConnection().getCatalog()).thenReturn("foo_db");
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+    void assertCheckFailureWhenCloseConnectionFails() throws SQLException {
+        mockShowGrantsQuery();
         when(resultSet.next()).thenReturn(true);
         when(resultSet.getString(1)).thenReturn("GRANT ALL PRIVILEGES ON *.* 
TO '%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.SELECT);
-        verify(preparedStatement).executeQuery();
+        doThrow(SQLException.class).when(connection).close();
+        assertThrows(CheckDatabaseEnvironmentFailedException.class, () -> 
checker.check(dataSource, PrivilegeCheckType.PIPELINE));
     }
     
     @Test
-    void assertCheckSelectWithAllPrivilegesOnDatabase() throws SQLException {
-        when(dataSource.getConnection().getCatalog()).thenReturn("foo_db");
-        when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        when(resultSet.next()).thenReturn(true);
-        when(resultSet.getString(1)).thenReturn("GRANT ALL PRIVILEGES ON 
`FOO_DB`.* TO '%'@'%'");
-        new MySQLDatabasePrivilegeChecker().check(dataSource, 
PrivilegeCheckType.SELECT);
-        verify(preparedStatement).executeQuery();
+    void assertCheckSkipsXAInMySQL5() throws SQLException {
+        when(dataSource.getConnection()).thenReturn(connection);
+        when(connection.getMetaData()).thenReturn(databaseMetaData);
+        when(databaseMetaData.getDatabaseMajorVersion()).thenReturn(5);
+        checker.check(dataSource, PrivilegeCheckType.XA);
+        verify(preparedStatement, never()).executeQuery();
     }
     
-    @Test
-    void assertCheckSelectWithLackPrivileges() throws SQLException {
+    private void mockShowGrantsQuery() throws SQLException {
+        mockConnectionAndPreparedStatement();
         when(preparedStatement.executeQuery()).thenReturn(resultSet);
-        assertThrows(MissingRequiredPrivilegeException.class, () -> new 
MySQLDatabasePrivilegeChecker().check(dataSource, PrivilegeCheckType.SELECT));
+    }
+    
+    private void mockConnectionAndPreparedStatement() throws SQLException {
+        when(dataSource.getConnection()).thenReturn(connection);
+        when(connection.prepareStatement("SHOW 
GRANTS")).thenReturn(preparedStatement);
+    }
+    
+    private void mockXAMetaData(final int majorVersion) throws SQLException {
+        when(connection.getMetaData()).thenReturn(databaseMetaData);
+        
when(databaseMetaData.getDatabaseMajorVersion()).thenReturn(majorVersion);
+    }
+    
+    private static Stream<Arguments> checkSuccessArguments() {
+        return Stream.of(
+                Arguments.of("pipeline with replication privilege", 
PrivilegeCheckType.PIPELINE, 0, null, "GRANT REPLICATION SLAVE, REPLICATION 
CLIENT ON *.* TO '%'@'%'"),
+                Arguments.of("pipeline with all privileges", 
PrivilegeCheckType.PIPELINE, 0, null, "GRANT ALL PRIVILEGES ON *.* TO '%'@'%'"),
+                Arguments.of("xa with xa recover admin on mysql8", 
PrivilegeCheckType.XA, 8, null, "GRANT XA_RECOVER_ADMIN ON *.* TO '%'@'%'"),
+                Arguments.of("xa with all privileges on mysql8", 
PrivilegeCheckType.XA, 8, null, "GRANT ALL PRIVILEGES ON *.* TO '%'@'%'"),
+                Arguments.of("select with select privilege on all databases", 
PrivilegeCheckType.SELECT, 0, "foo_db", "GRANT SELECT ON *.* TO '%'@'%'"),
+                Arguments.of("select with select privilege on target 
database", PrivilegeCheckType.SELECT, 0, "foo_db", "GRANT SELECT ON `FOO_DB`.* 
TO '%'@'%'"),
+                Arguments.of("select with all privileges on all databases", 
PrivilegeCheckType.SELECT, 0, "foo_db", "GRANT ALL PRIVILEGES ON *.* TO 
'%'@'%'"),
+                Arguments.of("select with all privileges on target database", 
PrivilegeCheckType.SELECT, 0, "foo_db", "GRANT ALL PRIVILEGES ON `FOO_DB`.* TO 
'%'@'%'"));
+    }
+    
+    private static Stream<Arguments> checkMissingPrivilegeArguments() {
+        return Stream.of(
+                Arguments.of("pipeline without grant rows", 
PrivilegeCheckType.PIPELINE, 0, null, false),
+                Arguments.of("pipeline with unrelated grant row", 
PrivilegeCheckType.PIPELINE, 0, null, true),
+                Arguments.of("xa without grant rows on mysql8", 
PrivilegeCheckType.XA, 8, null, false),
+                Arguments.of("select with unrelated grant row", 
PrivilegeCheckType.SELECT, 0, "foo_db", true),
+                Arguments.of("none with unrelated grant row", 
PrivilegeCheckType.NONE, 0, null, true));
     }
 }

Reply via email to