Improves error message when a configuration file is empty.
This commit is contained in:
parent
d3977ce40e
commit
c02f222005
4 changed files with 52 additions and 15 deletions
|
@ -13,8 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// decodeFileToNode decodes the configuration in filePath in a tree of untyped nodes.
|
// decodeFileToNode decodes the configuration in filePath in a tree of untyped nodes.
|
||||||
// If filters is not empty, it skips any configuration element whose name is
|
// If filters is not empty, it skips any configuration element whose name is not among filters.
|
||||||
// not among filters.
|
|
||||||
func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) {
|
func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) {
|
||||||
content, err := ioutil.ReadFile(filePath)
|
content, err := ioutil.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -40,7 +39,20 @@ func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error)
|
||||||
return nil, fmt.Errorf("unsupported file extension: %s", filePath)
|
return nil, fmt.Errorf("unsupported file extension: %s", filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return decodeRawToNode(data, parser.DefaultRootName, filters...)
|
if len(data) == 0 {
|
||||||
|
return nil, fmt.Errorf("no configuration found in file: %s", filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
node, err := decodeRawToNode(data, parser.DefaultRootName, filters...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(node.Children) == 0 {
|
||||||
|
return nil, fmt.Errorf("no valid configuration found in file: %s", filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRootFieldNames(element interface{}) []string {
|
func getRootFieldNames(element interface{}) []string {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/parser"
|
"github.com/containous/traefik/v2/pkg/config/parser"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_getRootFieldNames(t *testing.T) {
|
func Test_getRootFieldNames(t *testing.T) {
|
||||||
|
@ -42,17 +43,43 @@ func Test_getRootFieldNames(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_decodeFileToNode_errors(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
confFile string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "non existing file",
|
||||||
|
confFile: "./fixtures/not_existing.toml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "file without content",
|
||||||
|
confFile: "./fixtures/empty.toml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "file without any valid configuration",
|
||||||
|
confFile: "./fixtures/no_conf.toml",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
node, err := decodeFileToNode(test.confFile,
|
||||||
|
"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
|
||||||
|
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Nil(t, node)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Test_decodeFileToNode_compare(t *testing.T) {
|
func Test_decodeFileToNode_compare(t *testing.T) {
|
||||||
nodeToml, err := decodeFileToNode("./fixtures/sample.toml",
|
nodeToml, err := decodeFileToNode("./fixtures/sample.toml",
|
||||||
"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
|
"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeYaml, err := decodeFileToNode("./fixtures/sample.yml")
|
nodeYaml, err := decodeFileToNode("./fixtures/sample.yml")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, nodeToml, nodeYaml)
|
assert.Equal(t, nodeToml, nodeYaml)
|
||||||
}
|
}
|
||||||
|
@ -60,9 +87,7 @@ func Test_decodeFileToNode_compare(t *testing.T) {
|
||||||
func Test_decodeFileToNode_Toml(t *testing.T) {
|
func Test_decodeFileToNode_Toml(t *testing.T) {
|
||||||
node, err := decodeFileToNode("./fixtures/sample.toml",
|
node, err := decodeFileToNode("./fixtures/sample.toml",
|
||||||
"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
|
"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := &parser.Node{
|
expected := &parser.Node{
|
||||||
Name: "traefik",
|
Name: "traefik",
|
||||||
|
@ -294,9 +319,7 @@ func Test_decodeFileToNode_Toml(t *testing.T) {
|
||||||
|
|
||||||
func Test_decodeFileToNode_Yaml(t *testing.T) {
|
func Test_decodeFileToNode_Yaml(t *testing.T) {
|
||||||
node, err := decodeFileToNode("./fixtures/sample.yml")
|
node, err := decodeFileToNode("./fixtures/sample.yml")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := &parser.Node{
|
expected := &parser.Node{
|
||||||
Name: "traefik",
|
Name: "traefik",
|
||||||
|
|
0
pkg/config/file/fixtures/empty.toml
Normal file
0
pkg/config/file/fixtures/empty.toml
Normal file
2
pkg/config/file/fixtures/no_conf.toml
Normal file
2
pkg/config/file/fixtures/no_conf.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[foo]
|
||||||
|
bar = "test"
|
Loading…
Reference in a new issue