This is an automated email from the ASF dual-hosted git repository.
zfeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-seata-go.git
The following commit(s) were added to refs/heads/master by this push:
new 72f847e4 test: add unit tests for pkg/constant, pkg/client, and pkg/tm
(#988)
72f847e4 is described below
commit 72f847e472a22aa9cf512c20b90aac36f2997bf7
Author: 深几许 <[email protected]>
AuthorDate: Sun Nov 16 13:13:02 2025 +0800
test: add unit tests for pkg/constant, pkg/client, and pkg/tm (#988)
* test: add unit tests for pkg/constant, pkg/client, and pkg/tm
- Add comprehensive tests for constant values and types
- Add client initialization function tests
- Add tm config, constants, and init function tests
* bugfix:remove race condition in TestInitTm_Concurrency tes
* fix: ci
---------
Co-authored-by: jimin <[email protected]>
---
pkg/client/client_test.go | 160 +++++++++++++++++++++++++++++++++++++++
pkg/constant/context_test.go | 146 ++++++++++++++++++++++++++++++++++++
pkg/tm/config_test.go | 175 +++++++++++++++++++++++++++++++++++++++++++
pkg/tm/constant_test.go | 135 +++++++++++++++++++++++++++++++++
pkg/tm/init_test.go | 170 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 786 insertions(+)
diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go
new file mode 100644
index 00000000..8af3cd14
--- /dev/null
+++ b/pkg/client/client_test.go
@@ -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 client
+
+import (
+ "sync"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "seata.apache.org/seata-go/pkg/tm"
+)
+
+func TestInit(t *testing.T) {
+ // Test that Init() function exists
+ assert.NotNil(t, Init)
+}
+
+func TestInitPath(t *testing.T) {
+ // Test that InitPath() function exists
+ assert.NotNil(t, InitPath)
+}
+
+func TestOnceInstances(t *testing.T) {
+ // Test that sync.Once instances are properly initialized
+ assert.NotNil(t, &onceInitTmClient, "onceInitTmClient should be
initialized")
+ assert.NotNil(t, &onceInitRmClient, "onceInitRmClient should be
initialized")
+ assert.NotNil(t, &onceInitDatasource, "onceInitDatasource should be
initialized")
+ assert.NotNil(t, &onceInitRegistry, "onceInitRegistry should be
initialized")
+}
+
+func TestInitTmClientFunction(t *testing.T) {
+ // Create a minimal config for testing
+ cfg := &Config{
+ ClientConfig: ClientConfig{
+ TmConfig: tm.TmConfig{
+ CommitRetryCount: 5,
+ RollbackRetryCount: 5,
+ },
+ },
+ }
+
+ // The function should exist and be callable
+ assert.NotNil(t, initTmClient)
+
+ // Test that the function has the correct signature
+ assert.IsType(t, func(*Config) {}, initTmClient)
+
+ // We won't actually call it to avoid dependency issues
+ _ = cfg
+}
+
+func TestInitRmClientFunction(t *testing.T) {
+ // Create a minimal config for testing
+ cfg := &Config{
+ ApplicationID: "test-app",
+ TxServiceGroup: "test-group",
+ }
+
+ // The function should exist and be callable
+ assert.NotNil(t, initRmClient)
+
+ // Test that the function has the correct signature
+ assert.IsType(t, func(*Config) {}, initRmClient)
+
+ // We won't actually call it to avoid dependency issues
+ _ = cfg
+}
+
+func TestInitDatasourceFunction(t *testing.T) {
+ // The function should exist and be callable
+ assert.NotNil(t, initDatasource)
+
+ // Test that the function has the correct signature
+ assert.IsType(t, func() {}, initDatasource)
+}
+
+func TestInitRegistryFunction(t *testing.T) {
+ // Create a minimal config for testing
+ cfg := &Config{
+ ApplicationID: "test-app",
+ TxServiceGroup: "test-group",
+ }
+
+ // The function should exist and be callable
+ assert.NotNil(t, initRegistry)
+
+ // Test that the function has the correct signature
+ assert.IsType(t, func(*Config) {}, initRegistry)
+
+ // We won't actually call it to avoid dependency issues
+ _ = cfg
+}
+
+func TestInitRemotingFunction(t *testing.T) {
+ // Create a minimal config for testing
+ cfg := &Config{
+ ApplicationID: "test-app",
+ TxServiceGroup: "test-group",
+ }
+
+ // The function should exist and be callable
+ assert.NotNil(t, initRemoting)
+
+ // Test that the function has the correct signature
+ assert.IsType(t, func(*Config) {}, initRemoting)
+
+ // We won't actually call it to avoid dependency issues
+ _ = cfg
+}
+
+func TestSyncOnceTypes(t *testing.T) {
+ // Test that all once variables are of type sync.Once
+ assert.IsType(t, sync.Once{}, onceInitTmClient)
+ assert.IsType(t, sync.Once{}, onceInitRmClient)
+ assert.IsType(t, sync.Once{}, onceInitDatasource)
+ assert.IsType(t, sync.Once{}, onceInitRegistry)
+}
+
+func TestConfigStruct(t *testing.T) {
+ // Test that we can create a Config struct
+ cfg := &Config{}
+ assert.NotNil(t, cfg)
+
+ // Test that Config has expected fields
+ cfg.ApplicationID = "test"
+ cfg.TxServiceGroup = "test-group"
+ cfg.Enabled = true
+
+ assert.Equal(t, "test", cfg.ApplicationID)
+ assert.Equal(t, "test-group", cfg.TxServiceGroup)
+ assert.True(t, cfg.Enabled)
+}
+
+func TestClientConfigStruct(t *testing.T) {
+ // Test that we can create a ClientConfig struct
+ clientCfg := &ClientConfig{}
+ assert.NotNil(t, clientCfg)
+
+ // Test that ClientConfig has TmConfig field
+ clientCfg.TmConfig = tm.TmConfig{
+ CommitRetryCount: 3,
+ }
+
+ assert.Equal(t, 3, clientCfg.TmConfig.CommitRetryCount)
+}
diff --git a/pkg/constant/context_test.go b/pkg/constant/context_test.go
new file mode 100644
index 00000000..22576855
--- /dev/null
+++ b/pkg/constant/context_test.go
@@ -0,0 +1,146 @@
+/*
+ * 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 constant
+
+import (
+ "testing"
+)
+
+func TestConstants(t *testing.T) {
+ tests := []struct {
+ name string
+ constant string
+ expected string
+ }{
+ {"ActionStartTime", ActionStartTime, "action-start-time"},
+ {"HostName", HostName, "host-name"},
+ {"ActionContext", ActionContext, "actionContext"},
+ {"PrepareMethod", PrepareMethod, "sys::prepare"},
+ {"CommitMethod", CommitMethod, "sys::commit"},
+ {"RollbackMethod", RollbackMethod, "sys::rollback"},
+ {"ActionName", ActionName, "actionName"},
+ {"SeataXidKey", SeataXidKey, "SEATA_XID"},
+ {"XidKey", XidKey, "TX_XID"},
+ {"XidKeyLowercase", XidKeyLowercase, "tx_xid"},
+ {"MdcXidKey", MdcXidKey, "X-TX-XID"},
+ {"MdcBranchIDKey", MdcBranchIDKey, "X-TX-BRANCH-ID"},
+ {"BranchTypeKey", BranchTypeKey, "TX_BRANCH_TYPE"},
+ {"GlobalLockKey", GlobalLockKey, "TX_LOCK"},
+ {"SeataFilterKey", SeataFilterKey, "seataDubboFilter"},
+ {"SeataVersion", SeataVersion, "1.1.0"},
+ {"TccBusinessActionContextParameter",
TccBusinessActionContextParameter, "tccParam"},
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ if test.constant != test.expected {
+ t.Errorf("Expected %s to be %s, but got %s",
test.name, test.expected, test.constant)
+ }
+ })
+ }
+}
+
+func TestConstantTypes(t *testing.T) {
+ // Test that constants are of string type
+ constants := []interface{}{
+ ActionStartTime,
+ HostName,
+ ActionContext,
+ PrepareMethod,
+ CommitMethod,
+ RollbackMethod,
+ ActionName,
+ SeataXidKey,
+ XidKey,
+ XidKeyLowercase,
+ MdcXidKey,
+ MdcBranchIDKey,
+ BranchTypeKey,
+ GlobalLockKey,
+ SeataFilterKey,
+ SeataVersion,
+ TccBusinessActionContextParameter,
+ }
+
+ for i, constant := range constants {
+ if _, ok := constant.(string); !ok {
+ t.Errorf("Constant at index %d is not of string type",
i)
+ }
+ }
+}
+
+func TestConstantValues(t *testing.T) {
+ // Test that constants are not empty
+ constants := map[string]string{
+ "ActionStartTime": ActionStartTime,
+ "HostName": HostName,
+ "ActionContext": ActionContext,
+ "PrepareMethod": PrepareMethod,
+ "CommitMethod": CommitMethod,
+ "RollbackMethod": RollbackMethod,
+ "ActionName": ActionName,
+ "SeataXidKey": SeataXidKey,
+ "XidKey": XidKey,
+ "XidKeyLowercase": XidKeyLowercase,
+ "MdcXidKey": MdcXidKey,
+ "MdcBranchIDKey": MdcBranchIDKey,
+ "BranchTypeKey": BranchTypeKey,
+ "GlobalLockKey": GlobalLockKey,
+ "SeataFilterKey": SeataFilterKey,
+ "SeataVersion": SeataVersion,
+ "TccBusinessActionContextParameter":
TccBusinessActionContextParameter,
+ }
+
+ for name, value := range constants {
+ if value == "" {
+ t.Errorf("Constant %s should not be empty", name)
+ }
+ }
+}
+
+func TestMethodConstants(t *testing.T) {
+ // Test that method constants follow expected format
+ methodConstants := []string{PrepareMethod, CommitMethod, RollbackMethod}
+ expectedPrefix := "sys::"
+
+ for _, method := range methodConstants {
+ if len(method) <= len(expectedPrefix) ||
method[:len(expectedPrefix)] != expectedPrefix {
+ t.Errorf("Method constant %s should start with %s",
method, expectedPrefix)
+ }
+ }
+}
+
+func TestXidConstants(t *testing.T) {
+ // Test XID related constants
+ xidConstants := map[string]string{
+ "SeataXidKey": SeataXidKey,
+ "XidKey": XidKey,
+ "XidKeyLowercase": XidKeyLowercase,
+ "MdcXidKey": MdcXidKey,
+ "MdcBranchIDKey": MdcBranchIDKey,
+ }
+
+ for name, value := range xidConstants {
+ if value == "" {
+ t.Errorf("XID constant %s should not be empty", name)
+ }
+ if name == "XidKeyLowercase" && value != "tx_xid" {
+ t.Errorf("XidKeyLowercase should be lowercase: %s",
value)
+ }
+ }
+}
diff --git a/pkg/tm/config_test.go b/pkg/tm/config_test.go
new file mode 100644
index 00000000..eac8f55b
--- /dev/null
+++ b/pkg/tm/config_test.go
@@ -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 tm
+
+import (
+ "flag"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestTmConfig_DefaultValues(t *testing.T) {
+ cfg := &TmConfig{}
+
+ // Test that zero values are correct
+ assert.Equal(t, 0, cfg.CommitRetryCount)
+ assert.Equal(t, 0, cfg.RollbackRetryCount)
+ assert.Equal(t, time.Duration(0), cfg.DefaultGlobalTransactionTimeout)
+ assert.False(t, cfg.DegradeCheck)
+ assert.Equal(t, 0, cfg.DegradeCheckPeriod)
+ assert.Equal(t, time.Duration(0), cfg.DegradeCheckAllowTimes)
+ assert.Equal(t, 0, cfg.InterceptorOrder)
+}
+
+func TestTmConfig_SetValues(t *testing.T) {
+ cfg := &TmConfig{
+ CommitRetryCount: 10,
+ RollbackRetryCount: 5,
+ DefaultGlobalTransactionTimeout: 30 * time.Second,
+ DegradeCheck: true,
+ DegradeCheckPeriod: 1000,
+ DegradeCheckAllowTimes: 5 * time.Second,
+ InterceptorOrder: 100,
+ }
+
+ assert.Equal(t, 10, cfg.CommitRetryCount)
+ assert.Equal(t, 5, cfg.RollbackRetryCount)
+ assert.Equal(t, 30*time.Second, cfg.DefaultGlobalTransactionTimeout)
+ assert.True(t, cfg.DegradeCheck)
+ assert.Equal(t, 1000, cfg.DegradeCheckPeriod)
+ assert.Equal(t, 5*time.Second, cfg.DegradeCheckAllowTimes)
+ assert.Equal(t, 100, cfg.InterceptorOrder)
+}
+
+func TestTmConfig_RegisterFlagsWithPrefix(t *testing.T) {
+ cfg := &TmConfig{}
+ flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
+
+ // Test that the function doesn't panic
+ assert.NotPanics(t, func() {
+ cfg.RegisterFlagsWithPrefix("", flagSet)
+ })
+
+ // Test that the function doesn't panic with a prefix
+ assert.NotPanics(t, func() {
+ cfg.RegisterFlagsWithPrefix("tm", flagSet)
+ })
+}
+
+func TestTmConfig_RegisterFlagsWithPrefix_FunctionExists(t *testing.T) {
+ cfg := &TmConfig{}
+
+ // Test that the method exists
+ assert.NotNil(t, cfg.RegisterFlagsWithPrefix)
+
+ // Test that it has the correct signature
+ assert.IsType(t, func(string, *flag.FlagSet) {},
cfg.RegisterFlagsWithPrefix)
+}
+
+func TestTmConfig_FieldTypes(t *testing.T) {
+ cfg := &TmConfig{}
+
+ // Test that fields have correct types
+ assert.IsType(t, int(0), cfg.CommitRetryCount)
+ assert.IsType(t, int(0), cfg.RollbackRetryCount)
+ assert.IsType(t, time.Duration(0), cfg.DefaultGlobalTransactionTimeout)
+ assert.IsType(t, false, cfg.DegradeCheck)
+ assert.IsType(t, int(0), cfg.DegradeCheckPeriod)
+ assert.IsType(t, time.Duration(0), cfg.DegradeCheckAllowTimes)
+ assert.IsType(t, int(0), cfg.InterceptorOrder)
+}
+
+func TestTmConfig_StructInstantiation(t *testing.T) {
+ // Test struct instantiation with different methods
+ cfg1 := TmConfig{}
+ cfg2 := &TmConfig{}
+ cfg3 := new(TmConfig)
+
+ assert.NotNil(t, &cfg1)
+ assert.NotNil(t, cfg2)
+ assert.NotNil(t, cfg3)
+
+ // All should have zero values
+ assert.Equal(t, 0, cfg1.CommitRetryCount)
+ assert.Equal(t, 0, cfg2.CommitRetryCount)
+ assert.Equal(t, 0, cfg3.CommitRetryCount)
+}
+
+func TestTmConfig_FieldAssignment(t *testing.T) {
+ cfg := &TmConfig{}
+
+ // Test field assignment
+ cfg.CommitRetryCount = 5
+ cfg.RollbackRetryCount = 3
+ cfg.DefaultGlobalTransactionTimeout = 60 * time.Second
+ cfg.DegradeCheck = true
+ cfg.DegradeCheckPeriod = 2000
+ cfg.DegradeCheckAllowTimes = 10 * time.Second
+ cfg.InterceptorOrder = -1000
+
+ assert.Equal(t, 5, cfg.CommitRetryCount)
+ assert.Equal(t, 3, cfg.RollbackRetryCount)
+ assert.Equal(t, 60*time.Second, cfg.DefaultGlobalTransactionTimeout)
+ assert.True(t, cfg.DegradeCheck)
+ assert.Equal(t, 2000, cfg.DegradeCheckPeriod)
+ assert.Equal(t, 10*time.Second, cfg.DegradeCheckAllowTimes)
+ assert.Equal(t, -1000, cfg.InterceptorOrder)
+}
+
+func TestTmConfig_NegativeValues(t *testing.T) {
+ cfg := &TmConfig{
+ CommitRetryCount: -1,
+ RollbackRetryCount: -5,
+ DefaultGlobalTransactionTimeout: -1 * time.Second,
+ DegradeCheck: false,
+ DegradeCheckPeriod: -100,
+ DegradeCheckAllowTimes: -5 * time.Second,
+ InterceptorOrder: -2147483648,
+ }
+
+ // Negative values should be preserved
+ assert.Equal(t, -1, cfg.CommitRetryCount)
+ assert.Equal(t, -5, cfg.RollbackRetryCount)
+ assert.Equal(t, -1*time.Second, cfg.DefaultGlobalTransactionTimeout)
+ assert.False(t, cfg.DegradeCheck)
+ assert.Equal(t, -100, cfg.DegradeCheckPeriod)
+ assert.Equal(t, -5*time.Second, cfg.DegradeCheckAllowTimes)
+ assert.Equal(t, -2147483648, cfg.InterceptorOrder)
+}
+
+func TestTmConfig_ExtremeValues(t *testing.T) {
+ cfg := &TmConfig{
+ CommitRetryCount: 2147483647, // Max int32
+ RollbackRetryCount: 2147483647, // Max int32
+ DefaultGlobalTransactionTimeout: 24 * time.Hour,
+ DegradeCheck: true,
+ DegradeCheckPeriod: 2147483647, // Max int32
+ DegradeCheckAllowTimes: 24 * time.Hour,
+ InterceptorOrder: 2147483647, // Max int32
+ }
+
+ assert.Equal(t, 2147483647, cfg.CommitRetryCount)
+ assert.Equal(t, 2147483647, cfg.RollbackRetryCount)
+ assert.Equal(t, 24*time.Hour, cfg.DefaultGlobalTransactionTimeout)
+ assert.True(t, cfg.DegradeCheck)
+ assert.Equal(t, 2147483647, cfg.DegradeCheckPeriod)
+ assert.Equal(t, 24*time.Hour, cfg.DegradeCheckAllowTimes)
+ assert.Equal(t, 2147483647, cfg.InterceptorOrder)
+}
diff --git a/pkg/tm/constant_test.go b/pkg/tm/constant_test.go
new file mode 100644
index 00000000..ae865a10
--- /dev/null
+++ b/pkg/tm/constant_test.go
@@ -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 tm
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGlobalTransactionRole(t *testing.T) {
+ tests := []struct {
+ name string
+ role GlobalTransactionRole
+ expected string
+ }{
+ {"UnKnow", UnKnow, "UnKnow"},
+ {"Launcher", Launcher, "Launcher"},
+ {"Participant", Participant, "Participant"},
+ {"Invalid role", GlobalTransactionRole(99), "UnKnow"},
+ {"Negative role", GlobalTransactionRole(-1), "UnKnow"},
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ assert.Equal(t, test.expected, test.role.String())
+ })
+ }
+}
+
+func TestGlobalTransactionRoleValues(t *testing.T) {
+ assert.Equal(t, GlobalTransactionRole(0), UnKnow)
+ assert.Equal(t, GlobalTransactionRole(1), Launcher)
+ assert.Equal(t, GlobalTransactionRole(2), Participant)
+}
+
+func TestPropagation(t *testing.T) {
+ tests := []struct {
+ name string
+ propagation Propagation
+ expected string
+ }{
+ {"Required", Required, "Required"},
+ {"RequiresNew", RequiresNew, "RequiresNew"},
+ {"NotSupported", NotSupported, "NotSupported"},
+ {"Supports", Supports, "Supports"},
+ {"Never", Never, "Never"},
+ {"Mandatory", Mandatory, "Mandatory"},
+ {"Invalid propagation", Propagation(99), "UnKnow"},
+ {"Negative propagation", Propagation(-1), "UnKnow"},
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ assert.Equal(t, test.expected,
test.propagation.String())
+ })
+ }
+}
+
+func TestPropagationValues(t *testing.T) {
+ assert.Equal(t, Propagation(0), Required)
+ assert.Equal(t, Propagation(1), RequiresNew)
+ assert.Equal(t, Propagation(2), NotSupported)
+ assert.Equal(t, Propagation(3), Supports)
+ assert.Equal(t, Propagation(4), Never)
+ assert.Equal(t, Propagation(5), Mandatory)
+}
+
+func TestTransactionManagerInterface(t *testing.T) {
+ // Test that TransactionManager is an interface
+ var tm TransactionManager
+ assert.Nil(t, tm, "TransactionManager interface should be nil when not
implemented")
+}
+
+func TestGlobalTransactionRoleType(t *testing.T) {
+ // Test that GlobalTransactionRole is an int8
+ var role GlobalTransactionRole = 1
+ assert.IsType(t, int8(0), int8(role))
+}
+
+func TestPropagationType(t *testing.T) {
+ // Test that Propagation is an int8
+ var prop Propagation = 1
+ assert.IsType(t, int8(0), int8(prop))
+}
+
+func TestRoleConstants(t *testing.T) {
+ roles := []GlobalTransactionRole{UnKnow, Launcher, Participant}
+
+ // Test that all roles are unique
+ seen := make(map[GlobalTransactionRole]bool)
+ for _, role := range roles {
+ assert.False(t, seen[role], "Role %d should be unique", role)
+ seen[role] = true
+ }
+}
+
+func TestPropagationConstants(t *testing.T) {
+ propagations := []Propagation{Required, RequiresNew, NotSupported,
Supports, Never, Mandatory}
+
+ // Test that all propagations are unique
+ seen := make(map[Propagation]bool)
+ for _, prop := range propagations {
+ assert.False(t, seen[prop], "Propagation %d should be unique",
prop)
+ seen[prop] = true
+ }
+}
+
+func TestStringMethodsAreIdempotent(t *testing.T) {
+ // Test that calling String() multiple times returns the same result
+ role := Launcher
+ first := role.String()
+ second := role.String()
+ assert.Equal(t, first, second, "String() method should be idempotent")
+
+ prop := Required
+ firstProp := prop.String()
+ secondProp := prop.String()
+ assert.Equal(t, firstProp, secondProp, "String() method should be
idempotent")
+}
diff --git a/pkg/tm/init_test.go b/pkg/tm/init_test.go
new file mode 100644
index 00000000..822aa49a
--- /dev/null
+++ b/pkg/tm/init_test.go
@@ -0,0 +1,170 @@
+/*
+ * 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 tm
+
+import (
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestInitTm(t *testing.T) {
+ // Save original config
+ originalConfig := config
+ defer func() {
+ config = originalConfig
+ }()
+
+ // Test with default config
+ testConfig := TmConfig{
+ CommitRetryCount: 5,
+ RollbackRetryCount: 3,
+ DefaultGlobalTransactionTimeout: 30 * time.Second,
+ DegradeCheck: true,
+ DegradeCheckPeriod: 1000,
+ DegradeCheckAllowTimes: 5 * time.Second,
+ InterceptorOrder: 100,
+ }
+
+ InitTm(testConfig)
+
+ assert.Equal(t, testConfig.CommitRetryCount, config.CommitRetryCount)
+ assert.Equal(t, testConfig.RollbackRetryCount,
config.RollbackRetryCount)
+ assert.Equal(t, testConfig.DefaultGlobalTransactionTimeout,
config.DefaultGlobalTransactionTimeout)
+ assert.Equal(t, testConfig.DegradeCheck, config.DegradeCheck)
+ assert.Equal(t, testConfig.DegradeCheckPeriod,
config.DegradeCheckPeriod)
+ assert.Equal(t, testConfig.DegradeCheckAllowTimes,
config.DegradeCheckAllowTimes)
+ assert.Equal(t, testConfig.InterceptorOrder, config.InterceptorOrder)
+}
+
+func TestInitTm_ZeroConfig(t *testing.T) {
+ // Save original config
+ originalConfig := config
+ defer func() {
+ config = originalConfig
+ }()
+
+ // Test with zero config
+ zeroConfig := TmConfig{}
+
+ InitTm(zeroConfig)
+
+ assert.Equal(t, 0, config.CommitRetryCount)
+ assert.Equal(t, 0, config.RollbackRetryCount)
+ assert.Equal(t, time.Duration(0),
config.DefaultGlobalTransactionTimeout)
+ assert.False(t, config.DegradeCheck)
+ assert.Equal(t, 0, config.DegradeCheckPeriod)
+ assert.Equal(t, time.Duration(0), config.DegradeCheckAllowTimes)
+ assert.Equal(t, 0, config.InterceptorOrder)
+}
+
+func TestInitTm_MultipleInits(t *testing.T) {
+ // Save original config
+ originalConfig := config
+ defer func() {
+ config = originalConfig
+ }()
+
+ // Test multiple initializations
+ firstConfig := TmConfig{
+ CommitRetryCount: 10,
+ RollbackRetryCount: 5,
+ DegradeCheck: true,
+ }
+
+ secondConfig := TmConfig{
+ CommitRetryCount: 20,
+ RollbackRetryCount: 15,
+ DegradeCheck: false,
+ }
+
+ // First initialization
+ InitTm(firstConfig)
+ assert.Equal(t, 10, config.CommitRetryCount)
+ assert.Equal(t, 5, config.RollbackRetryCount)
+ assert.True(t, config.DegradeCheck)
+
+ // Second initialization should override
+ InitTm(secondConfig)
+ assert.Equal(t, 20, config.CommitRetryCount)
+ assert.Equal(t, 15, config.RollbackRetryCount)
+ assert.False(t, config.DegradeCheck)
+}
+
+func TestInitTm_ConfigIsolation(t *testing.T) {
+ // Save original config
+ originalConfig := config
+ defer func() {
+ config = originalConfig
+ }()
+
+ // Test that modifying the original config doesn't affect the stored
config
+ testConfig := TmConfig{
+ CommitRetryCount: 5,
+ }
+
+ InitTm(testConfig)
+ assert.Equal(t, 5, config.CommitRetryCount)
+
+ // Modify original config
+ testConfig.CommitRetryCount = 10
+
+ // Stored config should not be affected
+ assert.Equal(t, 5, config.CommitRetryCount)
+}
+
+func TestInitTm_ExtremeValues(t *testing.T) {
+ // Save original config
+ originalConfig := config
+ defer func() {
+ config = originalConfig
+ }()
+
+ // Test with extreme values
+ extremeConfig := TmConfig{
+ CommitRetryCount: 2147483647, // Max int32
+ RollbackRetryCount: -2147483648, // Min int32
+ DefaultGlobalTransactionTimeout: 24 * time.Hour, // Large
duration
+ DegradeCheck: true,
+ DegradeCheckPeriod: 0,
+ DegradeCheckAllowTimes: time.Nanosecond, // Small
duration
+ InterceptorOrder: -1000000,
+ }
+
+ InitTm(extremeConfig)
+
+ assert.Equal(t, 2147483647, config.CommitRetryCount)
+ assert.Equal(t, -2147483648, config.RollbackRetryCount)
+ assert.Equal(t, 24*time.Hour, config.DefaultGlobalTransactionTimeout)
+ assert.True(t, config.DegradeCheck)
+ assert.Equal(t, 0, config.DegradeCheckPeriod)
+ assert.Equal(t, time.Nanosecond, config.DegradeCheckAllowTimes)
+ assert.Equal(t, -1000000, config.InterceptorOrder)
+}
+
+func TestGlobalConfigVariable(t *testing.T) {
+ // Test that the global config variable exists and is accessible
+ assert.NotNil(t, &config, "Global config variable should exist")
+
+ // Test that it's initially a zero value
+ var zeroConfig TmConfig
+ if config == zeroConfig {
+ assert.True(t, true, "Global config starts as zero value")
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]