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

jimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-seata-k8s.git


The following commit(s) were added to refs/heads/master by this push:
     new e944657  optimize: add some UT for pkg (#50)
e944657 is described below

commit e944657c37f958542beb4d70ada8487c9b891583
Author: jimin <[email protected]>
AuthorDate: Sat Jan 10 18:00:20 2026 +0800

    optimize: add some UT for pkg (#50)
---
 pkg/finalizer/finalizer_manager_test.go | 239 ++++++++++++++++++++++++++++++--
 pkg/seata/generators_test.go            | 131 +++++++++++++++++
 pkg/seata/synchronizers_test.go         | 107 ++++++++++++++
 pkg/webhook/validating_webhook_test.go  | 110 +++++++++++++++
 4 files changed, 578 insertions(+), 9 deletions(-)

diff --git a/pkg/finalizer/finalizer_manager_test.go 
b/pkg/finalizer/finalizer_manager_test.go
index 8e8f290..90af00c 100644
--- a/pkg/finalizer/finalizer_manager_test.go
+++ b/pkg/finalizer/finalizer_manager_test.go
@@ -19,16 +19,33 @@ package finalizer
 
 import (
        "context"
+       "testing"
+       "time"
+
        seatav1 "github.com/apache/seata-k8s/api/v1"
+       seatav1alpha1 "github.com/apache/seata-k8s/api/v1alpha1"
        "github.com/go-logr/logr"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/runtime"
        "k8s.io/apimachinery/pkg/types"
        "sigs.k8s.io/controller-runtime/pkg/client/fake"
-       "testing"
-       "time"
 )
 
+func TestNewFinalizerManager(t *testing.T) {
+       scheme := createTestScheme()
+       fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
+       logger := logr.Discard()
+
+       fm := NewFinalizerManager(fakeClient, logger)
+
+       if fm == nil {
+               t.Fatal("NewFinalizerManager should not return nil")
+       }
+       if fm.Client == nil {
+               t.Error("FinalizerManager.Client should not be nil")
+       }
+}
+
 func TestFinalizerManager_AddFinalizer(t *testing.T) {
        testCases := []struct {
                name        string
@@ -285,23 +302,227 @@ func TestFinalizerManager_IsBeingDeleted(t *testing.T) {
 }
 
 func TestFinalizerManager_GetNamespacedName(t *testing.T) {
-       seataServer := &seatav1.SeataServer{
+       testCases := []struct {
+               name        string
+               server      interface{}
+               expected    types.NamespacedName
+       }{
+               {
+                       name: "v1 SeataServer",
+                       server: &seatav1.SeataServer{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Name:      "test-seata",
+                                       Namespace: "default",
+                               },
+                       },
+                       expected: types.NamespacedName{Name: "test-seata", 
Namespace: "default"},
+               },
+               {
+                       name: "v1alpha1 SeataServer",
+                       server: &seatav1alpha1.SeataServer{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Name:      "test-alpha",
+                                       Namespace: "test-ns",
+                               },
+                       },
+                       expected: types.NamespacedName{Name: "test-alpha", 
Namespace: "test-ns"},
+               },
+               {
+                       name:     "unsupported type",
+                       server:   "invalid",
+                       expected: types.NamespacedName{},
+               },
+       }
+
+       fm := &FinalizerManager{
+               Client: nil,
+               Log:    logr.Discard(),
+       }
+
+       for _, tc := range testCases {
+               t.Run(tc.name, func(t *testing.T) {
+                       result := fm.GetNamespacedName(tc.server)
+                       if result != tc.expected {
+                               t.Errorf("expected %v, got %v", tc.expected, 
result)
+                       }
+               })
+       }
+}
+
+func TestFinalizerManager_GetDeletionTimestamp(t *testing.T) {
+       now := metav1.Now()
+
+       testCases := []struct {
+               name     string
+               server   interface{}
+               expected interface{}
+       }{
+               {
+                       name: "v1 SeataServer with deletion timestamp",
+                       server: &seatav1.SeataServer{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Name:              "test-seata",
+                                       Namespace:         "default",
+                                       DeletionTimestamp: &now,
+                               },
+                       },
+                       expected: &now,
+               },
+               {
+                       name: "v1alpha1 SeataServer with deletion timestamp",
+                       server: &seatav1alpha1.SeataServer{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Name:              "test-alpha",
+                                       Namespace:         "default",
+                                       DeletionTimestamp: &now,
+                               },
+                       },
+                       expected: &now,
+               },
+               {
+                       name:     "unsupported type",
+                       server:   "invalid",
+                       expected: nil,
+               },
+       }
+
+       fm := &FinalizerManager{
+               Client: nil,
+               Log:    logr.Discard(),
+       }
+
+       for _, tc := range testCases {
+               t.Run(tc.name, func(t *testing.T) {
+                       result := fm.GetDeletionTimestamp(tc.server)
+                       if result != tc.expected {
+                               t.Errorf("expected %v, got %v", tc.expected, 
result)
+                       }
+               })
+       }
+}
+
+func TestFinalizerManager_AddFinalizer_V1Alpha1(t *testing.T) {
+       scheme := runtime.NewScheme()
+       _ = seatav1.AddToScheme(scheme)
+       _ = seatav1alpha1.AddToScheme(scheme)
+
+       seataServer := &seatav1alpha1.SeataServer{
                ObjectMeta: metav1.ObjectMeta{
-                       Name:      "test-seata",
-                       Namespace: "default",
+                       Name:       "test-seata-alpha",
+                       Namespace:  "default",
+                       Finalizers: []string{},
                },
        }
 
+       fakeClient := fake.NewClientBuilder().
+               WithScheme(scheme).
+               WithObjects(seataServer).
+               Build()
+
+       fm := &FinalizerManager{
+               Client: fakeClient,
+               Log:    logr.Discard(),
+       }
+
+       ctx := context.Background()
+       err := fm.AddFinalizer(ctx, seataServer, SeataFinalizerName)
+
+       if err != nil {
+               t.Errorf("AddFinalizer for v1alpha1 failed: %v", err)
+       }
+
+       if !fm.HasFinalizer(seataServer, SeataFinalizerName) {
+               t.Errorf("finalizer %s not found after adding", 
SeataFinalizerName)
+       }
+}
+
+func TestFinalizerManager_RemoveFinalizer_V1Alpha1(t *testing.T) {
+       scheme := runtime.NewScheme()
+       _ = seatav1.AddToScheme(scheme)
+       _ = seatav1alpha1.AddToScheme(scheme)
+
+       seataServer := &seatav1alpha1.SeataServer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:       "test-seata-alpha",
+                       Namespace:  "default",
+                       Finalizers: []string{SeataFinalizerName, 
"other-finalizer"},
+               },
+       }
+
+       fakeClient := fake.NewClientBuilder().
+               WithScheme(scheme).
+               WithObjects(seataServer).
+               Build()
+
+       fm := &FinalizerManager{
+               Client: fakeClient,
+               Log:    logr.Discard(),
+       }
+
+       ctx := context.Background()
+       err := fm.RemoveFinalizer(ctx, seataServer, SeataFinalizerName)
+
+       if err != nil {
+               t.Errorf("RemoveFinalizer for v1alpha1 failed: %v", err)
+       }
+
+       hasFinalizer := fm.HasFinalizer(seataServer, SeataFinalizerName)
+       if hasFinalizer {
+               t.Errorf("expected finalizer to be removed")
+       }
+}
+
+func TestFinalizerManager_AddFinalizer_UnsupportedType(t *testing.T) {
+       scheme := createTestScheme()
+       fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
+
+       fm := &FinalizerManager{
+               Client: fakeClient,
+               Log:    logr.Discard(),
+       }
+
+       err := fm.AddFinalizer(context.Background(), "invalid-type", 
SeataFinalizerName)
+       if err == nil {
+               t.Error("Expected error for unsupported type, got nil")
+       }
+}
+
+func TestFinalizerManager_RemoveFinalizer_UnsupportedType(t *testing.T) {
+       scheme := createTestScheme()
+       fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
+
+       fm := &FinalizerManager{
+               Client: fakeClient,
+               Log:    logr.Discard(),
+       }
+
+       err := fm.RemoveFinalizer(context.Background(), "invalid-type", 
SeataFinalizerName)
+       if err == nil {
+               t.Error("Expected error for unsupported type, got nil")
+       }
+}
+
+func TestFinalizerManager_HasFinalizer_UnsupportedType(t *testing.T) {
        fm := &FinalizerManager{
                Client: nil,
                Log:    logr.Discard(),
        }
 
-       result := fm.GetNamespacedName(seataServer)
-       expected := types.NamespacedName{Name: "test-seata", Namespace: 
"default"}
+       result := fm.HasFinalizer("invalid-type", SeataFinalizerName)
+       if result {
+               t.Error("Expected false for unsupported type")
+       }
+}
+
+func TestFinalizerManager_IsBeingDeleted_UnsupportedType(t *testing.T) {
+       fm := &FinalizerManager{
+               Client: nil,
+               Log:    logr.Discard(),
+       }
 
-       if result != expected {
-               t.Errorf("expected %v, got %v", expected, result)
+       result := fm.IsBeingDeleted("invalid-type")
+       if result {
+               t.Error("Expected false for unsupported type")
        }
 }
 
diff --git a/pkg/seata/generators_test.go b/pkg/seata/generators_test.go
index 3abfb6d..c9dbc12 100644
--- a/pkg/seata/generators_test.go
+++ b/pkg/seata/generators_test.go
@@ -340,3 +340,134 @@ func TestBuildEnvVars_WithMultipleReplicas(t *testing.T) {
        }
 }
 
