mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
254 lines
7.5 KiB
Go
254 lines
7.5 KiB
Go
|
package config
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"io/ioutil"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
type errReadCloser int
|
||
|
|
||
|
func (errReadCloser) Read(p []byte) (n int, err error) {
|
||
|
return 0, errors.New("read error")
|
||
|
}
|
||
|
|
||
|
func (errReadCloser) Close() error {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func TestReadConfig(t *testing.T) {
|
||
|
|
||
|
var c Config
|
||
|
|
||
|
t.Run("Success case", func(t *testing.T) {
|
||
|
|
||
|
myConfig := strings.NewReader("general:\n generalTestKey: generalTestValue\nsteps:\n testStep:\n testStepKey: testStepValue")
|
||
|
|
||
|
err := c.ReadConfig(ioutil.NopCloser(myConfig)) // NopCloser "no-ops" the closing interface since strings do not need to be closed
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error although no error expected: %v", err)
|
||
|
}
|
||
|
|
||
|
if c.General["generalTestKey"] != "generalTestValue" {
|
||
|
t.Errorf("General config- got: %v, expected: %v", c.General["generalTestKey"], "generalTestValue")
|
||
|
}
|
||
|
|
||
|
if c.Steps["testStep"]["testStepKey"] != "testStepValue" {
|
||
|
t.Errorf("Step config - got: %v, expected: %v", c.Steps["testStep"]["testStepKey"], "testStepValue")
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("Read failure", func(t *testing.T) {
|
||
|
var rc errReadCloser
|
||
|
err := c.ReadConfig(rc)
|
||
|
if err == nil {
|
||
|
t.Errorf("Got no error although error expected.")
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("Unmarshalling failure", func(t *testing.T) {
|
||
|
myConfig := strings.NewReader("general:\n generalTestKey: generalTestValue\nsteps:\n testStep:\n\ttestStepKey: testStepValue")
|
||
|
err := c.ReadConfig(ioutil.NopCloser(myConfig))
|
||
|
if err == nil {
|
||
|
t.Errorf("Got no error although error expected.")
|
||
|
}
|
||
|
})
|
||
|
|
||
|
}
|
||
|
|
||
|
func TestGetStepConfig(t *testing.T) {
|
||
|
|
||
|
t.Run("Success case", func(t *testing.T) {
|
||
|
|
||
|
testConfig := `general:
|
||
|
p3: p3_general
|
||
|
px3: px3_general
|
||
|
p4: p4_general
|
||
|
steps:
|
||
|
step1:
|
||
|
p4: p4_step
|
||
|
px4: px4_step
|
||
|
p5: p5_step
|
||
|
stages:
|
||
|
stage1:
|
||
|
p5: p5_stage
|
||
|
px5: px5_stage
|
||
|
p6: p6_stage
|
||
|
`
|
||
|
filters := StepFilters{
|
||
|
General: []string{"p0", "p1", "p2", "p3", "p4"},
|
||
|
Steps: []string{"p0", "p1", "p2", "p3", "p4", "p5"},
|
||
|
Stages: []string{"p0", "p1", "p2", "p3", "p4", "p5", "p6"},
|
||
|
Parameters: []string{"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7"},
|
||
|
Env: []string{"p0", "p1", "p2", "p3", "p4", "p5"},
|
||
|
}
|
||
|
|
||
|
defaults1 := `general:
|
||
|
p0: p0_general_default
|
||
|
px0: px0_general_default
|
||
|
p1: p1_general_default
|
||
|
steps:
|
||
|
step1:
|
||
|
p1: p1_step_default
|
||
|
px1: px1_step_default
|
||
|
p2: p2_step_default
|
||
|
`
|
||
|
|
||
|
defaults2 := `general:
|
||
|
p2: p2_general_default
|
||
|
px2: px2_general_default
|
||
|
p3: p3_general_default
|
||
|
`
|
||
|
paramJSON := `{"p6":"p6_param","p7":"p7_param"}`
|
||
|
|
||
|
flags := map[string]interface{}{"p7": "p7_flag"}
|
||
|
|
||
|
var c Config
|
||
|
defaults := []io.ReadCloser{ioutil.NopCloser(strings.NewReader(defaults1)), ioutil.NopCloser(strings.NewReader(defaults2))}
|
||
|
|
||
|
myConfig := ioutil.NopCloser(strings.NewReader(testConfig))
|
||
|
stepConfig, err := c.GetStepConfig(flags, paramJSON, myConfig, defaults, filters, "stage1", "step1")
|
||
|
|
||
|
assert.Equal(t, nil, err, "error occured but none expected")
|
||
|
|
||
|
t.Run("Config", func(t *testing.T) {
|
||
|
expected := map[string]string{
|
||
|
"p0": "p0_general_default",
|
||
|
"p1": "p1_step_default",
|
||
|
"p2": "p2_general_default",
|
||
|
"p3": "p3_general",
|
||
|
"p4": "p4_step",
|
||
|
"p5": "p5_stage",
|
||
|
"p6": "p6_param",
|
||
|
"p7": "p7_flag",
|
||
|
}
|
||
|
for k, v := range expected {
|
||
|
t.Run(k, func(t *testing.T) {
|
||
|
if stepConfig.Config[k] != v {
|
||
|
t.Errorf("got: %v, expected: %v", stepConfig.Config[k], v)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("Config not expected", func(t *testing.T) {
|
||
|
notExpectedKeys := []string{"px0", "px1", "px2", "px3", "px4", "px5"}
|
||
|
for _, p := range notExpectedKeys {
|
||
|
t.Run(p, func(t *testing.T) {
|
||
|
if stepConfig.Config[p] != nil {
|
||
|
t.Errorf("unexpected: %v", p)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
})
|
||
|
|
||
|
t.Run("Failure case config", func(t *testing.T) {
|
||
|
var c Config
|
||
|
myConfig := ioutil.NopCloser(strings.NewReader("invalid config"))
|
||
|
_, err := c.GetStepConfig(nil, "", myConfig, nil, StepFilters{}, "stage1", "step1")
|
||
|
assert.EqualError(t, err, "failed to parse custom pipeline configuration: error unmarshalling \"invalid config\": error unmarshaling JSON: json: cannot unmarshal string into Go value of type config.Config", "default error expected")
|
||
|
})
|
||
|
|
||
|
t.Run("Failure case defaults", func(t *testing.T) {
|
||
|
var c Config
|
||
|
myConfig := ioutil.NopCloser(strings.NewReader(""))
|
||
|
myDefaults := []io.ReadCloser{ioutil.NopCloser(strings.NewReader("invalid defaults"))}
|
||
|
_, err := c.GetStepConfig(nil, "", myConfig, myDefaults, StepFilters{}, "stage1", "step1")
|
||
|
assert.EqualError(t, err, "failed to parse pipeline default configuration: error unmarshalling \"invalid defaults\": error unmarshaling JSON: json: cannot unmarshal string into Go value of type config.Config", "default error expected")
|
||
|
})
|
||
|
|
||
|
//ToDo: test merging of env and parameters/flags
|
||
|
}
|
||
|
|
||
|
func TestGetStepConfigWithJSON(t *testing.T) {
|
||
|
|
||
|
filters := StepFilters{All: []string{"key1"}}
|
||
|
|
||
|
t.Run("Without flags", func(t *testing.T) {
|
||
|
sc := GetStepConfigWithJSON(nil, `"key1":"value1","key2":"value2"`, filters)
|
||
|
|
||
|
if sc.Config["key1"] != "value1" && sc.Config["key2"] == "value2" {
|
||
|
t.Errorf("got: %v, expected: %v", sc.Config, StepConfig{Config: map[string]interface{}{"key1": "value1"}})
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("With flags", func(t *testing.T) {
|
||
|
flags := map[string]interface{}{"key1": "flagVal1"}
|
||
|
sc := GetStepConfigWithJSON(flags, `"key1":"value1","key2":"value2"`, filters)
|
||
|
if sc.Config["key1"] != "flagVal1" {
|
||
|
t.Errorf("got: %v, expected: %v", sc.Config["key1"], "flagVal1")
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestGetJSON(t *testing.T) {
|
||
|
|
||
|
t.Run("Success case", func(t *testing.T) {
|
||
|
custom := map[string]interface{}{"key1": "value1"}
|
||
|
json, err := GetJSON(custom)
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error although no error expected: %v", err)
|
||
|
}
|
||
|
|
||
|
if json != `{"key1":"value1"}` {
|
||
|
t.Errorf("got: %v, expected: %v", json, `{"key1":"value1"}`)
|
||
|
}
|
||
|
|
||
|
})
|
||
|
t.Run("Marshalling failure", func(t *testing.T) {
|
||
|
_, err := GetJSON(make(chan int))
|
||
|
if err == nil {
|
||
|
t.Errorf("Got no error although error expected")
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestMerge(t *testing.T) {
|
||
|
|
||
|
testTable := []struct {
|
||
|
Source map[string]interface{}
|
||
|
Filter []string
|
||
|
MergeData map[string]interface{}
|
||
|
ExpectedOutput map[string]interface{}
|
||
|
}{
|
||
|
{
|
||
|
Source: map[string]interface{}{"key1": "baseValue"},
|
||
|
Filter: []string{},
|
||
|
MergeData: map[string]interface{}{"key1": "overwrittenValue"},
|
||
|
ExpectedOutput: map[string]interface{}{"key1": "overwrittenValue"},
|
||
|
},
|
||
|
{
|
||
|
Source: map[string]interface{}{"key1": "value1"},
|
||
|
Filter: []string{},
|
||
|
MergeData: map[string]interface{}{"key2": "value2"},
|
||
|
ExpectedOutput: map[string]interface{}{"key1": "value1", "key2": "value2"},
|
||
|
},
|
||
|
{
|
||
|
Source: map[string]interface{}{"key1": "value1"},
|
||
|
Filter: []string{"key1"},
|
||
|
MergeData: map[string]interface{}{"key2": "value2"},
|
||
|
ExpectedOutput: map[string]interface{}{"key1": "value1"},
|
||
|
},
|
||
|
{
|
||
|
Source: map[string]interface{}{"key1": map[string]interface{}{"key1_1": "value1"}},
|
||
|
Filter: []string{},
|
||
|
MergeData: map[string]interface{}{"key1": map[string]interface{}{"key1_2": "value2"}},
|
||
|
ExpectedOutput: map[string]interface{}{"key1": map[string]interface{}{"key1_1": "value1", "key1_2": "value2"}},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, row := range testTable {
|
||
|
t.Run(fmt.Sprintf("Merging %v into %v", row.MergeData, row.Source), func(t *testing.T) {
|
||
|
stepConfig := StepConfig{Config: row.Source}
|
||
|
stepConfig.mixIn(row.MergeData, row.Filter)
|
||
|
assert.Equal(t, row.ExpectedOutput, stepConfig.Config, "Mixin was incorrect")
|
||
|
})
|
||
|
}
|
||
|
}
|