diff --git a/core/config/config.go b/core/config/config.go index 1736a01af..d6c7999ff 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -22,11 +22,7 @@ var ( ) func init() { - var envVarRxErr error - envVarRx, envVarRxErr = regexp.Compile(`^\s*([^#=]+)=(.+)$`) - if envVarRxErr != nil { - panic(envVarRxErr) - } + envVarRx = regexp.MustCompile(`^\s*([^#=]+)=(.+)$`) loadEtcEnvironment() initConfigKeyMap() } @@ -142,7 +138,7 @@ func NewConfig( c.Viper.SetConfigType(configType) cfgFile := fmt.Sprintf("%s.%s", configName, configType) - etcRexRayFile := fmt.Sprintf("%s/%s", util.EtcDirPath(), cfgFile) + etcRexRayFile := util.EtcFilePath(cfgFile) usrRexRayFile := fmt.Sprintf("%s/.rexray/%s", util.HomeDir(), cfgFile) if loadGlobalConfig && util.FileExists(etcRexRayFile) { @@ -184,12 +180,8 @@ func (c *Config) SetJSONMarshalStrategy(s JSONMarshalStrategy) { // Copy creates a copy of this Config instance func (c *Config) Copy() (*Config, error) { newC := New() - if err := c.Viper.Unmarshal(&newC.plainTextConfig); err != nil { - return nil, err - } - if err := c.Viper.Unmarshal(&newC.secureConfig); err != nil { - return nil, err - } + c.Viper.Unmarshal(&newC.plainTextConfig) + c.Viper.Unmarshal(&newC.secureConfig) return newC, nil } @@ -205,20 +197,14 @@ func FromJSON(from string) (*Config, error) { // ToJSON exports this Config instance to a JSON string func (c *Config) ToJSON() (string, error) { - buf, err := c.marshalJSON(JSONMarshalPlainText) - if err != nil { - return "", err - } + buf, _ := c.marshalJSON(JSONMarshalPlainText) return string(buf), nil } // ToSecureJSON exports this Config instance to a JSON string omitting any of // the secure fields func (c *Config) ToSecureJSON() (string, error) { - buf, err := c.marshalJSON(JSONMarshalSecure) - if err != nil { - return "", err - } + buf, _ := c.marshalJSON(JSONMarshalSecure) return string(buf), nil } @@ -230,14 +216,11 @@ func (c *Config) MarshalJSON() ([]byte, error) { func (c *Config) marshalJSON(s JSONMarshalStrategy) ([]byte, error) { switch s { - case JSONMarshalSecure: - return json.MarshalIndent(c.secureConfig, "", " ") case JSONMarshalPlainText: return json.MarshalIndent(c.plainTextConfig, "", " ") + default: + return json.MarshalIndent(c.secureConfig, "", " ") } - - return nil, errors.WithField( - "strategy", s, "unknown json marshalling strategy") } // ReadConfig reads a configuration stream into the current config instance @@ -247,17 +230,9 @@ func (c *Config) ReadConfig(in io.Reader) error { return errors.New("config reader is nil") } - if err := c.Viper.ReadConfigNoNil(in); err != nil { - return err - } - - if err := c.Viper.Unmarshal(&c.secureConfig); err != nil { - return err - } - - if err := c.Viper.Unmarshal(&c.plainTextConfig); err != nil { - return err - } + c.Viper.ReadConfigNoNil(in) + c.Viper.Unmarshal(&c.secureConfig) + c.Viper.Unmarshal(&c.plainTextConfig) for key := range keys { c.updateFlag(key, c.GlobalFlags) diff --git a/core/config/config_test.go b/core/config/config_test.go index 8774f9ffe..b4a39627b 100644 --- a/core/config/config_test.go +++ b/core/config/config_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" "os" "reflect" "testing" @@ -11,6 +12,99 @@ import ( "github.com/emccode/rexray/util" ) +var ( + tmpPrefixDirs []string + usrRexRayFile string +) + +func TestMain(m *testing.M) { + usrRexRayDir := fmt.Sprintf("%s/.rexray", util.HomeDir()) + os.MkdirAll(usrRexRayDir, 0755) + usrRexRayFile = fmt.Sprintf("%s/%s.%s", usrRexRayDir, "config", "yml") + usrRexRayFileBak := fmt.Sprintf("%s.bak", usrRexRayFile) + + os.Remove(usrRexRayFileBak) + os.Rename(usrRexRayFile, usrRexRayFileBak) + + exitCode := m.Run() + for _, d := range tmpPrefixDirs { + os.RemoveAll(d) + } + + os.Remove(usrRexRayFile) + os.Rename(usrRexRayFileBak, usrRexRayFile) + os.Exit(exitCode) +} + +func newPrefixDir(testName string, t *testing.T) string { + tmpDir, err := ioutil.TempDir( + "", fmt.Sprintf("rexray-core-config_test-%s", testName)) + if err != nil { + t.Fatal(err) + } + + util.Prefix(tmpDir) + os.MkdirAll(tmpDir, 0755) + tmpPrefixDirs = append(tmpPrefixDirs, tmpDir) + return tmpDir +} + +func TestCopy(t *testing.T) { + newPrefixDir("TestCopy", t) + + etcRexRayCfg := util.EtcFilePath("config.yml") + t.Logf("etcRexRayCfg=%s", etcRexRayCfg) + util.WriteStringToFile(string(yamlConfig1), etcRexRayCfg) + + c := New() + + assertLogLevel(t, c, "error") + assertStorageDrivers(t, c) + assertOsDrivers1(t, c) + + cc, _ := c.Copy() + + assertLogLevel(t, cc, "error") + assertStorageDrivers(t, cc) + assertOsDrivers1(t, cc) + + cJSON, _ := c.ToJSON() + ccJSON, _ := cc.ToJSON() + + cMap := map[string]interface{}{} + ccMap := map[string]interface{}{} + json.Unmarshal([]byte(cJSON), cMap) + json.Unmarshal([]byte(ccJSON), ccJSON) + + if !reflect.DeepEqual(cMap, ccMap) { + t.Fail() + } +} + +func TestEnvVars(t *testing.T) { + c := New() + c.Viper.Set("awsSecretKey", "Hello, world.") + if !util.StringInSlice("AWS_SECRET_KEY=Hello, world.", c.EnvVars()) { + t.Fail() + } + + if util.StringInSlice("AWS_SECRET_KEY=Hello, world.", New().EnvVars()) { + t.Fail() + } +} + +func TestJSONMarshalStrategy(t *testing.T) { + c := New() + if c.JSONMarshalStrategy() != JSONMarshalSecure { + t.Fail() + } + c.SetJSONMarshalStrategy(JSONMarshalPlainText) + if c.JSONMarshalStrategy() != JSONMarshalPlainText { + t.Fail() + } + c.SetJSONMarshalStrategy(JSONMarshalSecure) +} + func TestToJson(t *testing.T) { c := New() @@ -136,6 +230,13 @@ func TestFromJson(t *testing.T) { assertAwsSecretKey(t, c, "MyAwsSecretKey") } +func TestFromJsonWithErrors(t *testing.T) { + _, err := FromJSON("///*") + if err == nil { + t.Fatal("expected unmarshalling error") + } +} + func TestFromSecureJson(t *testing.T) { c, err := FromJSON(secureJSONConfig) if err != nil { @@ -147,21 +248,39 @@ func TestFromSecureJson(t *testing.T) { assertAwsSecretKey(t, c, "") } -func TestNew(t *testing.T) { +func TestNewWithUserConfigFile(t *testing.T) { + util.WriteStringToFile(string(yamlConfig1), usrRexRayFile) + defer os.RemoveAll(usrRexRayFile) - usrRexRayDir := fmt.Sprintf("%s/.rexray", util.HomeDir()) - os.MkdirAll(usrRexRayDir, 0755) - usrRexRayFile := fmt.Sprintf("%s/%s.%s", usrRexRayDir, "config", "yml") - usrRexRayFileBak := fmt.Sprintf("%s.bak", usrRexRayFile) + c := New() - os.Remove(usrRexRayFileBak) - os.Rename(usrRexRayFile, usrRexRayFileBak) - defer func() { - os.Remove(usrRexRayFile) - os.Rename(usrRexRayFileBak, usrRexRayFile) - }() + assertLogLevel(t, c, "error") + assertStorageDrivers(t, c) + assertOsDrivers1(t, c) + + if err := c.ReadConfig(bytes.NewReader(yamlConfig2)); err != nil { + t.Fatal(err) + } + + assertLogLevel(t, c, "debug") + assertStorageDrivers(t, c) + assertOsDrivers2(t, c) +} +func TestNewWithUserConfigFileWithErrors(t *testing.T) { util.WriteStringToFile(string(yamlConfig1), usrRexRayFile) + defer os.RemoveAll(usrRexRayFile) + + os.Chmod(usrRexRayFile, 0000) + New() +} + +func TestNewWithGlobalConfigFile(t *testing.T) { + newPrefixDir("TestNewWithGlobalConfigFile", t) + + etcRexRayCfg := util.EtcFilePath("config.yml") + t.Logf("etcRexRayCfg=%s", etcRexRayCfg) + util.WriteStringToFile(string(yamlConfig1), etcRexRayCfg) c := New() @@ -178,6 +297,38 @@ func TestNew(t *testing.T) { assertOsDrivers2(t, c) } +func TestNewWithGlobalConfigFileWithErrors(t *testing.T) { + newPrefixDir("TestNewWithGlobalConfigFileWithErrors", t) + + etcRexRayCfg := util.EtcFilePath("config.yml") + t.Logf("etcRexRayCfg=%s", etcRexRayCfg) + util.WriteStringToFile(string(yamlConfig1), etcRexRayCfg) + + os.Chmod(etcRexRayCfg, 0000) + New() +} + +func TestReadConfigFile(t *testing.T) { + var err error + var tmp *os.File + if tmp, err = ioutil.TempFile("", "TestReadConfigFile"); err != nil { + t.Fatal(err) + } + defer os.Remove(tmp.Name()) + + if _, err := tmp.Write(yamlConfig1); err != nil { + t.Fatal(err) + } + tmp.Close() + + os.Chmod(tmp.Name(), 0000) + + c := New() + if err := c.ReadConfigFile(tmp.Name()); err == nil { + t.Fatal("expected error reading config file") + } +} + func TestReadConfig(t *testing.T) { c := NewConfig(false, false, "config", "yml") if err := c.ReadConfig(bytes.NewReader(yamlConfig1)); err != nil { @@ -197,6 +348,12 @@ func TestReadConfig(t *testing.T) { assertOsDrivers2(t, c) } +func TestReadNilConfig(t *testing.T) { + if err := New().ReadConfig(nil); err == nil { + t.Fatal("expected nil config error") + } +} + func assertAwsSecretKey(t *testing.T, c *Config, expected string) { val := c.Viper.GetString("awsSecretKey") if val != expected { diff --git a/util/util.go b/util/util.go index d5fb515e4..e4d2db67c 100644 --- a/util/util.go +++ b/util/util.go @@ -88,6 +88,14 @@ func Prefix(p string) { return } + binDirPath = "" + binFilePath = "" + logDirPath = "" + libDirPath = "" + runDirPath = "" + etcDirPath = "" + pidFilePath = "" + prefix = p } diff --git a/util/util_test.go b/util/util_test.go index d4f7a8f8d..51be92ba0 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -13,33 +13,19 @@ import ( ) var r10 string -var tmpHomeDirs []string +var tmpPrefixDirs []string func TestMain(m *testing.M) { r10 = RandomString(10) exitCode := m.Run() - for _, d := range tmpHomeDirs { + for _, d := range tmpPrefixDirs { os.RemoveAll(d) } os.Exit(exitCode) } -func resetPaths() { - prefix = "" - homeDir = "" - binDirPath = "" - binFilePath = "" - logDirPath = "" - libDirPath = "" - runDirPath = "" - etcDirPath = "" - pidFilePath = "" -} - -func newHomeDir(testName string, t *testing.T) string { - resetPaths() - +func newPrefixDir(testName string, t *testing.T) string { tmpDir, err := ioutil.TempDir( "", fmt.Sprintf("rexray-util_test-%s", testName)) if err != nil { @@ -48,7 +34,7 @@ func newHomeDir(testName string, t *testing.T) string { Prefix(tmpDir) os.MkdirAll(tmpDir, 0755) - tmpHomeDirs = append(tmpHomeDirs, tmpDir) + tmpPrefixDirs = append(tmpPrefixDirs, tmpDir) return tmpDir } @@ -71,7 +57,7 @@ func TestPrefix(t *testing.T) { t.Fatalf("is prefixed %s", GetPrefix()) } - tmpDir := newHomeDir("TestHomeDir", t) + tmpDir := newPrefixDir("TestHomeDir", t) Prefix(tmpDir) if !IsPrefixed() { t.Fatalf("is not prefixed %s", GetPrefix()) @@ -84,7 +70,7 @@ func TestPrefix(t *testing.T) { } func TestPrefixAndDirs(t *testing.T) { - tmpDir := newHomeDir("TestPrefixAndDirs", t) + tmpDir := newPrefixDir("TestPrefixAndDirs", t) etcDirPath := EtcDirPath() expEtcDirPath := fmt.Sprintf("%s/etc/rexray", tmpDir) @@ -152,7 +138,7 @@ func TestPrefixAndDirs(t *testing.T) { } func TestStdOutAndLogFile(t *testing.T) { - newHomeDir("TestStdOutAndLogFile", t) + newPrefixDir("TestStdOutAndLogFile", t) if _, err := StdOutAndLogFile("BadFile/"); err == nil { t.Fatal("error expected in created BadFile") @@ -170,7 +156,7 @@ func TestStdOutAndLogFile(t *testing.T) { } func TestWriteAndReadStringToFile(t *testing.T) { - tmpDir := newHomeDir("TestWriteAndReadStringToFile", t) + tmpDir := newPrefixDir("TestWriteAndReadStringToFile", t) tmpFile, _ := ioutil.TempFile(tmpDir, "temp") WriteStringToFile("Hello, world.", tmpFile.Name()) @@ -192,7 +178,7 @@ func TestReadtringToFileError(t *testing.T) { } func TestWriteReadCurrentPidFile(t *testing.T) { - newHomeDir("TestWriteReadPidFile", t) + newPrefixDir("TestWriteReadPidFile", t) var err error var pidRead int @@ -213,7 +199,7 @@ func TestWriteReadCurrentPidFile(t *testing.T) { } func TestWriteReadCustomPidFile(t *testing.T) { - newHomeDir("TestWriteReadPidFile", t) + newPrefixDir("TestWriteReadPidFile", t) var err error if _, err = ReadPidFile(); err == nil { @@ -236,7 +222,7 @@ func TestWriteReadCustomPidFile(t *testing.T) { } func TestReadPidFileWithErrors(t *testing.T) { - newHomeDir("TestWriteReadPidFile", t) + newPrefixDir("TestWriteReadPidFile", t) var err error if _, err = ReadPidFile(); err == nil { @@ -255,7 +241,7 @@ func TestIsDirEmpty(t *testing.T) { t.Fatal("expected error for invalid path") } - tmpDir := newHomeDir("TestWriteReadPidFile", t) + tmpDir := newPrefixDir("TestWriteReadPidFile", t) var err error var isEmpty bool @@ -282,7 +268,7 @@ func TestLineReader(t *testing.T) { t.Fatal("expected nil channel for invalid path") } - newHomeDir("TestLineReader", t) + newPrefixDir("TestLineReader", t) WritePidFile(100) c := LineReader(PidFilePath())