ui/models/perfSeries.js (134 lines of code) (raw):
import queryString from 'query-string';
import { getProjectUrl } from '../helpers/location';
import { createQueryParams, getArtifactsUrl } from '../helpers/url';
import { getData } from '../helpers/http';
import JobModel from './job';
import OptionCollectionModel from './optionCollection';
export const getTestName = function getTestName(signatureProps) {
// only return suite name if testname is identical, and handle
// undefined test name
return [
...new Set(
[signatureProps.suite, signatureProps.test].filter((item) => item),
),
].join(' ');
};
export const getSeriesOptions = function getSeriesOptions(
signatureProps,
optionCollectionMap,
) {
let options = [optionCollectionMap[signatureProps.option_collection_hash]];
if (signatureProps.extra_options) {
options = options.concat(signatureProps.extra_options);
}
return [...new Set(options)];
};
export const getSeriesName = function getSeriesName(
signatureProps,
optionCollectionMap,
displayOptions,
) {
const platform = signatureProps.machine_platform;
let name = getTestName(signatureProps);
if (displayOptions && displayOptions.includePlatformInName) {
name = `${name} ${platform}`;
}
const options = getSeriesOptions(signatureProps, optionCollectionMap);
return `${name} ${options.join(' ')}`;
};
export const getSeriesSummary = function getSeriesSummary(
projectName,
signatureId,
signatureProps,
optionCollectionMap,
) {
const platform = signatureProps.machine_platform;
const options = getSeriesOptions(signatureProps, optionCollectionMap);
const signatureIntId =
typeof signatureId === 'string' ? parseInt(signatureId, 10) : signatureId;
return {
id: signatureIntId,
name: getSeriesName(signatureProps, optionCollectionMap),
testName: getTestName(signatureProps), // unadorned with platform/option info
suite: signatureProps.suite,
test: signatureProps.test || null,
signature: signatureProps.signature_hash,
hasSubtests: signatureProps.has_subtests || false,
tags: signatureProps.tags || [],
parentSignature: signatureProps.parent_signature || null,
projectName,
platform,
options,
measurementUnit: signatureProps.measurement_unit || '',
frameworkId: signatureProps.framework_id,
application: signatureProps.application || null,
lowerIsBetter:
signatureProps.lower_is_better === undefined ||
signatureProps.lower_is_better,
should_alert: signatureProps.should_alert,
};
};
export default class PerfSeriesModel {
constructor() {
this.optionCollectionMap = null;
}
static async getSeriesList(projectName, params) {
if (!this.optionCollectionMap) {
this.optionCollectionMap = await OptionCollectionModel.getMap();
}
// we use stringify here because for certain params like 'id'
// the query string needs to be id=1234&id=5678 vs id=123,5678;
const response = await getData(
`${getProjectUrl(
'/performance/signatures/',
projectName,
)}?${queryString.stringify(params)}`,
);
if (response.failureStatus) {
return response;
}
const data = Object.entries(
response.data,
).map(([signatureId, signatureProps]) =>
getSeriesSummary(
projectName,
signatureId,
signatureProps,
this.optionCollectionMap,
),
);
return { data, failureStatus: null };
}
static getPlatformList(projectName, params) {
return getData(
`${getProjectUrl(
'/performance/platforms/',
projectName,
)}${createQueryParams(params)}`,
);
}
static getSeriesData(projectName, params) {
return fetch(
`${getProjectUrl(
'/performance/data/',
projectName,
)}?${queryString.stringify(params)}`,
).then((resp) => {
if (resp.ok) {
return resp.json();
}
return Promise.reject('No series data found');
});
}
static async getReplicateData({ jobId, rootUrl }) {
const { data, failureStatus } = await JobModel.getList({ id: jobId });
if (failureStatus || !data.length) {
return { failureStatus: true, data: ['No data for this job'] };
}
const { task_id: taskId, retry_id: run } = data[0];
const url = getArtifactsUrl({
taskId,
run,
rootUrl,
artifactPath: 'public/test_info/perfherder-data.json',
});
const replicateDatum = await getData(url);
return replicateDatum;
}
}