+func TestMakeStatefulSet_WithEmptyLabelsAndAnnotations(t *testing.T) {
+       seataServer := &seatav1alpha1.SeataServer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "test-seata",
+                       Namespace: "default",
+                       UID:       types.UID("test-uid"),
+               },
+               Spec: seatav1alpha1.SeataServerSpec{
+                       ContainerSpec: seatav1alpha1.ContainerSpec{
+                               ContainerName: "seata",
+                               Image:         "seata:latest",
+                       },
+                       ServiceName: "seata-svc",
+                       Replicas:    1,
+                       Ports: seatav1alpha1.Ports{
+                               ServicePort: 8091,
+                               ConsolePort: 7091,
+                               RaftPort:    9091,
+                       },
+                       Persistence: seatav1alpha1.Persistence{
+                               PersistentVolumeClaimSpec: 
apiv1.PersistentVolumeClaimSpec{
+                                       Resources: apiv1.ResourceRequirements{
+                                               Requests: apiv1.ResourceList{
+                                                       apiv1.ResourceStorage: 
resource.MustParse("1Gi"),
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       sts := MakeStatefulSet(seataServer)
+
+       if sts == nil {
+               t.Fatal("MakeStatefulSet returned nil")
+       }
+
+       if sts.Name != "test-seata" {
+               t.Errorf("Expected name 'test-seata', got '%s'", sts.Name)
+       }
+}
+
+func TestMakeHeadlessService_WithDifferentPorts(t *testing.T) {
+       seataServer := &seatav1alpha1.SeataServer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "custom-seata",
+                       Namespace: "custom-ns",
+               },
+               Spec: seatav1alpha1.SeataServerSpec{
+                       ServiceName: "custom-service",
+                       Ports: seatav1alpha1.Ports{
+                               ServicePort: 8888,
+                               ConsolePort: 7777,
+                               RaftPort:    9999,
+                       },
+               },
+       }
+
+       svc := MakeHeadlessService(seataServer)
+
+       if svc.Name != "custom-service" {
+               t.Errorf("Expected service name 'custom-service', got '%s'", 
svc.Name)
+       }
+
+       if svc.Namespace != "custom-ns" {
+               t.Errorf("Expected namespace 'custom-ns', got '%s'", 
svc.Namespace)
+       }
+
+       portMap := make(map[string]int32)
+       for _, port := range svc.Spec.Ports {
+               portMap[port.Name] = port.Port
+       }
+
+       if portMap["service-port"] != 8888 {
+               t.Errorf("Expected service-port 8888, got %d", 
portMap["service-port"])
+       }
+       if portMap["console-port"] != 7777 {
+               t.Errorf("Expected console-port 7777, got %d", 
portMap["console-port"])
+       }
+       if portMap["raft-port"] != 9999 {
+               t.Errorf("Expected raft-port 9999, got %d", 
portMap["raft-port"])
+       }
+}
+
+func TestBuildEntrypointScript_WithDifferentServiceName(t *testing.T) {
+       seataServer := &seatav1alpha1.SeataServer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "my-seata",
+                       Namespace: "production",
+               },
+               Spec: seatav1alpha1.SeataServerSpec{
+                       ServiceName: "my-custom-service",
+               },
+       }
+
+       script := buildEntrypointScript(seataServer)
+
+       if !strings.Contains(script, "my-custom-service") {
+               t.Errorf("Script should contain service name 
'my-custom-service', got: %s", script)
+       }
+
+       if !strings.Contains(script, "export SEATA_IP") {
+               t.Error("Script should contain SEATA_IP export")
+       }
+}
+
+func TestBuildEnvVars_EmptyEnv(t *testing.T) {
+       seataServer := &seatav1alpha1.SeataServer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "test-seata",
+                       Namespace: "default",
+               },
+               Spec: seatav1alpha1.SeataServerSpec{
+                       ContainerSpec: seatav1alpha1.ContainerSpec{
+                               Env: []apiv1.EnvVar{},
+                       },
+                       Ports: seatav1alpha1.Ports{
+                               ServicePort: 8091,
+                               ConsolePort: 7091,
+                               RaftPort:    9091,
+                       },
+               },
+       }
+
+       envs := buildEnvVars(seataServer)
+
+       // Should still have base environment variables
+       if len(envs) < 5 {
+               t.Errorf("Expected at least 5 base env vars, got %d", len(envs))
+       }
+}
diff --git a/pkg/seata/synchronizers_test.go b/pkg/seata/synchronizers_test.go
index bcae8d2..545bd6b 100644
--- a/pkg/seata/synchronizers_test.go
+++ b/pkg/seata/synchronizers_test.go
@@ -262,3 +262,110 @@ func TestSyncStatefulSet_WithMultipleContainers(t 
*testing.T) {
        }
 }
 
