test_push_to_try.py (7340B)
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 import os 6 import subprocess 7 import textwrap 8 import uuid 9 10 import mozunit 11 import pytest 12 13 from mozversioncontrol import MissingVCSExtension, get_repository_object 14 15 16 def test_push_to_try(repo, monkeypatch): 17 if repo.vcs == "src": 18 pytest.skip("src repo cannot push") 19 20 commit_message = "commit message" 21 vcs = get_repository_object(repo.dir) 22 23 captured_commands = [] 24 captured_inputs = [] 25 26 def fake_run(*args, **kwargs): 27 cmd = args[0] 28 captured_commands.append(cmd) 29 if cmd[1] == "var" and cmd[2] in ("GIT_AUTHOR_IDENT", "GIT_COMMITTER_IDENT"): 30 return "FooBar <foobar@example.com> 0 +0000" 31 if cmd[1:] == ("rev-parse", "HEAD"): 32 return "0987654321098765432109876543210987654321" 33 if cmd[1:] == ("fast-import", "--quiet"): 34 if input := kwargs.get("input"): 35 captured_inputs.append(input) 36 return "1234567890123456789012345678901234567890" 37 if os.path.basename(cmd[0]).startswith("hg") and cmd[1] == "--version": 38 return "version 6.7" 39 return "" 40 41 def normalize_fake_run(*args, **kwargs): 42 if ( 43 kwargs.get("text") 44 or kwargs.get("universal_newlines") 45 or kwargs.get("encoding") 46 ): 47 return fake_run(*args, **kwargs) 48 if input := kwargs.get("input"): 49 kwargs["input"] = input.decode("utf-8") 50 return fake_run(*args, **kwargs).encode("utf-8") 51 52 def fake_uuid(): 53 return "974284fd-f395-4a15-a9d7-814a71241242" 54 55 monkeypatch.setattr(subprocess, "check_output", normalize_fake_run) 56 monkeypatch.setattr(subprocess, "check_call", normalize_fake_run) 57 monkeypatch.setattr(uuid, "uuid4", fake_uuid) 58 59 vcs.push_to_try( 60 commit_message, 61 { 62 "extra-file": "content", 63 "other/extra-file": "content2", 64 }, 65 ) 66 tool = vcs._tool 67 68 if repo.vcs == "hg": 69 expected = [ 70 (str(tool), "--version"), 71 ( 72 str(tool), 73 "--config", 74 "extensions.automv=", 75 "addremove", 76 os.path.join(vcs.path, "extra-file"), 77 os.path.join(vcs.path, "other", "extra-file"), 78 ), 79 (str(tool), "push-to-try", "-m", commit_message), 80 (str(tool), "revert", "-a"), 81 ] 82 expected_inputs = [] 83 elif repo.vcs == "git": 84 expected = [ 85 (str(tool), "cinnabar", "--version"), 86 (str(tool), "rev-parse", "HEAD"), 87 (str(tool), "var", "GIT_AUTHOR_IDENT"), 88 (str(tool), "var", "GIT_COMMITTER_IDENT"), 89 (str(tool), "fast-import", "--quiet"), 90 ( 91 str(tool), 92 "-c", 93 "cinnabar.data=never", 94 "push", 95 "hg::ssh://hg.mozilla.org/try", 96 "+1234567890123456789012345678901234567890:refs/heads/branches/default/tip", 97 ), 98 ( 99 str(tool), 100 "update-ref", 101 "-m", 102 "mach try: push", 103 "HEAD", 104 "1234567890123456789012345678901234567890", 105 "0987654321098765432109876543210987654321", 106 ), 107 ( 108 str(tool), 109 "update-ref", 110 "-m", 111 "mach try: restore", 112 "HEAD", 113 "0987654321098765432109876543210987654321", 114 "1234567890123456789012345678901234567890", 115 ), 116 ] 117 expected_inputs = [ 118 textwrap.dedent( 119 f"""\ 120 commit refs/machtry/974284fd-f395-4a15-a9d7-814a71241242 121 mark :1 122 author FooBar <foobar@example.com> 0 +0000 123 committer FooBar <foobar@example.com> 0 +0000 124 data {len(commit_message)} 125 {commit_message} 126 from 0987654321098765432109876543210987654321 127 M 100644 inline extra-file 128 data 7 129 content 130 M 100644 inline other/extra-file 131 data 8 132 content2 133 reset refs/machtry/974284fd-f395-4a15-a9d7-814a71241242 134 from 0000000000000000000000000000000000000000 135 get-mark :1 136 """ 137 ), 138 ] 139 else: 140 assert repo.vcs == "jj" 141 expected = [ 142 (str(vcs._git._tool), "cinnabar", "--version"), 143 (str(tool), "debug", "snapshot"), 144 ( 145 str(tool), 146 "operation", 147 "log", 148 "-n1", 149 "--no-graph", 150 "-T", 151 "id.short(16)", 152 ), 153 ( 154 str(tool), 155 "new", 156 "-m", 157 "commit message", 158 'coalesce(@ ~ (empty() & description(exact:"")) ~ bookmarks(), @-)', 159 ), 160 (str(tool), "file", "track", "extra-file"), 161 (str(tool), "file", "track", "other/extra-file"), 162 (str(tool), "log", "-n0"), 163 ( 164 str(tool), 165 "--ignore-working-copy", 166 "log", 167 "--no-graph", 168 "-n1", 169 "-r", 170 "@", 171 "-T", 172 "change_id.short()", 173 ), 174 (str(vcs._git._tool), "remote"), 175 ( 176 str(vcs._git._tool), 177 "remote", 178 "add", 179 "mach_tryserver", 180 "hg::ssh://hg.mozilla.org/try", 181 ), 182 (str(tool), "git", "import"), 183 ( 184 str(tool), 185 "git", 186 "push", 187 "--remote", 188 "mach_tryserver", 189 "--change", 190 None, 191 "--allow-new", 192 "--allow-empty-description", 193 ), 194 (str(tool), "operation", "restore", ""), 195 (str(tool), "git", "remote", "remove", "mach_tryserver"), 196 ] 197 expected_inputs = [] 198 199 for i, value in enumerate(captured_commands): 200 assert value == expected[i] 201 202 assert len(captured_commands) == len(expected) 203 204 for i, value in enumerate(captured_inputs): 205 assert value == expected_inputs[i] 206 207 assert len(captured_inputs) == len(expected_inputs) 208 209 210 def test_push_to_try_missing_extensions(repo, monkeypatch): 211 if repo.vcs not in ("git", "jj"): 212 return 213 214 vcs = get_repository_object(repo.dir) 215 216 orig = vcs._run 217 218 def cinnabar_raises(*args, **kwargs): 219 # Simulate not having git cinnabar 220 if args[0] == "cinnabar": 221 raise subprocess.CalledProcessError(1, args) 222 return orig(*args, **kwargs) 223 224 monkeypatch.setattr(vcs, "_run", cinnabar_raises) 225 if hasattr(vcs, "_git"): 226 monkeypatch.setattr(vcs._git, "_run", cinnabar_raises) 227 228 with pytest.raises(MissingVCSExtension): 229 vcs.push_to_try("commit message") 230 231 232 if __name__ == "__main__": 233 mozunit.main()