conf: rewrite tests
This commit is contained in:
parent
163424dc32
commit
cd9792fec0
|
@ -6,11 +6,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/crypto/nacl/secretbox"
|
"golang.org/x/crypto/nacl/secretbox"
|
||||||
)
|
)
|
||||||
|
@ -30,44 +28,9 @@ func writeTempFile(byts []byte) (string, error) {
|
||||||
return tmpf.Name(), nil
|
return tmpf.Name(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvironment(t *testing.T) {
|
func TestWithFileAndEnv(t *testing.T) {
|
||||||
// string
|
|
||||||
os.Setenv("RTSP_RUNONCONNECT", "test=cmd")
|
|
||||||
defer os.Unsetenv("RTSP_RUNONCONNECT")
|
|
||||||
|
|
||||||
// int
|
|
||||||
os.Setenv("RTSP_READBUFFERCOUNT", "3000")
|
|
||||||
defer os.Unsetenv("RTSP_READBUFFERCOUNT")
|
|
||||||
|
|
||||||
// bool
|
|
||||||
os.Setenv("RTSP_METRICS", "yes")
|
|
||||||
defer os.Unsetenv("RTSP_METRICS")
|
|
||||||
|
|
||||||
// duration
|
|
||||||
os.Setenv("RTSP_READTIMEOUT", "22s")
|
|
||||||
defer os.Unsetenv("RTSP_READTIMEOUT")
|
|
||||||
|
|
||||||
// slice
|
|
||||||
os.Setenv("RTSP_LOGDESTINATIONS", "stdout,file")
|
|
||||||
defer os.Unsetenv("RTSP_LOGDESTINATIONS")
|
|
||||||
|
|
||||||
// map key
|
|
||||||
os.Setenv("RTSP_PATHS_TEST2", "")
|
|
||||||
defer os.Unsetenv("RTSP_PATHS_TEST2")
|
|
||||||
|
|
||||||
// map values, "all" path
|
|
||||||
os.Setenv("RTSP_PATHS_ALL_READUSER", "testuser")
|
|
||||||
defer os.Unsetenv("RTSP_PATHS_ALL_READUSER")
|
|
||||||
os.Setenv("RTSP_PATHS_ALL_READPASS", "testpass")
|
|
||||||
defer os.Unsetenv("RTSP_PATHS_ALL_READPASS")
|
|
||||||
|
|
||||||
// map values, generic path
|
|
||||||
os.Setenv("RTSP_PATHS_CAM1_SOURCE", "rtsp://testing")
|
os.Setenv("RTSP_PATHS_CAM1_SOURCE", "rtsp://testing")
|
||||||
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCE")
|
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCE")
|
||||||
os.Setenv("RTSP_PATHS_CAM1_SOURCEPROTOCOL", "tcp")
|
|
||||||
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCEPROTOCOL")
|
|
||||||
os.Setenv("RTSP_PATHS_CAM1_SOURCEONDEMAND", "yes")
|
|
||||||
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCEONDEMAND")
|
|
||||||
|
|
||||||
tmpf, err := writeTempFile([]byte("{}"))
|
tmpf, err := writeTempFile([]byte("{}"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -77,49 +40,11 @@ func TestEnvironment(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, true, hasFile)
|
require.Equal(t, true, hasFile)
|
||||||
|
|
||||||
require.Equal(t, "test=cmd", conf.RunOnConnect)
|
pa, ok := conf.Paths["cam1"]
|
||||||
|
|
||||||
require.Equal(t, 3000, conf.ReadBufferCount)
|
|
||||||
|
|
||||||
require.Equal(t, true, conf.Metrics)
|
|
||||||
|
|
||||||
require.Equal(t, 22*time.Second, conf.ReadTimeout)
|
|
||||||
|
|
||||||
require.Equal(t, []string{"stdout", "file"}, conf.LogDestinations)
|
|
||||||
|
|
||||||
pa, ok := conf.Paths["test2"]
|
|
||||||
require.Equal(t, true, ok)
|
require.Equal(t, true, ok)
|
||||||
require.Equal(t, &PathConf{
|
require.Equal(t, &PathConf{
|
||||||
Source: "record",
|
Source: "rtsp://testing",
|
||||||
SourceOnDemandStartTimeout: 10 * time.Second,
|
SourceProtocol: "automatic",
|
||||||
SourceOnDemandCloseAfter: 10 * time.Second,
|
|
||||||
RunOnDemandStartTimeout: 10 * time.Second,
|
|
||||||
RunOnDemandCloseAfter: 10 * time.Second,
|
|
||||||
}, pa)
|
|
||||||
|
|
||||||
pa, ok = conf.Paths["~^.*$"]
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
require.Equal(t, &PathConf{
|
|
||||||
Regexp: regexp.MustCompile("^.*$"),
|
|
||||||
Source: "record",
|
|
||||||
SourceOnDemandStartTimeout: 10 * time.Second,
|
|
||||||
SourceOnDemandCloseAfter: 10 * time.Second,
|
|
||||||
ReadUser: "testuser",
|
|
||||||
ReadPass: "testpass",
|
|
||||||
RunOnDemandStartTimeout: 10 * time.Second,
|
|
||||||
RunOnDemandCloseAfter: 10 * time.Second,
|
|
||||||
}, pa)
|
|
||||||
|
|
||||||
pa, ok = conf.Paths["cam1"]
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
require.Equal(t, &PathConf{
|
|
||||||
Source: "rtsp://testing",
|
|
||||||
SourceProtocol: "tcp",
|
|
||||||
SourceProtocolParsed: func() *gortsplib.StreamProtocol {
|
|
||||||
v := gortsplib.StreamProtocolTCP
|
|
||||||
return &v
|
|
||||||
}(),
|
|
||||||
SourceOnDemand: true,
|
|
||||||
SourceOnDemandStartTimeout: 10 * time.Second,
|
SourceOnDemandStartTimeout: 10 * time.Second,
|
||||||
SourceOnDemandCloseAfter: 10 * time.Second,
|
SourceOnDemandCloseAfter: 10 * time.Second,
|
||||||
RunOnDemandStartTimeout: 10 * time.Second,
|
RunOnDemandStartTimeout: 10 * time.Second,
|
||||||
|
@ -127,7 +52,7 @@ func TestEnvironment(t *testing.T) {
|
||||||
}, pa)
|
}, pa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvironmentNoFile(t *testing.T) {
|
func TestWithEnvOnly(t *testing.T) {
|
||||||
os.Setenv("RTSP_PATHS_CAM1_SOURCE", "rtsp://testing")
|
os.Setenv("RTSP_PATHS_CAM1_SOURCE", "rtsp://testing")
|
||||||
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCE")
|
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCE")
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,14 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func load(env map[string]string, envKey string, rv reflect.Value) error {
|
func load(env map[string]string, prefix string, rv reflect.Value) error {
|
||||||
rt := rv.Type()
|
rt := rv.Type()
|
||||||
|
|
||||||
if rt == reflect.TypeOf(time.Duration(0)) {
|
if rt == reflect.TypeOf(time.Duration(0)) {
|
||||||
if ev, ok := env[envKey]; ok {
|
if ev, ok := env[prefix]; ok {
|
||||||
d, err := time.ParseDuration(ev)
|
d, err := time.ParseDuration(ev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: %s", envKey, err)
|
return fmt.Errorf("%s: %s", prefix, err)
|
||||||
}
|
}
|
||||||
rv.Set(reflect.ValueOf(d))
|
rv.Set(reflect.ValueOf(d))
|
||||||
}
|
}
|
||||||
|
@ -25,33 +25,33 @@ func load(env map[string]string, envKey string, rv reflect.Value) error {
|
||||||
|
|
||||||
switch rt.Kind() {
|
switch rt.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
if ev, ok := env[envKey]; ok {
|
if ev, ok := env[prefix]; ok {
|
||||||
rv.SetString(ev)
|
rv.SetString(ev)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
if ev, ok := env[envKey]; ok {
|
if ev, ok := env[prefix]; ok {
|
||||||
iv, err := strconv.ParseInt(ev, 10, 64)
|
iv, err := strconv.ParseInt(ev, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: %s", envKey, err)
|
return fmt.Errorf("%s: %s", prefix, err)
|
||||||
}
|
}
|
||||||
rv.SetInt(iv)
|
rv.SetInt(iv)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case reflect.Uint64:
|
case reflect.Uint64:
|
||||||
if ev, ok := env[envKey]; ok {
|
if ev, ok := env[prefix]; ok {
|
||||||
iv, err := strconv.ParseUint(ev, 10, 64)
|
iv, err := strconv.ParseUint(ev, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: %s", envKey, err)
|
return fmt.Errorf("%s: %s", prefix, err)
|
||||||
}
|
}
|
||||||
rv.SetUint(iv)
|
rv.SetUint(iv)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
if ev, ok := env[envKey]; ok {
|
if ev, ok := env[prefix]; ok {
|
||||||
switch strings.ToLower(ev) {
|
switch strings.ToLower(ev) {
|
||||||
case "yes", "true":
|
case "yes", "true":
|
||||||
rv.SetBool(true)
|
rv.SetBool(true)
|
||||||
|
@ -60,14 +60,14 @@ func load(env map[string]string, envKey string, rv reflect.Value) error {
|
||||||
rv.SetBool(false)
|
rv.SetBool(false)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%s: invalid value '%s'", envKey, ev)
|
return fmt.Errorf("%s: invalid value '%s'", prefix, ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
if rt.Elem().Kind() == reflect.String {
|
if rt.Elem().Kind() == reflect.String {
|
||||||
if ev, ok := env[envKey]; ok {
|
if ev, ok := env[prefix]; ok {
|
||||||
nv := reflect.Zero(rt)
|
nv := reflect.Zero(rt)
|
||||||
for _, sv := range strings.Split(ev, ",") {
|
for _, sv := range strings.Split(ev, ",") {
|
||||||
nv = reflect.Append(nv, reflect.ValueOf(sv))
|
nv = reflect.Append(nv, reflect.ValueOf(sv))
|
||||||
|
@ -79,11 +79,11 @@ func load(env map[string]string, envKey string, rv reflect.Value) error {
|
||||||
|
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
for k := range env {
|
for k := range env {
|
||||||
if !strings.HasPrefix(k, envKey+"_") {
|
if !strings.HasPrefix(k, prefix+"_") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
mapKey := strings.Split(k[len(envKey+"_"):], "_")[0]
|
mapKey := strings.Split(k[len(prefix+"_"):], "_")[0]
|
||||||
if len(mapKey) == 0 {
|
if len(mapKey) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ func load(env map[string]string, envKey string, rv reflect.Value) error {
|
||||||
rv.SetMapIndex(reflect.ValueOf(mapKeyLower), nv)
|
rv.SetMapIndex(reflect.ValueOf(mapKeyLower), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := load(env, envKey+"_"+mapKey, nv.Elem())
|
err := load(env, prefix+"_"+mapKey, nv.Elem())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ func load(env map[string]string, envKey string, rv reflect.Value) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err := load(env, envKey+"_"+strings.ToUpper(f.Name), rv.Field(i))
|
err := load(env, prefix+"_"+strings.ToUpper(f.Name), rv.Field(i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -135,12 +135,12 @@ func load(env map[string]string, envKey string, rv reflect.Value) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load fills a structure with data from the environment.
|
// Load fills a structure with data from the environment.
|
||||||
func Load(envKey string, v interface{}) error {
|
func Load(prefix string, v interface{}) error {
|
||||||
env := make(map[string]string)
|
env := make(map[string]string)
|
||||||
for _, kv := range os.Environ() {
|
for _, kv := range os.Environ() {
|
||||||
tmp := strings.SplitN(kv, "=", 2)
|
tmp := strings.SplitN(kv, "=", 2)
|
||||||
env[tmp[0]] = tmp[1]
|
env[tmp[0]] = tmp[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return load(env, envKey, reflect.ValueOf(v).Elem())
|
return load(env, prefix, reflect.ValueOf(v).Elem())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package confenv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mapEntry struct {
|
||||||
|
MyValue string
|
||||||
|
}
|
||||||
|
|
||||||
|
type testStruct struct {
|
||||||
|
// string
|
||||||
|
MyString string
|
||||||
|
|
||||||
|
// int
|
||||||
|
MyInt int
|
||||||
|
|
||||||
|
// bool
|
||||||
|
MyBool bool
|
||||||
|
|
||||||
|
// duration
|
||||||
|
MyDuration time.Duration
|
||||||
|
|
||||||
|
// slice
|
||||||
|
MySlice []string
|
||||||
|
|
||||||
|
// map
|
||||||
|
MyMap map[string]*mapEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test(t *testing.T) {
|
||||||
|
os.Setenv("MYPREFIX_MYSTRING", "testcontent")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYSTRING")
|
||||||
|
|
||||||
|
os.Setenv("MYPREFIX_MYINT", "123")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYINT")
|
||||||
|
|
||||||
|
os.Setenv("MYPREFIX_MYBOOL", "yes")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYBOOL")
|
||||||
|
|
||||||
|
os.Setenv("MYPREFIX_MYDURATION", "22s")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYDURATION")
|
||||||
|
|
||||||
|
os.Setenv("MYPREFIX_MYSLICE", "el1,el2")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYSLICE")
|
||||||
|
|
||||||
|
os.Setenv("MYPREFIX_MYMAP_MYKEY", "")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYMAP_MYKEY")
|
||||||
|
|
||||||
|
os.Setenv("MYPREFIX_MYMAP_MYKEY2_MYVALUE", "asd")
|
||||||
|
defer os.Unsetenv("MYPREFIX_MYMAP_MYKEY2_MYVALUE")
|
||||||
|
|
||||||
|
var s testStruct
|
||||||
|
err := Load("MYPREFIX", &s)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "testcontent", s.MyString)
|
||||||
|
require.Equal(t, 123, s.MyInt)
|
||||||
|
require.Equal(t, true, s.MyBool)
|
||||||
|
require.Equal(t, 22*time.Second, s.MyDuration)
|
||||||
|
require.Equal(t, []string{"el1", "el2"}, s.MySlice)
|
||||||
|
|
||||||
|
_, ok := s.MyMap["mykey"]
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
v, ok := s.MyMap["mykey2"]
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.Equal(t, "asd", v.MyValue)
|
||||||
|
}
|
Loading…
Reference in New Issue