blob: 56af0226f36b2c7053c86be218c357ddf0b53798 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package config
import (
"fmt"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
func ExampleConfigTool_readValue() {
tmpDir, _ := os.MkdirTemp("", "ops")
defer os.RemoveAll(tmpDir)
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm, _ := NewConfigMapBuilder().WithOpsRoot(opsRootPath).WithConfigJson(configPath).Build()
os.Args = []string{"config", "FOO=bar"}
err := ConfigTool(cm)
if err != nil {
fmt.Println("error:", err)
}
os.Args = []string{"config", "FOO"}
err = ConfigTool(cm)
if err != nil {
fmt.Println("error:", err)
}
// nested key
os.Args = []string{"config", "NESTED_VAL=val"}
err = ConfigTool(cm)
if err != nil {
fmt.Println("error:", err)
}
os.Args = []string{"config", "NESTED_VAL"}
err = ConfigTool(cm)
if err != nil {
fmt.Println("error:", err)
}
// Output:
// bar
// val
}
func TestConfigTool(t *testing.T) {
readConfigJson := func(path string) (map[string]interface{}, error) {
return readConfig(filepath.Join(path, "config.json"), fromConfigJson)
}
buildCM := func(nv string, c string) ConfigMap {
cm, _ := NewConfigMapBuilder().WithConfigJson(c).WithOpsRoot(nv).Build()
return cm
}
t.Run("new config.json", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO=bar"}
err := ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{
"foo": "bar",
}
require.Equal(t, want, got)
})
t.Run("write values on existing config.json", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO=bar"}
err := ConfigTool(cm)
require.NoError(t, err)
os.Args = []string{"config", "BAR=baz"}
err = ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{
"foo": "bar",
"bar": "baz",
}
require.Equal(t, want, got)
})
t.Run("write existing value is overridden", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO=bar"}
err := ConfigTool(cm)
require.NoError(t, err)
os.Args = []string{"config", "FOO=new"}
err = ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{
"foo": "new",
}
require.Equal(t, want, got)
})
t.Run("write existing key object is merged", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO_BAR=bar"}
err := ConfigTool(cm)
require.NoError(t, err)
os.Args = []string{"config", "FOO_BAZ=baz"}
err = ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{
"foo": map[string]interface{}{
"bar": "bar",
"baz": "baz",
},
}
require.Equal(t, want, got)
})
t.Run("write empty string to disable key", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO_BAR=bar"}
err := ConfigTool(cm)
require.NoError(t, err)
os.Args = []string{"config", "FOO_BAR=\"\""}
err = ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{
"foo": map[string]interface{}{
"bar": "",
},
}
require.Equal(t, want, got)
})
t.Run("remove existing key", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO=bar"}
err := ConfigTool(cm)
require.NoError(t, err)
os.Args = []string{"config", "-r", "FOO"}
err = ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{}
require.Equal(t, want, got)
})
t.Run("remove nested key object", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "FOO_BAR=bar", "FOO_BAZ=baz"}
err := ConfigTool(cm)
require.NoError(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{
"foo": map[string]interface{}{
"bar": "bar",
"baz": "baz",
},
}
require.Equal(t, want, got)
os.Args = []string{"config", "-r", "FOO_BAR"}
err = ConfigTool(cm)
require.NoError(t, err)
got, err = readConfigJson(tmpDir)
require.NoError(t, err)
want = map[string]interface{}{
"foo": map[string]interface{}{
"baz": "baz",
},
}
require.Equal(t, want, got)
})
t.Run("remove non-existing key", func(t *testing.T) {
tmpDir := t.TempDir()
opsRootPath := filepath.Join(tmpDir, "opsroot.json")
configPath := filepath.Join(tmpDir, "config.json")
cm := buildCM(opsRootPath, configPath)
os.Args = []string{"config", "-r", "FOO"}
err := ConfigTool(cm)
require.Error(t, err)
got, err := readConfigJson(tmpDir)
require.NoError(t, err)
want := map[string]interface{}{}
require.Equal(t, want, got)
})
}
func Test_buildKeyValueMap(t *testing.T) {
testCases := []struct {
name string
input []string
want keyValues
err error
}{
{
name: "Empty string",
input: []string{},
want: nil,
err: fmt.Errorf("no key-value pairs provided"),
},
{
name: "Single key-value pair",
input: []string{"foo=bar"},
want: keyValues{"foo": "bar"},
err: nil,
},
{
name: "Multiple key-value pairs",
input: []string{"foo=bar", "baz=qux"},
want: keyValues{"foo": "bar", "baz": "qux"},
err: nil,
},
{
name: "Invalid key-value pair",
input: []string{"foo"},
want: nil,
err: fmt.Errorf("invalid key-value pair: %q", "foo"),
},
{
name: "Invalid key-value pair",
input: []string{"foo="},
want: nil,
err: fmt.Errorf("invalid key-value pair: %q", "foo="),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, err := buildInputKVMap(tc.input)
require.Equal(t, tc.err, err)
require.Equal(t, tc.want, got)
})
}
}