From: Simon Glass <simon.glass@canonical.com> Add TestPrepareThread class to test_builder.py with tests covering: - No git setup (setup_git=None) - Existing clone (fetches updates) - Existing worktree (no action needed) - Invalid git_dir (neither file nor directory) - Creating new worktree - Creating new clone - Clone with setup_git=True - Invalid setup_git value Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/main.py | 1 + tools/buildman/test_builder.py | 118 +++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 70547b2991d..6e780b9e07e 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -54,6 +54,7 @@ def run_tests(skip_net_tests, debug, verbose, args): func_test.TestFunctional, test_boards.TestBoards, test_bsettings.TestBsettings, test_builder.TestPrintFuncSizeDetail, + test_builder.TestPrepareThread, 'buildman.toolchain']) return (0 if result.wasSuccessful() else 1) diff --git a/tools/buildman/test_builder.py b/tools/buildman/test_builder.py index 5d003de1966..042dacc2f34 100644 --- a/tools/buildman/test_builder.py +++ b/tools/buildman/test_builder.py @@ -4,9 +4,13 @@ """Unit tests for builder.py""" +import os import unittest +from unittest import mock from buildman import builder +from buildman import builderthread +from u_boot_pylib import gitutil from u_boot_pylib import terminal @@ -140,5 +144,119 @@ class TestPrintFuncSizeDetail(unittest.TestCase): self.assertEqual(len(lines), 0) +class TestPrepareThread(unittest.TestCase): + """Tests for Builder._prepare_thread()""" + + def setUp(self): + """Set up test fixtures""" + self.builder = builder.Builder( + toolchains=None, base_dir='/tmp/test', git_dir='/src/repo', + num_threads=4, num_jobs=1) + terminal.set_print_test_mode() + + def tearDown(self): + """Clean up after tests""" + terminal.set_print_test_mode(False) + + @mock.patch.object(builderthread, 'mkdir') + def test_no_setup_git(self, mock_mkdir): + """Test with setup_git=None (no git setup needed)""" + self.builder._prepare_thread(0, None) + mock_mkdir.assert_called_once() + + @mock.patch.object(gitutil, 'fetch') + @mock.patch.object(os.path, 'isdir', return_value=True) + @mock.patch.object(builderthread, 'mkdir') + def test_existing_clone(self, mock_mkdir, mock_isdir, mock_fetch): + """Test with existing git clone (fetches updates)""" + terminal.get_print_test_lines() # Clear + self.builder._prepare_thread(0, 'clone') + + mock_fetch.assert_called_once() + lines = terminal.get_print_test_lines() + self.assertEqual(len(lines), 1) + self.assertIn('Fetching repo', lines[0].text) + + @mock.patch.object(os.path, 'isfile', return_value=True) + @mock.patch.object(os.path, 'isdir', return_value=False) + @mock.patch.object(builderthread, 'mkdir') + def test_existing_worktree(self, mock_mkdir, mock_isdir, mock_isfile): + """Test with existing worktree (no action needed)""" + terminal.get_print_test_lines() # Clear + self.builder._prepare_thread(0, 'worktree') + + # No git operations should be called + lines = terminal.get_print_test_lines() + self.assertEqual(len(lines), 0) + + @mock.patch.object(os.path, 'exists', return_value=True) + @mock.patch.object(os.path, 'isfile', return_value=False) + @mock.patch.object(os.path, 'isdir', return_value=False) + @mock.patch.object(builderthread, 'mkdir') + def test_invalid_git_dir(self, mock_mkdir, mock_isdir, mock_isfile, + mock_exists): + """Test with git_dir that exists but is neither file nor directory""" + with self.assertRaises(ValueError) as ctx: + self.builder._prepare_thread(0, 'clone') + self.assertIn('exists, but is not a file or a directory', + str(ctx.exception)) + + @mock.patch.object(gitutil, 'add_worktree') + @mock.patch.object(os.path, 'exists', return_value=False) + @mock.patch.object(os.path, 'isfile', return_value=False) + @mock.patch.object(os.path, 'isdir', return_value=False) + @mock.patch.object(builderthread, 'mkdir') + def test_create_worktree(self, mock_mkdir, mock_isdir, mock_isfile, + mock_exists, mock_add_worktree): + """Test creating a new worktree""" + terminal.get_print_test_lines() # Clear + self.builder._prepare_thread(0, 'worktree') + + mock_add_worktree.assert_called_once() + lines = terminal.get_print_test_lines() + self.assertEqual(len(lines), 1) + self.assertIn('Checking out worktree', lines[0].text) + + @mock.patch.object(gitutil, 'clone') + @mock.patch.object(os.path, 'exists', return_value=False) + @mock.patch.object(os.path, 'isfile', return_value=False) + @mock.patch.object(os.path, 'isdir', return_value=False) + @mock.patch.object(builderthread, 'mkdir') + def test_create_clone(self, mock_mkdir, mock_isdir, mock_isfile, + mock_exists, mock_clone): + """Test creating a new clone""" + terminal.get_print_test_lines() # Clear + self.builder._prepare_thread(0, 'clone') + + mock_clone.assert_called_once() + lines = terminal.get_print_test_lines() + self.assertEqual(len(lines), 1) + self.assertIn('Cloning repo', lines[0].text) + + @mock.patch.object(gitutil, 'clone') + @mock.patch.object(os.path, 'exists', return_value=False) + @mock.patch.object(os.path, 'isfile', return_value=False) + @mock.patch.object(os.path, 'isdir', return_value=False) + @mock.patch.object(builderthread, 'mkdir') + def test_create_clone_with_true(self, mock_mkdir, mock_isdir, mock_isfile, + mock_exists, mock_clone): + """Test creating a clone when setup_git=True""" + terminal.get_print_test_lines() # Clear + self.builder._prepare_thread(0, True) + + mock_clone.assert_called_once() + + @mock.patch.object(os.path, 'exists', return_value=False) + @mock.patch.object(os.path, 'isfile', return_value=False) + @mock.patch.object(os.path, 'isdir', return_value=False) + @mock.patch.object(builderthread, 'mkdir') + def test_invalid_setup_git(self, mock_mkdir, mock_isdir, mock_isfile, + mock_exists): + """Test with invalid setup_git value""" + with self.assertRaises(ValueError) as ctx: + self.builder._prepare_thread(0, 'invalid') + self.assertIn("Can't setup git repo", str(ctx.exception)) + + if __name__ == '__main__': unittest.main() -- 2.43.0