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
}
Exemple #3
0
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,
			},
		},
	)
}
Exemple #4
0
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
}
Exemple #6
0
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
}
Exemple #7
0
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
}
Exemple #8
0
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
}