diff options
Diffstat (limited to 'service/container_test.go')
-rw-r--r-- | service/container_test.go | 534 |
1 files changed, 0 insertions, 534 deletions
diff --git a/service/container_test.go b/service/container_test.go deleted file mode 100644 index f990b2cb..00000000 --- a/service/container_test.go +++ /dev/null @@ -1,534 +0,0 @@ -package service - -import ( - "errors" - "sync" - "testing" - "time" - - json "github.com/json-iterator/go" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/assert" -) - -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") -} |