+func TestSyncService_WithSinglePort(t *testing.T) {
+       curr := &apiv1.Service{
+               Spec: apiv1.ServiceSpec{
+                       Ports: []apiv1.ServicePort{
+                               {Name: "old-port", Port: 8080},
+                               {Name: "another-port", Port: 9090},
+                       },
+               },
+       }
+
+       next := &apiv1.Service{
+               Spec: apiv1.ServiceSpec{
+                       Ports: []apiv1.ServicePort{
+                               {Name: "new-port", Port: 8091},
+                       },
+               },
+       }
+
+       SyncService(curr, next)
+
+       if len(curr.Spec.Ports) != 1 {
+               t.Errorf("Expected 1 port after sync, got %d", 
len(curr.Spec.Ports))
+       }
+
+       if curr.Spec.Ports[0].Name != "new-port" {
+               t.Errorf("Expected port name 'new-port', got '%s'", 
curr.Spec.Ports[0].Name)
+       }
+
+       if curr.Spec.Ports[0].Port != 8091 {
+               t.Errorf("Expected port 8091, got %d", curr.Spec.Ports[0].Port)
+       }
+}
+
+func TestSyncStatefulSet_ReplicasScaleUp(t *testing.T) {
+       replicas1 := int32(1)
+       replicas5 := int32(5)
+
+       curr := &appsv1.StatefulSet{
+               Spec: appsv1.StatefulSetSpec{
+                       Replicas: &replicas1,
+                       Template: apiv1.PodTemplateSpec{
+                               Spec: apiv1.PodSpec{
+                                       Containers: []apiv1.Container{
+                                               {Name: "app", Image: "app:v1"},
+                                       },
+                               },
+                       },
+               },
+       }
+
+       next := &appsv1.StatefulSet{
+               Spec: appsv1.StatefulSetSpec{
+                       Replicas: &replicas5,
+                       Template: apiv1.PodTemplateSpec{
+                               Spec: apiv1.PodSpec{
+                                       Containers: []apiv1.Container{
+                                               {Name: "app", Image: "app:v1"},
+                                       },
+                               },
+                       },
+               },
+       }
+
+       SyncStatefulSet(curr, next)
+
+       if *curr.Spec.Replicas != 5 {
+               t.Errorf("Expected 5 replicas after scale up, got %d", 
*curr.Spec.Replicas)
+       }
+}
+
+func TestSyncStatefulSet_ReplicasScaleDown(t *testing.T) {
+       replicas5 := int32(5)
+       replicas2 := int32(2)
+
+       curr := &appsv1.StatefulSet{
+               Spec: appsv1.StatefulSetSpec{
+                       Replicas: &replicas5,
+                       Template: apiv1.PodTemplateSpec{
+                               Spec: apiv1.PodSpec{
+                                       Containers: []apiv1.Container{
+                                               {Name: "app", Image: "app:v1"},
+                                       },
+                               },
+                       },
+               },
+       }
+
+       next := &appsv1.StatefulSet{
+               Spec: appsv1.StatefulSetSpec{
+                       Replicas: &replicas2,
+                       Template: apiv1.PodTemplateSpec{
+                               Spec: apiv1.PodSpec{
+                                       Containers: []apiv1.Container{
+                                               {Name: "app", Image: "app:v1"},
+                                       },
+                               },
+                       },
+               },
+       }
+
+       SyncStatefulSet(curr, next)
+
+       if *curr.Spec.Replicas != 2 {
+               t.Errorf("Expected 2 replicas after scale down, got %d", 
*curr.Spec.Replicas)
+       }
+}
+
diff --git a/pkg/webhook/validating_webhook_test.go 
b/pkg/webhook/validating_webhook_test.go
index 12ff24d..9cffb35 100644
--- a/pkg/webhook/validating_webhook_test.go
+++ b/pkg/webhook/validating_webhook_test.go
@@ -344,6 +344,13 @@ func TestValidateEnvironmentVariables(t *testing.T) {
                        },
                        valid: false,
                },
