зеркало из https://github.com/mozilla/treeherder.git
Tidy Up After Matchers (#4015)
* Use Match.matcher_name instead of Matcher object endpoint * remove Matcher database table * Replace Matchers data with TextLogErrorMatch.matcher_name
This commit is contained in:
Родитель
ecf4c4e33a
Коммит
5c58fc600a
|
@ -5,30 +5,10 @@ from __future__ import unicode_literals
|
|||
from django.db import migrations
|
||||
|
||||
|
||||
def populate_matcher_names(apps, schema_editor):
|
||||
FailureMatch = apps.get_model('model', 'FailureMatch')
|
||||
Matcher = apps.get_model('model', 'Matcher')
|
||||
TextLogErrorMatch = apps.get_model('model', 'TextLogErrorMatch')
|
||||
|
||||
for matcher in Matcher.objects.all():
|
||||
FailureMatch.objects.filter(matcher=matcher).update(matcher_name=matcher.name)
|
||||
TextLogErrorMatch.objects.filter(matcher=matcher).update(matcher_name=matcher.name)
|
||||
|
||||
|
||||
def empty_matcher_names(apps, schema_editor):
|
||||
FailureMatch = apps.get_model('model', 'FailureMatch')
|
||||
TextLogErrorMatch = apps.get_model('model', 'TextLogErrorMatch')
|
||||
|
||||
FailureMatch.objects.update(matcher_name='')
|
||||
TextLogErrorMatch.objects.update(matcher_name='')
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('model', '0003_add_matcher_name_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(populate_matcher_names, reverse_code=empty_matcher_names)
|
||||
]
|
||||
operations = []
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.13 on 2018-06-06 09:25
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('model', '0010_remove_runnable_job'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='Matcher',
|
||||
),
|
||||
]
|
|
@ -1208,13 +1208,6 @@ class ClassifiedFailure(models.Model):
|
|||
db_table = 'classified_failure'
|
||||
|
||||
|
||||
class Matcher(models.Model):
|
||||
name = models.CharField(max_length=50, unique=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'matcher'
|
||||
|
||||
|
||||
class TextLogStep(models.Model):
|
||||
"""
|
||||
An individual step in the textual (unstructured) log
|
||||
|
|
|
@ -56,11 +56,3 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
|
||||
def get_queryset(self):
|
||||
return User.objects.filter(id=self.request.user.id)
|
||||
|
||||
|
||||
class MatcherViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
queryset = models.Matcher.objects.all()
|
||||
serializer_class = th_serializers.MatcherSerializer
|
||||
|
||||
class Meta:
|
||||
model = models.Matcher
|
||||
|
|
|
@ -104,13 +104,6 @@ class BugscacheSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
|
||||
class MatcherSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = models.Matcher
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class ClassifiedFailureSerializer(serializers.ModelSerializer):
|
||||
bug = BugscacheSerializer(read_only=True)
|
||||
|
||||
|
|
|
@ -110,7 +110,6 @@ default_router.register(r'optioncollectionhash', refdata.OptionCollectionHashVie
|
|||
base_name='optioncollectionhash')
|
||||
default_router.register(r'failureclassification', refdata.FailureClassificationViewSet)
|
||||
default_router.register(r'user', refdata.UserViewSet, base_name='user')
|
||||
default_router.register(r'matcher', refdata.MatcherViewSet)
|
||||
default_router.register(r'performance/alertsummary',
|
||||
performance_data.PerformanceAlertSummaryViewSet,
|
||||
base_name='performance-alert-summaries')
|
||||
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
|
||||
import { thEvents } from '../../../../helpers/constants';
|
||||
import { getLogViewerUrl, getApiUrl, getProjectJobUrl } from '../../../../helpers/url';
|
||||
import { getLogViewerUrl, getProjectJobUrl } from '../../../../helpers/url';
|
||||
import TextLogErrorsModel from '../../../../models/textLogErrors';
|
||||
|
||||
import AutoclassifyToolbar from './AutoclassifyToolbar';
|
||||
|
@ -89,10 +89,6 @@ class AutoclassifyTab extends React.Component {
|
|||
this.onPin = this.onPin.bind(this);
|
||||
this.save = this.save.bind(this);
|
||||
|
||||
// Cache the errorMatchers if we don't already have them loaded.
|
||||
if (!this.state.errorMatchers) {
|
||||
this.fetchErrorMatchers();
|
||||
}
|
||||
// Load the data here
|
||||
if (this.props.selectedJob.id) {
|
||||
this.fetchErrorData();
|
||||
|
@ -279,14 +275,6 @@ class AutoclassifyTab extends React.Component {
|
|||
this.$rootScope.$emit(thEvents.autoclassifyVerified, { jobs: { [selectedJob.id]: selectedJob } });
|
||||
}
|
||||
|
||||
async fetchErrorMatchers() {
|
||||
const matcherResp = await fetch(getApiUrl('/matcher/'));
|
||||
const matcherData = await matcherResp.json();
|
||||
const errorMatchers = matcherData.reduce(
|
||||
(matchersById, matcher) => matchersById.set(matcher.id, matcher), new Map());
|
||||
this.setState({ errorMatchers });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TextLogerror data from the API
|
||||
*/
|
||||
|
|
|
@ -356,16 +356,14 @@ class ErrorLine extends React.Component {
|
|||
matchesByCF.get(match.classified_failure).push(match);
|
||||
return matchesByCF;
|
||||
}, new Map());
|
||||
const matchFunc = (cf_id) => {
|
||||
const { errorMatchers } = this.props;
|
||||
return matchesByCF.get(cf_id).map(
|
||||
|
||||
const matchFunc = cf_id => matchesByCF.get(cf_id).map(
|
||||
function (match) {
|
||||
return {
|
||||
matcher: errorMatchers.get(match.matcher),
|
||||
matcher: match.matcher_name,
|
||||
score: match.score,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
return matchFunc.bind(this);
|
||||
}
|
||||
|
@ -650,12 +648,10 @@ ErrorLine.propTypes = {
|
|||
setEditable: PropTypes.func.isRequired,
|
||||
canClassify: PropTypes.bool.isRequired,
|
||||
$injector: PropTypes.object.isRequired,
|
||||
errorMatchers: PropTypes.object,
|
||||
prevErrorLine: PropTypes.object,
|
||||
};
|
||||
|
||||
ErrorLine.defaultProps = {
|
||||
errorMatchers: null,
|
||||
prevErrorLine: null,
|
||||
};
|
||||
|
||||
|
|
|
@ -75,8 +75,12 @@ class LineOption extends React.Component {
|
|||
} = this.props;
|
||||
const { isBugFilerOpen, repoName } = this.state;
|
||||
const option = optionModel;
|
||||
let logUrl = selectedJob.logs.filter(x => x.name.endsWith('_json'));
|
||||
logUrl = logUrl[0] ? logUrl[0].url : selectedJob.logs[0].url;
|
||||
let logUrl;
|
||||
|
||||
if (selectedJob.logs) {
|
||||
logUrl = selectedJob.logs.filter(x => x.name.endsWith('_json'));
|
||||
logUrl = logUrl[0] ? logUrl[0].url : selectedJob.logs[0].url;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="classification-option">
|
||||
|
@ -171,8 +175,8 @@ class LineOption extends React.Component {
|
|||
|
||||
{option.type === 'classifiedFailure' && <div className="classification-matchers">
|
||||
Matched by:
|
||||
{option.matches && option.matches.map(match => (<span key={match.matcher.id}>
|
||||
{match.matcher.name} ({match.score})
|
||||
{option.matches && option.matches.map(match => (<span key={match.matcher_name}>
|
||||
{match.matcher_name} ({match.score})
|
||||
</span>))}
|
||||
</div>}
|
||||
{isBugFilerOpen && <BugFiler
|
||||
|
|
Загрузка…
Ссылка в новой задаче