BundleDebugSymbols: Initial api/controller implementation and test.
Provide initial implementation that calls GenerateBreakpadSymbols
and GatherSymbolFiles (per go/buildapi-archive-debug-symbols).
Next steps:
1. Test on bot with led: go/luci-how-to-led
2. Determine if other debug files are needed (see doc above).
BUG=chromium:1031380
TEST=run_pytest unit tests
Change-Id: I0dcdcbdbedf3e77f77f8acf91b44c582c72357f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2588273
Commit-Queue: Michael Mortensen <mmortensen@google.com>
Tested-by: Michael Mortensen <mmortensen@google.com>
Reviewed-by: Alex Klein <saklein@chromium.org>
diff --git a/api/controller/artifacts_unittest.py b/api/controller/artifacts_unittest.py
index 7a0364c..862340a 100644
--- a/api/controller/artifacts_unittest.py
+++ b/api/controller/artifacts_unittest.py
@@ -1130,3 +1130,71 @@
with self.assertRaises(cros_build_lib.DieSystemExit):
artifacts.BundleGceTarball(self.target_request, self.response,
self.api_config)
+
+
+class BundleDebugSymbolsTest(BundleTestCase):
+ """Unittests for BundleDebugSymbols."""
+
+ def setUp(self):
+ # Create a chroot_path that also includes a chroot tmp dir.
+ self.chroot_path = os.path.join(self.tempdir, 'chroot_dir')
+ osutils.SafeMakedirs(self.chroot_path)
+ osutils.SafeMakedirs(os.path.join(self.chroot_path, 'tmp'))
+ # Create output dir.
+ output_dir = os.path.join(self.tempdir, 'output_dir')
+ osutils.SafeMakedirs(output_dir)
+ # Build target request.
+ self.target_request = self.BuildTargetRequest(
+ build_target='target',
+ output_dir=self.output_dir,
+ chroot=self.chroot_path)
+
+ def testValidateOnly(self):
+ """Check that a validate only call does not execute any logic."""
+ patch = self.PatchObject(artifacts_svc, 'GenerateBreakpadSymbols')
+ artifacts.BundleDebugSymbols(self.target_request, self.response,
+ 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(artifacts_svc, 'GenerateBreakpadSymbols')
+ artifacts.BundleDebugSymbols(self.target_request, self.response,
+ self.mock_call_config)
+ patch.assert_not_called()
+ self.assertEqual(len(self.response.artifacts), 1)
+ self.assertEqual(self.response.artifacts[0].path,
+ os.path.join(self.output_dir,
+ constants.DEBUG_SYMBOLS_TAR))
+
+ def testBundleDebugSymbols(self):
+ """BundleDebugSymbols calls cbuildbot/commands with correct args."""
+ # Patch service layer functions.
+ generate_breakpad_symbols_patch = self.PatchObject(
+ artifacts_svc, 'GenerateBreakpadSymbols',
+ return_value=cros_build_lib.CommandResult(returncode=0, output=''))
+ gather_symbol_files_patch = self.PatchObject(
+ artifacts_svc, 'GatherSymbolFiles',
+ return_value=[artifacts_svc.SymbolFileTuple(
+ source_file_name='path/to/source/file1.sym',
+ relative_path='file1.sym')])
+
+ artifacts.BundleDebugSymbols(self.target_request, self.response,
+ self.api_config)
+ # Verify mock objects were called.
+ generate_breakpad_symbols_patch.assert_called()
+ gather_symbol_files_patch.assert_called()
+
+ # Verify response proto contents and output directory contents.
+ self.assertEqual(
+ [artifact.path for artifact in self.response.artifacts],
+ [os.path.join(self.output_dir, constants.DEBUG_SYMBOLS_TAR)])
+ files = os.listdir(self.output_dir)
+ self.assertEqual(files, [constants.DEBUG_SYMBOLS_TAR])
+
+ def testBundleGceTarballNoImageDir(self):
+ """BundleDebugSymbols dies when image dir does not exist."""
+ self.PatchObject(os.path, 'exists', return_value=False)
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ artifacts.BundleDebugSymbols(self.target_request, self.response,
+ self.api_config)