Relates to the deprecation, added in3c0a167ed5The docker CLI up until v1.7.0 used the `~/.dockercfg` file to store credentials after authenticating to a registry (`docker login`). Docker v1.7.0 replaced this file with a new CLI configuration file, located in `~/.docker/config.json`. When implementing the new configuration file, the old file (and file-format) was kept as a fall-back, to assist existing users with migrating to the new file. Given that the old file format encourages insecure storage of credentials (credentials are stored unencrypted), and that no version of the CLI since Docker v1.7.0 has created this file, the file is marked deprecated, and support for this file will be removed in a future release. This patch adds a deprecation warning, which is printed if the CLI falls back to using the deprecated ~/.dockercfg file. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commitb83bc67136) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
613 lines
17 KiB
Go
613 lines
17 KiB
Go
package config
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/docker/cli/cli/config/configfile"
|
|
"github.com/docker/cli/cli/config/credentials"
|
|
"github.com/docker/cli/cli/config/types"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
"gotest.tools/v3/env"
|
|
"gotest.tools/v3/fs"
|
|
)
|
|
|
|
var homeKey = "HOME"
|
|
|
|
func init() {
|
|
if runtime.GOOS == "windows" {
|
|
homeKey = "USERPROFILE"
|
|
}
|
|
}
|
|
|
|
func setupConfigDir(t *testing.T) (string, func()) {
|
|
tmpdir, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
oldDir := Dir()
|
|
SetDir(tmpdir)
|
|
|
|
return tmpdir, func() {
|
|
SetDir(oldDir)
|
|
os.RemoveAll(tmpdir)
|
|
}
|
|
}
|
|
|
|
func TestEmptyConfigDir(t *testing.T) {
|
|
tmpHome, cleanup := setupConfigDir(t)
|
|
defer cleanup()
|
|
|
|
config, err := Load("")
|
|
assert.NilError(t, err)
|
|
|
|
expectedConfigFilename := filepath.Join(tmpHome, ConfigFileName)
|
|
assert.Check(t, is.Equal(expectedConfigFilename, config.Filename))
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestMissingFile(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestSaveFileToDirs(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
tmpHome += "/.docker"
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestEmptyFile(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
err = ioutil.WriteFile(fn, []byte(""), 0600)
|
|
assert.NilError(t, err)
|
|
|
|
_, err = Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
}
|
|
|
|
func TestEmptyJSON(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
err = ioutil.WriteFile(fn, []byte("{}"), 0600)
|
|
assert.NilError(t, err)
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestOldInvalidsAuth(t *testing.T) {
|
|
invalids := map[string]string{
|
|
`username = test`: "The Auth config file is empty",
|
|
`username
|
|
password`: "Invalid Auth config file",
|
|
`username = test
|
|
email`: "Invalid auth configuration file",
|
|
}
|
|
|
|
resetHomeDir()
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
defer env.Patch(t, homeKey, tmpHome)()
|
|
|
|
for content, expectedError := range invalids {
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
err := ioutil.WriteFile(fn, []byte(content), 0600)
|
|
assert.NilError(t, err)
|
|
|
|
_, err = Load(tmpHome)
|
|
assert.ErrorContains(t, err, expectedError)
|
|
}
|
|
}
|
|
|
|
func TestOldValidAuth(t *testing.T) {
|
|
resetHomeDir()
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
defer env.Patch(t, homeKey, tmpHome)()
|
|
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
js := `username = am9lam9lOmhlbGxv
|
|
email = user@example.com`
|
|
err = ioutil.WriteFile(fn, []byte(js), 0600)
|
|
assert.NilError(t, err)
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
// defaultIndexserver is https://index.docker.io/v1/
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
assert.Equal(t, ac.Username, "joejoe")
|
|
assert.Equal(t, ac.Password, "hello")
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
}
|
|
}`
|
|
|
|
assert.Check(t, is.Equal(expConfStr, configStr))
|
|
}
|
|
|
|
func TestOldJSONInvalid(t *testing.T) {
|
|
resetHomeDir()
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
defer env.Patch(t, homeKey, tmpHome)()
|
|
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
js := `{"https://index.docker.io/v1/":{"auth":"test","email":"user@example.com"}}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
// Use Contains instead of == since the file name will change each time
|
|
if err == nil || !strings.Contains(err.Error(), "Invalid auth configuration file") {
|
|
t.Fatalf("Expected an error got : %v, %v", config, err)
|
|
}
|
|
}
|
|
|
|
func TestOldJSON(t *testing.T) {
|
|
resetHomeDir()
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
defer env.Patch(t, homeKey, tmpHome)()
|
|
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
assert.Equal(t, ac.Username, "joejoe")
|
|
assert.Equal(t, ac.Password, "hello")
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv",
|
|
"email": "user@example.com"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n'%s'\n not \n'%s'\n", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestOldJSONFallbackDeprecationWarning(t *testing.T) {
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
tmpHome := fs.NewDir(t, t.Name(), fs.WithFile(oldConfigfile, js))
|
|
defer tmpHome.Remove()
|
|
defer env.PatchAll(t, map[string]string{homeKey: tmpHome.Path(), "DOCKER_CONFIG": ""})()
|
|
|
|
// reset the homeDir, configDir, and its sync.Once, to force them being resolved again
|
|
resetHomeDir()
|
|
resetConfigDir()
|
|
|
|
buffer := new(bytes.Buffer)
|
|
configFile := LoadDefaultConfigFile(buffer)
|
|
expected := configfile.New(tmpHome.Join(configFileDir, ConfigFileName))
|
|
expected.AuthConfigs = map[string]types.AuthConfig{
|
|
"https://index.docker.io/v1/": {
|
|
Username: "joejoe",
|
|
Password: "hello",
|
|
Email: "user@example.com",
|
|
ServerAddress: "https://index.docker.io/v1/",
|
|
},
|
|
}
|
|
assert.Assert(t, strings.Contains(buffer.String(), "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format is deprecated and will be removed in an upcoming release"))
|
|
assert.Check(t, is.DeepEqual(expected, configFile))
|
|
}
|
|
|
|
func TestNewJSON(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } } }`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
assert.Equal(t, ac.Username, "joejoe")
|
|
assert.Equal(t, ac.Password, "hello")
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestNewJSONNoEmail(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } } }`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
assert.Equal(t, ac.Username, "joejoe")
|
|
assert.Equal(t, ac.Password, "hello")
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestJSONWithPsFormat(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` {
|
|
t.Fatalf("Unknown ps format: %s\n", config.PsFormat)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
if !strings.Contains(configStr, `"psFormat":`) ||
|
|
!strings.Contains(configStr, "{{.ID}}") {
|
|
t.Fatalf("Should have save in new form: %s", configStr)
|
|
}
|
|
}
|
|
|
|
func TestJSONWithCredentialStore(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
|
|
"credsStore": "crazy-secure-storage"
|
|
}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
if config.CredentialsStore != "crazy-secure-storage" {
|
|
t.Fatalf("Unknown credential store: %s\n", config.CredentialsStore)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
if !strings.Contains(configStr, `"credsStore":`) ||
|
|
!strings.Contains(configStr, "crazy-secure-storage") {
|
|
t.Fatalf("Should have save in new form: %s", configStr)
|
|
}
|
|
}
|
|
|
|
func TestJSONWithCredentialHelpers(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
|
|
"credHelpers": { "images.io": "images-io", "containers.com": "crazy-secure-storage" }
|
|
}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
assert.NilError(t, err)
|
|
|
|
if config.CredentialHelpers == nil {
|
|
t.Fatal("config.CredentialHelpers was nil")
|
|
} else if config.CredentialHelpers["images.io"] != "images-io" ||
|
|
config.CredentialHelpers["containers.com"] != "crazy-secure-storage" {
|
|
t.Fatalf("Credential helpers not deserialized properly: %v\n", config.CredentialHelpers)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
if !strings.Contains(configStr, `"credHelpers":`) ||
|
|
!strings.Contains(configStr, "images.io") ||
|
|
!strings.Contains(configStr, "images-io") ||
|
|
!strings.Contains(configStr, "containers.com") ||
|
|
!strings.Contains(configStr, "crazy-secure-storage") {
|
|
t.Fatalf("Should have save in new form: %s", configStr)
|
|
}
|
|
}
|
|
|
|
// Save it and make sure it shows up in new form
|
|
func saveConfigAndValidateNewFormat(t *testing.T, config *configfile.ConfigFile, configDir string) string {
|
|
t.Helper()
|
|
assert.NilError(t, config.Save())
|
|
|
|
buf, err := ioutil.ReadFile(filepath.Join(configDir, ConfigFileName))
|
|
assert.NilError(t, err)
|
|
assert.Check(t, is.Contains(string(buf), `"auths":`))
|
|
return string(buf)
|
|
}
|
|
|
|
func TestConfigDir(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
if Dir() == tmpHome {
|
|
t.Fatalf("Expected ConfigDir to be different than %s by default, but was the same", tmpHome)
|
|
}
|
|
|
|
// Update configDir
|
|
SetDir(tmpHome)
|
|
|
|
if Dir() != tmpHome {
|
|
t.Fatalf("Expected ConfigDir to %s, but was %s", tmpHome, Dir())
|
|
}
|
|
}
|
|
|
|
func TestJSONReaderNoFile(t *testing.T) {
|
|
js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } } }`
|
|
|
|
config, err := LoadFromReader(strings.NewReader(js))
|
|
assert.NilError(t, err)
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
assert.Equal(t, ac.Username, "joejoe")
|
|
assert.Equal(t, ac.Password, "hello")
|
|
}
|
|
|
|
func TestOldJSONReaderNoFile(t *testing.T) {
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
|
|
config, err := LegacyLoadFromReader(strings.NewReader(js))
|
|
assert.NilError(t, err)
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
assert.Equal(t, ac.Username, "joejoe")
|
|
assert.Equal(t, ac.Password, "hello")
|
|
}
|
|
|
|
func TestJSONWithPsFormatNoFile(t *testing.T) {
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
config, err := LoadFromReader(strings.NewReader(js))
|
|
assert.NilError(t, err)
|
|
|
|
if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` {
|
|
t.Fatalf("Unknown ps format: %s\n", config.PsFormat)
|
|
}
|
|
}
|
|
|
|
func TestJSONSaveWithNoFile(t *testing.T) {
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } },
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
config, err := LoadFromReader(strings.NewReader(js))
|
|
assert.NilError(t, err)
|
|
err = config.Save()
|
|
assert.ErrorContains(t, err, "with empty filename")
|
|
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
defer f.Close()
|
|
|
|
assert.NilError(t, config.SaveToWriter(f))
|
|
buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName))
|
|
assert.NilError(t, err)
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
},
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
if string(buf) != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\nnot \n%s", string(buf), expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestLegacyJSONSaveWithNoFile(t *testing.T) {
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
config, err := LegacyLoadFromReader(strings.NewReader(js))
|
|
assert.NilError(t, err)
|
|
err = config.Save()
|
|
assert.ErrorContains(t, err, "with empty filename")
|
|
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
assert.NilError(t, err)
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
defer f.Close()
|
|
|
|
assert.NilError(t, config.SaveToWriter(f))
|
|
buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName))
|
|
assert.NilError(t, err)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv",
|
|
"email": "user@example.com"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if string(buf) != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestLoadDefaultConfigFile(t *testing.T) {
|
|
dir, cleanup := setupConfigDir(t)
|
|
defer cleanup()
|
|
buffer := new(bytes.Buffer)
|
|
|
|
filename := filepath.Join(dir, ConfigFileName)
|
|
content := []byte(`{"PsFormat": "format"}`)
|
|
err := ioutil.WriteFile(filename, content, 0644)
|
|
assert.NilError(t, err)
|
|
|
|
configFile := LoadDefaultConfigFile(buffer)
|
|
credStore := credentials.DetectDefaultStore("")
|
|
expected := configfile.New(filename)
|
|
expected.CredentialsStore = credStore
|
|
expected.PsFormat = "format"
|
|
|
|
assert.Check(t, is.DeepEqual(expected, configFile))
|
|
}
|
|
|
|
func TestConfigPath(t *testing.T) {
|
|
oldDir := Dir()
|
|
|
|
for _, tc := range []struct {
|
|
name string
|
|
dir string
|
|
path []string
|
|
expected string
|
|
expectedErr string
|
|
}{
|
|
{
|
|
name: "valid_path",
|
|
dir: "dummy",
|
|
path: []string{"a", "b"},
|
|
expected: filepath.Join("dummy", "a", "b"),
|
|
},
|
|
{
|
|
name: "valid_path_absolute_dir",
|
|
dir: "/dummy",
|
|
path: []string{"a", "b"},
|
|
expected: filepath.Join("/dummy", "a", "b"),
|
|
},
|
|
{
|
|
name: "invalid_relative_path",
|
|
dir: "dummy",
|
|
path: []string{"e", "..", "..", "f"},
|
|
expectedErr: fmt.Sprintf("is outside of root config directory %q", "dummy"),
|
|
},
|
|
{
|
|
name: "invalid_absolute_path",
|
|
dir: "dummy",
|
|
path: []string{"/a", "..", ".."},
|
|
expectedErr: fmt.Sprintf("is outside of root config directory %q", "dummy"),
|
|
},
|
|
} {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
SetDir(tc.dir)
|
|
f, err := Path(tc.path...)
|
|
assert.Equal(t, f, tc.expected)
|
|
if tc.expectedErr == "" {
|
|
assert.NilError(t, err)
|
|
} else {
|
|
assert.ErrorContains(t, err, tc.expectedErr)
|
|
}
|
|
})
|
|
}
|
|
|
|
SetDir(oldDir)
|
|
}
|