11cb0ef41Sopenharmony_ci#!/usr/bin/env python3
21cb0ef41Sopenharmony_ci# Copyright 2013 the V8 project authors. All rights reserved.
31cb0ef41Sopenharmony_ci# Redistribution and use in source and binary forms, with or without
41cb0ef41Sopenharmony_ci# modification, are permitted provided that the following conditions are
51cb0ef41Sopenharmony_ci# met:
61cb0ef41Sopenharmony_ci#
71cb0ef41Sopenharmony_ci#     * Redistributions of source code must retain the above copyright
81cb0ef41Sopenharmony_ci#       notice, this list of conditions and the following disclaimer.
91cb0ef41Sopenharmony_ci#     * Redistributions in binary form must reproduce the above
101cb0ef41Sopenharmony_ci#       copyright notice, this list of conditions and the following
111cb0ef41Sopenharmony_ci#       disclaimer in the documentation and/or other materials provided
121cb0ef41Sopenharmony_ci#       with the distribution.
131cb0ef41Sopenharmony_ci#     * Neither the name of Google Inc. nor the names of its
141cb0ef41Sopenharmony_ci#       contributors may be used to endorse or promote products derived
151cb0ef41Sopenharmony_ci#       from this software without specific prior written permission.
161cb0ef41Sopenharmony_ci#
171cb0ef41Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181cb0ef41Sopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191cb0ef41Sopenharmony_ci# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201cb0ef41Sopenharmony_ci# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211cb0ef41Sopenharmony_ci# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221cb0ef41Sopenharmony_ci# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231cb0ef41Sopenharmony_ci# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241cb0ef41Sopenharmony_ci# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251cb0ef41Sopenharmony_ci# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261cb0ef41Sopenharmony_ci# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
271cb0ef41Sopenharmony_ci# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciimport json
301cb0ef41Sopenharmony_ciimport os
311cb0ef41Sopenharmony_ciimport shutil
321cb0ef41Sopenharmony_ciimport tempfile
331cb0ef41Sopenharmony_ciimport traceback
341cb0ef41Sopenharmony_ciimport unittest
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ciimport auto_push
371cb0ef41Sopenharmony_cifrom auto_push import LastReleaseBailout
381cb0ef41Sopenharmony_ciimport auto_roll
391cb0ef41Sopenharmony_ciimport common_includes
401cb0ef41Sopenharmony_cifrom common_includes import *
411cb0ef41Sopenharmony_ciimport create_release
421cb0ef41Sopenharmony_cifrom create_release import *
431cb0ef41Sopenharmony_ciimport merge_to_branch
441cb0ef41Sopenharmony_cifrom merge_to_branch import MergeToBranch
451cb0ef41Sopenharmony_ciimport roll_merge
461cb0ef41Sopenharmony_cifrom roll_merge import RollMerge
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciTEST_CONFIG = {
491cb0ef41Sopenharmony_ci  "DEFAULT_CWD": None,
501cb0ef41Sopenharmony_ci  "BRANCHNAME": "test-prepare-push",
511cb0ef41Sopenharmony_ci  "PERSISTFILE_BASENAME": "/tmp/test-create-releases-tempfile",
521cb0ef41Sopenharmony_ci  "PATCH_FILE": "/tmp/test-v8-create-releases-tempfile-tempfile-patch",
531cb0ef41Sopenharmony_ci  "COMMITMSG_FILE": "/tmp/test-v8-create-releases-tempfile-commitmsg",
541cb0ef41Sopenharmony_ci  "CHROMIUM": "/tmp/test-create-releases-tempfile-chromium",
551cb0ef41Sopenharmony_ci  "SETTINGS_LOCATION": None,
561cb0ef41Sopenharmony_ci  "ALREADY_MERGING_SENTINEL_FILE":
571cb0ef41Sopenharmony_ci      "/tmp/test-merge-to-branch-tempfile-already-merging",
581cb0ef41Sopenharmony_ci  "TEMPORARY_PATCH_FILE": "/tmp/test-merge-to-branch-tempfile-temporary-patch",
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ciAUTO_PUSH_ARGS = [
631cb0ef41Sopenharmony_ci  "-a", "author@chromium.org",
641cb0ef41Sopenharmony_ci  "-r", "reviewer@chromium.org",
651cb0ef41Sopenharmony_ci]
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ciclass ToplevelTest(unittest.TestCase):
691cb0ef41Sopenharmony_ci  def testSaniniziteVersionTags(self):
701cb0ef41Sopenharmony_ci    self.assertEquals("4.8.230", SanitizeVersionTag("4.8.230"))
711cb0ef41Sopenharmony_ci    self.assertEquals("4.8.230", SanitizeVersionTag("tags/4.8.230"))
721cb0ef41Sopenharmony_ci    self.assertEquals(None, SanitizeVersionTag("candidate"))
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  def testNormalizeVersionTags(self):
751cb0ef41Sopenharmony_ci    input = ["4.8.230",
761cb0ef41Sopenharmony_ci              "tags/4.8.230",
771cb0ef41Sopenharmony_ci              "tags/4.8.224.1",
781cb0ef41Sopenharmony_ci              "4.8.224.1",
791cb0ef41Sopenharmony_ci              "4.8.223.1",
801cb0ef41Sopenharmony_ci              "tags/4.8.223",
811cb0ef41Sopenharmony_ci              "tags/4.8.231",
821cb0ef41Sopenharmony_ci              "candidates"]
831cb0ef41Sopenharmony_ci    expected = ["4.8.230",
841cb0ef41Sopenharmony_ci                "4.8.230",
851cb0ef41Sopenharmony_ci                "4.8.224.1",
861cb0ef41Sopenharmony_ci                "4.8.224.1",
871cb0ef41Sopenharmony_ci                "4.8.223.1",
881cb0ef41Sopenharmony_ci                "4.8.223",
891cb0ef41Sopenharmony_ci                "4.8.231",
901cb0ef41Sopenharmony_ci                ]
911cb0ef41Sopenharmony_ci    self.assertEquals(expected, NormalizeVersionTags(input))
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  def testCommand(self):
941cb0ef41Sopenharmony_ci    """Ensure json can decode the output of commands."""
951cb0ef41Sopenharmony_ci    json.dumps(Command('ls', pipe=True))
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_cidef Cmd(*args, **kwargs):
991cb0ef41Sopenharmony_ci  """Convenience function returning a shell command test expectation."""
1001cb0ef41Sopenharmony_ci  return {
1011cb0ef41Sopenharmony_ci    "name": "command",
1021cb0ef41Sopenharmony_ci    "args": args,
1031cb0ef41Sopenharmony_ci    "ret": args[-1],
1041cb0ef41Sopenharmony_ci    "cb": kwargs.get("cb"),
1051cb0ef41Sopenharmony_ci    "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]),
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_cidef RL(text, cb=None):
1101cb0ef41Sopenharmony_ci  """Convenience function returning a readline test expectation."""
1111cb0ef41Sopenharmony_ci  return {
1121cb0ef41Sopenharmony_ci    "name": "readline",
1131cb0ef41Sopenharmony_ci    "args": [],
1141cb0ef41Sopenharmony_ci    "ret": text,
1151cb0ef41Sopenharmony_ci    "cb": cb,
1161cb0ef41Sopenharmony_ci    "cwd": None,
1171cb0ef41Sopenharmony_ci  }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_cidef URL(*args, **kwargs):
1211cb0ef41Sopenharmony_ci  """Convenience function returning a readurl test expectation."""
1221cb0ef41Sopenharmony_ci  return {
1231cb0ef41Sopenharmony_ci    "name": "readurl",
1241cb0ef41Sopenharmony_ci    "args": args[:-1],
1251cb0ef41Sopenharmony_ci    "ret": args[-1],
1261cb0ef41Sopenharmony_ci    "cb": kwargs.get("cb"),
1271cb0ef41Sopenharmony_ci    "cwd": None,
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciclass SimpleMock(object):
1321cb0ef41Sopenharmony_ci  def __init__(self):
1331cb0ef41Sopenharmony_ci    self._recipe = []
1341cb0ef41Sopenharmony_ci    self._index = -1
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  def Expect(self, recipe):
1371cb0ef41Sopenharmony_ci    self._recipe = recipe
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  def Call(self, name, *args, **kwargs):  # pragma: no cover
1401cb0ef41Sopenharmony_ci    self._index += 1
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci    try:
1431cb0ef41Sopenharmony_ci      expected_call = self._recipe[self._index]
1441cb0ef41Sopenharmony_ci    except IndexError:
1451cb0ef41Sopenharmony_ci      raise NoRetryException("Calling %s %s" % (name, " ".join(args)))
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci    if not isinstance(expected_call, dict):
1481cb0ef41Sopenharmony_ci      raise NoRetryException("Found wrong expectation type for %s %s" %
1491cb0ef41Sopenharmony_ci                             (name, " ".join(args)))
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci    if expected_call["name"] != name:
1521cb0ef41Sopenharmony_ci      raise NoRetryException("Expected action: %s %s - Actual: %s" %
1531cb0ef41Sopenharmony_ci          (expected_call["name"], expected_call["args"], name))
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci    # Check if the given working directory matches the expected one.
1561cb0ef41Sopenharmony_ci    if expected_call["cwd"] != kwargs.get("cwd"):
1571cb0ef41Sopenharmony_ci      raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" %
1581cb0ef41Sopenharmony_ci          (expected_call["cwd"],
1591cb0ef41Sopenharmony_ci           expected_call["name"],
1601cb0ef41Sopenharmony_ci           expected_call["args"],
1611cb0ef41Sopenharmony_ci           kwargs.get("cwd")))
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci    # The number of arguments in the expectation must match the actual
1641cb0ef41Sopenharmony_ci    # arguments.
1651cb0ef41Sopenharmony_ci    if len(args) > len(expected_call['args']):
1661cb0ef41Sopenharmony_ci      raise NoRetryException("When calling %s with arguments, the "
1671cb0ef41Sopenharmony_ci          "expectations must consist of at least as many arguments." %
1681cb0ef41Sopenharmony_ci          name)
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci    # Compare expected and actual arguments.
1711cb0ef41Sopenharmony_ci    for (expected_arg, actual_arg) in zip(expected_call['args'], args):
1721cb0ef41Sopenharmony_ci      if expected_arg != actual_arg:
1731cb0ef41Sopenharmony_ci        raise NoRetryException("Expected: %s - Actual: %s" %
1741cb0ef41Sopenharmony_ci                               (expected_arg, actual_arg))
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci    # The expected call contains an optional callback for checking the context
1771cb0ef41Sopenharmony_ci    # at the time of the call.
1781cb0ef41Sopenharmony_ci    if expected_call['cb']:
1791cb0ef41Sopenharmony_ci      try:
1801cb0ef41Sopenharmony_ci        expected_call['cb']()
1811cb0ef41Sopenharmony_ci      except:
1821cb0ef41Sopenharmony_ci        tb = traceback.format_exc()
1831cb0ef41Sopenharmony_ci        raise NoRetryException("Caught exception from callback: %s" % tb)
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci    # If the return value is an exception, raise it instead of returning.
1861cb0ef41Sopenharmony_ci    if isinstance(expected_call['ret'], Exception):
1871cb0ef41Sopenharmony_ci      raise expected_call['ret']
1881cb0ef41Sopenharmony_ci    return expected_call['ret']
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  def AssertFinished(self):  # pragma: no cover
1911cb0ef41Sopenharmony_ci    if self._index < len(self._recipe) -1:
1921cb0ef41Sopenharmony_ci      raise NoRetryException("Called mock too seldom: %d vs. %d" %
1931cb0ef41Sopenharmony_ci                             (self._index, len(self._recipe)))
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ciclass ScriptTest(unittest.TestCase):
1971cb0ef41Sopenharmony_ci  def MakeEmptyTempFile(self):
1981cb0ef41Sopenharmony_ci    handle, name = tempfile.mkstemp()
1991cb0ef41Sopenharmony_ci    os.close(handle)
2001cb0ef41Sopenharmony_ci    self._tmp_files.append(name)
2011cb0ef41Sopenharmony_ci    return name
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  def MakeEmptyTempDirectory(self):
2041cb0ef41Sopenharmony_ci    name = tempfile.mkdtemp()
2051cb0ef41Sopenharmony_ci    self._tmp_files.append(name)
2061cb0ef41Sopenharmony_ci    return name
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci  def WriteFakeVersionFile(self, major=3, minor=22, build=4, patch=0):
2101cb0ef41Sopenharmony_ci    version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)
2111cb0ef41Sopenharmony_ci    if not os.path.exists(os.path.dirname(version_file)):
2121cb0ef41Sopenharmony_ci      os.makedirs(os.path.dirname(version_file))
2131cb0ef41Sopenharmony_ci    with open(version_file, "w") as f:
2141cb0ef41Sopenharmony_ci      f.write("  // Some line...\n")
2151cb0ef41Sopenharmony_ci      f.write("\n")
2161cb0ef41Sopenharmony_ci      f.write("#define V8_MAJOR_VERSION    %s\n" % major)
2171cb0ef41Sopenharmony_ci      f.write("#define V8_MINOR_VERSION    %s\n" % minor)
2181cb0ef41Sopenharmony_ci      f.write("#define V8_BUILD_NUMBER     %s\n" % build)
2191cb0ef41Sopenharmony_ci      f.write("#define V8_PATCH_LEVEL      %s\n" % patch)
2201cb0ef41Sopenharmony_ci      f.write("  // Some line...\n")
2211cb0ef41Sopenharmony_ci      f.write("#define V8_IS_CANDIDATE_VERSION 0\n")
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  def WriteFakeWatchlistsFile(self):
2241cb0ef41Sopenharmony_ci    watchlists_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], WATCHLISTS_FILE)
2251cb0ef41Sopenharmony_ci    if not os.path.exists(os.path.dirname(watchlists_file)):
2261cb0ef41Sopenharmony_ci      os.makedirs(os.path.dirname(watchlists_file))
2271cb0ef41Sopenharmony_ci    with open(watchlists_file, "w") as f:
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci      content = """
2301cb0ef41Sopenharmony_ci    'merges': [
2311cb0ef41Sopenharmony_ci      # Only enabled on branches created with tools/release/create_release.py
2321cb0ef41Sopenharmony_ci      # 'v8-merges@googlegroups.com',
2331cb0ef41Sopenharmony_ci    ],
2341cb0ef41Sopenharmony_ci"""
2351cb0ef41Sopenharmony_ci      f.write(content)
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci  def MakeStep(self):
2381cb0ef41Sopenharmony_ci    """Convenience wrapper."""
2391cb0ef41Sopenharmony_ci    options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([])
2401cb0ef41Sopenharmony_ci    return MakeStep(step_class=Step, state=self._state,
2411cb0ef41Sopenharmony_ci                    config=TEST_CONFIG, side_effect_handler=self,
2421cb0ef41Sopenharmony_ci                    options=options)
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci  def RunStep(self, script=CreateRelease, step_class=Step, args=None):
2451cb0ef41Sopenharmony_ci    """Convenience wrapper."""
2461cb0ef41Sopenharmony_ci    args = args if args is not None else ["-m", "-a=author", "-r=reviewer", ]
2471cb0ef41Sopenharmony_ci    return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci  def Call(self, fun, *args, **kwargs):
2501cb0ef41Sopenharmony_ci    print("Calling %s with %s and %s" % (str(fun), str(args), str(kwargs)))
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
2531cb0ef41Sopenharmony_ci    print("%s %s" % (cmd, args))
2541cb0ef41Sopenharmony_ci    print("in %s" % cwd)
2551cb0ef41Sopenharmony_ci    return self._mock.Call("command", cmd + " " + args, cwd=cwd)
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci  def ReadLine(self):
2581cb0ef41Sopenharmony_ci    return self._mock.Call("readline")
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci  def ReadURL(self, url, params):
2611cb0ef41Sopenharmony_ci    if params is not None:
2621cb0ef41Sopenharmony_ci      return self._mock.Call("readurl", url, params)
2631cb0ef41Sopenharmony_ci    else:
2641cb0ef41Sopenharmony_ci      return self._mock.Call("readurl", url)
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ci  def Sleep(self, seconds):
2671cb0ef41Sopenharmony_ci    pass
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci  def GetUTCStamp(self):
2701cb0ef41Sopenharmony_ci    return "1000000"
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci  def Expect(self, *args):
2731cb0ef41Sopenharmony_ci    """Convenience wrapper."""
2741cb0ef41Sopenharmony_ci    self._mock.Expect(*args)
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  def setUp(self):
2771cb0ef41Sopenharmony_ci    self._mock = SimpleMock()
2781cb0ef41Sopenharmony_ci    self._tmp_files = []
2791cb0ef41Sopenharmony_ci    self._state = {}
2801cb0ef41Sopenharmony_ci    TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory()
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_ci  def tearDown(self):
2831cb0ef41Sopenharmony_ci    if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]):
2841cb0ef41Sopenharmony_ci      shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"])
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci    # Clean up temps. Doesn't work automatically.
2871cb0ef41Sopenharmony_ci    for name in self._tmp_files:
2881cb0ef41Sopenharmony_ci      if os.path.isfile(name):
2891cb0ef41Sopenharmony_ci        os.remove(name)
2901cb0ef41Sopenharmony_ci      if os.path.isdir(name):
2911cb0ef41Sopenharmony_ci        shutil.rmtree(name)
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci    self._mock.AssertFinished()
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  def testGitMock(self):
2961cb0ef41Sopenharmony_ci    self.Expect([Cmd("git --version", "git version 1.2.3"),
2971cb0ef41Sopenharmony_ci                 Cmd("git dummy", "")])
2981cb0ef41Sopenharmony_ci    self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version"))
2991cb0ef41Sopenharmony_ci    self.assertEquals("", self.MakeStep().Git("dummy"))
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci  def testCommonPrepareDefault(self):
3021cb0ef41Sopenharmony_ci    self.Expect([
3031cb0ef41Sopenharmony_ci      Cmd("git status -s -uno", ""),
3041cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
3051cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3061cb0ef41Sopenharmony_ci      Cmd("git branch", "  branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
3071cb0ef41Sopenharmony_ci      RL("Y"),
3081cb0ef41Sopenharmony_ci      Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
3091cb0ef41Sopenharmony_ci    ])
3101cb0ef41Sopenharmony_ci    self.MakeStep().CommonPrepare()
3111cb0ef41Sopenharmony_ci    self.MakeStep().PrepareBranch()
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  def testCommonPrepareNoConfirm(self):
3141cb0ef41Sopenharmony_ci    self.Expect([
3151cb0ef41Sopenharmony_ci      Cmd("git status -s -uno", ""),
3161cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
3171cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3181cb0ef41Sopenharmony_ci      Cmd("git branch", "  branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
3191cb0ef41Sopenharmony_ci      RL("n"),
3201cb0ef41Sopenharmony_ci    ])
3211cb0ef41Sopenharmony_ci    self.MakeStep().CommonPrepare()
3221cb0ef41Sopenharmony_ci    self.assertRaises(Exception, self.MakeStep().PrepareBranch)
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  def testCommonPrepareDeleteBranchFailure(self):
3251cb0ef41Sopenharmony_ci    self.Expect([
3261cb0ef41Sopenharmony_ci      Cmd("git status -s -uno", ""),
3271cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
3281cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3291cb0ef41Sopenharmony_ci      Cmd("git branch", "  branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
3301cb0ef41Sopenharmony_ci      RL("Y"),
3311cb0ef41Sopenharmony_ci      Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None),
3321cb0ef41Sopenharmony_ci    ])
3331cb0ef41Sopenharmony_ci    self.MakeStep().CommonPrepare()
3341cb0ef41Sopenharmony_ci    self.assertRaises(Exception, self.MakeStep().PrepareBranch)
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci  def testInitialEnvironmentChecks(self):
3371cb0ef41Sopenharmony_ci    TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
3381cb0ef41Sopenharmony_ci    os.environ["EDITOR"] = "vi"
3391cb0ef41Sopenharmony_ci    self.Expect([
3401cb0ef41Sopenharmony_ci      Cmd("which vi", "/usr/bin/vi"),
3411cb0ef41Sopenharmony_ci    ])
3421cb0ef41Sopenharmony_ci    self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"])
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  def testTagTimeout(self):
3451cb0ef41Sopenharmony_ci    self.Expect([
3461cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3471cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
3481cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3491cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
3501cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3511cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
3521cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
3531cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
3541cb0ef41Sopenharmony_ci    ])
3551cb0ef41Sopenharmony_ci    args = ["--branch", "candidates", "ab12345"]
3561cb0ef41Sopenharmony_ci    self._state["version"] = "tag_name"
3571cb0ef41Sopenharmony_ci    self._state["commit_title"] = "Title"
3581cb0ef41Sopenharmony_ci    self.assertRaises(Exception,
3591cb0ef41Sopenharmony_ci        lambda: self.RunStep(RollMerge, TagRevision, args))
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_ci  def testReadAndPersistVersion(self):
3621cb0ef41Sopenharmony_ci    self.WriteFakeVersionFile(build=5)
3631cb0ef41Sopenharmony_ci    step = self.MakeStep()
3641cb0ef41Sopenharmony_ci    step.ReadAndPersistVersion()
3651cb0ef41Sopenharmony_ci    self.assertEquals("3", step["major"])
3661cb0ef41Sopenharmony_ci    self.assertEquals("22", step["minor"])
3671cb0ef41Sopenharmony_ci    self.assertEquals("5", step["build"])
3681cb0ef41Sopenharmony_ci    self.assertEquals("0", step["patch"])
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci  def testRegex(self):
3711cb0ef41Sopenharmony_ci    self.assertEqual("(issue 321)",
3721cb0ef41Sopenharmony_ci                     re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321"))
3731cb0ef41Sopenharmony_ci    self.assertEqual("(Chromium issue 321)",
3741cb0ef41Sopenharmony_ci                     re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321"))
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci    cl = "  too little\n\ttab\ttab\n         too much\n        trailing  "
3771cb0ef41Sopenharmony_ci    cl = MSub(r"\t", r"        ", cl)
3781cb0ef41Sopenharmony_ci    cl = MSub(r"^ {1,7}([^ ])", r"        \1", cl)
3791cb0ef41Sopenharmony_ci    cl = MSub(r"^ {9,80}([^ ])", r"        \1", cl)
3801cb0ef41Sopenharmony_ci    cl = MSub(r" +$", r"", cl)
3811cb0ef41Sopenharmony_ci    self.assertEqual("        too little\n"
3821cb0ef41Sopenharmony_ci                     "        tab        tab\n"
3831cb0ef41Sopenharmony_ci                     "        too much\n"
3841cb0ef41Sopenharmony_ci                     "        trailing", cl)
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci    self.assertEqual("//\n#define V8_BUILD_NUMBER  3\n",
3871cb0ef41Sopenharmony_ci                     MSub(r"(?<=#define V8_BUILD_NUMBER)(?P<space>\s+)\d*$",
3881cb0ef41Sopenharmony_ci                          r"\g<space>3",
3891cb0ef41Sopenharmony_ci                          "//\n#define V8_BUILD_NUMBER  321\n"))
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  TAGS = """
3921cb0ef41Sopenharmony_ci4425.0
3931cb0ef41Sopenharmony_ci0.0.0.0
3941cb0ef41Sopenharmony_ci3.9.6
3951cb0ef41Sopenharmony_ci3.22.4
3961cb0ef41Sopenharmony_citest_tag
3971cb0ef41Sopenharmony_ci"""
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  # Version as tag: 3.22.4.0. Version on main: 3.22.6.
4001cb0ef41Sopenharmony_ci  # Make sure that the latest version is 3.22.6.0.
4011cb0ef41Sopenharmony_ci  def testIncrementVersion(self):
4021cb0ef41Sopenharmony_ci    self.Expect([
4031cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
4041cb0ef41Sopenharmony_ci      Cmd("git tag", self.TAGS),
4051cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main -- include/v8-version.h",
4061cb0ef41Sopenharmony_ci          "", cb=lambda: self.WriteFakeVersionFile(3, 22, 6)),
4071cb0ef41Sopenharmony_ci    ])
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci    self.RunStep(CreateRelease, IncrementVersion)
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci    self.assertEquals("3", self._state["new_major"])
4121cb0ef41Sopenharmony_ci    self.assertEquals("22", self._state["new_minor"])
4131cb0ef41Sopenharmony_ci    self.assertEquals("7", self._state["new_build"])
4141cb0ef41Sopenharmony_ci    self.assertEquals("0", self._state["new_patch"])
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ci  def testBootstrapper(self):
4171cb0ef41Sopenharmony_ci    work_dir = self.MakeEmptyTempDirectory()
4181cb0ef41Sopenharmony_ci    class FakeScript(ScriptsBase):
4191cb0ef41Sopenharmony_ci      def _Steps(self):
4201cb0ef41Sopenharmony_ci        return []
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ci    # Use the test configuration without the fake testing default work dir.
4231cb0ef41Sopenharmony_ci    fake_config = dict(TEST_CONFIG)
4241cb0ef41Sopenharmony_ci    del(fake_config["DEFAULT_CWD"])
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci    self.Expect([
4271cb0ef41Sopenharmony_ci      Cmd("fetch v8", "", cwd=work_dir),
4281cb0ef41Sopenharmony_ci    ])
4291cb0ef41Sopenharmony_ci    FakeScript(fake_config, self).Run(["--work-dir", work_dir])
4301cb0ef41Sopenharmony_ci
4311cb0ef41Sopenharmony_ci  def testCreateRelease(self):
4321cb0ef41Sopenharmony_ci    TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci    # The version file on main has build level 5.
4351cb0ef41Sopenharmony_ci    self.WriteFakeVersionFile(build=5)
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_ci    commit_msg = """Version 3.22.5"""
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci    def CheckVersionCommit():
4401cb0ef41Sopenharmony_ci      commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
4411cb0ef41Sopenharmony_ci      self.assertEquals(commit_msg, commit)
4421cb0ef41Sopenharmony_ci      version = FileToText(
4431cb0ef41Sopenharmony_ci          os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
4441cb0ef41Sopenharmony_ci      self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version))
4451cb0ef41Sopenharmony_ci      self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version))
4461cb0ef41Sopenharmony_ci      self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version))
4471cb0ef41Sopenharmony_ci      self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version))
4481cb0ef41Sopenharmony_ci      self.assertTrue(
4491cb0ef41Sopenharmony_ci          re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci    expectations = [
4521cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/heads/*:refs/heads/*", ""),
4531cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", "", cb=self.WriteFakeWatchlistsFile),
4541cb0ef41Sopenharmony_ci      Cmd("git branch", ""),
4551cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
4561cb0ef41Sopenharmony_ci      Cmd("git tag", self.TAGS),
4571cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main -- include/v8-version.h",
4581cb0ef41Sopenharmony_ci          "", cb=self.WriteFakeVersionFile),
4591cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
4601cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s release_hash", "Version 3.22.4\n"),
4611cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H release_hash^", "abc3\n"),
4621cb0ef41Sopenharmony_ci      Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
4631cb0ef41Sopenharmony_ci      Cmd("git push origin push_hash:refs/heads/3.22.5", ""),
4641cb0ef41Sopenharmony_ci      Cmd("git reset --hard origin/main", ""),
4651cb0ef41Sopenharmony_ci      Cmd("git new-branch work-branch --upstream origin/3.22.5", ""),
4661cb0ef41Sopenharmony_ci      Cmd("git checkout -f 3.22.4 -- include/v8-version.h", "",
4671cb0ef41Sopenharmony_ci          cb=self.WriteFakeVersionFile),
4681cb0ef41Sopenharmony_ci      Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
4691cb0ef41Sopenharmony_ci          cb=CheckVersionCommit),
4701cb0ef41Sopenharmony_ci      Cmd("git cl upload --send-mail "
4711cb0ef41Sopenharmony_ci          "-f --set-bot-commit --bypass-hooks --no-autocc --message-file "
4721cb0ef41Sopenharmony_ci          "\"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
4731cb0ef41Sopenharmony_ci      Cmd("git cl land --bypass-hooks -f", ""),
4741cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
4751cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep="
4761cb0ef41Sopenharmony_ci          "\"Version 3.22.5\" origin/3.22.5", "hsh_to_tag"),
4771cb0ef41Sopenharmony_ci      Cmd("git tag 3.22.5 hsh_to_tag", ""),
4781cb0ef41Sopenharmony_ci      Cmd("git push origin refs/tags/3.22.5:refs/tags/3.22.5", ""),
4791cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
4801cb0ef41Sopenharmony_ci      Cmd("git branch", "* main\n  work-branch\n"),
4811cb0ef41Sopenharmony_ci      Cmd("git branch -D work-branch", ""),
4821cb0ef41Sopenharmony_ci      Cmd("git gc", ""),
4831cb0ef41Sopenharmony_ci    ]
4841cb0ef41Sopenharmony_ci    self.Expect(expectations)
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci    args = ["-a", "author@chromium.org",
4871cb0ef41Sopenharmony_ci            "-r", "reviewer@chromium.org",
4881cb0ef41Sopenharmony_ci            "--revision", "push_hash"]
4891cb0ef41Sopenharmony_ci    CreateRelease(TEST_CONFIG, self).Run(args)
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci    # Note: The version file is on build number 5 again in the end of this test
4921cb0ef41Sopenharmony_ci    # since the git command that merges to main is mocked out.
4931cb0ef41Sopenharmony_ci
4941cb0ef41Sopenharmony_ci    # Check for correct content of the WATCHLISTS file
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_ci    watchlists_content = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"],
4971cb0ef41Sopenharmony_ci                                          WATCHLISTS_FILE))
4981cb0ef41Sopenharmony_ci    expected_watchlists_content = """
4991cb0ef41Sopenharmony_ci    'merges': [
5001cb0ef41Sopenharmony_ci      # Only enabled on branches created with tools/release/create_release.py
5011cb0ef41Sopenharmony_ci      'v8-merges@googlegroups.com',
5021cb0ef41Sopenharmony_ci    ],
5031cb0ef41Sopenharmony_ci"""
5041cb0ef41Sopenharmony_ci    self.assertEqual(watchlists_content, expected_watchlists_content)
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci  C_V8_22624_LOG = """V8 CL.
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_cigit-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci"""
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci  C_V8_123455_LOG = """V8 CL.
5131cb0ef41Sopenharmony_ci
5141cb0ef41Sopenharmony_cigit-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci"""
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci  C_V8_123456_LOG = """V8 CL.
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_cigit-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci"""
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci  ROLL_COMMIT_MSG = """Update V8 to version 3.22.4.
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ciSummary of changes available at:
5271cb0ef41Sopenharmony_cihttps://chromium.googlesource.com/v8/v8/+log/last_rol..roll_hsh
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ciPlease follow these instructions for assigning/CC'ing issues:
5301cb0ef41Sopenharmony_cihttps://v8.dev/docs/triage-issues
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_ciPlease close rolling in case of a roll revert:
5331cb0ef41Sopenharmony_cihttps://v8-roll.appspot.com/
5341cb0ef41Sopenharmony_ciThis only works with a Google account.
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ciCQ_INCLUDE_TRYBOTS=luci.chromium.try:linux-blink-rel
5371cb0ef41Sopenharmony_ciCQ_INCLUDE_TRYBOTS=luci.chromium.try:linux_optional_gpu_tests_rel
5381cb0ef41Sopenharmony_ciCQ_INCLUDE_TRYBOTS=luci.chromium.try:mac_optional_gpu_tests_rel
5391cb0ef41Sopenharmony_ciCQ_INCLUDE_TRYBOTS=luci.chromium.try:win_optional_gpu_tests_rel
5401cb0ef41Sopenharmony_ciCQ_INCLUDE_TRYBOTS=luci.chromium.try:android_optional_gpu_tests_rel
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ciR=reviewer@chromium.org"""
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_ci  # Snippet from the original DEPS file.
5451cb0ef41Sopenharmony_ci  FAKE_DEPS = """
5461cb0ef41Sopenharmony_civars = {
5471cb0ef41Sopenharmony_ci  "v8_revision": "last_roll_hsh",
5481cb0ef41Sopenharmony_ci}
5491cb0ef41Sopenharmony_cideps = {
5501cb0ef41Sopenharmony_ci  "src/v8":
5511cb0ef41Sopenharmony_ci    (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
5521cb0ef41Sopenharmony_ci    Var("v8_revision"),
5531cb0ef41Sopenharmony_ci}
5541cb0ef41Sopenharmony_ci"""
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci  def testChromiumRollUpToDate(self):
5571cb0ef41Sopenharmony_ci    TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
5581cb0ef41Sopenharmony_ci    json_output_file = os.path.join(TEST_CONFIG["CHROMIUM"], "out.json")
5591cb0ef41Sopenharmony_ci    TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
5601cb0ef41Sopenharmony_ci    chrome_dir = TEST_CONFIG["CHROMIUM"]
5611cb0ef41Sopenharmony_ci    self.Expect([
5621cb0ef41Sopenharmony_ci      Cmd("git fetch origin", ""),
5631cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
5641cb0ef41Sopenharmony_ci      Cmd("gclient getdep -r src/v8", "last_roll_hsh", cwd=chrome_dir),
5651cb0ef41Sopenharmony_ci      Cmd("git describe --tags last_roll_hsh", "3.22.4"),
5661cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
5671cb0ef41Sopenharmony_ci      Cmd("git rev-list --max-age=395200 --tags",
5681cb0ef41Sopenharmony_ci          "bad_tag\nroll_hsh\nhash_123"),
5691cb0ef41Sopenharmony_ci      Cmd("git describe --tags bad_tag", ""),
5701cb0ef41Sopenharmony_ci      Cmd("git describe --tags roll_hsh", "3.22.4"),
5711cb0ef41Sopenharmony_ci      Cmd("git describe --tags hash_123", "3.22.3"),
5721cb0ef41Sopenharmony_ci      Cmd("git describe --tags roll_hsh", "3.22.4"),
5731cb0ef41Sopenharmony_ci      Cmd("git describe --tags hash_123", "3.22.3"),
5741cb0ef41Sopenharmony_ci    ])
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci    result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
5771cb0ef41Sopenharmony_ci        AUTO_PUSH_ARGS + [
5781cb0ef41Sopenharmony_ci          "-c", TEST_CONFIG["CHROMIUM"],
5791cb0ef41Sopenharmony_ci          "--json-output", json_output_file])
5801cb0ef41Sopenharmony_ci    self.assertEquals(0, result)
5811cb0ef41Sopenharmony_ci    json_output = json.loads(FileToText(json_output_file))
5821cb0ef41Sopenharmony_ci    self.assertEquals("up_to_date", json_output["monitoring_state"])
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ci  def testChromiumRoll(self):
5861cb0ef41Sopenharmony_ci    # Setup fake directory structures.
5871cb0ef41Sopenharmony_ci    TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
5881cb0ef41Sopenharmony_ci    json_output_file = os.path.join(TEST_CONFIG["CHROMIUM"], "out.json")
5891cb0ef41Sopenharmony_ci    TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
5901cb0ef41Sopenharmony_ci    TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git"))
5911cb0ef41Sopenharmony_ci    chrome_dir = TEST_CONFIG["CHROMIUM"]
5921cb0ef41Sopenharmony_ci    os.makedirs(os.path.join(chrome_dir, "v8"))
5931cb0ef41Sopenharmony_ci
5941cb0ef41Sopenharmony_ci    def WriteDeps():
5951cb0ef41Sopenharmony_ci      TextToFile("Some line\n   \"v8_revision\": \"22624\",\n  some line",
5961cb0ef41Sopenharmony_ci                 os.path.join(chrome_dir, "DEPS"))
5971cb0ef41Sopenharmony_ci
5981cb0ef41Sopenharmony_ci    expectations = [
5991cb0ef41Sopenharmony_ci      Cmd("git fetch origin", ""),
6001cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
6011cb0ef41Sopenharmony_ci      Cmd("gclient getdep -r src/v8", "last_roll_hsh", cwd=chrome_dir),
6021cb0ef41Sopenharmony_ci      Cmd("git describe --tags last_roll_hsh", "3.22.3.1"),
6031cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
6041cb0ef41Sopenharmony_ci      Cmd("git rev-list --max-age=395200 --tags",
6051cb0ef41Sopenharmony_ci          "bad_tag\nroll_hsh\nhash_123"),
6061cb0ef41Sopenharmony_ci      Cmd("git describe --tags bad_tag", ""),
6071cb0ef41Sopenharmony_ci      Cmd("git describe --tags roll_hsh", "3.22.4"),
6081cb0ef41Sopenharmony_ci      Cmd("git describe --tags hash_123", "3.22.3"),
6091cb0ef41Sopenharmony_ci      Cmd("git describe --tags roll_hsh", "3.22.4"),
6101cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s roll_hsh", "Version 3.22.4\n"),
6111cb0ef41Sopenharmony_ci      Cmd("git describe --tags roll_hsh", "3.22.4"),
6121cb0ef41Sopenharmony_ci      Cmd("git describe --tags last_roll_hsh", "3.22.2.1"),
6131cb0ef41Sopenharmony_ci      Cmd("git status -s -uno", "", cwd=chrome_dir),
6141cb0ef41Sopenharmony_ci      Cmd("git checkout -f main", "", cwd=chrome_dir),
6151cb0ef41Sopenharmony_ci      Cmd("git branch", "", cwd=chrome_dir),
6161cb0ef41Sopenharmony_ci      Cmd("git pull", "", cwd=chrome_dir),
6171cb0ef41Sopenharmony_ci      Cmd("git fetch origin", ""),
6181cb0ef41Sopenharmony_ci      Cmd("git new-branch work-branch", "", cwd=chrome_dir),
6191cb0ef41Sopenharmony_ci      Cmd("gclient setdep -r src/v8@roll_hsh", "", cb=WriteDeps,
6201cb0ef41Sopenharmony_ci          cwd=chrome_dir),
6211cb0ef41Sopenharmony_ci      Cmd(("git commit -am \"%s\" "
6221cb0ef41Sopenharmony_ci           "--author \"author@chromium.org <author@chromium.org>\"" %
6231cb0ef41Sopenharmony_ci           self.ROLL_COMMIT_MSG),
6241cb0ef41Sopenharmony_ci          "", cwd=chrome_dir),
6251cb0ef41Sopenharmony_ci      Cmd("git cl upload --send-mail -f "
6261cb0ef41Sopenharmony_ci          "--cq-dry-run --set-bot-commit --bypass-hooks", "",
6271cb0ef41Sopenharmony_ci          cwd=chrome_dir),
6281cb0ef41Sopenharmony_ci      Cmd("git checkout -f main", "", cwd=chrome_dir),
6291cb0ef41Sopenharmony_ci      Cmd("git branch -D work-branch", "", cwd=chrome_dir),
6301cb0ef41Sopenharmony_ci    ]
6311cb0ef41Sopenharmony_ci    self.Expect(expectations)
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci    args = ["-a", "author@chromium.org", "-c", chrome_dir,
6341cb0ef41Sopenharmony_ci            "-r", "reviewer@chromium.org", "--json-output", json_output_file]
6351cb0ef41Sopenharmony_ci    auto_roll.AutoRoll(TEST_CONFIG, self).Run(args)
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_ci    deps = FileToText(os.path.join(chrome_dir, "DEPS"))
6381cb0ef41Sopenharmony_ci    self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps))
6391cb0ef41Sopenharmony_ci
6401cb0ef41Sopenharmony_ci    json_output = json.loads(FileToText(json_output_file))
6411cb0ef41Sopenharmony_ci    self.assertEquals("success", json_output["monitoring_state"])
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_ci  def testCheckLastPushRecently(self):
6441cb0ef41Sopenharmony_ci    self.Expect([
6451cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
6461cb0ef41Sopenharmony_ci      Cmd("git tag", self.TAGS),
6471cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
6481cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s release_hash",
6491cb0ef41Sopenharmony_ci          "Version 3.22.4 (based on abc3)\n"),
6501cb0ef41Sopenharmony_ci      Cmd("git log --format=%H abc3..abc123", "\n"),
6511cb0ef41Sopenharmony_ci    ])
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci    self._state["candidate"] = "abc123"
6541cb0ef41Sopenharmony_ci    self.assertEquals(0, self.RunStep(
6551cb0ef41Sopenharmony_ci        auto_push.AutoPush, LastReleaseBailout, AUTO_PUSH_ARGS))
6561cb0ef41Sopenharmony_ci
6571cb0ef41Sopenharmony_ci  def testAutoPush(self):
6581cb0ef41Sopenharmony_ci    self.Expect([
6591cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
6601cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/heads/lkgr:refs/heads/lkgr", ""),
6611cb0ef41Sopenharmony_ci      Cmd("git show-ref -s refs/heads/lkgr", "abc123\n"),
6621cb0ef41Sopenharmony_ci      Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
6631cb0ef41Sopenharmony_ci      Cmd("git tag", self.TAGS),
6641cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
6651cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s release_hash",
6661cb0ef41Sopenharmony_ci          "Version 3.22.4 (based on abc3)\n"),
6671cb0ef41Sopenharmony_ci      Cmd("git log --format=%H abc3..abc123", "some_stuff\n"),
6681cb0ef41Sopenharmony_ci    ])
6691cb0ef41Sopenharmony_ci
6701cb0ef41Sopenharmony_ci    auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci    state = json.loads(FileToText("%s-state.json"
6731cb0ef41Sopenharmony_ci                                  % TEST_CONFIG["PERSISTFILE_BASENAME"]))
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci    self.assertEquals("abc123", state["candidate"])
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci  def testRollMerge(self):
6781cb0ef41Sopenharmony_ci    TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
6791cb0ef41Sopenharmony_ci    TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
6801cb0ef41Sopenharmony_ci    self.WriteFakeVersionFile(build=5)
6811cb0ef41Sopenharmony_ci    os.environ["EDITOR"] = "vi"
6821cb0ef41Sopenharmony_ci    extra_patch = self.MakeEmptyTempFile()
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci    def VerifyPatch(patch):
6851cb0ef41Sopenharmony_ci      return lambda: self.assertEquals(patch,
6861cb0ef41Sopenharmony_ci          FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ci    msg = """Version 3.22.5.1 (cherry-pick)
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_ciMerged ab12345
6911cb0ef41Sopenharmony_ciMerged ab23456
6921cb0ef41Sopenharmony_ciMerged ab34567
6931cb0ef41Sopenharmony_ciMerged ab45678
6941cb0ef41Sopenharmony_ciMerged ab56789
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_ciTitle4
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ciTitle2
6991cb0ef41Sopenharmony_ci
7001cb0ef41Sopenharmony_ciTitle3
7011cb0ef41Sopenharmony_ci
7021cb0ef41Sopenharmony_ciTitle1
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ciRevert "Something"
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ciBUG=123,234,345,456,567,v8:123
7071cb0ef41Sopenharmony_ci"""
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ci    def VerifyLand():
7101cb0ef41Sopenharmony_ci      commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
7111cb0ef41Sopenharmony_ci      self.assertEquals(msg, commit)
7121cb0ef41Sopenharmony_ci      version = FileToText(
7131cb0ef41Sopenharmony_ci          os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
7141cb0ef41Sopenharmony_ci      self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version))
7151cb0ef41Sopenharmony_ci      self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version))
7161cb0ef41Sopenharmony_ci      self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+1", version))
7171cb0ef41Sopenharmony_ci      self.assertTrue(
7181cb0ef41Sopenharmony_ci          re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ci    self.Expect([
7211cb0ef41Sopenharmony_ci      Cmd("git status -s -uno", ""),
7221cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
7231cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
7241cb0ef41Sopenharmony_ci      Cmd("git branch", "  branch1\n* branch2\n"),
7251cb0ef41Sopenharmony_ci      Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" %
7261cb0ef41Sopenharmony_ci          TEST_CONFIG["BRANCHNAME"], ""),
7271cb0ef41Sopenharmony_ci      Cmd(("git log --format=%H --grep=\"Port ab12345\" "
7281cb0ef41Sopenharmony_ci           "--reverse origin/main"),
7291cb0ef41Sopenharmony_ci          "ab45678\nab23456"),
7301cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab45678", "Title1"),
7311cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab23456", "Title2"),
7321cb0ef41Sopenharmony_ci      Cmd(("git log --format=%H --grep=\"Port ab23456\" "
7331cb0ef41Sopenharmony_ci           "--reverse origin/main"),
7341cb0ef41Sopenharmony_ci          ""),
7351cb0ef41Sopenharmony_ci      Cmd(("git log --format=%H --grep=\"Port ab34567\" "
7361cb0ef41Sopenharmony_ci           "--reverse origin/main"),
7371cb0ef41Sopenharmony_ci          "ab56789"),
7381cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab56789", "Title3"),
7391cb0ef41Sopenharmony_ci      RL("Y"),  # Automatically add corresponding ports (ab34567, ab56789)?
7401cb0ef41Sopenharmony_ci      # Simulate git being down which stops the script.
7411cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab12345", None),
7421cb0ef41Sopenharmony_ci      # Restart script in the failing step.
7431cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab12345", "Title4"),
7441cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab23456", "Title2"),
7451cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab34567", "Title3"),
7461cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab45678", "Title1"),
7471cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
7481cb0ef41Sopenharmony_ci      Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
7491cb0ef41Sopenharmony_ci      Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
7501cb0ef41Sopenharmony_ci      Cmd("git log -1 ab34567", "Title3\nBUG=567, 456"),
7511cb0ef41Sopenharmony_ci      Cmd("git log -1 ab45678", "Title1\nBUG="),
7521cb0ef41Sopenharmony_ci      Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
7531cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab12345", "patch4"),
7541cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
7551cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
7561cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch4")),
7571cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab23456", "patch2"),
7581cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
7591cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
7601cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch2")),
7611cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab34567", "patch3"),
7621cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
7631cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
7641cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch3")),
7651cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab45678", "patch1"),
7661cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
7671cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
7681cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch1")),
7691cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab56789", "patch5\n"),
7701cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
7711cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
7721cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch5\n")),
7731cb0ef41Sopenharmony_ci      Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
7741cb0ef41Sopenharmony_ci      RL("Y"),  # Automatically increment patch level?
7751cb0ef41Sopenharmony_ci      Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
7761cb0ef41Sopenharmony_ci      RL("reviewer@chromium.org"),  # V8 reviewer.
7771cb0ef41Sopenharmony_ci      Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
7781cb0ef41Sopenharmony_ci          "--bypass-hooks", ""),
7791cb0ef41Sopenharmony_ci      Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
7801cb0ef41Sopenharmony_ci      RL("LGTM"),  # Enter LGTM for V8 CL.
7811cb0ef41Sopenharmony_ci      Cmd("git cl presubmit", "Presubmit successfull\n"),
7821cb0ef41Sopenharmony_ci      Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
7831cb0ef41Sopenharmony_ci          cb=VerifyLand),
7841cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
7851cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep=\""
7861cb0ef41Sopenharmony_ci          "Version 3.22.5.1 (cherry-pick)"
7871cb0ef41Sopenharmony_ci          "\" refs/remotes/origin/candidates",
7881cb0ef41Sopenharmony_ci          ""),
7891cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
7901cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%H --grep=\""
7911cb0ef41Sopenharmony_ci          "Version 3.22.5.1 (cherry-pick)"
7921cb0ef41Sopenharmony_ci          "\" refs/remotes/origin/candidates",
7931cb0ef41Sopenharmony_ci          "hsh_to_tag"),
7941cb0ef41Sopenharmony_ci      Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
7951cb0ef41Sopenharmony_ci      Cmd("git push origin refs/tags/3.22.5.1:refs/tags/3.22.5.1", ""),
7961cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
7971cb0ef41Sopenharmony_ci      Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
7981cb0ef41Sopenharmony_ci    ])
7991cb0ef41Sopenharmony_ci
8001cb0ef41Sopenharmony_ci    # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
8011cb0ef41Sopenharmony_ci    # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
8021cb0ef41Sopenharmony_ci    args = ["-f", "-p", extra_patch, "--branch", "candidates",
8031cb0ef41Sopenharmony_ci            "ab12345", "ab23456", "ab34567"]
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ci    # The first run of the script stops because of git being down.
8061cb0ef41Sopenharmony_ci    self.assertRaises(GitFailedException,
8071cb0ef41Sopenharmony_ci        lambda: RollMerge(TEST_CONFIG, self).Run(args))
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci    # Test that state recovery after restarting the script works.
8101cb0ef41Sopenharmony_ci    args += ["-s", "4"]
8111cb0ef41Sopenharmony_ci    RollMerge(TEST_CONFIG, self).Run(args)
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ci  def testMergeToBranch(self):
8141cb0ef41Sopenharmony_ci    TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
8151cb0ef41Sopenharmony_ci    TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
8161cb0ef41Sopenharmony_ci    self.WriteFakeVersionFile(build=5)
8171cb0ef41Sopenharmony_ci    os.environ["EDITOR"] = "vi"
8181cb0ef41Sopenharmony_ci    extra_patch = self.MakeEmptyTempFile()
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_ci    def VerifyPatch(patch):
8221cb0ef41Sopenharmony_ci      return lambda: self.assertEquals(patch,
8231cb0ef41Sopenharmony_ci          FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci    info_msg = ("NOTE: This script will no longer automatically "
8261cb0ef41Sopenharmony_ci     "update include/v8-version.h "
8271cb0ef41Sopenharmony_ci     "and create a tag. This is done automatically by the autotag bot. "
8281cb0ef41Sopenharmony_ci     "Please call the merge_to_branch.py with --help for more information.")
8291cb0ef41Sopenharmony_ci
8301cb0ef41Sopenharmony_ci    msg = """Merged: Squashed multiple commits.
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ciMerged: Title4
8331cb0ef41Sopenharmony_ciRevision: ab12345
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ciMerged: Title2
8361cb0ef41Sopenharmony_ciRevision: ab23456
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ciMerged: Title3
8391cb0ef41Sopenharmony_ciRevision: ab34567
8401cb0ef41Sopenharmony_ci
8411cb0ef41Sopenharmony_ciMerged: Title1
8421cb0ef41Sopenharmony_ciRevision: ab45678
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ciMerged: Revert \"Something\"
8451cb0ef41Sopenharmony_ciRevision: ab56789
8461cb0ef41Sopenharmony_ci
8471cb0ef41Sopenharmony_ciBUG=123,234,345,456,567,v8:123
8481cb0ef41Sopenharmony_ciNOTRY=true
8491cb0ef41Sopenharmony_ciNOPRESUBMIT=true
8501cb0ef41Sopenharmony_ciNOTREECHECKS=true
8511cb0ef41Sopenharmony_ci"""
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci    def VerifyLand():
8541cb0ef41Sopenharmony_ci      commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
8551cb0ef41Sopenharmony_ci      self.assertEquals(msg, commit)
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci    self.Expect([
8581cb0ef41Sopenharmony_ci      Cmd("git status -s -uno", ""),
8591cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
8601cb0ef41Sopenharmony_ci      Cmd("git fetch", ""),
8611cb0ef41Sopenharmony_ci      Cmd("git branch", "  branch1\n* branch2\n"),
8621cb0ef41Sopenharmony_ci      Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" %
8631cb0ef41Sopenharmony_ci          TEST_CONFIG["BRANCHNAME"], ""),
8641cb0ef41Sopenharmony_ci      Cmd(("git log --format=%H --grep=\"^[Pp]ort ab12345\" "
8651cb0ef41Sopenharmony_ci           "--reverse origin/main"),
8661cb0ef41Sopenharmony_ci          "ab45678\nab23456"),
8671cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab45678", "Title1"),
8681cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab23456", "Title2"),
8691cb0ef41Sopenharmony_ci      Cmd(("git log --format=%H --grep=\"^[Pp]ort ab23456\" "
8701cb0ef41Sopenharmony_ci           "--reverse origin/main"),
8711cb0ef41Sopenharmony_ci          ""),
8721cb0ef41Sopenharmony_ci      Cmd(("git log --format=%H --grep=\"^[Pp]ort ab34567\" "
8731cb0ef41Sopenharmony_ci           "--reverse origin/main"),
8741cb0ef41Sopenharmony_ci          "ab56789"),
8751cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab56789", "Title3"),
8761cb0ef41Sopenharmony_ci      RL("Y"),  # Automatically add corresponding ports (ab34567, ab56789)?
8771cb0ef41Sopenharmony_ci      # Simulate git being down which stops the script.
8781cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab12345", None),
8791cb0ef41Sopenharmony_ci      # Restart script in the failing step.
8801cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab12345", "Title4"),
8811cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab23456", "Title2"),
8821cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab34567", "Title3"),
8831cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab45678", "Title1"),
8841cb0ef41Sopenharmony_ci      Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
8851cb0ef41Sopenharmony_ci      Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
8861cb0ef41Sopenharmony_ci      Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
8871cb0ef41Sopenharmony_ci      Cmd("git log -1 ab34567", "Title3\nBug: 567, 456,345"),
8881cb0ef41Sopenharmony_ci      Cmd("git log -1 ab45678", "Title1\nBug:"),
8891cb0ef41Sopenharmony_ci      Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
8901cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab12345", "patch4"),
8911cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
8921cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
8931cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch4")),
8941cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab23456", "patch2"),
8951cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
8961cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
8971cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch2")),
8981cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab34567", "patch3"),
8991cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
9001cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
9011cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch3")),
9021cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab45678", "patch1"),
9031cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
9041cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
9051cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch1")),
9061cb0ef41Sopenharmony_ci      Cmd("git log -1 -p ab56789", "patch5\n"),
9071cb0ef41Sopenharmony_ci      Cmd(("git apply --index --reject \"%s\"" %
9081cb0ef41Sopenharmony_ci           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
9091cb0ef41Sopenharmony_ci          "", cb=VerifyPatch("patch5\n")),
9101cb0ef41Sopenharmony_ci      Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
9111cb0ef41Sopenharmony_ci      Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
9121cb0ef41Sopenharmony_ci      RL("reviewer@chromium.org"),  # V8 reviewer.
9131cb0ef41Sopenharmony_ci      Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
9141cb0ef41Sopenharmony_ci          "--bypass-hooks", ""),
9151cb0ef41Sopenharmony_ci      Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
9161cb0ef41Sopenharmony_ci      RL("LGTM"),  # Enter LGTM for V8 CL.
9171cb0ef41Sopenharmony_ci      Cmd("git cl presubmit", "Presubmit successfull\n"),
9181cb0ef41Sopenharmony_ci      Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
9191cb0ef41Sopenharmony_ci          cb=VerifyLand),
9201cb0ef41Sopenharmony_ci      Cmd("git checkout -f origin/main", ""),
9211cb0ef41Sopenharmony_ci      Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
9221cb0ef41Sopenharmony_ci    ])
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ci    # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
9251cb0ef41Sopenharmony_ci    # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
9261cb0ef41Sopenharmony_ci    args = ["-f", "-p", extra_patch, "--branch", "candidates",
9271cb0ef41Sopenharmony_ci            "ab12345", "ab23456", "ab34567"]
9281cb0ef41Sopenharmony_ci
9291cb0ef41Sopenharmony_ci    # The first run of the script stops because of git being down.
9301cb0ef41Sopenharmony_ci    self.assertRaises(GitFailedException,
9311cb0ef41Sopenharmony_ci        lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_ci    # Test that state recovery after restarting the script works.
9341cb0ef41Sopenharmony_ci    args += ["-s", "4"]
9351cb0ef41Sopenharmony_ci    MergeToBranch(TEST_CONFIG, self).Run(args)
9361cb0ef41Sopenharmony_ci
9371cb0ef41Sopenharmony_ciif __name__ == '__main__':
9381cb0ef41Sopenharmony_ci  unittest.main()
939