conf: rewrite tests

This commit is contained in:
aler9 2021-05-09 17:51:38 +02:00
parent 163424dc32
commit cd9792fec0
3 changed files with 95 additions and 97 deletions

View File

@ -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")

View File

@ -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())
} }

View File

@ -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)
}