Repository: apecloud/kubeblocks

Issue:
[BUG] Previously updated parameters have been overwritten


Discussion:
@shanshanying: - dup https://github.com/apecloud/kubeblocks/issues/9332

Solution patch:
diff --git a/controllers/dataprotection/utils.go b/controllers/dataprotection/utils.go
index 5cd4b7d6c..1aa42c782 100644
--- a/controllers/dataprotection/utils.go
+++ b/controllers/dataprotection/utils.go
@@ -165,8 +165,11 @@ func GetTargetPods(reqCtx intctrlutil.RequestCtx,
 			if len(selectedPodNames) == 0 || backupType == dpv1alpha1.BackupTypeContinuous {
 				pod = dputils.GetFirstIndexRunningPod(pods)
 			} else {
-				// if already selected target pods and backupType is not Continuous, we should re-use them.
-				pod = dputils.GetPodByName(pods, selectedPodNames[0])
+				// If the target pods have already been selected and the backup type is not Continuous, we should reuse them.
+				pod = &corev1.Pod{}
+				if err = cli.Get(reqCtx.Ctx, client.ObjectKey{Name: selectedPodNames[0], Namespace: reqCtx.Req.Namespace}, pod); err != nil {
+					return nil, err
+				}
 			}
 			if pod != nil {
 				targetPods = append(targetPods, pod)
diff --git a/controllers/parameters/componentdrivenparameter_controller.go b/controllers/parameters/componentdrivenparameter_controller.go
index c1adfe40b..e554c8f66 100644
--- a/controllers/parameters/componentdrivenparameter_controller.go
+++ b/controllers/parameters/componentdrivenparameter_controller.go
@@ -26,6 +26,7 @@ import (
 	"reflect"
 	"slices"
 
+	"github.com/imdario/mergo"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -324,7 +325,7 @@ func resolveInitParametersFromParameterCR(parameterCRs []parametersv1alpha1.Para
 	for _, pcr := range parameterCRs {
 		for _, compParams := range pcr.Spec.ComponentParameters {
 			if compParams.ComponentName == compName {
-				if err := mergeWithOverride(&initParams, compParams.Parameters); err != nil {
+				if err := mergo.Merge(&initParams, compParams.Parameters); err != nil {
 					return nil, err
 				}
 			}
diff --git a/controllers/parameters/parameter_util.go b/controllers/parameters/parameter_util.go
index f549aa61a..6e965feae 100644
--- a/controllers/parameters/parameter_util.go
+++ b/controllers/parameters/parameter_util.go
@@ -84,8 +84,26 @@ func syncReconfiguringPhase(rctx *ReconcileContext, status *parametersv1alpha1.C
 	updateStatus()
 }
 
-func mergeWithOverride(dst, src interface{}) error {
-	return mergo.Merge(dst, src, mergo.WithOverride)
+func mergeWithOverride(item *parametersv1alpha1.ConfigTemplateItemDetail, updatedParameters map[string]parametersv1alpha1.ParametersInFile) error {
+	if item.ConfigFileParams == nil {
+		item.ConfigFileParams = updatedParameters
+		return nil
+	}
+	for key, parameters := range updatedParameters {
+		if _, ok := item.ConfigFileParams[key]; !ok {
+			item.ConfigFileParams[key] = parameters
+			continue
+		}
+		merged := item.ConfigFileParams[key]
+		if parameters.Content != nil {
+			merged.Content = parameters.Content
+		}
+		if err := mergo.Merge(&merged.Parameters, parameters.Parameters, mergo.WithOverride); err != nil {
+			return err
+		}
+		item.ConfigFileParams[key] = merged
+	}
+	return nil
 }
 
 func updateParameters(rctx *ReconcileContext, parameter *parametersv1alpha1.Parameter) error {
@@ -103,7 +121,7 @@ func updateParameters(rctx *ReconcileContext, parameter *parametersv1alpha1.Para
 			status.Phase = parametersv1alpha1.CMergeFailedPhase
 			continue
 		}
-		if err := mergeWithOverride(&item.ConfigFileParams, status.UpdatedParameters); err != nil {
+		if err := mergeWithOverride(item, status.UpdatedParameters); err != nil {
 			status.Phase = parametersv1alpha1.CMergeFailedPhase
 			return err
 		}
diff --git a/pkg/controller/instanceset/instance_template_util.go b/pkg/controller/instanceset/instance_template_util.go
index b173da3d7..832c8fc5a 100644
--- a/pkg/controller/instanceset/instance_template_util.go
+++ b/pkg/controller/instanceset/instance_template_util.go
@@ -53,7 +53,7 @@ func BuildInstanceName2TemplateMap(itsExt *InstanceSetExt) (map[string]*instance
 	allNameTemplateMap := make(map[string]*instanceTemplateExt)
 	var instanceNameList []string
 	for _, template := range instanceTemplateList {
-		ordinalList, err := GetOrdinalListByTemplateName(itsExt.Its, template.Name)
+		ordinalList, err := getOrdinalListByTemplateName(itsExt.Its, template.Name)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/controller/instanceset/instance_util.go b/pkg/controller/instanceset/instance_util.go
index 03ed3fc2b..f5a5a667c 100644
--- a/pkg/controller/instanceset/instance_util.go
+++ b/pkg/controller/instanceset/instance_util.go
@@ -291,7 +291,7 @@ func buildInstanceName2TemplateMap(itsExt *instanceSetExt) (map[string]*instance
 	allNameTemplateMap := make(map[string]*instanceTemplateExt)
 	var instanceNameList []string
 	for _, template := range instanceTemplateList {
-		ordinalList, err := GetOrdinalListByTemplateName(itsExt.its, template.Name)
+		ordinalList, err := getOrdinalListByTemplateName(itsExt.its, template.Name)
 		if err != nil {
 			return nil, err
 		}
@@ -320,7 +320,7 @@ func GenerateAllInstanceNames(parentName string, replicas int32, templates []Ins
 	instanceNameList := make([]string, 0)
 	for _, template := range templates {
 		replicas := template.GetReplicas()
-		ordinalList, err := ConvertOrdinalsToSortedList(template.GetOrdinals())
+		ordinalList, err := convertOrdinalsToSortedList(template.GetOrdinals())
 		if err != nil {
 			return nil, err
 		}
@@ -332,7 +332,7 @@ func GenerateAllInstanceNames(parentName string, replicas int32, templates []Ins
 		totalReplicas += replicas
 	}
 	if totalReplicas < replicas {
-		ordinalList, err := ConvertOrdinalsToSortedList(defaultTemplateOrdinals)
+		ordinalList, err := convertOrdinalsToSortedList(defaultTemplateOrdinals)
 		if err != nil {
 			return nil, err
 		}
@@ -350,17 +350,17 @@ func GenerateAllInstanceNames(parentName string, replicas int32, templates []Ins
 }
 
 func GenerateInstanceNamesFromTemplate(parentName, templateName string, replicas int32, offlineInstances []string, ordinalList []int32) ([]string, error) {
-	instanceNames, err := GenerateInstanceNames(parentName, templateName, replicas, 0, offlineInstances, ordinalList)
+	instanceNames, err := generateInstanceNames(parentName, templateName, replicas, 0, offlineInstances, ordinalList)
 	return instanceNames, err
 }
 
-// GenerateInstanceNames generates instance names based on certain rules:
+// generateInstanceNames generates instance names based on certain rules:
 // The naming convention for instances (pods) based on the Parent Name, InstanceTemplate Name, and ordinal.
 // The constructed instance name follows the pattern: $(parent.name)-$(template.name)-$(ordinal).
-func GenerateInstanceNames(parentName, templateName string,
+func generateInstanceNames(parentName, templateName string,
 	replicas int32, ordinal int32, offlineInstances []string, ordinalList []int32) ([]string, error) {
 	if len(ordinalList) > 0 {
-		return GenerateInstanceNamesWithOrdinalList(parentName, templateName, replicas, offlineInstances, ordinalList)
+		return generateInstanceNamesWithOrdinalList(parentName, templateName, replicas, offlineInstances, ordinalList)
 	}
 	usedNames := sets.New(offlineInstances...)
 	var instanceNameList []string
@@ -382,13 +382,16 @@ func GenerateInstanceNames(parentName, templateName string,
 	return instanceNameList, nil
 }
 
-// GenerateInstanceNamesWithOrdinalList generates instance names based on ordinalList and offlineInstances.
-func GenerateInstanceNamesWithOrdinalList(parentName, templateName string,
+// generateInstanceNamesWithOrdinalList generates instance names based on ordinalList and offlineInstances.
+func generateInstanceNamesWithOrdinalList(parentName, templateName string,
 	replicas int32, offlineInstances []string, ordinalList []int32) ([]string, error) {
 	var instanceNameList []string
 	usedNames := sets.New(offlineInstances...)
 	slices.Sort(ordinalList)
 	for _, ordinal := range ordinalList {
+		if len(instanceNameList) >= int(replicas) {
+			break
+		}
 		var name string
 		if len(templateName) == 0 {
 			name = fmt.Sprintf("%s-%d", parentName, ordinal)
@@ -399,9 +402,6 @@ func GenerateInstanceNamesWithOrdinalList(parentName, templateName string,
 			continue
 		}
 		instanceNameList = append(instanceNameList, name)
-		if len(instanceNameList) == int(replicas) {
-			break
-		}
 	}
 	if int32(len(instanceNameList)) != replicas {
 		errorMessage := fmt.Sprintf("for template '%s', expected %d instance names but generated %d: [%s]",
@@ -411,15 +411,15 @@ func GenerateInstanceNamesWithOrdinalList(parentName, templateName string,
 	return instanceNameList, nil
 }
 
-func GetOrdinalListByTemplateName(its *workloads.InstanceSet, templateName string) ([]int32, error) {
-	ordinals, err := GetOrdinalsByTemplateName(its, templateName)
+func getOrdinalListByTemplateName(its *workloads.InstanceSet, templateName string) ([]int32, error) {
+	ordinals, err := getOrdinalsByTemplateName(its, templateName)
 	if err != nil {
 		return nil, err
 	}
-	return ConvertOrdinalsToSortedList(ordinals)
+	return convertOrdinalsToSortedList(ordinals)
 }
 
-func GetOrdinalsByTemplateName(its *workloads.InstanceSet, templateName string) (kbappsv1.Ordinals, error) {
+func getOrdinalsByTemplateName(its *workloads.InstanceSet, templateName string) (kbappsv1.Ordinals, error) {
 	if templateName == "" {
 		return its.Spec.DefaultTemplateOrdinals, nil
 	}
@@ -431,7 +431,7 @@ func GetOrdinalsByTemplateName(its *workloads.InstanceSet, templateName string)
 	return kbappsv1.Ordinals{}, fmt.Errorf("template %s not found", templateName)
 }
 
-func ConvertOrdinalsToSortedList(ordinals kbappsv1.Ordinals) ([]int32, error) {
+func convertOrdinalsToSortedList(ordinals kbappsv1.Ordinals) ([]int32, error) {
 	ordinalList := sets.New(ordinals.Discrete...)
 	for _, item := range ordinals.Ranges {
 		start := item.Start
diff --git a/pkg/controller/instanceset/reconciler_revision_update.go b/pkg/controller/instanceset/reconciler_revision_update.go
index 74970df75..759223066 100644
--- a/pkg/controller/instanceset/reconciler_revision_update.go
+++ b/pkg/controller/instanceset/reconciler_revision_update.go
@@ -64,7 +64,7 @@ func (r *revisionUpdateReconciler) Reconcile(tree *kubebuilderx.ObjectTree) (kub
 	// build instance revision list from instance templates
 	var instanceRevisionList []instanceRevision
 	for _, template := range instanceTemplateList {
-		ordinalList, err := GetOrdinalListByTemplateName(itsExt.its, template.Name)
+		ordinalList, err := getOrdinalListByTemplateName(itsExt.its, template.Name)
 		if err != nil {
 			return kubebuilderx.Continue, err
 		}



Test patch:
diff --git a/controllers/parameters/parameter_controller_test.go b/controllers/parameters/parameter_controller_test.go
index 9fc46ecc3..bdc28dfdf 100644
--- a/controllers/parameters/parameter_controller_test.go
+++ b/controllers/parameters/parameter_controller_test.go
@@ -26,6 +26,7 @@ import (
 	. "github.com/onsi/gomega"
 
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
@@ -77,12 +78,41 @@ var _ = Describe("Parameter Controller", func() {
 			Eventually(testapps.CheckObj(&testCtx, compParamKey, func(g Gomega, compParameter *parametersv1alpha1.ComponentParameter) {
 				g.Expect(compParameter.Status.ObservedGeneration).Should(BeEquivalentTo(int64(2)))
 				g.Expect(compParameter.Status.Phase).Should(BeEquivalentTo(parametersv1alpha1.CFinishedPhase))
-			}), time.Second*10).Should(Succeed())
+			})).Should(Succeed())
+
+			By("check parameter status")
+			Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(parameterObj), func(g Gomega, parameter *parametersv1alpha1.Parameter) {
+				g.Expect(parameter.Status.Phase).Should(BeEquivalentTo(parametersv1alpha1.CFinishedPhase))
+			})).Should(Succeed())
+
+			By("check component parameters cr")
+			Eventually(testapps.CheckObj(&testCtx, compParamKey, func(g Gomega, compParameter *parametersv1alpha1.ComponentParameter) {
+				item := intctrlutil.GetConfigTemplateItem(&compParameter.Spec, configSpecName)
+				Expect(item).ShouldNot(BeNil())
+				Expect(item.ConfigFileParams[testparameters.MysqlConfigFile].Parameters).Should(HaveKeyWithValue("max_connections", pointer.String("100")))
+				Expect(item.ConfigFileParams[testparameters.MysqlConfigFile].Parameters).Should(HaveKeyWithValue("innodb_buffer_pool_size", pointer.String("1024M")))
+			})).Should(Succeed())
+
+			By("the second update parameters")
+			key = testapps.GetRandomizedKey(comp.Namespace, comp.FullCompName)
+			parameterObj = testparameters.NewParameterFactory(key.Name, key.Namespace, comp.ClusterName, comp.Name).
+				AddParameters("max_connections", "2000").
+				AddParameters("gtid_mode", "OFF").
+				Create(&testCtx).
+				GetObject()
 
 			By("check parameter status")
 			Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(parameterObj), func(g Gomega, parameter *parametersv1alpha1.Parameter) {
 				g.Expect(parameter.Status.Phase).Should(BeEquivalentTo(parametersv1alpha1.CFinishedPhase))
 			})).Should(Succeed())
+
+			By("check component parameter")
+			Eventually(testapps.CheckObj(&testCtx, compParamKey, func(g Gomega, compParameter *parametersv1alpha1.ComponentParameter) {
+				item := intctrlutil.GetConfigTemplateItem(&compParameter.Spec, configSpecName)
+				Expect(item).ShouldNot(BeNil())
+				Expect(item.ConfigFileParams[testparameters.MysqlConfigFile].Parameters).Should(HaveKeyWithValue("max_connections", pointer.String("2000")))
+				Expect(item.ConfigFileParams[testparameters.MysqlConfigFile].Parameters).Should(HaveKeyWithValue("gtid_mode", pointer.String("OFF")))
+			})).Should(Succeed())
 		})
 
 		It("parameters validate fails", func() {
diff --git a/pkg/controller/instanceset/instance_util_test.go b/pkg/controller/instanceset/instance_util_test.go
index d45377e93..9f19af332 100644
--- a/pkg/controller/instanceset/instance_util_test.go
+++ b/pkg/controller/instanceset/instance_util_test.go
@@ -428,6 +428,7 @@ var _ = Describe("instance util test", func() {
 			podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2"}
 			Expect(instanceNameList).Should(Equal(podNamesExpected))
 		})
+
 		It("without OfflineInstances, should work well", func() {
 			parentName := "foo"
 			templateName := "bar"
@@ -459,6 +460,7 @@ var _ = Describe("instance util test", func() {
 			podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2"}
 			Expect(instanceNameList).Should(Equal(podNamesExpected))
 		})
+
 		It("with OfflineInstances, should work well", func() {
 			parentName := "foo"
 			templateName := "bar"
@@ -491,6 +493,34 @@ var _ = Describe("instance util test", func() {
 			podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2"}
 			Expect(instanceNameList).Should(Equal(podNamesExpected))
 		})
+
+		It("w/ ordinals, unmatched replicas", func() {
+			parentName := "foo"
+			templateName := "bar"
+			template := &instanceTemplateExt{
+				Replicas: 5,
+				Name:     templateName,
+			}
+			template2OrdinalList := []int32{0, 1, 2}
+
+			_, err := GenerateInstanceNamesFromTemplate(parentName, template.Name, template.Replicas, nil, template2OrdinalList)
+			Expect(err).ShouldNot(BeNil())
+			Expect(err.Error()).Should(ContainSubstring("expected 5 instance names but generated 3"))
+		})
+
+		It("w/ ordinals, zero replicas", func() {
+			parentName := "foo"
+			templateName := "bar"
+			template := &instanceTemplateExt{
+				Replicas: 0,
+				Name:     templateName,
+			}
+			template2OrdinalList := []int32{0, 1, 2}
+
+			instanceNames, err := GenerateInstanceNamesFromTemplate(parentName, template.Name, template.Replicas, nil, template2OrdinalList)
+			Expect(err).Should(BeNil())
+			Expect(instanceNames).Should(BeEmpty())
+		})
 	})
 
 	Context("GenerateAllInstanceNames", func() {
@@ -513,6 +543,7 @@ var _ = Describe("instance util test", func() {
 			podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2", "foo-foo-0"}
 			Expect(instanceNameList).Should(Equal(podNamesExpected))
 		})
+
 		It("with Ordinals, without offlineInstances", func() {
 			parentName := "foo"
 			defaultTemplateOrdinals := kbappsv1.Ordinals{
@@ -551,6 +582,7 @@ var _ = Describe("instance util test", func() {
 			podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2", "foo-bar-3", "foo-foo-0"}
 			Expect(instanceNameList).Should(Equal(podNamesExpected))
 		})
+
 		It("with templatesOrdinals, with offlineInstances", func() {
 			parentName := "foo"
 			defaultTemplateOrdinals := kbappsv1.Ordinals{
@@ -590,6 +622,7 @@ var _ = Describe("instance util test", func() {
 			podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2", "foo-foo-0"}
 			Expect(instanceNameList).Should(Equal(podNamesExpected))
 		})
+
 		It("with templatesOrdinals, with offlineInstances, replicas error", func() {
 			parentName := "foo"
 			defaultTemplateOrdinals := kbappsv1.Ordinals{
@@ -668,6 +701,12 @@ var _ = Describe("instance util test", func() {
 		errExpected := fmt.Errorf("for template '%s', expected %d instance names but generated %d: [%s]",
 			templateFoo.Name, *templateFoo.Replicas, len(errInstanceNameListExpected), strings.Join(errInstanceNameListExpected, ", "))
 		Expect(err).Should(Equal(errExpected))
+
+		By("zero replicas")
+		templateFoo.Replicas = pointer.Int32(0)
+		instanceNameList, err = GenerateAllInstanceNames(parentName, 0, []InstanceTemplate{templateFoo}, nil, kbappsv1.Ordinals{})
+		Expect(err).Should(BeNil())
+		Expect(len(instanceNameList)).Should(Equal(0))
 	})
 
 	Context("GetOrdinalListByTemplateName", func() {
@@ -709,22 +748,22 @@ var _ = Describe("instance util test", func() {
 			templateNameBar := "bar"
 			templateNameNotFound := "foobar"
 
-			ordinalListDefault, err := GetOrdinalListByTemplateName(its, templateNameDefault)
+			ordinalListDefault, err := getOrdinalListByTemplateName(its, templateNameDefault)
 			Expect(err).Should(BeNil())
 			ordinalListDefaultExpected := []int32{1, 2}
 			Expect(ordinalListDefault).Should(Equal(ordinalListDefaultExpected))
 
-			ordinalListFoo, err := GetOrdinalListByTemplateName(its, templateNameFoo)
+			ordinalListFoo, err := getOrdinalListByTemplateName(its, templateNameFoo)
 			Expect(err).Should(BeNil())
 			ordinalListFooExpected := []int32{0}
 			Expect(ordinalListFoo).Should(Equal(ordinalListFooExpected))
 
-			ordinalListBar, err := GetOrdinalListByTemplateName(its, templateNameBar)
+			ordinalListBar, err := getOrdinalListByTemplateName(its, templateNameBar)
 			Expect(err).Should(BeNil())
 			ordinalListBarExpected := []int32{0, 2, 3}
 			Expect(ordinalListBar).Should(Equal(ordinalListBarExpected))
 
-			ordinalListNotFound, err := GetOrdinalListByTemplateName(its, templateNameNotFound)
+			ordinalListNotFound, err := getOrdinalListByTemplateName(its, templateNameNotFound)
 			Expect(ordinalListNotFound).Should(BeNil())
 			errExpected := fmt.Errorf("template %s not found", templateNameNotFound)
 			Expect(err).Should(Equal(errExpected))
@@ -770,7 +809,7 @@ var _ = Describe("instance util test", func() {
 			templateNameBar := "bar"
 			templateNameNotFound := "foobar"
 
-			ordinalsDefault, err := GetOrdinalsByTemplateName(its, templateNameDefault)
+			ordinalsDefault, err := getOrdinalsByTemplateName(its, templateNameDefault)
 			Expect(err).Should(BeNil())
 			ordinalsDefaultExpected := kbappsv1.Ordinals{
 				Ranges: []kbappsv1.Range{
@@ -782,14 +821,14 @@ var _ = Describe("instance util test", func() {
 			}
 			Expect(ordinalsDefault).Should(Equal(ordinalsDefaultExpected))
 
-			ordinalsFoo, err := GetOrdinalsByTemplateName(its, templateNameFoo)
+			ordinalsFoo, err := getOrdinalsByTemplateName(its, templateNameFoo)
 			Expect(err).Should(BeNil())
 			ordinalsFooExpected := kbappsv1.Ordinals{
 				Discrete: []int32{0},
 			}
 			Expect(ordinalsFoo).Should(Equal(ordinalsFooExpected))
 
-			ordinalsBar, err := GetOrdinalsByTemplateName(its, templateNameBar)
+			ordinalsBar, err := getOrdinalsByTemplateName(its, templateNameBar)
 			Expect(err).Should(BeNil())
 			ordinalsBarExpected := kbappsv1.Ordinals{
 				Ranges: []kbappsv1.Range{
@@ -802,7 +841,7 @@ var _ = Describe("instance util test", func() {
 			}
 			Expect(ordinalsBar).Should(Equal(ordinalsBarExpected))
 
-			ordinalsNotFound, err := GetOrdinalsByTemplateName(its, templateNameNotFound)
+			ordinalsNotFound, err := getOrdinalsByTemplateName(its, templateNameNotFound)
 			Expect(ordinalsNotFound).Should(Equal(kbappsv1.Ordinals{}))
 			errExpected := fmt.Errorf("template %s not found", templateNameNotFound)
 			Expect(err).Should(Equal(errExpected))
@@ -820,10 +859,11 @@ var _ = Describe("instance util test", func() {
 				},
 				Discrete: []int32{0, 6},
 			}
-			ordinalList, err := ConvertOrdinalsToSortedList(ordinals)
+			ordinalList, err := convertOrdinalsToSortedList(ordinals)
 			Expect(err).Should(BeNil())
 			sets.New(ordinalList...).Equal(sets.New[int32](0, 2, 3, 4, 6))
 		})
+
 		It("rightNumber must >= leftNumber", func() {
 			ordinals := kbappsv1.Ordinals{
 				Ranges: []kbappsv1.Range{
@@ -834,7 +874,7 @@ var _ = Describe("instance util test", func() {
 				},
 				Discrete: []int32{0},
 			}
-			ordinalList, err := ConvertOrdinalsToSortedList(ordinals)
+			ordinalList, err := convertOrdinalsToSortedList(ordinals)
 			errExpected := fmt.Errorf("range's end(%v) must >= start(%v)", 2, 4)
 			Expect(err).Should(Equal(errExpected))
 			Expect(ordinalList).Should(BeNil())