func TestAlertQueue(t *testing.T) { Convey("After queueing a few alerts", t, func() { db.Clear(alert.Collection) now := time.Now() // a bunch of alerts, in order of oldest to newest testAlerts := []*alert.AlertRequest{ {Id: bson.NewObjectId(), Display: "test1", CreatedAt: now.Add(time.Millisecond)}, {Id: bson.NewObjectId(), Display: "test2", CreatedAt: now.Add(2 * time.Millisecond)}, {Id: bson.NewObjectId(), Display: "test3", CreatedAt: now.Add(3 * time.Millisecond)}, } for _, a := range testAlerts { err := alert.EnqueueAlertRequest(a) So(err, ShouldBeNil) } Convey("dequeuing should return them in order, oldest first", func() { found := 0 for { nextAlert, err := alert.DequeueAlertRequest() So(err, ShouldBeNil) if nextAlert == nil { break } So(nextAlert.Display, ShouldEqual, testAlerts[found].Display) So(nextAlert.QueueStatus, ShouldEqual, alert.InProgress) found++ } So(found, ShouldEqual, len(testAlerts)) }) }) }
// Run loops while there are any unprocessed alerts and attempts to deliver them. func (qp *QueueProcessor) Run(config *evergreen.Settings) error { evergreen.Logger.Logf(slogger.INFO, "Starting alert queue processor run") home := evergreen.FindEvergreenHome() qp.config = config qp.render = render.New(render.Options{ Directory: filepath.Join(home, "alerts", "templates"), DisableCache: !config.Ui.CacheTemplates, TextFuncs: nil, HtmlFuncs: nil, }) if len(qp.config.SuperUsers) == 0 { evergreen.Logger.Logf(slogger.WARN, "WARNING: No superusers configured, some alerts may have no recipient") } superUsers, err := user.Find(user.ByIds(qp.config.SuperUsers...)) if err != nil { evergreen.Logger.Logf(slogger.ERROR, "Error getting superuser list: %v", err) return err } qp.superUsersConfigs = []model.AlertConfig{} for _, u := range superUsers { qp.superUsersConfigs = append(qp.superUsersConfigs, model.AlertConfig{"email", bson.M{"rcpt": u.Email()}}) } evergreen.Logger.Logf(slogger.INFO, "Super-users config for outgoing alerts is: %#v", qp.superUsersConfigs) evergreen.Logger.Logf(slogger.INFO, "Running alert queue processing") for { nextAlert, err := alert.DequeueAlertRequest() if err != nil { evergreen.Logger.Logf(slogger.ERROR, "Failed to dequeue alert request: %v", err) return err } if nextAlert == nil { evergreen.Logger.Logf(slogger.INFO, "Reached end of queue items - stopping.") break } evergreen.Logger.Logf(slogger.DEBUG, "Processing queue item %v", nextAlert.Id.Hex()) alertContext, err := qp.loadAlertContext(nextAlert) if err != nil { evergreen.Logger.Logf(slogger.ERROR, "Failed to load alert context: %v", err) return err } evergreen.Logger.Logf(slogger.DEBUG, "Delivering queue item %v", nextAlert.Id.Hex()) err = qp.Deliver(nextAlert, alertContext) if err != nil { evergreen.Logger.Logf(slogger.ERROR, "Got error delivering message: %v", err) } } evergreen.Logger.Logf(slogger.INFO, "Finished alert queue processor run.") return nil }