From patchwork Fri Jan 9 18:30:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1382 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=1767983513; bh=xxXGRDbQxNrFq16nIFOt4PSSHrpw7KsTw0LDd/qfvnI=; 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=ROl5KiOtCh/s/iVyDfA+XXEhgkgsBYU1oXsiKPUVHzkDuaEuYbk/qFzRcYbvvdN0g n2mecRuLmBe211Bn5L73yP4s4GEwcECn0IWmZ1r9ietcD7R2jqqdJYUzfowrX1Ungz vsOB+LFHZPMat4/mWcORzMAjgleKbpBFK5+JmK1lH/c7LZ9//Rv153CQZxk5qLCC65 R27Cubb7R1kDkcXTzJYcDHBDhZnY/bAElaz10iVj5VKK9uGERk5C6v7zMJPNZBA6jL ItHkHN2yf/NgkqJaDkP9hJ7DoZXFtAbvgrAUonG0EmsICapSM1bBITeCdt64zGuwIE ryTb37mEpjw/g== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id ABE7A69218 for ; Fri, 9 Jan 2026 11:31:53 -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 Ox5K_13z9bsF for ; Fri, 9 Jan 2026 11:31:53 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983513; bh=xxXGRDbQxNrFq16nIFOt4PSSHrpw7KsTw0LDd/qfvnI=; 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=ROl5KiOtCh/s/iVyDfA+XXEhgkgsBYU1oXsiKPUVHzkDuaEuYbk/qFzRcYbvvdN0g n2mecRuLmBe211Bn5L73yP4s4GEwcECn0IWmZ1r9ietcD7R2jqqdJYUzfowrX1Ungz vsOB+LFHZPMat4/mWcORzMAjgleKbpBFK5+JmK1lH/c7LZ9//Rv153CQZxk5qLCC65 R27Cubb7R1kDkcXTzJYcDHBDhZnY/bAElaz10iVj5VKK9uGERk5C6v7zMJPNZBA6jL ItHkHN2yf/NgkqJaDkP9hJ7DoZXFtAbvgrAUonG0EmsICapSM1bBITeCdt64zGuwIE ryTb37mEpjw/g== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 99F616920A for ; Fri, 9 Jan 2026 11:31:53 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983511; bh=IniiT3t19w8nF6ZMBQfhpd8ep2n+OTKw9+kBzo1mrPg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fi0xMFSKozDKf3uCIcMv1Y/HA7XJWnelcrGzvg+piKRE/vqkmI7FzMNe7goz6tva7 Qj+S7YAEv+GbYDAotOaiz80IO746V5bkrpSHEDIzxZ4yv7hIK3TsrIgBvPLTBkV7XH kcHEChN4Q98iPgmc971rHwb1V/Qweafetw9oD0wjUnQSl5WtDbfrM3GRmLO2ckBY7s S8cNVAO1oVtvnZARvW4/wVv8aHYO3dQCzz+0vaDvqzMPeWELg3nntE2iAC7u/vhNh3 wmlAH+/+oNs6tPQw/flJApxUHd7VWxfGid+wFTQUUXLY5Kz/omZP/8jBGwwIPs+ja9 5LiuBkl1WLQIQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9C51669208; Fri, 9 Jan 2026 11:31:51 -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 BN4M15VqP4ym; Fri, 9 Jan 2026 11:31:51 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767983507; bh=07hzeqKQGEQWY7OeevVmieKkiFl4+A5W65yTEZeXmmM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=swYgEvCJIeOy3GCRnOkU1FZXd1RZKhfHREM64UCuCPVFz12cxP455GYuQAu8sj8sX 3tXeje+dxZbmlsdAEMkxsKqxYtGAu+jIdym0AOaq7edMjp/ZcnuJEHTbu3ov7HzYML Eg5g/7OH37prnWVzDtzI0Wmw8yeY4R25/6r7FNkPqhg0bYMWczEOiY/iMT5Zh9ruKV RDvsH/85+z4UXPu8tyAFoJU37tRKLkEqKQj/J02R1xSPmR9jynTSWCHiERDuKhiUWe zOVHRnRdOvX4zM8SVeQPUmOSFT3tz19AYn06nvSX9aenRYWQFDM0MWf26sJs93/uaa cYJnd76/gUj4Q== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id DA9CB69209; Fri, 9 Jan 2026 11:31:46 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 9 Jan 2026 11:30:56 -0700 Message-ID: <20260109183116.3262115-5-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: C4RROGCSRSNCMH3C4BUYKJRBCQIGWP2Q X-Message-ID-Hash: C4RROGCSRSNCMH3C4BUYKJRBCQIGWP2Q 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 04/18] buildman: Add unit tests for print_func_size_detail() 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 a new test_builder.py file with unit tests for the print_func_size_detail() method in Builder class. This method displays detailed function size changes between builds. Tests cover: - No size changes (no output expected) - Function grows in size - Function shrinks in size - New function added - Function removed - Mixed changes (add, remove, grow, shrink) - Empty dictionaries Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- tools/buildman/main.py | 2 + tools/buildman/test_builder.py | 144 +++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 tools/buildman/test_builder.py diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 04993dcd87b..70547b2991d 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -39,6 +39,7 @@ def run_tests(skip_net_tests, debug, verbose, args): from buildman import test from buildman import test_boards from buildman import test_bsettings + from buildman import test_builder test_name = args.terms and args.terms[0] or None if skip_net_tests: @@ -52,6 +53,7 @@ def run_tests(skip_net_tests, debug, verbose, args): test.TestBuildConfig, test.TestBuildMisc, test.TestBuilderFuncs, func_test.TestFunctional, test_boards.TestBoards, test_bsettings.TestBsettings, + test_builder.TestPrintFuncSizeDetail, 'buildman.toolchain']) return (0 if result.wasSuccessful() else 1) diff --git a/tools/buildman/test_builder.py b/tools/buildman/test_builder.py new file mode 100644 index 00000000000..5d003de1966 --- /dev/null +++ b/tools/buildman/test_builder.py @@ -0,0 +1,144 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2025 Google LLC +# Written by Simon Glass + +"""Unit tests for builder.py""" + +import unittest + +from buildman import builder +from u_boot_pylib import terminal + + +class TestPrintFuncSizeDetail(unittest.TestCase): + """Tests for Builder.print_func_size_detail()""" + + def setUp(self): + """Set up test fixtures""" + # Create a minimal Builder for testing + self.builder = builder.Builder( + toolchains=None, base_dir='/tmp', git_dir=None, num_threads=0, + num_jobs=1) + terminal.set_print_test_mode() + + def tearDown(self): + """Clean up after tests""" + terminal.set_print_test_mode(False) + + def test_no_change(self): + """Test with no size changes""" + old = {'func_a': 100, 'func_b': 200} + new = {'func_a': 100, 'func_b': 200} + + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', old, new) + lines = terminal.get_print_test_lines() + + # No output when there are no changes + self.assertEqual(len(lines), 0) + + def test_function_grows(self): + """Test when a function grows in size""" + old = {'func_a': 100} + new = {'func_a': 150} + + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', old, new) + lines = terminal.get_print_test_lines() + + text = '\n'.join(line.text for line in lines) + self.assertIn('u-boot', text) + self.assertIn('func_a', text) + self.assertIn('grow:', text) + # Check old, new and delta values appear + self.assertIn('100', text) + self.assertIn('150', text) + self.assertIn('+50', text) + + def test_function_shrinks(self): + """Test when a function shrinks in size""" + old = {'func_a': 200} + new = {'func_a': 150} + + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', old, new) + lines = terminal.get_print_test_lines() + + text = '\n'.join(line.text for line in lines) + self.assertIn('func_a', text) + self.assertIn('-50', text) + + def test_function_added(self): + """Test when a new function is added""" + old = {'func_a': 100} + new = {'func_a': 100, 'func_b': 200} + + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', old, new) + lines = terminal.get_print_test_lines() + + text = '\n'.join(line.text for line in lines) + self.assertIn('func_b', text) + self.assertIn('add:', text) + # New function shows '-' for old value + self.assertIn('-', text) + self.assertIn('200', text) + + def test_function_removed(self): + """Test when a function is removed""" + old = {'func_a': 100, 'func_b': 200} + new = {'func_a': 100} + + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', old, new) + lines = terminal.get_print_test_lines() + + text = '\n'.join(line.text for line in lines) + self.assertIn('func_b', text) + # Removed function shows '-' for new value + self.assertIn('-200', text) + + def test_mixed_changes(self): + """Test with a mix of added, removed, grown and shrunk functions""" + old = { + 'unchanged': 100, + 'grown': 200, + 'shrunk': 300, + 'removed': 400, + } + new = { + 'unchanged': 100, + 'grown': 250, + 'shrunk': 250, + 'added': 150, + } + + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', old, new) + lines = terminal.get_print_test_lines() + + text = '\n'.join(line.text for line in lines) + # Check all changed functions appear + self.assertIn('grown', text) + self.assertIn('shrunk', text) + self.assertIn('removed', text) + self.assertIn('added', text) + # unchanged should not appear (no delta) + # Check the header line appears + self.assertIn('function', text) + self.assertIn('old', text) + self.assertIn('new', text) + self.assertIn('delta', text) + + def test_empty_dicts(self): + """Test with empty dictionaries""" + terminal.get_print_test_lines() # Clear + self.builder.print_func_size_detail('u-boot', {}, {}) + lines = terminal.get_print_test_lines() + + # No output when both dicts are empty + self.assertEqual(len(lines), 0) + + +if __name__ == '__main__': + unittest.main()