From patchwork Fri Jan 9 18:31:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1390 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983551; bh=c+ZAEMms4WJxsrb4Xq+1LsDCDwbROlJ9WqhSgjEnoGk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=VmAL5ZyvshXsj7Z/aEIY1QYF2X2LRMiGPBTYPliYKLta5Ta0fMhG2LYsOg0ZKOBgj MiMdODdRwFtBXqoJvc3TtYx6SNcJnbaw8V8kcOdMR8fpxEtxv590Hyh1c/hZiA+GmF m28QPFN2N9j3Jk53aHMII9arRG9Ks5LG3UqZ0Vkw/2Xc2aK/Wy1mHywMWgW/WSIrWH kqZuT+Bysh+qux4qCDFoGV9MbC8u7H6hLctLFUmIbiBbznv0Z74KVJcLomxsX6vfm+ E+KKIgkrJIZ4ac+ZuLXhXyAkq8knWaPkx9IrHqUiw5iQDqNYHrx5uMM6FPoCYqjHyb 6xSd+LoTCsr5g== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0A4BB69218 for ; Fri, 9 Jan 2026 11:32:31 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 9jbqW_TD0U6X for ; Fri, 9 Jan 2026 11:32:30 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983550; bh=c+ZAEMms4WJxsrb4Xq+1LsDCDwbROlJ9WqhSgjEnoGk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=jo7o5NFQybW1UH7m1fL1tI/c7RYtb/QxuoAVoADvt1ANkxRlwM/AOEvOqedC/prUC jq5Hpn+mrKToiaAaWBEtC7XwkqfJ/ptjdNUD/qGSK3CcjAQWW/Rm18N/7+RSRVZAnB zqRQ2DqbbErrx+lWKZFV8p68GfPeDPbIWvzNC21CuQaqHGtgbXefTppSq4xhpkumQp wfinPZvr463cxNQT27BpXN7/wleI9BQHqmtC+O4rrwJqVxbDQn6cDBIUaulMWyxb3j Z5f8b3ZaBwo95iGqTAkIFx9Pa1PzpHKA0SppnVMMEnJkWryt0Xel9ZSd9YFg8yg/XU 3qQB2dxmu+q6w== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id EDBCB69216 for ; Fri, 9 Jan 2026 11:32:30 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983549; bh=sgxs2s+U/yjV9SJxBX+yN0g05dC+yoLz5wgdNQYCPA8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vtk6B6R/JSU6o1eS3j4vHPAgSh0in+9lOBoHVqenobJOTtmfrGIm6kcV8b2dgX+a8 DHv9VJzPIjdN8bndG5DpvIt4s2lchrHf9ffHO6kOGacDGzsjoSA3ACSB7QNRN2CzMc aBmJ8O3b3NvTxrTX4uUGFvAURC1ZuDIKiVqI2Jp3ualQkMvpxdcPwPSu3AS7nxUkZk ZLX14VVW9oNebW+gyf0fNzDNkXaQSFXk62Ff5eK/BM0hDz3OQr2SWhm8yS48WAZoeQ y0M8wXo/Wy04h3NOC7viaZTt1SoO9FWmExZISk5Q8btmakbGU84hfPxyq4ku9Cej2d siDcoeYBt8HYQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 24B5D6920A; Fri, 9 Jan 2026 11:32:29 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id hm9j_Doh-szN; Fri, 9 Jan 2026 11:32:29 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983544; bh=mieQrjzL9PYUK4ntZh3NyJWHjT2/GS6OfrdEaUVnSyI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q+2x2yMuO9BUYCwG2WTb9vriQkqaectOXOzBtMI84AkTF03ROUa3P8qgD6D3C76X6 MLI+NX0+WrToXYKxfKxRYqQEx27z3dgKGsQ3mLmDF60d0nBiSceY1cM/YVZefdtMJJ 7C3ZH5lUqmSxNQklpiBjX+DodL9ArMYfUnn0tW74jQIsu/wbzVD6kmZOl1YAQW4T47 sPWLHfjie530EPoG8ShPXNhPoQJO6FNgW8718sV+au+vL7OYlosUNYPI36v8Uy6lLt 7J31l+VXaY38q1ACxaWdN0AAtjW7dXs7XjgjwHkmJw9vDUix32cVMhxw30eC8JFn6D B7F/jv/weEHyA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 908F169209; Fri, 9 Jan 2026 11:32:24 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 9 Jan 2026 11:31:04 -0700 Message-ID: <20260109183116.3262115-13-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109183116.3262115-1-sjg@u-boot.org> References: <20260109183116.3262115-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: E7IND3KBX3ZU373JABSFAF6JIRMF6RX2 X-Message-ID-Hash: E7IND3KBX3ZU373JABSFAF6JIRMF6RX2 X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 12/18] buildman: Add unit tests for _prepare_output_space() List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add TestPrepareOutputSpace class to test_builder.py with tests: - _get_output_space_removals() with no commits - _get_output_space_removals() with no old directories - _get_output_space_removals() identifying old directories by pattern - _prepare_output_space() with nothing to remove - _prepare_output_space() removing directories and printing message The test verifies that the 'Removing' message is printed with newline=False so it can be overwritten by subsequent output. Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- tools/buildman/main.py | 1 + tools/buildman/test_builder.py | 84 ++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 74da226c2cf..449263b48e8 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -56,6 +56,7 @@ def run_tests(skip_net_tests, debug, verbose, args): test_builder.TestPrintFuncSizeDetail, test_builder.TestPrepareThread, test_builder.TestPrepareWorkingSpace, + test_builder.TestPrepareOutputSpace, 'buildman.toolchain']) return (0 if result.wasSuccessful() else 1) diff --git a/tools/buildman/test_builder.py b/tools/buildman/test_builder.py index d7359477ef2..b17d7942e1d 100644 --- a/tools/buildman/test_builder.py +++ b/tools/buildman/test_builder.py @@ -5,6 +5,7 @@ """Unit tests for builder.py""" import os +import shutil import unittest from unittest import mock @@ -338,5 +339,88 @@ class TestPrepareWorkingSpace(unittest.TestCase): mock_prepare_thread.assert_any_call(1, True) +class TestPrepareOutputSpace(unittest.TestCase): + """Tests for Builder._prepare_output_space() and _get_output_space_removals()""" + + 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) + + def test_get_removals_no_commits(self): + """Test _get_output_space_removals with no commits""" + self.builder.commits = None + result = self.builder._get_output_space_removals() + self.assertEqual(result, []) + + @mock.patch.object(builder.Builder, 'get_output_dir') + @mock.patch('glob.glob') + def test_get_removals_no_old_dirs(self, mock_glob, mock_get_output_dir): + """Test _get_output_space_removals with no old directories""" + self.builder.commits = [mock.Mock()] # Non-empty to trigger logic + self.builder.commit_count = 1 + mock_get_output_dir.return_value = '/tmp/test/01_gabcdef1_test' + mock_glob.return_value = [] + + result = self.builder._get_output_space_removals() + self.assertEqual(result, []) + + @mock.patch.object(builder.Builder, 'get_output_dir') + @mock.patch('glob.glob') + def test_get_removals_with_old_dirs(self, mock_glob, mock_get_output_dir): + """Test _get_output_space_removals identifies old directories""" + self.builder.commits = [mock.Mock()] # Non-empty to trigger logic + self.builder.commit_count = 1 + mock_get_output_dir.return_value = '/tmp/test/01_gabcdef1_current' + # Simulate old directories with buildman naming pattern + mock_glob.return_value = [ + '/tmp/test/01_gabcdef1_current', # Current - should not remove + '/tmp/test/02_g1234567_old', # Old - should remove + '/tmp/test/random_dir', # Not matching pattern - keep + ] + + result = self.builder._get_output_space_removals() + self.assertEqual(result, ['/tmp/test/02_g1234567_old']) + + @mock.patch.object(builder.Builder, '_get_output_space_removals') + def test_prepare_output_space_nothing_to_remove(self, mock_get_removals): + """Test _prepare_output_space with nothing to remove""" + mock_get_removals.return_value = [] + terminal.get_print_test_lines() # Clear + + self.builder._prepare_output_space() + + lines = terminal.get_print_test_lines() + self.assertEqual(len(lines), 0) + + @mock.patch.object(shutil, 'rmtree') + @mock.patch.object(builder.Builder, '_get_output_space_removals') + def test_prepare_output_space_removes_dirs(self, mock_get_removals, + mock_rmtree): + """Test _prepare_output_space removes old directories""" + mock_get_removals.return_value = ['/tmp/test/old1', '/tmp/test/old2'] + terminal.get_print_test_lines() # Clear + + self.builder._prepare_output_space() + + # Check rmtree was called for each directory + self.assertEqual(mock_rmtree.call_count, 2) + mock_rmtree.assert_any_call('/tmp/test/old1') + mock_rmtree.assert_any_call('/tmp/test/old2') + + # Check 'Removing' message was printed + lines = terminal.get_print_test_lines() + self.assertEqual(len(lines), 1) + self.assertIn('Removing 2 old build directories', lines[0].text) + # Check newline=False was used (message should be overwritten) + self.assertFalse(lines[0].newline) + + if __name__ == '__main__': unittest.main()