Bug 1656465 - [taskgraph.optimize] Implement a 'Not' composite strategy, r=marco

It turns out that 'Not' is needed to negate "backstops". E.g, we normally
we want to use a pattern like so:

    All("skip-unless-backstop", "test")

Since 'skip-unless-backstop' returns False on backstop pushes, it disables
the test strategy there.

However, suppose we wanted to run a special optimization, *only* on backstop
pushes. I.e, the opposite of the above example. Then we need to use:

    All(Not("skip-unless-backstop"), "test-backstop")

Depends on D89500

Differential Revision: https://phabricator.services.mozilla.com/D89734
This commit is contained in:
Andrew Halberstadt 2020-09-11 09:07:21 +00:00
parent 3cffeac488
commit fba47918cb
2 changed files with 31 additions and 4 deletions

View File

@ -473,6 +473,19 @@ class Alias(CompositeStrategy):
return next(results)
class Not(CompositeStrategy):
"""Given a strategy, returns the opposite."""
def __init__(self, strategy):
super(Not, self).__init__(strategy)
@property
def description(self):
return "not-" + self.substrategies[0].description
def reduce(self, results):
return not next(results)
def split_bugbug_arg(arg, substrategies):
"""Split args for bugbug based strategies.

View File

@ -8,7 +8,7 @@ from functools import partial
import pytest
from taskgraph import graph, optimize
from taskgraph.optimize import OptimizationStrategy, All, Any
from taskgraph.optimize import OptimizationStrategy, All, Any, Not
from taskgraph.taskgraph import TaskGraph
from taskgraph.task import Task
from mozunit import main
@ -146,6 +146,18 @@ def make_triangle(deps=True, **opts):
id="composite_strategies_all",
),
# Tasks with the 'not' composite strategy are removed when the substrategy says not to
pytest.param(
make_graph(
make_task('t1', {'not-never': None}),
make_task('t2', {'not-remove': None}),
),
{"strategies": lambda: {"not-never": Not("never"), "not-remove": Not("remove")}},
# expectations
{"t1"},
id="composite_strategies_not",
),
# Removable tasks that are depended on by non-removable tasks are not removed
pytest.param(
make_triangle(
@ -272,9 +284,11 @@ def test_remove_tasks(monkeypatch, graph, kwargs, exp_removed):
# set up strategies
strategies = default_strategies()
monkeypatch.setattr(optimize, "registry", strategies)
strategies = kwargs.pop('strategies', None) or strategies
if callable(strategies):
strategies = strategies()
extra = kwargs.pop('strategies', None)
if extra:
if callable(extra):
extra = extra()
strategies.update(extra)
kwargs.setdefault("params", {})
kwargs.setdefault("do_not_optimize", set())