Build API: Add chroot assertion options

BUG=chromium:912361
TEST=new unittests, run_tests

Change-Id: Ia83bca59c65ca8875af5ec463480177831b93165
Reviewed-on: https://chromium-review.googlesource.com/1453236
Commit-Ready: Alex Klein <saklein@chromium.org>
Tested-by: Alex Klein <saklein@chromium.org>
Reviewed-by: Lann Martin <lannm@chromium.org>
diff --git a/api/build_api_unittest.py b/api/build_api_unittest.py
index cc95655..6492ae9 100644
--- a/api/build_api_unittest.py
+++ b/api/build_api_unittest.py
@@ -3,10 +3,13 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+"""Tests for the build_api script covering the base Build API functionality."""
+
 from __future__ import print_function
 
 from chromite.api import build_api
 from chromite.api.gen import build_api_test_pb2
+from chromite.lib import cros_build_lib
 from chromite.lib import cros_test_lib
 
 
@@ -84,3 +87,87 @@
     with self.assertRaises(TypeError):
       self.router.Route('chromite.api.TestApiService', 'NoIoMethod',
                         self._INPUT_JSON)
+
+  def testRenameMethod(self):
+    """Test implementation name config."""
+    def _GetMethod(_, method_name):
+      self.assertEqual('CorrectName', method_name)
+      return lambda: None
+
+    self.PatchObject(self.router, '_GetMethod', side_effect=_GetMethod)
+
+    self.router.Route('chromite.api.TestApiService', 'RenamedMethod',
+                      self._INPUT_JSON)
+
+  def testInsideServiceChrootAsserts(self):
+    """Test the chroot assertion handling with service inside configured."""
+    # Helper variables/functions to make the patches simpler.
+    should_be_called = False
+    is_inside = False
+    def impl():
+      self.assertTrue(should_be_called,
+                      'The implementation should not have been called.')
+    def inside():
+      return is_inside
+
+    self.PatchObject(self.router, '_GetMethod', return_value=impl)
+    self.PatchObject(cros_build_lib, 'IsInsideChroot', side_effect=inside)
+
+    # Not inside chroot with inside requirement should raise an error.
+    with self.assertRaises(cros_build_lib.DieSystemExit):
+      self.router.Route('chromite.api.InsideChrootApiService',
+                        'InsideServiceInsideMethod', self._INPUT_JSON)
+
+    # Inside chroot with inside requirement.
+    is_inside = should_be_called = True
+    self.router.Route('chromite.api.InsideChrootApiService',
+                      'InsideServiceInsideMethod', self._INPUT_JSON)
+
+    # Inside chroot with outside override should raise assertion.
+    is_inside = True
+    should_be_called = False
+    with self.assertRaises(cros_build_lib.DieSystemExit):
+      self.router.Route('chromite.api.InsideChrootApiService',
+                        'InsideServiceOutsideMethod', self._INPUT_JSON)
+
+    is_inside = False
+    should_be_called = True
+    self.router.Route('chromite.api.InsideChrootApiService',
+                      'InsideServiceOutsideMethod', self._INPUT_JSON)
+
+  def testOutsideServiceChrootAsserts(self):
+    """Test the chroot assertion handling with service outside configured."""
+    # Helper variables/functions to make the patches simpler.
+    should_be_called = False
+    is_inside = False
+    def impl():
+      self.assertTrue(should_be_called,
+                      'The implementation should not have been called.')
+
+    self.PatchObject(self.router, '_GetMethod', return_value=impl)
+    self.PatchObject(cros_build_lib, 'IsInsideChroot',
+                     side_effect=lambda: is_inside)
+
+    # Outside chroot with outside requirement should be fine.
+    is_inside = False
+    should_be_called = True
+    self.router.Route('chromite.api.OutsideChrootApiService',
+                      'OutsideServiceOutsideMethod', self._INPUT_JSON)
+
+    # Inside chroot with outside requirement should raise error.
+    is_inside = True
+    should_be_called = False
+    with self.assertRaises(cros_build_lib.DieSystemExit):
+      self.router.Route('chromite.api.OutsideChrootApiService',
+                        'OutsideServiceOutsideMethod', self._INPUT_JSON)
+
+    # Outside chroot with inside override should raise error.
+    is_inside = should_be_called = False
+    with self.assertRaises(cros_build_lib.DieSystemExit):
+      self.router.Route('chromite.api.OutsideChrootApiService',
+                        'OutsideServiceInsideMethod', self._INPUT_JSON)
+
+    # Inside chroot with inside override should be fine.
+    is_inside = should_be_called = True
+    self.router.Route('chromite.api.OutsideChrootApiService',
+                      'OutsideServiceInsideMethod', self._INPUT_JSON)