blob: 9251ef5d9d105317929a063037083c70e3f1ceeb [file] [log] [blame]
<!--
The <chromium-analysis-runs-sk> custom element declaration. Displays a table with details about
each completed and pending Chromium Analysis task.
Attributes:
defaultSize: The number of tasks to show per page, default 10.
constrainByUser: Whether to show only tasks created by the logged-in user initially, default
false.
myRunsConstrainText: Button text to constrain by user, default "View only my runs".
everyonesRunsConstrainText: Button text to disable constraining by user, default "View
everyone's runs".
constrainByTestRun: Whether to show only non-test tasks, default true. Test tasks are those that
use the "Dummy1k" page sets.
nonTestRunsConstrainText: Button text to constrain to non-test tasks, default "Exclude test
runs".
testRunsConstrainText: Button text to disable constraining by test tasks, default "Include test
runs".
Events:
None.
Methods:
reload: queries for updated information on tasks.
resetPagination: Moves to the first page of tasks.
constrainRunsByUser: Toggles constrainByUser and reloads the appropriate data.
constrainTestRuns: Toggles constrainByTestRun and reloads the appropriate data.
-->
<dom-module id="chromium-analysis-runs-sk">
<style>
paper-dialog {
min-width: 200px;
max-width: calc(100% - 10px);
}
table.runshistory {
border-spacing: 0px;
}
tr.headers {
background-color: #CCCCFF;
text-align: center;
}
td.nowrap {
white-space: nowrap;
}
table.runshistory > tbody > tr > td {
padding: 10px;
border: solid black 1px;
}
.delete-button, .redo-button {
--paper-icon-button-disabled: {
display: none;
}
}
.oldruns {
margin-left: 20px;
}
</style>
<template>
<confirm-dialog-sk id="confirm_dialog"></confirm-dialog-sk>
<h2><template is="dom-if" if="{{constrainByUser}}">My </template>Chromium Analysis Runs</h2>
<paging-sk pagination="{{pagination}}" on-pagechange="pageChangedHandler"></paging-sk>
<br/>
<paper-button raised on-click="constrainRunsByUser">{{
constrainButtonText(constrainByUser, myRunsConstrainText, everyonesRunsConstrainText)
}}</paper-button>
<paper-button raised on-click="constrainTestRuns">{{
constrainButtonText(constrainByTestRun, nonTestRunsConstrainText, testRunsConstrainText)
}}</paper-button>
<br/>
<br/>
<!-- Section for popups. -->
<template is="dom-repeat" items="{{chromiumAnalysisTasks}}" as="chromiumAnalysisTask" index-as="index">
<paper-dialog heading="Benchmark Args" id="{{ getBenchmarkArgsId(index) }}">
<paper-dialog-scrollable>
<pre>{{chromiumAnalysisTask.BenchmarkArgs}}</pre>
</paper-dialog-scrollable>
</paper-dialog>
<paper-dialog heading="Browser Args" id="{{ getBrowserArgsId(index) }}">
<paper-dialog-scrollable>
<pre>{{chromiumAnalysisTask.BrowserArgs}}</pre>
</paper-dialog-scrollable>
</paper-dialog>
<paper-dialog heading="Match Stdout Text" id="{{ getMatchStdoutTxtId(index) }}">
<paper-dialog-scrollable>
<pre>{{chromiumAnalysisTask.MatchStdoutTxt}}</pre>
</paper-dialog-scrollable>
</paper-dialog>
</template>
<table class="runshistory" id="runshistory" cellpadding="5" border="1">
<tr class="headers">
<td>Id</td>
<td>User</td>
<td>Timestamps</td>
<td>Task Config</td>
<td>Description</td>
<td>Results</td>
<td>Arguments</td>
<td>Patches</td>
<td>Task Repeats</td>
</tr>
<template is="dom-repeat" items="{{chromiumAnalysisTasks}}" as="chromiumAnalysisTask" index-as="index">
<tr style="border: 1px solid black;">
<!-- Id col -->
<td class="nowrap">
<template is="dom-if" if="{{chromiumAnalysisTask.RawOutput}}">
<a href="{{chromiumAnalysisTask.RawOutput}}" target="_blank">{{chromiumAnalysisTask.Id}}</a>
</template>
<template is="dom-if" if="{{!chromiumAnalysisTask.RawOutput}}">
<span>{{chromiumAnalysisTask.Id}}</span>
</template>
<paper-icon-button icon="delete" mini
class="delete-button"
disabled="{{!chromiumAnalysisTask.canDelete}}"
alt="Delete"
data-index$="{{index}}"
data-type="delete">
</paper-icon-button>
<paper-icon-button icon="redo" mini
class="redo-button"
disabled="{{!chromiumAnalysisTask.canRedo}}"
alt="Redo"
data-index$="{{index}}"
data-type="redo">
</paper-icon-button>
</td>
<!-- User col -->
<td>{{chromiumAnalysisTask.Username}}</td>
<!-- Timestamps col -->
<td>
<table>
<tr>
<td>Added:</td>
<td class="nowrap">{{ formatTimestamp(chromiumAnalysisTask.TsAdded) }}</td>
</tr>
<tr>
<td>Started:</td>
<td class="nowrap">{{ formatTimestamp(chromiumAnalysisTask.TsStarted) }}</td>
</tr>
<tr>
<td>Completed:</td>
<td class="nowrap">{{ formatTimestamp(chromiumAnalysisTask.TsCompleted) }}</td>
</tr>
</table>
</td>
<!-- Task Config col -->
<td>
<table>
<tr>
<td>Benchmark:</td>
<td>{{chromiumAnalysisTask.Benchmark}}</td>
</tr>
<tr>
<td>Platform:</td>
<td>{{chromiumAnalysisTask.Platform}}</td>
</tr>
<tr>
<td>RunOnGCE:</td>
<td>{{chromiumAnalysisTask.RunOnGCE}}</td>
</tr>
<tr>
<td>PageSet:</td>
<template is="dom-if" if="{{ !isEmptyPatch(chromiumAnalysisTask.CustomWebpagesGSPath) }}">
<a href="{{ getGSLink(chromiumAnalysisTask.CustomWebpagesGSPath) }}" target="_blank">Custom Webpages</a>
</template>
<template is="dom-if" if="{{ isEmptyPatch(chromiumAnalysisTask.CustomWebpagesGSPath) }}">
{{chromiumAnalysisTask.PageSets}}
</template>
</td>
</tr>
<tr>
<td>ParallelRun:</td>
<td>{{chromiumAnalysisTask.RunInParallel}}</td>
</tr>
<template is="dom-if" if="{{chromiumAnalysisTask.ValueColumnName}}">
<tr>
<td class="nowrap">Value Column:</td>
<td class="nowrap">{{chromiumAnalysisTask.ValueColumnName}}</td>
</tr>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.TaskPriority}}">
<tr>
<td>TaskPriority:</td>
<td>{{chromiumAnalysisTask.TaskPriority}}</td>
</tr>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.CCList}}">
<tr>
<td>CC List:</td>
<td>{{chromiumAnalysisTask.CCList}}</td>
</tr>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.GroupName}}">
<tr>
<td>GroupName:</td>
<td><a href="https://ct-perf.skia.org/e/?request_type=1">{{chromiumAnalysisTask.GroupName}}</a></td>
</tr>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.ChromiumHash}}">
<tr>
<td>ChromiumHash:</td>
<td><a href="https://chromium.googlesource.com/chromium/src/+/{{chromiumAnalysisTask.ChromiumHash}}">{{chromiumAnalysisTask.ChromiumHash}}</a></td>
</tr>
</template>
</table>
</td>
<!-- Description col -->
<td>{{chromiumAnalysisTask.Description}}</td>
<!-- Results col -->
<td class="nowrap">
<template is="dom-if" if="{{chromiumAnalysisTask.Failure}}">
<div style="color:red;">Failed</div>
</template>
<template is="dom-if" if="{{!chromiumAnalysisTask.TaskDone}}">
<div style="color:green;">Waiting</div>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.RawOutput}}">
<a href="{{chromiumAnalysisTask.RawOutput}}" target="_blank">Output</a>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.SwarmingLogs}}">
<br/>
<a href="{{chromiumAnalysisTask.SwarmingLogs}}" target="_blank">Swarming Logs</a>
</template>
</td>
<!-- Arguments -->
<td class="nowrap">
<template is="dom-if" if="{{chromiumAnalysisTask.BenchmarkArgs}}">
<a href="javascript:void(0);" data-index$="{{index}}" data-type="benchmarkArgs">Benchmark Args</a>
<br/>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.BrowserArgs}}">
<a href="javascript:void(0);" data-index$="{{index}}" data-type="browserArgs">Browser Args</a>
<br/>
</template>
<template is="dom-if" if="{{chromiumAnalysisTask.MatchStdoutTxt}}">
<a href="javascript:void(0);" data-index$="{{index}}" data-type="matchStdoutTxt">Match Stdout Text</a>
<br/>
</template>
</td>
<!-- Patches -->
<td>
<template is="dom-if" if="{{ !isEmptyPatch(chromiumAnalysisTask.ChromiumPatchGSPath) }}">
<a href="{{ getGSLink(chromiumAnalysisTask.ChromiumPatchGSPath) }}" target="_blank">Chromium</a>
<br/>
</template>
<template is="dom-if" if="{{ !isEmptyPatch(chromiumAnalysisTask.SkiaPatchGSPath) }}">
<a href="{{ getGSLink(chromiumAnalysisTask.SkiaPatchGSPath) }}" target="_blank">Skia</a>
<br/>
</template>
<template is="dom-if" if="{{ !isEmptyPatch(chromiumAnalysisTask.V8PatchGSPath) }}">
<a href="{{ getGSLink(chromiumAnalysisTask.V8PatchGSPath) }}" target="_blank">V8</a>
<br/>
</template>
<template is="dom-if" if="{{ !isEmptyPatch(chromiumAnalysisTask.CatapultPatchGSPath) }}">
<a href="{{ getGSLink(chromiumAnalysisTask.CatapultPatchGSPath) }}" target="_blank">Catapult</a>
<br/>
</template>
<template is="dom-if" if="{{ !isEmptyPatch(chromiumAnalysisTask.BenchmarkPatchGSPath) }}">
<a href="{{ getGSLink(chromiumAnalysisTask.BenchmarkPatchGSPath) }}" target="_blank">Telemetry</a>
</template>
</td>
<!-- Task Repeats -->
<td>{{ formatRepeatAfterDays(chromiumAnalysisTask.RepeatAfterDays) }}</td>
</tr>
</template>
</table>
</template>
</dom-module>
<script>
Polymer({
is: "chromium-analysis-runs-sk",
properties: {
chromiumAnalysisTasks: {
type: Array,
value: function() { return []; },
},
defaultSize: {
type: Number,
value: 10,
},
constrainByUser: {
type: Boolean,
value: false,
},
myRunsConstrainText: {
type: String,
value: "View only my runs",
},
everyonesRunsConstrainText: {
type: String,
value: "View everyone's runs",
},
constrainByTestRun: {
type: Boolean,
value: true,
},
nonTestRunsConstrainText: {
type: String,
value: "Exclude test runs",
},
testRunsConstrainText: {
type: String,
value: "Include test runs",
},
pagination: {
type: Object,
value: function() { return {}; },
},
pageChangedHandler: {
type: Object,
value: function() { return null; },
},
},
ready: function() {
this.pagination = {"offset": 0, "size": this.defaultSize};
this.pageChangedHandler = this.reload.bind(this);
this.reload();
var that = this;
this.$.runshistory.addEventListener('click', function(e) {
var anchor = sk.findParent(e.target, "A");
if (anchor != null) {
var id = anchor.dataset.index;
if (anchor.dataset.type == "benchmarkArgs") {
that.toggleDialog(that.getBenchmarkArgsId(id));
} else if (anchor.dataset.type == "browserArgs") {
that.toggleDialog(that.getBrowserArgsId(id));
} else if (anchor.dataset.type == "matchStdoutTxt") {
that.toggleDialog(that.getMatchStdoutTxtId(id));
}
}
var button = sk.findParent(e.target, "PAPER-ICON-BUTTON");
if (button != null) {
if (button.dataset.type == "delete") {
var index = button.dataset.index;
that.$.confirm_dialog.open("Proceed with deleting task?")
.then(that.deleteTask.bind(that, index));
} else if (button.dataset.type == "redo") {
var index = button.dataset.index;
that.$.confirm_dialog.open("Reschedule this task?")
.then(that.redoTask.bind(that, index));
}
}
});
},
reload: function() {
var queryParams = {
"offset": this.pagination.offset,
"size": this.pagination.size,
}
if (this.constrainByUser) {
queryParams["filter_by_logged_in_user"] = true;
}
if (this.constrainByTestRun) {
queryParams["exclude_dummy_page_sets"] = true;
}
var queryStr = "?" + sk.query.fromObject(queryParams);
var that = this;
sk.post('/_/get_chromium_analysis_tasks' + queryStr).then(JSON.parse).then(function(json) {
that.chromiumAnalysisTasks = json.data;
that.pagination = json.pagination;
for (var i = 0; i < that.chromiumAnalysisTasks.length; i++) {
that.chromiumAnalysisTasks[i].canDelete = json.permissions[i].DeleteAllowed;
that.chromiumAnalysisTasks[i].canRedo = json.permissions[i].RedoAllowed;
that.chromiumAnalysisTasks[i].Id = json.ids[i];
}
}).catch(sk.errorMessage);
},
getBenchmarkArgsId: function(index) {
return "benchmark_args" + index;
},
getBrowserArgsId: function(index) {
return "browser_args" + index;
},
getMatchStdoutTxtId: function(index) {
return "match_stdout_txt" + index;
},
resetPagination: function() {
this.pagination.offset = 0;
this.pagination.size = this.defaultSize;
},
constrainRunsByUser: function() {
this.constrainByUser = !this.constrainByUser;
this.resetPagination();
this.reload();
},
constrainTestRuns: function() {
this.constrainByTestRun = !this.constrainByTestRun;
this.resetPagination();
this.reload();
},
constrainButtonText: function(constrained, constrainText, unconstrainText) {
if (constrained) {
return unconstrainText;
} else {
return constrainText;
}
},
toggleDialog: function(id) {
Polymer.dom(this.root).querySelector('#' + id).toggle();
},
deleteTask: function(deleteIndex) {
var params = {};
params["id"] = this.chromiumAnalysisTasks[deleteIndex].Id;
sk.post("/_/delete_chromium_analysis_task", JSON.stringify(params)).then(function() {
$$$("#confirm_toast").text = "Deleted task " + params["id"];
$$$("#confirm_toast").show();
}.bind(this)).catch(sk.errorMessage).then(function() {
this.reload();
}.bind(this));
},
redoTask: function(redoIndex) {
var params = {};
params["id"] = this.chromiumAnalysisTasks[redoIndex].Id;
sk.post("/_/redo_chromium_analysis_task", JSON.stringify(params)).then(function() {
$$$("#confirm_toast").text = "Resubmitted task " + params["id"];
$$$("#confirm_toast").show();
}.bind(this)).catch(sk.errorMessage).then(function() {
this.reload();
}.bind(this));
},
formatTimestamp: ctfe.getFormattedTimestamp,
formatRepeatAfterDays: ctfe.formatRepeatAfterDays,
getGSLink: ctfe.getGSLink,
isEmptyPatch: ctfe.isEmptyPatch,
});
</script>