// ensureAppIsStarted make sure that the app and all units present in the given // message are started. func ensureAppIsStarted(msg *queue.Message) (App, error) { app, err := GetByName(msg.Args[0]) if err != nil { return App{}, fmt.Errorf("Error handling %q: app %q does not exist.", msg.Action, msg.Args[0]) } units := getUnits(app, msg.Args[1:]) if len(msg.Args) > 1 && len(units) == 0 { format := "Error handling %q for the app %q: unknown units in the message. Deleting it..." return *app, fmt.Errorf(format, msg.Action, app.Name) } if !app.Available() || !units.Started() { format := "Error handling %q for the app %q:" uState := units.State() if uState == "error" || uState == "down" { format += fmt.Sprintf(" units are in %q state.", uState) } else { msg.Fail() format += " all units must be started." } return *app, fmt.Errorf(format, msg.Action, app.Name) } return *app, nil }
func (s *S) TestHandleMessageErrors(c *gocheck.C) { var data = []struct { action string args []string unitName string expectedLog string }{ { action: "unknown-action", args: []string{"does not matter"}, expectedLog: `Error handling "unknown-action": invalid action.`, }, { action: startApp, args: []string{"nemesis"}, expectedLog: `Error handling "start-app" for the app "nemesis":` + ` all units must be started.`, }, { action: startApp, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "start-app" for the app "totem":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"nemesis"}, expectedLog: `Error handling "regenerate-apprc" for the app "nemesis":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "regenerate-apprc" for the app "totem":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"unknown-app"}, expectedLog: `Error handling "regenerate-apprc": app "unknown-app" does not exist.`, }, { action: regenerateApprc, expectedLog: `Error handling "regenerate-apprc": this action requires at least 1 argument.`, }, { action: regenerateApprc, args: []string{"marathon", "marathon/0"}, expectedLog: `Error handling "regenerate-apprc" for the app "marathon":` + ` units are in "error" state.`, }, { action: regenerateApprc, args: []string{"territories", "territories/0"}, expectedLog: `Error handling "regenerate-apprc" for the app "territories":` + ` units are in "down" state.`, }, } a := App{Name: "nemesis"} err := s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{ Name: "totem", Units: []Unit{ {Name: "totem/0", State: "pending"}, {Name: "totem/1", State: "started"}, }, } err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "marathon", Units: []Unit{{Name: "marathon/0", State: "error"}}} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "territories", Units: []Unit{{Name: "territories/0", State: "down"}}} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) logger := testing.NewFakeLogger().(*testing.FakeLogger) for _, d := range data { message := queue.Message{Action: d.action} if len(d.args) > 0 { message.Args = d.args } handle(&message) } content := logger.Buf.String() lines := strings.Split(content, "\n") for i, d := range data { if lines[i] != d.expectedLog { c.Errorf("\nWant: %q.\nGot:\n%s", d.expectedLog, content) } } }
func (s *S) TestHandleMessageErrors(c *gocheck.C) { var data = []struct { action string args []string unitName string expectedLog string }{ { action: "unknown-action", args: []string{"does not matter"}, expectedLog: `Error handling "unknown-action": invalid action.`, }, { action: startApp, args: []string{"nemesis"}, expectedLog: `Error handling "start-app" for the app "nemesis":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"nemesis"}, expectedLog: `Error handling "regenerate-apprc" for the app "nemesis":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"unknown-app"}, expectedLog: `Error handling "regenerate-apprc": app "unknown-app" does not exist.`, }, { action: regenerateApprc, expectedLog: `Error handling "regenerate-apprc": this action requires at least 1 argument.`, }, { action: regenerateApprc, args: []string{"marathon", "marathon/0"}, expectedLog: `Error handling "regenerate-apprc" for the app "marathon":` + ` units are in "error" state.`, }, { action: regenerateApprc, args: []string{"territories", "territories/0"}, expectedLog: `Error handling "regenerate-apprc" for the app "territories":` + ` units are in "down" state.`, }, { action: startApp, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "start-app" for the app "totem":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "regenerate-apprc" for the app "totem":` + ` all units must be started.`, }, } a := App{Name: "nemesis"} err := s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "totem"} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) s.provisioner.AddUnit(&a, provision.Unit{Name: "totem/0", Status: provision.StatusBuilding}) s.provisioner.AddUnit(&a, provision.Unit{Name: "totem/1", Status: provision.StatusStarted}) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "marathon"} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) s.provisioner.AddUnit(&a, provision.Unit{Name: "marathon/0", Status: provision.StatusError, Type: "python"}) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "territories"} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) s.provisioner.AddUnit(&a, provision.Unit{Name: "territories/0", Status: provision.StatusDown}) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) for _, d := range data { logger := testing.NewFakeLogger().(*testing.FakeLogger) message := queue.Message{Action: d.action} if len(d.args) > 0 { message.Args = d.args } handle(&message) content := strings.Replace(logger.Buf.String(), "\n", "", -1) c.Check(content, gocheck.Equals, d.expectedLog) } }