From d4ccdfdcdc07fcecb9ff4ec0075a82f0001753dc Mon Sep 17 00:00:00 2001 From: warner Date: Tue, 19 Sep 2006 23:07:47 +0100 Subject: [PATCH] improve PyFlakes, add a unit test --- ChangeLog | 6 +++++ buildbot/steps/python.py | 58 ++++++++++++++++++++------------------------- buildbot/test/test_steps.py | 50 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 80 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a41031..a73c9aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2006-09-19 Brian Warner + + * buildbot/steps/python.py (PyFlakes): refactor, add summary logs + * buildbot/test/test_steps.py (Python.testPyFlakes): add a test + for at least the output-parsing parts of PyFlakes + 2006-09-18 Brian Warner * buildbot/steps/python.py: oops, fix import of StringIO diff --git a/buildbot/steps/python.py b/buildbot/steps/python.py index e0e9c5f..2c35818 100644 --- a/buildbot/steps/python.py +++ b/buildbot/steps/python.py @@ -54,53 +54,47 @@ class PyFlakes(ShellCommand): description = ["running", "pyflakes"] descriptionDone = ["pyflakes"] flunkOnFailure = False + flunkingIssues = ["undefined"] # any pyflakes lines like this cause FAILURE + + MESSAGES = ("unused", "undefined", "redefs", "import*", "misc") def createSummary(self, log): - unused_imports = 0 - undefined_names = 0 - redefinition_of_unused = 0 - star_import = 0 - misc = 0 - total = 0 + counts = {} + summaries = {} + for m in self.MESSAGES: + counts[m] = 0 + summaries[m] = [] for line in StringIO(log.getText()).readlines(): if "imported but unused" in line: - unused_imports += 1 + m = "unused" + elif "*' used; unable to detect undefined names" in line: + m = "import*" elif "undefined name" in line: - undefined_names += 1 + m = "undefined" elif "redefinition of unused" in line: - redefinition_of_unused += 1 - elif "*' used; unable to detect undefined names": - star_import += 1 + m = "redefs" else: - misc += 1 - total += 1 + m = "misc" + summaries[m].append(line) + counts[m] += 1 self.descriptionDone = self.descriptionDone[:] - if unused_imports: - self.descriptionDone.append("unused=%d" % unused_imports) - if undefined_names: - self.descriptionDone.append("undefined=%s" % undefined_names) - if redefinition_of_unused: - self.descriptionDone.append("redefs=%s" % redefinition_of_unused) - if star_import: - self.descriptionDone.append("import*=%s" % star_import) - if misc: - self.descriptionDone.append("misc=%s" % misc) - self.num_warnings = total - - self.setProperty("pyflakes-unused", unused_imports) - self.setProperty("pyflakes-undefined", undefined_names) - self.setProperty("pyflakes-redefinitions", redefinition_of_unused) - self.setProperty("pyflakes-import*", star_import) - self.setProperty("pyflakes-misc", misc) - self.setProperty("pyflakes-total", total) + for m in self.MESSAGES: + if counts[m]: + self.descriptionDone.append("%s=%d" % (m, counts[m])) + self.addCompleteLog(m, "".join(summaries[m])) + self.setProperty("pyflakes-%s" % m, counts[m]) + self.setProperty("pyflakes-total", sum(counts.values())) def evaluateCommand(self, cmd): if cmd.rc != 0: return FAILURE - if self.num_warnings: + for m in self.flunkingIssues: + if self.getProperty("pyflakes-%s" % m): + return FAILURE + if self.getProperty("pyflakes-total"): return WARNINGS return SUCCESS diff --git a/buildbot/test/test_steps.py b/buildbot/test/test_steps.py index e69f9a6..f143291 100644 --- a/buildbot/test/test_steps.py +++ b/buildbot/test/test_steps.py @@ -21,9 +21,9 @@ from twisted.internet import reactor, defer from buildbot.sourcestamp import SourceStamp from buildbot.process import buildstep, base, factory -from buildbot.steps import shell, source +from buildbot.steps import shell, source, python from buildbot.status import builder -from buildbot.status.builder import SUCCESS +from buildbot.status.builder import SUCCESS, FAILURE from buildbot.test.runutils import RunMixin, rmtree from buildbot.test.runutils import makeBuildStep, StepTester from buildbot.twcompat import maybeWait @@ -392,3 +392,49 @@ class CheckStepTester(StepTester, unittest.TestCase): self.failUnlessEqual(sb.flag_args, {"arg1": "value"}) d.addCallback(_checkSimple) return maybeWait(d) + +class Python(StepTester, unittest.TestCase): + def testPyFlakes(self): + self.masterbase = "Python.master" + step = self.makeStep(python.PyFlakes) + output = \ +"""buildbot/changes/freshcvsmail.py:5: 'FCMaildirSource' imported but unused +buildbot/clients/debug.py:9: redefinition of unused 'gtk' from line 9 +buildbot/clients/debug.py:9: 'gnome' imported but unused +buildbot/scripts/runner.py:323: redefinition of unused 'run' from line 321 +buildbot/scripts/runner.py:325: redefinition of unused 'run' from line 323 +buildbot/scripts/imaginary.py:12: undefined name 'size' +buildbot/scripts/imaginary.py:18: 'from buildbot import *' used; unable to detect undefined names +""" + log = step.addLog("stdio") + log.addStdout(output) + log.finish() + step.createSummary(log) + desc = step.descriptionDone + self.failUnless("unused=2" in desc) + self.failUnless("undefined=1" in desc) + self.failUnless("redefs=3" in desc) + self.failUnless("import*=1" in desc) + + self.failUnlessEqual(step.getProperty("pyflakes-unused"), 2) + self.failUnlessEqual(step.getProperty("pyflakes-undefined"), 1) + self.failUnlessEqual(step.getProperty("pyflakes-redefs"), 3) + self.failUnlessEqual(step.getProperty("pyflakes-import*"), 1) + self.failUnlessEqual(step.getProperty("pyflakes-misc"), 0) + self.failUnlessEqual(step.getProperty("pyflakes-total"), 7) + + logs = {} + for log in step.step_status.getLogs(): + logs[log.getName()] = log + + for name in ["unused", "undefined", "redefs", "import*"]: + self.failUnless(name in logs) + self.failIf("misc" in logs) + lines = logs["unused"].readlines() + self.failUnlessEqual(len(lines), 2) + self.failUnlessEqual(lines[0], "buildbot/changes/freshcvsmail.py:5: 'FCMaildirSource' imported but unused\n") + + cmd = buildstep.RemoteCommand(None, {}) + cmd.rc = 0 + results = step.evaluateCommand(cmd) + self.failUnlessEqual(results, FAILURE) # because of the 'undefined' -- 2.11.4.GIT