mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
add functions/vendor files
This commit is contained in:
597
vendor/github.com/vrischmann/envconfig/envconfig_test.go
generated
vendored
Normal file
597
vendor/github.com/vrischmann/envconfig/envconfig_test.go
generated
vendored
Normal file
@@ -0,0 +1,597 @@
|
||||
package envconfig_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vrischmann/envconfig"
|
||||
)
|
||||
|
||||
func TestParseSimpleConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Name string
|
||||
Log struct {
|
||||
Path string
|
||||
}
|
||||
}
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, "envconfig: keys NAME, name not found", err.Error())
|
||||
|
||||
os.Setenv("NAME", "foobar")
|
||||
err = envconfig.Init(&conf)
|
||||
require.Equal(t, "envconfig: keys LOG_PATH, log_path not found", err.Error())
|
||||
|
||||
os.Setenv("LOG_PATH", "/var/log/foobar")
|
||||
err = envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, "foobar", conf.Name)
|
||||
require.Equal(t, "/var/log/foobar", conf.Log.Path)
|
||||
|
||||
// Clean up at the end of the test - some tests share the same key and we don't values to be seen by those tests
|
||||
os.Setenv("NAME", "")
|
||||
os.Setenv("LOG_PATH", "")
|
||||
}
|
||||
|
||||
func TestParseIntegerConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Port int
|
||||
Long uint64
|
||||
Version uint8
|
||||
}
|
||||
|
||||
timestamp := time.Now().UnixNano()
|
||||
|
||||
os.Setenv("PORT", "80")
|
||||
os.Setenv("LONG", fmt.Sprintf("%d", timestamp))
|
||||
os.Setenv("VERSION", "2")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, 80, conf.Port)
|
||||
require.Equal(t, uint64(timestamp), conf.Long)
|
||||
require.Equal(t, uint8(2), conf.Version)
|
||||
}
|
||||
|
||||
func TestParseBoolConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
DoIt bool
|
||||
}
|
||||
|
||||
os.Setenv("DOIT", "true")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, true, conf.DoIt)
|
||||
}
|
||||
|
||||
func TestParseBytesConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Data []byte
|
||||
}
|
||||
|
||||
os.Setenv("DATA", "Rk9PQkFS")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, []byte("FOOBAR"), conf.Data)
|
||||
}
|
||||
|
||||
func TestParseFloatConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Delta float32
|
||||
DeltaV float64
|
||||
}
|
||||
|
||||
os.Setenv("DELTA", "0.02")
|
||||
os.Setenv("DELTAV", "400.20000000001")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, float32(0.02), conf.Delta)
|
||||
require.Equal(t, float64(400.20000000001), conf.DeltaV)
|
||||
}
|
||||
|
||||
func TestParseSliceConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Names []string
|
||||
Ports []int
|
||||
Shards []struct {
|
||||
Name string
|
||||
Addr string
|
||||
}
|
||||
}
|
||||
|
||||
os.Setenv("NAMES", "foobar,barbaz")
|
||||
os.Setenv("PORTS", "900,100")
|
||||
os.Setenv("SHARDS", "{foobar,localhost:2929},{barbaz,localhost:2828}")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, 2, len(conf.Names))
|
||||
require.Equal(t, "foobar", conf.Names[0])
|
||||
require.Equal(t, "barbaz", conf.Names[1])
|
||||
require.Equal(t, 2, len(conf.Ports))
|
||||
require.Equal(t, 900, conf.Ports[0])
|
||||
require.Equal(t, 100, conf.Ports[1])
|
||||
require.Equal(t, 2, len(conf.Shards))
|
||||
require.Equal(t, "foobar", conf.Shards[0].Name)
|
||||
require.Equal(t, "localhost:2929", conf.Shards[0].Addr)
|
||||
require.Equal(t, "barbaz", conf.Shards[1].Name)
|
||||
require.Equal(t, "localhost:2828", conf.Shards[1].Addr)
|
||||
}
|
||||
|
||||
func TestParseStructSliceWrongData(t *testing.T) {
|
||||
var conf struct {
|
||||
Shards []struct {
|
||||
Name string
|
||||
Addr string
|
||||
}
|
||||
}
|
||||
|
||||
os.Setenv("SHARDS", "foobar")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, "envconfig: struct token has 1 fields but struct has 2", err.Error())
|
||||
}
|
||||
|
||||
func TestParseStructSliceWrongValue(t *testing.T) {
|
||||
var conf struct {
|
||||
Shards []struct {
|
||||
Name string
|
||||
Port int32
|
||||
}
|
||||
}
|
||||
|
||||
os.Setenv("SHARDS", "{foobar,barbaz}")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, `strconv.ParseInt: parsing "barbaz": invalid syntax`, err.Error())
|
||||
}
|
||||
|
||||
func TestParseWrongValues(t *testing.T) {
|
||||
var conf struct{ OK bool }
|
||||
os.Setenv("OK", "foobar")
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, `strconv.ParseBool: parsing "foobar": invalid syntax`, err.Error())
|
||||
|
||||
var conf2 struct{ Port int }
|
||||
os.Setenv("PORT", "foobar")
|
||||
err = envconfig.Init(&conf2)
|
||||
require.Equal(t, `strconv.ParseInt: parsing "foobar": invalid syntax`, err.Error())
|
||||
|
||||
var conf3 struct{ Port uint }
|
||||
os.Setenv("PORT", "foobar")
|
||||
err = envconfig.Init(&conf3)
|
||||
require.Equal(t, `strconv.ParseUint: parsing "foobar": invalid syntax`, err.Error())
|
||||
|
||||
var conf4 struct{ Port float32 }
|
||||
os.Setenv("PORT", "foobar")
|
||||
err = envconfig.Init(&conf4)
|
||||
require.Equal(t, `strconv.ParseFloat: parsing "foobar": invalid syntax`, err.Error())
|
||||
|
||||
var conf5 struct{ Data []byte }
|
||||
os.Setenv("DATA", "foobar")
|
||||
err = envconfig.Init(&conf5)
|
||||
require.Equal(t, "illegal base64 data at input byte 4", err.Error())
|
||||
}
|
||||
|
||||
func TestDurationConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
os.Setenv("TIMEOUT", "1m")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, time.Minute*1, conf.Timeout)
|
||||
}
|
||||
|
||||
func TestInvalidDurationConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
os.Setenv("TIMEOUT", "foo")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestAllPointerConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Name *string
|
||||
Port *int
|
||||
Delta *float32
|
||||
DeltaV *float64
|
||||
Hosts *[]string
|
||||
Shards *[]*struct {
|
||||
Name *string
|
||||
Addr *string
|
||||
}
|
||||
Master *struct {
|
||||
Name *string
|
||||
Addr *string
|
||||
}
|
||||
Timeout *time.Duration
|
||||
}
|
||||
|
||||
os.Setenv("NAME", "foobar")
|
||||
os.Setenv("PORT", "9000")
|
||||
os.Setenv("DELTA", "40.01")
|
||||
os.Setenv("DELTAV", "200.00001")
|
||||
os.Setenv("HOSTS", "localhost,free.fr")
|
||||
os.Setenv("SHARDS", "{foobar,localhost:2828},{barbaz,localhost:2929}")
|
||||
os.Setenv("MASTER_NAME", "master")
|
||||
os.Setenv("MASTER_ADDR", "localhost:2727")
|
||||
os.Setenv("TIMEOUT", "1m")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, "foobar", *conf.Name)
|
||||
require.Equal(t, 9000, *conf.Port)
|
||||
require.Equal(t, float32(40.01), *conf.Delta)
|
||||
require.Equal(t, 200.00001, *conf.DeltaV)
|
||||
require.Equal(t, 2, len(*conf.Hosts))
|
||||
require.Equal(t, "localhost", (*conf.Hosts)[0])
|
||||
require.Equal(t, "free.fr", (*conf.Hosts)[1])
|
||||
require.Equal(t, 2, len(*conf.Shards))
|
||||
require.Equal(t, "foobar", *(*conf.Shards)[0].Name)
|
||||
require.Equal(t, "localhost:2828", *(*conf.Shards)[0].Addr)
|
||||
require.Equal(t, "barbaz", *(*conf.Shards)[1].Name)
|
||||
require.Equal(t, "localhost:2929", *(*conf.Shards)[1].Addr)
|
||||
require.Equal(t, "master", *conf.Master.Name)
|
||||
require.Equal(t, "localhost:2727", *conf.Master.Addr)
|
||||
require.Equal(t, time.Minute*1, *conf.Timeout)
|
||||
}
|
||||
|
||||
type logMode uint
|
||||
|
||||
const (
|
||||
logFile logMode = iota + 1
|
||||
logStdout
|
||||
)
|
||||
|
||||
func (m *logMode) Unmarshal(s string) error {
|
||||
switch strings.ToLower(s) {
|
||||
case "file":
|
||||
*m = logFile
|
||||
case "stdout":
|
||||
*m = logStdout
|
||||
default:
|
||||
return fmt.Errorf("unable to unmarshal %s", s)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestUnmarshaler(t *testing.T) {
|
||||
var conf struct {
|
||||
LogMode logMode
|
||||
}
|
||||
|
||||
os.Setenv("LOGMODE", "file")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, logFile, conf.LogMode)
|
||||
|
||||
var conf2 struct {
|
||||
LogMode *logMode
|
||||
}
|
||||
|
||||
err = envconfig.Init(&conf2)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, logFile, *conf2.LogMode)
|
||||
}
|
||||
|
||||
func TestParseOptionalConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Name string `envconfig:"optional"`
|
||||
Flag bool `envconfig:"optional"`
|
||||
Timeout time.Duration `envconfig:"optional"`
|
||||
Port int `envconfig:"optional"`
|
||||
Port2 uint `envconfig:"optional"`
|
||||
Delta float32 `envconfig:"optional"`
|
||||
DeltaV float64 `envconfig:"optional"`
|
||||
Slice []string `envconfig:"optional"`
|
||||
Struct struct {
|
||||
A string
|
||||
B int
|
||||
} `envconfig:"optional"`
|
||||
}
|
||||
|
||||
os.Setenv("NAME", "")
|
||||
os.Setenv("FLAG", "")
|
||||
os.Setenv("TIMEOUT", "")
|
||||
os.Setenv("PORT", "")
|
||||
os.Setenv("PORT2", "")
|
||||
os.Setenv("DELTA", "")
|
||||
os.Setenv("DELTAV", "")
|
||||
os.Setenv("SLICE", "")
|
||||
os.Setenv("STRUCT_A", "")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "", conf.Name)
|
||||
|
||||
os.Setenv("NAME", "foobar")
|
||||
os.Setenv("SLICE", "a,b")
|
||||
os.Setenv("STRUCT_A", "foobar")
|
||||
os.Setenv("STRUCT_B", "1")
|
||||
|
||||
err = envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "foobar", conf.Name)
|
||||
require.Equal(t, []string{"a", "b"}, conf.Slice)
|
||||
require.Equal(t, "foobar", conf.Struct.A)
|
||||
require.Equal(t, 1, conf.Struct.B)
|
||||
}
|
||||
|
||||
func TestParseSkippableConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Flag bool `envconfig:"-"`
|
||||
}
|
||||
|
||||
os.Setenv("FLAG", "true")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, false, conf.Flag)
|
||||
}
|
||||
|
||||
func TestParseCustomNameConfig(t *testing.T) {
|
||||
var conf struct {
|
||||
Name string `envconfig:"customName"`
|
||||
}
|
||||
|
||||
os.Setenv("customName", "foobar")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "foobar", conf.Name)
|
||||
}
|
||||
|
||||
func TestParseOptionalStruct(t *testing.T) {
|
||||
var conf struct {
|
||||
Master struct {
|
||||
Name string
|
||||
} `envconfig:"optional"`
|
||||
}
|
||||
|
||||
os.Setenv("MASTER_NAME", "")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "", conf.Master.Name)
|
||||
}
|
||||
|
||||
func TestParsePrefixedStruct(t *testing.T) {
|
||||
var conf struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
os.Setenv("NAME", "")
|
||||
os.Setenv("FOO_NAME", "")
|
||||
|
||||
os.Setenv("NAME", "bad")
|
||||
err := envconfig.InitWithPrefix(&conf, "FOO")
|
||||
require.NotNil(t, err)
|
||||
|
||||
os.Setenv("FOO_NAME", "good")
|
||||
err = envconfig.InitWithPrefix(&conf, "FOO")
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "good", conf.Name)
|
||||
}
|
||||
|
||||
func TestUnexportedField(t *testing.T) {
|
||||
var conf struct {
|
||||
name string
|
||||
}
|
||||
|
||||
os.Setenv("NAME", "foobar")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, envconfig.ErrUnexportedField, err)
|
||||
|
||||
err = envconfig.InitWithOptions(&conf, envconfig.Options{AllowUnexported: true})
|
||||
require.Equal(t, nil, err)
|
||||
}
|
||||
|
||||
func TestNestedUnexportedField(t *testing.T) {
|
||||
var conf struct {
|
||||
Foo struct {
|
||||
Bar struct {
|
||||
baz string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os.Setenv("FOO_BAR_BAZ", "foobar")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, envconfig.ErrUnexportedField, err)
|
||||
|
||||
err = envconfig.InitWithOptions(&conf, envconfig.Options{AllowUnexported: true})
|
||||
require.Equal(t, nil, err)
|
||||
}
|
||||
|
||||
type sliceWithUnmarshaler []int
|
||||
|
||||
func (sl *sliceWithUnmarshaler) Unmarshal(s string) error {
|
||||
tokens := strings.Split(s, ".")
|
||||
for _, tok := range tokens {
|
||||
tmp, err := strconv.Atoi(tok)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*sl = append(*sl, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSliceTypeWithUnmarshaler(t *testing.T) {
|
||||
var conf struct {
|
||||
Data sliceWithUnmarshaler
|
||||
}
|
||||
|
||||
os.Setenv("DATA", "1.2.3")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 3, len(conf.Data))
|
||||
require.Equal(t, 1, conf.Data[0])
|
||||
require.Equal(t, 2, conf.Data[1])
|
||||
require.Equal(t, 3, conf.Data[2])
|
||||
}
|
||||
|
||||
func TestParseDefaultVal(t *testing.T) {
|
||||
var conf struct {
|
||||
MySQL struct {
|
||||
Master struct {
|
||||
Address string `envconfig:"default=localhost"`
|
||||
Port int `envconfig:"default=3306"`
|
||||
}
|
||||
Timeout time.Duration `envconfig:"default=1m,myTimeout"`
|
||||
LocalTimeout time.Duration `envconfig:"myTimeout2,default=1m"`
|
||||
}
|
||||
}
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "localhost", conf.MySQL.Master.Address)
|
||||
require.Equal(t, 3306, conf.MySQL.Master.Port)
|
||||
require.Equal(t, time.Minute*1, conf.MySQL.Timeout)
|
||||
|
||||
os.Setenv("myTimeout", "2m")
|
||||
os.Setenv("myTimeout2", "20m")
|
||||
|
||||
err = envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "localhost", conf.MySQL.Master.Address)
|
||||
require.Equal(t, 3306, conf.MySQL.Master.Port)
|
||||
require.Equal(t, time.Minute*2, conf.MySQL.Timeout)
|
||||
require.Equal(t, time.Minute*20, conf.MySQL.LocalTimeout)
|
||||
}
|
||||
|
||||
func TestDefaultSlice(t *testing.T) {
|
||||
// See https://github.com/vrischmann/envconfig/pull/15
|
||||
//
|
||||
// The way people think about the following default value, is that the slice will be [a,b]
|
||||
// However this never worked because we split the entire envconfig tag on , therefore default is just `a` here.
|
||||
// The proper thing to do is to introduce a new format in the tag that doesn't have this limitation, but we don't have that yet.
|
||||
// For now, we simply return an error indicating default is not unsupported on slices.
|
||||
|
||||
var conf struct {
|
||||
Hosts []string `envconfig:"default=a,b"`
|
||||
}
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.NotNil(t, err)
|
||||
require.Equal(t, envconfig.ErrDefaultUnsupportedOnSlice, err)
|
||||
}
|
||||
|
||||
func TestInitNotAPointer(t *testing.T) {
|
||||
err := envconfig.Init("foobar")
|
||||
require.Equal(t, envconfig.ErrNotAPointer, err)
|
||||
}
|
||||
|
||||
func TestInitPointerToAPointer(t *testing.T) {
|
||||
type Conf struct {
|
||||
Name string
|
||||
}
|
||||
var tmp *Conf
|
||||
|
||||
os.Setenv("NAME", "foobar")
|
||||
|
||||
err := envconfig.Init(&tmp)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "foobar", tmp.Name)
|
||||
}
|
||||
|
||||
func TestInitInvalidValueKind(t *testing.T) {
|
||||
sl := []string{"foo", "bar"}
|
||||
err := envconfig.Init(&sl)
|
||||
require.Equal(t, envconfig.ErrInvalidValueKind, err)
|
||||
}
|
||||
|
||||
func TestInvalidFieldValueKind(t *testing.T) {
|
||||
var conf struct {
|
||||
Foo interface{}
|
||||
}
|
||||
|
||||
os.Setenv("FOO", "lalala")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, "envconfig: kind interface not supported", err.Error())
|
||||
}
|
||||
|
||||
func TestInvalidSliceElementValueKind(t *testing.T) {
|
||||
var conf struct {
|
||||
Foo []interface{}
|
||||
}
|
||||
|
||||
os.Setenv("FOO", "lalala")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Equal(t, "envconfig: kind interface not supported", err.Error())
|
||||
}
|
||||
|
||||
func TestParseEmptyTag(t *testing.T) {
|
||||
var conf struct {
|
||||
Name string `envconfig:""`
|
||||
}
|
||||
|
||||
os.Setenv("NAME", "foobar")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "foobar", conf.Name)
|
||||
}
|
||||
|
||||
func TestLeaveNil(t *testing.T) {
|
||||
var conf struct {
|
||||
MySQL *struct {
|
||||
Name string
|
||||
}
|
||||
}
|
||||
|
||||
err := envconfig.InitWithOptions(&conf, envconfig.Options{
|
||||
AllOptional: true,
|
||||
LeaveNil: true,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, conf.MySQL)
|
||||
}
|
||||
|
||||
type myMapType map[string]int
|
||||
|
||||
func (t *myMapType) Unmarshal(s string) error {
|
||||
(*t)[s] = 1
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestParseMapType(t *testing.T) {
|
||||
var conf struct {
|
||||
Map myMapType
|
||||
}
|
||||
|
||||
os.Setenv("MAP", "a")
|
||||
|
||||
err := envconfig.Init(&conf)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, conf.Map["a"])
|
||||
}
|
||||
Reference in New Issue
Block a user