+               {
+                       name: "invalid too long name",
+                       envs: []apiv1.EnvVar{
+                               {Name: "VAR_" + string(make([]byte, 250)), 
Value: "value"},
+                       },
+                       valid: false,
+               },
        }
 
        for _, tc := range testCases {
@@ -356,6 +363,43 @@ func TestValidateEnvironmentVariables(t *testing.T) {
        }
 }
 
+func TestValidateResourceQuantity(t *testing.T) {
+       testCases := []struct {
+               name         string
+               resourceName string
+               quantity     resource.Quantity
+               valid        bool
+       }{
+               {
+                       name:         "valid positive quantity",
+                       resourceName: "cpu",
+                       quantity:     resource.MustParse("100m"),
+                       valid:        true,
+               },
+               {
+                       name:         "valid zero quantity",
+                       resourceName: "memory",
+                       quantity:     resource.MustParse("0"),
+                       valid:        true,
+               },
+               {
+                       name:         "invalid negative quantity",
+                       resourceName: "cpu",
+                       quantity:     resource.MustParse("-100m"),
+                       valid:        false,
+               },
+       }
+
+       for _, tc := range testCases {
+               t.Run(tc.name, func(t *testing.T) {
+                       err := validateResourceQuantity(tc.resourceName, 
tc.quantity)
+                       if (err == nil) != tc.valid {
+                               t.Errorf("expected valid=%v, got error=%v", 
tc.valid, err)
+                       }
+               })
+       }
+}
+
 func TestValidateSeataServer(t *testing.T) {
        testCases := []struct {
                name   string
@@ -411,6 +455,11 @@ func TestValidateSeataServer(t *testing.T) {
                        },
                        valid: false,
                },
+               {
+                       name:   "nil SeataServer",
+                       server: nil,
+                       valid:  false,
+               },
        }
 
        for _, tc := range testCases {
@@ -422,3 +471,64 @@ func TestValidateSeataServer(t *testing.T) {
                })
        }
 }
