Skip to content

Commit edf2339

Browse files
daniel-hutaosteinliber
authored andcommitted
test: add uts for configmanager
Signed-off-by: Daniel Hu <tao.hu@merico.dev>
1 parent aaec055 commit edf2339

6 files changed

Lines changed: 308 additions & 13 deletions

File tree

internal/pkg/configmanager/config.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,22 @@ func (c *Config) getToolsWithVarsFromApp(a app) (Tools, error) {
7373
tools = append(tools, *repoScaffoldingTool)
7474
}
7575

76+
log.Debugf("Have got %d tools from app %s.", len(tools), rawApp.Name)
77+
for i, t := range tools {
78+
log.Debugf("Tool %d: %v", i+1, t)
79+
}
80+
7681
return tools, nil
7782
}
7883

7984
func (c *Config) renderPipelineTemplateMap() error {
80-
templateMap := make(map[string]string)
85+
c.pipelineTemplateMap = make(map[string]string)
8186
for _, pt := range c.PipelineTemplates {
8287
tplBytes, err := yaml.Marshal(pt)
8388
if err != nil {
8489
return err
8590
}
86-
templateMap[pt.Name] = string(tplBytes)
91+
c.pipelineTemplateMap[pt.Name] = string(tplBytes)
8792
}
8893
return nil
8994
}
@@ -98,3 +103,11 @@ func (c *Config) validate() error {
98103
}
99104
return nil
100105
}
106+
107+
func (c *Config) String() string {
108+
bs, err := yaml.Marshal(c)
109+
if err != nil {
110+
return err.Error()
111+
}
112+
return string(bs)
113+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package configmanager
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,263 @@
11
package configmanager_test
22

33
import (
4+
"os"
5+
"path/filepath"
6+
47
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
10+
"github.com/devstream-io/devstream/internal/pkg/configmanager"
511
)
612

13+
const configFileStr = `---
14+
config:
15+
state:
16+
backend: local
17+
options:
18+
stateFile: devstream.state
19+
20+
vars:
21+
foo1: bar1
22+
foo2: bar2
23+
registryType: dockerhub
24+
argocdNamespace: argocd
25+
26+
apps:
27+
- name: service-a
28+
spec:
29+
language: python
30+
framework: django
31+
repo:
32+
scmType: github
33+
owner: devstream-io
34+
org: devstream-io # choose between owner and org
35+
url: github.com/devstream-io/service-a # optional,if url is specified,we can infer scm/owner/org/name from url
36+
apiURL: gitlab.com/some/path/to/your/api # optional, if you want to create a repo from repo template
37+
# if repoTemplate is not empty,we could help user to create repo from scaffoldingRepo
38+
repoTemplate: # optional
39+
scmType: github
40+
owner: devstream-io
41+
org: devstream-io # choose between owner and org
42+
name: dtm-scaffolding-golang
43+
url: github.com/devstream-io/dtm-scaffolding-golang # optional,if url is specified,we can infer scm/owner/org/name from url
44+
ci:
45+
- type: template
46+
templateName: ci-pipeline-for-gh-actions
47+
options: # overwrite options in pipelineTemplates
48+
docker:
49+
registry:
50+
type: [[ registryType ]] # while overridden, use global variables
51+
vars: # optional, use to render vars in template(valid only if the ci.type is template)
52+
dockerUser: dockerUser1
53+
app: service-a
54+
cd:
55+
- type: template
56+
templateName: cd-pipeline-for-argocdapp
57+
options: # overwrite options in pipelineTemplates
58+
destination:
59+
namespace: devstream-io
60+
vars: # optional, use to render vars in template(valid only if the cd.type is template)
61+
app: service-a
62+
63+
tools:
64+
- name: plugin1
65+
instanceID: default
66+
options:
67+
foo1: [[ foo1 ]]
68+
- name: plugin2
69+
instanceID: tluafed
70+
options:
71+
foo: bar
72+
foo2: [[ foo2 ]]
73+
74+
pipelineTemplates:
75+
- name: ci-pipeline-for-gh-actions
76+
type: github-actions # corresponding to a plugin
77+
options:
78+
branch: main # optional, default is main
79+
docker:
80+
registry:
81+
type: dockerhub
82+
username: [[ dockerUser ]]
83+
repository: [[ app ]]
84+
- name: cd-pipeline-for-argocdapp
85+
type: argocdapp
86+
options:
87+
app:
88+
namespace: [[ argocdNamespace ]] # you can use global vars in templates
89+
destination:
90+
server: https://kubernetes.default.svc
91+
namespace: default
92+
source:
93+
valuefile: values.yaml
94+
path: helm/[[ app ]]
95+
repoURL: ${{repo-scaffolding.myapp.outputs.repoURL}}
96+
`
97+
798
var _ = Describe("LoadConfig", func() {
99+
var tmpWorkDir string
100+
101+
tool1 := configmanager.Tool{
102+
Name: "plugin1",
103+
InstanceID: "default",
104+
Options: configmanager.RawOptions{
105+
"foo1": "bar1",
106+
"instanceID": "default",
107+
},
108+
}
109+
110+
tool2 := configmanager.Tool{
111+
Name: "plugin2",
112+
InstanceID: "tluafed",
113+
Options: configmanager.RawOptions{
114+
"foo": "bar",
115+
"foo2": "bar2",
116+
"instanceID": "default1",
117+
},
118+
}
119+
120+
tool3 := configmanager.Tool{
121+
Name: "github-actions",
122+
InstanceID: "service-a",
123+
DependsOn: []string{
124+
"repo-scaffolding.service-a",
125+
},
126+
Options: configmanager.RawOptions{
127+
"pipeline": configmanager.RawOptions{
128+
"docker": configmanager.RawOptions{
129+
"registry": configmanager.RawOptions{
130+
"repository": "service-a",
131+
"type": "dockerhub",
132+
"username": "dockerUser1",
133+
},
134+
},
135+
"branch": "main",
136+
"configLocation": "git@github.com:devstream-io/ci-template.git//github-actions",
137+
},
138+
"scm": configmanager.RawOptions{
139+
"apiURL": "gitlab.com/some/path/to/your/api",
140+
"owner": "devstream-io",
141+
"org": "devstream-io",
142+
"name": "service-a",
143+
"scmType": "github",
144+
"url": "https://github.com/devstream-io/service-a",
145+
},
146+
"instanceID": "service-a",
147+
},
148+
}
149+
150+
tool4 := configmanager.Tool{
151+
Name: "argocdapp",
152+
InstanceID: "service-a",
153+
DependsOn: []string{
154+
"repo-scaffolding.service-a",
155+
},
156+
Options: configmanager.RawOptions{
157+
"pipeline": configmanager.RawOptions{
158+
"destination": configmanager.RawOptions{
159+
"namespace": "devstream-io",
160+
"server": "https://kubernetes.default.svc",
161+
},
162+
"app": configmanager.RawOptions{
163+
"namespace": "argocd",
164+
},
165+
"source": configmanager.RawOptions{
166+
"valuefile": "values.yaml",
167+
"path": "helm/service-a",
168+
"repoURL": "${{repo-scaffolding.myapp.outputs.repoURL}}",
169+
},
170+
"configLocation": "",
171+
},
172+
"scm": configmanager.RawOptions{
173+
"url": "https://github.com/devstream-io/service-a",
174+
"apiURL": "gitlab.com/some/path/to/your/api",
175+
"owner": "devstream-io",
176+
"org": "devstream-io",
177+
"name": "service-a",
178+
"scmType": "github",
179+
},
180+
"instanceID": "service-a",
181+
},
182+
}
183+
184+
tool5 := configmanager.Tool{
185+
Name: "repo-scaffolding",
186+
InstanceID: "service-a",
187+
Options: configmanager.RawOptions{
188+
"destinationRepo": configmanager.RawOptions{
189+
"needAuth": true,
190+
"org": "devstream-io",
191+
"repo": "service-a",
192+
"branch": "main",
193+
"repoType": "github",
194+
"url": "github.com/devstream-io/service-a",
195+
},
196+
"sourceRepo": configmanager.RawOptions{
197+
"repoType": "github",
198+
"url": "github.com/devstream-io/dtm-scaffolding-golang",
199+
"needAuth": true,
200+
"org": "devstream-io",
201+
"repo": "dtm-scaffolding-golang",
202+
"branch": "main",
203+
},
204+
"vars": configmanager.RawOptions{
205+
"foo1": "bar1",
206+
"foo2": "bar2",
207+
"registryType": "dockerhub",
208+
"framework": "django",
209+
"language": "python",
210+
"argocdNamespace": "argocd",
211+
},
212+
"instanceID": "service-a",
213+
},
214+
}
215+
216+
BeforeEach(func() {
217+
tmpWorkDir = GinkgoT().TempDir()
218+
err := os.WriteFile(filepath.Join(tmpWorkDir, "config.yaml"), []byte(configFileStr), 0644)
219+
Expect(err).NotTo(HaveOccurred())
220+
})
221+
222+
When("load a config file", func() {
223+
It("should return 5 tools", func() {
224+
mgr := configmanager.NewManager(filepath.Join(tmpWorkDir, "config.yaml"))
225+
cfg, err := mgr.LoadConfig()
226+
Expect(err).NotTo(HaveOccurred())
227+
Expect(cfg).NotTo(BeNil())
228+
229+
GinkgoWriter.Printf("Config: %v", cfg)
230+
231+
// config/state
232+
Expect(*cfg.Config.State).To(Equal(configmanager.State{
233+
Backend: "local",
234+
Options: configmanager.StateConfigOptions{
235+
StateFile: "devstream.state",
236+
},
237+
}))
238+
239+
// vars
240+
Expect(len(cfg.Vars)).To(Equal(4))
241+
Expect(cfg.Vars["foo1"]).To(Equal("bar1"))
8242

243+
// tools
244+
Expect(len(cfg.Tools)).To(Equal(5))
245+
for _, t := range cfg.Tools {
246+
switch t.Name {
247+
case "plugin1":
248+
Expect(t).Should(Equal(tool1))
249+
case "plugin2":
250+
Expect(t).Should(Equal(tool2))
251+
case "github-actions":
252+
Expect(t).Should(Equal(tool3))
253+
case "argocdapp":
254+
Expect(t).Should(Equal(tool4))
255+
case "repo-scaffolding":
256+
Expect(t).Should(Equal(tool5))
257+
default:
258+
Fail("Unexpected plugin name.")
259+
}
260+
}
261+
})
262+
})
9263
})

internal/pkg/configmanager/tool.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"runtime"
66
"strings"
77

8+
"gopkg.in/yaml.v3"
9+
810
"go.uber.org/multierr"
911

1012
"github.com/devstream-io/devstream/internal/pkg/version"
@@ -45,6 +47,14 @@ func newTool(name, instanceID string, options RawOptions) *Tool {
4547
}
4648
}
4749

