afdo: Allow multiple Chrome ebuild to exist when getting version

When migrating to recipes and in order to allow faster executions,
toolchain builders skips setting up chroot, which makes gentoo
commands like `equery` doesn't work. This creates the need to
implement a function to get the latest info for a package. Back
then, only one ebuild is allowed to present and otherwise will
fail. However, in release branches, there could be patch 0 ebuild
in the directory, so we need to support it.

This patch adds code to find all the ebuilds belong to a package
and find the latest version by comparing all the parts.

BUG=b:171514463
TEST=unittest added and passed

Change-Id: I581af4ebf87272a0905408f284be07adfce10a27
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2515019
Tested-by: Tiancong Wang <tcwang@google.com>
Reviewed-by: LaMont Jones <lamontjones@chromium.org>
Commit-Queue: Tiancong Wang <tcwang@google.com>
diff --git a/lib/toolchain_util.py b/lib/toolchain_util.py
index bf7d7e4..52fa796 100644
--- a/lib/toolchain_util.py
+++ b/lib/toolchain_util.py
@@ -105,10 +105,7 @@
 #
 # This must be consistent with the definitions in autotest.
 AFDO_DATA_GENERATORS_LLVM = ('chell', 'samus')
-CHROME_AFDO_VERIFIER_BOARDS = {
-    'samus': 'atom',
-    'eve': 'bigcore'
-}
+CHROME_AFDO_VERIFIER_BOARDS = {'samus': 'atom', 'eve': 'bigcore'}
 KERNEL_AFDO_VERIFIER_BOARDS = {
     'lulu': '3.14',
     'chell': '3.18',
@@ -132,6 +129,9 @@
 AFDO_ARTIFACT_EBUILD_REGEX = r'^(?P<bef>%s=)(?P<name>("[^"]*"|.*))(?P<aft>.*)'
 AFDO_ARTIFACT_EBUILD_REPL = r'\g<bef>"%s"\g<aft>'
 
+ChromeVersion = collections.namedtuple(
+    'ChromeVersion', ['major', 'minor', 'build', 'patch', 'revision'])
+
 BENCHMARK_PROFILE_NAME_REGEX = r"""
        ^chromeos-chrome-amd64-
        (\d+)\.                    # Major
@@ -1112,9 +1112,27 @@
       self._ebuild_info[constants.CHROME_PN] = info
       return info
     else:
-      raise PrepareForBuildHandlerError(
-          'Wrong number of %s/%s ebuilds found: %s' %
-          (category, package, ', '.join(paths)))
+      latest_version = ChromeVersion(0, 0, 0, 0, 0)
+      candidate = None
+      for p in paths:
+        PV = os.path.splitext(os.path.split(p)[1])[0]
+        info = _EbuildInfo(p, package_info.SplitCPV('%s/%s' % (category, PV)))
+        if not info.CPV.rev:
+          # Ignore versions without a rev
+          continue
+        version_re = re.compile(
+            r'^chromeos-chrome-(\d+)\.(\d+)\.(\d+)\.(\d+)_rc-r(\d+)')
+        m = version_re.search(PV)
+        assert m, f'failed to recognize Chrome ebuild name {p}'
+        version = ChromeVersion(*[int(x) for x in m.groups()])
+        if version > latest_version:
+          latest_version = version
+          candidate = info
+      if not candidate:
+        raise PrepareForBuildHandlerError(
+            f'No valid Chrome ebuild found among: {paths}')
+      self._ebuild_info[constants.CHROME_PN] = candidate
+      return candidate
 
   def _GetBenchmarkAFDOName(self, template=CHROME_BENCHMARK_AFDO_FILE):
     """Get the name of the benchmark AFDO file from the Chrome ebuild."""
diff --git a/lib/toolchain_util_unittest.py b/lib/toolchain_util_unittest.py
index 2c4b496..6c63175 100644
--- a/lib/toolchain_util_unittest.py
+++ b/lib/toolchain_util_unittest.py
@@ -224,9 +224,15 @@
     self.assertEqual('78', self.obj.chrome_branch)
     self.glob.assert_called_once()
 
-    self.glob.return_value = ['1', '2']
-    self.assertRaises(toolchain_util.PrepareForBuildHandlerError,
-                      self.obj._GetEbuildInfo, 'chromeos-kernel-3_14')
+  def testGetEbuildInfoWithMultipleChromes(self):
+    self.glob.return_value = [
+        'chromeos-chrome-78.0.3893.0.ebuild',
+        'chromeos-chrome-78.0.3893.0_rc-r1.ebuild',
+        'chromeos-chrome-78.0.3893.100_rc-r1.ebuild',
+        'chromeos-chrome-78.0.3893.10_rc-r1.ebuild'
+    ]
+    ret = self.obj._GetEbuildInfo('chromeos-chrome')
+    self.assertEqual(ret.CPV.version, '78.0.3893.100_rc-r1')
 
   def test_GetArtifactVersionInGob(self):
     """Test that we look in the right place in GoB."""