Build API: Additional controller_util functionality.

Added BuildTarget parsing in controller util.
Added eq support in BuildTarget and Chroot to make testing
easier and cleaner.
Enforce BuildTarget.name and Chroot.path immutability.

BUG=None
TEST=run_tests

Change-Id: I6699a83e67940799279a6bcb8fb8a4fbb559c2b0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1739156
Tested-by: Alex Klein <saklein@chromium.org>
Reviewed-by: David Burger <dburger@chromium.org>
Commit-Queue: Alex Klein <saklein@chromium.org>
diff --git a/api/controller/controller_util_unittest.py b/api/controller/controller_util_unittest.py
index 6b9ad9b..51ea8b7 100644
--- a/api/controller/controller_util_unittest.py
+++ b/api/controller/controller_util_unittest.py
@@ -8,9 +8,84 @@
 from __future__ import print_function
 
 from chromite.api.controller import controller_util
+from chromite.api.gen.chromite.api import build_api_test_pb2
 from chromite.api.gen.chromiumos import common_pb2
 from chromite.lib import cros_test_lib
 from chromite.lib import portage_util
+from chromite.lib.build_target_util import BuildTarget
+from chromite.lib.chroot_lib import Chroot
+
+
+class ParseChrootTest(cros_test_lib.TestCase):
+  """ParseChroot tests."""
+
+  def testSuccess(self):
+    """Test successful handling case."""
+    path = '/chroot/path'
+    cache_dir = '/cache/dir'
+    chrome_root = '/chrome/root'
+    use_flags = [{'flag': 'useflag1'}, {'flag': 'useflag2'}]
+    features = [{'feature': 'feature1'}, {'feature': 'feature2'}]
+    expected_env = {'USE': 'useflag1 useflag2',
+                    'FEATURES': 'feature1 feature2'}
+
+    chroot_message = common_pb2.Chroot(path=path, cache_dir=cache_dir,
+                                       chrome_dir=chrome_root,
+                                       env={'use_flags': use_flags,
+                                            'features': features})
+
+    expected = Chroot(path=path, cache_dir=cache_dir, chrome_root=chrome_root,
+                      env=expected_env)
+    result = controller_util.ParseChroot(chroot_message)
+
+    self.assertEqual(expected, result)
+
+  def testWrongMessage(self):
+    """Test invalid message type given."""
+    with self.assertRaises(AssertionError):
+      controller_util.ParseChroot(common_pb2.BuildTarget())
+
+
+class ParseBuildTargetTest(cros_test_lib.TestCase):
+  """ParseBuildTarget tests."""
+
+  def testSuccess(self):
+    """Test successful handling case."""
+    name = 'board'
+    build_target_message = common_pb2.BuildTarget(name=name)
+    expected = BuildTarget(name)
+    result = controller_util.ParseBuildTarget(build_target_message)
+
+    self.assertEqual(expected, result)
+
+  def testWrongMessage(self):
+    """Test invalid message type given."""
+    with self.assertRaises(AssertionError):
+      controller_util.ParseBuildTarget(common_pb2.Chroot())
+
+
+class ParseBuildTargetsTest(cros_test_lib.TestCase):
+  """ParseBuildTargets tests."""
+
+  def testSuccess(self):
+    """Test successful handling case."""
+    names = ['foo', 'bar', 'baz']
+    message = build_api_test_pb2.TestRequestMessage()
+    for name in names:
+      message.build_targets.add().name = name
+
+    result = controller_util.ParseBuildTargets(message.build_targets)
+
+    self.assertItemsEqual([BuildTarget(name) for name in names], result)
+
+  def testWrongMessage(self):
+    """Wrong message type handling."""
+    message = common_pb2.Chroot()
+    message.env.use_flags.add().flag = 'foo'
+    message.env.use_flags.add().flag = 'bar'
+
+    with self.assertRaises(AssertionError):
+      controller_util.ParseBuildTargets(message.env.use_flags)
 
 
 class CPVToPackageInfoTest(cros_test_lib.TestCase):