50+
func (t *Tool) String() string {
51+
bs, err := yaml.Marshal(t)
52+
if err != nil {
53+
return err.Error()
54+
}
55+
return string(bs)
56+
}
57+
4858
type Tools []Tool
4959

5060
func (tools Tools) validateAll() error {

internal/pkg/configmanager/variables.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package configmanager
22

33
import (
4+
"github.com/devstream-io/devstream/pkg/util/log"
45
"github.com/devstream-io/devstream/pkg/util/template"
56
)
67

78
func renderConfigWithVariables(fileContent string, variables map[string]interface{}) ([]byte, error) {
9+
log.Debugf("renderConfigWithVariables got str: %s", fileContent)
10+
log.Debugf("Vars: ---")
11+
for k, v := range variables {
12+
log.Debugf("%s: %s", k, v)
13+
}
14+
log.Debugf("---")
15+
816
str, err := template.New().
917
FromContent(fileContent).
1018
AddProcessor(template.AddDotForVariablesInConfigProcessor()).
Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
package configmanager
22

33
import (
4-
"testing"
5-
6-
"github.com/stretchr/testify/assert"
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
76
)
87

9-
func TestRenderConfigWithVariables(t *testing.T) {
10-
variables := map[string]interface{}{
11-
"varNameA": "A",
12-
"varNameB": "B",
8+
var _ = Describe("renderConfigWithVariables", func() {
9+
var vars = map[string]interface{}{
10+
"foo1": "bar1",
11+
"foo2": "bar2",
1312
}
14-
result, err := renderConfigWithVariables("[[ varNameA ]]/[[ varNameB]]", variables)
15-
assert.Equal(t, err, nil)
16-
assert.Equal(t, string(result), "A/B")
17-
}
13+
When("render a config with variables", func() {
14+
It("should works fine", func() {
15+
result1, err1 := renderConfigWithVariables("[[ foo1 ]]/[[ foo2]]", vars)
16+
result2, err2 := renderConfigWithVariables("a[[ foo1 ]]/[[ foo2]]b", vars)
17+
result3, err3 := renderConfigWithVariables(" [[ foo1 ]] [[ foo2]] ", vars)
18+
Expect(err1).NotTo(HaveOccurred())
19+
Expect(err2).NotTo(HaveOccurred())
20+
Expect(err3).NotTo(HaveOccurred())
21+
Expect(result1).To(Equal([]byte("bar1/bar2")))
22+
Expect(result2).To(Equal([]byte("abar1/bar2b")))
23+
Expect(result3).To(Equal([]byte(" bar1 bar2 ")))
24+
})
25+
})
26+
})

0 commit comments

Comments
 (0)