mirror of
https://github.com/zitadel/zitadel.git
synced 2025-06-25 05:28:34 +00:00
add tests for config
This commit is contained in:
parent
ecb894258f
commit
6deb0b029a
@ -7,31 +7,21 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/ghodss/yaml"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Reader interface {
|
|
||||||
Unmarshal(data []byte, o interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValidatableConfiguration interface {
|
type ValidatableConfiguration interface {
|
||||||
Validate() error
|
Validate() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReaderFunc func(data []byte, o interface{}) error
|
type ReaderFunc func(data []byte, o interface{}) error
|
||||||
|
|
||||||
func (c ReaderFunc) Unmarshal(data []byte, o interface{}) error {
|
|
||||||
return c(data, o)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
JSONReader = ReaderFunc(json.Unmarshal)
|
JSONReader = json.Unmarshal
|
||||||
TOMLReader = ReaderFunc(toml.Unmarshal)
|
TOMLReader = toml.Unmarshal
|
||||||
YAMLReader = ReaderFunc(func(y []byte, o interface{}) error {
|
YAMLReader = yaml.Unmarshal
|
||||||
return yaml.Unmarshal(y, o)
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Read deserializes each config file to the target obj
|
// Read deserializes each config file to the target obj
|
||||||
@ -39,11 +29,11 @@ var (
|
|||||||
// env vars are replaced in the config file as well as the file path
|
// env vars are replaced in the config file as well as the file path
|
||||||
func Read(obj interface{}, configFiles ...string) error {
|
func Read(obj interface{}, configFiles ...string) error {
|
||||||
for _, cf := range configFiles {
|
for _, cf := range configFiles {
|
||||||
configReader, err := configReaderForFile(cf)
|
readerFunc, err := readerFuncForFile(cf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := readConfigFile(configReader, cf, obj); err != nil {
|
if err := readConfigFile(readerFunc, cf, obj); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,13 +47,9 @@ func Read(obj interface{}, configFiles ...string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readConfigFile(configReader Reader, configFile string, obj interface{}) error {
|
func readConfigFile(readerFunc ReaderFunc, configFile string, obj interface{}) error {
|
||||||
configFile = os.ExpandEnv(configFile)
|
configFile = os.ExpandEnv(configFile)
|
||||||
|
|
||||||
if _, err := os.Stat(configFile); err != nil {
|
|
||||||
return errors.ThrowNotFoundf(err, "CONFI-Hs93M", "config file %s does not exist", configFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
configStr, err := ioutil.ReadFile(configFile)
|
configStr, err := ioutil.ReadFile(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.ThrowInternalf(err, "CONFI-nJk2a", "failed to read config file %s", configFile)
|
return errors.ThrowInternalf(err, "CONFI-nJk2a", "failed to read config file %s", configFile)
|
||||||
@ -71,14 +57,14 @@ func readConfigFile(configReader Reader, configFile string, obj interface{}) err
|
|||||||
|
|
||||||
configStr = []byte(os.ExpandEnv(string(configStr)))
|
configStr = []byte(os.ExpandEnv(string(configStr)))
|
||||||
|
|
||||||
if err := configReader.Unmarshal(configStr, obj); err != nil {
|
if err := readerFunc(configStr, obj); err != nil {
|
||||||
return errors.ThrowInternalf(err, "CONFI-2Mc3c", "error parse config file %s", configFile)
|
return errors.ThrowInternalf(err, "CONFI-2Mc3c", "error parse config file %s", configFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func configReaderForFile(configFile string) (Reader, error) {
|
func readerFuncForFile(configFile string) (ReaderFunc, error) {
|
||||||
ext := filepath.Ext(configFile)
|
ext := filepath.Ext(configFile)
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".yaml", ".yml":
|
case ".yaml", ".yml":
|
||||||
|
198
internal/config/config_test.go
Normal file
198
internal/config/config_test.go
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type test struct {
|
||||||
|
Test bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type validatable struct {
|
||||||
|
Test bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *validatable) Validate() error {
|
||||||
|
if v.Test {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRead(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
obj interface{}
|
||||||
|
configFiles []string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"not supoorted config file error",
|
||||||
|
args{
|
||||||
|
configFiles: []string{"notsupported.unknown"},
|
||||||
|
obj: nil,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"non existing config file error",
|
||||||
|
args{
|
||||||
|
configFiles: []string{"nonexisting.yaml"},
|
||||||
|
obj: nil,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"non parsable config file error",
|
||||||
|
args{
|
||||||
|
configFiles: []string{"./testdata/non_parsable.json"},
|
||||||
|
obj: &test{},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid parsable config file error",
|
||||||
|
args{
|
||||||
|
configFiles: []string{"./testdata/invalid.json"},
|
||||||
|
obj: &validatable{},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parsable config file ok",
|
||||||
|
args{
|
||||||
|
configFiles: []string{"./testdata/valid.json"},
|
||||||
|
obj: &test{},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid parsable config file ok",
|
||||||
|
args{
|
||||||
|
configFiles: []string{"./testdata/valid.json"},
|
||||||
|
obj: &validatable{},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := Read(tt.args.obj, tt.args.configFiles...); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Read() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_readerFuncForFile(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
configFile string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want ReaderFunc
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"unknown extension error",
|
||||||
|
args{configFile: "test.unknown"},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"toml",
|
||||||
|
args{configFile: "test.toml"},
|
||||||
|
TOMLReader,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"json",
|
||||||
|
args{configFile: "test.json"},
|
||||||
|
JSONReader,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"yaml",
|
||||||
|
args{configFile: "test.yaml"},
|
||||||
|
YAMLReader,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"yml",
|
||||||
|
args{configFile: "test.yml"},
|
||||||
|
YAMLReader,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := readerFuncForFile(tt.args.configFile)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("configReaderForFile() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
funcName1 := runtime.FuncForPC(reflect.ValueOf(got).Pointer()).Name()
|
||||||
|
funcName2 := runtime.FuncForPC(reflect.ValueOf(tt.want).Pointer()).Name()
|
||||||
|
if !assert.Equal(t, funcName1, funcName2) {
|
||||||
|
t.Errorf("configReaderForFile() got = %v, want %v", funcName1, funcName2)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_readConfigFile(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
configReader ReaderFunc
|
||||||
|
configFile string
|
||||||
|
obj interface{}
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"non existing config file error",
|
||||||
|
args{
|
||||||
|
configReader: YAMLReader,
|
||||||
|
configFile: "nonexisting.json",
|
||||||
|
obj: nil,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"non parsable config file error",
|
||||||
|
args{
|
||||||
|
configReader: YAMLReader,
|
||||||
|
configFile: "./testdata/non_parsable.json",
|
||||||
|
obj: &test{},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parsable config file no error",
|
||||||
|
args{
|
||||||
|
configReader: YAMLReader,
|
||||||
|
configFile: "./testdata/valid.json",
|
||||||
|
obj: &test{},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := readConfigFile(tt.args.configReader, tt.args.configFile, tt.args.obj); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("readConfigFile() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
3
internal/config/testdata/invalid.json
vendored
Normal file
3
internal/config/testdata/invalid.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Test" : false
|
||||||
|
}
|
1
internal/config/testdata/non_parsable.json
vendored
Normal file
1
internal/config/testdata/non_parsable.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Test
|
3
internal/config/testdata/valid.json
vendored
Normal file
3
internal/config/testdata/valid.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Test" : true
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user