This is an automated email from the ASF dual-hosted git repository.
jimin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git
The following commit(s) were added to refs/heads/2.x by this push:
new 5b58b33bdc test: add test for compatible module (#7727)
5b58b33bdc is described below
commit 5b58b33bdcb25e304241a98d709dad48e8671bb1
Author: Eric Wang <[email protected]>
AuthorDate: Thu Oct 23 17:03:13 2025 +0300
test: add test for compatible module (#7727)
---
compatible/pom.xml | 4 +
.../java/io/seata/common/LockStrategyModeTest.java | 94 ++++++++
.../java/io/seata/core/auth/AuthSignerTest.java | 45 ++++
.../core/exception/TransactionExceptionTest.java | 157 +++++++++++++
.../core/store/db/sql/lock/LockStoreSqlTest.java | 46 ++++
.../core/store/db/sql/log/LogStoreSqlsTest.java | 46 ++++
.../client/ClientTransactionInterceptorTest.java | 58 +++++
.../server/ServerTransactionInterceptorTest.java | 58 +++++
.../integration/http/DefaultHttpExecutorTest.java | 135 +++++++++++
.../http/JakartaSeataWebMvcConfigurerTest.java | 57 +++++
...kartaTransactionPropagationInterceptorTest.java | 57 +++++
.../http/SeataWebMvcConfigurerTest.java | 57 +++++
.../TransactionPropagationInterceptorTest.java | 57 +++++
.../interceptor/ActionInterceptorHandlerTest.java | 177 ++++++++++++++
.../GlobalTransactionalInterceptorHandlerTest.java | 256 +++++++++++++++++++++
.../integration/tx/api/json/JsonParserTest.java | 72 ++++++
.../tx/api/remoting/RemotingParserTest.java | 90 ++++++++
.../api/BusinessActionContextParameterTest.java | 144 ++++++++++++
.../rm/tcc/api/BusinessActionContextTest.java | 60 +++++
.../java/io/seata/rm/tcc/api/LocalTCCTest.java | 104 +++++++++
.../rm/tcc/api/TwoPhaseBusinessActionTest.java | 196 ++++++++++++++++
.../TccActionInterceptorHandlerTest.java | 253 ++++++++++++++++++++
.../seata/tm/api/DefaultGlobalTransactionTest.java | 128 +++++++++++
.../seata/tm/api/GlobalTransactionContextTest.java | 192 ++++++++++++++++
24 files changed, 2543 insertions(+)
diff --git a/compatible/pom.xml b/compatible/pom.xml
index b8e1d7e7ae..6f34d10600 100644
--- a/compatible/pom.xml
+++ b/compatible/pom.xml
@@ -121,6 +121,10 @@
<artifactId>druid</artifactId>
<scope>provided</scope>
</dependency>
+<!-- <dependency>-->
+<!-- <groupId>commons-lang</groupId>-->
+<!-- <artifactId>commons-lang</artifactId>-->
+<!-- </dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
diff --git a/compatible/src/test/java/io/seata/common/LockStrategyModeTest.java
b/compatible/src/test/java/io/seata/common/LockStrategyModeTest.java
new file mode 100644
index 0000000000..85f79f3920
--- /dev/null
+++ b/compatible/src/test/java/io/seata/common/LockStrategyModeTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.common;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for LockStrategyMode enum.
+ */
+public class LockStrategyModeTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+ LockStrategyMode.class.isAnnotationPresent(Deprecated.class),
+ "LockStrategyMode should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testIsEnum() {
+ assertTrue(LockStrategyMode.class.isEnum(), "LockStrategyMode should
be an enum");
+ }
+
+ @Test
+ public void testEnumValues() {
+ LockStrategyMode[] values = LockStrategyMode.values();
+ assertEquals(2, values.length, "Should have exactly 2 enum values");
+ }
+
+ @Test
+ public void testOptimisticMode() {
+ LockStrategyMode mode = LockStrategyMode.OPTIMISTIC;
+ assertNotNull(mode);
+ assertEquals("OPTIMISTIC", mode.name());
+ assertEquals(0, mode.ordinal());
+ }
+
+ @Test
+ public void testPessimisticMode() {
+ LockStrategyMode mode = LockStrategyMode.PESSIMISTIC;
+ assertNotNull(mode);
+ assertEquals("PESSIMISTIC", mode.name());
+ assertEquals(1, mode.ordinal());
+ }
+
+ @Test
+ public void testValueOf() {
+ assertEquals(LockStrategyMode.OPTIMISTIC,
LockStrategyMode.valueOf("OPTIMISTIC"));
+ assertEquals(LockStrategyMode.PESSIMISTIC,
LockStrategyMode.valueOf("PESSIMISTIC"));
+ }
+
+ @Test
+ public void testToString() {
+ assertEquals("OPTIMISTIC", LockStrategyMode.OPTIMISTIC.toString());
+ assertEquals("PESSIMISTIC", LockStrategyMode.PESSIMISTIC.toString());
+ }
+
+ @Test
+ public void testSwitchStatement() {
+ LockStrategyMode mode = LockStrategyMode.OPTIMISTIC;
+ String result;
+
+ switch (mode) {
+ case OPTIMISTIC:
+ result = "optimistic";
+ break;
+ case PESSIMISTIC:
+ result = "pessimistic";
+ break;
+ default:
+ result = "unknown";
+ }
+
+ assertEquals("optimistic", result);
+ }
+}
diff --git a/compatible/src/test/java/io/seata/core/auth/AuthSignerTest.java
b/compatible/src/test/java/io/seata/core/auth/AuthSignerTest.java
new file mode 100644
index 0000000000..b1b4c4ecc7
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/auth/AuthSignerTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.core.auth;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for AuthSigner interface.
+ */
+public class AuthSignerTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+ AuthSigner.class.isAnnotationPresent(Deprecated.class),
"AuthSigner should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testIsInterface() {
+ assertTrue(AuthSigner.class.isInterface(), "AuthSigner should be an
interface");
+ }
+
+ @Test
+ public void testExtendsApacheSeataAuthSigner() {
+ assertTrue(
+
org.apache.seata.core.auth.AuthSigner.class.isAssignableFrom(AuthSigner.class),
+ "Should extend org.apache.seata.core.auth.AuthSigner");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/core/exception/TransactionExceptionTest.java
b/compatible/src/test/java/io/seata/core/exception/TransactionExceptionTest.java
new file mode 100644
index 0000000000..0e23c77558
--- /dev/null
+++
b/compatible/src/test/java/io/seata/core/exception/TransactionExceptionTest.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.core.exception;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for TransactionException compatibility layer.
+ */
+public class TransactionExceptionTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
TransactionException.class.isAnnotationPresent(Deprecated.class),
+ "TransactionException should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataException() {
+ assertTrue(
+
org.apache.seata.core.exception.TransactionException.class.isAssignableFrom(TransactionException.class),
+ "TransactionException should extend
org.apache.seata.core.exception.TransactionException");
+ }
+
+ @Test
+ public void testConstructorWithCode() {
+ TransactionException exception = new
TransactionException(TransactionExceptionCode.BeginFailed);
+
+ assertNotNull(exception);
+
assertEquals(org.apache.seata.core.exception.TransactionExceptionCode.BeginFailed,
exception.getCode());
+ }
+
+ @Test
+ public void testConstructorWithCodeAndCause() {
+ Throwable cause = new RuntimeException("Test cause");
+ TransactionException exception =
+ new
TransactionException(TransactionExceptionCode.FailedToSendBranchCommitRequest,
cause);
+
+ assertNotNull(exception);
+ assertEquals(
+
org.apache.seata.core.exception.TransactionExceptionCode.FailedToSendBranchCommitRequest,
+ exception.getCode());
+ assertSame(cause, exception.getCause());
+ }
+
+ @Test
+ public void testConstructorWithMessage() {
+ String message = "Test exception message";
+ TransactionException exception = new TransactionException(message);
+
+ assertNotNull(exception);
+ assertEquals(message, exception.getMessage());
+ // Apache Seata sets default Unknown code when only message is provided
+
assertEquals(org.apache.seata.core.exception.TransactionExceptionCode.Unknown,
exception.getCode());
+ }
+
+ @Test
+ public void testConstructorWithCodeAndMessage() {
+ String message = "Rollback failed due to timeout";
+ TransactionException exception =
+ new
TransactionException(TransactionExceptionCode.BranchRollbackFailed_Retriable,
message);
+
+ assertNotNull(exception);
+ assertEquals(
+
org.apache.seata.core.exception.TransactionExceptionCode.BranchRollbackFailed_Retriable,
+ exception.getCode());
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ public void testConstructorWithCause() {
+ Throwable cause = new IllegalStateException("Invalid state");
+ TransactionException exception = new TransactionException(cause);
+
+ assertNotNull(exception);
+ assertSame(cause, exception.getCause());
+ }
+
+ @Test
+ public void testConstructorWithMessageAndCause() {
+ String message = "Transaction failed";
+ Throwable cause = new IllegalArgumentException("Invalid argument");
+ TransactionException exception = new TransactionException(message,
cause);
+
+ assertNotNull(exception);
+ assertEquals(message, exception.getMessage());
+ assertSame(cause, exception.getCause());
+ }
+
+ @Test
+ public void testConstructorWithCodeMessageAndCause() {
+ String message = "Global lock acquire failed";
+ Throwable cause = new InterruptedException("Lock timeout");
+ TransactionException exception =
+ new
TransactionException(TransactionExceptionCode.LockKeyConflict, message, cause);
+
+ assertNotNull(exception);
+
assertEquals(org.apache.seata.core.exception.TransactionExceptionCode.LockKeyConflict,
exception.getCode());
+ assertEquals(message, exception.getMessage());
+ assertSame(cause, exception.getCause());
+ }
+
+ @Test
+ public void testAllExceptionCodes() {
+ // Test that all exception codes can be properly converted via ordinal
+ for (TransactionExceptionCode code :
TransactionExceptionCode.values()) {
+ TransactionException exception = new TransactionException(code);
+ assertNotNull(exception);
+ assertNotNull(exception.getCode());
+ // Compare by ordinal since conversion is based on ordinal, not
name
+ // (io.seata has typo "FailedLockGlobalTranscation" vs Apache's
"FailedLockGlobalTransaction")
+ assertEquals(code.ordinal(), exception.getCode().ordinal());
+ }
+ }
+
+ @Test
+ public void testExceptionCodeConversion() {
+ // Test specific code conversions
+ TransactionException unknownException = new
TransactionException(TransactionExceptionCode.Unknown);
+
assertEquals(org.apache.seata.core.exception.TransactionExceptionCode.Unknown,
unknownException.getCode());
+
+ TransactionException beginException = new
TransactionException(TransactionExceptionCode.BeginFailed);
+
assertEquals(org.apache.seata.core.exception.TransactionExceptionCode.BeginFailed,
beginException.getCode());
+
+ TransactionException commitException =
+ new
TransactionException(TransactionExceptionCode.FailedToSendBranchCommitRequest);
+ assertEquals(
+
org.apache.seata.core.exception.TransactionExceptionCode.FailedToSendBranchCommitRequest,
+ commitException.getCode());
+
+ TransactionException rollbackException =
+ new
TransactionException(TransactionExceptionCode.BranchRollbackFailed_Retriable);
+ assertEquals(
+
org.apache.seata.core.exception.TransactionExceptionCode.BranchRollbackFailed_Retriable,
+ rollbackException.getCode());
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/core/store/db/sql/lock/LockStoreSqlTest.java
b/compatible/src/test/java/io/seata/core/store/db/sql/lock/LockStoreSqlTest.java
new file mode 100644
index 0000000000..5b9c82bd4c
--- /dev/null
+++
b/compatible/src/test/java/io/seata/core/store/db/sql/lock/LockStoreSqlTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.core.store.db.sql.lock;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for LockStoreSql interface.
+ */
+public class LockStoreSqlTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+ LockStoreSql.class.isAnnotationPresent(Deprecated.class),
+ "LockStoreSql should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testIsInterface() {
+ assertTrue(LockStoreSql.class.isInterface(), "LockStoreSql should be
an interface");
+ }
+
+ @Test
+ public void testExtendsApacheSeataLockStoreSql() {
+ assertTrue(
+
org.apache.seata.core.store.db.sql.lock.LockStoreSql.class.isAssignableFrom(LockStoreSql.class),
+ "Should extend
org.apache.seata.core.store.db.sql.lock.LockStoreSql");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/core/store/db/sql/log/LogStoreSqlsTest.java
b/compatible/src/test/java/io/seata/core/store/db/sql/log/LogStoreSqlsTest.java
new file mode 100644
index 0000000000..0b09c320a8
--- /dev/null
+++
b/compatible/src/test/java/io/seata/core/store/db/sql/log/LogStoreSqlsTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.core.store.db.sql.log;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for LogStoreSqls interface.
+ */
+public class LogStoreSqlsTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+ LogStoreSqls.class.isAnnotationPresent(Deprecated.class),
+ "LogStoreSqls should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testIsInterface() {
+ assertTrue(LogStoreSqls.class.isInterface(), "LogStoreSqls should be
an interface");
+ }
+
+ @Test
+ public void testExtendsApacheSeataLogStoreSqls() {
+ assertTrue(
+
org.apache.seata.core.store.db.sql.log.LogStoreSqls.class.isAssignableFrom(LogStoreSqls.class),
+ "Should extend
org.apache.seata.core.store.db.sql.log.LogStoreSqls");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/grpc/interceptor/client/ClientTransactionInterceptorTest.java
b/compatible/src/test/java/io/seata/integration/grpc/interceptor/client/ClientTransactionInterceptorTest.java
new file mode 100644
index 0000000000..e29efc94de
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/grpc/interceptor/client/ClientTransactionInterceptorTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.grpc.interceptor.client;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for ClientTransactionInterceptor compatibility wrapper.
+ */
+public class ClientTransactionInterceptorTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
ClientTransactionInterceptor.class.isAnnotationPresent(Deprecated.class),
+ "ClientTransactionInterceptor should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.grpc.interceptor.client.ClientTransactionInterceptor.class
+ .isAssignableFrom(ClientTransactionInterceptor.class),
+ "ClientTransactionInterceptor should extend Apache Seata
ClientTransactionInterceptor");
+ }
+
+ @Test
+ public void testConstructor() {
+ ClientTransactionInterceptor interceptor = new
ClientTransactionInterceptor();
+ assertNotNull(interceptor);
+ }
+
+ @Test
+ public void testInstanceOfApacheSeataClass() {
+ ClientTransactionInterceptor interceptor = new
ClientTransactionInterceptor();
+ assertTrue(
+ interceptor
+ instanceof
org.apache.seata.integration.grpc.interceptor.client.ClientTransactionInterceptor,
+ "Instance should be of Apache Seata
ClientTransactionInterceptor type");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/grpc/interceptor/server/ServerTransactionInterceptorTest.java
b/compatible/src/test/java/io/seata/integration/grpc/interceptor/server/ServerTransactionInterceptorTest.java
new file mode 100644
index 0000000000..6fcdc0820a
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/grpc/interceptor/server/ServerTransactionInterceptorTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.grpc.interceptor.server;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for ServerTransactionInterceptor compatibility wrapper.
+ */
+public class ServerTransactionInterceptorTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
ServerTransactionInterceptor.class.isAnnotationPresent(Deprecated.class),
+ "ServerTransactionInterceptor should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.grpc.interceptor.server.ServerTransactionInterceptor.class
+ .isAssignableFrom(ServerTransactionInterceptor.class),
+ "ServerTransactionInterceptor should extend Apache Seata
ServerTransactionInterceptor");
+ }
+
+ @Test
+ public void testConstructor() {
+ ServerTransactionInterceptor interceptor = new
ServerTransactionInterceptor();
+ assertNotNull(interceptor);
+ }
+
+ @Test
+ public void testInstanceOfApacheSeataClass() {
+ ServerTransactionInterceptor interceptor = new
ServerTransactionInterceptor();
+ assertTrue(
+ interceptor
+ instanceof
org.apache.seata.integration.grpc.interceptor.server.ServerTransactionInterceptor,
+ "Instance should be of Apache Seata
ServerTransactionInterceptor type");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/http/DefaultHttpExecutorTest.java
b/compatible/src/test/java/io/seata/integration/http/DefaultHttpExecutorTest.java
new file mode 100644
index 0000000000..c9f8a41964
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/http/DefaultHttpExecutorTest.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.http;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for DefaultHttpExecutor compatibility wrapper.
+ */
+public class DefaultHttpExecutorTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
DefaultHttpExecutor.class.isAnnotationPresent(Deprecated.class),
+ "DefaultHttpExecutor should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testGetInstance() {
+ DefaultHttpExecutor executor = DefaultHttpExecutor.getInstance();
+ assertNotNull(executor, "getInstance() should return non-null
instance");
+ }
+
+ @Test
+ public void testGetInstanceReturnsSameWrapper() {
+ DefaultHttpExecutor executor1 = DefaultHttpExecutor.getInstance();
+ DefaultHttpExecutor executor2 = DefaultHttpExecutor.getInstance();
+
+ assertNotNull(executor1);
+ assertNotNull(executor2);
+ // Each call creates a new wrapper instance
+ }
+
+ @Test
+ public void testInitGetUrl() {
+ DefaultHttpExecutor executor = DefaultHttpExecutor.getInstance();
+
+ String host = "http://localhost:8080";
+ String path = "/api/test";
+ Map<String, String> querys = new HashMap<>();
+ querys.put("param1", "value1");
+ querys.put("param2", "value2");
+
+ String url = executor.initGetUrl(host, path, querys);
+
+ assertNotNull(url);
+ assertTrue(url.contains(host));
+ assertTrue(url.contains(path));
+ }
+
+ // @Test
+ // public void testInitGetUrlWithNullQuerys() {
+ // DefaultHttpExecutor executor = DefaultHttpExecutor.getInstance();
+ //
+ // String host = "http://localhost:8080";
+ // String path = "/api/test";
+ //
+ // String url = executor.initGetUrl(host, path, null);
+ //
+ // assertNotNull(url);
+ // assertTrue(url.contains(host));
+ // assertTrue(url.contains(path));
+ // }
+
+ @Test
+ public void testInitGetUrlWithEmptyQuerys() {
+ DefaultHttpExecutor executor = DefaultHttpExecutor.getInstance();
+
+ String host = "http://localhost:8080";
+ String path = "/api/test";
+ Map<String, String> querys = new HashMap<>();
+
+ String url = executor.initGetUrl(host, path, querys);
+
+ assertNotNull(url);
+ assertTrue(url.contains(host));
+ assertTrue(url.contains(path));
+ }
+
+ @Test
+ public void testBuildGetHeaders() {
+ DefaultHttpExecutor executor = DefaultHttpExecutor.getInstance();
+
+ Map<String, String> headers = new HashMap<>();
+ TestParam paramObject = new TestParam("test-value");
+
+ // Should not throw exception
+ executor.buildGetHeaders(headers, paramObject);
+ }
+
+ @Test
+ public void testBuildPostHeaders() {
+ DefaultHttpExecutor executor = DefaultHttpExecutor.getInstance();
+
+ Map<String, String> headers = new HashMap<>();
+ TestParam paramObject = new TestParam("test-value");
+
+ // Should not throw exception
+ executor.buildPostHeaders(headers, paramObject);
+ }
+
+ // Test helper class
+ static class TestParam {
+ private String value;
+
+ public TestParam(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/http/JakartaSeataWebMvcConfigurerTest.java
b/compatible/src/test/java/io/seata/integration/http/JakartaSeataWebMvcConfigurerTest.java
new file mode 100644
index 0000000000..695b84b438
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/http/JakartaSeataWebMvcConfigurerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.http;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for JakartaSeataWebMvcConfigurer compatibility wrapper.
+ */
+public class JakartaSeataWebMvcConfigurerTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
JakartaSeataWebMvcConfigurer.class.isAnnotationPresent(Deprecated.class),
+ "JakartaSeataWebMvcConfigurer should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.http.JakartaSeataWebMvcConfigurer.class.isAssignableFrom(
+ JakartaSeataWebMvcConfigurer.class),
+ "JakartaSeataWebMvcConfigurer should extend Apache Seata
JakartaSeataWebMvcConfigurer");
+ }
+
+ @Test
+ public void testConstructor() {
+ JakartaSeataWebMvcConfigurer configurer = new
JakartaSeataWebMvcConfigurer();
+ assertNotNull(configurer);
+ }
+
+ @Test
+ public void testInstanceOfApacheSeataClass() {
+ JakartaSeataWebMvcConfigurer configurer = new
JakartaSeataWebMvcConfigurer();
+ assertTrue(
+ configurer instanceof
org.apache.seata.integration.http.JakartaSeataWebMvcConfigurer,
+ "Instance should be of Apache Seata
JakartaSeataWebMvcConfigurer type");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/http/JakartaTransactionPropagationInterceptorTest.java
b/compatible/src/test/java/io/seata/integration/http/JakartaTransactionPropagationInterceptorTest.java
new file mode 100644
index 0000000000..66b135b90c
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/http/JakartaTransactionPropagationInterceptorTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.http;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for JakartaTransactionPropagationInterceptor compatibility
wrapper.
+ */
+public class JakartaTransactionPropagationInterceptorTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
JakartaTransactionPropagationInterceptor.class.isAnnotationPresent(Deprecated.class),
+ "JakartaTransactionPropagationInterceptor should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.http.JakartaTransactionPropagationInterceptor.class.isAssignableFrom(
+ JakartaTransactionPropagationInterceptor.class),
+ "JakartaTransactionPropagationInterceptor should extend Apache
Seata JakartaTransactionPropagationInterceptor");
+ }
+
+ @Test
+ public void testConstructor() {
+ JakartaTransactionPropagationInterceptor interceptor = new
JakartaTransactionPropagationInterceptor();
+ assertNotNull(interceptor);
+ }
+
+ @Test
+ public void testInstanceOfApacheSeataClass() {
+ JakartaTransactionPropagationInterceptor interceptor = new
JakartaTransactionPropagationInterceptor();
+ assertTrue(
+ interceptor instanceof
org.apache.seata.integration.http.JakartaTransactionPropagationInterceptor,
+ "Instance should be of Apache Seata
JakartaTransactionPropagationInterceptor type");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/http/SeataWebMvcConfigurerTest.java
b/compatible/src/test/java/io/seata/integration/http/SeataWebMvcConfigurerTest.java
new file mode 100644
index 0000000000..f0c23f5d25
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/http/SeataWebMvcConfigurerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.http;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for SeataWebMvcConfigurer compatibility wrapper.
+ */
+public class SeataWebMvcConfigurerTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
SeataWebMvcConfigurer.class.isAnnotationPresent(Deprecated.class),
+ "SeataWebMvcConfigurer should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.http.SeataWebMvcConfigurer.class.isAssignableFrom(
+ SeataWebMvcConfigurer.class),
+ "SeataWebMvcConfigurer should extend Apache Seata
SeataWebMvcConfigurer");
+ }
+
+ @Test
+ public void testConstructor() {
+ SeataWebMvcConfigurer configurer = new SeataWebMvcConfigurer();
+ assertNotNull(configurer);
+ }
+
+ @Test
+ public void testInstanceOfApacheSeataClass() {
+ SeataWebMvcConfigurer configurer = new SeataWebMvcConfigurer();
+ assertTrue(
+ configurer instanceof
org.apache.seata.integration.http.SeataWebMvcConfigurer,
+ "Instance should be of Apache Seata SeataWebMvcConfigurer
type");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/http/TransactionPropagationInterceptorTest.java
b/compatible/src/test/java/io/seata/integration/http/TransactionPropagationInterceptorTest.java
new file mode 100644
index 0000000000..494583e003
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/http/TransactionPropagationInterceptorTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.http;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for TransactionPropagationInterceptor compatibility wrapper.
+ */
+public class TransactionPropagationInterceptorTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
TransactionPropagationInterceptor.class.isAnnotationPresent(Deprecated.class),
+ "TransactionPropagationInterceptor should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.http.TransactionPropagationInterceptor.class.isAssignableFrom(
+ TransactionPropagationInterceptor.class),
+ "TransactionPropagationInterceptor should extend Apache Seata
TransactionPropagationInterceptor");
+ }
+
+ @Test
+ public void testConstructor() {
+ TransactionPropagationInterceptor interceptor = new
TransactionPropagationInterceptor();
+ assertNotNull(interceptor);
+ }
+
+ @Test
+ public void testInstanceOfApacheSeataClass() {
+ TransactionPropagationInterceptor interceptor = new
TransactionPropagationInterceptor();
+ assertTrue(
+ interceptor instanceof
org.apache.seata.integration.http.TransactionPropagationInterceptor,
+ "Instance should be of Apache Seata
TransactionPropagationInterceptor type");
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandlerTest.java
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandlerTest.java
new file mode 100644
index 0000000000..77c9c37ae4
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandlerTest.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.tx.api.interceptor;
+
+import io.seata.rm.tcc.api.BusinessActionContext;
+import io.seata.rm.tcc.api.BusinessActionContextParameter;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for ActionInterceptorHandler compatibility wrapper.
+ */
+public class ActionInterceptorHandlerTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
ActionInterceptorHandler.class.isAnnotationPresent(Deprecated.class),
+ "ActionInterceptorHandler should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataClass() {
+ assertTrue(
+
org.apache.seata.integration.tx.api.interceptor.ActionInterceptorHandler.class.isAssignableFrom(
+ ActionInterceptorHandler.class),
+ "ActionInterceptorHandler should extend Apache Seata
ActionInterceptorHandler");
+ }
+
+ @Test
+ public void testConstructor() {
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+ assertNotNull(handler);
+ }
+
+ @Test
+ public void testGetOrCreateActionContextWithNullContext() throws Exception
{
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+
+ Method method = ActionInterceptorHandler.class.getDeclaredMethod(
+ "getOrCreateActionContextAndResetToArguments", Class[].class,
Object[].class);
+ method.setAccessible(true);
+
+ Class<?>[] parameterTypes = {String.class, int.class};
+ Object[] arguments = {"test", 123};
+
+ BusinessActionContext result = (BusinessActionContext)
method.invoke(handler, parameterTypes, arguments);
+
+ assertNotNull(result);
+ }
+
+ @Test
+ public void testGetOrCreateActionContextWithExistingContext() throws
Exception {
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+
+ Method method = ActionInterceptorHandler.class.getDeclaredMethod(
+ "getOrCreateActionContextAndResetToArguments", Class[].class,
Object[].class);
+ method.setAccessible(true);
+
+ BusinessActionContext existingContext = new BusinessActionContext();
+ existingContext.setXid("test-xid");
+
+ Class<?>[] parameterTypes = {BusinessActionContext.class,
String.class};
+ Object[] arguments = {existingContext, "test"};
+
+ BusinessActionContext result = (BusinessActionContext)
method.invoke(handler, parameterTypes, arguments);
+
+ assertNotNull(result);
+ assertEquals("test-xid", result.getXid());
+ }
+
+ @Test
+ public void testGetOrCreateActionContextCreatesNewWhenNull() throws
Exception {
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+
+ Method method = ActionInterceptorHandler.class.getDeclaredMethod(
+ "getOrCreateActionContextAndResetToArguments", Class[].class,
Object[].class);
+ method.setAccessible(true);
+
+ Class<?>[] parameterTypes = {BusinessActionContext.class,
String.class};
+ Object[] arguments = {null, "test"};
+
+ BusinessActionContext result = (BusinessActionContext)
method.invoke(handler, parameterTypes, arguments);
+
+ assertNotNull(result);
+ // Verify the argument was updated
+ assertNotNull(arguments[0]);
+ }
+
+ @Test
+ public void testFetchActionRequestContextWithAnnotatedParam() throws
Exception {
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+
+ Method testMethod =
TestService.class.getMethod("actionWithAnnotatedParam", String.class,
int.class);
+
+ Method fetchMethod = ActionInterceptorHandler.class.getDeclaredMethod(
+ "fetchActionRequestContext", Method.class, Object[].class);
+ fetchMethod.setAccessible(true);
+
+ Object[] arguments = {"test-value", 100};
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> context = (Map<String, Object>)
fetchMethod.invoke(handler, testMethod, arguments);
+
+ assertNotNull(context);
+ assertEquals("test-value", context.get("userId"));
+ }
+
+ @Test
+ public void testFetchActionRequestContextWithoutAnnotation() throws
Exception {
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+
+ Method testMethod =
TestService.class.getMethod("actionWithoutAnnotation", String.class);
+
+ Method fetchMethod = ActionInterceptorHandler.class.getDeclaredMethod(
+ "fetchActionRequestContext", Method.class, Object[].class);
+ fetchMethod.setAccessible(true);
+
+ Object[] arguments = {"test-value"};
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> context = (Map<String, Object>)
fetchMethod.invoke(handler, testMethod, arguments);
+
+ assertNotNull(context);
+ assertTrue(context.isEmpty());
+ }
+
+ @Test
+ public void testFetchActionRequestContextWithNullParam() throws Exception {
+ ActionInterceptorHandler handler = new ActionInterceptorHandler();
+
+ Method testMethod =
TestService.class.getMethod("actionWithAnnotatedParam", String.class,
int.class);
+
+ Method fetchMethod = ActionInterceptorHandler.class.getDeclaredMethod(
+ "fetchActionRequestContext", Method.class, Object[].class);
+ fetchMethod.setAccessible(true);
+
+ Object[] arguments = {null, 100};
+
+ assertThrows(
+ Exception.class,
+ () -> fetchMethod.invoke(handler, testMethod, arguments),
+ "Should throw exception for null annotated parameter");
+ }
+
+ // Test service class
+ public static class TestService {
+
+ public void actionWithAnnotatedParam(
+ @BusinessActionContextParameter(paramName = "userId") String
userId, int amount) {}
+
+ public void actionWithoutAnnotation(String param) {}
+
+ public void actionWithContext(BusinessActionContext context, String
param) {}
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandlerTest.java
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandlerTest.java
new file mode 100644
index 0000000000..a0f52859d9
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandlerTest.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.tx.api.interceptor.handler;
+
+import io.seata.common.LockStrategyMode;
+import io.seata.spring.annotation.GlobalLock;
+import io.seata.spring.annotation.GlobalTransactional;
+import io.seata.tm.api.transaction.Propagation;
+import org.apache.seata.core.model.GlobalLockConfig;
+import org.apache.seata.integration.tx.api.annotation.AspectTransactional;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for GlobalTransactionalInterceptorHandler.
+ */
+public class GlobalTransactionalInterceptorHandlerTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
GlobalTransactionalInterceptorHandler.class.isAnnotationPresent(Deprecated.class),
+ "GlobalTransactionalInterceptorHandler should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataHandler() {
+ assertTrue(
+
org.apache.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler.class
+
.isAssignableFrom(GlobalTransactionalInterceptorHandler.class),
+ "Should extend Apache Seata
GlobalTransactionalInterceptorHandler");
+ }
+
+ @Test
+ public void testGetGlobalLockConfigWithAnnotation() throws Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithGlobalLock");
+ GlobalLockConfig config = handler.getGlobalLockConfig(method,
TestService.class);
+
+ assertNotNull(config);
+ assertEquals(100, config.getLockRetryInterval());
+ assertEquals(10, config.getLockRetryTimes());
+ }
+
+ @Test
+ public void testGetGlobalLockConfigWithoutAnnotation() throws Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithoutGlobalLock");
+ GlobalLockConfig config = handler.getGlobalLockConfig(method,
TestService.class);
+
+ assertNull(config);
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithRequiredPropagation() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithRequired");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(30000, aspectTransactional.getTimeoutMills());
+ assertEquals("testTx", aspectTransactional.getName());
+ assertEquals(org.apache.seata.tm.api.transaction.Propagation.REQUIRED,
aspectTransactional.getPropagation());
+ assertEquals(org.apache.seata.common.LockStrategyMode.OPTIMISTIC,
aspectTransactional.getLockStrategyMode());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithRequiresNewPropagation() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithRequiresNew");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(
+ org.apache.seata.tm.api.transaction.Propagation.REQUIRES_NEW,
aspectTransactional.getPropagation());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithSupportsPropagation() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithSupports");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(org.apache.seata.tm.api.transaction.Propagation.SUPPORTS,
aspectTransactional.getPropagation());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithNotSupportedPropagation() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithNotSupported");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(
+ org.apache.seata.tm.api.transaction.Propagation.NOT_SUPPORTED,
aspectTransactional.getPropagation());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithNeverPropagation() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithNever");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(org.apache.seata.tm.api.transaction.Propagation.NEVER,
aspectTransactional.getPropagation());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithMandatoryPropagation() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithMandatory");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+
assertEquals(org.apache.seata.tm.api.transaction.Propagation.MANDATORY,
aspectTransactional.getPropagation());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithPessimisticLock() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method =
TestService.class.getMethod("methodWithPessimisticLock");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(org.apache.seata.common.LockStrategyMode.PESSIMISTIC,
aspectTransactional.getLockStrategyMode());
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithoutAnnotation() throws Exception
{
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithoutAnnotation");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNull(aspectTransactional);
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithRollbackFor() throws Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithRollbackFor");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(1, aspectTransactional.getRollbackFor().length);
+ assertEquals(Exception.class, aspectTransactional.getRollbackFor()[0]);
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithNoRollbackFor() throws Exception
{
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithNoRollbackFor");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(1, aspectTransactional.getNoRollbackFor().length);
+ assertEquals(RuntimeException.class,
aspectTransactional.getNoRollbackFor()[0]);
+ }
+
+ @Test
+ public void testGetAspectTransactionalWithLockRetryConfig() throws
Exception {
+ GlobalTransactionalInterceptorHandler handler = createHandler();
+
+ Method method = TestService.class.getMethod("methodWithLockRetry");
+ AspectTransactional aspectTransactional =
handler.getAspectTransactional(method, TestService.class);
+
+ assertNotNull(aspectTransactional);
+ assertEquals(500, aspectTransactional.getLockRetryInterval());
+ assertEquals(5, aspectTransactional.getLockRetryTimes());
+ }
+
+ private GlobalTransactionalInterceptorHandler createHandler() {
+ Set<String> methodsToProxy = new HashSet<>();
+ return new GlobalTransactionalInterceptorHandler(
+ new org.apache.seata.tm.api.DefaultFailureHandlerImpl(),
methodsToProxy);
+ }
+
+ // Test service class with various annotations
+ public static class TestService {
+
+ @GlobalLock(lockRetryInterval = 100, lockRetryTimes = 10)
+ public void methodWithGlobalLock() {}
+
+ public void methodWithoutGlobalLock() {}
+
+ @GlobalTransactional(
+ timeoutMills = 30000,
+ name = "testTx",
+ propagation = Propagation.REQUIRED,
+ lockStrategyMode = LockStrategyMode.OPTIMISTIC)
+ public void methodWithRequired() {}
+
+ @GlobalTransactional(propagation = Propagation.REQUIRES_NEW)
+ public void methodWithRequiresNew() {}
+
+ @GlobalTransactional(propagation = Propagation.SUPPORTS)
+ public void methodWithSupports() {}
+
+ @GlobalTransactional(propagation = Propagation.NOT_SUPPORTED)
+ public void methodWithNotSupported() {}
+
+ @GlobalTransactional(propagation = Propagation.NEVER)
+ public void methodWithNever() {}
+
+ @GlobalTransactional(propagation = Propagation.MANDATORY)
+ public void methodWithMandatory() {}
+
+ @GlobalTransactional(lockStrategyMode = LockStrategyMode.PESSIMISTIC)
+ public void methodWithPessimisticLock() {}
+
+ public void methodWithoutAnnotation() {}
+
+ @GlobalTransactional(rollbackFor = Exception.class)
+ public void methodWithRollbackFor() {}
+
+ @GlobalTransactional(noRollbackFor = RuntimeException.class)
+ public void methodWithNoRollbackFor() {}
+
+ @GlobalTransactional(lockRetryInterval = 500, lockRetryTimes = 5)
+ public void methodWithLockRetry() {}
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/tx/api/json/JsonParserTest.java
b/compatible/src/test/java/io/seata/integration/tx/api/json/JsonParserTest.java
new file mode 100644
index 0000000000..2092bd296e
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/tx/api/json/JsonParserTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.tx.api.json;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for JsonParser compatibility interface.
+ */
+public class JsonParserTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+ JsonParser.class.isAnnotationPresent(Deprecated.class),
"JsonParser should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataInterface() {
+ assertTrue(
+
org.apache.seata.integration.tx.api.json.JsonParser.class.isAssignableFrom(JsonParser.class),
+ "JsonParser should extend Apache Seata JsonParser interface");
+ }
+
+ @Test
+ public void testIsInterface() {
+ assertTrue(JsonParser.class.isInterface(), "JsonParser should be an
interface");
+ }
+
+ @Test
+ public void testImplementationCanBeAssigned() {
+ // Test that an implementation of Apache Seata JsonParser can be used
as io.seata JsonParser
+ org.apache.seata.integration.tx.api.json.JsonParser apacheParser = new
TestJsonParser();
+ assertTrue(
+ apacheParser instanceof JsonParser,
+ "Apache Seata JsonParser implementation should be assignable
to io.seata JsonParser");
+ }
+
+ // Test implementation
+ static class TestJsonParser implements JsonParser {
+ @Override
+ public String toJSONString(Object object) {
+ return "{}";
+ }
+
+ @Override
+ public <T> T parseObject(String text, Class<T> clazz) {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "test-parser";
+ }
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/integration/tx/api/remoting/RemotingParserTest.java
b/compatible/src/test/java/io/seata/integration/tx/api/remoting/RemotingParserTest.java
new file mode 100644
index 0000000000..0fd3312d53
--- /dev/null
+++
b/compatible/src/test/java/io/seata/integration/tx/api/remoting/RemotingParserTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.integration.tx.api.remoting;
+
+import org.apache.seata.common.exception.FrameworkException;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for RemotingParser compatibility interface.
+ */
+public class RemotingParserTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+ RemotingParser.class.isAnnotationPresent(Deprecated.class),
+ "RemotingParser should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataInterface() {
+ assertTrue(
+
org.apache.seata.integration.tx.api.remoting.RemotingParser.class.isAssignableFrom(
+ RemotingParser.class),
+ "RemotingParser should extend Apache Seata RemotingParser
interface");
+ }
+
+ @Test
+ public void testIsInterface() {
+ assertTrue(RemotingParser.class.isInterface(), "RemotingParser should
be an interface");
+ }
+
+ @Test
+ public void testImplementationCanBeAssigned() {
+ // Test that an implementation of Apache Seata RemotingParser can be
used as io.seata RemotingParser
+ org.apache.seata.integration.tx.api.remoting.RemotingParser
apacheParser = new TestRemotingParser();
+ assertTrue(
+ apacheParser instanceof RemotingParser,
+ "Apache Seata RemotingParser implementation should be
assignable to io.seata RemotingParser");
+ }
+
+ // Test implementation
+ static class TestRemotingParser implements RemotingParser {
+ @Override
+ public boolean isRemoting(Object bean, String beanName) {
+ return false;
+ }
+
+ @Override
+ public boolean isReference(Object bean, String beanName) {
+ return false;
+ }
+
+ @Override
+ public boolean isService(Object bean, String beanName) {
+ return false;
+ }
+
+ @Override
+ public boolean isService(Class<?> beanClass) throws FrameworkException
{
+ return false;
+ }
+
+ @Override
+ public org.apache.seata.integration.tx.api.remoting.RemotingDesc
getServiceDesc(Object bean, String beanName) {
+ return null;
+ }
+
+ @Override
+ public short getProtocol() {
+ return 0;
+ }
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/rm/tcc/api/BusinessActionContextParameterTest.java
b/compatible/src/test/java/io/seata/rm/tcc/api/BusinessActionContextParameterTest.java
new file mode 100644
index 0000000000..4b45dd9d75
--- /dev/null
+++
b/compatible/src/test/java/io/seata/rm/tcc/api/BusinessActionContextParameterTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.rm.tcc.api;
+
+import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for BusinessActionContextParameter annotation.
+ */
+public class BusinessActionContextParameterTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
BusinessActionContextParameter.class.isAnnotationPresent(Deprecated.class),
+ "BusinessActionContextParameter should be marked as
@Deprecated");
+ }
+
+ @Test
+ public void testAnnotationRetention() {
+ Retention retention =
BusinessActionContextParameter.class.getAnnotation(Retention.class);
+ assertNotNull(retention);
+ assertEquals(RetentionPolicy.RUNTIME, retention.value());
+ }
+
+ @Test
+ public void testAnnotationTarget() {
+ Target target =
BusinessActionContextParameter.class.getAnnotation(Target.class);
+ assertNotNull(target);
+ assertEquals(2, target.value().length);
+ assertTrue(containsElementType(target.value(), ElementType.PARAMETER),
"Should target PARAMETER");
+ assertTrue(containsElementType(target.value(), ElementType.FIELD),
"Should target FIELD");
+ }
+
+ @Test
+ public void testDefaultValues() throws NoSuchMethodException {
+ Method valueMethod =
BusinessActionContextParameter.class.getMethod("value");
+ assertEquals("", valueMethod.getDefaultValue());
+
+ Method paramNameMethod =
BusinessActionContextParameter.class.getMethod("paramName");
+ assertEquals("", paramNameMethod.getDefaultValue());
+
+ Method isShardingParamMethod =
BusinessActionContextParameter.class.getMethod("isShardingParam");
+ assertEquals(false, isShardingParamMethod.getDefaultValue());
+
+ Method indexMethod =
BusinessActionContextParameter.class.getMethod("index");
+ assertEquals(-1, indexMethod.getDefaultValue());
+
+ Method isParamInPropertyMethod =
BusinessActionContextParameter.class.getMethod("isParamInProperty");
+ assertEquals(false, isParamInPropertyMethod.getDefaultValue());
+ }
+
+ @Test
+ public void testParameterAnnotationUsage() throws Exception {
+ Method method = TestService.class.getMethod("testMethod",
String.class, int.class, String.class);
+ Parameter[] parameters = method.getParameters();
+
+ // First parameter
+ BusinessActionContextParameter annotation1 =
parameters[0].getAnnotation(BusinessActionContextParameter.class);
+ assertNotNull(annotation1);
+ assertEquals("userId", annotation1.value());
+ assertEquals("", annotation1.paramName());
+ assertEquals(-1, annotation1.index());
+ assertFalse(annotation1.isParamInProperty());
+
+ // Second parameter
+ BusinessActionContextParameter annotation2 =
parameters[1].getAnnotation(BusinessActionContextParameter.class);
+ assertNotNull(annotation2);
+ assertEquals("", annotation2.value());
+ assertEquals("amount", annotation2.paramName());
+ assertEquals(0, annotation2.index());
+ assertFalse(annotation2.isParamInProperty());
+
+ // Third parameter
+ BusinessActionContextParameter annotation3 =
parameters[2].getAnnotation(BusinessActionContextParameter.class);
+ assertNotNull(annotation3);
+ assertTrue(annotation3.isParamInProperty());
+ }
+
+ @Test
+ public void testFieldAnnotationUsage() throws Exception {
+ Field field = TestEntity.class.getDeclaredField("accountId");
+ BusinessActionContextParameter annotation =
field.getAnnotation(BusinessActionContextParameter.class);
+
+ assertNotNull(annotation);
+ assertEquals("account_id", annotation.value());
+ }
+
+ @Test
+ public void testIsShardingParamDeprecated() throws NoSuchMethodException {
+ Method method =
BusinessActionContextParameter.class.getMethod("isShardingParam");
+ assertTrue(method.isAnnotationPresent(Deprecated.class),
"isShardingParam should be marked as @Deprecated");
+ }
+
+ private boolean containsElementType(ElementType[] types, ElementType
target) {
+ for (ElementType type : types) {
+ if (type == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Test service for annotation usage
+ public static class TestService {
+ public void testMethod(
+ @BusinessActionContextParameter(value = "userId") String
userId,
+ @BusinessActionContextParameter(paramName = "amount", index =
0) int amount,
+ @BusinessActionContextParameter(isParamInProperty = true)
String data) {}
+ }
+
+ // Test entity for field annotation
+ public static class TestEntity {
+ @BusinessActionContextParameter("account_id")
+ private String accountId;
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/rm/tcc/api/BusinessActionContextTest.java
b/compatible/src/test/java/io/seata/rm/tcc/api/BusinessActionContextTest.java
new file mode 100644
index 0000000000..83f012e8bf
--- /dev/null
+++
b/compatible/src/test/java/io/seata/rm/tcc/api/BusinessActionContextTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.rm.tcc.api;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for BusinessActionContext.
+ */
+public class BusinessActionContextTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
BusinessActionContext.class.isAnnotationPresent(Deprecated.class),
+ "BusinessActionContext should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataBusinessActionContext() {
+ assertTrue(
+
org.apache.seata.rm.tcc.api.BusinessActionContext.class.isAssignableFrom(BusinessActionContext.class),
+ "Should extend
org.apache.seata.rm.tcc.api.BusinessActionContext");
+ }
+
+ @Test
+ public void testDefaultConstructor() {
+ BusinessActionContext context = new BusinessActionContext();
+ assertNotNull(context);
+ }
+
+ @Test
+ public void testInheritedMethods() {
+ BusinessActionContext context = new BusinessActionContext();
+
+ context.setXid("test-xid");
+ context.setBranchId(123456L);
+ context.setActionName("testAction");
+ context.setDelayReport(true);
+
+ assertNotNull(context);
+ }
+}
diff --git a/compatible/src/test/java/io/seata/rm/tcc/api/LocalTCCTest.java
b/compatible/src/test/java/io/seata/rm/tcc/api/LocalTCCTest.java
new file mode 100644
index 0000000000..143cd78b4b
--- /dev/null
+++ b/compatible/src/test/java/io/seata/rm/tcc/api/LocalTCCTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.rm.tcc.api;
+
+import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for LocalTCC annotation.
+ */
+public class LocalTCCTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(LocalTCC.class.isAnnotationPresent(Deprecated.class),
"LocalTCC should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testAnnotationRetention() {
+ Retention retention = LocalTCC.class.getAnnotation(Retention.class);
+ assertNotNull(retention);
+ assertEquals(RetentionPolicy.RUNTIME, retention.value());
+ }
+
+ @Test
+ public void testAnnotationTarget() {
+ Target target = LocalTCC.class.getAnnotation(Target.class);
+ assertNotNull(target);
+ assertEquals(1, target.value().length);
+ assertEquals(ElementType.TYPE, target.value()[0]);
+ }
+
+ @Test
+ public void testAnnotationInherited() {
+ assertTrue(LocalTCC.class.isAnnotationPresent(Inherited.class),
"LocalTCC should be marked as @Inherited");
+ }
+
+ @Test
+ public void testAnnotationUsage() {
+ LocalTCC annotation =
TestTccService.class.getAnnotation(LocalTCC.class);
+ assertNotNull(annotation, "TestTccService should have LocalTCC
annotation");
+ }
+
+ @Test
+ public void testInheritance() {
+ // Test that the annotation is inherited
+ LocalTCC annotation =
ChildTestTccService.class.getAnnotation(LocalTCC.class);
+ assertNotNull(annotation, "ChildTestTccService should inherit LocalTCC
annotation from parent");
+ }
+
+ @Test
+ public void testWithoutAnnotation() {
+ LocalTCC annotation =
RegularService.class.getAnnotation(LocalTCC.class);
+ assertTrue(annotation == null, "RegularService should not have
LocalTCC annotation");
+ }
+
+ // Test service classes
+ @LocalTCC
+ public static class TestTccService {
+ @TwoPhaseBusinessAction(name = "testAction")
+ public boolean prepare(String param) {
+ return true;
+ }
+
+ public boolean commit(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean rollback(BusinessActionContext context) {
+ return true;
+ }
+ }
+
+ public static class ChildTestTccService extends TestTccService {
+ // Inherits LocalTCC annotation
+ }
+
+ public static class RegularService {
+ // No annotation
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/rm/tcc/api/TwoPhaseBusinessActionTest.java
b/compatible/src/test/java/io/seata/rm/tcc/api/TwoPhaseBusinessActionTest.java
new file mode 100644
index 0000000000..79df3efb94
--- /dev/null
+++
b/compatible/src/test/java/io/seata/rm/tcc/api/TwoPhaseBusinessActionTest.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.rm.tcc.api;
+
+import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for TwoPhaseBusinessAction annotation.
+ */
+public class TwoPhaseBusinessActionTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
TwoPhaseBusinessAction.class.isAnnotationPresent(Deprecated.class),
+ "TwoPhaseBusinessAction should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testAnnotationRetention() {
+ Retention retention =
TwoPhaseBusinessAction.class.getAnnotation(Retention.class);
+ assertNotNull(retention);
+ assertEquals(RetentionPolicy.RUNTIME, retention.value());
+ }
+
+ @Test
+ public void testAnnotationTarget() {
+ Target target =
TwoPhaseBusinessAction.class.getAnnotation(Target.class);
+ assertNotNull(target);
+ assertEquals(1, target.value().length);
+ assertEquals(ElementType.METHOD, target.value()[0]);
+ }
+
+ @Test
+ public void testAnnotationInherited() {
+ assertTrue(
+
TwoPhaseBusinessAction.class.isAnnotationPresent(Inherited.class),
+ "TwoPhaseBusinessAction should be marked as @Inherited");
+ }
+
+ @Test
+ public void testDefaultValues() throws NoSuchMethodException {
+ Method commitMethodAttr =
TwoPhaseBusinessAction.class.getMethod("commitMethod");
+ assertEquals("commit", commitMethodAttr.getDefaultValue());
+
+ Method rollbackMethodAttr =
TwoPhaseBusinessAction.class.getMethod("rollbackMethod");
+ assertEquals("rollback", rollbackMethodAttr.getDefaultValue());
+
+ Method isDelayReportAttr =
TwoPhaseBusinessAction.class.getMethod("isDelayReport");
+ assertEquals(false, isDelayReportAttr.getDefaultValue());
+
+ Method useTCCFenceAttr =
TwoPhaseBusinessAction.class.getMethod("useTCCFence");
+ assertEquals(false, useTCCFenceAttr.getDefaultValue());
+
+ Method commitArgsClassesAttr =
TwoPhaseBusinessAction.class.getMethod("commitArgsClasses");
+ Class<?>[] defaultCommitArgs = (Class<?>[])
commitArgsClassesAttr.getDefaultValue();
+ assertEquals(1, defaultCommitArgs.length);
+ assertEquals(BusinessActionContext.class, defaultCommitArgs[0]);
+
+ Method rollbackArgsClassesAttr =
TwoPhaseBusinessAction.class.getMethod("rollbackArgsClasses");
+ Class<?>[] defaultRollbackArgs = (Class<?>[])
rollbackArgsClassesAttr.getDefaultValue();
+ assertEquals(1, defaultRollbackArgs.length);
+ assertEquals(BusinessActionContext.class, defaultRollbackArgs[0]);
+ }
+
+ @Test
+ public void testAnnotationWithMinimalConfig() throws Exception {
+ Method method = TestService.class.getMethod("prepareMinimal",
String.class);
+ TwoPhaseBusinessAction annotation =
method.getAnnotation(TwoPhaseBusinessAction.class);
+
+ assertNotNull(annotation);
+ assertEquals("minimalAction", annotation.name());
+ assertEquals("commit", annotation.commitMethod());
+ assertEquals("rollback", annotation.rollbackMethod());
+ assertFalse(annotation.isDelayReport());
+ assertFalse(annotation.useTCCFence());
+ }
+
+ @Test
+ public void testAnnotationWithFullConfig() throws Exception {
+ Method method = TestService.class.getMethod("prepareWithFullConfig",
String.class, int.class, Object.class);
+ TwoPhaseBusinessAction annotation =
method.getAnnotation(TwoPhaseBusinessAction.class);
+
+ assertNotNull(annotation);
+ assertEquals("fullConfigAction", annotation.name());
+ assertEquals("customCommit", annotation.commitMethod());
+ assertEquals("customRollback", annotation.rollbackMethod());
+ assertTrue(annotation.isDelayReport());
+ assertTrue(annotation.useTCCFence());
+ assertArrayEquals(new Class<?>[] {BusinessActionContext.class,
String.class}, annotation.commitArgsClasses());
+ assertArrayEquals(new Class<?>[] {BusinessActionContext.class,
String.class}, annotation.rollbackArgsClasses());
+ }
+
+ @Test
+ public void testAnnotationWithTCCFence() throws Exception {
+ Method method = TestService.class.getMethod("prepareWithFence",
String.class);
+ TwoPhaseBusinessAction annotation =
method.getAnnotation(TwoPhaseBusinessAction.class);
+
+ assertNotNull(annotation);
+ assertTrue(annotation.useTCCFence());
+ assertTrue(annotation.isDelayReport());
+ }
+
+ @Test
+ public void testAnnotationWithCustomMethods() throws Exception {
+ Method method =
TestService.class.getMethod("prepareWithCustomMethods", String.class);
+ TwoPhaseBusinessAction annotation =
method.getAnnotation(TwoPhaseBusinessAction.class);
+
+ assertNotNull(annotation);
+ assertEquals("customAction", annotation.name());
+ assertEquals("myCommit", annotation.commitMethod());
+ assertEquals("myRollback", annotation.rollbackMethod());
+ }
+
+ // Test service class
+ public static class TestService {
+
+ @TwoPhaseBusinessAction(name = "minimalAction")
+ public boolean prepareMinimal(String param) {
+ return true;
+ }
+
+ @TwoPhaseBusinessAction(
+ name = "fullConfigAction",
+ commitMethod = "customCommit",
+ rollbackMethod = "customRollback",
+ isDelayReport = true,
+ useTCCFence = true,
+ commitArgsClasses = {BusinessActionContext.class,
String.class},
+ rollbackArgsClasses = {BusinessActionContext.class,
String.class})
+ public boolean prepareWithFullConfig(String param1, int param2, Object
param3) {
+ return true;
+ }
+
+ @TwoPhaseBusinessAction(name = "fenceAction", useTCCFence = true,
isDelayReport = true)
+ public boolean prepareWithFence(String param) {
+ return true;
+ }
+
+ @TwoPhaseBusinessAction(name = "customAction", commitMethod =
"myCommit", rollbackMethod = "myRollback")
+ public boolean prepareWithCustomMethods(String param) {
+ return true;
+ }
+
+ public boolean commit(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean rollback(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean customCommit(BusinessActionContext context, String
extra) {
+ return true;
+ }
+
+ public boolean customRollback(BusinessActionContext context, String
extra) {
+ return true;
+ }
+
+ public boolean myCommit(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean myRollback(BusinessActionContext context) {
+ return true;
+ }
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandlerTest.java
b/compatible/src/test/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandlerTest.java
new file mode 100644
index 0000000000..db338aff7d
--- /dev/null
+++
b/compatible/src/test/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandlerTest.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.rm.tcc.interceptor;
+
+import io.seata.rm.tcc.api.BusinessActionContext;
+import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
+import org.apache.seata.common.Constants;
+import
org.apache.seata.integration.tx.api.interceptor.TwoPhaseBusinessActionParam;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for TccActionInterceptorHandler.
+ */
+public class TccActionInterceptorHandlerTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
TccActionInterceptorHandler.class.isAnnotationPresent(Deprecated.class),
+ "TccActionInterceptorHandler should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testExtendsApacheSeataTccHandler() {
+ assertTrue(
+
org.apache.seata.rm.tcc.interceptor.TccActionInterceptorHandler.class.isAssignableFrom(
+ TccActionInterceptorHandler.class),
+ "Should extend Apache Seata TccActionInterceptorHandler");
+ }
+
+ @Test
+ public void testConstructor() {
+ Object targetBean = new TestTccService();
+ Set<String> methodsToProxy = new HashSet<>();
+ methodsToProxy.add("prepare");
+
+ TccActionInterceptorHandler handler = new
TccActionInterceptorHandler(targetBean, methodsToProxy);
+
+ assertNotNull(handler);
+ }
+
+ @Test
+ public void testGetAnnotationClass() throws Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method method =
TccActionInterceptorHandler.class.getDeclaredMethod("getAnnotationClass");
+ method.setAccessible(true);
+
+ Class<?> annotationClass = (Class<?>) method.invoke(handler);
+
+ assertEquals(TwoPhaseBusinessAction.class, annotationClass);
+ }
+
+ @Test
+ public void testParserCommonFenceConfigEnabled() throws Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method testMethod = TestTccService.class.getMethod("prepareWithFence",
String.class, int.class);
+ TwoPhaseBusinessAction annotation =
testMethod.getAnnotation(TwoPhaseBusinessAction.class);
+
+ Method method = TccActionInterceptorHandler.class.getDeclaredMethod(
+ "parserCommonFenceConfig",
java.lang.annotation.Annotation.class);
+ method.setAccessible(true);
+
+ boolean result = (boolean) method.invoke(handler, annotation);
+
+ assertTrue(result, "Should return true for TCC fence enabled
annotation");
+ }
+
+ @Test
+ public void testParserCommonFenceConfigDisabled() throws Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method testMethod =
TestTccService.class.getMethod("prepareWithoutFence", String.class);
+ TwoPhaseBusinessAction annotation =
testMethod.getAnnotation(TwoPhaseBusinessAction.class);
+
+ Method method = TccActionInterceptorHandler.class.getDeclaredMethod(
+ "parserCommonFenceConfig",
java.lang.annotation.Annotation.class);
+ method.setAccessible(true);
+
+ boolean result = (boolean) method.invoke(handler, annotation);
+
+ assertFalse(result, "Should return false for TCC fence disabled
annotation");
+ }
+
+ @Test
+ public void testParserCommonFenceConfigWithNull() throws Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method method = TccActionInterceptorHandler.class.getDeclaredMethod(
+ "parserCommonFenceConfig",
java.lang.annotation.Annotation.class);
+ method.setAccessible(true);
+
+ boolean result = (boolean) method.invoke(handler, new Object[] {null});
+
+ assertFalse(result, "Should return false for null annotation");
+ }
+
+ @Test
+ public void testCreateTwoPhaseBusinessActionParam() throws Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method testMethod = TestTccService.class.getMethod("prepareWithFence",
String.class, int.class);
+ TwoPhaseBusinessAction annotation =
testMethod.getAnnotation(TwoPhaseBusinessAction.class);
+
+ Method method = TccActionInterceptorHandler.class.getDeclaredMethod(
+ "createTwoPhaseBusinessActionParam",
java.lang.annotation.Annotation.class);
+ method.setAccessible(true);
+
+ TwoPhaseBusinessActionParam param = (TwoPhaseBusinessActionParam)
method.invoke(handler, annotation);
+
+ assertNotNull(param);
+ assertEquals("testAction", param.getActionName());
+ assertTrue(param.getDelayReport());
+ assertTrue(param.getUseCommonFence());
+ assertEquals(org.apache.seata.core.model.BranchType.TCC,
param.getBranchType());
+
+ Map<String, Object> context = param.getBusinessActionContext();
+ assertNotNull(context);
+ assertEquals("commitWithFence", context.get(Constants.COMMIT_METHOD));
+ assertEquals("rollbackWithFence",
context.get(Constants.ROLLBACK_METHOD));
+ assertEquals("testAction", context.get(Constants.ACTION_NAME));
+ assertEquals(true, context.get(Constants.USE_COMMON_FENCE));
+ }
+
+ @Test
+ public void testCreateTwoPhaseBusinessActionParamWithoutFence() throws
Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method testMethod =
TestTccService.class.getMethod("prepareWithoutFence", String.class);
+ TwoPhaseBusinessAction annotation =
testMethod.getAnnotation(TwoPhaseBusinessAction.class);
+
+ Method method = TccActionInterceptorHandler.class.getDeclaredMethod(
+ "createTwoPhaseBusinessActionParam",
java.lang.annotation.Annotation.class);
+ method.setAccessible(true);
+
+ TwoPhaseBusinessActionParam param = (TwoPhaseBusinessActionParam)
method.invoke(handler, annotation);
+
+ assertNotNull(param);
+ assertEquals("simpleAction", param.getActionName());
+ assertFalse(param.getDelayReport());
+ assertFalse(param.getUseCommonFence());
+
+ Map<String, Object> context = param.getBusinessActionContext();
+ assertNotNull(context);
+ assertEquals("commit", context.get(Constants.COMMIT_METHOD));
+ assertEquals("rollback", context.get(Constants.ROLLBACK_METHOD));
+ assertEquals("simpleAction", context.get(Constants.ACTION_NAME));
+ assertEquals(false, context.get(Constants.USE_COMMON_FENCE));
+ }
+
+ @Test
+ public void testCreateTwoPhaseBusinessActionParamWithCustomMethods()
throws Exception {
+ TccActionInterceptorHandler handler = createHandler();
+
+ Method testMethod =
TestTccService.class.getMethod("prepareWithCustomMethods", String.class);
+ TwoPhaseBusinessAction annotation =
testMethod.getAnnotation(TwoPhaseBusinessAction.class);
+
+ Method method = TccActionInterceptorHandler.class.getDeclaredMethod(
+ "createTwoPhaseBusinessActionParam",
java.lang.annotation.Annotation.class);
+ method.setAccessible(true);
+
+ TwoPhaseBusinessActionParam param = (TwoPhaseBusinessActionParam)
method.invoke(handler, annotation);
+
+ assertNotNull(param);
+ assertEquals("customAction", param.getActionName());
+
+ Map<String, Object> context = param.getBusinessActionContext();
+ assertEquals("customCommit", context.get(Constants.COMMIT_METHOD));
+ assertEquals("customRollback", context.get(Constants.ROLLBACK_METHOD));
+ }
+
+ private TccActionInterceptorHandler createHandler() {
+ Object targetBean = new TestTccService();
+ Set<String> methodsToProxy = new HashSet<>();
+ methodsToProxy.add("prepareWithFence");
+ methodsToProxy.add("prepareWithoutFence");
+ methodsToProxy.add("prepareWithCustomMethods");
+ return new TccActionInterceptorHandler(targetBean, methodsToProxy);
+ }
+
+ // Test service class with TCC annotations
+ public static class TestTccService {
+
+ @TwoPhaseBusinessAction(
+ name = "testAction",
+ commitMethod = "commitWithFence",
+ rollbackMethod = "rollbackWithFence",
+ isDelayReport = true,
+ useTCCFence = true)
+ public boolean prepareWithFence(String param1, int param2) {
+ return true;
+ }
+
+ public boolean commitWithFence(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean rollbackWithFence(BusinessActionContext context) {
+ return true;
+ }
+
+ @TwoPhaseBusinessAction(name = "simpleAction")
+ public boolean prepareWithoutFence(String param) {
+ return true;
+ }
+
+ public boolean commit(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean rollback(BusinessActionContext context) {
+ return true;
+ }
+
+ @TwoPhaseBusinessAction(name = "customAction", commitMethod =
"customCommit", rollbackMethod = "customRollback")
+ public boolean prepareWithCustomMethods(String param) {
+ return true;
+ }
+
+ public boolean customCommit(BusinessActionContext context) {
+ return true;
+ }
+
+ public boolean customRollback(BusinessActionContext context) {
+ return true;
+ }
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/tm/api/DefaultGlobalTransactionTest.java
b/compatible/src/test/java/io/seata/tm/api/DefaultGlobalTransactionTest.java
new file mode 100644
index 0000000000..195a937717
--- /dev/null
+++ b/compatible/src/test/java/io/seata/tm/api/DefaultGlobalTransactionTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.tm.api;
+
+import io.seata.core.model.GlobalStatus;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for DefaultGlobalTransaction implementation.
+ */
+public class DefaultGlobalTransactionTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
DefaultGlobalTransaction.class.isAnnotationPresent(Deprecated.class),
+ "DefaultGlobalTransaction should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testImplementsGlobalTransaction() {
+ assertTrue(
+
GlobalTransaction.class.isAssignableFrom(DefaultGlobalTransaction.class),
+ "DefaultGlobalTransaction should implement GlobalTransaction");
+ }
+
+ @Test
+ public void testDefaultConstructor() {
+ DefaultGlobalTransaction transaction = new DefaultGlobalTransaction();
+ assertNotNull(transaction);
+ assertNotNull(transaction.getInstance());
+ }
+
+ @Test
+ public void testConstructorWithParameters() {
+ String xid = "test-xid-123";
+ GlobalStatus status = GlobalStatus.Begin;
+ GlobalTransactionRole role = GlobalTransactionRole.Launcher;
+
+ DefaultGlobalTransaction transaction = new
DefaultGlobalTransaction(xid, status, role);
+
+ assertNotNull(transaction);
+ assertEquals(xid, transaction.getXid());
+ }
+
+ @Test
+ public void testGetXid() {
+ String expectedXid = "192.168.1.1:8091:123456";
+ DefaultGlobalTransaction transaction =
+ new DefaultGlobalTransaction(expectedXid, GlobalStatus.Begin,
GlobalTransactionRole.Launcher);
+
+ assertEquals(expectedXid, transaction.getXid());
+ }
+
+ @Test
+ public void testGetLocalStatus() {
+ DefaultGlobalTransaction transaction =
+ new DefaultGlobalTransaction("xid", GlobalStatus.Begin,
GlobalTransactionRole.Launcher);
+
+ GlobalStatus localStatus = transaction.getLocalStatus();
+ assertNotNull(localStatus);
+ }
+
+ @Test
+ public void testGetGlobalTransactionRole() {
+ DefaultGlobalTransaction launcherTx =
+ new DefaultGlobalTransaction("xid1", GlobalStatus.Begin,
GlobalTransactionRole.Launcher);
+ assertEquals(GlobalTransactionRole.Launcher,
launcherTx.getGlobalTransactionRole());
+
+ DefaultGlobalTransaction participantTx =
+ new DefaultGlobalTransaction("xid2", GlobalStatus.Begin,
GlobalTransactionRole.Participant);
+ assertEquals(GlobalTransactionRole.Participant,
participantTx.getGlobalTransactionRole());
+ }
+
+ @Test
+ public void testGetInstance() {
+ DefaultGlobalTransaction transaction = new DefaultGlobalTransaction();
+ assertNotNull(transaction.getInstance());
+ assertTrue(transaction.getInstance() instanceof
org.apache.seata.tm.api.DefaultGlobalTransaction);
+ }
+
+ @Test
+ public void testGlobalTransactionRoleConversion() {
+ // Test Launcher role
+ DefaultGlobalTransaction launcherTx =
+ new DefaultGlobalTransaction("xid1", GlobalStatus.Begin,
GlobalTransactionRole.Launcher);
+ assertEquals(GlobalTransactionRole.Launcher,
launcherTx.getGlobalTransactionRole());
+
+ // Test Participant role
+ DefaultGlobalTransaction participantTx =
+ new DefaultGlobalTransaction("xid2", GlobalStatus.Begin,
GlobalTransactionRole.Participant);
+ assertEquals(GlobalTransactionRole.Participant,
participantTx.getGlobalTransactionRole());
+ }
+
+ @Test
+ public void testConstructorWithDifferentStatuses() {
+ // Test with different GlobalStatus values
+ DefaultGlobalTransaction beginTx =
+ new DefaultGlobalTransaction("xid1", GlobalStatus.Begin,
GlobalTransactionRole.Launcher);
+ assertNotNull(beginTx);
+
+ DefaultGlobalTransaction committedTx =
+ new DefaultGlobalTransaction("xid2", GlobalStatus.Committed,
GlobalTransactionRole.Launcher);
+ assertNotNull(committedTx);
+
+ DefaultGlobalTransaction rollbackedTx =
+ new DefaultGlobalTransaction("xid3", GlobalStatus.Rollbacked,
GlobalTransactionRole.Launcher);
+ assertNotNull(rollbackedTx);
+ }
+}
diff --git
a/compatible/src/test/java/io/seata/tm/api/GlobalTransactionContextTest.java
b/compatible/src/test/java/io/seata/tm/api/GlobalTransactionContextTest.java
new file mode 100644
index 0000000000..172aba6774
--- /dev/null
+++ b/compatible/src/test/java/io/seata/tm/api/GlobalTransactionContextTest.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.tm.api;
+
+import io.seata.core.context.RootContext;
+import io.seata.core.exception.TransactionException;
+import io.seata.core.model.GlobalStatus;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for GlobalTransactionContext.
+ */
+public class GlobalTransactionContextTest {
+
+ @AfterEach
+ public void cleanup() {
+ RootContext.unbind();
+ }
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ assertTrue(
+
GlobalTransactionContext.class.isAnnotationPresent(Deprecated.class),
+ "GlobalTransactionContext should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testCreateNew() {
+ GlobalTransaction transaction = GlobalTransactionContext.createNew();
+
+ assertNotNull(transaction, "createNew should return a non-null
transaction");
+ assertTrue(
+ transaction instanceof DefaultGlobalTransaction,
+ "createNew should return a DefaultGlobalTransaction instance");
+ }
+
+ @Test
+ public void testGetCurrentWithNoContext() {
+ RootContext.unbind();
+
+ GlobalTransaction transaction = GlobalTransactionContext.getCurrent();
+
+ assertNull(transaction, "getCurrent should return null when no XID is
bound");
+ }
+
+ @Test
+ public void testGetCurrentWithContext() {
+ String testXid = "192.168.1.1:8091:123456";
+ RootContext.bind(testXid);
+
+ GlobalTransaction transaction = GlobalTransactionContext.getCurrent();
+
+ assertNotNull(transaction, "getCurrent should return a transaction
when XID is bound");
+ assertEquals(testXid, transaction.getXid(), "Transaction XID should
match the bound XID");
+ assertEquals(GlobalStatus.Begin, transaction.getLocalStatus(),
"Transaction status should be Begin");
+ assertEquals(
+ GlobalTransactionRole.Participant,
+ transaction.getGlobalTransactionRole(),
+ "Transaction role should be Participant");
+ }
+
+ @Test
+ public void testGetCurrentOrCreateWithNoContext() {
+ RootContext.unbind();
+
+ GlobalTransaction transaction =
GlobalTransactionContext.getCurrentOrCreate();
+
+ assertNotNull(transaction, "getCurrentOrCreate should return a
non-null transaction");
+ assertTrue(
+ transaction instanceof DefaultGlobalTransaction,
+ "getCurrentOrCreate should return a DefaultGlobalTransaction
instance");
+ }
+
+ @Test
+ public void testGetCurrentOrCreateWithContext() {
+ String testXid = "192.168.1.1:8091:654321";
+ RootContext.bind(testXid);
+
+ GlobalTransaction transaction =
GlobalTransactionContext.getCurrentOrCreate();
+
+ assertNotNull(transaction, "getCurrentOrCreate should return a
non-null transaction");
+ assertEquals(testXid, transaction.getXid(), "Transaction XID should
match the bound XID");
+ }
+
+ @Test
+ public void testReload() throws TransactionException {
+ String testXid = "192.168.1.1:8091:999999";
+
+ GlobalTransaction transaction =
GlobalTransactionContext.reload(testXid);
+
+ assertNotNull(transaction, "reload should return a non-null
transaction");
+ assertEquals(testXid, transaction.getXid(), "Transaction XID should
match the provided XID");
+ assertEquals(
+ GlobalStatus.UnKnown, transaction.getLocalStatus(), "Reloaded
transaction status should be UnKnown");
+ assertEquals(
+ GlobalTransactionRole.Launcher,
+ transaction.getGlobalTransactionRole(),
+ "Reloaded transaction role should be Launcher");
+ }
+
+ @Test
+ public void testReloadedTransactionCannotBegin() throws
TransactionException {
+ String testXid = "192.168.1.1:8091:888888";
+
+ GlobalTransaction transaction =
GlobalTransactionContext.reload(testXid);
+
+ assertThrows(
+ IllegalStateException.class,
+ () -> transaction.begin(30000, "test"),
+ "Reloaded transaction should not allow begin operation");
+ }
+
+ @Test
+ public void testMultipleCreateNew() {
+ GlobalTransaction tx1 = GlobalTransactionContext.createNew();
+ GlobalTransaction tx2 = GlobalTransactionContext.createNew();
+
+ assertNotNull(tx1);
+ assertNotNull(tx2);
+ }
+
+ @Test
+ public void testGetCurrentAfterUnbind() {
+ String testXid = "192.168.1.1:8091:111111";
+ RootContext.bind(testXid);
+
+ GlobalTransaction tx1 = GlobalTransactionContext.getCurrent();
+ assertNotNull(tx1);
+
+ RootContext.unbind();
+
+ GlobalTransaction tx2 = GlobalTransactionContext.getCurrent();
+ assertNull(tx2, "getCurrent should return null after unbind");
+ }
+
+ @Test
+ public void testGetCurrentOrCreateMultipleTimes() {
+ RootContext.unbind();
+
+ GlobalTransaction tx1 = GlobalTransactionContext.getCurrentOrCreate();
+ assertNotNull(tx1);
+
+ // Bind an XID
+ String testXid = "192.168.1.1:8091:222222";
+ RootContext.bind(testXid);
+
+ GlobalTransaction tx2 = GlobalTransactionContext.getCurrentOrCreate();
+ assertNotNull(tx2);
+ assertEquals(testXid, tx2.getXid());
+
+ // Unbind and call again
+ RootContext.unbind();
+
+ GlobalTransaction tx3 = GlobalTransactionContext.getCurrentOrCreate();
+ assertNotNull(tx3);
+ }
+
+ @Test
+ public void testReloadWithDifferentXids() throws TransactionException {
+ String xid1 = "192.168.1.1:8091:100001";
+ String xid2 = "192.168.1.1:8091:100002";
+
+ GlobalTransaction tx1 = GlobalTransactionContext.reload(xid1);
+ GlobalTransaction tx2 = GlobalTransactionContext.reload(xid2);
+
+ assertNotNull(tx1);
+ assertNotNull(tx2);
+ assertEquals(xid1, tx1.getXid());
+ assertEquals(xid2, tx2.getXid());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]