+
+func TestValidateResourceRequirements(t *testing.T) {
+       testCases := []struct {
+               name         string
+               requirements apiv1.ResourceRequirements
+               valid        bool
+       }{
+               {
+                       name: "valid resource requirements",
+                       requirements: apiv1.ResourceRequirements{
+                               Requests: apiv1.ResourceList{
+                                       apiv1.ResourceCPU:    
resource.MustParse("100m"),
+                                       apiv1.ResourceMemory: 
resource.MustParse("128Mi"),
+                               },
+                               Limits: apiv1.ResourceList{
+                                       apiv1.ResourceCPU:    
resource.MustParse("1000m"),
+                                       apiv1.ResourceMemory: 
resource.MustParse("1Gi"),
+                               },
+                       },
+                       valid: true,
+               },
+               {
+                       name: "CPU limit less than request",
+                       requirements: apiv1.ResourceRequirements{
+                               Requests: apiv1.ResourceList{
+                                       apiv1.ResourceCPU: 
resource.MustParse("1000m"),
+                               },
+                               Limits: apiv1.ResourceList{
+                                       apiv1.ResourceCPU: 
resource.MustParse("500m"),
+                               },
+                       },
+                       valid: false,
+               },
+               {
+                       name: "Memory limit less than request",
+                       requirements: apiv1.ResourceRequirements{
+                               Requests: apiv1.ResourceList{
+                                       apiv1.ResourceMemory: 
resource.MustParse("2Gi"),
+                               },
+                               Limits: apiv1.ResourceList{
+                                       apiv1.ResourceMemory: 
resource.MustParse("1Gi"),
+                               },
+                       },
+                       valid: false,
+               },
+               {
+                       name:         "empty resource requirements",
+                       requirements: apiv1.ResourceRequirements{},
+                       valid:        true,
+               },
+       }
+
+       for _, tc := range testCases {
+               t.Run(tc.name, func(t *testing.T) {
+                       err := validateResourceRequirements(tc.requirements)
+                       if (err == nil) != tc.valid {
+                               t.Errorf("expected valid=%v, got error=%v", 
tc.valid, err)
+                       }
+               })
+       }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to