func (self *taskHistoryIterator) GetDistinctTestNames(numCommits int) ([]string, error) { session, db, err := db.GetGlobalSessionFactory().GetSession() defer session.Close() pipeline := db.C(TasksCollection).Pipe( []bson.M{ { "$match": bson.M{ TaskBuildVariantKey: bson.M{"$in": self.BuildVariants}, TaskDisplayNameKey: self.TaskName, }, }, bson.M{"$sort": bson.D{{TaskRevisionOrderNumberKey, -1}}}, bson.M{"$limit": numCommits}, bson.M{"$unwind": fmt.Sprintf("$%v", TaskTestResultsKey)}, bson.M{"$group": bson.M{"_id": fmt.Sprintf("$%v.%v", TaskTestResultsKey, TestResultTestFileKey)}}, }, ) var output []bson.M err = pipeline.All(&output) if err != nil { return nil, err } names := make([]string, 0) for _, doc := range output { names = append(names, doc["_id"].(string)) } return names, nil }
// finds a bookkeeping entry matching the specified interface func findOneTaskBk(matcher interface{}, selector interface{}) (*TaskBookkeeping, error) { // establish a database connection session, db, err := db.GetGlobalSessionFactory().GetSession() if err != nil { evergreen.Logger.Errorf(slogger.ERROR, "Error establishing database connection: %v", err) return nil, err } // make sure the function is closed when the function exits defer session.Close() // query for the bookkeeping entry taskBk := &TaskBookkeeping{} err = db.C(TaskBookkeepingCollection).Find(matcher).Select(selector).One(taskBk) // no entry was found if err == mgo.ErrNotFound { return nil, nil } // failure if err != nil { evergreen.Logger.Errorf(slogger.ERROR, "Unexpected error retrieving task bookkeeping entry from database: %v", err) return nil, err } // success return taskBk, nil }
func (self *TaskLog) AddLogMessage(msg LogMessage) error { session, db, err := getSessionAndDB() if err != nil { return err } defer session.Close() // set the mode to unsafe - it's not a total disaster // if this gets lost and it'll save bandwidth session.SetSafe(nil) self.Messages = append(self.Messages, msg) self.MessageCount = self.MessageCount + 1 return db.C(TaskLogCollection).UpdateId(self.Id, bson.M{ "$inc": bson.M{ TaskLogMessageCountKey: 1, }, "$push": bson.M{ TaskLogMessagesKey: msg, }, }, ) }
func (self *TaskLog) Insert() error { session, db, err := getSessionAndDB() if err != nil { return err } defer session.Close() return db.C(TaskLogCollection).Insert(self) }
// upsert a single bookkeeping entry func upsertOneTaskBk(matcher interface{}, update interface{}) error { // establish a database connection session, db, err := db.GetGlobalSessionFactory().GetSession() if err != nil { evergreen.Logger.Errorf(slogger.ERROR, "Error establishing database connection: %v", err) return err } // make sure the session is closed when the function exits defer session.Close() // update the bookkeeping entry _, err = db.C(TaskBookkeepingCollection).Upsert(matcher, update) return err }
func FindMostRecentTaskLogs(taskId string, execution int, limit int) ([]TaskLog, error) { session, db, err := getSessionAndDB() if err != nil { return nil, err } defer session.Close() result := []TaskLog{} err = db.C(TaskLogCollection).Find( bson.M{ TaskLogTaskIdKey: taskId, TaskLogExecutionKey: execution, }, ).Sort("-" + TaskLogTimestampKey).Limit(limit).All(&result) if err == mgo.ErrNotFound { return nil, nil } return result, err }
func FindTaskLogsBeforeTime(taskId string, execution int, ts time.Time, limit int) ([]TaskLog, error) { session, db, err := getSessionAndDB() if err != nil { return nil, err } defer session.Close() query := bson.M{ TaskLogTaskIdKey: taskId, TaskLogExecutionKey: execution, TaskLogTimestampKey: bson.M{ "$lt": ts, }, } result := []TaskLog{} err = db.C(TaskLogCollection).Find(query).Sort("-" + TaskLogTimestampKey).Limit(limit).All(&result) if err == mgo.ErrNotFound { return nil, nil } return result, err }
func GetRawTaskLogChannel(taskId string, execution int, severities []string, msgTypes []string) (chan LogMessage, error) { session, db, err := getSessionAndDB() if err != nil { return nil, err } logObj := TaskLog{} // 100 is an arbitrary magic number. Unbuffered channel would be bad for // performance, so just picked a buffer size out of thin air. channel := make(chan LogMessage, 100) // TODO(EVG-227) var query bson.M if execution == 0 { query = bson.M{"$and": []bson.M{ {TaskLogTaskIdKey: taskId}, {"$or": []bson.M{ {TaskLogExecutionKey: 0}, {TaskLogExecutionKey: nil}, }}}} } else { query = bson.M{ TaskLogTaskIdKey: taskId, TaskLogExecutionKey: execution, } } iter := db.C(TaskLogCollection).Find(query).Sort(TaskLogTimestampKey).Iter() oldMsgTypes := []string{} for _, msgType := range msgTypes { switch msgType { case SystemLogPrefix: oldMsgTypes = append(oldMsgTypes, "system") case AgentLogPrefix: oldMsgTypes = append(oldMsgTypes, "agent") case TaskLogPrefix: oldMsgTypes = append(oldMsgTypes, "task") } } go func() { defer session.Close() defer close(channel) defer iter.Close() for iter.Next(&logObj) { for _, logMsg := range logObj.Messages { if len(severities) > 0 && !util.SliceContains(severities, logMsg.Severity) { continue } if len(msgTypes) > 0 { if !(util.SliceContains(msgTypes, logMsg.Type) || util.SliceContains(oldMsgTypes, logMsg.Type)) { continue } } channel <- logMsg } } }() return channel, nil }