This is an automated email from the ASF dual-hosted git repository.
jianbin 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 b93d30b404 test: Add comprehensive unit tests for compatible module
with Apache license headers - Fixes #7383 (#7438)
b93d30b404 is described below
commit b93d30b40480d65bcf57922d47caa9d9483562e0
Author: Eric Wang <[email protected]>
AuthorDate: Sun Jun 15 13:48:22 2025 +0800
test: Add comprehensive unit tests for compatible module with Apache
license headers - Fixes #7383 (#7438)
---
.../java/io/seata/common/util/StringUtilsTest.java | 160 +++++++++++
.../io/seata/core/compressor/CompressorTest.java | 135 +++++++++
.../seata/core/constants/DubboConstantsTest.java | 109 ++++++++
.../io/seata/core/context/ContextCoreTest.java | 81 ++++++
.../io/seata/core/context/RootContextTest.java | 244 +++++++++++++++++
.../exception/TransactionExceptionCodeTest.java | 201 ++++++++++++++
.../java/io/seata/core/model/BranchTypeTest.java | 138 ++++++++++
.../java/io/seata/core/model/GlobalStatusTest.java | 233 ++++++++++++++++
.../io/seata/core/model/ResourceManagerTest.java | 283 +++++++++++++++++++
.../io/seata/core/serializer/SerializerTest.java | 179 ++++++++++++
.../src/test/java/io/seata/rm/RMClientTest.java | 106 +++++++
.../src/test/java/io/seata/tm/TMClientTest.java | 96 +++++++
.../io/seata/tm/api/GlobalTransactionRoleTest.java | 175 ++++++++++++
.../io/seata/tm/api/GlobalTransactionTest.java | 305 +++++++++++++++++++++
14 files changed, 2445 insertions(+)
diff --git a/compatible/src/test/java/io/seata/common/util/StringUtilsTest.java
b/compatible/src/test/java/io/seata/common/util/StringUtilsTest.java
new file mode 100644
index 0000000000..d031e34276
--- /dev/null
+++ b/compatible/src/test/java/io/seata/common/util/StringUtilsTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.util;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Unit test for StringUtils class
+ */
+public class StringUtilsTest {
+
+ @Test
+ public void testIsEmpty() {
+ // Test null string
+ Assertions.assertTrue(StringUtils.isEmpty(null));
+
+ // Test empty string
+ Assertions.assertTrue(StringUtils.isEmpty(""));
+
+ // Test non-empty string
+ Assertions.assertFalse(StringUtils.isEmpty("hello"));
+
+ // Test string with spaces
+ Assertions.assertFalse(StringUtils.isEmpty(" "));
+ }
+
+ @Test
+ public void testIsNotEmpty() {
+ // Test null string
+ Assertions.assertFalse(StringUtils.isNotEmpty(null));
+
+ // Test empty string
+ Assertions.assertFalse(StringUtils.isNotEmpty(""));
+
+ // Test non-empty string
+ Assertions.assertTrue(StringUtils.isNotEmpty("hello"));
+
+ // Test string with spaces
+ Assertions.assertTrue(StringUtils.isNotEmpty(" "));
+ }
+
+ @Test
+ public void testIsBlank() {
+ // Test null string
+ Assertions.assertTrue(StringUtils.isBlank(null));
+
+ // Test empty string
+ Assertions.assertTrue(StringUtils.isBlank(""));
+
+ // Test string with only spaces
+ Assertions.assertTrue(StringUtils.isBlank(" "));
+
+ // Test string with tabs and newlines
+ Assertions.assertTrue(StringUtils.isBlank("\t\n\r "));
+
+ // Test non-blank string
+ Assertions.assertFalse(StringUtils.isBlank("hello"));
+
+ // Test string with content and spaces
+ Assertions.assertFalse(StringUtils.isBlank(" hello "));
+ }
+
+ @Test
+ public void testIsNotBlank() {
+ // Test null string
+ Assertions.assertFalse(StringUtils.isNotBlank(null));
+
+ // Test empty string
+ Assertions.assertFalse(StringUtils.isNotBlank(""));
+
+ // Test string with only spaces
+ Assertions.assertFalse(StringUtils.isNotBlank(" "));
+
+ // Test non-blank string
+ Assertions.assertTrue(StringUtils.isNotBlank("hello"));
+
+ // Test string with content and spaces
+ Assertions.assertTrue(StringUtils.isNotBlank(" hello "));
+ }
+
+ @Test
+ public void testTrim() {
+ // Test null string
+ Assertions.assertNull(StringUtils.trim(null));
+
+ // Test empty string
+ Assertions.assertEquals("", StringUtils.trim(""));
+
+ // Test string with leading/trailing spaces
+ Assertions.assertEquals("hello", StringUtils.trim(" hello "));
+
+ // Test string without spaces
+ Assertions.assertEquals("hello", StringUtils.trim("hello"));
+
+ // Test string with only spaces
+ Assertions.assertEquals("", StringUtils.trim(" "));
+ }
+
+ @Test
+ public void testJoin() {
+ // Test join with iterator
+ List<String> list = Arrays.asList("a", "b", "c");
+ Iterator<String> iterator = list.iterator();
+ Assertions.assertEquals("a,b,c", StringUtils.join(iterator, ","));
+ }
+
+ @Test
+ public void testInputStreamToString() {
+ // Test with normal input stream
+ String testString = "Hello World";
+ InputStream inputStream = new
ByteArrayInputStream(testString.getBytes());
+ String result = StringUtils.inputStream2String(inputStream);
+ Assertions.assertEquals(testString, result);
+
+ // Test with empty input stream
+ InputStream emptyStream = new ByteArrayInputStream(new byte[0]);
+ String emptyResult = StringUtils.inputStream2String(emptyStream);
+ Assertions.assertEquals("", emptyResult);
+ }
+
+ @Test
+ public void testCompatibilityWithApacheSeata() {
+ // Test that the compatible StringUtils delegates to Apache Seata's
StringUtils
+ String testStr = " test ";
+
+ // Compare results with Apache Seata's StringUtils
+ boolean isEmpty =
org.apache.seata.common.util.StringUtils.isEmpty(testStr);
+ boolean isEmptyCompat = StringUtils.isEmpty(testStr);
+ Assertions.assertEquals(isEmpty, isEmptyCompat);
+
+ boolean isBlank =
org.apache.seata.common.util.StringUtils.isBlank(testStr);
+ boolean isBlankCompat = StringUtils.isBlank(testStr);
+ Assertions.assertEquals(isBlank, isBlankCompat);
+
+ String trimmed =
org.apache.seata.common.util.StringUtils.trim(testStr);
+ String trimmedCompat = StringUtils.trim(testStr);
+ Assertions.assertEquals(trimmed, trimmedCompat);
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/compressor/CompressorTest.java
b/compatible/src/test/java/io/seata/core/compressor/CompressorTest.java
new file mode 100644
index 0000000000..eb92416e4d
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/compressor/CompressorTest.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.core.compressor;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Unit test for Compressor interface
+ */
+public class CompressorTest {
+
+ /**
+ * Mock implementation for testing
+ */
+ private static class MockCompressor implements Compressor {
+ @Override
+ public byte[] compress(byte[] bytes) {
+ return bytes; // Simple mock implementation
+ }
+
+ @Override
+ public byte[] decompress(byte[] bytes) {
+ return bytes; // Simple mock implementation
+ }
+ }
+
+ @Test
+ public void testCompressorInterfaceInheritance() {
+ // Test that Compressor extends from Apache Seata's Compressor
+ Assertions.assertTrue(org.apache.seata.core.compressor.Compressor.class
+ .isAssignableFrom(Compressor.class));
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the Compressor interface is marked as deprecated
+
Assertions.assertTrue(Compressor.class.isAnnotationPresent(Deprecated.class),
+ "Compressor should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInterfaceStructure() {
+ // Test interface modifiers
+ int modifiers = Compressor.class.getModifiers();
+
Assertions.assertTrue(java.lang.reflect.Modifier.isInterface(modifiers),
+ "Compressor should be an interface");
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "Compressor should be public");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.core.compressor",
+ Compressor.class.getPackage().getName(),
+ "Compressor should be in io.seata.core.compressor package");
+ }
+
+ @Test
+ public void testMethodInheritance() throws Exception {
+ // Test that the interface has the expected methods from the parent
interface
+ MockCompressor mockCompressor = new MockCompressor();
+
+ // Test that the mock compressor implements both interfaces
+ Assertions.assertTrue(mockCompressor instanceof Compressor);
+ Assertions.assertTrue(mockCompressor instanceof
org.apache.seata.core.compressor.Compressor);
+ }
+
+ @Test
+ public void testInterfaceCompatibility() {
+ // Test that compatible Compressor can be used wherever Apache Seata
Compressor is expected
+ MockCompressor compatibleCompressor = new MockCompressor();
+ org.apache.seata.core.compressor.Compressor apacheCompressor =
compatibleCompressor;
+
+ Assertions.assertNotNull(apacheCompressor);
+ Assertions.assertSame(compatibleCompressor, apacheCompressor);
+ }
+
+ @Test
+ public void testImplementationFunctionality() {
+ // Test basic functionality of a mock implementation
+ MockCompressor compressor = new MockCompressor();
+
+ byte[] testData = "Hello World".getBytes();
+
+ // Test compress method
+ byte[] compressed = compressor.compress(testData);
+ Assertions.assertNotNull(compressed);
+
+ // Test decompress method
+ byte[] decompressed = compressor.decompress(compressed);
+ Assertions.assertNotNull(decompressed);
+
+ // In our mock implementation, data should be unchanged
+ Assertions.assertArrayEquals(testData, decompressed);
+ }
+
+ @Test
+ public void testInterfaceMethods() throws Exception {
+ // Test that the interface has the expected method signatures
+ java.lang.reflect.Method compressMethod =
Compressor.class.getMethod("compress", byte[].class);
+ Assertions.assertNotNull(compressMethod);
+ Assertions.assertEquals(byte[].class, compressMethod.getReturnType());
+
+ java.lang.reflect.Method decompressMethod =
Compressor.class.getMethod("decompress", byte[].class);
+ Assertions.assertNotNull(decompressMethod);
+ Assertions.assertEquals(byte[].class,
decompressMethod.getReturnType());
+ }
+
+ @Test
+ public void testPolymorphism() {
+ // Test polymorphic behavior
+ MockCompressor mockCompressor = new MockCompressor();
+ Compressor compressor = mockCompressor;
+ Object obj = compressor;
+
+ Assertions.assertTrue(obj instanceof
org.apache.seata.core.compressor.Compressor);
+ Assertions.assertTrue(obj instanceof Compressor);
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/constants/DubboConstantsTest.java
b/compatible/src/test/java/io/seata/core/constants/DubboConstantsTest.java
new file mode 100644
index 0000000000..ddf7d95b76
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/constants/DubboConstantsTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.constants;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+import java.lang.reflect.Field;
+
+/**
+ * Unit test for DubboConstants class
+ */
+public class DubboConstantsTest {
+
+ @Test
+ public void testDubboConstantsInheritance() {
+ // Test that DubboConstants extends from Apache Seata's DubboConstants
+
Assertions.assertTrue(org.apache.seata.core.constants.DubboConstants.class
+ .isAssignableFrom(DubboConstants.class));
+ }
+
+ @Test
+ public void testConstantsCompatibility() throws Exception {
+ // Test that all constants in Apache Seata's DubboConstants are
accessible in compatible version
+ Field[] apacheFields =
org.apache.seata.core.constants.DubboConstants.class.getDeclaredFields();
+
+ for (Field apacheField : apacheFields) {
+ if
(java.lang.reflect.Modifier.isStatic(apacheField.getModifiers()) &&
+
java.lang.reflect.Modifier.isPublic(apacheField.getModifiers()) &&
+
java.lang.reflect.Modifier.isFinal(apacheField.getModifiers())) {
+
+ try {
+ // Try to access the field through the compatible class
+ Field compatField =
DubboConstants.class.getField(apacheField.getName());
+
+ // Compare values
+ Object apacheValue = apacheField.get(null);
+ Object compatValue = compatField.get(null);
+
+ Assertions.assertEquals(apacheValue, compatValue,
+ "Constant " + apacheField.getName() + " should have
the same value in both classes");
+ } catch (NoSuchFieldException e) {
+ // This is acceptable for inherited constants
+ // The constant should still be accessible through
inheritance
+ try {
+ Field inheritedField =
DubboConstants.class.getDeclaredField(apacheField.getName());
+ // If we get here, the field exists but might not be
public in the child class
+ } catch (NoSuchFieldException e2) {
+ // The constant should be accessible through
inheritance
+ Object value = apacheField.get(null);
+ // Just verify we can access it without error -
inheritance should handle this
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the DubboConstants class is marked as deprecated
+
Assertions.assertTrue(DubboConstants.class.isAnnotationPresent(Deprecated.class),
+ "DubboConstants should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInstanceCreation() {
+ // Test that we can create an instance of DubboConstants
+ DubboConstants constants = new DubboConstants();
+ Assertions.assertNotNull(constants);
+
+ // Test that it's an instance of Apache Seata's DubboConstants
+ Assertions.assertTrue(constants instanceof
org.apache.seata.core.constants.DubboConstants);
+ }
+
+ @Test
+ public void testClassStructure() {
+ // Test class modifiers
+ int modifiers = DubboConstants.class.getModifiers();
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "DubboConstants should be public");
+
+ // Test superclass
+
Assertions.assertEquals(org.apache.seata.core.constants.DubboConstants.class,
+ DubboConstants.class.getSuperclass(),
+ "DubboConstants should extend Apache Seata's DubboConstants");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.core.constants",
+ DubboConstants.class.getPackage().getName(),
+ "DubboConstants should be in io.seata.core.constants package");
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/context/ContextCoreTest.java
b/compatible/src/test/java/io/seata/core/context/ContextCoreTest.java
new file mode 100644
index 0000000000..21fab14ced
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/context/ContextCoreTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.context;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Unit test for ContextCore interface
+ */
+public class ContextCoreTest {
+
+ @Test
+ public void testContextCoreInterfaceInheritance() {
+ // Test that ContextCore extends from Apache Seata's ContextCore
+ Assertions.assertTrue(org.apache.seata.core.context.ContextCore.class
+ .isAssignableFrom(ContextCore.class));
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the ContextCore interface is marked as deprecated
+
Assertions.assertTrue(ContextCore.class.isAnnotationPresent(Deprecated.class),
+ "ContextCore should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInterfaceStructure() {
+ // Test interface modifiers
+ int modifiers = ContextCore.class.getModifiers();
+
Assertions.assertTrue(java.lang.reflect.Modifier.isInterface(modifiers),
+ "ContextCore should be an interface");
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "ContextCore should be public");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.core.context",
+ ContextCore.class.getPackage().getName(),
+ "ContextCore should be in io.seata.core.context package");
+ }
+
+ @Test
+ public void testMethodInheritance() throws Exception {
+ // Test that the interface extends from the parent interface
+
Assertions.assertTrue(org.apache.seata.core.context.ContextCore.class.isAssignableFrom(ContextCore.class));
+ }
+
+ @Test
+ public void testInterfaceCompatibility() {
+ // Test that compatible ContextCore is assignable from Apache Seata
ContextCore
+
Assertions.assertTrue(org.apache.seata.core.context.ContextCore.class.isAssignableFrom(ContextCore.class));
+ }
+
+ @Test
+ public void testInterfaceMethods() throws Exception {
+ // Test that the interface has inherited the expected methods from
parent interface
+ java.lang.reflect.Method[] parentMethods =
org.apache.seata.core.context.ContextCore.class.getMethods();
+ java.lang.reflect.Method[] childMethods =
ContextCore.class.getMethods();
+
+ // The child interface should have access to parent methods through
inheritance
+ Assertions.assertTrue(parentMethods.length > 0, "Parent interface
should have methods");
+ Assertions.assertTrue(childMethods.length >= parentMethods.length,
"Child interface should inherit parent methods");
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/context/RootContextTest.java
b/compatible/src/test/java/io/seata/core/context/RootContextTest.java
new file mode 100644
index 0000000000..57cea2cf68
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/context/RootContextTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.context;
+
+import io.seata.core.model.BranchType;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+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.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for RootContext compatibility.
+ */
+public class RootContextTest {
+
+ @BeforeEach
+ public void setUp() {
+ // Clean up context before each test
+ RootContext.unbind();
+ RootContext.unbindBranchType();
+ RootContext.unbindGlobalLockFlag();
+ }
+
+ @AfterEach
+ public void tearDown() {
+ // Clean up context after each test
+ RootContext.unbind();
+ RootContext.unbindBranchType();
+ RootContext.unbindGlobalLockFlag();
+ }
+
+ @Test
+ public void testConstants() {
+ // Test KEY_XID constant
+ assertEquals("TX_XID", RootContext.KEY_XID,
+ "KEY_XID constant should match expected value");
+
+ // Test KEY_BRANCH_TYPE constant
+ assertEquals("TX_BRANCH_TYPE", RootContext.KEY_BRANCH_TYPE,
+ "KEY_BRANCH_TYPE constant should match expected value");
+ }
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ // Test that RootContext is marked as @Deprecated
+ assertTrue(RootContext.class.isAnnotationPresent(Deprecated.class),
+ "RootContext should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testXidBindingAndUnbinding() {
+ // Test initial state
+ assertNull(RootContext.getXID(), "Initial XID should be null");
+
+ // Test binding XID
+ String testXid = "test-xid-123";
+ RootContext.bind(testXid);
+ assertEquals(testXid, RootContext.getXID(),
+ "XID should be bound correctly");
+
+ // Test unbinding XID
+ String unboundXid = RootContext.unbind();
+ assertEquals(testXid, unboundXid,
+ "Unbind should return the previously bound XID");
+ assertNull(RootContext.getXID(),
+ "XID should be null after unbinding");
+ }
+
+ @Test
+ public void testBranchTypeOperations() {
+ // Test initial state
+ assertNull(RootContext.getBranchType(), "Initial branch type should be
null");
+
+ // Bind XID first (required for branch type operations in some
contexts)
+ RootContext.bind("test-xid-for-branch");
+
+ // Test binding branch type
+ BranchType testBranchType = BranchType.AT;
+ RootContext.bindBranchType(testBranchType);
+ assertEquals(testBranchType, RootContext.getBranchType(),
+ "Branch type should be bound correctly");
+
+ // Test unbinding branch type
+ BranchType unboundBranchType = RootContext.unbindBranchType();
+ assertEquals(testBranchType, unboundBranchType,
+ "Unbind should return the previously bound branch type");
+
+ // Note: In test environment, branch type might persist until context
is fully cleaned
+ // So we test that unbinding works by binding a different type
+ RootContext.bindBranchType(BranchType.XA);
+ assertEquals(BranchType.XA, RootContext.getBranchType(),
+ "Should be able to bind different branch type");
+ }
+
+ @Test
+ public void testDefaultBranchType() {
+ // Test setting default branch type (only AT and XA are allowed)
+ BranchType defaultBranchType = BranchType.AT;
+ assertDoesNotThrow(() ->
RootContext.setDefaultBranchType(defaultBranchType),
+ "Setting default branch type to AT should not throw
exception");
+
+ // Test that TCC is not allowed as default branch type
+ assertThrows(IllegalArgumentException.class,
+ () -> RootContext.setDefaultBranchType(BranchType.TCC),
+ "Setting default branch type to TCC should throw
IllegalArgumentException");
+ }
+
+ @Test
+ public void testTimeoutOperations() {
+ // Test initial timeout
+ Integer initialTimeout = RootContext.getTimeout();
+ // Initial timeout might be null or some default value
+
+ // Test setting timeout
+ Integer testTimeout = 30000; // 30 seconds
+ RootContext.setTimeout(testTimeout);
+ assertEquals(testTimeout, RootContext.getTimeout(),
+ "Timeout should be set correctly");
+
+ // Test setting null timeout
+ RootContext.setTimeout(null);
+ assertNull(RootContext.getTimeout(),
+ "Timeout should be null when set to null");
+ }
+
+ @Test
+ public void testGlobalLockFlag() {
+ // Test initial state
+ assertFalse(RootContext.requireGlobalLock(),
+ "Initial global lock flag should be false");
+
+ // Test binding global lock flag
+ RootContext.bindGlobalLockFlag();
+ assertTrue(RootContext.requireGlobalLock(),
+ "Global lock flag should be true after binding");
+
+ // Test unbinding global lock flag
+ RootContext.unbindGlobalLockFlag();
+ assertFalse(RootContext.requireGlobalLock(),
+ "Global lock flag should be false after unbinding");
+ }
+
+ @Test
+ public void testTransactionStateChecks() {
+ // Test initial state - not in any transaction
+ assertFalse(RootContext.inGlobalTransaction(),
+ "Should not be in global transaction initially");
+ assertFalse(RootContext.inTccBranch(),
+ "Should not be in TCC branch initially");
+ assertFalse(RootContext.inSagaBranch(),
+ "Should not be in Saga branch initially");
+
+ // Test with XID bound (simulating global transaction)
+ RootContext.bind("test-xid");
+ assertTrue(RootContext.inGlobalTransaction(),
+ "Should be in global transaction when XID is bound");
+
+ // Test with TCC branch type
+ RootContext.bindBranchType(BranchType.TCC);
+ assertTrue(RootContext.inTccBranch(),
+ "Should be in TCC branch when TCC branch type is bound");
+
+ // Test with Saga branch type
+ RootContext.bindBranchType(BranchType.SAGA);
+ assertTrue(RootContext.inSagaBranch(),
+ "Should be in Saga branch when Saga branch type is bound");
+ }
+
+ @Test
+ public void testAssertNotInGlobalTransaction() {
+ // Should not throw when not in global transaction
+ assertDoesNotThrow(() -> RootContext.assertNotInGlobalTransaction(),
+ "Should not throw when not in global transaction");
+
+ // Should throw when in global transaction (may throw
ShouldNeverHappenException in compatible mode)
+ RootContext.bind("test-xid");
+ assertThrows(RuntimeException.class,
+ () -> RootContext.assertNotInGlobalTransaction(),
+ "Should throw exception when in global transaction");
+ }
+
+ @Test
+ public void testEntries() {
+ // Test entries method returns a map
+ Map<String, Object> entries = RootContext.entries();
+ assertNotNull(entries, "Entries should not be null");
+ assertTrue(entries instanceof Map, "Entries should be a Map");
+ }
+
+ @Test
+ public void testComplexScenario() {
+ // Test a complex scenario with multiple operations
+ String xid = "complex-test-xid";
+ BranchType branchType = BranchType.AT;
+ Integer timeout = 60000;
+
+ // Bind all context
+ RootContext.bind(xid);
+ RootContext.bindBranchType(branchType);
+ RootContext.bindGlobalLockFlag();
+ RootContext.setTimeout(timeout);
+
+ // Verify all are set correctly
+ assertEquals(xid, RootContext.getXID());
+ assertEquals(branchType, RootContext.getBranchType());
+ assertTrue(RootContext.requireGlobalLock());
+ assertEquals(timeout, RootContext.getTimeout());
+ assertTrue(RootContext.inGlobalTransaction());
+
+ // Clean up
+ assertEquals(xid, RootContext.unbind());
+ assertEquals(branchType, RootContext.unbindBranchType());
+ RootContext.unbindGlobalLockFlag();
+
+ // Verify clean state
+ assertNull(RootContext.getXID());
+ assertNull(RootContext.getBranchType());
+ assertFalse(RootContext.requireGlobalLock());
+ assertFalse(RootContext.inGlobalTransaction());
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/exception/TransactionExceptionCodeTest.java
b/compatible/src/test/java/io/seata/core/exception/TransactionExceptionCodeTest.java
new file mode 100644
index 0000000000..3cd7b0df30
--- /dev/null
+++
b/compatible/src/test/java/io/seata/core/exception/TransactionExceptionCodeTest.java
@@ -0,0 +1,201 @@
+/*
+ * 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.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for TransactionExceptionCode enum compatibility.
+ */
+public class TransactionExceptionCodeTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ // Test that TransactionExceptionCode is marked as @Deprecated
+
assertTrue(TransactionExceptionCode.class.isAnnotationPresent(Deprecated.class),
+ "TransactionExceptionCode should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testAllEnumValues() {
+ // Test all enum values exist
+ assertNotNull(TransactionExceptionCode.Unknown);
+ assertNotNull(TransactionExceptionCode.BeginFailed);
+ assertNotNull(TransactionExceptionCode.LockKeyConflict);
+ assertNotNull(TransactionExceptionCode.IO);
+ assertNotNull(TransactionExceptionCode.BranchRollbackFailed_Retriable);
+
assertNotNull(TransactionExceptionCode.BranchRollbackFailed_Unretriable);
+ assertNotNull(TransactionExceptionCode.BranchRegisterFailed);
+ assertNotNull(TransactionExceptionCode.BranchReportFailed);
+ assertNotNull(TransactionExceptionCode.LockableCheckFailed);
+ assertNotNull(TransactionExceptionCode.BranchTransactionNotExist);
+ assertNotNull(TransactionExceptionCode.GlobalTransactionNotExist);
+ assertNotNull(TransactionExceptionCode.GlobalTransactionNotActive);
+ assertNotNull(TransactionExceptionCode.GlobalTransactionStatusInvalid);
+
assertNotNull(TransactionExceptionCode.FailedToSendBranchCommitRequest);
+
assertNotNull(TransactionExceptionCode.FailedToSendBranchRollbackRequest);
+ assertNotNull(TransactionExceptionCode.FailedToAddBranch);
+ assertNotNull(TransactionExceptionCode.FailedLockGlobalTranscation);
+ assertNotNull(TransactionExceptionCode.FailedWriteSession);
+ assertNotNull(TransactionExceptionCode.FailedStore);
+ assertNotNull(TransactionExceptionCode.NotRaftLeader);
+ assertNotNull(TransactionExceptionCode.LockKeyConflictFailFast);
+ assertNotNull(TransactionExceptionCode.TransactionTimeout);
+ assertNotNull(TransactionExceptionCode.CommitHeuristic);
+ assertNotNull(TransactionExceptionCode.Broken);
+ }
+
+ @Test
+ public void testEnumOrdinals() {
+ // Test that ordinals are consistent (important for serialization)
+ TransactionExceptionCode[] values = TransactionExceptionCode.values();
+
+ assertEquals(0, TransactionExceptionCode.Unknown.ordinal());
+ assertEquals(1, TransactionExceptionCode.BeginFailed.ordinal());
+ assertEquals(2, TransactionExceptionCode.LockKeyConflict.ordinal());
+ assertEquals(3, TransactionExceptionCode.IO.ordinal());
+
+ // Test that ordinals are sequential
+ for (int i = 0; i < values.length; i++) {
+ assertEquals(i, values[i].ordinal(),
+ "Ordinal should be sequential for index: " + i);
+ }
+ }
+
+ @Test
+ public void testGetByIntOrdinal() {
+ // Test getting exception code by int ordinal
+ TransactionExceptionCode[] values = TransactionExceptionCode.values();
+
+ for (int i = 0; i < values.length; i++) {
+ assertEquals(values[i], TransactionExceptionCode.get(i),
+ "Should get correct enum value for ordinal: " + i);
+ }
+ }
+
+ @Test
+ public void testGetByByteOrdinal() {
+ // Test getting exception code by byte ordinal
+ assertEquals(TransactionExceptionCode.Unknown,
TransactionExceptionCode.get((byte) 0));
+ assertEquals(TransactionExceptionCode.BeginFailed,
TransactionExceptionCode.get((byte) 1));
+ assertEquals(TransactionExceptionCode.LockKeyConflict,
TransactionExceptionCode.get((byte) 2));
+ assertEquals(TransactionExceptionCode.IO,
TransactionExceptionCode.get((byte) 3));
+ }
+
+ @Test
+ public void testGetInvalidOrdinal() {
+ // Test that invalid ordinals throw IllegalArgumentException
+ assertThrows(IllegalArgumentException.class, () ->
TransactionExceptionCode.get(-1),
+ "Should throw IllegalArgumentException for negative ordinal");
+ assertThrows(IllegalArgumentException.class, () ->
TransactionExceptionCode.get(100),
+ "Should throw IllegalArgumentException for ordinal > max
value");
+ assertThrows(IllegalArgumentException.class,
+ () ->
TransactionExceptionCode.get(TransactionExceptionCode.values().length),
+ "Should throw IllegalArgumentException for ordinal >= values
length");
+ }
+
+ @Test
+ public void testConvertTransactionExceptionCode() {
+ // Test conversion to Apache Seata TransactionExceptionCode
+ for (TransactionExceptionCode code :
TransactionExceptionCode.values()) {
+ org.apache.seata.core.exception.TransactionExceptionCode converted
=
+ code.convertTransactionExceptionCode();
+ assertNotNull(converted, "Converted exception code should not be
null for: " + code);
+ assertEquals(code.ordinal(), converted.ordinal(),
+ "Converted exception code should have same ordinal for: "
+ code);
+ }
+ }
+
+ @Test
+ public void testEnumValueCount() {
+ // Test that we have the expected number of enum values
+ TransactionExceptionCode[] values = TransactionExceptionCode.values();
+ assertEquals(24, values.length, "Should have 24
TransactionExceptionCode enum values");
+ }
+
+ @Test
+ public void testSpecificExceptionCodes() {
+ // Test some specific important exception codes
+ assertEquals("Unknown", TransactionExceptionCode.Unknown.name());
+ assertEquals("BeginFailed",
TransactionExceptionCode.BeginFailed.name());
+ assertEquals("LockKeyConflict",
TransactionExceptionCode.LockKeyConflict.name());
+ assertEquals("BranchRollbackFailed_Retriable",
TransactionExceptionCode.BranchRollbackFailed_Retriable.name());
+ assertEquals("BranchRollbackFailed_Unretriable",
TransactionExceptionCode.BranchRollbackFailed_Unretriable.name());
+ assertEquals("GlobalTransactionNotExist",
TransactionExceptionCode.GlobalTransactionNotExist.name());
+ assertEquals("TransactionTimeout",
TransactionExceptionCode.TransactionTimeout.name());
+ }
+
+ @Test
+ public void testExceptionCodeCategories() {
+ // Test that different categories of exceptions exist
+
+ // Connection/IO related
+ assertNotNull(TransactionExceptionCode.IO);
+ assertNotNull(TransactionExceptionCode.FailedWriteSession);
+ assertNotNull(TransactionExceptionCode.FailedStore);
+
+ // Transaction lifecycle
+ assertNotNull(TransactionExceptionCode.BeginFailed);
+ assertNotNull(TransactionExceptionCode.TransactionTimeout);
+ assertNotNull(TransactionExceptionCode.CommitHeuristic);
+
+ // Branch operations
+ assertNotNull(TransactionExceptionCode.BranchRegisterFailed);
+ assertNotNull(TransactionExceptionCode.BranchReportFailed);
+ assertNotNull(TransactionExceptionCode.BranchRollbackFailed_Retriable);
+
assertNotNull(TransactionExceptionCode.BranchRollbackFailed_Unretriable);
+
+ // Lock operations
+ assertNotNull(TransactionExceptionCode.LockKeyConflict);
+ assertNotNull(TransactionExceptionCode.LockKeyConflictFailFast);
+ assertNotNull(TransactionExceptionCode.LockableCheckFailed);
+
+ // Global transaction states
+ assertNotNull(TransactionExceptionCode.GlobalTransactionNotExist);
+ assertNotNull(TransactionExceptionCode.GlobalTransactionNotActive);
+ assertNotNull(TransactionExceptionCode.GlobalTransactionStatusInvalid);
+ }
+
+ @Test
+ public void testAllValuesHaveNames() {
+ // Test that all enum values have proper names
+ for (TransactionExceptionCode code :
TransactionExceptionCode.values()) {
+ assertNotNull(code.name(), "Exception code name should not be null
for: " + code);
+ assertTrue(code.name().length() > 0, "Exception code name should
not be empty for: " + code);
+ }
+ }
+
+ @Test
+ public void testBidirectionalCompatibility() {
+ // Test that conversion is bidirectional compatible
+ for (TransactionExceptionCode originalCode :
TransactionExceptionCode.values()) {
+ org.apache.seata.core.exception.TransactionExceptionCode
apacheCode =
+ originalCode.convertTransactionExceptionCode();
+
+ // Convert back using ordinal
+ TransactionExceptionCode backConverted =
TransactionExceptionCode.get(apacheCode.ordinal());
+
+ assertEquals(originalCode, backConverted,
+ "Bidirectional conversion should work for: " +
originalCode);
+ }
+ }
+}
\ No newline at end of file
diff --git a/compatible/src/test/java/io/seata/core/model/BranchTypeTest.java
b/compatible/src/test/java/io/seata/core/model/BranchTypeTest.java
new file mode 100644
index 0000000000..ab96e59122
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/model/BranchTypeTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.model;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Unit test for BranchType enum
+ */
+public class BranchTypeTest {
+
+ @Test
+ public void testBranchTypeValues() {
+ // Test that all branch types exist
+ Assertions.assertNotNull(BranchType.AT);
+ Assertions.assertNotNull(BranchType.TCC);
+ Assertions.assertNotNull(BranchType.SAGA);
+ Assertions.assertNotNull(BranchType.XA);
+ }
+
+ @Test
+ public void testBranchTypeCompatibility() {
+ // Test that compatible BranchType has same values as Apache Seata
BranchType
+
+ // Test AT branch type
+ Assertions.assertEquals(
+ org.apache.seata.core.model.BranchType.AT.ordinal(),
+ BranchType.AT.ordinal()
+ );
+
+ // Test TCC branch type
+ Assertions.assertEquals(
+ org.apache.seata.core.model.BranchType.TCC.ordinal(),
+ BranchType.TCC.ordinal()
+ );
+
+ // Test SAGA branch type
+ Assertions.assertEquals(
+ org.apache.seata.core.model.BranchType.SAGA.ordinal(),
+ BranchType.SAGA.ordinal()
+ );
+
+ // Test XA branch type
+ Assertions.assertEquals(
+ org.apache.seata.core.model.BranchType.XA.ordinal(),
+ BranchType.XA.ordinal()
+ );
+ }
+
+ @Test
+ public void testGetMethod() {
+ // Test the get method for each branch type
+ Assertions.assertEquals(BranchType.AT, BranchType.get((byte) 0));
+ Assertions.assertEquals(BranchType.TCC, BranchType.get((byte) 1));
+ Assertions.assertEquals(BranchType.SAGA, BranchType.get((byte) 2));
+ Assertions.assertEquals(BranchType.XA, BranchType.get((byte) 3));
+ }
+
+ @Test
+ public void testGetMethodWithInvalidValue() {
+ // Test get method with invalid byte value
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ BranchType.get((byte) 99);
+ });
+ }
+
+ @Test
+ public void testBranchTypeNames() {
+ // Test that branch type names match
+ Assertions.assertEquals("AT", BranchType.AT.name());
+ Assertions.assertEquals("TCC", BranchType.TCC.name());
+ Assertions.assertEquals("SAGA", BranchType.SAGA.name());
+ Assertions.assertEquals("XA", BranchType.XA.name());
+ }
+
+ @Test
+ public void testBranchTypeValuesArray() {
+ // Test the values() method
+ BranchType[] values = BranchType.values();
+ Assertions.assertTrue(values.length >= 4);
+
+ // Verify all expected types are present
+ boolean hasAT = false, hasTCC = false, hasSAGA = false, hasXA = false;
+ for (BranchType type : values) {
+ switch (type.name()) {
+ case "AT":
+ hasAT = true;
+ break;
+ case "TCC":
+ hasTCC = true;
+ break;
+ case "SAGA":
+ hasSAGA = true;
+ break;
+ case "XA":
+ hasXA = true;
+ break;
+ }
+ }
+
+ Assertions.assertTrue(hasAT, "AT branch type should be present");
+ Assertions.assertTrue(hasTCC, "TCC branch type should be present");
+ Assertions.assertTrue(hasSAGA, "SAGA branch type should be present");
+ Assertions.assertTrue(hasXA, "XA branch type should be present");
+ }
+
+ @Test
+ public void testValueOf() {
+ // Test the valueOf method
+ Assertions.assertEquals(BranchType.AT, BranchType.valueOf("AT"));
+ Assertions.assertEquals(BranchType.TCC, BranchType.valueOf("TCC"));
+ Assertions.assertEquals(BranchType.SAGA, BranchType.valueOf("SAGA"));
+ Assertions.assertEquals(BranchType.XA, BranchType.valueOf("XA"));
+ }
+
+ @Test
+ public void testValueOfWithInvalidName() {
+ // Test valueOf with invalid name
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ BranchType.valueOf("INVALID");
+ });
+ }
+}
\ No newline at end of file
diff --git a/compatible/src/test/java/io/seata/core/model/GlobalStatusTest.java
b/compatible/src/test/java/io/seata/core/model/GlobalStatusTest.java
new file mode 100644
index 0000000000..f9c05f7ea2
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/model/GlobalStatusTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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.model;
+
+import org.junit.jupiter.api.Test;
+
+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.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test cases for GlobalStatus enum compatibility.
+ */
+public class GlobalStatusTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ // Test that GlobalStatus is marked as @Deprecated
+ assertTrue(GlobalStatus.class.isAnnotationPresent(Deprecated.class),
+ "GlobalStatus should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testAllEnumValues() {
+ // Test all enum values exist
+ assertNotNull(GlobalStatus.UnKnown);
+ assertNotNull(GlobalStatus.Begin);
+ assertNotNull(GlobalStatus.Committing);
+ assertNotNull(GlobalStatus.CommitRetrying);
+ assertNotNull(GlobalStatus.Rollbacking);
+ assertNotNull(GlobalStatus.RollbackRetrying);
+ assertNotNull(GlobalStatus.TimeoutRollbacking);
+ assertNotNull(GlobalStatus.TimeoutRollbackRetrying);
+ assertNotNull(GlobalStatus.AsyncCommitting);
+ assertNotNull(GlobalStatus.Committed);
+ assertNotNull(GlobalStatus.CommitFailed);
+ assertNotNull(GlobalStatus.Rollbacked);
+ assertNotNull(GlobalStatus.RollbackFailed);
+ assertNotNull(GlobalStatus.TimeoutRollbacked);
+ assertNotNull(GlobalStatus.TimeoutRollbackFailed);
+ assertNotNull(GlobalStatus.Finished);
+ assertNotNull(GlobalStatus.CommitRetryTimeout);
+ assertNotNull(GlobalStatus.RollbackRetryTimeout);
+ }
+
+ @Test
+ public void testStatusCodes() {
+ // Test that each status has the correct code
+ assertEquals(0, GlobalStatus.UnKnown.getCode());
+ assertEquals(1, GlobalStatus.Begin.getCode());
+ assertEquals(2, GlobalStatus.Committing.getCode());
+ assertEquals(3, GlobalStatus.CommitRetrying.getCode());
+ assertEquals(4, GlobalStatus.Rollbacking.getCode());
+ assertEquals(5, GlobalStatus.RollbackRetrying.getCode());
+ assertEquals(6, GlobalStatus.TimeoutRollbacking.getCode());
+ assertEquals(7, GlobalStatus.TimeoutRollbackRetrying.getCode());
+ assertEquals(8, GlobalStatus.AsyncCommitting.getCode());
+ assertEquals(9, GlobalStatus.Committed.getCode());
+ assertEquals(10, GlobalStatus.CommitFailed.getCode());
+ assertEquals(11, GlobalStatus.Rollbacked.getCode());
+ assertEquals(12, GlobalStatus.RollbackFailed.getCode());
+ assertEquals(13, GlobalStatus.TimeoutRollbacked.getCode());
+ assertEquals(14, GlobalStatus.TimeoutRollbackFailed.getCode());
+ assertEquals(15, GlobalStatus.Finished.getCode());
+ assertEquals(16, GlobalStatus.CommitRetryTimeout.getCode());
+ assertEquals(17, GlobalStatus.RollbackRetryTimeout.getCode());
+ }
+
+ @Test
+ public void testGetByIntCode() {
+ // Test getting status by int code
+ assertEquals(GlobalStatus.UnKnown, GlobalStatus.get(0));
+ assertEquals(GlobalStatus.Begin, GlobalStatus.get(1));
+ assertEquals(GlobalStatus.Committing, GlobalStatus.get(2));
+ assertEquals(GlobalStatus.Committed, GlobalStatus.get(9));
+ assertEquals(GlobalStatus.Rollbacked, GlobalStatus.get(11));
+ assertEquals(GlobalStatus.Finished, GlobalStatus.get(15));
+ assertEquals(GlobalStatus.RollbackRetryTimeout, GlobalStatus.get(17));
+ }
+
+ @Test
+ public void testGetByByteCode() {
+ // Test getting status by byte code
+ assertEquals(GlobalStatus.UnKnown, GlobalStatus.get((byte) 0));
+ assertEquals(GlobalStatus.Begin, GlobalStatus.get((byte) 1));
+ assertEquals(GlobalStatus.Committed, GlobalStatus.get((byte) 9));
+ assertEquals(GlobalStatus.Rollbacked, GlobalStatus.get((byte) 11));
+ }
+
+ @Test
+ public void testGetInvalidCode() {
+ // Test that invalid codes throw IllegalArgumentException
+ assertThrows(IllegalArgumentException.class, () ->
GlobalStatus.get(-1),
+ "Should throw IllegalArgumentException for negative code");
+ assertThrows(IllegalArgumentException.class, () ->
GlobalStatus.get(100),
+ "Should throw IllegalArgumentException for code > max value");
+ assertThrows(IllegalArgumentException.class, () ->
GlobalStatus.get(GlobalStatus.values().length),
+ "Should throw IllegalArgumentException for code >= values
length");
+ }
+
+ @Test
+ public void testIsOnePhaseTimeout() {
+ // Test timeout status detection
+
assertTrue(GlobalStatus.isOnePhaseTimeout(GlobalStatus.TimeoutRollbacking),
+ "TimeoutRollbacking should be one phase timeout");
+
assertTrue(GlobalStatus.isOnePhaseTimeout(GlobalStatus.TimeoutRollbackRetrying),
+ "TimeoutRollbackRetrying should be one phase timeout");
+
assertTrue(GlobalStatus.isOnePhaseTimeout(GlobalStatus.TimeoutRollbacked),
+ "TimeoutRollbacked should be one phase timeout");
+
assertTrue(GlobalStatus.isOnePhaseTimeout(GlobalStatus.TimeoutRollbackFailed),
+ "TimeoutRollbackFailed should be one phase timeout");
+
+ // Test non-timeout statuses
+ assertFalse(GlobalStatus.isOnePhaseTimeout(GlobalStatus.Begin),
+ "Begin should not be one phase timeout");
+ assertFalse(GlobalStatus.isOnePhaseTimeout(GlobalStatus.Committed),
+ "Committed should not be one phase timeout");
+ assertFalse(GlobalStatus.isOnePhaseTimeout(GlobalStatus.Rollbacked),
+ "Rollbacked should not be one phase timeout");
+ }
+
+ @Test
+ public void testIsTwoPhaseSuccess() {
+ // Test two phase success status detection
+ assertTrue(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.Committed),
+ "Committed should be two phase success");
+ assertTrue(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.Rollbacked),
+ "Rollbacked should be two phase success");
+
assertTrue(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.TimeoutRollbacked),
+ "TimeoutRollbacked should be two phase success");
+
+ // Test non-success statuses
+ assertFalse(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.Begin),
+ "Begin should not be two phase success");
+ assertFalse(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.Committing),
+ "Committing should not be two phase success");
+ assertFalse(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.CommitFailed),
+ "CommitFailed should not be two phase success");
+
assertFalse(GlobalStatus.isTwoPhaseSuccess(GlobalStatus.RollbackFailed),
+ "RollbackFailed should not be two phase success");
+ }
+
+ @Test
+ public void testIsTwoPhaseHeuristic() {
+ // Test two phase heuristic status detection
+ assertTrue(GlobalStatus.isTwoPhaseHeuristic(GlobalStatus.Finished),
+ "Finished should be two phase heuristic");
+
+ // Test non-heuristic statuses
+ assertFalse(GlobalStatus.isTwoPhaseHeuristic(GlobalStatus.Begin),
+ "Begin should not be two phase heuristic");
+ assertFalse(GlobalStatus.isTwoPhaseHeuristic(GlobalStatus.Committed),
+ "Committed should not be two phase heuristic");
+ assertFalse(GlobalStatus.isTwoPhaseHeuristic(GlobalStatus.Rollbacked),
+ "Rollbacked should not be two phase heuristic");
+ }
+
+ @Test
+ public void testConvertGlobalStatus() {
+ // Test conversion to Apache Seata GlobalStatus
+ for (GlobalStatus status : GlobalStatus.values()) {
+ org.apache.seata.core.model.GlobalStatus converted =
status.convertGlobalStatus();
+ assertNotNull(converted, "Converted status should not be null for:
" + status);
+ assertEquals(status.getCode(), converted.getCode(),
+ "Converted status should have same code for: " + status);
+ }
+ }
+
+ @Test
+ public void testStatusDescriptions() {
+ // Test that all statuses have descriptions (not testing exact text as
it might change)
+ for (GlobalStatus status : GlobalStatus.values()) {
+ // Access the description through toString or other means
+ // The exact description is implementation detail, just ensure
it's accessible
+ assertNotNull(status.name(), "Status name should not be null for:
" + status);
+ assertTrue(status.name().length() > 0, "Status name should not be
empty for: " + status);
+ }
+ }
+
+ @Test
+ public void testEnumValueCount() {
+ // Test that we have the expected number of enum values
+ GlobalStatus[] values = GlobalStatus.values();
+ assertEquals(18, values.length, "Should have 18 GlobalStatus enum
values");
+ }
+
+ @Test
+ public void testEnumOrdinals() {
+ // Test that ordinals match codes for consistent ordering
+ for (GlobalStatus status : GlobalStatus.values()) {
+ assertEquals(status.ordinal(), status.getCode(),
+ "Ordinal should match code for status: " + status);
+ }
+ }
+
+ @Test
+ public void testPhaseStatusGroups() {
+ // Test phase 1 statuses
+ assertEquals(1, GlobalStatus.Begin.getCode(), "Begin should be phase
1");
+
+ // Test phase 2 running statuses (transient states)
+ assertTrue(GlobalStatus.Committing.getCode() >= 2 &&
GlobalStatus.Committing.getCode() <= 8,
+ "Committing should be in phase 2 running range");
+ assertTrue(GlobalStatus.Rollbacking.getCode() >= 2 &&
GlobalStatus.Rollbacking.getCode() <= 8,
+ "Rollbacking should be in phase 2 running range");
+ assertTrue(GlobalStatus.AsyncCommitting.getCode() >= 2 &&
GlobalStatus.AsyncCommitting.getCode() <= 8,
+ "AsyncCommitting should be in phase 2 running range");
+
+ // Test phase 2 final statuses
+ assertTrue(GlobalStatus.Committed.getCode() >= 9,
+ "Committed should be in final status range");
+ assertTrue(GlobalStatus.Rollbacked.getCode() >= 9,
+ "Rollbacked should be in final status range");
+ assertTrue(GlobalStatus.Finished.getCode() >= 9,
+ "Finished should be in final status range");
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/model/ResourceManagerTest.java
b/compatible/src/test/java/io/seata/core/model/ResourceManagerTest.java
new file mode 100644
index 0000000000..6577eb85e2
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/model/ResourceManagerTest.java
@@ -0,0 +1,283 @@
+/*
+ * 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.model;
+
+import org.apache.seata.core.exception.TransactionException;
+import org.apache.seata.core.model.BranchStatus;
+import org.apache.seata.core.model.BranchType;
+import org.apache.seata.core.model.GlobalStatus;
+import org.apache.seata.core.model.Resource;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Unit test for ResourceManager interface
+ */
+public class ResourceManagerTest {
+
+ /**
+ * Mock implementation for testing
+ */
+ private static class MockResourceManager implements ResourceManager {
+ private final Map<String, Resource> managedResources = new HashMap<>();
+
+ @Override
+ public Long branchRegister(BranchType branchType, String resourceId,
String clientId, String xid, String applicationData, String lockKeys) throws
TransactionException {
+ return System.currentTimeMillis(); // Simple mock implementation
+ }
+
+ @Override
+ public void branchReport(BranchType branchType, String xid, long
branchId, BranchStatus status, String applicationData) throws
TransactionException {
+ // Mock implementation - do nothing
+ }
+
+ @Override
+ public boolean lockQuery(BranchType branchType, String resourceId,
String xid, String lockKeys) throws TransactionException {
+ return true; // Simple mock implementation
+ }
+
+ @Override
+ public BranchStatus branchCommit(BranchType branchType, String xid,
long branchId, String resourceId, String applicationData) throws
TransactionException {
+ return BranchStatus.PhaseTwo_Committed; // Simple mock
implementation
+ }
+
+ @Override
+ public BranchStatus branchRollback(BranchType branchType, String xid,
long branchId, String resourceId, String applicationData) throws
TransactionException {
+ return BranchStatus.PhaseTwo_Rollbacked; // Simple mock
implementation
+ }
+
+ @Override
+ public void registerResource(Resource resource) {
+ managedResources.put(resource.getResourceId(), resource);
+ }
+
+ @Override
+ public void unregisterResource(Resource resource) {
+ managedResources.remove(resource.getResourceId());
+ }
+
+ @Override
+ public Map<String, Resource> getManagedResources() {
+ return new HashMap<>(managedResources);
+ }
+
+ @Override
+ public BranchType getBranchType() {
+ return BranchType.AT; // Simple mock implementation
+ }
+
+ @Override
+ public GlobalStatus getGlobalStatus(BranchType branchType, String xid)
{
+ return GlobalStatus.Begin; // Simple mock implementation
+ }
+ }
+
+ @Test
+ public void testResourceManagerInterfaceInheritance() {
+ // Test that ResourceManager extends from Apache Seata's
ResourceManager
+ Assertions.assertTrue(org.apache.seata.core.model.ResourceManager.class
+ .isAssignableFrom(ResourceManager.class));
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the ResourceManager interface is marked as deprecated
+
Assertions.assertTrue(ResourceManager.class.isAnnotationPresent(Deprecated.class),
+ "ResourceManager should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInterfaceStructure() {
+ // Test interface modifiers
+ int modifiers = ResourceManager.class.getModifiers();
+
Assertions.assertTrue(java.lang.reflect.Modifier.isInterface(modifiers),
+ "ResourceManager should be an interface");
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "ResourceManager should be public");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.core.model",
+ ResourceManager.class.getPackage().getName(),
+ "ResourceManager should be in io.seata.core.model package");
+ }
+
+ @Test
+ public void testMethodInheritance() throws Exception {
+ // Test that the interface has the expected methods from the parent
interface
+ MockResourceManager mockResourceManager = new MockResourceManager();
+
+ // Test that the mock resource manager implements both interfaces
+ Assertions.assertTrue(mockResourceManager instanceof ResourceManager);
+ Assertions.assertTrue(mockResourceManager instanceof
org.apache.seata.core.model.ResourceManager);
+ }
+
+ @Test
+ public void testInterfaceCompatibility() {
+ // Test that compatible ResourceManager can be used wherever Apache
Seata ResourceManager is expected
+ MockResourceManager compatibleResourceManager = new
MockResourceManager();
+ org.apache.seata.core.model.ResourceManager apacheResourceManager =
compatibleResourceManager;
+
+ Assertions.assertNotNull(apacheResourceManager);
+ Assertions.assertSame(compatibleResourceManager,
apacheResourceManager);
+ }
+
+ @Test
+ public void testImplementationFunctionality() throws TransactionException {
+ // Test basic functionality of a mock implementation
+ MockResourceManager resourceManager = new MockResourceManager();
+
+ // Test branchRegister method
+ Long branchId = resourceManager.branchRegister(BranchType.AT,
"resource1", "client1", "xid1", "data", "keys");
+ Assertions.assertNotNull(branchId);
+ Assertions.assertTrue(branchId > 0);
+
+ // Test lockQuery method
+ boolean lockResult = resourceManager.lockQuery(BranchType.AT,
"resource1", "xid1", "keys");
+ Assertions.assertTrue(lockResult);
+
+ // Test branchCommit method
+ BranchStatus commitStatus =
resourceManager.branchCommit(BranchType.AT, "xid1", branchId, "resource1",
"data");
+ Assertions.assertEquals(BranchStatus.PhaseTwo_Committed, commitStatus);
+
+ // Test branchRollback method
+ BranchStatus rollbackStatus =
resourceManager.branchRollback(BranchType.AT, "xid1", branchId, "resource1",
"data");
+ Assertions.assertEquals(BranchStatus.PhaseTwo_Rollbacked,
rollbackStatus);
+
+ // Test getBranchType method
+ BranchType branchType = resourceManager.getBranchType();
+ Assertions.assertEquals(BranchType.AT, branchType);
+
+ // Test getGlobalStatus method
+ GlobalStatus globalStatus =
resourceManager.getGlobalStatus(BranchType.AT, "xid1");
+ Assertions.assertEquals(GlobalStatus.Begin, globalStatus);
+ }
+
+ @Test
+ public void testResourceManagement() {
+ // Test resource registration and management
+ MockResourceManager resourceManager = new MockResourceManager();
+
+ // Create a mock resource
+ Resource mockResource = new Resource() {
+ @Override
+ public String getResourceGroupId() {
+ return "testGroup";
+ }
+
+ @Override
+ public String getResourceId() {
+ return "testResource";
+ }
+
+ @Override
+ public BranchType getBranchType() {
+ return BranchType.AT;
+ }
+ };
+
+ // Test registerResource method
+ resourceManager.registerResource(mockResource);
+ Map<String, Resource> managedResources =
resourceManager.getManagedResources();
+ Assertions.assertTrue(managedResources.containsKey("testResource"));
+ Assertions.assertEquals(mockResource,
managedResources.get("testResource"));
+
+ // Test unregisterResource method
+ resourceManager.unregisterResource(mockResource);
+ managedResources = resourceManager.getManagedResources();
+ Assertions.assertFalse(managedResources.containsKey("testResource"));
+ }
+
+ @Test
+ public void testPolymorphism() {
+ // Test polymorphic behavior
+ MockResourceManager mockResourceManager = new MockResourceManager();
+ ResourceManager resourceManager = mockResourceManager;
+ Object obj = resourceManager;
+
+ Assertions.assertTrue(obj instanceof
org.apache.seata.core.model.ResourceManager);
+ Assertions.assertTrue(obj instanceof ResourceManager);
+ }
+
+ @Test
+ public void testRequiredMethods() throws Exception {
+ // Test that all required methods are present
+ java.lang.reflect.Method[] methods =
ResourceManager.class.getMethods();
+
+ boolean hasBranchRegister = false;
+ boolean hasBranchReport = false;
+ boolean hasLockQuery = false;
+ boolean hasBranchCommit = false;
+ boolean hasBranchRollback = false;
+ boolean hasRegisterResource = false;
+ boolean hasUnregisterResource = false;
+ boolean hasGetManagedResources = false;
+ boolean hasGetBranchType = false;
+ boolean hasGetGlobalStatus = false;
+
+ for (java.lang.reflect.Method method : methods) {
+ switch (method.getName()) {
+ case "branchRegister":
+ if (method.getParameterCount() == 6) hasBranchRegister =
true;
+ break;
+ case "branchReport":
+ if (method.getParameterCount() == 5) hasBranchReport =
true;
+ break;
+ case "lockQuery":
+ if (method.getParameterCount() == 4) hasLockQuery = true;
+ break;
+ case "branchCommit":
+ if (method.getParameterCount() == 5) hasBranchCommit =
true;
+ break;
+ case "branchRollback":
+ if (method.getParameterCount() == 5) hasBranchRollback =
true;
+ break;
+ case "registerResource":
+ if (method.getParameterCount() == 1) hasRegisterResource =
true;
+ break;
+ case "unregisterResource":
+ if (method.getParameterCount() == 1) hasUnregisterResource
= true;
+ break;
+ case "getManagedResources":
+ if (method.getParameterCount() == 0)
hasGetManagedResources = true;
+ break;
+ case "getBranchType":
+ if (method.getParameterCount() == 0) hasGetBranchType =
true;
+ break;
+ case "getGlobalStatus":
+ if (method.getParameterCount() == 2) hasGetGlobalStatus =
true;
+ break;
+ }
+ }
+
+ Assertions.assertTrue(hasBranchRegister, "ResourceManager should have
branchRegister method");
+ Assertions.assertTrue(hasBranchReport, "ResourceManager should have
branchReport method");
+ Assertions.assertTrue(hasLockQuery, "ResourceManager should have
lockQuery method");
+ Assertions.assertTrue(hasBranchCommit, "ResourceManager should have
branchCommit method");
+ Assertions.assertTrue(hasBranchRollback, "ResourceManager should have
branchRollback method");
+ Assertions.assertTrue(hasRegisterResource, "ResourceManager should
have registerResource method");
+ Assertions.assertTrue(hasUnregisterResource, "ResourceManager should
have unregisterResource method");
+ Assertions.assertTrue(hasGetManagedResources, "ResourceManager should
have getManagedResources method");
+ Assertions.assertTrue(hasGetBranchType, "ResourceManager should have
getBranchType method");
+ Assertions.assertTrue(hasGetGlobalStatus, "ResourceManager should have
getGlobalStatus method");
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/core/serializer/SerializerTest.java
b/compatible/src/test/java/io/seata/core/serializer/SerializerTest.java
new file mode 100644
index 0000000000..5dfd336897
--- /dev/null
+++ b/compatible/src/test/java/io/seata/core/serializer/SerializerTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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.serializer;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Unit test for Serializer interface
+ */
+public class SerializerTest {
+
+ /**
+ * Mock implementation for testing
+ */
+ private static class MockSerializer implements Serializer {
+ @Override
+ public <T> byte[] serialize(T t) {
+ if (t == null) {
+ return new byte[0];
+ }
+ return t.toString().getBytes(); // Simple mock implementation
+ }
+
+ @Override
+ public <T> T deserialize(byte[] bytes) {
+ if (bytes == null || bytes.length == 0) {
+ return null;
+ }
+ return (T) new String(bytes); // Simple mock implementation
+ }
+ }
+
+ @Test
+ public void testSerializerInterfaceInheritance() {
+ // Test that Serializer extends from Apache Seata's Serializer
+ Assertions.assertTrue(org.apache.seata.core.serializer.Serializer.class
+ .isAssignableFrom(Serializer.class));
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the Serializer interface is marked as deprecated
+
Assertions.assertTrue(Serializer.class.isAnnotationPresent(Deprecated.class),
+ "Serializer should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInterfaceStructure() {
+ // Test interface modifiers
+ int modifiers = Serializer.class.getModifiers();
+
Assertions.assertTrue(java.lang.reflect.Modifier.isInterface(modifiers),
+ "Serializer should be an interface");
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "Serializer should be public");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.core.serializer",
+ Serializer.class.getPackage().getName(),
+ "Serializer should be in io.seata.core.serializer package");
+ }
+
+ @Test
+ public void testMethodInheritance() throws Exception {
+ // Test that the interface has the expected methods from the parent
interface
+ MockSerializer mockSerializer = new MockSerializer();
+
+ // Test that the mock serializer implements both interfaces
+ Assertions.assertTrue(mockSerializer instanceof Serializer);
+ Assertions.assertTrue(mockSerializer instanceof
org.apache.seata.core.serializer.Serializer);
+ }
+
+ @Test
+ public void testInterfaceCompatibility() {
+ // Test that compatible Serializer can be used wherever Apache Seata
Serializer is expected
+ MockSerializer compatibleSerializer = new MockSerializer();
+ org.apache.seata.core.serializer.Serializer apacheSerializer =
compatibleSerializer;
+
+ Assertions.assertNotNull(apacheSerializer);
+ Assertions.assertSame(compatibleSerializer, apacheSerializer);
+ }
+
+ @Test
+ public void testImplementationFunctionality() {
+ // Test basic functionality of a mock implementation
+ MockSerializer serializer = new MockSerializer();
+
+ String testObject = "Hello World";
+
+ // Test serialize method
+ byte[] serialized = serializer.serialize(testObject);
+ Assertions.assertNotNull(serialized);
+ Assertions.assertTrue(serialized.length > 0);
+
+ // Test deserialize method
+ String deserialized = serializer.deserialize(serialized);
+ Assertions.assertNotNull(deserialized);
+ Assertions.assertEquals(testObject, deserialized);
+ }
+
+ @Test
+ public void testInterfaceMethods() throws Exception {
+ // Test that the interface has the expected method signatures
+ java.lang.reflect.Method serializeMethod =
Serializer.class.getMethod("serialize", Object.class);
+ Assertions.assertNotNull(serializeMethod);
+ Assertions.assertEquals(byte[].class, serializeMethod.getReturnType());
+
+ java.lang.reflect.Method deserializeMethod =
Serializer.class.getMethod("deserialize", byte[].class);
+ Assertions.assertNotNull(deserializeMethod);
+ Assertions.assertEquals(Object.class,
deserializeMethod.getReturnType());
+ }
+
+ @Test
+ public void testPolymorphism() {
+ // Test polymorphic behavior
+ MockSerializer mockSerializer = new MockSerializer();
+ Serializer serializer = mockSerializer;
+ Object obj = serializer;
+
+ Assertions.assertTrue(obj instanceof
org.apache.seata.core.serializer.Serializer);
+ Assertions.assertTrue(obj instanceof Serializer);
+ }
+
+ @Test
+ public void testGenericMethods() {
+ // Test generic method usage
+ MockSerializer serializer = new MockSerializer();
+
+ // Test with different types
+ Integer intValue = 42;
+ byte[] intSerialized = serializer.serialize(intValue);
+ String intDeserialized = serializer.deserialize(intSerialized);
+ Assertions.assertEquals("42", intDeserialized);
+
+ // Test with null
+ byte[] nullSerialized = serializer.serialize(null);
+ Assertions.assertNotNull(nullSerialized);
+ Assertions.assertEquals(0, nullSerialized.length);
+
+ String nullDeserialized = serializer.deserialize(null);
+ Assertions.assertNull(nullDeserialized);
+ }
+
+ @Test
+ public void testMethodSignatures() {
+ // Test that all required methods are present with correct signatures
+ java.lang.reflect.Method[] methods = Serializer.class.getMethods();
+
+ boolean hasSerialize = false, hasDeserialize = false;
+
+ for (java.lang.reflect.Method method : methods) {
+ if (method.getName().equals("serialize") &&
method.getParameterCount() == 1) {
+ hasSerialize = true;
+ } else if (method.getName().equals("deserialize") &&
method.getParameterCount() == 1) {
+ hasDeserialize = true;
+ }
+ }
+
+ Assertions.assertTrue(hasSerialize, "Serializer should have serialize
method");
+ Assertions.assertTrue(hasDeserialize, "Serializer should have
deserialize method");
+ }
+}
\ No newline at end of file
diff --git a/compatible/src/test/java/io/seata/rm/RMClientTest.java
b/compatible/src/test/java/io/seata/rm/RMClientTest.java
new file mode 100644
index 0000000000..64b7bf77bc
--- /dev/null
+++ b/compatible/src/test/java/io/seata/rm/RMClientTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Unit test for RMClient class
+ */
+public class RMClientTest {
+
+ @Test
+ public void testRMClientInheritance() {
+ // Test that RMClient extends from Apache Seata's RMClient
+
Assertions.assertTrue(org.apache.seata.rm.RMClient.class.isAssignableFrom(RMClient.class));
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the RMClient class is marked as deprecated
+
Assertions.assertTrue(RMClient.class.isAnnotationPresent(Deprecated.class),
+ "RMClient should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInstanceCreation() {
+ // Test that we can create an instance of RMClient
+ RMClient rmClient = new RMClient();
+ Assertions.assertNotNull(rmClient);
+
+ // Test that it's an instance of Apache Seata's RMClient
+ Assertions.assertTrue(rmClient instanceof
org.apache.seata.rm.RMClient);
+ }
+
+ @Test
+ public void testClassStructure() {
+ // Test class modifiers
+ int modifiers = RMClient.class.getModifiers();
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "RMClient should be public");
+
+ // Test superclass
+ Assertions.assertEquals(org.apache.seata.rm.RMClient.class,
+ RMClient.class.getSuperclass(),
+ "RMClient should extend Apache Seata's RMClient");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.rm",
+ RMClient.class.getPackage().getName(),
+ "RMClient should be in io.seata.rm package");
+ }
+
+ @Test
+ public void testMethodInheritance() throws Exception {
+ // Test that important methods are inherited from parent class
+ RMClient rmClient = new RMClient();
+
+ // Check if the class has inherited methods (through reflection)
+ // We can verify that it has the same methods as the parent class
+ java.lang.reflect.Method[] parentMethods =
org.apache.seata.rm.RMClient.class.getDeclaredMethods();
+ java.lang.reflect.Method[] childMethods =
RMClient.class.getDeclaredMethods();
+
+ // The child class should have access to parent methods through
inheritance
+ // Since this is a simple extension, we mainly test that the
inheritance works
+ Assertions.assertTrue(rmClient instanceof org.apache.seata.rm.RMClient,
+ "RMClient should inherit from Apache Seata RMClient");
+ }
+
+ @Test
+ public void testClassCompatibility() {
+ // Test that compatible RMClient can be used wherever Apache Seata
RMClient is expected
+ RMClient compatibleClient = new RMClient();
+ org.apache.seata.rm.RMClient apacheClient = compatibleClient;
+
+ Assertions.assertNotNull(apacheClient);
+ Assertions.assertSame(compatibleClient, apacheClient);
+ }
+
+ @Test
+ public void testPolymorphism() {
+ // Test polymorphic behavior
+ RMClient rmClient = new RMClient();
+ Object obj = rmClient;
+
+ Assertions.assertTrue(obj instanceof org.apache.seata.rm.RMClient);
+ Assertions.assertTrue(obj instanceof RMClient);
+ }
+}
\ No newline at end of file
diff --git a/compatible/src/test/java/io/seata/tm/TMClientTest.java
b/compatible/src/test/java/io/seata/tm/TMClientTest.java
new file mode 100644
index 0000000000..ef1f4f1a6e
--- /dev/null
+++ b/compatible/src/test/java/io/seata/tm/TMClientTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Unit test for TMClient class
+ */
+public class TMClientTest {
+
+ @Test
+ public void testTMClientInheritance() {
+ // Test that TMClient extends from Apache Seata's TMClient
+
Assertions.assertTrue(org.apache.seata.tm.TMClient.class.isAssignableFrom(TMClient.class));
+ }
+
+ @Test
+ public void testDeprecationAnnotation() {
+ // Test that the TMClient class is marked as deprecated
+
Assertions.assertTrue(TMClient.class.isAnnotationPresent(Deprecated.class),
+ "TMClient should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testInstanceCreation() {
+ // Test that we can create an instance of TMClient
+ TMClient tmClient = new TMClient();
+ Assertions.assertNotNull(tmClient);
+
+ // Test that it's an instance of Apache Seata's TMClient
+ Assertions.assertTrue(tmClient instanceof
org.apache.seata.tm.TMClient);
+ }
+
+ @Test
+ public void testClassStructure() {
+ // Test class modifiers
+ int modifiers = TMClient.class.getModifiers();
+ Assertions.assertTrue(java.lang.reflect.Modifier.isPublic(modifiers),
+ "TMClient should be public");
+
+ // Test superclass
+ Assertions.assertEquals(org.apache.seata.tm.TMClient.class,
+ TMClient.class.getSuperclass(),
+ "TMClient should extend Apache Seata's TMClient");
+ }
+
+ @Test
+ public void testPackageName() {
+ // Test that the package is the expected compatible package
+ Assertions.assertEquals("io.seata.tm",
+ TMClient.class.getPackage().getName(),
+ "TMClient should be in io.seata.tm package");
+ }
+
+ @Test
+ public void testMethodInheritance() throws Exception {
+ // Test that important methods are inherited from parent class
+ TMClient tmClient = new TMClient();
+
+ // Check if the class has inherited methods (through reflection)
+ // We can verify that it has the same methods as the parent class
+ java.lang.reflect.Method[] parentMethods =
org.apache.seata.tm.TMClient.class.getDeclaredMethods();
+ java.lang.reflect.Method[] childMethods =
TMClient.class.getDeclaredMethods();
+
+ // The child class should have access to parent methods through
inheritance
+ // Since this is a simple extension, we mainly test that the
inheritance works
+ Assertions.assertTrue(tmClient instanceof org.apache.seata.tm.TMClient,
+ "TMClient should inherit from Apache Seata TMClient");
+ }
+
+ @Test
+ public void testClassCompatibility() {
+ // Test that compatible TMClient can be used wherever Apache Seata
TMClient is expected
+ TMClient compatibleClient = new TMClient();
+ org.apache.seata.tm.TMClient apacheClient = compatibleClient;
+
+ Assertions.assertNotNull(apacheClient);
+ Assertions.assertSame(compatibleClient, apacheClient);
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/tm/api/GlobalTransactionRoleTest.java
b/compatible/src/test/java/io/seata/tm/api/GlobalTransactionRoleTest.java
new file mode 100644
index 0000000000..5e33da9cd5
--- /dev/null
+++ b/compatible/src/test/java/io/seata/tm/api/GlobalTransactionRoleTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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 org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+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 GlobalTransactionRole enum compatibility.
+ */
+public class GlobalTransactionRoleTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ // Test that GlobalTransactionRole is marked as @Deprecated
+
assertTrue(GlobalTransactionRole.class.isAnnotationPresent(Deprecated.class),
+ "GlobalTransactionRole should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testAllEnumValues() {
+ // Test all enum values exist
+ assertNotNull(GlobalTransactionRole.Launcher);
+ assertNotNull(GlobalTransactionRole.Participant);
+ }
+
+ @Test
+ public void testEnumValueCount() {
+ // Test that we have the expected number of enum values
+ GlobalTransactionRole[] values = GlobalTransactionRole.values();
+ assertEquals(2, values.length, "Should have 2 GlobalTransactionRole
enum values");
+ }
+
+ @Test
+ public void testEnumOrdinals() {
+ // Test that ordinals are consistent
+ assertEquals(0, GlobalTransactionRole.Launcher.ordinal(),
+ "Launcher should have ordinal 0");
+ assertEquals(1, GlobalTransactionRole.Participant.ordinal(),
+ "Participant should have ordinal 1");
+ }
+
+ @Test
+ public void testEnumNames() {
+ // Test enum names
+ assertEquals("Launcher", GlobalTransactionRole.Launcher.name());
+ assertEquals("Participant", GlobalTransactionRole.Participant.name());
+ }
+
+ @Test
+ public void testValueOf() {
+ // Test valueOf method
+ assertEquals(GlobalTransactionRole.Launcher,
+ GlobalTransactionRole.valueOf("Launcher"));
+ assertEquals(GlobalTransactionRole.Participant,
+ GlobalTransactionRole.valueOf("Participant"));
+ }
+
+ @Test
+ public void testValueOfInvalid() {
+ // Test valueOf with invalid name
+ assertThrows(IllegalArgumentException.class,
+ () -> GlobalTransactionRole.valueOf("InvalidRole"),
+ "Should throw IllegalArgumentException for invalid role name");
+
+ assertThrows(IllegalArgumentException.class,
+ () -> GlobalTransactionRole.valueOf("launcher"),
+ "Should throw IllegalArgumentException for lowercase role
name");
+
+ assertThrows(IllegalArgumentException.class,
+ () -> GlobalTransactionRole.valueOf("LAUNCHER"),
+ "Should throw IllegalArgumentException for uppercase role
name");
+ }
+
+ @Test
+ public void testValues() {
+ // Test values method returns correct array
+ GlobalTransactionRole[] values = GlobalTransactionRole.values();
+ assertNotNull(values);
+ assertEquals(2, values.length);
+ assertEquals(GlobalTransactionRole.Launcher, values[0]);
+ assertEquals(GlobalTransactionRole.Participant, values[1]);
+ }
+
+ @Test
+ public void testToString() {
+ // Test toString method (should return the name)
+ assertEquals("Launcher", GlobalTransactionRole.Launcher.toString());
+ assertEquals("Participant",
GlobalTransactionRole.Participant.toString());
+ }
+
+ @Test
+ public void testEqualsAndHashCode() {
+ // Test equals
+ assertEquals(GlobalTransactionRole.Launcher,
GlobalTransactionRole.Launcher);
+ assertEquals(GlobalTransactionRole.Participant,
GlobalTransactionRole.Participant);
+ assertNotEquals(GlobalTransactionRole.Launcher,
GlobalTransactionRole.Participant);
+ assertNotEquals(GlobalTransactionRole.Participant,
GlobalTransactionRole.Launcher);
+
+ // Test hashCode consistency
+ assertEquals(GlobalTransactionRole.Launcher.hashCode(),
+ GlobalTransactionRole.Launcher.hashCode());
+ assertEquals(GlobalTransactionRole.Participant.hashCode(),
+ GlobalTransactionRole.Participant.hashCode());
+ }
+
+ @Test
+ public void testCompatibilityWithApacheSeata() {
+ // Test that enum names match Apache Seata equivalents
+ // This ensures compatibility when converting between packages
+
+ for (GlobalTransactionRole role : GlobalTransactionRole.values()) {
+ // Test that Apache Seata has equivalent enum value
+ assertDoesNotThrow(() -> {
+
org.apache.seata.tm.api.GlobalTransactionRole.valueOf(role.name());
+ }, "Apache Seata should have equivalent role: " + role.name());
+ }
+
+ // Test reverse compatibility
+ for (org.apache.seata.tm.api.GlobalTransactionRole apacheRole :
+ org.apache.seata.tm.api.GlobalTransactionRole.values()) {
+ assertDoesNotThrow(() -> {
+ GlobalTransactionRole.valueOf(apacheRole.name());
+ }, "Compatible package should have equivalent role: " +
apacheRole.name());
+ }
+ }
+
+ @Test
+ public void testEnumCompareTo() {
+ // Test enum comparison (based on ordinal)
+
assertTrue(GlobalTransactionRole.Launcher.compareTo(GlobalTransactionRole.Participant)
< 0,
+ "Launcher should come before Participant");
+
assertTrue(GlobalTransactionRole.Participant.compareTo(GlobalTransactionRole.Launcher)
> 0,
+ "Participant should come after Launcher");
+ assertEquals(0,
GlobalTransactionRole.Launcher.compareTo(GlobalTransactionRole.Launcher),
+ "Same enum should compare equal");
+ }
+
+ @Test
+ public void testSemanticMeaning() {
+ // Test the semantic meaning based on documentation comments
+
+ // Launcher: The one begins the current global transaction
+ assertNotNull(GlobalTransactionRole.Launcher,
+ "Launcher role should exist for transaction initiator");
+
+ // Participant: The one just joins into a existing global transaction
+ assertNotNull(GlobalTransactionRole.Participant,
+ "Participant role should exist for transaction joiner");
+
+ // Ensure they are different
+ assertNotEquals(GlobalTransactionRole.Launcher,
GlobalTransactionRole.Participant,
+ "Launcher and Participant should be different roles");
+ }
+}
\ No newline at end of file
diff --git
a/compatible/src/test/java/io/seata/tm/api/GlobalTransactionTest.java
b/compatible/src/test/java/io/seata/tm/api/GlobalTransactionTest.java
new file mode 100644
index 0000000000..998cb086ed
--- /dev/null
+++ b/compatible/src/test/java/io/seata/tm/api/GlobalTransactionTest.java
@@ -0,0 +1,305 @@
+/*
+ * 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.exception.TransactionException;
+import io.seata.core.model.GlobalStatus;
+import io.seata.tm.api.transaction.SuspendedResourcesHolder;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test cases for GlobalTransaction interface compatibility.
+ */
+public class GlobalTransactionTest {
+
+ @Test
+ public void testDeprecatedAnnotation() {
+ // Test that GlobalTransaction is marked as @Deprecated
+
assertTrue(GlobalTransaction.class.isAnnotationPresent(Deprecated.class),
+ "GlobalTransaction should be marked as @Deprecated");
+ }
+
+ @Test
+ public void testIsInterface() {
+ // Test that GlobalTransaction is an interface
+ assertTrue(GlobalTransaction.class.isInterface(),
+ "GlobalTransaction should be an interface");
+ }
+
+ @Test
+ public void testExtendsBaseTransaction() {
+ // Test that GlobalTransaction extends BaseTransaction
+
assertTrue(org.apache.seata.tm.api.BaseTransaction.class.isAssignableFrom(GlobalTransaction.class),
+ "GlobalTransaction should extend BaseTransaction");
+ }
+
+ @Test
+ public void testBeginMethods() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test begin() method
+ doNothing().when(mockTransaction).begin();
+ assertDoesNotThrow(() -> mockTransaction.begin(),
+ "begin() should not throw exception");
+ verify(mockTransaction).begin();
+
+ // Test begin(int timeout) method
+ doNothing().when(mockTransaction).begin(anyInt());
+ assertDoesNotThrow(() -> mockTransaction.begin(30000),
+ "begin(timeout) should not throw exception");
+ verify(mockTransaction).begin(30000);
+
+ // Test begin(int timeout, String name) method
+ doNothing().when(mockTransaction).begin(anyInt(), anyString());
+ assertDoesNotThrow(() -> mockTransaction.begin(30000,
"test-transaction"),
+ "begin(timeout, name) should not throw exception");
+ verify(mockTransaction).begin(30000, "test-transaction");
+ }
+
+ @Test
+ public void testCommitMethod() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test commit() method
+ doNothing().when(mockTransaction).commit();
+ assertDoesNotThrow(() -> mockTransaction.commit(),
+ "commit() should not throw exception");
+ verify(mockTransaction).commit();
+ }
+
+ @Test
+ public void testRollbackMethod() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test rollback() method
+ doNothing().when(mockTransaction).rollback();
+ assertDoesNotThrow(() -> mockTransaction.rollback(),
+ "rollback() should not throw exception");
+ verify(mockTransaction).rollback();
+ }
+
+ @Test
+ public void testSuspendMethods() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+ SuspendedResourcesHolder mockHolder =
Mockito.mock(SuspendedResourcesHolder.class);
+
+ // Test suspend() method
+ when(mockTransaction.suspend()).thenReturn(mockHolder);
+ SuspendedResourcesHolder result = mockTransaction.suspend();
+ assertSame(mockHolder, result, "suspend() should return the mock
holder");
+ verify(mockTransaction).suspend();
+
+ // Test suspend(boolean clean) method
+ when(mockTransaction.suspend(anyBoolean())).thenReturn(mockHolder);
+ SuspendedResourcesHolder result2 = mockTransaction.suspend(true);
+ assertSame(mockHolder, result2, "suspend(clean) should return the mock
holder");
+ verify(mockTransaction).suspend(true);
+ }
+
+ @Test
+ public void testResumeMethod() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+ SuspendedResourcesHolder mockHolder =
Mockito.mock(SuspendedResourcesHolder.class);
+
+ // Test resume() method
+
doNothing().when(mockTransaction).resume(any(SuspendedResourcesHolder.class));
+ assertDoesNotThrow(() -> mockTransaction.resume(mockHolder),
+ "resume() should not throw exception");
+ verify(mockTransaction).resume(mockHolder);
+ }
+
+ @Test
+ public void testGetStatusMethod() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test getStatus() method
+ when(mockTransaction.getStatus()).thenReturn(GlobalStatus.Begin);
+ GlobalStatus status = mockTransaction.getStatus();
+ assertEquals(GlobalStatus.Begin, status, "getStatus() should return
Begin status");
+ verify(mockTransaction).getStatus();
+ }
+
+ @Test
+ public void testGetXidMethod() {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test getXid() method
+ String testXid = "test-xid-123";
+ when(mockTransaction.getXid()).thenReturn(testXid);
+ String xid = mockTransaction.getXid();
+ assertEquals(testXid, xid, "getXid() should return the test XID");
+ verify(mockTransaction).getXid();
+ }
+
+ @Test
+ public void testGlobalReportMethod() throws TransactionException {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test globalReport() method
+
doNothing().when(mockTransaction).globalReport(any(GlobalStatus.class));
+ assertDoesNotThrow(() ->
mockTransaction.globalReport(GlobalStatus.Committed),
+ "globalReport() should not throw exception");
+ verify(mockTransaction).globalReport(GlobalStatus.Committed);
+ }
+
+ @Test
+ public void testGetLocalStatusMethod() {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test getLocalStatus() method
+ when(mockTransaction.getLocalStatus()).thenReturn(GlobalStatus.Begin);
+ GlobalStatus localStatus = mockTransaction.getLocalStatus();
+ assertEquals(GlobalStatus.Begin, localStatus, "getLocalStatus() should
return Begin status");
+ verify(mockTransaction).getLocalStatus();
+ }
+
+ @Test
+ public void testGetGlobalTransactionRoleMethod() {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test getGlobalTransactionRole() method
+
when(mockTransaction.getGlobalTransactionRole()).thenReturn(GlobalTransactionRole.Launcher);
+ GlobalTransactionRole role =
mockTransaction.getGlobalTransactionRole();
+ assertEquals(GlobalTransactionRole.Launcher, role,
"getGlobalTransactionRole() should return Launcher role");
+ verify(mockTransaction).getGlobalTransactionRole();
+ }
+
+ @Test
+ public void testGetCreateTimeMethod() {
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test getCreateTime() method
+ long createTime = System.currentTimeMillis();
+ when(mockTransaction.getCreateTime()).thenReturn(createTime);
+ long time = mockTransaction.getCreateTime();
+ assertEquals(createTime, time, "getCreateTime() should return the
create time");
+ verify(mockTransaction).getCreateTime();
+ }
+
+ @Test
+ public void testTransactionExceptionHandling() throws TransactionException
{
+ // Create a mock implementation
+ GlobalTransaction mockTransaction =
Mockito.mock(GlobalTransaction.class);
+
+ // Test that methods can throw TransactionException
+ TransactionException testException = new TransactionException("Test
exception");
+
+ doThrow(testException).when(mockTransaction).begin();
+ assertThrows(TransactionException.class, () -> mockTransaction.begin(),
+ "begin() should be able to throw TransactionException");
+
+ doThrow(testException).when(mockTransaction).commit();
+ assertThrows(TransactionException.class, () ->
mockTransaction.commit(),
+ "commit() should be able to throw TransactionException");
+
+ doThrow(testException).when(mockTransaction).rollback();
+ assertThrows(TransactionException.class, () ->
mockTransaction.rollback(),
+ "rollback() should be able to throw TransactionException");
+
+ doThrow(testException).when(mockTransaction).suspend();
+ assertThrows(TransactionException.class, () ->
mockTransaction.suspend(),
+ "suspend() should be able to throw TransactionException");
+
+ doThrow(testException).when(mockTransaction).resume(any());
+ assertThrows(TransactionException.class, () ->
mockTransaction.resume(null),
+ "resume() should be able to throw TransactionException");
+
+ when(mockTransaction.getStatus()).thenThrow(testException);
+ assertThrows(TransactionException.class, () ->
mockTransaction.getStatus(),
+ "getStatus() should be able to throw TransactionException");
+
+ doThrow(testException).when(mockTransaction).globalReport(any());
+ assertThrows(TransactionException.class, () ->
mockTransaction.globalReport(GlobalStatus.Committed),
+ "globalReport() should be able to throw TransactionException");
+ }
+
+ @Test
+ public void testInterfaceMethods() {
+ // Test that all required methods are present in the interface
+ try {
+ // Test method signatures exist
+ GlobalTransaction.class.getMethod("begin");
+ GlobalTransaction.class.getMethod("begin", int.class);
+ GlobalTransaction.class.getMethod("begin", int.class,
String.class);
+ GlobalTransaction.class.getMethod("commit");
+ GlobalTransaction.class.getMethod("rollback");
+ GlobalTransaction.class.getMethod("suspend");
+ GlobalTransaction.class.getMethod("suspend", boolean.class);
+ GlobalTransaction.class.getMethod("resume",
SuspendedResourcesHolder.class);
+ GlobalTransaction.class.getMethod("getStatus");
+ GlobalTransaction.class.getMethod("getXid");
+ GlobalTransaction.class.getMethod("globalReport",
GlobalStatus.class);
+ GlobalTransaction.class.getMethod("getLocalStatus");
+ GlobalTransaction.class.getMethod("getGlobalTransactionRole");
+ GlobalTransaction.class.getMethod("getCreateTime");
+
+ } catch (NoSuchMethodException e) {
+ fail("Required method not found in GlobalTransaction interface: "
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testMethodReturnTypes() {
+ // Test that methods have correct return types
+ try {
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("begin").getReturnType());
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("begin", int.class).getReturnType());
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("begin", int.class,
String.class).getReturnType());
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("commit").getReturnType());
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("rollback").getReturnType());
+ assertEquals(SuspendedResourcesHolder.class,
GlobalTransaction.class.getMethod("suspend").getReturnType());
+ assertEquals(SuspendedResourcesHolder.class,
GlobalTransaction.class.getMethod("suspend", boolean.class).getReturnType());
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("resume",
SuspendedResourcesHolder.class).getReturnType());
+ assertEquals(GlobalStatus.class,
GlobalTransaction.class.getMethod("getStatus").getReturnType());
+ assertEquals(String.class,
GlobalTransaction.class.getMethod("getXid").getReturnType());
+ assertEquals(void.class,
GlobalTransaction.class.getMethod("globalReport",
GlobalStatus.class).getReturnType());
+ assertEquals(GlobalStatus.class,
GlobalTransaction.class.getMethod("getLocalStatus").getReturnType());
+ assertEquals(GlobalTransactionRole.class,
GlobalTransaction.class.getMethod("getGlobalTransactionRole").getReturnType());
+ assertEquals(long.class,
GlobalTransaction.class.getMethod("getCreateTime").getReturnType());
+
+ } catch (NoSuchMethodException e) {
+ fail("Method not found when testing return types: " +
e.getMessage());
+ }
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]