Commit e1ec8183 authored by slamm's avatar slamm Committed by Commit bot

Rename page filter options to story options.

Refactor code and tests.

--page-filter is kept as a (deprecated) alternative to --story-filter.

BUG=444425

Review URL: https://codereview.chromium.org/994683003

Cr-Commit-Position: refs/heads/master@{#321226}
parent 29fda863
...@@ -62,7 +62,7 @@ class MediaAndroid(benchmark.Benchmark): ...@@ -62,7 +62,7 @@ class MediaAndroid(benchmark.Benchmark):
tag = 'android' tag = 'android'
page_set = page_sets.ToughVideoCasesPageSet page_set = page_sets.ToughVideoCasesPageSet
# Exclude is_4k and 50 fps media files (garden* & crowd*). # Exclude is_4k and 50 fps media files (garden* & crowd*).
options = {'page_label_filter_exclude': 'is_4k,is_50fps'} options = {'story_label_filter_exclude': 'is_4k,is_50fps'}
@classmethod @classmethod
def Name(cls): def Name(cls):
...@@ -77,9 +77,9 @@ class MediaChromeOS4kOnly(benchmark.Benchmark): ...@@ -77,9 +77,9 @@ class MediaChromeOS4kOnly(benchmark.Benchmark):
tag = 'chromeOS4kOnly' tag = 'chromeOS4kOnly'
page_set = page_sets.ToughVideoCasesPageSet page_set = page_sets.ToughVideoCasesPageSet
options = { options = {
'page_label_filter': 'is_4k', 'story_label_filter': 'is_4k',
# Exclude is_50fps test files: crbug/331816 # Exclude is_50fps test files: crbug/331816
'page_label_filter_exclude': 'is_50fps' 'story_label_filter_exclude': 'is_50fps'
} }
@classmethod @classmethod
...@@ -98,7 +98,7 @@ class MediaChromeOS(benchmark.Benchmark): ...@@ -98,7 +98,7 @@ class MediaChromeOS(benchmark.Benchmark):
tag = 'chromeOS' tag = 'chromeOS'
page_set = page_sets.ToughVideoCasesPageSet page_set = page_sets.ToughVideoCasesPageSet
# Exclude is_50fps test files: crbug/331816 # Exclude is_50fps test files: crbug/331816
options = {'page_label_filter_exclude': 'is_4k,is_50fps'} options = {'story_label_filter_exclude': 'is_4k,is_50fps'}
@classmethod @classmethod
def Name(cls): def Name(cls):
......
...@@ -216,7 +216,7 @@ class SmoothnessGpuRasterizationPolymer(benchmark.Benchmark): ...@@ -216,7 +216,7 @@ class SmoothnessGpuRasterizationPolymer(benchmark.Benchmark):
class SmoothnessToughFastScrollingCases(benchmark.Benchmark): class SmoothnessToughFastScrollingCases(benchmark.Benchmark):
test = smoothness.Smoothness test = smoothness.Smoothness
page_set = page_sets.ToughScrollingCasesPageSet page_set = page_sets.ToughScrollingCasesPageSet
options = {'page_label_filter': 'fastscrolling'} options = {'story_label_filter': 'fastscrolling'}
@classmethod @classmethod
def Name(cls): def Name(cls):
......
...@@ -47,7 +47,7 @@ class ThreadTimesFastPathMobileSites(_ThreadTimes): ...@@ -47,7 +47,7 @@ class ThreadTimesFastPathMobileSites(_ThreadTimes):
key mobile sites labeled with fast-path tag. key mobile sites labeled with fast-path tag.
http://www.chromium.org/developers/design-documents/rendering-benchmarks""" http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
page_set = page_sets.KeyMobileSitesSmoothPageSet page_set = page_sets.KeyMobileSitesSmoothPageSet
options = {'page_label_filter' : 'fastpath'} options = {'story_label_filter' : 'fastpath'}
@classmethod @classmethod
def Name(cls): def Name(cls):
......
...@@ -8,73 +8,76 @@ import re ...@@ -8,73 +8,76 @@ import re
from telemetry.core import command_line from telemetry.core import command_line
def HasLabelIn(user_story, labels): class _StoryMatcher(object):
return bool(user_story.labels.intersection(labels)) def __init__(self, pattern):
self._regex = None
self.has_compile_error = False
if pattern:
try:
self._regex = re.compile(pattern)
except re.error:
self.has_compile_error = True
def __nonzero__(self):
return self._regex is not None
def HasMatch(self, user_story):
return self and bool(
self._regex.search(user_story.display_name) or
(user_story.name and self._regex.search(user_story.name)))
class _StoryLabelMatcher(object):
def __init__(self, labels_str):
self._labels = labels_str.split(',') if labels_str else None
def __nonzero__(self):
return self._labels is not None
def HasLabelIn(self, user_story):
return self and bool(user_story.labels.intersection(self._labels))
class UserStoryFilter(command_line.ArgumentHandlerMixIn): class UserStoryFilter(command_line.ArgumentHandlerMixIn):
"""Filters pages in the page set based on command-line flags.""" """Filters user stories in the user story set based on command-line flags."""
@classmethod @classmethod
def AddCommandLineArgs(cls, parser): def AddCommandLineArgs(cls, parser):
group = optparse.OptionGroup(parser, 'Page filtering options') group = optparse.OptionGroup(parser, 'User story filtering options')
group.add_option('--page-filter', group.add_option('--story-filter',
help='Use only pages whose URLs match the given filter regexp.') help='Use only user stories whose names match the given filter regexp.')
group.add_option('--page-filter-exclude', group.add_option('--page-filter', dest='story_filter',
help='Exclude pages whose URLs match the given filter regexp.') help='Deprecated. Use --story-filter instead.')
group.add_option('--page-label-filter', group.add_option('--story-filter-exclude',
help='Use only pages that have any of these labels') help='Exclude user stories whose names match the given filter regexp.')
group.add_option('--page-label-filter-exclude', group.add_option('--story-label-filter',
help='Exclude pages that have any of these labels') help='Use only user stories that have any of these labels')
group.add_option('--story-label-filter-exclude',
help='Exclude user stories that have any of these labels')
parser.add_option_group(group) parser.add_option_group(group)
@classmethod @classmethod
def ProcessCommandLineArgs(cls, parser, args): def ProcessCommandLineArgs(cls, parser, args):
cls._page_regex = None cls._include_regex = _StoryMatcher(args.story_filter)
cls._page_exclude_regex = None cls._exclude_regex = _StoryMatcher(args.story_filter_exclude)
cls._include_labels = None cls._include_labels = _StoryLabelMatcher(args.story_label_filter)
cls._exclude_labels = None cls._exclude_labels = _StoryLabelMatcher(args.story_label_filter_exclude)
if args.page_filter:
try:
cls._page_regex = re.compile(args.page_filter)
except re.error:
raise parser.error('--page-filter: invalid regex')
if args.page_filter_exclude:
try:
cls._page_exclude_regex = re.compile(args.page_filter_exclude)
except re.error:
raise parser.error('--page-filter-exclude: invalid regex')
if args.page_label_filter: if cls._include_regex.has_compile_error:
cls._include_labels = args.page_label_filter.split(',') raise parser.error('--story-filter: Invalid regex.')
if cls._exclude_regex.has_compile_error:
if args.page_label_filter_exclude: raise parser.error('--story-filter-exclude: Invalid regex.')
cls._exclude_labels = args.page_label_filter_exclude.split(',')
@classmethod @classmethod
def IsSelected(cls, user_story): def IsSelected(cls, user_story):
# Exclude filters take priority. # Exclude filters take priority.
if cls._exclude_labels and HasLabelIn(user_story, cls._exclude_labels): if cls._exclude_labels.HasLabelIn(user_story):
return False
if cls._exclude_regex.HasMatch(user_story):
return False
if cls._include_labels and not cls._include_labels.HasLabelIn(user_story):
return False
if cls._include_regex and not cls._include_regex.HasMatch(user_story):
return False return False
if cls._page_exclude_regex: return True
matches_display_name = cls._page_exclude_regex.search(
user_story.display_name)
matches_name = user_story.name and cls._page_exclude_regex.search(
user_story.name)
if matches_display_name or matches_name:
return False
# Apply all filters.
filter_result = True
if cls._include_labels:
filter_result = filter_result and HasLabelIn(
user_story, cls._include_labels)
if cls._page_regex:
matches_display_name = cls._page_regex.search(user_story.display_name)
matches_name = user_story.name and cls._page_regex.search(user_story.name)
filter_result = filter_result and (matches_display_name or matches_name)
return filter_result
...@@ -4,92 +4,91 @@ ...@@ -4,92 +4,91 @@
import unittest import unittest
from telemetry.user_story import user_story_filter
from telemetry.page import page from telemetry.page import page
from telemetry.page import page_set from telemetry.page import page_set
from telemetry.user_story import user_story_filter
class MockUrlFilterOptions(object):
def __init__(self, page_filter_include, page_filter_exclude):
self.page_filter = page_filter_include
self.page_filter_exclude = page_filter_exclude
self.page_label_filter = None
self.page_label_filter_exclude = None
class MockLabelFilterOptions(object):
def __init__(self, page_label_filter, page_label_filter_exclude):
self.page_filter = None
self.page_filter_exclude = None
self.page_label_filter = page_label_filter
self.page_label_filter_exclude = page_label_filter_exclude
class UserStoryFilterTest(unittest.TestCase): class UserStoryFilterTest(unittest.TestCase):
def setUp(self): def setUp(self):
ps = page_set.PageSet() ps = page_set.PageSet()
self.p1 = page.Page( self.p1 = page.Page(
'file://conformance/textures/tex-sub-image-2d.html', page_set=ps, url='file://your/smile/widen.html', page_set=ps,
name='WebglConformance.conformance_textures_tex_sub_image_2d', name='MayYour.smile_widen', labels=['label1', 'label2'])
labels=['label1', 'label2'])
self.p2 = page.Page( self.p2 = page.Page(
'file://othersuite/textures/tex-sub-image-3d.html', page_set=ps, url='file://share_a/smile/too.html', page_set=ps,
name='OtherSuite.textures_tex_sub_image_3d', name='ShareA.smiles_too', labels=['label1'])
labels=['label1'])
self.p3 = page.Page( self.p3 = page.Page(
'file://othersuite/textures/tex-sub-image-3d.html', page_set=ps, url='file://share_a/smile/too.html', page_set=ps,
labels=['label2']) labels=['label2'])
self.pages = [self.p1, self.p2, self.p3]
@staticmethod
def ProcessCommandLineArgs(parser=None, **kwargs):
class Options(object):
def __init__(
self, story_filter=None, story_filter_exclude=None,
story_label_filter=None, story_label_filter_exclude=None):
self.story_filter = story_filter
self.story_filter_exclude = story_filter_exclude
self.story_label_filter = story_label_filter
self.story_label_filter_exclude = story_label_filter_exclude
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(
parser, Options(**kwargs))
def PageSelections(self):
return [user_story_filter.UserStoryFilter.IsSelected(p) for p in self.pages]
def testNoFilterMatchesAll(self):
self.ProcessCommandLineArgs()
self.assertEquals([True, True, True], self.PageSelections())
def testBadRegexCallsParserError(self):
class MockParserException(Exception):
pass
class MockParser(object):
def error(self, _):
raise MockParserException
with self.assertRaises(MockParserException):
self.ProcessCommandLineArgs(parser=MockParser(), story_filter='+')
def testUniqueSubstring(self):
self.ProcessCommandLineArgs(story_filter='smile_widen')
self.assertEquals([True, False, False], self.PageSelections())
def testSharedSubstring(self):
self.ProcessCommandLineArgs(story_filter='smile')
self.assertEquals([True, True, True], self.PageSelections())
def testNoMatch(self):
self.ProcessCommandLineArgs(story_filter='frown')
self.assertEquals([False, False, False], self.PageSelections())
def testExclude(self):
self.ProcessCommandLineArgs(story_filter_exclude='ShareA')
self.assertEquals([True, False, True], self.PageSelections())
def testExcludeTakesPriority(self):
self.ProcessCommandLineArgs(
story_filter='smile',
story_filter_exclude='wide')
self.assertEquals([False, True, True], self.PageSelections())
def testNoNameMatchesDisplayName(self):
self.ProcessCommandLineArgs(story_filter='share_a/smile')
self.assertEquals([False, False, True], self.PageSelections())
def testNoLabelMatch(self):
self.ProcessCommandLineArgs(story_label_filter='labelX')
self.assertEquals([False, False, False], self.PageSelections())
def testLabelsAllMatch(self):
self.ProcessCommandLineArgs(story_label_filter='label1,label2')
self.assertEquals([True, True, True], self.PageSelections())
def testURLPattern(self): def testExcludeLabelTakesPriority(self):
options = MockUrlFilterOptions('conformance_textures', '') self.ProcessCommandLineArgs(
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options) story_label_filter='label1',
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p1)) story_label_filter_exclude='label2')
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p2)) self.assertEquals([False, True, False], self.PageSelections())
options = MockUrlFilterOptions('textures', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p2))
options = MockUrlFilterOptions('somethingelse', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p2))
def testName(self):
options = MockUrlFilterOptions('somethingelse', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p2))
options = MockUrlFilterOptions('textures_tex_sub_image', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p2))
options = MockUrlFilterOptions('WebglConformance', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p2))
options = MockUrlFilterOptions('OtherSuite', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p2))
def testNameNone(self):
options = MockUrlFilterOptions('othersuite/textures', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p3))
options = MockUrlFilterOptions('conformance/textures', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p3))
def testLabelFilters(self):
# Include both labels
options = MockLabelFilterOptions('label1,label2', '')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p2))
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p3))
# Exclude takes priority
options = MockLabelFilterOptions('label1', 'label2')
user_story_filter.UserStoryFilter.ProcessCommandLineArgs(None, options)
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p1))
self.assertTrue(user_story_filter.UserStoryFilter.IsSelected(self.p2))
self.assertFalse(user_story_filter.UserStoryFilter.IsSelected(self.p3))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment