tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_target_tasks.py (16171B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 
      6 import re
      7 import unittest
      8 
      9 import pytest
     10 from mozunit import main
     11 from taskgraph.graph import Graph
     12 from taskgraph.target_tasks import get_method
     13 from taskgraph.task import Task
     14 from taskgraph.taskgraph import TaskGraph
     15 
     16 from gecko_taskgraph import target_tasks
     17 
     18 
     19 class TestTargetTasks(unittest.TestCase):
     20    def default_matches_project(self, run_on_projects, project):
     21        return self.default_matches(
     22            attributes={
     23                "run_on_projects": run_on_projects,
     24            },
     25            parameters={
     26                "project": project,
     27                "repository_type": "hg",
     28                "hg_branch": "default",
     29            },
     30        )
     31 
     32    def default_matches_hg_branch(self, run_on_hg_branches, hg_branch):
     33        attributes = {"run_on_projects": ["all"]}
     34        if run_on_hg_branches is not None:
     35            attributes["run_on_hg_branches"] = run_on_hg_branches
     36 
     37        return self.default_matches(
     38            attributes=attributes,
     39            parameters={
     40                "project": "mozilla-central",
     41                "repository_type": "hg",
     42                "hg_branch": hg_branch,
     43            },
     44        )
     45 
     46    def default_matches(self, attributes, parameters):
     47        method = get_method("default")
     48        graph = TaskGraph(
     49            tasks={
     50                "a": Task(kind="build", label="a", attributes=attributes, task={}),
     51            },
     52            graph=Graph(nodes={"a"}, edges=set()),
     53        )
     54        return "a" in method(graph, parameters, {})
     55 
     56    def test_default_all(self):
     57        """run_on_projects=[all] includes release, integration, and other projects"""
     58        self.assertTrue(self.default_matches_project(["all"], "mozilla-central"))
     59        self.assertTrue(self.default_matches_project(["all"], "baobab"))
     60 
     61    def test_default_integration(self):
     62        """run_on_projects=[integration] includes integration projects"""
     63        self.assertFalse(
     64            self.default_matches_project(["integration"], "mozilla-central")
     65        )
     66        self.assertFalse(self.default_matches_project(["integration"], "baobab"))
     67 
     68    def test_default_release(self):
     69        """run_on_projects=[release] includes release projects"""
     70        self.assertTrue(self.default_matches_project(["release"], "mozilla-central"))
     71        self.assertFalse(self.default_matches_project(["release"], "baobab"))
     72 
     73    def test_default_nothing(self):
     74        """run_on_projects=[] includes nothing"""
     75        self.assertFalse(self.default_matches_project([], "mozilla-central"))
     76        self.assertFalse(self.default_matches_project([], "baobab"))
     77 
     78    def test_default_hg_branch(self):
     79        self.assertTrue(self.default_matches_hg_branch(None, "default"))
     80        self.assertTrue(self.default_matches_hg_branch(None, "GECKOVIEW_62_RELBRANCH"))
     81 
     82        self.assertFalse(self.default_matches_hg_branch([], "default"))
     83        self.assertFalse(self.default_matches_hg_branch([], "GECKOVIEW_62_RELBRANCH"))
     84 
     85        self.assertTrue(self.default_matches_hg_branch(["all"], "default"))
     86        self.assertTrue(
     87            self.default_matches_hg_branch(["all"], "GECKOVIEW_62_RELBRANCH")
     88        )
     89 
     90        self.assertTrue(self.default_matches_hg_branch(["default"], "default"))
     91        self.assertTrue(self.default_matches_hg_branch([r"default"], "default"))
     92        self.assertFalse(
     93            self.default_matches_hg_branch([r"default"], "GECKOVIEW_62_RELBRANCH")
     94        )
     95 
     96        self.assertTrue(
     97            self.default_matches_hg_branch(
     98                ["GECKOVIEW_62_RELBRANCH"], "GECKOVIEW_62_RELBRANCH"
     99            )
    100        )
    101        self.assertTrue(
    102            self.default_matches_hg_branch(
    103                [r"GECKOVIEW_\d+_RELBRANCH"], "GECKOVIEW_62_RELBRANCH"
    104            )
    105        )
    106        self.assertTrue(
    107            self.default_matches_hg_branch(
    108                [r"GECKOVIEW_\d+_RELBRANCH"], "GECKOVIEW_62_RELBRANCH"
    109            )
    110        )
    111        self.assertFalse(
    112            self.default_matches_hg_branch([r"GECKOVIEW_\d+_RELBRANCH"], "default")
    113        )
    114 
    115    def make_task_graph(self):
    116        tasks = {
    117            "a": Task(kind=None, label="a", attributes={}, task={}),
    118            "b": Task(kind=None, label="b", attributes={"at-at": "yep"}, task={}),
    119            "c": Task(
    120                kind=None, label="c", attributes={"run_on_projects": ["try"]}, task={}
    121            ),
    122            "ddd-1": Task(kind="test", label="ddd-1", attributes={}, task={}),
    123            "ddd-2": Task(kind="test", label="ddd-2", attributes={}, task={}),
    124            "ddd-1-cf": Task(kind="test", label="ddd-1-cf", attributes={}, task={}),
    125            "ddd-2-cf": Task(kind="test", label="ddd-2-cf", attributes={}, task={}),
    126            "ddd-var-1": Task(kind="test", label="ddd-var-1", attributes={}, task={}),
    127            "ddd-var-2": Task(kind="test", label="ddd-var-2", attributes={}, task={}),
    128        }
    129        graph = Graph(
    130            nodes=set([
    131                "a",
    132                "b",
    133                "c",
    134                "ddd-1",
    135                "ddd-2",
    136                "ddd-1-cf",
    137                "ddd-2-cf",
    138                "ddd-var-1",
    139                "ddd-var-2",
    140            ]),
    141            edges=set(),
    142        )
    143        return TaskGraph(tasks, graph)
    144 
    145    def test_empty_try(self):
    146        "try_mode = None runs nothing"
    147        tg = self.make_task_graph()
    148        method = get_method("try_tasks")
    149        params = {
    150            "try_mode": None,
    151            "project": "try",
    152            "message": "",
    153        }
    154        # only runs the task with run_on_projects: try
    155        self.assertEqual(method(tg, params, {}), [])
    156 
    157    def test_try_task_config(self):
    158        "try_mode = try_task_config uses the try config"
    159        tg = self.make_task_graph()
    160        method = get_method("try_tasks")
    161        params = {
    162            "try_mode": "try_task_config",
    163            "try_task_config": {"tasks": ["a"]},
    164        }
    165        self.assertEqual(method(tg, params, {}), ["a"])
    166 
    167    def test_try_task_config_regex(self):
    168        "try_mode = try_task_config uses the try config with regex instead of chunk numbers"
    169        tg = self.make_task_graph()
    170        method = get_method("try_tasks")
    171        params = {
    172            "try_mode": "try_task_config",
    173            "try_task_config": {"new-test-config": True, "tasks": ["ddd-*"]},
    174            "project": "try",
    175        }
    176        self.assertEqual(sorted(method(tg, params, {})), ["ddd-1", "ddd-2"])
    177 
    178    def test_try_task_config_regex_with_paths(self):
    179        "try_mode = try_task_config uses the try config with regex instead of chunk numbers"
    180        tg = self.make_task_graph()
    181        method = get_method("try_tasks")
    182        params = {
    183            "try_mode": "try_task_config",
    184            "try_task_config": {
    185                "new-test-config": True,
    186                "tasks": ["ddd-*"],
    187                "env": {"MOZHARNESS_TEST_PATHS": "foo/bar"},
    188            },
    189            "project": "try",
    190        }
    191        self.assertEqual(sorted(method(tg, params, {})), ["ddd-1"])
    192 
    193    def test_try_task_config_absolute(self):
    194        "try_mode = try_task_config uses the try config with full task labels"
    195        tg = self.make_task_graph()
    196        method = get_method("try_tasks")
    197        params = {
    198            "try_mode": "try_task_config",
    199            "try_task_config": {
    200                "new-test-config": True,
    201                "tasks": ["ddd-var-2", "ddd-1"],
    202            },
    203            "project": "try",
    204        }
    205        self.assertEqual(sorted(method(tg, params, {})), ["ddd-1", "ddd-var-2"])
    206 
    207    def test_try_task_config_regex_var(self):
    208        "try_mode = try_task_config uses the try config with regex instead of chunk numbers and a test variant"
    209        tg = self.make_task_graph()
    210        method = get_method("try_tasks")
    211        params = {
    212            "try_mode": "try_task_config",
    213            "try_task_config": {"new-test-config": True, "tasks": ["ddd-var-*"]},
    214            "project": "try",
    215        }
    216        self.assertEqual(sorted(method(tg, params, {})), ["ddd-var-1", "ddd-var-2"])
    217 
    218 
    219 # tests for specific filters
    220 
    221 
    222 @pytest.mark.parametrize(
    223    "name,params,expected",
    224    (
    225        pytest.param(
    226            "filter_tests_without_manifests",
    227            {
    228                "task": Task(kind="test", label="a", attributes={}, task={}),
    229                "parameters": None,
    230            },
    231            True,
    232            id="filter_tests_without_manifests_not_in_attributes",
    233        ),
    234        pytest.param(
    235            "filter_tests_without_manifests",
    236            {
    237                "task": Task(
    238                    kind="test",
    239                    label="a",
    240                    attributes={"test_manifests": ["foo"]},
    241                    task={},
    242                ),
    243                "parameters": None,
    244            },
    245            True,
    246            id="filter_tests_without_manifests_has_test_manifests",
    247        ),
    248        pytest.param(
    249            "filter_tests_without_manifests",
    250            {
    251                "task": Task(
    252                    kind="build",
    253                    label="a",
    254                    attributes={"test_manifests": None},
    255                    task={},
    256                ),
    257                "parameters": None,
    258            },
    259            True,
    260            id="filter_tests_without_manifests_not_a_test",
    261        ),
    262        pytest.param(
    263            "filter_tests_without_manifests",
    264            {
    265                "task": Task(
    266                    kind="test", label="a", attributes={"test_manifests": None}, task={}
    267                ),
    268                "parameters": None,
    269            },
    270            False,
    271            id="filter_tests_without_manifests_has_no_test_manifests",
    272        ),
    273        pytest.param(
    274            "filter_by_regex",
    275            {
    276                "task_label": "build-linux64-debug",
    277                "regexes": [re.compile("build")],
    278                "mode": "include",
    279            },
    280            True,
    281            id="filter_regex_simple_include",
    282        ),
    283        pytest.param(
    284            "filter_by_regex",
    285            {
    286                "task_label": "build-linux64-debug",
    287                "regexes": [re.compile("linux(.+)debug")],
    288                "mode": "include",
    289            },
    290            True,
    291            id="filter_regex_re_include",
    292        ),
    293        pytest.param(
    294            "filter_by_regex",
    295            {
    296                "task_label": "build-linux64-debug",
    297                "regexes": [re.compile("nothing"), re.compile("linux(.+)debug")],
    298                "mode": "include",
    299            },
    300            True,
    301            id="filter_regex_re_include_multiple",
    302        ),
    303        pytest.param(
    304            "filter_by_regex",
    305            {
    306                "task_label": "build-linux64-debug",
    307                "regexes": [re.compile("build")],
    308                "mode": "exclude",
    309            },
    310            False,
    311            id="filter_regex_simple_exclude",
    312        ),
    313        pytest.param(
    314            "filter_by_regex",
    315            {
    316                "task_label": "build-linux64-debug",
    317                "regexes": [re.compile("linux(.+)debug")],
    318                "mode": "exclude",
    319            },
    320            False,
    321            id="filter_regex_re_exclude",
    322        ),
    323        pytest.param(
    324            "filter_by_regex",
    325            {
    326                "task_label": "build-linux64-debug",
    327                "regexes": [re.compile("linux(.+)debug"), re.compile("nothing")],
    328                "mode": "exclude",
    329            },
    330            False,
    331            id="filter_regex_re_exclude_multiple",
    332        ),
    333        pytest.param(
    334            "filter_unsupported_artifact_builds",
    335            {
    336                "task": Task(
    337                    kind="test",
    338                    label="a",
    339                    attributes={"supports-artifact-builds": False},
    340                    task={},
    341                ),
    342                "parameters": {
    343                    "try_task_config": {
    344                        "use-artifact-builds": False,
    345                    },
    346                },
    347            },
    348            True,
    349            id="filter_unsupported_artifact_builds_no_artifact_builds",
    350        ),
    351        pytest.param(
    352            "filter_unsupported_artifact_builds",
    353            {
    354                "task": Task(
    355                    kind="test",
    356                    label="a",
    357                    attributes={"supports-artifact-builds": False},
    358                    task={},
    359                ),
    360                "parameters": {
    361                    "try_task_config": {
    362                        "use-artifact-builds": True,
    363                    },
    364                },
    365            },
    366            False,
    367            id="filter_unsupported_artifact_builds_removed",
    368        ),
    369        pytest.param(
    370            "filter_unsupported_artifact_builds",
    371            {
    372                "task": Task(
    373                    kind="test",
    374                    label="a",
    375                    attributes={"supports-artifact-builds": True},
    376                    task={},
    377                ),
    378                "parameters": {
    379                    "try_task_config": {
    380                        "use-artifact-builds": True,
    381                    },
    382                },
    383            },
    384            True,
    385            id="filter_unsupported_artifact_builds_not_removed",
    386        ),
    387        pytest.param(
    388            "filter_unsupported_artifact_builds",
    389            {
    390                "task": Task(kind="test", label="a", attributes={}, task={}),
    391                "parameters": {
    392                    "try_task_config": {
    393                        "use-artifact-builds": True,
    394                    },
    395                },
    396            },
    397            True,
    398            id="filter_unsupported_artifact_builds_not_removed",
    399        ),
    400        pytest.param(
    401            "filter_for_repo_type",
    402            {
    403                "task": Task(kind="test", label="a", attributes={}, task={}),
    404                "parameters": {
    405                    "repository_type": "hg",
    406                },
    407            },
    408            True,
    409            id="filter_for_repo_type_default_hg_not_removed",
    410        ),
    411        pytest.param(
    412            "filter_for_repo_type",
    413            {
    414                "task": Task(kind="test", label="a", attributes={}, task={}),
    415                "parameters": {
    416                    "repository_type": "git",
    417                },
    418            },
    419            True,
    420            id="filter_for_repo_type_default_git_not_removed",
    421        ),
    422        pytest.param(
    423            "filter_for_repo_type",
    424            {
    425                "task": Task(
    426                    kind="test",
    427                    label="a",
    428                    attributes={"run_on_repo_type": ["hg"]},
    429                    task={},
    430                ),
    431                "parameters": {
    432                    "repository_type": "git",
    433                },
    434            },
    435            False,
    436            id="filter_for_repo_type_no_match_removed",
    437        ),
    438        pytest.param(
    439            "filter_for_repo_type",
    440            {
    441                "task": Task(
    442                    kind="test",
    443                    label="a",
    444                    attributes={"run_on_repo_type": ["git"]},
    445                    task={},
    446                ),
    447                "parameters": {
    448                    "repository_type": "git",
    449                },
    450            },
    451            True,
    452            id="filter_for_repo_type_match_not_removed",
    453        ),
    454        pytest.param(
    455            "filter_for_repo_type",
    456            {
    457                "task": Task(
    458                    kind="test",
    459                    label="a",
    460                    attributes={"run_on_repo_type": ["all"]},
    461                    task={},
    462                ),
    463                "parameters": {
    464                    "repository_type": "git",
    465                },
    466            },
    467            True,
    468            id="filter_for_repo_type_all_not_removed",
    469        ),
    470    ),
    471 )
    472 def test_filters(name, params, expected):
    473    func = getattr(target_tasks, name)
    474    assert func(**params) is expected
    475 
    476 
    477 if __name__ == "__main__":
    478    main()