Repository: buildbot/buildbot

Issue:
minor fix for influxdb
- fix documenation for CaptureBuildDurationAllBuilders
- fix when influxdb python is not installed. 

```
2016-03-16 11:08:01+0100 [-] error while parsing config file:
    Traceback (most recent call last):
      File "/home/xdelannoy/Projects/prototype/env/local/lib/python2.7/site-packages/Twisted-15.5.0-py2.7-linux-x86_64.egg/twisted/python/threadpool.py", line 246, in inContext
        result = inContext.theWork()
      File "/home/xdelannoy/Projects/prototype/env/local/lib/python2.7/site-packages/Twisted-15.5.0-py2.7-linux-x86_64.egg/twisted/python/threadpool.py", line 262, in <lambda>
        inContext.theWork = lambda: context.call(ctx, func, *args, **kw)
      File "/home/xdelannoy/Projects/prototype/env/local/lib/python2.7/site-packages/Twisted-15.5.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 118, in callWithContext
        return self.currentContext().callWithContext(ctx, func, *args, **kw)
      File "/home/xdelannoy/Projects/prototype/env/local/lib/python2.7/site-packages/Twisted-15.5.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 81, in callWithContext
        return func(*args,**kw)
    --- <exception caught here> ---
      File "/home/xdelannoy/Projects/myGitHub/buildbot-work/src/master/buildbot/config.py", line 204, in loadConfig
        exec(f, localDict)
      File "/home/xdelannoy/Projects/prototype/basedir/master.cfg", line 10, in <module>
        from config import services
      File "config/services.py", line 24, in <module>
        InfluxStorageService('localhost', 8086, 'root', 'root', 'test', captures)
      File "/home/xdelannoy/Projects/myGitHub/buildbot-work/src/master/buildbot/statistics/storage_backends/influxdb_client.py", line 46, in __init__
        self.password, self.db)
    exceptions.TypeError: 'NoneType' object is not callable
```



Discussion:

Resolving patch:
diff --git a/master/buildbot/steps/python.py b/master/buildbot/steps/python.py
--- a/master/buildbot/steps/python.py
+++ b/master/buildbot/steps/python.py
@@ -166,8 +166,8 @@ class PyLint(ShellCommand):
 
     _re_groupname = 'errtype'
     _msgtypes_re_str = '(?P<%s>[%s])' % (_re_groupname, ''.join(MESSAGES.keys()))
-    _default_line_re = re.compile(r'^%s: *\d+:.+' % _msgtypes_re_str)
-    _parseable_line_re = re.compile(r'[^:]+:\d+: \[%s[,\]] .+' % _msgtypes_re_str)
+    _default_line_re = re.compile(r'^%s(\d{4})?: *\d+(,\d+)?:.+' % _msgtypes_re_str)
+    _parseable_line_re = re.compile(r'[^:]+:\d+: \[%s(\d{4})?[,\]] .+' % _msgtypes_re_str)
 
     def createSummary(self, log):
         counts = {}


Test patch:
diff --git a/master/buildbot/test/unit/test_steps_python.py b/master/buildbot/test/unit/test_steps_python.py
--- a/master/buildbot/test/unit/test_steps_python.py
+++ b/master/buildbot/test/unit/test_steps_python.py
@@ -15,7 +15,7 @@
 
 from twisted.trial import unittest
 
-from buildbot.status.results import FAILURE, SUCCESS
+from buildbot.status.results import FAILURE, SUCCESS, WARNINGS
 from buildbot.steps import python
 from buildbot.test.fake.remotecommand import ExpectShell
 from buildbot.test.util import steps
@@ -93,3 +93,113 @@ def test_failure_zero_returncode(self):
         self.expectProperty('pylint-error', 1)
         return self.runStep()
 
