From f3b9743b7deee0bfebe0facc99805871f7d50015 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Fri, 8 Jul 2016 14:02:18 +0200 Subject: [PATCH 1/4] Test action --- cmd/kappa/main.go | 4 +++ container/action/action.go | 8 ++++-- container/action/action_test.go | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 container/action/action_test.go diff --git a/cmd/kappa/main.go b/cmd/kappa/main.go index ff970fd..cffc5f3 100644 --- a/cmd/kappa/main.go +++ b/cmd/kappa/main.go @@ -22,6 +22,7 @@ func main() { app.Version = version.FullVersion() app.Author = "@opsfactory" app.Usage = "Native docker autoscaling for the most popular orchestration frameworks." + app.Flags = []cli.Flag{ cli.StringFlag{ Name: "config, C", @@ -32,6 +33,7 @@ func main() { Usage: "Enable debug logging", }, } + app.Before = func(c *cli.Context) error { if c.Bool("debug") { log.SetLevel(log.DebugLevel) @@ -45,6 +47,7 @@ func main() { return nil } + app.Action = func(ctx *cli.Context) error { log.Infof("Reading config from %s.", configFile) cfg, err := config.NewConfigFromFile(configFile) @@ -62,4 +65,5 @@ func main() { if err := app.Run(os.Args); err != nil { log.Fatal(err) } + } diff --git a/container/action/action.go b/container/action/action.go index 158fc50..f77a44e 100644 --- a/container/action/action.go +++ b/container/action/action.go @@ -21,6 +21,10 @@ type Action struct { } func (a Action) String() string { - return fmt.Sprintf("Action{Container: %s, Command: %s, Unit: %d}", - a.Container, a.Command, a.Unit) + return fmt.Sprintf( + "Action{Container: %s, Command: %s, Unit: %d}", + a.Container, + a.Command, + a.Unit, + ) } diff --git a/container/action/action_test.go b/container/action/action_test.go new file mode 100644 index 0000000..a2a75e0 --- /dev/null +++ b/container/action/action_test.go @@ -0,0 +1,43 @@ +package action + +import ( + "testing" + + "github.com/opsfactory/kappa/container" + "github.com/opsfactory/kappa/container/label" +) + +func TestActionString(t *testing.T) { + ct := container.NewContainer() + ct.Name = "john" + ct.Backend = container.MesosBackend + ct.Replicas = []string{} + ct.NumReplicas = 0 + ct.DesiredReplicas = 2 + lbls := label.NewLabelContainer() + lbls.Max = "10" + lbls.Min = "1" + lbls.Rate = "1" + lbls.Metric = "mymetric" + ct.Labels = lbls + + command := ScaleUp + var unit ActionUnit + unit = 1 + a := Action{ + Container: &ct, + Command: command, + Unit: unit, + } + + estr := "Action{Container: Container{Name: john, Labels: LabelContainer{Min: 1, Max: 10, Rate: 1, Metric: mymetric}, Replicas: [], NumReplicas: 0, DesiredReplicas: 2, Backend: mesos}, Command: ScaleUP, Unit: 1}" + + res := a.String() + if res != estr { + t.Errorf( + "Expected string and Action string does not match:\nExpected:%s\nGiven:%s", + estr, + res, + ) + } +} From e949da43f9e44a6e6d159747c1be0e3ce9cf2c3b Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Fri, 8 Jul 2016 14:52:06 +0200 Subject: [PATCH 2/4] Specialized config creation func --- config/config.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 8b0107a..190b0d2 100644 --- a/config/config.go +++ b/config/config.go @@ -33,13 +33,17 @@ func parse(y []byte) (Config, error) { return c, nil } +func NewConfigFromByteArray(config []byte) (Config, error) { + return parse(config) +} + func NewConfigFromFile(file string) (Config, error) { data, err := ioutil.ReadFile(file) if err != nil { log.Fatalf("Unable to read config file %s: %v.", file, err) return Config{}, nil } - return parse(data) + return NewConfigFromByteArray(data) } func (c Config) Print() { From 4db337e1b1285799a6175807aea99a9f44399fec Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Fri, 8 Jul 2016 15:29:21 +0200 Subject: [PATCH 3/4] Evh tests --- container/backend/docker/event_handler.go | 4 ++-- container/event/event.go | 24 +++++++++------------- container/event/event_test.go | 25 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 container/event/event_test.go diff --git a/container/backend/docker/event_handler.go b/container/backend/docker/event_handler.go index cc677d9..6a92261 100644 --- a/container/backend/docker/event_handler.go +++ b/container/backend/docker/event_handler.go @@ -15,7 +15,7 @@ func startHandlerBuilder(d *Docker, ech chan<- kappaevent.Event) handlerFunc { return } log.Debugf("[Docker][EventHandler][Start] ID: %s Name: %s Labels: %s", c.Replicas[0], c.Name, c.Labels) - ech <- kappaevent.NewContainerStartEvent(&c) + ech <- kappaevent.NewContainerStartEvent(c) } } @@ -26,6 +26,6 @@ func dieHandlerBuilder(d *Docker, ech chan<- kappaevent.Event) handlerFunc { return } log.Debugf("[Docker][EventHandler][Die] ID: %s Name: %s", c.Replicas[0], c.Name) - ech <- kappaevent.NewContainerDieEvent(&c) + ech <- kappaevent.NewContainerDieEvent(c) } } diff --git a/container/event/event.go b/container/event/event.go index 8c9727e..296825f 100644 --- a/container/event/event.go +++ b/container/event/event.go @@ -14,7 +14,7 @@ const ( ) type Event struct { - Container *container.Container + Container container.Container Type EventType } @@ -23,20 +23,16 @@ func (ev Event) String() string { ev.Container, ev.Type) } -func NewEvent() Event { - return Event{} +func newEvent(c container.Container, t EventType) Event { + return Event{ + Container: c, + Type: t, + } } - -func NewContainerStartEvent(c *container.Container) Event { - e := NewEvent() - e.Container = c - e.Type = ContainerStart - return e +func NewContainerStartEvent(c container.Container) Event { + return newEvent(c, ContainerStart) } -func NewContainerDieEvent(c *container.Container) Event { - e := NewEvent() - e.Container = c - e.Type = ContainerDie - return e +func NewContainerDieEvent(c container.Container) Event { + return newEvent(c, ContainerDie) } diff --git a/container/event/event_test.go b/container/event/event_test.go new file mode 100644 index 0000000..1721653 --- /dev/null +++ b/container/event/event_test.go @@ -0,0 +1,25 @@ +package event + +import ( + "testing" + + "github.com/opsfactory/kappa/container" +) + +func TestNewContainerStartEvent(t *testing.T) { + c := container.NewContainer() + ev := NewContainerStartEvent(c) + + if ev.Type != ContainerStart { + t.Error("event type should be `Start`, not: ", ev.Type) + } +} + +func TestNewContainerDieEvent(t *testing.T) { + c := container.NewContainer() + ev := NewContainerDieEvent(c) + + if ev.Type != ContainerDie { + t.Error("event type should be `Die`, not: ", ev.Type) + } +} From 4efd752a7c64caab7f8719be16411caa96f1c627 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Fri, 8 Jul 2016 17:08:39 +0200 Subject: [PATCH 4/4] Law of demeter FTW --- cmd/kappa/main.go | 8 ++++++-- engine/engine.go | 19 +++++++------------ engine/engine_test.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 engine/engine_test.go diff --git a/cmd/kappa/main.go b/cmd/kappa/main.go index cffc5f3..9caea57 100644 --- a/cmd/kappa/main.go +++ b/cmd/kappa/main.go @@ -4,6 +4,7 @@ import ( "os" "github.com/opsfactory/kappa/config" + "github.com/opsfactory/kappa/container/backend" "github.com/opsfactory/kappa/engine" "github.com/opsfactory/kappa/version" @@ -55,10 +56,13 @@ func main() { log.Fatalf("Unexpected error parsing configuration: %v", err) } - eng, err := engine.NewEngine(cfg) + b, err := backend.NewBackend(cfg.Backend, cfg.BackendConfig) if err != nil { - log.Fatalf("Unexpected error starting Kappa with the given configuration: %v", err) + log.Fatalf("Unable to create backend %s: %v", cfg.Backend, err) + return err } + + eng := engine.NewEngine(b) return eng.Run() } diff --git a/engine/engine.go b/engine/engine.go index ab3b38c..59e29c4 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -2,25 +2,17 @@ package engine import ( log "github.com/Sirupsen/logrus" - "github.com/opsfactory/kappa/config" "github.com/opsfactory/kappa/container/action" "github.com/opsfactory/kappa/container/backend" "github.com/opsfactory/kappa/container/event" ) type Engine struct { - cfg config.Config backend backend.Backend } -func NewEngine(cfg config.Config) (*Engine, error) { - b, err := backend.NewBackend(cfg.Backend, cfg.BackendConfig) - if err != nil { - log.Fatalf("Unable to create backend %s: %v", cfg.Backend, err) - return nil, err - } - - return &Engine{cfg: cfg, backend: b}, nil +func NewEngine(b backend.Backend) *Engine { + return &Engine{backend: b} } func (e Engine) Run() error { @@ -40,8 +32,11 @@ func (e Engine) Run() error { return nil } -func (e Engine) handleEvent(eventsChan <-chan event.Event, - actionsChan <-chan action.Action, errChan chan<- error) { +func (e Engine) handleEvent( + eventsChan <-chan event.Event, + actionsChan <-chan action.Action, + errChan chan<- error, +) { for ev := range eventsChan { log.Infof("[EVENT] %s", ev) } diff --git a/engine/engine_test.go b/engine/engine_test.go new file mode 100644 index 0000000..af87515 --- /dev/null +++ b/engine/engine_test.go @@ -0,0 +1,31 @@ +package engine + +import ( + "fmt" + "testing" + + "github.com/opsfactory/kappa/container/action" + "github.com/opsfactory/kappa/container/event" +) + +type stubBackend struct { +} + +func (b stubBackend) Monitor(eventsChan chan<- event.Event, errChan chan<- error) { + errChan <- fmt.Errorf("I am meant to interrupt") +} + +func (b stubBackend) Exec(eventsChan chan<- action.Action, errChan chan<- error) { + +} + +// TODO: update this tests once the actual Run function is in the process of being implemented +func TestEngineRun(t *testing.T) { + b := stubBackend{} + e := NewEngine(b) + res := e.Run() + + if res == nil { + t.Error("An error was expected") + } +}