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

duanzhengqiang 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 d06f8fad667 Add test cases on GlobalClockTransactionHook (#32948)
d06f8fad667 is described below

commit d06f8fad6672722a3a470df290b928a05b61196e
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Sep 21 19:52:21 2024 +0800

    Add test cases on GlobalClockTransactionHook (#32948)
    
    * Add test cases on GlobalClockTransactionHook
    
    * Add test cases on GlobalClockTransactionHook
---
 kernel/global-clock/core/pom.xml                   |  6 ++
 .../executor/GlobalClockTransactionHook.java       | 20 +++---
 .../executor/GlobalClockTransactionHookTest.java   | 73 +++++++++++++++++++---
 3 files changed, 83 insertions(+), 16 deletions(-)

diff --git a/kernel/global-clock/core/pom.xml b/kernel/global-clock/core/pom.xml
index 9c38d93d620..008170ee423 100644
--- a/kernel/global-clock/core/pom.xml
+++ b/kernel/global-clock/core/pom.xml
@@ -43,6 +43,12 @@
             <version>${project.version}</version>
         </dependency>
         
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-test-util</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.apache.shardingsphere</groupId>
             <artifactId>shardingsphere-test-it-yaml</artifactId>
diff --git 
a/kernel/global-clock/core/src/main/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHook.java
 
b/kernel/global-clock/core/src/main/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHook.java
index 49a040437b7..87a0ba3f067 100644
--- 
a/kernel/global-clock/core/src/main/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHook.java
+++ 
b/kernel/global-clock/core/src/main/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHook.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.globalclock.executor;
 
+import com.google.common.base.Preconditions;
 import org.apache.shardingsphere.globalclock.provider.GlobalClockProvider;
 import org.apache.shardingsphere.globalclock.rule.GlobalClockRule;
 import org.apache.shardingsphere.globalclock.rule.constant.GlobalClockOrder;
@@ -66,17 +67,16 @@ public final class GlobalClockTransactionHook implements 
TransactionHook<GlobalC
     @Override
     public void beforeExecuteSQL(final GlobalClockRule rule, final 
DatabaseType databaseType, final Collection<Connection> connections, final 
TransactionConnectionContext connectionContext,
                                  final TransactionIsolationLevel 
isolationLevel) throws SQLException {
-        if (!rule.getConfiguration().isEnabled()) {
+        if (!rule.getConfiguration().isEnabled() || null != isolationLevel && 
TransactionIsolationLevel.READ_COMMITTED != isolationLevel) {
             return;
         }
-        if (null != isolationLevel && TransactionIsolationLevel.READ_COMMITTED 
!= isolationLevel) {
+        Optional<GlobalClockTransactionExecutor> 
globalClockTransactionExecutor = 
DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType);
+        if (!globalClockTransactionExecutor.isPresent()) {
             return;
         }
-        Optional<GlobalClockTransactionExecutor> 
globalClockTransactionExecutor = 
DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType);
         Optional<GlobalClockProvider> globalClockProvider = 
rule.getGlobalClockProvider();
-        if (globalClockTransactionExecutor.isPresent() && 
globalClockProvider.isPresent()) {
-            
globalClockTransactionExecutor.get().sendSnapshotTimestamp(connections, 
globalClockProvider.get().getCurrentTimestamp());
-        }
+        Preconditions.checkState(globalClockProvider.isPresent());
+        
globalClockTransactionExecutor.get().sendSnapshotTimestamp(connections, 
globalClockProvider.get().getCurrentTimestamp());
     }
     
     @Override
@@ -88,10 +88,12 @@ public final class GlobalClockTransactionHook implements 
TransactionHook<GlobalC
         }
         if (lockContext.tryLock(lockDefinition, 200L)) {
             Optional<GlobalClockTransactionExecutor> 
globalClockTransactionExecutor = 
DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType);
-            Optional<GlobalClockProvider> globalClockProvider = 
rule.getGlobalClockProvider();
-            if (globalClockTransactionExecutor.isPresent() && 
globalClockProvider.isPresent()) {
-                
globalClockTransactionExecutor.get().sendCommitTimestamp(connections, 
globalClockProvider.get().getCurrentTimestamp());
+            if (!globalClockTransactionExecutor.isPresent()) {
+                return;
             }
+            Optional<GlobalClockProvider> globalClockProvider = 
rule.getGlobalClockProvider();
+            Preconditions.checkState(globalClockProvider.isPresent());
+            
globalClockTransactionExecutor.get().sendCommitTimestamp(connections, 
globalClockProvider.get().getCurrentTimestamp());
         }
     }
     
diff --git 
a/kernel/global-clock/core/src/test/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHookTest.java
 
b/kernel/global-clock/core/src/test/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHookTest.java
index 910050cc440..1a5a16c0486 100644
--- 
a/kernel/global-clock/core/src/test/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHookTest.java
+++ 
b/kernel/global-clock/core/src/test/java/org/apache/shardingsphere/globalclock/executor/GlobalClockTransactionHookTest.java
@@ -21,6 +21,7 @@ import 
org.apache.shardingsphere.globalclock.provider.GlobalClockProvider;
 import org.apache.shardingsphere.globalclock.rule.GlobalClockRule;
 import 
org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.lock.LockContext;
 import 
