test_util_backstop.py (5063B)
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 from datetime import datetime 7 from textwrap import dedent 8 from time import mktime 9 10 import pytest 11 from mozunit import main 12 from taskgraph.util.taskcluster import get_artifact_url, get_index_url, get_task_url 13 14 from gecko_taskgraph.util.backstop import ( 15 BACKSTOP_INDEX, 16 BACKSTOP_PUSH_INTERVAL, 17 BACKSTOP_TIME_INTERVAL, 18 is_backstop, 19 ) 20 21 LAST_BACKSTOP_PUSHID = 1 22 LAST_BACKSTOP_PUSHDATE = mktime(datetime.now().timetuple()) 23 DEFAULT_RESPONSES = { 24 "index": { 25 "status": 200, 26 "json": {"taskId": LAST_BACKSTOP_PUSHID}, 27 }, 28 "artifact": { 29 "status": 200, 30 "body": dedent( 31 f""" 32 pushdate: {LAST_BACKSTOP_PUSHDATE} 33 pushlog_id: "{LAST_BACKSTOP_PUSHID}" 34 """ 35 ), 36 }, 37 "status": { 38 "status": 200, 39 "json": {"status": {"state": "complete"}}, 40 }, 41 } 42 43 44 @pytest.fixture 45 def params(): 46 return { 47 "branch": "integration/autoland", 48 "head_repository": "https://hg.mozilla.org/integration/autoland", 49 "head_rev": "abcdef", 50 "project": "autoland", 51 "pushdate": LAST_BACKSTOP_PUSHDATE + 1, 52 "pushlog_id": f"{LAST_BACKSTOP_PUSHID + 1}", 53 "repository_type": "hg", 54 "target_tasks_method": "default", 55 } 56 57 58 @pytest.mark.parametrize( 59 "response_args,extra_params,expected", 60 ( 61 pytest.param( 62 { 63 "index": {"status": 404}, 64 }, 65 {"pushlog_id": "1"}, 66 True, 67 id="no previous backstop", 68 ), 69 pytest.param( 70 { 71 "index": DEFAULT_RESPONSES["index"], 72 "status": DEFAULT_RESPONSES["status"], 73 "artifact": {"status": 404}, 74 }, 75 {"pushlog_id": 1}, 76 False, 77 id="previous backstop not finished", 78 ), 79 pytest.param( 80 DEFAULT_RESPONSES, 81 { 82 "pushlog_id": f"{LAST_BACKSTOP_PUSHID + BACKSTOP_PUSH_INTERVAL - 1}", 83 "pushdate": LAST_BACKSTOP_PUSHDATE + (BACKSTOP_TIME_INTERVAL * 60) - 1, 84 }, 85 False, 86 id="not a backstop", 87 ), 88 pytest.param( 89 {}, 90 { 91 "target_tasks_method": "nothing", 92 }, 93 False, 94 id="dontbuild", 95 ), 96 pytest.param( 97 DEFAULT_RESPONSES, 98 { 99 "pushlog_id": f"{LAST_BACKSTOP_PUSHID + BACKSTOP_PUSH_INTERVAL}", 100 }, 101 True, 102 id="interval", 103 ), 104 pytest.param( 105 DEFAULT_RESPONSES, 106 { 107 "pushlog_id": f"{LAST_BACKSTOP_PUSHID + BACKSTOP_PUSH_INTERVAL + 1}", 108 }, 109 True, 110 id="greater than interval", 111 ), 112 pytest.param( 113 DEFAULT_RESPONSES, 114 { 115 "pushdate": LAST_BACKSTOP_PUSHDATE + (BACKSTOP_TIME_INTERVAL * 60), 116 }, 117 True, 118 id="time elapsed", 119 ), 120 pytest.param( 121 {}, 122 { 123 "project": "try", 124 "pushlog_id": f"{BACKSTOP_PUSH_INTERVAL}", 125 }, 126 False, 127 id="try not a backstop", 128 ), 129 pytest.param( 130 {}, 131 { 132 "project": "mozilla-central", 133 }, 134 True, 135 id="release branches always a backstop", 136 ), 137 pytest.param( 138 { 139 "index": DEFAULT_RESPONSES["index"], 140 "status": { 141 "status": 200, 142 "json": {"status": {"state": "failed"}}, 143 }, 144 }, 145 {}, 146 True, 147 id="last backstop failed", 148 ), 149 pytest.param( 150 {}, 151 { 152 "repository_type": "git", 153 }, 154 True, 155 id="git", 156 ), 157 ), 158 ) 159 def test_is_backstop( 160 monkeypatch, 161 responses, 162 params, 163 response_args, 164 extra_params, 165 expected, 166 ): 167 root_url = "https://taskcluster.example.com" 168 monkeypatch.delenv("TASKCLUSTER_PROXY_URL", raising=False) 169 monkeypatch.setenv("TASKCLUSTER_ROOT_URL", root_url) 170 171 urls = { 172 "index": get_index_url( 173 BACKSTOP_INDEX.format(**{ 174 "trust-domain": "gecko", 175 "project": params["project"], 176 }) 177 ), 178 "artifact": get_artifact_url(LAST_BACKSTOP_PUSHID, "public%2Fparameters.yml"), 179 "status": get_task_url(LAST_BACKSTOP_PUSHID) + "/status", 180 } 181 182 for key in ("index", "status", "artifact"): 183 if key in response_args: 184 responses.add(responses.GET, urls[key], **response_args[key]) 185 186 params.update(extra_params) 187 assert is_backstop(params) is expected 188 189 190 if __name__ == "__main__": 191 main()