Skip to content

Commit 0dbeec4

Browse files
committed
add suit test
Signed-off-by: Allen Li <liyuchen223@gmail.com>
1 parent 8dcb5c6 commit 0dbeec4

File tree

3 files changed

+846
-0
lines changed

3 files changed

+846
-0
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
//
2+
// Copyright 2022 IBM Corporation
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
package bootstrap
18+
19+
import (
20+
"errors"
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
"github.com/stretchr/testify/require"
25+
26+
apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3"
27+
)
28+
29+
// resetConfigMerger clears the package-level configMerger between tests to
30+
// prevent state leaking across test cases.
31+
func resetConfigMerger() {
32+
configMerger = nil
33+
}
34+
35+
// TestSetConfigMerger_NilByDefault verifies that before SetConfigMerger is called
36+
// the package-level merger is nil and mergeConfigs returns the base config unchanged.
37+
func TestSetConfigMerger_NilByDefault(t *testing.T) {
38+
resetConfigMerger()
39+
40+
b := &Bootstrap{
41+
CSData: apiv3.CSData{ServicesNs: "ibm-common-services"},
42+
}
43+
cs := &apiv3.CommonService{}
44+
45+
result, err := b.mergeConfigs("base-config", cs)
46+
require.NoError(t, err)
47+
assert.Equal(t, "base-config", result,
48+
"when no merger is set, mergeConfigs must return the base config unchanged")
49+
}
50+
51+
// TestSetConfigMerger_InjectsFunction verifies that SetConfigMerger stores the
52+
// provided function and that mergeConfigs delegates to it.
53+
func TestSetConfigMerger_InjectsFunction(t *testing.T) {
54+
resetConfigMerger()
55+
defer resetConfigMerger()
56+
57+
called := false
58+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
59+
called = true
60+
return "merged-" + baseConfig, nil
61+
})
62+
63+
b := &Bootstrap{
64+
CSData: apiv3.CSData{ServicesNs: "ibm-common-services"},
65+
}
66+
cs := &apiv3.CommonService{}
67+
68+
result, err := b.mergeConfigs("base", cs)
69+
require.NoError(t, err)
70+
assert.True(t, called, "the injected merger function must be called")
71+
assert.Equal(t, "merged-base", result)
72+
}
73+
74+
// TestSetConfigMerger_PassesServicesNs verifies that mergeConfigs forwards the
75+
// Bootstrap's ServicesNs to the injected merger function.
76+
func TestSetConfigMerger_PassesServicesNs(t *testing.T) {
77+
resetConfigMerger()
78+
defer resetConfigMerger()
79+
80+
var capturedNs string
81+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
82+
capturedNs = servicesNs
83+
return baseConfig, nil
84+
})
85+
86+
b := &Bootstrap{
87+
CSData: apiv3.CSData{ServicesNs: "my-services-ns"},
88+
}
89+
cs := &apiv3.CommonService{}
90+
91+
_, err := b.mergeConfigs("config", cs)
92+
require.NoError(t, err)
93+
assert.Equal(t, "my-services-ns", capturedNs,
94+
"mergeConfigs must pass Bootstrap.CSData.ServicesNs to the merger function")
95+
}
96+
97+
// TestSetConfigMerger_PassesCSInstance verifies that mergeConfigs forwards the
98+
// CommonService instance to the injected merger function.
99+
func TestSetConfigMerger_PassesCSInstance(t *testing.T) {
100+
resetConfigMerger()
101+
defer resetConfigMerger()
102+
103+
var capturedCS *apiv3.CommonService
104+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
105+
capturedCS = cs
106+
return baseConfig, nil
107+
})
108+
109+
b := &Bootstrap{
110+
CSData: apiv3.CSData{ServicesNs: "ibm-common-services"},
111+
}
112+
cs := &apiv3.CommonService{}
113+
cs.Name = "common-service"
114+
cs.Namespace = "ibm-common-services"
115+
116+
_, err := b.mergeConfigs("config", cs)
117+
require.NoError(t, err)
118+
require.NotNil(t, capturedCS)
119+
assert.Equal(t, "common-service", capturedCS.Name)
120+
assert.Equal(t, "ibm-common-services", capturedCS.Namespace)
121+
}
122+
123+
// TestSetConfigMerger_PropagatesError verifies that an error returned by the
124+
// injected merger function is propagated back to the caller of mergeConfigs.
125+
func TestSetConfigMerger_PropagatesError(t *testing.T) {
126+
resetConfigMerger()
127+
defer resetConfigMerger()
128+
129+
mergeErr := errors.New("merge failed")
130+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
131+
return "", mergeErr
132+
})
133+
134+
b := &Bootstrap{
135+
CSData: apiv3.CSData{ServicesNs: "ibm-common-services"},
136+
}
137+
cs := &apiv3.CommonService{}
138+
139+
result, err := b.mergeConfigs("config", cs)
140+
assert.Error(t, err)
141+
assert.Equal(t, mergeErr, err)
142+
assert.Empty(t, result)
143+
}
144+
145+
// TestSetConfigMerger_Overwrite verifies that calling SetConfigMerger a second
146+
// time replaces the previously registered function.
147+
func TestSetConfigMerger_Overwrite(t *testing.T) {
148+
resetConfigMerger()
149+
defer resetConfigMerger()
150+
151+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
152+
return "first", nil
153+
})
154+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
155+
return "second", nil
156+
})
157+
158+
b := &Bootstrap{
159+
CSData: apiv3.CSData{ServicesNs: "ibm-common-services"},
160+
}
161+
cs := &apiv3.CommonService{}
162+
163+
result, err := b.mergeConfigs("config", cs)
164+
require.NoError(t, err)
165+
assert.Equal(t, "second", result,
166+
"the second SetConfigMerger call must overwrite the first")
167+
}
168+
169+
// TestMergeConfigs_SingleStageNoRaceCondition is the key integration test for the
170+
// Single-Stage Creation feature. It verifies that a single mergeConfigs call
171+
// produces a complete merged result — there is no intermediate state where the
172+
// base config is returned before CS values are applied.
173+
func TestMergeConfigs_SingleStageNoRaceCondition(t *testing.T) {
174+
resetConfigMerger()
175+
defer resetConfigMerger()
176+
177+
// Simulate the real merger: it always returns a "complete" config that
178+
// includes both base and CS values in one shot.
179+
SetConfigMerger(func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error) {
180+
// In production this would be MergeConfigs(); here we just verify the
181+
// contract: the result must differ from the bare base config, proving
182+
// CS values were applied in the same call.
183+
return baseConfig + "+cs-values", nil
184+
})
185+
186+
b := &Bootstrap{
187+
CSData: apiv3.CSData{ServicesNs: "ibm-common-services"},
188+
}
189+
cs := &apiv3.CommonService{}
190+
191+
result, err := b.mergeConfigs("base-opcon", cs)
192+
require.NoError(t, err)
193+
194+
// The result must already contain CS values — no second call needed.
195+
assert.Equal(t, "base-opcon+cs-values", result,
196+
"single mergeConfigs call must return complete config with CS values applied")
197+
assert.NotEqual(t, "base-opcon", result,
198+
"result must not be the bare base config (that would indicate an incomplete intermediate state)")
199+
}
200+
201+
// Made with Bob

0 commit comments

Comments
 (0)