BuildAPI: Add unit tests and mocks for Test service.

Regenerated api/gen/chromite/api/test_pb2.py by running
api/compile_build_api_proto.

BUG=chromium:1029033
TEST=run_tests

Change-Id: I8b6d8dc991fa97e2df60d30acb5027feb308729b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1945787
Tested-by: Michael Mortensen <mmortensen@google.com>
Reviewed-by: Michael Mortensen <mmortensen@google.com>
diff --git a/api/controller/test_unittest.py b/api/controller/test_unittest.py
index f28abf7..4e08b17 100644
--- a/api/controller/test_unittest.py
+++ b/api/controller/test_unittest.py
@@ -107,6 +107,34 @@
                                         self.validate_only_config)
     patch.assert_not_called()
 
+  def testMockCall(self):
+    """Test that a mock call does not execute logic, returns mocked value."""
+    patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
+
+    input_msg = self._GetInput(board='board', result_path=self.tempdir)
+    response = self._GetOutput()
+    test_controller.BuildTargetUnitTest(input_msg, response,
+                                        self.mock_call_config)
+    patch.assert_not_called()
+    self.assertEqual(response.tarball_path,
+                     os.path.join(input_msg.result_path, 'unit_tests.tar'))
+
+  def testMockError(self):
+    """Test that a mock error does not execute logic, returns mocked value."""
+    patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
+
+    input_msg = self._GetInput(board='board', result_path=self.tempdir)
+    response = self._GetOutput()
+    rc = test_controller.BuildTargetUnitTest(input_msg, response,
+                                             self.mock_error_config)
+    patch.assert_not_called()
+    self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
+    self.assertTrue(response.failed_packages)
+    self.assertEqual(response.failed_packages[0].category, 'foo')
+    self.assertEqual(response.failed_packages[0].package_name, 'bar')
+    self.assertEqual(response.failed_packages[1].category, 'cat')
+    self.assertEqual(response.failed_packages[1].package_name, 'pkg')
+
   def testNoArgumentFails(self):
     """Test no arguments fails."""
     input_msg = self._GetInput()
@@ -177,6 +205,23 @@
     self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
     self.assertFalse(output_msg.failed_packages)
 
+  def testBuildTargetUnitTest(self):
+    """Test BuildTargetUnitTest successful call."""
+    input_msg = self._GetInput(board='board', result_path=self.tempdir)
+
+    result = test_service.BuildTargetUnitTestResult(0, None)
+    self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
+
+    tarball_result = os.path.join(input_msg.result_path, 'unit_tests.tar')
+    self.PatchObject(test_service, 'BuildTargetUnitTestTarball',
+                     return_value=tarball_result)
+
+    response = self._GetOutput()
+    test_controller.BuildTargetUnitTest(input_msg, response,
+                                        self.api_config)
+    self.assertEqual(response.tarball_path,
+                     os.path.join(input_msg.result_path, 'unit_tests.tar'))
+
 
 class ChromiteUnitTestTest(cros_test_lib.MockTestCase,
                            api_config.ApiConfigMixin):
@@ -222,11 +267,36 @@
                           api_config.ApiConfigMixin):
   """CrosSigningTest tests."""
 
+  def setUp(self):
+    self.chroot_path = '/path/to/chroot'
+
+  def _GetInput(self, chroot_path=None):
+    """Helper to build an input message instance."""
+    proto = test_pb2.CrosSigningTestRequest(
+        chroot={'path': chroot_path},
+    )
+    return proto
+
+  def _GetOutput(self):
+    """Helper to get an empty output message instance."""
+    return test_pb2.CrosSigningTestResponse()
+
   def testValidateOnly(self):
     """Sanity check that a validate only call does not execute any logic."""
     test_controller.CrosSigningTest(None, None, self.validate_only_config)
     self.assertFalse(self.rc.call_count)
 
+  def testCrosSigningTest(self):
+    """Call CrosSigningTest with mocked cros_build_lib.run."""
+    request = self._GetInput(chroot_path=self.chroot_path)
+    patch = self.PatchObject(
+        cros_build_lib, 'run',
+        return_value=cros_build_lib.CommandResult(returncode=0))
+
+    test_controller.CrosSigningTest(request, self._GetOutput(),
+                                    self.api_config)
+    patch.assert_called_once()
+
 
 class SimpleChromeWorkflowTestTest(cros_test_lib.MockTestCase,
                                    api_config.ApiConfigMixin):
@@ -257,7 +327,7 @@
         test_service, 'SimpleChromeWorkflowTest')
 
   def testMissingBuildTarget(self):
-    """Test VmTest dies when build_target not set."""
+    """Test SimpleChromeWorkflowTest dies when build_target not set."""
     input_proto = self._Input(build_target=None, sysroot_path='/sysroot/dir',
                               chrome_root='/chrome/path')
     with self.assertRaises(cros_build_lib.DieSystemExit):
@@ -265,7 +335,7 @@
                                                self.api_config)
 
   def testMissingSysrootPath(self):
-    """Test VmTest dies when build_target not set."""
+    """Test SimpleChromeWorkflowTest dies when build_target not set."""
     input_proto = self._Input(build_target='board', sysroot_path=None,
                               chrome_root='/chrome/path')
     with self.assertRaises(cros_build_lib.DieSystemExit):
@@ -273,7 +343,7 @@
                                                self.api_config)
 
   def testMissingChromeRoot(self):
-    """Test VmTest dies when build_target not set."""
+    """Test SimpleChromeWorkflowTest dies when build_target not set."""
     input_proto = self._Input(build_target='board', sysroot_path='/sysroot/dir',
                               chrome_root=None)
     with self.assertRaises(cros_build_lib.DieSystemExit):
@@ -314,6 +384,9 @@
     values.update(kwargs)
     return test_pb2.VmTestRequest(**values)
 
+  def _Output(self):
+    return test_pb2.VmTestResponse()
+
   def testValidateOnly(self):
     """Sanity check that a validate only call does not execute any logic."""
     test_controller.VmTest(self._GetInput(), None, self.validate_only_config)
@@ -370,6 +443,17 @@
     with self.assertRaises(cros_build_lib.DieSystemExit):
       test_controller.VmTest(input_proto, None, self.api_config)
 
+  def testVmTest(self):
+    """Call VmTest with valid args and temp dir."""
+    request = self._GetInput()
+    response = self._Output()
+    patch = self.PatchObject(
+        cros_build_lib, 'run',
+        return_value=cros_build_lib.CommandResult(returncode=0))
+
+    test_controller.VmTest(request, response, self.api_config)
+    patch.assert_called()
+
 
 class MoblabVmTestTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
   """Test the MoblabVmTest endpoint."""