+    def test_regex_text(self):
+        self.setupStep(python.PyLint(command=['pylint']))
+        self.expectCommands(
+            ExpectShell(workdir='wkdir', command=['pylint'],
+                        usePTY='slave-config')
+            + ExpectShell.log(
+                'stdio',
+                stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
+                        'C:  1:foo123: Missing docstring\n'))
+            + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
+        self.expectOutcome(result=WARNINGS,
+                           status_text=['pylint', 'convention=1', 'warning=1',
+                                        'warnings'])
+        self.expectProperty('pylint-warning', 1)
+        self.expectProperty('pylint-convention', 1)
+        self.expectProperty('pylint-total', 2)
+        return self.runStep()
+
+    def test_regex_text_0_24(self):
+        # pylint >= 0.24.0 prints out column offsets when using text format
+        self.setupStep(python.PyLint(command=['pylint']))
+        self.expectCommands(
+            ExpectShell(workdir='wkdir', command=['pylint'],
+                        usePTY='slave-config')
+            + ExpectShell.log(
+                'stdio',
+                stdout=('W: 11,0: Bad indentation. Found 6 spaces, expected 4\n'
+                        'C:  3,10:foo123: Missing docstring\n'))
+            + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
+        self.expectOutcome(result=WARNINGS,
+                           status_text=['pylint', 'convention=1', 'warning=1',
+                                        'warnings'])
+        self.expectProperty('pylint-warning', 1)
+        self.expectProperty('pylint-convention', 1)
+        self.expectProperty('pylint-total', 2)
+        return self.runStep()
+
+    def test_regex_text_ids(self):
+        self.setupStep(python.PyLint(command=['pylint']))
+        self.expectCommands(
+            ExpectShell(workdir='wkdir', command=['pylint'],
+                        usePTY='slave-config')
+            + ExpectShell.log(
+                'stdio',
+                stdout=('W0311: 11: Bad indentation.\n'
+                        'C0111:  1:funcName: Missing docstring\n'))
+            + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
+        self.expectOutcome(result=WARNINGS,
+                           status_text=['pylint', 'convention=1', 'warning=1',
+                                        'warnings'])
+        self.expectProperty('pylint-warning', 1)
+        self.expectProperty('pylint-convention', 1)
+        self.expectProperty('pylint-total', 2)
+        return self.runStep()
+
+    def test_regex_text_ids_0_24(self):
+        # pylint >= 0.24.0 prints out column offsets when using text format
+        self.setupStep(python.PyLint(command=['pylint']))
+        self.expectCommands(
+            ExpectShell(workdir='wkdir', command=['pylint'],
+                        usePTY='slave-config')
+            + ExpectShell.log(
+                'stdio',
+                stdout=('W0311: 11,0: Bad indentation.\n'
+                        'C0111:  3,10:foo123: Missing docstring\n'))
+            + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
+        self.expectOutcome(result=WARNINGS,
+                           status_text=['pylint', 'convention=1', 'warning=1',
+                                        'warnings'])
+        self.expectProperty('pylint-warning', 1)
+        self.expectProperty('pylint-convention', 1)
+        self.expectProperty('pylint-total', 2)
+        return self.runStep()
+
+    def test_regex_parseable_ids(self):
+        self.setupStep(python.PyLint(command=['pylint']))
+        self.expectCommands(
+            ExpectShell(workdir='wkdir', command=['pylint'],
+                        usePTY='slave-config')
+            + ExpectShell.log(
+                'stdio',
+                stdout=('test.py:9: [W0311] Bad indentation.\n'
+                        'test.py:3: [C0111, foo123] Missing docstring\n'))
+            + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
+        self.expectOutcome(result=WARNINGS,
+                           status_text=['pylint', 'convention=1', 'warning=1',
+                                        'warnings'])
+        self.expectProperty('pylint-warning', 1)
+        self.expectProperty('pylint-convention', 1)
+        self.expectProperty('pylint-total', 2)
+        return self.runStep()
+
+    def test_regex_parseable(self):
+        self.setupStep(python.PyLint(command=['pylint']))
+        self.expectCommands(
+            ExpectShell(workdir='wkdir', command=['pylint'],
+                        usePTY='slave-config')
+            + ExpectShell.log(
+                'stdio',
+                stdout=('test.py:9: [W] Bad indentation.\n'
+                        'test.py:3: [C, foo123] Missing docstring\n'))
+            + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
+        self.expectOutcome(result=WARNINGS,
+                           status_text=['pylint', 'convention=1', 'warning=1',
+                                        'warnings'])
+        self.expectProperty('pylint-warning', 1)
+        self.expectProperty('pylint-convention', 1)
+        self.expectProperty('pylint-total', 2)
+        return self.runStep()
+