summaryrefslogtreecommitdiff
path: root/_old/container_test.go
diff options
context:
space:
mode:
Diffstat (limited to '_old/container_test.go')
-rw-r--r--_old/container_test.go533
1 files changed, 533 insertions, 0 deletions
diff --git a/_old/container_test.go b/_old/container_test.go
new file mode 100644
index 00000000..2f860c41
--- /dev/null
+++ b/_old/container_test.go
@@ -0,0 +1,533 @@
+package _old
+
+import (
+ "errors"
+ json "github.com/json-iterator/go"
+ "github.com/sirupsen/logrus"
+ "github.com/sirupsen/logrus/hooks/test"
+ "github.com/stretchr/testify/assert"
+ "sync"
+ "testing"
+ "time"
+)
+
+type testService struct {
+ mu sync.Mutex
+ waitForServe chan interface{}
+ delay time.Duration
+ ok bool
+ cfg Config
+ c Container
+ cfgE, serveE error
+ done chan interface{}
+}
+
+func (t *testService) Init(cfg Config, c Container) (enabled bool, err error) {
+ t.cfg = cfg
+ t.c = c
+ t.done = make(chan interface{})
+ return t.ok, t.cfgE
+}
+
+func (t *testService) Serve() error {
+ time.Sleep(t.delay)
+
+ if t.serveE != nil {
+ return t.serveE
+ }
+
+ if c := t.waitChan(); c != nil {
+ close(c)
+ t.setChan(nil)
+ }
+
+ <-t.done
+ return nil
+}
+
+func (t *testService) Stop() {
+ close(t.done)
+}
+
+func (t *testService) waitChan() chan interface{} {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+
+ return t.waitForServe
+}
+
+func (t *testService) setChan(c chan interface{}) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+
+ t.waitForServe = c
+}
+
+type testCfg struct{ cfg string }
+
+func (cfg *testCfg) Get(name string) Config {
+ vars := make(map[string]interface{})
+ j := json.ConfigCompatibleWithStandardLibrary
+ err := j.Unmarshal([]byte(cfg.cfg), &vars)
+ if err != nil {
+ panic("error unmarshalling the cfg.cfg value")
+ }
+
+ v, ok := vars[name]
+ if !ok {
+ return nil
+ }
+
+ d, _ := j.Marshal(v)
+ return &testCfg{cfg: string(d)}
+}
+func (cfg *testCfg) Unmarshal(out interface{}) error {
+ j := json.ConfigCompatibleWithStandardLibrary
+ return j.Unmarshal([]byte(cfg.cfg), out)
+}
+
+// Config defines RPC service config.
+type dConfig struct {
+ // Indicates if RPC connection is enabled.
+ Value string
+}
+
+// Hydrate must populate Config values using given Config source. Must return error if Config is not valid.
+func (c *dConfig) Hydrate(cfg Config) error {
+ return cfg.Unmarshal(c)
+}
+
+// InitDefaults allows to init blank config with pre-defined set of default values.
+func (c *dConfig) InitDefaults() error {
+ c.Value = "default"
+
+ return nil
+}
+
+type dService struct {
+ Cfg *dConfig
+}
+
+func (s *dService) Init(cfg *dConfig) (bool, error) {
+ s.Cfg = cfg
+ return true, nil
+}
+
+func TestContainer_Register(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testService{})
+
+ assert.Equal(t, 0, len(hook.Entries))
+}
+
+func TestContainer_Has(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testService{})
+
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.True(t, c.Has("test"))
+ assert.False(t, c.Has("another"))
+}
+
+func TestContainer_List(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testService{})
+
+ assert.Equal(t, 0, len(hook.Entries))
+ assert.Equal(t, 1, len(c.List()))
+
+ assert.True(t, c.Has("test"))
+ assert.False(t, c.Has("another"))
+}
+
+func TestContainer_Get(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testService{})
+ assert.Equal(t, 0, len(hook.Entries))
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusInactive, st)
+
+ s, st = c.Get("another")
+ assert.Nil(t, s)
+ assert.Equal(t, StatusUndefined, st)
+}
+
+func TestContainer_Stop_NotStarted(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testService{})
+ assert.Equal(t, 0, len(hook.Entries))
+
+ c.Stop()
+}
+
+func TestContainer_Configure(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{ok: true}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`}))
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusOK, st)
+}
+
+func TestContainer_Init_Default(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &dService{}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.NoError(t, c.Init(&testCfg{`{}`}))
+
+ s, st := c.Get("test")
+ assert.IsType(t, &dService{}, s)
+ assert.Equal(t, StatusOK, st)
+
+ assert.Equal(t, "default", svc.Cfg.Value)
+}
+
+func TestContainer_Init_Default_Overwrite(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &dService{}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.NoError(t, c.Init(&testCfg{`{"test":{"value": "something"}}`}))
+
+ s, st := c.Get("test")
+ assert.IsType(t, &dService{}, s)
+ assert.Equal(t, StatusOK, st)
+
+ assert.Equal(t, "something", svc.Cfg.Value)
+}
+
+func TestContainer_ConfigureNull(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{ok: true}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.NoError(t, c.Init(&testCfg{`{"another":"something"}`}))
+ assert.Equal(t, 1, len(hook.Entries))
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusInactive, st)
+}
+
+func TestContainer_ConfigureDisabled(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{ok: false}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`}))
+ assert.Equal(t, 1, len(hook.Entries))
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusInactive, st)
+}
+
+func TestContainer_ConfigureError(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{
+ ok: false,
+ cfgE: errors.New("configure error"),
+ }
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ err := c.Init(&testCfg{`{"test":"something"}`})
+ assert.Error(t, err)
+ assert.Contains(t, err.Error(), "configure error")
+ assert.Contains(t, err.Error(), "test")
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusInactive, st)
+}
+
+func TestContainer_ConfigureTwice(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{ok: true}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`}))
+ assert.Error(t, c.Init(&testCfg{`{"test":"something"}`}))
+}
+
+// bug #276 test
+func TestContainer_ServeEmptyContainer(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{ok: true}
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+
+ go assert.NoError(t, c.Serve())
+
+ time.Sleep(time.Millisecond * 500)
+
+ c.Stop()
+}
+
+func TestContainer_Serve(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{
+ ok: true,
+ waitForServe: make(chan interface{}),
+ }
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`}))
+
+ go func() {
+ assert.NoError(t, c.Serve())
+ }()
+
+ <-svc.waitChan()
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusServing, st)
+
+ c.Stop()
+
+ s, st = c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusStopped, st)
+}
+
+func TestContainer_ServeError(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{
+ ok: true,
+ waitForServe: make(chan interface{}),
+ serveE: errors.New("serve error"),
+ }
+
+ c := NewContainer(logger)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`}))
+
+ err := c.Serve()
+ assert.Error(t, err)
+ assert.Contains(t, err.Error(), "serve error")
+ assert.Contains(t, err.Error(), "test")
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusStopped, st)
+}
+
+func TestContainer_ServeErrorMultiple(t *testing.T) {
+ logger, hook := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ svc := &testService{
+ ok: true,
+ delay: time.Millisecond * 10,
+ waitForServe: make(chan interface{}),
+ serveE: errors.New("serve error"),
+ }
+
+ svc2 := &testService{
+ ok: true,
+ waitForServe: make(chan interface{}),
+ }
+
+ c := NewContainer(logger)
+ c.Register("test2", svc2)
+ c.Register("test", svc)
+ assert.Equal(t, 0, len(hook.Entries))
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something", "test2":"something-else"}`}))
+
+ err := c.Serve()
+ assert.Error(t, err)
+ assert.Contains(t, err.Error(), "serve error")
+ assert.Contains(t, err.Error(), "test")
+
+ s, st := c.Get("test")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusStopped, st)
+
+ s, st = c.Get("test2")
+ assert.IsType(t, &testService{}, s)
+ assert.Equal(t, StatusStopped, st)
+}
+
+type testInitA struct{}
+
+func (t *testInitA) Init() error {
+ return nil
+}
+
+type testInitB struct{}
+
+func (t *testInitB) Init() (int, error) {
+ return 0, nil
+}
+
+func TestContainer_InitErrorA(t *testing.T) {
+ logger, _ := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testInitA{})
+
+ assert.Error(t, c.Init(&testCfg{`{"test":"something", "test2":"something-else"}`}))
+}
+
+func TestContainer_InitErrorB(t *testing.T) {
+ logger, _ := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testInitB{})
+
+ assert.Error(t, c.Init(&testCfg{`{"test":"something", "test2":"something-else"}`}))
+}
+
+type testInitC struct{}
+
+func (r *testInitC) Test() bool {
+ return true
+}
+
+func TestContainer_NoInit(t *testing.T) {
+ logger, _ := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testInitC{})
+
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something", "test2":"something-else"}`}))
+}
+
+type testInitD struct {
+ c *testInitC //nolint:golint,unused,structcheck
+}
+
+type DCfg struct {
+ V string
+}
+
+// Hydrate must populate Config values using given Config source. Must return error if Config is not valid.
+func (c *DCfg) Hydrate(cfg Config) error {
+ if err := cfg.Unmarshal(c); err != nil {
+ return err
+ }
+ if c.V == "fail" {
+ return errors.New("failed config")
+ }
+
+ return nil
+}
+
+func (t *testInitD) Init(r *testInitC, c Container, cfg *DCfg) (bool, error) {
+ if r == nil {
+ return false, errors.New("unable to find testInitC")
+ }
+
+ if c == nil {
+ return false, errors.New("unable to find Container")
+ }
+
+ if cfg.V != "ok" {
+ return false, errors.New("invalid config")
+ }
+
+ return false, nil
+}
+
+func TestContainer_InitDependency(t *testing.T) {
+ logger, _ := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testInitC{})
+ c.Register("test2", &testInitD{})
+
+ assert.NoError(t, c.Init(&testCfg{`{"test":"something", "test2":{"v":"ok"}}`}))
+}
+
+func TestContainer_InitDependencyFail(t *testing.T) {
+ logger, _ := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test", &testInitC{})
+ c.Register("test2", &testInitD{})
+
+ assert.Error(t, c.Init(&testCfg{`{"test":"something", "test2":{"v":"fail"}}`}))
+}
+
+func TestContainer_InitDependencyEmpty(t *testing.T) {
+ logger, _ := test.NewNullLogger()
+ logger.SetLevel(logrus.DebugLevel)
+
+ c := NewContainer(logger)
+ c.Register("test2", &testInitD{})
+
+ assert.Contains(t, c.Init(&testCfg{`{"test2":{"v":"ok"}}`}).Error(), "testInitC")
+}