Skip to content

Commit

Permalink
Bug 1822513 - Add links to side by side in Performance Tab of page lo…
Browse files Browse the repository at this point in the history
…ad job (#7719)

Bug 1822513 - Add links to side by side in Performance Tab of page load job
  • Loading branch information
alexandru-io committed Jun 19, 2023
1 parent d1ae8de commit 09ae7bd
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 117 deletions.
6 changes: 6 additions & 0 deletions ui/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,9 @@ export const genericErrorMessage = 'Something went wrong';
export const mercurialDatetimeFormat = 'ddd MMM DD HH:mm:ss YYYY ZZ';

export const alertsViewDatetimeFormat = 'ddd MMM DD HH:mm YYYY';

export const sxsJobTypeName = 'perftest-linux-side-by-side';

export const sxsTaskName = 'side-by-side';

export const geckoProfileTaskName = 'geckoprofile';
7 changes: 3 additions & 4 deletions ui/helpers/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ export const isReftest = function isReftest(job) {
export const isPerfTest = function isPerfTest(job) {
return [job.job_group_name, job.job_type_name].some(
(name) =>
(name.toLowerCase().includes('talos') ||
name.toLowerCase().includes('raptor') ||
name.toLowerCase().includes('browsertime')) &&
!name.toLowerCase().includes('side-by-side'),
name.toLowerCase().includes('talos') ||
name.toLowerCase().includes('raptor') ||
name.toLowerCase().includes('browsertime'),
);
};

Expand Down
13 changes: 7 additions & 6 deletions ui/helpers/performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,31 @@ import { getAction } from './taskcluster';
* @param {Object} decisionTaskMap - Object that maps a job push ID to a decision task.
* @param {string} currentRepo - The name of the current repo, e.g. "try"
*/
export async function triggerGeckoProfileTask(
export async function triggerTask(
selectedJobFull,
notify,
decisionTaskMap,
currentRepo,
taskName,
) {
const { id: decisionTaskId } = decisionTaskMap[selectedJobFull.push_id];

TaskclusterModel.load(decisionTaskId, selectedJobFull, currentRepo).then(
(results) => {
try {
const geckoprofile = getAction(results.actions, 'geckoprofile');
const action = getAction(results.actions, taskName);

if (
geckoprofile === undefined ||
!Object.prototype.hasOwnProperty.call(geckoprofile, 'kind')
action === undefined ||
!Object.prototype.hasOwnProperty.call(action, 'kind')
) {
return notify(
'Job was scheduled without taskcluster support for GeckoProfiles',
`Job was scheduled without taskcluster support for ${taskName}`,
);
}

TaskclusterModel.submit({
action: geckoprofile,
action,
decisionTaskId,
taskId: results.originalTaskId,
task: results.originalTask,
Expand Down
5 changes: 4 additions & 1 deletion ui/job-view/details/DetailsPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ class DetailsPanel extends React.Component {
// of all the extra fields in ``selectedJobFull``. It's not that much for just one job, but as
// one selects job after job, over the course of a day, it can add up. Therefore, we keep
// selectedJobFull data as transient only when the job is selected.
const selectedJobFull = jobResult;
const selectedJobFull = {
...jobResult,
hasSideBySide: selectedJob.hasSideBySide,
};
const jobRevision = push ? push.revision : null;

addAggregateFields(selectedJobFull);
Expand Down
37 changes: 34 additions & 3 deletions ui/job-view/details/summary/ActionBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ import {
faCrosshairs,
} from '@fortawesome/free-solid-svg-icons';

import { thEvents } from '../../../helpers/constants';
import { triggerGeckoProfileTask } from '../../../helpers/performance';
import {
geckoProfileTaskName,
sxsTaskName,
thEvents,
} from '../../../helpers/constants';
import { triggerTask } from '../../../helpers/performance';
import { formatTaskclusterError } from '../../../helpers/errorMessage';
import {
isReftest,
Expand Down Expand Up @@ -97,11 +101,28 @@ class ActionBar extends React.PureComponent {
decisionTaskMap,
currentRepo,
} = this.props;
return triggerGeckoProfileTask(
return triggerTask(
selectedJobFull,
notify,
decisionTaskMap,
currentRepo,
geckoProfileTaskName,
);
};

createSideBySide = async () => {
const {
selectedJobFull,
notify,
decisionTaskMap,
currentRepo,
} = this.props;
await triggerTask(
selectedJobFull,
notify,
decisionTaskMap,
currentRepo,
sxsTaskName,
);
};

Expand Down Expand Up @@ -469,6 +490,16 @@ class ActionBar extends React.PureComponent {
Create Gecko Profile
</DropdownItem>
)}
{isPerfTest(selectedJobFull) &&
!selectedJobFull.hasSideBySide && (
<DropdownItem
tag="a"
className="py-2"
onClick={this.createSideBySide}
>
Generate side-by-side
</DropdownItem>
)}
{canConfirmFailure(selectedJobFull) && (
<DropdownItem
tag="a"
Expand Down
113 changes: 113 additions & 0 deletions ui/job-view/details/tabs/PerfData.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import { notify } from '../../redux/stores/notifications';

class PerfData extends React.PureComponent {
render() {
const { perfJobDetail, selectedJobFull } = this.props;

const sortedDetails = perfJobDetail.slice();

// These styles are shared across all of the table cells.
const cellClassName = 'nowrap pl-2 pr-2';

return (
<>
<h3 className="font-size-16 mt-3 mb-2">
Results for: {selectedJobFull.job_type_name}
</h3>
<table className="table table-sm performance-panel-data">
<thead>
<tr>
<th scope="col" className={`text-right ${cellClassName}`}>
Value
</th>
<th scope="col" className={cellClassName}>
Unit
</th>
<th scope="col" className={cellClassName}>
Better
</th>
<th scope="col" className={cellClassName}>
History
</th>
<th scope="col" className={cellClassName}>
Name
</th>
</tr>
</thead>
<tbody>
{sortedDetails.map(
(
{
value,
url,
measurementUnit,
lowerIsBetter,
title,
suite,
perfdocs,
},
idx,
) => (
// eslint-disable-next-line react/no-array-index-key
<tr key={idx}>
{/* Ensure the value and measurement are visually next to each
other in the chart, by aligning the value to the right. */}
<td className={`text-right ${cellClassName}`}>{value}</td>
<td className={cellClassName}>{measurementUnit || '–'}</td>
<td className={cellClassName}>
{lowerIsBetter ? 'Lower' : 'Higher'}
</td>
<td className={cellClassName}>
<a
href={url}
className="btn btn-outline-darker-secondary btn-sm performance-panel-view-button"
target="_blank"
rel="noopener noreferrer"
>
View
</a>
</td>
<td className="w-100">
{perfdocs.hasDocumentation() ? (
<div>
<a
href={perfdocs.documentationURL}
target="_blank"
rel="noopener noreferrer"
>
{`${suite} `}
</a>
{`${perfdocs.remainingName}`}
</div>
) : (
title
)}
</td>
</tr>
),
)}
</tbody>
</table>
</>
);
}
}

PerfData.propTypes = {
perfJobDetail: PropTypes.arrayOf(PropTypes.object),
};

PerfData.defaultProps = {
perfJobDetail: [],
};

const mapStateToProps = (state) => ({
decisionTaskMap: state.pushes.decisionTaskMap,
});
const mapDispatchToProps = { notify };

export default connect(mapStateToProps, mapDispatchToProps)(PerfData);

0 comments on commit 09ae7bd

Please sign in to comment.