From patchwork Mon Dec 22 04:18:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1030 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=1766377094; bh=AtAC5kquEDn+zZxJPl76t2wmsJg1o1qnb9Wg2h4iR8U=; h=From:To:Date:CC:Subject:List-Id:List-Archive:List-Help:List-Owner: List-Post:List-Subscribe:List-Unsubscribe:From; b=sdNGQpppxOEYiL5yhQIJUKLxqhWPY6ifyncayT9tTgsXdUJUO6X+2itMOQ91lefY1 Ww09HreBD5vySPixAnRah2pQXyBnlsuJhppvLNyUhRvHpMPN7XhBfFfr4lCPYy2E/w MBfloBIOGLXV7qmrs1V048cslBCOuaVDt9z8O0pksLD9/09gUqyxsOEZ+/nmQleVJA P0J6C/oZHlyHzfWMhPabDsTiDgnlJ/psUXN9dzYQPMLpcIBBV2tlExZtkfJsML1j9l 6Zsmvxrg+Cmk6rcZUk5sOsDmztg32+FKmUehupqNUnKGiH3QRBV8O63tkfhh9q/PZQ 9KJ028XbAzGog== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AC01A64D36 for ; Sun, 21 Dec 2025 21:18:14 -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 GJNUsHIgChgx for ; Sun, 21 Dec 2025 21:18:14 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766377094; bh=AtAC5kquEDn+zZxJPl76t2wmsJg1o1qnb9Wg2h4iR8U=; h=From:To:Date:CC:Subject:List-Id:List-Archive:List-Help:List-Owner: List-Post:List-Subscribe:List-Unsubscribe:From; b=sdNGQpppxOEYiL5yhQIJUKLxqhWPY6ifyncayT9tTgsXdUJUO6X+2itMOQ91lefY1 Ww09HreBD5vySPixAnRah2pQXyBnlsuJhppvLNyUhRvHpMPN7XhBfFfr4lCPYy2E/w MBfloBIOGLXV7qmrs1V048cslBCOuaVDt9z8O0pksLD9/09gUqyxsOEZ+/nmQleVJA P0J6C/oZHlyHzfWMhPabDsTiDgnlJ/psUXN9dzYQPMLpcIBBV2tlExZtkfJsML1j9l 6Zsmvxrg+Cmk6rcZUk5sOsDmztg32+FKmUehupqNUnKGiH3QRBV8O63tkfhh9q/PZQ 9KJ028XbAzGog== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 97D7D64CD1 for ; Sun, 21 Dec 2025 21:18:14 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766377093; bh=J7O/3g/+KWt0JWr2EM0oU20HVbA+mIaLRaYlefOY8Jw=; h=From:To:Cc:Subject:Date:From; b=U3twCqJdN/jeHO8oIGOm73/qNRKc8efF5g4v1cH3a/7nGsZMGacwk0svixJMc6QK1 ZKtf3r+dKXvctkfXbS9Ns9feZ/w5WaBqoSIXO+0k+IAB1C5kuT0Zku94PXGCoopHaj JyNiduamtSE7XPZHfXGvCewST9dH7Y5z7uiSzhCVYx7NCHTFDVUcUHL3s0PiITgjcH q6r16TXbkbt19yhv5AjhoWdGAajMWgQQ1MT0WxOyWoiQHfhIjFV2qm2rLGwhEn28Oi uvmJFlt00Nskfxu3EFRbUwJd5T7y06zUWDxOdI0SnYTgFxadBcZSDpmrtaY/m3R6p7 ptIYh4v9jLSjw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4113A64D27; Sun, 21 Dec 2025 21:18:13 -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 PrS4LWnZRvZG; Sun, 21 Dec 2025 21:18:13 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766377092; bh=J3WU87hd2A9ra6Y6+ecxX406zxFuytGr6tPevl6ix1M=; h=From:To:Cc:Subject:Date:From; b=Jqme1geHpJAsGKdLltLD7kdfViFk5dsJU81EZ1jREhnwl7C66EUIbSpcLtKMkkuOp oSWbX7ykxccMTy3yCp7UOyWGJbVLrQzVrlNRQ860xluHIXal+WBZa3Vb4hh53uzHwF nWBfsbmLJsMzBXVckekdwU5IceCLwI3+yi0cX74sf/m29gd9ocJuyZ47a0/Fsu1bsh o6qPYrx8tU6Q2egc0KTMCdm8enJem41iDTLIvy0wb0LMGSGFIECszslXJ2/e6+ahEM qvtfNi/hw3AyBrhf3xdQbop0zRfomN+MllxCZtE5wnwl6Kr5YT5VI77Au9ruoDf3Jl WrjYUHTLUvneQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 8FBBF64CD1; Sun, 21 Dec 2025 21:18:12 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Sun, 21 Dec 2025 21:18:04 -0700 Message-ID: <20251222041805.3157330-1-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Message-ID-Hash: T4JZVHVRKTS5BAE4QT5GJLHMKLFQFURL X-Message-ID-Hash: T4JZVHVRKTS5BAE4QT5GJLHMKLFQFURL 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: Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH] buildman: Add tests for bsettings.py 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_bsettings.py with 12 tests to achieve 100% coverage for bsettings.py Co-developed-by: Claude Signed-off-by: Simon Glass --- tools/buildman/main.py | 3 +- tools/buildman/test_bsettings.py | 143 +++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 tools/buildman/test_bsettings.py diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 9483e12e5d0..3c9820b262a 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -42,6 +42,7 @@ def run_tests(skip_net_tests, debug, verbose, args): from buildman import func_test from buildman import test from buildman import test_boards + from buildman import test_bsettings test_name = args.terms and args.terms[0] or None if skip_net_tests: @@ -52,7 +53,7 @@ def run_tests(skip_net_tests, debug, verbose, args): result = test_util.run_test_suites( 'buildman', debug, verbose, False, False, args.threads, test_name, [], [test.TestBuild, func_test.TestFunctional, test_boards.TestBoards, - 'buildman.toolchain']) + test_bsettings.TestBsettings, 'buildman.toolchain']) return (0 if result.wasSuccessful() else 1) diff --git a/tools/buildman/test_bsettings.py b/tools/buildman/test_bsettings.py new file mode 100644 index 00000000000..524281f49b0 --- /dev/null +++ b/tools/buildman/test_bsettings.py @@ -0,0 +1,143 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2024 Google, Inc + +"""Tests for bsettings.py""" + +import os +import tempfile +import unittest +from unittest import mock + +from buildman import bsettings + + +class TestBsettings(unittest.TestCase): + """Test bsettings module""" + + def setUp(self): + self._tmpdir = tempfile.mkdtemp() + + def tearDown(self): + import shutil + shutil.rmtree(self._tmpdir) + + def test_setup_no_file(self): + """Test setup() with fname=None (no config file)""" + bsettings.setup(None) + # Should not raise, settings should be empty + self.assertEqual([], bsettings.get_items('nonexistent')) + + def test_setup_default_missing(self): + """Test setup() creates config when default file missing""" + # Use a non-existent path for HOME + fake_home = os.path.join(self._tmpdir, 'fakehome') + os.makedirs(fake_home) + config_file = os.path.join(fake_home, '.buildman') + + with mock.patch.dict(os.environ, {'HOME': fake_home}): + with mock.patch('builtins.print'): + bsettings.setup('') + + # Config file should have been created + self.assertTrue(os.path.exists(config_file)) + + def test_setup_existing_file(self): + """Test setup() reads existing config file""" + config_file = os.path.join(self._tmpdir, 'test.buildman') + with open(config_file, 'w') as f: + f.write('[toolchain]\narm = /opt/arm\n') + + bsettings.setup(config_file) + items = bsettings.get_items('toolchain') + self.assertEqual([('arm', '/opt/arm')], items) + + def test_add_file(self): + """Test add_file() adds config data""" + bsettings.setup(None) + bsettings.add_file('[test]\nkey = value\n') + items = bsettings.get_items('test') + self.assertEqual([('key', 'value')], items) + + def test_add_section(self): + """Test add_section() creates new section""" + bsettings.setup(None) + bsettings.add_section('newsection') + # Section should exist but be empty + self.assertEqual([], bsettings.get_items('newsection')) + + def test_get_items_missing_section(self): + """Test get_items() returns empty list for missing section""" + bsettings.setup(None) + self.assertEqual([], bsettings.get_items('nonexistent')) + + def test_get_items_other_error(self): + """Test get_items() re-raises non-NoSectionError exceptions""" + bsettings.setup(None) + with mock.patch.object(bsettings.settings, 'items', + side_effect=ValueError('test error')): + with self.assertRaises(ValueError): + bsettings.get_items('test') + + def test_get_global_item_value(self): + """Test get_global_item_value() retrieves global items""" + bsettings.setup(None) + bsettings.add_file('[global]\nmykey = myvalue\n') + self.assertEqual('myvalue', bsettings.get_global_item_value('mykey')) + self.assertIsNone(bsettings.get_global_item_value('missing')) + + def test_set_item(self): + """Test set_item() sets value and writes to file""" + config_file = os.path.join(self._tmpdir, 'test_set.buildman') + with open(config_file, 'w') as f: + f.write('[toolchain]\n') + + bsettings.setup(config_file) + bsettings.set_item('toolchain', 'newkey', 'newvalue') + + # Value should be set in memory + items = dict(bsettings.get_items('toolchain')) + self.assertEqual('newvalue', items['newkey']) + + # Value should be written to file + with open(config_file) as f: + content = f.read() + self.assertIn('newkey', content) + self.assertIn('newvalue', content) + + def test_set_item_no_file(self): + """Test set_item() when config_fname is None""" + # Explicitly reset config_fname to None + bsettings.config_fname = None + bsettings.setup(None) + bsettings.add_section('test') + # Should not raise even though there's no file to write + bsettings.set_item('test', 'key', 'value') + items = dict(bsettings.get_items('test')) + self.assertEqual('value', items['key']) + + def test_create_buildman_config_file(self): + """Test create_buildman_config_file() creates valid config""" + config_file = os.path.join(self._tmpdir, 'new.buildman') + + bsettings.create_buildman_config_file(config_file) + + self.assertTrue(os.path.exists(config_file)) + with open(config_file) as f: + content = f.read() + self.assertIn('[toolchain]', content) + self.assertIn('[toolchain-prefix]', content) + self.assertIn('[toolchain-alias]', content) + self.assertIn('[make-flags]', content) + + def test_create_buildman_config_file_error(self): + """Test create_buildman_config_file() handles IOError""" + # Try to create file in non-existent directory + bad_path = '/nonexistent/path/config' + + with mock.patch('builtins.print'): + with self.assertRaises(IOError): + bsettings.create_buildman_config_file(bad_path) + + +if __name__ == '__main__': + unittest.main()