[Buildbot-commits] buildbot/docs buildbot.texinfo,1.54,1.55

Brian Warner warner at users.sourceforge.net
Thu Jun 15 05:47:57 UTC 2006


Update of /cvsroot/buildbot/buildbot/docs
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv30797/docs

Modified Files:
	buildbot.texinfo 
Log Message:
[project @ add user's manual sections on LogObservers, writing status plugins]

Original author: warner at lothar.com
Date: 2006-06-15 01:30:52

Index: buildbot.texinfo
===================================================================
RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- buildbot.texinfo	12 Jun 2006 08:36:08 -0000	1.54
+++ buildbot.texinfo	15 Jun 2006 05:47:55 -0000	1.55
@@ -142,6 +142,7 @@
 * Source Checkout::             
 * ShellCommand::                
 * Simple ShellCommand Subclasses::  
+* Writing New BuildSteps::      
 
 Source Checkout
 
@@ -158,9 +159,12 @@
 * Configure::                   
 * Compile::                     
 * Test::                        
-* Writing New BuildSteps::      
 * Build Properties::            
 
+Writing New BuildSteps
+
+* Adding LogObservers::         
+
 Build Factories
 
 * BuildStep Objects::           
@@ -184,6 +188,7 @@
 * HTML Waterfall::              
 * IRC Bot::                     
 * PBListener::                  
+* Writing New Status Plugins::  
 
 Command-line tool
 
@@ -2509,7 +2514,7 @@
 @end table
 
 
- at node P4Source, , PBChangeSource, Change Sources
+ at node P4Source,  , PBChangeSource, Change Sources
 @subsection P4Source
 
 The @code{P4Source} periodically polls a @uref{http://www.perforce.com/,
@@ -2623,6 +2628,7 @@
 * Source Checkout::             
 * ShellCommand::                
 * Simple ShellCommand Subclasses::  
+* Writing New BuildSteps::      
 @end menu
 
 @node Common Parameters, Source Checkout, Build Steps, Build Steps
@@ -3181,7 +3187,7 @@
 
 @end table
 
- at node Simple ShellCommand Subclasses,  , ShellCommand, Build Steps
+ at node Simple ShellCommand Subclasses, Writing New BuildSteps, ShellCommand, Build Steps
 @subsection Simple ShellCommand Subclasses
 
 Several subclasses of ShellCommand are provided as starting points for
@@ -3193,7 +3199,6 @@
 * Configure::                   
 * Compile::                     
 * Test::                        
-* Writing New BuildSteps::      
 * Build Properties::            
 @end menu
 
@@ -3214,7 +3219,7 @@
 created with any problems that were seen (TODO: the summary is not yet
 created).
 
- at node Test, Writing New BuildSteps, Compile, Simple ShellCommand Subclasses
+ at node Test, Build Properties, Compile, Simple ShellCommand Subclasses
 @subsubsection Test
 
 This is meant to handle unit tests. The default command is @code{make
@@ -3222,28 +3227,7 @@
 
 
 
-
-
- at node Writing New BuildSteps, Build Properties, Test, Simple ShellCommand Subclasses
- at subsubsection Writing New BuildSteps
-
-While it is a good idea to keep your build process self-contained in
-the source code tree, sometimes it is convenient to put more
-intelligence into your Buildbot configuration. One was to do this is
-to write a custom BuildStep. Once written, this Step can be used in
-the @file{master.cfg} file.
-
-The best reason for writing a custom BuildStep is to better parse the
-results of the command being run. For example, a BuildStep that knows
-about JUnit could look at the logfiles to determine which tests had
-been run, how many passed and how many failed, and then report more
-detailed information than a simple @code{rc==0} -based ``good/bad''
-decision.
-
-TODO: add more description of BuildSteps.
-
-
- at node Build Properties,  , Writing New BuildSteps, Simple ShellCommand Subclasses
+ at node Build Properties,  , Test, Simple ShellCommand Subclasses
 @subsubsection Build Properties
 
 @cindex build properties
@@ -3394,6 +3378,126 @@
 @end table
 
 
+ at node Writing New BuildSteps,  , Simple ShellCommand Subclasses, Build Steps
+ at subsection Writing New BuildSteps
+
+While it is a good idea to keep your build process self-contained in
+the source code tree, sometimes it is convenient to put more
+intelligence into your Buildbot configuration. One was to do this is
+to write a custom BuildStep. Once written, this Step can be used in
+the @file{master.cfg} file.
+
+The best reason for writing a custom BuildStep is to better parse the
+results of the command being run. For example, a BuildStep that knows
+about JUnit could look at the logfiles to determine which tests had
+been run, how many passed and how many failed, and then report more
+detailed information than a simple @code{rc==0} -based ``good/bad''
+decision.
+
+TODO: add more description of BuildSteps.
+
+ at menu
+* Adding LogObservers::         
+ at end menu
+
+ at node Adding LogObservers,  , Writing New BuildSteps, Writing New BuildSteps
+ at subsubsection Adding LogObservers
+
+ at cindex LogObserver
+ at cindex LogLineObserver
+
+Most shell commands emit messages to stdout or stderr as they operate,
+especially if you ask them nicely with a @code{--verbose} flag of some
+sort. They may also write text to a log file while they run. Your
+BuildStep can watch this output as it arrives, to keep track of how
+much progress the command has made. You can get a better measure of
+progress by counting the number of source files compiled or test cases
+run than by merely tracking the number of bytes that have been written
+to stdout. This improves the accuracy and the smoothness of the ETA
+display.
+
+To accomplish this, you will need to attach a @code{LogObserver} to
+one of the log channels, most commonly to the ``stdio'' channel but
+perhaps to another one which tracks a log file. This observer is given
+all text as it is emitted from the command, and has the opportunity to
+parse that output incrementally. Once the observer has decided that
+some event has occurred (like a source file being compiled), it can
+use the @code{setProgress} method to tell the BuildStep about the
+progress that this event represents.
+
+There are a number of pre-built @code{LogObserver} classes that you
+can choose from, and of course you can subclass them to add further
+customization. The @code{LogLineObserver} class handles the grunt work
+of buffering and scanning for end-of-line delimiters, allowing your
+parser to operate on complete stdout/stderr lines.
+
+For example, let's take a look at the @code{TrialTestCaseCounter},
+which is used by the Trial step to count test cases as they are run.
+As Trial executes, it emits lines like the following:
+
+ at example
+buildbot.test.test_config.ConfigTest.testDebugPassword ... [OK]
+buildbot.test.test_config.ConfigTest.testEmpty ... [OK]
+buildbot.test.test_config.ConfigTest.testIRC ... [FAIL]
+buildbot.test.test_config.ConfigTest.testLocks ... [OK]
+ at end example
+
+When the tests are finished, trial emits a long line of ``======'' and
+then some lines which summarize the tests that failed. We want to
+avoid parsing these trailing lines, because their format is less
+well-defined than the ``[OK]'' lines.
+
+The parser class looks like this:
+
+ at example
+class TrialTestCaseCounter(step.LogLineObserver):
+    _line_re = re.compile(r'^([\w\.]+) \.\.\. \[([^\]]+)\]$')
+    numTests = 0
+    finished = False
+
+    def outLineReceived(self, line):
+        if self.finished:
+            return
+        if line.startswith("=" * 40):
+            self.finished = True
+            return
+
+        m = self._line_re.search(line.strip())
+        if m:
+            testname, result = m.groups()
+            self.numTests += 1
+            self.step.setProgress('tests', self.numTests)
+ at end example
+
+This parser only pays attention to stdout, since that's where trial
+writes the progress lines. It has a mode flag named @code{finished} to
+ignore everything after the ``===='' marker, and a scary-looking
+regular expression to match each line while hopefully ignoring other
+messages that might get displayed as the test runs.
+
+Each time it identifies a test has been completed, it increments its
+counter and delivers the new progress value to the step with
+ at code{self.step.setProgress}. This class is specifically measuring
+progress along the ``tests'' metric, in units of test cases (as
+opposed to other kinds of progress like the ``output'' metric, which
+measures in units of bytes). The Progress-tracking code uses each
+progress metric separately to come up with an overall completion
+percentage and an ETA value.
+
+To connect this parser into the @code{Trial} BuildStep,
+ at code{Trial.__init__} ends with the following clause:
+
+ at example
+        # this counter will feed Progress along the 'test cases' metric
+        counter = TrialTestCaseCounter()
+        self.addLogObserver('stdio', counter)
+ at end example
+
+This creates a TrialTestCaseCounter and tells the step to attach it to
+the ``stdio'' log. The observer is automatically given a reference to
+the step in its @code{.step} attribute.
+
+
 @node Interlocks, Build Factories, Build Steps, Build Process
 @section Interlocks
 
@@ -4068,10 +4172,11 @@
 * HTML Waterfall::              
 * IRC Bot::                     
 * PBListener::                  
+* Writing New Status Plugins::  
 @end menu
 
 @node HTML Waterfall, IRC Bot, Status Delivery, Status Delivery
- at subsection HTML Waterfall
+ at section HTML Waterfall
 
 @cindex Waterfall
 
@@ -4152,7 +4257,7 @@
 
 
 @node IRC Bot, PBListener, HTML Waterfall, Status Delivery
- at subsection IRC Bot
+ at section IRC Bot
 
 @cindex IRC
 
@@ -4221,8 +4326,8 @@
 before starting the second (hopefully fixed) build.
 @end table
 
- at node PBListener,  , IRC Bot, Status Delivery
- at subsection PBListener
+ at node PBListener, Writing New Status Plugins, IRC Bot, Status Delivery
+ at section PBListener
 
 @cindex PBListener
 
@@ -4239,6 +4344,34 @@
 status client. The @code{port} argument can also be a strports
 specification string.
 
+ at node Writing New Status Plugins,  , PBListener, Status Delivery
+ at section Writing New Status Plugins
+
+TODO: this needs a lot more examples
+
+Each status plugin is an object which provides the
+ at code{twisted.application.service.IService} interface, which creates a
+tree of Services with the buildmaster at the top [not strictly true].
+The status plugins are all children of an object which implements
+ at code{buildbot.interfaces.IStatus}, the main status object. From this
+object, the plugin can retrieve anything it wants about current and
+past builds. It can also subscribe to hear about new and upcoming
+builds.
+
+Status plugins which only react to human queries (like the Waterfall
+display) never need to subscribe to anything: they are idle until
+someone asks a question, then wake up and extract the information they
+need to answer it, then they go back to sleep. Plugins which need to
+act spontaneously when builds complete (like the Mail plugin) need to
+subscribe to hear about new builds.
+
+If the status plugin needs to run network services (like the HTTP
+server used by the Waterfall plugin), they can be attached as Service
+children of the plugin itself, using the @code{IServiceCollection}
+interface.
+
+
+
 @node Command-line tool, Resources, Status Delivery, Top
 @chapter Command-line tool
 





More information about the Commits mailing list