add report of bisection events
This commit is contained in:
Родитель
9640ad526e
Коммит
804feb5be2
|
@ -9,6 +9,7 @@ from mozlog.structured.structuredlog import StructuredLogger
|
|||
from mozregui.ui.mainwindow import Ui_MainWindow
|
||||
from mozregui.wizard import BisectionWizard
|
||||
from mozregui.bisection import BisectRunner
|
||||
from mozregui.report import ReportModel
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
|
@ -18,6 +19,12 @@ class MainWindow(QMainWindow):
|
|||
self.ui.setupUi(self)
|
||||
self.bisect_runner = BisectRunner(self)
|
||||
|
||||
self.report_model = ReportModel()
|
||||
self.ui.report_view.setModel(self.report_model)
|
||||
|
||||
self.bisect_runner.bisector_created.connect(
|
||||
self.report_model.attach_bisector)
|
||||
|
||||
@Slot()
|
||||
def start_bisection_wizard(self):
|
||||
wizard = BisectionWizard(self)
|
||||
|
|
|
@ -66,7 +66,11 @@ class GuiTestRunner(QObject, TestRunner):
|
|||
|
||||
|
||||
class GuiBisector(QObject, Bisector):
|
||||
finished = Signal(int)
|
||||
started = Signal(object)
|
||||
finished = Signal(object, int)
|
||||
step_started = Signal(object, int)
|
||||
step_build_found = Signal(object, int, object)
|
||||
step_finished = Signal(object, int, str)
|
||||
|
||||
def __init__(self, fetch_config, persist=None):
|
||||
QObject.__init__(self)
|
||||
|
@ -75,6 +79,7 @@ class GuiBisector(QObject, Bisector):
|
|||
self.bisection = None
|
||||
self.mid = None
|
||||
self.build_infos = None
|
||||
self._step_num = 0
|
||||
|
||||
self.download_manager.download_finished.connect(self._build_dl_finished)
|
||||
self.test_runner.evaluate_finished.connect(self._evaluate_finished)
|
||||
|
@ -85,19 +90,25 @@ class GuiBisector(QObject, Bisector):
|
|||
self.test_runner,
|
||||
self.fetch_config,
|
||||
dl_in_background=False)
|
||||
self._step_num = 0
|
||||
self.started.emit(self.bisection)
|
||||
self._bisect_next()
|
||||
|
||||
@Slot()
|
||||
def _bisect_next(self):
|
||||
self._step_num += 1
|
||||
self.step_started.emit(self.bisection, self._step_num)
|
||||
# todo: make this non blocking
|
||||
self.mid = mid = self.bisection.search_mid_point()
|
||||
result = self.bisection.init_handler(mid)
|
||||
if result != Bisection.RUNNING:
|
||||
self.finished.emit(result)
|
||||
self.finished.emit(self.bisection, result)
|
||||
else:
|
||||
self.build_infos = \
|
||||
self.bisection.handler.build_infos(mid, self.fetch_config)
|
||||
self.download_manager.focus_download(self.build_infos)
|
||||
self.step_build_found.emit(self.bisection, self._step_num,
|
||||
self.build_infos)
|
||||
|
||||
@Slot(object)
|
||||
def _build_dl_finished(self, dl):
|
||||
|
@ -111,14 +122,18 @@ class GuiBisector(QObject, Bisector):
|
|||
@Slot()
|
||||
def _evaluate_finished(self):
|
||||
self.bisection.update_build_info(self.mid, self.test_runner.app_info)
|
||||
self.step_finished.emit(self.bisection, self._step_num,
|
||||
self.test_runner.verdict)
|
||||
result = self.bisection.handle_verdict(self.mid, self.test_runner.verdict)
|
||||
if result != Bisection.RUNNING:
|
||||
self.finished.emit(result)
|
||||
self.finished.emit(self.bisection, result)
|
||||
else:
|
||||
self._bisect_next()
|
||||
|
||||
|
||||
class BisectRunner(QObject):
|
||||
bisector_created = Signal(object)
|
||||
|
||||
def __init__(self, mainwindow):
|
||||
QObject.__init__(self)
|
||||
self.mainwindow = mainwindow
|
||||
|
@ -129,6 +144,7 @@ class BisectRunner(QObject):
|
|||
fetch_config = create_config(options['application'],
|
||||
mozinfo.os, mozinfo.bits)
|
||||
self.bisector = GuiBisector(fetch_config)
|
||||
self.bisector.started.connect(self.on_bisection_started)
|
||||
self.bisector.download_manager.download_progress.connect(
|
||||
self.show_dl_progress)
|
||||
self.bisector.test_runner.evaluate_started.connect(
|
||||
|
@ -166,8 +182,8 @@ class BisectRunner(QObject):
|
|||
verdict = "b"
|
||||
self.bisector.test_runner.finish(verdict)
|
||||
|
||||
@Slot(int)
|
||||
def bisection_finished(self, resultcode):
|
||||
@Slot(object, int)
|
||||
def bisection_finished(self, bisection, resultcode):
|
||||
if resultcode == Bisection.NO_DATA:
|
||||
msg = "Unable to find enough data to bisect."
|
||||
dialog = QMessageBox.warning
|
||||
|
@ -175,3 +191,7 @@ class BisectRunner(QObject):
|
|||
msg = "The bisection is done."
|
||||
dialog = QMessageBox.information
|
||||
dialog(self.mainwindow, "End of the bisection", msg)
|
||||
|
||||
@Slot()
|
||||
def on_bisection_started(self):
|
||||
self.bisector_created.emit(self.bisector)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
from PySide.QtCore import QAbstractTableModel, QModelIndex, Qt, \
|
||||
Slot
|
||||
|
||||
class StepReport(object):
|
||||
def __init__(self):
|
||||
self.build_infos = None
|
||||
self.verdict = None
|
||||
|
||||
def status_text(self):
|
||||
if self.build_infos is None:
|
||||
return "Looking for build data..."
|
||||
if self.build_infos['build_type'] == 'nightly':
|
||||
msg = "Found nightly build: %s" % self.build_infos['build_date']
|
||||
else:
|
||||
msg = "Found inbound build: %s" % self.build_infos['changeset']
|
||||
if self.verdict is not None:
|
||||
msg += ' (verdict: %s)' % self.verdict
|
||||
return msg
|
||||
|
||||
class ReportModel(QAbstractTableModel):
|
||||
def __init__(self):
|
||||
QAbstractTableModel.__init__(self)
|
||||
self.step_reports = []
|
||||
|
||||
@Slot(object)
|
||||
def attach_bisector(self, bisector):
|
||||
bisector.step_started.connect(self.step_started)
|
||||
bisector.step_build_found.connect(self.step_build_found)
|
||||
bisector.step_finished.connect(self.step_finished)
|
||||
bisector.finished.connect(self.finished)
|
||||
|
||||
def rowCount(self, parent=QModelIndex()):
|
||||
return len(self.step_reports)
|
||||
|
||||
def columnCount(self, parent=QModelIndex()):
|
||||
return 1
|
||||
|
||||
def data(self, index, role=Qt.DisplayRole):
|
||||
if role == Qt.DisplayRole:
|
||||
step_report = self.step_reports[index.row()]
|
||||
return step_report.status_text()
|
||||
return None
|
||||
|
||||
def update_step_report(self, step_report):
|
||||
index = self.createIndex(self.step_reports.index(step_report), 0)
|
||||
self.dataChanged.emit(index, index)
|
||||
|
||||
@Slot(object, int)
|
||||
def step_started(self, bisection, step_num):
|
||||
self.beginInsertRows(QModelIndex(), step_num-1, step_num-1)
|
||||
self.step_reports.append(StepReport())
|
||||
self.endInsertRows()
|
||||
|
||||
@Slot(object, int, object)
|
||||
def step_build_found(self, bisection, step_num, build_infos):
|
||||
step_report = self.step_reports[step_num-1]
|
||||
step_report.build_infos = build_infos
|
||||
self.update_step_report(step_report)
|
||||
|
||||
@Slot(object, int, str)
|
||||
def step_finished(self, bisection, step_num, verdict):
|
||||
step_report = self.step_reports[step_num-1]
|
||||
step_report.verdict = verdict
|
||||
self.update_step_report(step_report)
|
||||
|
||||
@Slot(object, int)
|
||||
def finished(self, bisection, result):
|
||||
# remove the last insterted step
|
||||
index = len(self.step_reports) -1
|
||||
self.beginRemoveRows(QModelIndex(), index, index)
|
||||
self.step_reports.pop(index)
|
||||
self.endRemoveRows()
|
|
@ -13,7 +13,23 @@
|
|||
<property name="windowTitle">
|
||||
<string>Mozregression-gui</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="report_view">
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
|
Загрузка…
Ссылка в новой задаче