From patchwork Sun Jun 14 16:54:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 242328 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 14 Jun 2020 10:54:04 -0600 Subject: [PATCH 1/5] patman: Rename test.py to test_checkpatch.py In-Reply-To: <20200614165409.158795-1-sjg@chromium.org> References: <20200614165409.158795-1-sjg@chromium.org> Message-ID: <20200614165409.158795-2-sjg@chromium.org> These tests check checkpatch.pl operation and can server as our tests for the U-Boot-specific updates to that script. Rename the file and update comments to indicate this. Signed-off-by: Simon Glass --- tools/patman/main.py | 4 ++-- tools/patman/{test.py => test_checkpatch.py} | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) rename tools/patman/{test.py => test_checkpatch.py} (98%) diff --git a/tools/patman/main.py b/tools/patman/main.py index 0974c84059..4a11f80db5 100755 --- a/tools/patman/main.py +++ b/tools/patman/main.py @@ -25,7 +25,7 @@ from patman import patchstream from patman import project from patman import settings from patman import terminal -from patman import test +from patman import test_checkpatch parser = OptionParser() @@ -93,7 +93,7 @@ elif options.test: sys.argv = [sys.argv[0]] result = unittest.TestResult() - for module in (test.TestPatch, func_test.TestFunctional): + for module in (test_checkpatch.TestPatch, func_test.TestFunctional): suite = unittest.TestLoader().loadTestsFromTestCase(module) suite.run(result) diff --git a/tools/patman/test.py b/tools/patman/test_checkpatch.py similarity index 98% rename from tools/patman/test.py rename to tools/patman/test_checkpatch.py index e7f709e34c..03ff576c9e 100644 --- a/tools/patman/test.py +++ b/tools/patman/test_checkpatch.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # SPDX-License-Identifier: GPL-2.0+ # +# Tests for U-Boot-specific checkpatch.pl features +# # Copyright (c) 2011 The Chromium OS Authors. # @@ -16,10 +18,7 @@ from patman import commit class TestPatch(unittest.TestCase): - """Test this program - - TODO: Write tests for the rest of the functionality - """ + """Test the u_boot_line() function in checkpatch.pl""" def testBasic(self): """Test basic filter operation""" From patchwork Sun Jun 14 16:54:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 242329 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 14 Jun 2020 10:54:05 -0600 Subject: [PATCH 2/5] patman: Add a test for the 'possible new uclass' check In-Reply-To: <20200614165409.158795-1-sjg@chromium.org> References: <20200614165409.158795-1-sjg@chromium.org> Message-ID: <20200614165409.158795-3-sjg@chromium.org> It is quite likely that the number of U-Boot-specific tests in checkpatch.pl will increase over time. We should have tests for these to avoid undefined behaviour and bugs being introduced, which might cause people to ignore the warnings. Add a simple new class that can generate a patch with a single-line addition in it. Use that to add a test for one of the checkpatch checks. Signed-off-by: Simon Glass --- tools/patman/test_checkpatch.py | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py index 03ff576c9e..e841b9abca 100644 --- a/tools/patman/test_checkpatch.py +++ b/tools/patman/test_checkpatch.py @@ -17,6 +17,74 @@ from patman import series from patman import commit +class Line: + def __init__(self, fname, text): + self.fname = fname + self.text = text + + +class PatchMaker: + def __init__(self): + self.lines = [] + + def add_line(self, fname, text): + self.lines.append(Line(fname, text)) + + def get_patch_text(self): + base = '''From 125b77450f4c66b8fd9654319520bbe795c9ef31 Mon Sep 17 00:00:00 2001 +From: Simon Glass +Date: Sun, 14 Jun 2020 09:45:14 -0600 +Subject: [PATCH] Test commit + +This is a test commit. + +Signed-off-by: Simon Glass +--- + +''' + lines = base.splitlines() + + # Create the diffstat + change = 0 + insert = 0 + for line in self.lines: + lines.append(' %s | 1 +' % line.fname) + change += 1 + insert += 1 + lines.append(' %d files changed, %d insertions(+)' % (change, insert)) + lines.append('') + + # Create the patch info for each file + for line in self.lines: + lines.append('diff --git a/%s b/%s' % (line.fname, line.fname)) + lines.append('index 7837d459f18..5ba7840f68e 100644') + lines.append('--- a/%s' % line.fname) + lines.append('+++ b/%s' % line.fname) + lines += ('''@@ -121,6 +121,7 @@ enum uclass_id { + UCLASS_W1, /* Dallas 1-Wire bus */ + UCLASS_W1_EEPROM, /* one-wire EEPROMs */ + UCLASS_WDT, /* Watchdog Timer driver */ ++%s + + UCLASS_COUNT, + UCLASS_INVALID = -1, +''' % line.text).splitlines() + lines.append('---') + lines.append('2.17.1') + + return '\n'.join(lines) + + def get_patch(self): + inhandle, inname = tempfile.mkstemp() + infd = os.fdopen(inhandle, 'w') + infd.write(self.get_patch_text()) + infd.close() + return inname + + def run_checkpatch(self): + return checkpatch.CheckPatch(self.get_patch()) + + class TestPatch(unittest.TestCase): """Test the u_boot_line() function in checkpatch.pl""" @@ -280,6 +348,15 @@ index 0000000..2234c87 self.assertEqual(result.lines, 62) os.remove(inf) + def testUclass(self): + """Test for possible new uclass""" + pm = PatchMaker() + pm.add_line('include/dm/uclass-id.h', 'UCLASS_WIBBLE,') + result = pm.run_checkpatch() + self.assertEqual(result.warnings, 1) + self.assertEqual(len(result.problems), 1) + self.assertIn('Possible new uclass', result.problems[0]['msg']) + if __name__ == "__main__": unittest.main() From patchwork Sun Jun 14 16:54:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 242332 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 14 Jun 2020 10:54:06 -0600 Subject: [PATCH 3/5] patman: Decode output from the '--show-types' option In-Reply-To: <20200614165409.158795-1-sjg@chromium.org> References: <20200614165409.158795-1-sjg@chromium.org> Message-ID: <20200614165409.158795-4-sjg@chromium.org> Collect the 'checkpatch type' from each error, warning and check. Provide this to patman and update the uclass test to use it. Signed-off-by: Simon Glass --- tools/patman/checkpatch.py | 24 +++++++++++++++--------- tools/patman/test_checkpatch.py | 4 ++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py index 98c63af1dd..07c3e2739a 100644 --- a/tools/patman/checkpatch.py +++ b/tools/patman/checkpatch.py @@ -38,7 +38,7 @@ def FindCheckPatch(): sys.exit('Cannot find checkpatch.pl - please put it in your ' + '~/bin directory or use --no-check') -def CheckPatch(fname, verbose=False): +def CheckPatch(fname, verbose=False, show_types=False): """Run checkpatch.pl on a file. Returns: @@ -64,8 +64,10 @@ def CheckPatch(fname, verbose=False): result.problems = [] chk = FindCheckPatch() item = {} - result.stdout = command.Output(chk, '--no-tree', fname, - raise_on_error=False) + args = [chk, '--no-tree'] + if show_types: + args.append('--show-types') + result.stdout = command.Output(*args, fname, raise_on_error=False) #pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE) #stdout, stderr = pipe.communicate() @@ -81,9 +83,10 @@ def CheckPatch(fname, verbose=False): ' checks, (\d+)') re_ok = re.compile('.*has no obvious style problems') re_bad = re.compile('.*has style problems, please review') - re_error = re.compile('ERROR: (.*)') - re_warning = re.compile(emacs_prefix + 'WARNING:(?:[A-Z_]+:)? (.*)') - re_check = re.compile('CHECK: (.*)') + type_name = '([A-Z_]+:)?' + re_error = re.compile('ERROR:%s (.*)' % type_name) + re_warning = re.compile(emacs_prefix + 'WARNING:%s (.*)' % type_name) + re_check = re.compile('CHECK:%s (.*)' % type_name) re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):') re_note = re.compile('NOTE: (.*)') indent = ' ' * 6 @@ -129,13 +132,16 @@ def CheckPatch(fname, verbose=False): check_match = re_check.match(line) subject_match = line.startswith('Subject:') if err_match: - item['msg'] = err_match.group(1) + item['cptype'] = err_match.group(1) + item['msg'] = err_match.group(2) item['type'] = 'error' elif warn_match: - item['msg'] = warn_match.group(1) + item['cptype'] = warn_match.group(1) + item['msg'] = warn_match.group(2) item['type'] = 'warning' elif check_match: - item['msg'] = check_match.group(1) + item['cptype'] = check_match.group(1) + item['msg'] = check_match.group(2) item['type'] = 'check' elif file_match: item['file'] = file_match.group(1) diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py index e841b9abca..7f40133b33 100644 --- a/tools/patman/test_checkpatch.py +++ b/tools/patman/test_checkpatch.py @@ -82,7 +82,7 @@ Signed-off-by: Simon Glass return inname def run_checkpatch(self): - return checkpatch.CheckPatch(self.get_patch()) + return checkpatch.CheckPatch(self.get_patch(), show_types=True) class TestPatch(unittest.TestCase): @@ -355,7 +355,7 @@ index 0000000..2234c87 result = pm.run_checkpatch() self.assertEqual(result.warnings, 1) self.assertEqual(len(result.problems), 1) - self.assertIn('Possible new uclass', result.problems[0]['msg']) + self.assertIn('NEW_UCLASS', result.problems[0]['cptype']) if __name__ == "__main__": From patchwork Sun Jun 14 16:54:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 242330 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 14 Jun 2020 10:54:07 -0600 Subject: [PATCH 4/5] patman: Add tests for the rest of the checkpatch checks In-Reply-To: <20200614165409.158795-1-sjg@chromium.org> References: <20200614165409.158795-1-sjg@chromium.org> Message-ID: <20200614165409.158795-5-sjg@chromium.org> Finish off the tests for our small collection of checkpatch checks. Signed-off-by: Simon Glass --- tools/patman/test_checkpatch.py | 47 ++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py index 7f40133b33..710b4a7d88 100644 --- a/tools/patman/test_checkpatch.py +++ b/tools/patman/test_checkpatch.py @@ -348,14 +348,53 @@ index 0000000..2234c87 self.assertEqual(result.lines, 62) os.remove(inf) + def checkSingleMessage(self, pm, msg, pmtype = 'warning'): + """Helper function to run checkpatch and check the result + + Args: + pm: PatchMaker object to use + msg" Expected message (e.g. 'LIVETREE') + pmtype: Type of problem ('error', 'warning') + """ + result = pm.run_checkpatch() + if pmtype == 'warning': + self.assertEqual(result.warnings, 1) + elif pmtype == 'error': + self.assertEqual(result.errors, 1) + if len(result.problems) != 1: + print(result.problems) + self.assertEqual(len(result.problems), 1) + self.assertIn(msg, result.problems[0]['cptype']) + def testUclass(self): """Test for possible new uclass""" pm = PatchMaker() pm.add_line('include/dm/uclass-id.h', 'UCLASS_WIBBLE,') - result = pm.run_checkpatch() - self.assertEqual(result.warnings, 1) - self.assertEqual(len(result.problems), 1) - self.assertIn('NEW_UCLASS', result.problems[0]['cptype']) + self.checkSingleMessage(pm, 'NEW_UCLASS') + + def testLivetree(self): + """Test for Use the livetree API""" + pm = PatchMaker() + pm.add_line('common/main.c', 'fdtdec_do_something()') + self.checkSingleMessage(pm, 'LIVETREE') + + def testNewCommand(self): + """Test for Use the livetree API""" + pm = PatchMaker() + pm.add_line('common/main.c', 'do_wibble(struct cmd_tbl *cmd_tbl)') + self.checkSingleMessage(pm, 'CMD_TEST') + + def testNewCommand(self): + """Test for Use the livetree API""" + pm = PatchMaker() + pm.add_line('common/main.c', '#ifdef CONFIG_YELLOW') + self.checkSingleMessage(pm, "PREFER_IF") + + def testCommandUseDefconfig(self): + """Test for Use the livetree API""" + pm = PatchMaker() + pm.add_line('common/main.c', '#undef CONFIG_CMD_WHICH') + self.checkSingleMessage(pm, 'DEFINE_CONFIG_CMD', 'error') if __name__ == "__main__": From patchwork Sun Jun 14 16:54:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 242331 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 14 Jun 2020 10:54:08 -0600 Subject: [PATCH 5/5] checkpatch: Don't warn about PREFER_IF in headers/DT files In-Reply-To: <20200614165409.158795-1-sjg@chromium.org> References: <20200614165409.158795-1-sjg@chromium.org> Message-ID: <20200614165409.158795-6-sjg@chromium.org> This warning should only be displayed for C files. Fix it and update the test. Signed-off-by: Simon Glass --- scripts/checkpatch.pl | 2 +- tools/patman/test_checkpatch.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index edba365651..5731cd221e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2263,7 +2263,7 @@ sub u_boot_line { } # use if instead of #if - if ($line =~ /^\+#if.*CONFIG.*/) { + if ($realfile =~ /\.c$/ && $line =~ /^\+#if.*CONFIG.*/) { WARN("PREFER_IF", "Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' where possible\n" . $herecurr); } diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py index 710b4a7d88..c9580adb54 100644 --- a/tools/patman/test_checkpatch.py +++ b/tools/patman/test_checkpatch.py @@ -388,6 +388,8 @@ index 0000000..2234c87 """Test for Use the livetree API""" pm = PatchMaker() pm.add_line('common/main.c', '#ifdef CONFIG_YELLOW') + pm.add_line('common/init.h', '#ifdef CONFIG_YELLOW') + pm.add_line('fred.dtsi', '#ifdef CONFIG_YELLOW') self.checkSingleMessage(pm, "PREFER_IF") def testCommandUseDefconfig(self):