org.apache.shardingsphere.infra.session.connection.transaction.TransactionConnectionContext;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 import 
org.apache.shardingsphere.sql.parser.statement.core.enums.TransactionIsolationLevel;
@@ -40,6 +41,7 @@ import java.util.Optional;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -127,26 +129,83 @@ class GlobalClockTransactionHookTest {
     @Test
     void assertBeforeExecuteSQLWhenGlobalClockTransactionExecutorAbsent() 
throws SQLException {
         when(rule.getConfiguration().isEnabled()).thenReturn(true);
+        
when(rule.getGlobalClockProvider()).thenReturn(Optional.of(globalClockProvider));
         transactionHook.beforeExecuteSQL(rule, databaseType, 
Collections.emptyList(), transactionContext, 
TransactionIsolationLevel.READ_COMMITTED);
         
when(DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType)).thenReturn(Optional.empty());
         verify(globalClockTransactionExecutor, 
times(0)).sendSnapshotTimestamp(any(), anyLong());
     }
     
     @Test
-    void assertBeforeExecuteSQLWhenGlobalClockProviderAbsent() throws 
SQLException {
+    void assertBeforeExecuteSQLWhenNullTransactionIsolationLevel() throws 
SQLException {
         when(rule.getConfiguration().isEnabled()).thenReturn(true);
-        transactionHook.beforeExecuteSQL(rule, databaseType, 
Collections.emptyList(), transactionContext, 
TransactionIsolationLevel.READ_COMMITTED);
+        
when(rule.getGlobalClockProvider()).thenReturn(Optional.of(globalClockProvider));
         
when(DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType)).thenReturn(Optional.of(globalClockTransactionExecutor));
-        verify(globalClockTransactionExecutor, 
times(0)).sendSnapshotTimestamp(any(), anyLong());
+        when(globalClockProvider.getCurrentTimestamp()).thenReturn(10L);
+        transactionHook.beforeExecuteSQL(rule, databaseType, 
Collections.emptyList(), transactionContext, null);
+        
verify(globalClockTransactionExecutor).sendSnapshotTimestamp(Collections.emptyList(),
 10L);
     }
     
+    @SuppressWarnings({"rawtypes", "unchecked"})
     @Test
-    void assertBeforeExecuteSQLWhenNullTransactionIsolationLevel() throws 
SQLException {
+    void assertBeforeCommitWhenDisabledGlobalClockRule() throws SQLException {
+        LockContext lockContext = mock(LockContext.class);
+        transactionHook.beforeCommit(rule, databaseType, 
Collections.emptyList(), transactionContext, lockContext);
+        verify(lockContext, times(0)).tryLock(any(), anyLong());
+    }
+    
+    @SuppressWarnings("rawtypes")
+    @Test
+    void assertBeforeCommitWhenTryLockFailed() throws SQLException {
+        when(rule.getConfiguration().isEnabled()).thenReturn(true);
+        LockContext lockContext = mock(LockContext.class);
+        transactionHook.beforeCommit(rule, databaseType, 
Collections.emptyList(), transactionContext, lockContext);
+        verify(globalClockTransactionExecutor, 
times(0)).sendCommitTimestamp(any(), anyLong());
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test
+    void assertBeforeCommitWhenGlobalClockTransactionExecutorAbsent() throws 
SQLException {
+        when(rule.getConfiguration().isEnabled()).thenReturn(true);
+        LockContext lockContext = mock(LockContext.class);
+        when(lockContext.tryLock(any(), anyLong())).thenReturn(true);
+        
when(DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType)).thenReturn(Optional.empty());
+        transactionHook.beforeCommit(rule, databaseType, 
Collections.emptyList(), transactionContext, lockContext);
+        verify(globalClockTransactionExecutor, 
times(0)).sendCommitTimestamp(any(), anyLong());
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test
+    void assertBeforeCommit() throws SQLException {
         when(rule.getConfiguration().isEnabled()).thenReturn(true);
         
when(rule.getGlobalClockProvider()).thenReturn(Optional.of(globalClockProvider));
-        
when(DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType)).thenReturn(Optional.of(globalClockTransactionExecutor));
         when(globalClockProvider.getCurrentTimestamp()).thenReturn(10L);
-        transactionHook.beforeExecuteSQL(rule, databaseType, 
Collections.emptyList(), transactionContext, null);
-        
verify(globalClockTransactionExecutor).sendSnapshotTimestamp(Collections.emptyList(),
 10L);
+        LockContext lockContext = mock(LockContext.class);
+        when(lockContext.tryLock(any(), anyLong())).thenReturn(true);
+        
when(DatabaseTypedSPILoader.findService(GlobalClockTransactionExecutor.class, 
databaseType)).thenReturn(Optional.of(globalClockTransactionExecutor));
+        transactionHook.beforeCommit(rule, databaseType, 
Collections.emptyList(), transactionContext, lockContext);
+        
verify(globalClockTransactionExecutor).sendCommitTimestamp(Collections.emptyList(),
 10L);
+    }
+    
+    @Test
+    void assertAfterCommitWhenGlobalClockProviderAbsent() {
+        transactionHook.afterCommit(rule, databaseType, 
Collections.emptyList(), transactionContext, mock(LockContext.class));
+        verify(globalClockProvider, times(0)).getNextTimestamp();
+    }
+    
+    @Test
+    void assertAfterCommitWhenGlobalClockProviderPresent() {
+        
when(rule.getGlobalClockProvider()).thenReturn(Optional.of(globalClockProvider));
+        transactionHook.afterCommit(rule, databaseType, 
Collections.emptyList(), transactionContext, mock(LockContext.class));
+        verify(globalClockProvider).getNextTimestamp();
+    }
+    
+    @Test
+    void assertBeforeRollback() {
+        assertDoesNotThrow(() -> transactionHook.beforeRollback(rule, 
databaseType, Collections.emptyList(), transactionContext));
+    }
+    
+    @Test
+    void assertAfterRollback() {
+        assertDoesNotThrow(() -> transactionHook.afterRollback(rule, 
databaseType, Collections.emptyList(), transactionContext));
     }
 }

Reply via email to