예제 #1
0
// update incorporates the given restuls into the current results for this
// issue.
func (t *TryBotResults) update(botParams map[string]string, patchset int64, testResults []*goldingester.Result, timeStamp int64) {
	botId, err := util.MD5Params(botParams)
	if err != nil {
		glog.Errorf("Unable to hash bot parameters \n\n%v\n\n. Error: %s", botParams, err)
		return
	}

	current, ok := t.Bots[botId]
	if !ok || (current.TS < timeStamp) {
		// Replace the current entry for this bot.
		current = &BotResults{
			BotParams: botParams,
			Patchset:  patchset,
		}

		botTestResults := []*TestResult{}
		for _, result := range testResults {
			params := util.AddParams(result.Key, result.Options)
			if !goldingester.IgnoreResult(params) {
				botTestResults = append(botTestResults, &TestResult{
					Params: params,
					digest: result.Digest,
				})
			}
		}

		current.TestResults = botTestResults
		current.TS = timeStamp
		t.Bots[botId] = current
	}
}
예제 #2
0
// getTraceDBEntries returns a map of tracedb.Entry instances.
func (b *BenchData) getTraceDBEntries() map[string]*tracedb.Entry {
	ret := make(map[string]*tracedb.Entry, len(b.Results))
	keyPrefix := b.keyPrefix()
	for testName, allConfigs := range b.Results {
		for configName, result := range allConfigs {
			key := fmt.Sprintf("%s:%s:%s", keyPrefix, testName, configName)

			// Construct the Traces params from all the options.
			params := util.CopyStringMap(b.Key)
			params["test"] = testName
			params["config"] = configName
			util.AddParams(params, b.Options)

			// If there is an options map inside the result add it to the params.
			if resultOptions, ok := result["options"]; ok {
				if opts, ok := resultOptions.(map[string]interface{}); ok {
					for k, vi := range opts {
						if s, ok := vi.(string); ok {
							params[k] = s
						}
					}
				}
			}

			// We used to just pick out only "min_ms" as the only result of a bunch
			// of key, value pairs in the result, such as max_ms, mean_ms, etc. Now
			// nanobench uploads only the metrics we are interested in, so we need to
			// use all the values there, except 'options'.
			for k, vi := range result {
				if k == "options" {
					continue
				}

				floatVal, ok := vi.(float64)
				if !ok {
					glog.Errorf("Found a non-float64 in %s", key)
					continue
				}

				params["sub_result"] = k
				perResultKey := key
				if k != "min_ms" {
					perResultKey = fmt.Sprintf("%s:%s", perResultKey, k)
				}
				paramsCopy := util.CopyStringMap(params)
				ret[perResultKey] = &tracedb.Entry{
					Params: paramsCopy,
					Value:  types.BytesFromFloat64(floatVal),
				}
			}
		}
	}
	return ret
}
예제 #3
0
// searchByIssue searches across the given issue.
func searchByIssue(issue string, q *Query, exp *expstorage.Expectations, parsedQuery url.Values, storages *storage.Storage, tile *tiling.Tile, tallies *tally.Tallies, tileParamSet *paramsets.Summary) ([]*Digest, error) {
	trybotResults, err := storages.TrybotResults.Get(issue)
	if err != nil {
		return nil, err
	}

	// Get a matcher for the ignore rules if we filter ignores.
	var ignoreMatcher ignore.RuleMatcher = nil
	if !q.IncludeIgnores {
		ignoreMatcher, err = storages.IgnoreStore.BuildRuleMatcher()
		if err != nil {
			return nil, fmt.Errorf("Unable to build rules matcher: %s", err)
		}
	}

	// Set up a rule to match the query.
	var queryRule ignore.QueryRule = nil
	if len(parsedQuery) > 0 {
		queryRule = ignore.NewQueryRule(parsedQuery)
	}

	// Aggregate the results into an intermediate representation to avoid
	// passing over the dataset twice.
	inter := map[string]*issueIntermediate{}
	talliesByTest := tallies.ByTest()

	for _, bot := range trybotResults.Bots {
		for _, result := range bot.TestResults {
			expandedParams := util.CopyStringMap(bot.BotParams)
			util.AddParams(expandedParams, result.Params)

			if ignoreMatcher != nil {
				if _, ok := ignoreMatcher(expandedParams); ok {
					continue
				}
			}

			if (queryRule == nil) || queryRule.IsMatch(expandedParams) {
				testName := expandedParams[types.PRIMARY_KEY_FIELD]
				digest := trybotResults.Digests[result.DigestIdx]
				key := testName + ":" + digest
				if !q.IncludeMaster {
					if _, ok := talliesByTest[testName][digest]; ok {
						continue
					}
				}
				if found, ok := inter[key]; ok {
					found.add(expandedParams)
				} else if cl := exp.Classification(testName, digest); !q.excludeClassification(cl) {
					inter[key] = newIssueIntermediate(expandedParams, digest, cl)
				}
			}
		}
	}

	// Build the output and make sure the digest are cached on disk.
	digests := make(map[string]bool, len(inter))
	ret := make([]*Digest, 0, len(inter))
	emptyTraces := &Traces{}
	for _, i := range inter {
		ret = append(ret, &Digest{
			Test:     i.test,
			Digest:   i.digest,
			Status:   i.status.String(),
			ParamSet: i.paramSet,
			Diff:     buildDiff(i.test, i.digest, exp, tile, talliesByTest, nil, storages.DiffStore, tileParamSet, q.IncludeIgnores),
			Traces:   emptyTraces,
		})
		digests[i.digest] = true
	}

	// This ensures that all digests are cached on disk.
	storages.DiffStore.AbsPath(util.KeysOfStringSet(digests))
	return ret, nil
}