зеркало из https://github.com/mozilla/treeherder.git
Bug 1831945 - Add a toggle for replicates to the CompareView. (#7703)
This commit is contained in:
Родитель
c78cd4e78d
Коммит
4d7f863362
|
@ -162,6 +162,8 @@ const compareTableControlsNode = (
|
|||
showOnlyComparable: '0',
|
||||
showOnlyConfident: '0',
|
||||
showOnlyNoise: '0',
|
||||
originalProject: 'try',
|
||||
newProject: 'mozilla-central',
|
||||
filter: null,
|
||||
}}
|
||||
location={{
|
||||
|
@ -246,7 +248,13 @@ test('toggle all buttons should update the URL params', async () => {
|
|||
fireEvent.click(showImportant);
|
||||
expect(mockUpdateParams).toHaveBeenLastCalledWith(
|
||||
{ page: 1, showOnlyImportant: 1 },
|
||||
['filter', 'showOnlyComparable', 'showOnlyConfident', 'showOnlyNoise'],
|
||||
[
|
||||
'filter',
|
||||
'showOnlyComparable',
|
||||
'showOnlyConfident',
|
||||
'showOnlyNoise',
|
||||
'replicates',
|
||||
],
|
||||
);
|
||||
|
||||
const hideUncertain = await waitFor(() =>
|
||||
|
@ -259,7 +267,7 @@ test('toggle all buttons should update the URL params', async () => {
|
|||
showOnlyImportant: 1,
|
||||
showOnlyConfident: 1,
|
||||
},
|
||||
['filter', 'showOnlyComparable', 'showOnlyNoise'],
|
||||
['filter', 'showOnlyComparable', 'showOnlyNoise', 'replicates'],
|
||||
);
|
||||
|
||||
const showNoise = await waitFor(() => getByText(filterText.showNoise));
|
||||
|
@ -271,7 +279,7 @@ test('toggle all buttons should update the URL params', async () => {
|
|||
showOnlyConfident: 1,
|
||||
showOnlyNoise: 1,
|
||||
},
|
||||
['filter', 'showOnlyComparable'],
|
||||
['filter', 'showOnlyComparable', 'replicates'],
|
||||
);
|
||||
|
||||
const hideUncomparable = await waitFor(() =>
|
||||
|
@ -286,6 +294,22 @@ test('toggle all buttons should update the URL params', async () => {
|
|||
showOnlyNoise: 1,
|
||||
showOnlyComparable: 1,
|
||||
},
|
||||
['filter', 'replicates'],
|
||||
);
|
||||
|
||||
const useReplicates = await waitFor(() =>
|
||||
getByText('Use replicates (try-only)'),
|
||||
);
|
||||
fireEvent.click(useReplicates);
|
||||
expect(mockUpdateParams).toHaveBeenLastCalledWith(
|
||||
{
|
||||
page: 1,
|
||||
showOnlyImportant: 1,
|
||||
showOnlyConfident: 1,
|
||||
showOnlyNoise: 1,
|
||||
showOnlyComparable: 1,
|
||||
replicates: 1,
|
||||
},
|
||||
['filter'],
|
||||
);
|
||||
});
|
||||
|
@ -299,7 +323,13 @@ test('filters that are not enabled are removed from URL params', async () => {
|
|||
fireEvent.click(showImportant);
|
||||
expect(mockUpdateParams).toHaveBeenLastCalledWith(
|
||||
{ page: 1, showOnlyImportant: 1 },
|
||||
['filter', 'showOnlyComparable', 'showOnlyConfident', 'showOnlyNoise'],
|
||||
[
|
||||
'filter',
|
||||
'showOnlyComparable',
|
||||
'showOnlyConfident',
|
||||
'showOnlyNoise',
|
||||
'replicates',
|
||||
],
|
||||
);
|
||||
fireEvent.click(showImportant);
|
||||
expect(mockUpdateParams).toHaveBeenLastCalledWith({ page: 1 }, [
|
||||
|
@ -308,6 +338,7 @@ test('filters that are not enabled are removed from URL params', async () => {
|
|||
'showOnlyImportant',
|
||||
'showOnlyConfident',
|
||||
'showOnlyNoise',
|
||||
'replicates',
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -624,6 +624,7 @@ class PerformanceSummary(generics.ListAPIView):
|
|||
no_subtests = query_params.validated_data['no_subtests']
|
||||
all_data = query_params.validated_data['all_data']
|
||||
no_retriggers = query_params.validated_data['no_retriggers']
|
||||
replicates = query_params.validated_data['replicates']
|
||||
|
||||
signature_data = PerformanceSignature.objects.select_related(
|
||||
'framework', 'repository', 'platform', 'push', 'job'
|
||||
|
@ -707,10 +708,23 @@ class PerformanceSummary(generics.ListAPIView):
|
|||
else:
|
||||
grouped_values = defaultdict(list)
|
||||
grouped_job_ids = defaultdict(list)
|
||||
for signature_id, value, job_id in data.values_list('signature_id', 'value', 'job_id'):
|
||||
if value is not None:
|
||||
grouped_values[signature_id].append(value)
|
||||
grouped_job_ids[signature_id].append(job_id)
|
||||
if replicates:
|
||||
for signature_id, value, job_id, replicate_value in data.values_list(
|
||||
'signature_id', 'value', 'job_id', 'performancedatumreplicate__value'
|
||||
):
|
||||
if replicate_value is not None:
|
||||
grouped_values[signature_id].append(replicate_value)
|
||||
grouped_job_ids[signature_id].append(job_id)
|
||||
elif value is not None:
|
||||
grouped_values[signature_id].append(value)
|
||||
grouped_job_ids[signature_id].append(job_id)
|
||||
else:
|
||||
for signature_id, value, job_id in data.values_list(
|
||||
'signature_id', 'value', 'job_id'
|
||||
):
|
||||
if value is not None:
|
||||
grouped_values[signature_id].append(value)
|
||||
grouped_job_ids[signature_id].append(job_id)
|
||||
|
||||
# name field is created in the serializer
|
||||
for item in self.queryset:
|
||||
|
|
|
@ -316,6 +316,7 @@ class PerformanceQueryParamsSerializer(serializers.Serializer):
|
|||
signature = serializers.CharField(required=False, allow_null=True, default=None)
|
||||
no_subtests = serializers.BooleanField(required=False)
|
||||
all_data = OptionalBooleanField()
|
||||
replicates = OptionalBooleanField()
|
||||
no_retriggers = OptionalBooleanField()
|
||||
|
||||
def validate(self, data):
|
||||
|
|
|
@ -603,6 +603,10 @@ li.pagination-active.active > button {
|
|||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.download-json-container .btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.download-json-container .download-button {
|
||||
background-color: transparent !important;
|
||||
color: #1f7d8e !important;
|
||||
|
|
|
@ -29,6 +29,7 @@ export default class CompareTableControls extends React.Component {
|
|||
showImportant: convertParams(this.validated, 'showOnlyImportant'),
|
||||
hideUncertain: convertParams(this.validated, 'showOnlyConfident'),
|
||||
showNoise: convertParams(this.validated, 'showOnlyNoise'),
|
||||
useReplicates: convertParams(this.validated, 'replicates'),
|
||||
results: new Map(),
|
||||
filteredText: this.getDefaultFilterText(this.validated),
|
||||
showRetriggerModal: false,
|
||||
|
@ -49,6 +50,9 @@ export default class CompareTableControls extends React.Component {
|
|||
const params = parseQueryParams(location.search);
|
||||
const prevParams = parseQueryParams(prevProps.location.search);
|
||||
|
||||
if (params.replicates !== prevParams.replicates) {
|
||||
window.location.reload(false);
|
||||
}
|
||||
if (prevState.countPages !== countPages) {
|
||||
this.setState({ totalPagesList: this.generatePages(countPages) });
|
||||
}
|
||||
|
@ -80,6 +84,13 @@ export default class CompareTableControls extends React.Component {
|
|||
);
|
||||
};
|
||||
|
||||
updateReplicates = () => {
|
||||
this.setState(
|
||||
(prevState) => ({ useReplicates: !prevState.useReplicates }),
|
||||
() => this.updateUrlParams(),
|
||||
);
|
||||
};
|
||||
|
||||
filterResult = (testName, result) => {
|
||||
const {
|
||||
filteredText,
|
||||
|
@ -183,6 +194,7 @@ export default class CompareTableControls extends React.Component {
|
|||
showImportant,
|
||||
hideUncertain,
|
||||
showNoise,
|
||||
useReplicates,
|
||||
page,
|
||||
} = this.state;
|
||||
const compareURLParams = {};
|
||||
|
@ -203,6 +215,9 @@ export default class CompareTableControls extends React.Component {
|
|||
if (showNoise) compareURLParams.showOnlyNoise = 1;
|
||||
else paramsToRemove.push('showOnlyNoise');
|
||||
|
||||
if (useReplicates) compareURLParams.replicates = 1;
|
||||
else paramsToRemove.push('replicates');
|
||||
|
||||
compareURLParams.page = page;
|
||||
updateParams(compareURLParams, paramsToRemove);
|
||||
};
|
||||
|
@ -265,6 +280,7 @@ export default class CompareTableControls extends React.Component {
|
|||
hideUncertain,
|
||||
showImportant,
|
||||
showNoise,
|
||||
useReplicates,
|
||||
results,
|
||||
showRetriggerModal,
|
||||
currentRetriggerRow,
|
||||
|
@ -304,6 +320,8 @@ export default class CompareTableControls extends React.Component {
|
|||
|
||||
const viewablePagesList = this.getCurrentPages();
|
||||
const hasMorePages = () => viewablePagesList.length > 0 && countPages !== 1;
|
||||
const hasTryProject = () =>
|
||||
validated.newProject === 'try' || validated.originalProject === 'try';
|
||||
|
||||
const formattedJSONData = this.formatDownloadData(compareResults);
|
||||
|
||||
|
@ -337,8 +355,19 @@ export default class CompareTableControls extends React.Component {
|
|||
</Row>
|
||||
)
|
||||
: null}
|
||||
|
||||
<div className="download-json-container">
|
||||
{hasTryProject() && (
|
||||
<Button
|
||||
color="darker-info"
|
||||
outline
|
||||
className="btn"
|
||||
type="button"
|
||||
onClick={this.updateReplicates}
|
||||
active={useReplicates}
|
||||
>
|
||||
Use replicates (try-only)
|
||||
</Button>
|
||||
)}
|
||||
{formattedJSONData.length > 0 && (
|
||||
<Button
|
||||
className="btn download-button"
|
||||
|
|
|
@ -27,6 +27,7 @@ class CompareView extends React.PureComponent {
|
|||
framework,
|
||||
interval,
|
||||
no_subtests: true,
|
||||
replicates: false,
|
||||
});
|
||||
|
||||
getQueryParams = (timeRange, framework) => {
|
||||
|
@ -37,6 +38,7 @@ class CompareView extends React.PureComponent {
|
|||
newRevision,
|
||||
newResultSet,
|
||||
originalResultSet,
|
||||
replicates,
|
||||
} = this.props.validated;
|
||||
|
||||
let originalParams;
|
||||
|
@ -71,6 +73,12 @@ class CompareView extends React.PureComponent {
|
|||
|
||||
const newParams = this.queryParams(newProject, interval, framework.id);
|
||||
newParams.revision = newRevision;
|
||||
|
||||
if (replicates) {
|
||||
originalParams.replicates = true;
|
||||
newParams.replicates = true;
|
||||
}
|
||||
|
||||
return [originalParams, newParams];
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче