report-xfstests.py: Add filtering support for tests

- Flip a switch to hide tests that were completely skipped
- Flip a switch to hide tests that were completely passed
- Type to do a regex search of test names

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
Anna Schumaker 2022-01-27 16:39:07 -05:00
parent 1aa5f29ae9
commit b6f523e622
1 changed files with 117 additions and 6 deletions

View File

@ -4,6 +4,7 @@ gi.require_version("Gtk", "4.0")
import bisect
import pathlib
import re
import sys
import xdg.BaseDirectory
import xml.etree.ElementTree
@ -135,6 +136,15 @@ class TestCase(GObject.GObject):
def __lt__(self, rhs):
return self.name < rhs.name
def passed(self):
return False not in [ len(elm) == 0 for elm in self.tests.values() ]
def failed(self):
return 3 in [ len(elm) for elm in self.tests.values() ]
def skipped(self):
return False not in [ len(elm) == 1 for elm in self.tests.values() ]
class TestResultsModel(GObject.GObject, Gio.ListModel):
def __init__(self):
@ -169,6 +179,58 @@ class TestResultsModel(GObject.GObject, Gio.ListModel):
self.emit("items-changed", 0, rm, len(self.tests))
class TestResultsFilter(Gtk.Filter):
def __init__(self):
Gtk.Filter.__init__(self)
self.show_passing = True
self.show_skipped = True
self.regex = re.compile("")
def set_regex(self, text):
change = Gtk.FilterChange.DIFFERENT
if text in self.regex.pattern:
change = Gtk.FilterChange.LESS_STRICT
elif self.regex.pattern in text:
change = Gtk.FilterChange.MORE_STRICT
self.regex = re.compile(text, re.I)
self.changed(change)
def set_show_passing(self, val):
self.show_passing = val
self.set_show_changed(self.show_passing)
def set_show_skipped(self, val):
self.show_skipped = val
self.set_show_changed(self.show_skipped)
def set_show_changed(self, newval):
match newval:
case True: self.changed(Gtk.FilterChange.LESS_STRICT)
case False: self.changed(Gtk.FilterChange.MORE_STRICT)
def do_match(self, item):
if not self.show_passing and item.passed():
return False
if not self.show_skipped and item.skipped():
return False
if not self.show_passing and not self.show_skipped and not item.failed():
return False
return self.regex.search(item.name) != None
class FilterPopover(Gtk.Popover):
def __init__(self, parent):
Gtk.Popover.__init__(self)
self.set_child(Gtk.Label())
self.set_autohide(False)
self.set_parent(parent)
def popup(self, text):
self.get_child().set_text(text)
super().popup()
class TestResultsFactory(Gtk.SignalListItemFactory):
def __init__(self, column):
Gtk.SignalListItemFactory.__init__(self)
@ -202,12 +264,22 @@ class TestWindow(Gtk.ScrolledWindow):
Gtk.ScrolledWindow.__init__(self, vexpand=True, hexpand=True,
hscrollbar_policy=Gtk.PolicyType.NEVER)
self.results = TestResultsModel()
self.selection = Gtk.NoSelection.new(self.results)
self.filter = Gtk.FilterListModel.new(self.results, TestResultsFilter())
self.selection = Gtk.NoSelection.new(self.filter)
self.view = Gtk.ColumnView.new(self.selection)
self.set_child(self.view)
if len(sys.argv) > 1:
self.set_tests(pathlib.Path(sys.argv[1]))
def set_show_passing(self, show):
self.filter.get_filter().set_show_passing(show)
def set_show_skipped(self, show):
self.filter.get_filter().set_show_skipped(show)
def set_filter_regex(self, text):
self.filter.get_filter().set_regex(text)
def set_tests(self, path):
for column in [ c for c in self.view.get_columns() ]:
self.view.remove_column(column)
@ -222,16 +294,40 @@ class Window(Gtk.Window):
Gtk.Window.__init__(self, title="Xfstests Results")
self.calendar = Calendar()
self.servers = ServerWindow()
self.passing = Gtk.Switch(halign=Gtk.Align.CENTER, active=True)
self.lpass = Gtk.Label.new("Show Passing Tests")
self.skipped = Gtk.Switch(halign=Gtk.Align.CENTER, active=True)
self.lskip = Gtk.Label.new("Show Skipped Tests")
self.search = Gtk.SearchEntry(placeholder_text="Type To Filter Tests")
self.popover = FilterPopover(parent=self.search)
self.xfstests = TestWindow()
self.grid = Gtk.Grid()
self.grid.attach(self.calendar, 0, 0, 1, 1)
self.grid.attach(self.servers, 0, 1, 1, 1)
self.grid.attach(self.xfstests, 1, 0, 1, 2)
self.left = Gtk.Grid(row_spacing=5)
self.left.attach(self.calendar, 0, 0, 2, 1)
self.left.attach(self.servers, 0, 1, 2, 1)
self.left.attach(self.passing, 0, 2, 1, 1)
self.left.attach(self.lpass, 1, 2, 1, 1)
self.left.attach(self.skipped, 0, 3, 1, 1)
self.left.attach(self.lskip, 1, 3, 1, 1)
self.right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
self.right.append(self.search)
self.right.append(self.xfstests)
self.child = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
self.child.append(self.left)
self.child.append(self.right)
self.lskip.set_xalign(0)
self.lpass.set_xalign(0)
self.set_default_size(1000, 600)
self.set_child(self.grid)
self.set_child(self.child)
self.calendar.connect("day-selected", self.date_changed)
self.servers.connect("test-changed", self.test_changed)
self.passing.connect("notify::active", self.show_passing)
self.skipped.connect("notify::active", self.show_skipped)
self.search.connect("search-changed", self.search_changed)
self.date_changed(self.calendar)
def date_changed(self, calendar):
@ -240,6 +336,21 @@ class Window(Gtk.Window):
def test_changed(self, window, file):
self.xfstests.set_tests(pathlib.Path(file.get_path()))
def show_passing(self, passing, param):
self.xfstests.set_show_passing(passing.get_active())
def show_skipped(self, skipped, param):
self.xfstests.set_show_skipped(skipped.get_active())
def search_changed(self, search):
try:
self.xfstests.set_filter_regex(search.get_text())
self.search.remove_css_class("warning")
self.popover.popdown()
except re.error as e:
self.search.add_css_class("warning")
self.popover.popup(str(e))
class Application(Gtk.Application):
def __init__(self, *args, **kwargs):