Skip to content

Commit

Permalink
Merge pull request #1316 from wlach/1251353
Browse files Browse the repository at this point in the history
Bug 1251353 - Add a dashboard for tracking e10s vs. non-e10s performance
  • Loading branch information
mozilla-autolander-deprecated committed Feb 25, 2016
2 parents 7145aff + 47ac44c commit 761411c
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 65 deletions.
56 changes: 42 additions & 14 deletions ui/js/controllers/perf/compare.js
Expand Up @@ -302,20 +302,6 @@ perf.controller('CompareResultsCtrl', [
$scope.dataLoading = true;
$scope.getCompareClasses = PhCompare.getCompareClasses;

$scope.updateFilters = function() {
$state.transitionTo('compare', {
framework: $scope.filterOptions.framework.id,
filter: $scope.filterOptions.filter,
showOnlyImportant: Boolean($scope.filterOptions.showOnlyImportant) ? undefined : 0,
showOnlyConfident: Boolean($scope.filterOptions.showOnlyConfident) ? 1 : undefined
}, {
location: true,
inherit: true,
relative: $state.$current,
notify: false
});
};

var optionCollectionMap = {};
var loadRepositories = ThRepositoryModel.load();
var loadOptions = ThOptionCollectionModel.getMap().then(
Expand Down Expand Up @@ -347,6 +333,24 @@ perf.controller('CompareResultsCtrl', [
parseInt($stateParams.showOnlyConfident)
};

$scope.$watchGroup(['filterOptions.frameworkId',
'filterOptions.filter',
'filterOptions.showOnlyImportant',
'filterOptions.showOnlyConfident'],
function() {
$state.transitionTo('compare', {
framework: $scope.filterOptions.framework.id,
filter: $scope.filterOptions.filter,
showOnlyImportant: Boolean($scope.filterOptions.showOnlyImportant) ? undefined : 0,
showOnlyConfident: Boolean($scope.filterOptions.showOnlyConfident) ? 1 : undefined
}, {
location: true,
inherit: true,
relative: $state.$current,
notify: false
});
});

$scope.originalProject = ThRepositoryModel.getRepo(
$stateParams.originalProject);
$scope.newProject = ThRepositoryModel.getRepo(
Expand Down Expand Up @@ -402,6 +406,30 @@ perf.controller('CompareSubtestResultsCtrl', [
$scope.testList[0].split(' ')[0]);
window.document.title = $scope.subtestTitle + " subtest comparison";

$scope.filterOptions = {
filter: $stateParams.filter || "",
showOnlyImportant: $stateParams.showOnlyImportant !== undefined &&
parseInt($stateParams.showOnlyImportant),
showOnlyConfident: $stateParams.showOnlyConfident !== undefined &&
parseInt($stateParams.showOnlyConfident)
};

$scope.$watchGroup(['filterOptions.filter',
'filterOptions.showOnlyImportant',
'filterOptions.showOnlyConfident'],
function() {
$state.transitionTo('comparesubtest', {
filter: $scope.filterOptions.filter,
showOnlyImportant: Boolean($scope.filterOptions.showOnlyImportant) ? 1 : undefined,
showOnlyConfident: Boolean($scope.filterOptions.showOnlyConfident) ? 1 : undefined
}, {
location: true,
inherit: true,
relative: $state.$current,
notify: false
});
});

$scope.testList.forEach(function(testName) {
$scope.titles[testName] = $scope.platformList[0] + ': ' +
testName.replace('summary ', '');
Expand Down
114 changes: 114 additions & 0 deletions ui/js/controllers/perf/e10s.js
@@ -0,0 +1,114 @@
"use strict";

perf.controller('e10sCtrl', [
'$state', '$stateParams', '$scope', '$rootScope', '$q', '$http',
'ThOptionCollectionModel', 'PhSeries', 'PhCompare',
function e10sCtrl($state, $stateParams, $scope, $rootScope, $q, $http,
ThOptionCollectionModel, PhSeries, PhCompare) {
var projectName = 'mozilla-inbound';
var interval = 86400*2;

$scope.testList = [];
$scope.dataLoading = true;
$scope.compareResults = {};
$scope.titles = {};

$scope.filterOptions = {
filter: $stateParams.filter || "",
showOnlyImportant: $stateParams.showOnlyImportant !== undefined &&
parseInt($stateParams.showOnlyImportant),
showOnlyConfident: $stateParams.showOnlyConfident !== undefined &&
parseInt($stateParams.showOnlyConfident)
};

$scope.$watchGroup(['filterOptions.filter',
'filterOptions.showOnlyImportant',
'filterOptions.showOnlyConfident'],
function() {
$state.transitionTo('e10s', {
filter: $scope.filterOptions.filter,
showOnlyImportant: Boolean($scope.filterOptions.showOnlyImportant) ? 1 : undefined,
showOnlyConfident: Boolean($scope.filterOptions.showOnlyConfident) ? 1 : undefined
}, {
location: true,
inherit: true,
relative: $state.$current,
notify: false
});
});

var resultsMap = {
e10s: {},
base: {}
};
ThOptionCollectionModel.getMap().then(function(optionCollectionMap) {
PhSeries.getSeriesSummaries(projectName, interval, optionCollectionMap).then(function(seriesData) {

var seriesToMeasure = _.filter(seriesData.seriesList, function(series) {
return series.options.indexOf('pgo') >= 0 ||
(series.platform === 'osx-10-10' &&
series.options.indexOf('opt') >= 0);
});
$scope.platformList = seriesData.platformList;
// just use suite names as tests
$scope.testList = _.uniq(_.map(seriesToMeasure, function(series) {
return PhSeries.getTestName(series);
}));

$q.all(_.chunk(seriesToMeasure, 20).map(function(seriesChunk) {
var url = thServiceDomain + '/api/project/' + projectName +
'/performance/data/?interval=' + interval +
_.map(seriesChunk, function(series) {
return "&signatures=" + series.signature;
}).join("");
return $http.get(url).then(function(response) {
_.forIn(response.data, function(data, signature) {
var series = _.find(seriesChunk, { signature: signature });
var type = (series.options.indexOf('e10s') >= 0) ? 'e10s' : 'base';
resultsMap[type][signature] = {
platform: series.platform,
suite: series.suite,
name: PhSeries.getTestName(series),
lowerIsBetter: series.lowerIsBetter,
values: _.map(data, 'value')
};
});
});
})).then(function() {
$scope.dataLoading = false;
$scope.testList.forEach(function(testName) {
$scope.titles[testName] = testName;
$scope.platformList.forEach(function(platform) {
var baseSig = _.find(Object.keys(resultsMap['base']), function (sig) {
return resultsMap['base'][sig].name === testName &&
resultsMap['base'][sig].platform === platform;
});
var e10sSig = _.find(Object.keys(resultsMap['e10s']), function (sig) {
return resultsMap['e10s'][sig].name === testName &&
resultsMap['e10s'][sig].platform == platform;
});
if (e10sSig && baseSig) {
var cmap = PhCompare.getCounterMap(
testName, resultsMap['base'][baseSig],
resultsMap['e10s'][e10sSig]);
cmap.name = platform + ' ' + (platform === 'osx-10-10' ? 'opt' : 'pgo');
cmap.links = [{
title: 'graph',
href: 'perf.html#/graphs?' + _.map([baseSig, e10sSig],
function(sig) {
return 'series=[' + [ projectName, sig, 1 ];
}).join('&') + ']'
}];
if (!$scope.compareResults[testName]) {
$scope.compareResults[testName] = [cmap];
} else {
$scope.compareResults[testName].push(cmap);
}
}
});
});
});
});
});
}
]);
32 changes: 22 additions & 10 deletions ui/js/directives/perf/compare.js
Expand Up @@ -6,31 +6,40 @@ treeherder.directive(
return {
templateUrl: 'partials/perf/comparetable.html',
scope: {
baseTitle: '@',
newTitle: '@',
frameworks: '=',
titles: '=',
compareResults: '=',
testList: '=',
frameworkId: '=',
filter: '=',
showOnlyImportant: '=',
showOnlyConfident: '='
filterOptions: '=',
filterByFramework: '@'
},
link: function(scope, element, attrs) {
if (!scope.baseTitle) {
scope.baseTitle = "Base";
}
if (!scope.newTitle) {
scope.newTitle = "New";
}

scope.getCompareClasses = PhCompare.getCompareClasses;
function filter(item, matchText) {
return !matchText || item.toLowerCase().indexOf(matchText.toLowerCase()) > (-1);
}
function shouldBeShown(result) {
return (scope.frameworkId === undefined || result.frameworkId === scope.frameworkId) &&
(!scope.showOnlyImportant || result.isMeaningful) &&
(!scope.showOnlyConfident || result.isConfident);
return (!scope.filterByFramework || _.isUndefined(scope.filterOptions.framework) ||
result.frameworkId === scope.filterOptions.framework.id) &&
(!scope.filterOptions.showOnlyImportant || result.isMeaningful) &&
(!scope.filterOptions.showOnlyConfident || result.isConfident);
}
function filterResult(results, key) {
if (scope.filter === undefined) {
if (_.isUndefined(scope.filterOptions.filter)) {
return results;
}
return _.filter(results, function(result) {
var testCondition = key + ' ' + result.name;
return _.every(scope.filter.split(' '), function(matchText) {
return _.every(scope.filterOptions.filter.split(' '), function(matchText) {
return filter(testCondition, matchText) && shouldBeShown(result);
});
});
Expand All @@ -50,7 +59,10 @@ treeherder.directive(
scope.hasNoResults = _.isEmpty(scope.filteredResultList);
}

scope.$watchGroup(['frameworkId', 'filter', 'showOnlyImportant', 'showOnlyConfident'],
scope.$watchGroup([
'filterOptions.framework', 'filterOptions.filter',
'filterOptions.showOnlyImportant',
'filterOptions.showOnlyConfident'],
function() {
updateFilteredTestList();
});
Expand Down
17 changes: 11 additions & 6 deletions ui/js/models/perf/alerts.js
Expand Up @@ -16,16 +16,21 @@ treeherder.factory('PhAlerts', [
return _.result(_.find(phAlertStatusMap, {id: this.status}),
'text');
};
Alert.prototype.getGraphsURL = function(timeRange, alertRepository) {
Alert.prototype.getGraphsURL = function(timeRange, alertRepository,
performanceFramework) {
var signature = this.series_signature.signature_hash;
var url = "#/graphs?timerange=" + timeRange +
"&series=[" + [alertRepository, signature, 1] + "]" +
"&selected=[" + [alertRepository, signature,] + "]";
_.forEach(thPerformanceBranches, function(performanceBranch) {
if (performanceBranch !== alertRepository) {
url += "&series=[" + [performanceBranch, signature, 0] + "]";
}
});

// for talos only, automatically add related branches
if (performanceFramework.name === "talos") {
_.forEach(thPerformanceBranches, function(performanceBranch) {
if (performanceBranch !== alertRepository) {
url += "&series=[" + [performanceBranch, signature, 0] + "]";
}
});
}

return url;
};
Expand Down
2 changes: 2 additions & 0 deletions ui/js/perf.js
Expand Up @@ -44,6 +44,8 @@ treeherder.factory('PhSeries', ['$http', 'thServiceDomain', function($http, thSe
var options = _getSeriesOptions(signatureProps, optionCollectionMap);

return { name: _getSeriesName(signatureProps, optionCollectionMap),
suite: signatureProps['suite'],
test: signatureProps['test'] || null,
projectName: projectName, signature: signature,
platform: platform, options: options,
frameworkId: signatureProps.framework_id,
Expand Down
9 changes: 7 additions & 2 deletions ui/js/perfapp.js
Expand Up @@ -21,17 +21,22 @@ perf.config(function($compileProvider, $httpProvider, $stateProvider, $urlRouter
controller: 'GraphsCtrl'
}).state('compare', {
templateUrl: 'partials/perf/comparectrl.html',
url: '/compare?originalProject&originalRevision&newProject&newRevision&hideMinorChanges&framework&filter&showOnlyImportant&showOnlyConfident',
url: '/compare?originalProject&originalRevision&newProject&newRevision&hideMinorChanges&framework&filter&showOnlyImportant&showOnlyConfidentw',
controller: 'CompareResultsCtrl'
}).state('comparesubtest', {
templateUrl: 'partials/perf/comparesubtestctrl.html',
url: '/comparesubtest?originalProject&originalRevision&newProject&newRevision&originalSignature&newSignature',
url: '/comparesubtest?originalProject&originalRevision&newProject&newRevision&originalSignature&newSignature&filter&showOnlyImportant&showOnlyConfident',
controller: 'CompareSubtestResultsCtrl'
}).state('comparechooser', {
title: 'Compare',
templateUrl: 'partials/perf/comparechooserctrl.html',
url: '/comparechooser?originalProject&originalRevision&newProject&newRevision',
controller: 'CompareChooserCtrl'
}).state('e10s', {
title: 'e10s talos dashboard',
templateUrl: 'partials/perf/e10s.html',
url: '/e10s?&filter&showOnlyImportant&showOnlyConfident',
controller: 'e10sCtrl'
});

$urlRouterProvider.otherwise('/graphs');
Expand Down
31 changes: 3 additions & 28 deletions ui/partials/perf/comparectrl.html
Expand Up @@ -14,38 +14,13 @@ <h1>Perfherder Compare Revisions</h1>
<strong>tests with no results:</strong>
{{testNoResults}}
</div>
<form class="form-inline">
<div class="form-group">
<select ng-model="filterOptions.framework"
ng-options="framework.name for framework in frameworks track by framework.id"
ng-change="updateFilters()"/>
</div>
&nbsp;
<div class="form-group">
<input id="filter" type="text" class="form-control" ng-model="filterOptions.filter" placeholder="filter text e.g. linux tp5o" ng-change="updateFilters()" ng-model-options="{debounce: 250}"/>
</div>
<div class="checkbox" uib-tooltip="Non-trivial changes (2%+)">
<label>
<input type="checkbox" ng-model="filterOptions.showOnlyImportant" ng-change="updateFilters()"/>
Show only important changes
</label>
</div>
<div class="checkbox" uib-tooltip="At least 6 datapoints OR 2+ datapoints and a large difference">
<label>
<input type="checkbox" ng-model="filterOptions.showOnlyConfident" ng-change="updateFilters()"/>
Hide uncertain results
</label>
</div>
</form>
<hr/>
<ph-compare-table
titles="titles"
test-list="testList"
compare-results="compareResults"
framework-id="filterOptions.framework.id"
filter="filterOptions.filter"
show-only-important="filterOptions.showOnlyImportant"
show-only-confident="filterOptions.showOnlyConfident">
frameworks="frameworks"
filter-options="filterOptions"
filter-by-framework="1">
</ph-compare-table>
</div>
</div>
Expand Down
4 changes: 1 addition & 3 deletions ui/partials/perf/comparesubtestctrl.html
Expand Up @@ -15,9 +15,7 @@ <h1>{{subtestTitle}} subtest summary</h1>
titles="titles"
test-list="testList"
compare-results="compareResults"
filter=""
show-only-important="0"
show-only-confident="0">
filter-options="filterOptions">
</ph-compare-table>
</div>
</div>

0 comments on commit 761411c

Please sign in to comment.