forked from helm-unittest/helm-unittest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_suite.go
145 lines (123 loc) · 3.43 KB
/
test_suite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package unittest
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
"github.com/lrills/helm-unittest/unittest/snapshot"
"gopkg.in/yaml.v2"
"k8s.io/helm/pkg/proto/hapi/chart"
)
// ParseTestSuiteFile parse a suite file at path and returns TestSuite
func ParseTestSuiteFile(suiteFilePath, chartRoute string) (*TestSuite, error) {
suite := TestSuite{chartRoute: chartRoute}
content, err := ioutil.ReadFile(suiteFilePath)
if err != nil {
return &suite, err
}
cwd, _ := os.Getwd()
absPath, _ := filepath.Abs(suiteFilePath)
suite.definitionFile, err = filepath.Rel(cwd, absPath)
if err != nil {
return &suite, err
}
if err := yaml.Unmarshal(content, &suite); err != nil {
return &suite, err
}
return &suite, nil
}
// TestSuite defines scope and templates to render and tests to run
type TestSuite struct {
Name string `yaml:"suite"`
Templates []string
Tests []*TestJob
// where the test suite file located
definitionFile string
// route indicate which chart in the dependency hierarchy
// like "parant-chart", "parent-charts/charts/child-chart"
chartRoute string
}
// Run runs all the test jobs defined in TestSuite
func (s *TestSuite) Run(
targetChart *chart.Chart,
snapshotCache *snapshot.Cache,
result *TestSuiteResult,
) *TestSuiteResult {
s.polishTestJobsPathInfo()
result.DisplayName = s.Name
result.FilePath = s.definitionFile
preparedChart, err := s.prepareChart(targetChart)
if err != nil {
result.ExecError = err
return result
}
result.Passed, result.TestsResult = s.runTestJobs(
preparedChart,
snapshotCache,
)
result.countSnapshot(snapshotCache)
return result
}
// fill file path related info of TestJob
func (s *TestSuite) polishTestJobsPathInfo() {
for _, test := range s.Tests {
test.chartRoute = s.chartRoute
test.definitionFile = s.definitionFile
if len(s.Templates) > 0 {
test.defaultTemplateToAssert = s.Templates[0]
}
}
}
func (s *TestSuite) prepareChart(targetChart *chart.Chart) (*chart.Chart, error) {
copiedChart := new(chart.Chart)
*copiedChart = *targetChart
suiteIsFromRootChart := len(strings.Split(s.chartRoute, string(filepath.Separator))) <= 1
if len(s.Templates) == 0 && suiteIsFromRootChart {
return copiedChart, nil
}
filteredTemplate := make([]*chart.Template, 0, len(s.Templates))
// check templates and add them in chart dependencies, if from subchart leave it empty
if suiteIsFromRootChart {
for _, fileName := range s.Templates {
found := false
for _, template := range targetChart.Templates {
if filepath.Base(template.Name) == fileName {
filteredTemplate = append(filteredTemplate, template)
found = true
break
}
}
if !found {
return &chart.Chart{}, fmt.Errorf(
"template file `templates/%s` not found in chart",
fileName,
)
}
}
}
// add templates with extension .tpl
for _, template := range targetChart.Templates {
if path.Ext(template.Name) == ".tpl" {
filteredTemplate = append(filteredTemplate, template)
}
}
copiedChart.Templates = filteredTemplate
return copiedChart, nil
}
func (s *TestSuite) runTestJobs(
chart *chart.Chart,
cache *snapshot.Cache,
) (bool, []*TestJobResult) {
suitePass := true
jobResults := make([]*TestJobResult, len(s.Tests))
for idx, testJob := range s.Tests {
jobResult := testJob.Run(chart, cache, &TestJobResult{Index: idx})
jobResults[idx] = jobResult
if !jobResult.Passed {
suitePass = false
}
}
return suitePass, jobResults
}