2021-10-26 23:04:03 +03:00
|
|
|
package env
|
2020-12-04 02:37:48 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"os"
|
2020-12-20 00:26:18 +03:00
|
|
|
"testing"
|
2021-11-24 01:21:55 +03:00
|
|
|
"time"
|
2020-12-20 00:26:18 +03:00
|
|
|
|
2023-05-05 17:40:52 +03:00
|
|
|
"go.unistack.org/micro/v4/config"
|
|
|
|
rutil "go.unistack.org/micro/v4/util/reflect"
|
2020-12-04 02:37:48 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type Config struct {
|
2022-11-26 15:38:29 +03:00
|
|
|
StringValue string `env:"STRING_VALUE,STRING_VALUE2"`
|
2020-12-20 00:26:18 +03:00
|
|
|
BoolValue bool `env:"BOOL_VALUE"`
|
|
|
|
StringSlice []string `env:"STRING_SLICE"`
|
|
|
|
IntSlice []int `env:"INT_SLICE"`
|
2020-12-04 22:41:46 +03:00
|
|
|
MapStringValue map[string]string `env:"MAP_STRING"`
|
2020-12-20 00:26:18 +03:00
|
|
|
MapIntValue map[string]int `env:"MAP_INT"`
|
2020-12-04 02:37:48 +03:00
|
|
|
}
|
|
|
|
|
2021-11-24 01:21:55 +03:00
|
|
|
func TestMerge(t *testing.T) {
|
2022-11-26 15:38:29 +03:00
|
|
|
defer func() {
|
|
|
|
for _, v := range []string{"STRING_VALUE", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2021-11-24 01:21:55 +03:00
|
|
|
ctx := context.Background()
|
|
|
|
type Nested struct {
|
|
|
|
Name string `env:"NAME_VALUE"`
|
|
|
|
}
|
|
|
|
type Cfg struct {
|
|
|
|
Name string `env:"NAME_VALUE"`
|
|
|
|
Nested Nested
|
|
|
|
}
|
|
|
|
|
|
|
|
conf := &Cfg{}
|
|
|
|
|
|
|
|
cfg := NewConfig(config.Struct(conf))
|
|
|
|
|
|
|
|
if err := cfg.Init(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cfg.Load(ctx, config.LoadOverride(true), config.LoadAppend(true)); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
w, err := cfg.Watch(ctx, config.WatchInterval(50*time.Millisecond, 500*time.Millisecond))
|
|
|
|
defer func() {
|
|
|
|
if err := w.Stop(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}()
|
2022-11-26 15:38:29 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2021-11-24 01:21:55 +03:00
|
|
|
|
|
|
|
os.Setenv("NAME_VALUE", "after")
|
|
|
|
changes, err := w.Next()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, v := range changes {
|
|
|
|
if err := rutil.SetFieldByPath(conf, v, k); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.Name != "after" || conf.Nested.Name != "after" {
|
|
|
|
t.Fatalf("changes %#+v not applied to %#+v", changes, conf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-08 19:38:03 +03:00
|
|
|
func TestLoad(t *testing.T) {
|
2022-11-26 15:38:29 +03:00
|
|
|
defer func() {
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2020-12-04 02:37:48 +03:00
|
|
|
ctx := context.Background()
|
|
|
|
conf := &Config{StringValue: "before_load"}
|
2021-10-26 23:04:03 +03:00
|
|
|
cfg := NewConfig(config.Struct(conf))
|
2020-12-04 02:37:48 +03:00
|
|
|
|
|
|
|
if err := cfg.Init(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-06-22 01:39:38 +03:00
|
|
|
if err := cfg.Load(ctx, config.LoadOverride(true), config.LoadAppend(true)); err != nil {
|
2020-12-04 02:37:48 +03:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.StringValue != "before_load" {
|
2020-12-20 00:26:18 +03:00
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf)
|
2020-12-04 02:37:48 +03:00
|
|
|
}
|
|
|
|
|
2020-12-20 00:26:18 +03:00
|
|
|
os.Setenv("STRING_VALUE", "STRING_VALUE")
|
|
|
|
os.Setenv("BOOL_VALUE", "true")
|
2020-12-04 21:52:21 +03:00
|
|
|
os.Setenv("STRING_SLICE", "STRING_SLICE1,STRING_SLICE2;STRING_SLICE3")
|
|
|
|
os.Setenv("INT_SLICE", "1,2,3,4,5")
|
2020-12-04 22:41:46 +03:00
|
|
|
os.Setenv("MAP_STRING", "key1=val1,key2=val2")
|
2020-12-04 22:44:00 +03:00
|
|
|
os.Setenv("MAP_INT", "key1=1,key2=2")
|
2020-12-04 02:37:48 +03:00
|
|
|
|
2021-06-22 01:39:38 +03:00
|
|
|
if err := cfg.Load(ctx, config.LoadOverride(true), config.LoadAppend(true)); err != nil {
|
2020-12-04 02:37:48 +03:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if conf.StringValue != "STRING_VALUE" {
|
2020-12-20 00:26:18 +03:00
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf)
|
2020-12-04 02:37:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if !conf.BoolValue {
|
2020-12-20 00:26:18 +03:00
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf)
|
2020-12-04 02:37:48 +03:00
|
|
|
}
|
|
|
|
|
2020-12-04 21:52:21 +03:00
|
|
|
if len(conf.StringSlice) != 3 {
|
2020-12-20 00:26:18 +03:00
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf.StringSlice)
|
2020-12-04 02:37:48 +03:00
|
|
|
}
|
2020-12-04 21:52:21 +03:00
|
|
|
|
2020-12-04 22:44:00 +03:00
|
|
|
if len(conf.MapStringValue) != 2 {
|
2020-12-20 00:26:18 +03:00
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf.MapStringValue)
|
2020-12-04 22:44:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(conf.MapIntValue) != 2 {
|
2020-12-20 00:26:18 +03:00
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf.MapIntValue)
|
2020-12-04 22:44:00 +03:00
|
|
|
}
|
2022-11-26 15:38:29 +03:00
|
|
|
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2020-12-04 02:37:48 +03:00
|
|
|
}
|
2021-10-26 23:04:03 +03:00
|
|
|
|
2021-05-08 19:38:03 +03:00
|
|
|
func TestSave(t *testing.T) {
|
2022-11-26 15:38:29 +03:00
|
|
|
defer func() {
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2021-05-08 19:38:03 +03:00
|
|
|
ctx := context.Background()
|
|
|
|
conf := &Config{StringValue: "MICRO_CONFIG_ENV"}
|
2021-10-26 23:04:03 +03:00
|
|
|
cfg := NewConfig(config.Struct(conf))
|
2021-05-08 19:38:03 +03:00
|
|
|
|
|
|
|
if err := cfg.Init(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := os.LookupEnv("STRING_VALUE"); ok {
|
|
|
|
if err := os.Unsetenv("STRING_VALUE"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.Unsetenv("STRING_VALUE"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cfg.Save(ctx); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := os.LookupEnv("STRING_VALUE"); !ok {
|
|
|
|
t.Fatal("env value STRING_VALUE=MICRO_CONFIG_ENV not set")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.Unsetenv("STRING_VALUE"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tv := range []string{"STRING_VALUE", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if v, ok := os.LookupEnv("STRING_VALUE"); ok {
|
|
|
|
t.Fatalf("env value %s=%s set", tv, v)
|
|
|
|
}
|
|
|
|
}
|
2022-11-26 15:38:29 +03:00
|
|
|
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLoadMultiple(t *testing.T) {
|
|
|
|
defer func() {
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
conf := &Config{StringValue: "before_load"}
|
|
|
|
cfg := NewConfig(config.Struct(conf))
|
|
|
|
|
|
|
|
if err := cfg.Init(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cfg.Load(ctx, config.LoadOverride(true), config.LoadAppend(true)); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.StringValue != "before_load" {
|
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf)
|
|
|
|
}
|
|
|
|
|
|
|
|
os.Setenv("STRING_VALUE", "STRING_VALUE1")
|
|
|
|
os.Setenv("STRING_VALUE2", "STRING_VALUE2")
|
|
|
|
defer func() {
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
if err := cfg.Load(ctx, config.LoadOverride(true), config.LoadAppend(true)); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if conf.StringValue != "STRING_VALUE2" {
|
|
|
|
t.Fatalf("something wrong with env config: %#+v", conf)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range []string{"STRING_VALUE", "STRING_VALUE2", "BOOL_VALUE", "STRING_SLICE", "INT_SLICE", "MAP_STRING", "MAP_INT"} {
|
|
|
|
if err := os.Unsetenv(v); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2021-05-08 19:38:03 +03:00
|
|
|
}
|