Mozilla BuildBot Trending/Patches

From CDOT Wiki
Revision as of 13:33, 7 February 2009 by John64 (talk | contribs)
Jump to: navigation, search

First attempt at timestamps

This patch can be applied to buildbot-0.7.9 to enable build-logs to use the format

1233811875.619101 | 'local-slave' | local-osx | 41 | pulling from http://hg.mozilla.org/mozilla-central/

1233811875.9946001 | 'local-slave' | local-osx | 41 | searching for changes

1233811878.362067 | 'local-slave' | local-osx | 41 | adding changesets

1233811878.373631 | 'local-slave' | local-osx | 41 | adding manifests

1233811878.7630169 | 'local-slave' | local-osx | 41 | adding file changes

1233811881.238174 | 'local-slave' | local-osx | 41 | added 2 changesets with 4 changes to 4 files

The format is unixtime | build slave name | builder name | build number | output
The patch is applied against http://downloads.sourceforge.net/buildbot/buildbot-0.7.9.tar.gz
File:Timestamp.patch.zip

diff -r a9c16958d5dc buildbot/buildbot/status/builder.py
--- a/buildbot/buildbot/status/builder.py	Thu Feb 05 00:37:33 2009 -0500
+++ b/buildbot/buildbot/status/builder.py	Thu Feb 05 00:39:45 2009 -0500
@@ -393,9 +393,9 @@
         self.length += len(text)
 
     def addStdout(self, text):
-        self.addEntry(STDOUT, text)
+        self.addEntry(STDOUT, repr(time()) + ' | ' + repr(self.getStep().build.slavename) + ' | ' + self.getStep().build.getBuilder().getName() + ' | ' + repr(self.getStep().build.getNumber()) + ' | ' + text + '\n')
     def addStderr(self, text):
-        self.addEntry(STDERR, text)
+        self.addEntry(STDERR, repr(time()) + ' | ' + repr(self.getStep().build.slavename) + ' | ' + self.getStep().build.getBuilder().getName() + ' | ' + repr(self.getStep().build.getNumber()) + ' | ' + text + '\n')
     def addHeader(self, text):
         self.addEntry(HEADER, text)
 

New Timestamps Patch

This patch, applied to the previous patch changes the behaviour of the timestamps. Instead of having all information on ever line it only puts a timestamp on each line. Information that is constant throughout the run are only inserted once

diff -r 9a6c6b742a5a buildbot/buildbot/status/builder.py
--- a/buildbot/buildbot/status/builder.py	Sat Feb 07 12:22:37 2009 -0500
+++ b/buildbot/buildbot/status/builder.py	Sat Feb 07 12:27:49 2009 -0500
@@ -6,6 +6,8 @@
 from twisted.internet import reactor, defer
 from twisted.protocols import basic
 from buildbot.process.properties import Properties
+# JOHNFORD
+from time import time
 
 import os, shutil, sys, re, urllib, itertools
 from cPickle import load, dump
@@ -232,6 +234,12 @@
         self.runEntries = []
         self.watchers = []
         self.finishedWatchers = []
+        # Add some information about the build to the log
+        self.addEntry(STDOUT, repr(time()) + ' | '
+                      + repr(self.getStep().build.slavename) + ' | ' 
+                      + self.getStep().build.getBuilder().getName() + ' | ' 
+                      + repr(self.getStep().build.getNumber()))# + ' | ' 
+                      #+ repr(getFilename()))
 
     def getFilename(self):
         return os.path.join(self.step.build.builder.basedir, self.filename)
@@ -391,11 +399,11 @@
         for w in self.watchers:
             w.logChunk(self.step.build, self.step, self, channel, text)
         self.length += len(text)
-
+    
     def addStdout(self, text):
-        self.addEntry(STDOUT, repr(time()) + ' | ' + repr(self.getStep().build.slavename) + ' | ' + self.getStep().build.getBuilder().getName() + ' | ' + repr(self.getStep().build.getNumber()) + ' | ' + text + '\n')
+        self.addEntry(STDOUT, repr(time()) + ' | ' + text)
     def addStderr(self, text):
-        self.addEntry(STDERR, repr(time()) + ' | ' + repr(self.getStep().build.slavename) + ' | ' + self.getStep().build.getBuilder().getName() + ' | ' + repr(self.getStep().build.getNumber()) + ' | ' + text + '\n')
+        self.addEntry(STDERR, repr(time()) + ' | ' + text)
     def addHeader(self, text):
         self.addEntry(HEADER, text)

MozBuild.py and Master.cfg

This patch adds my master.cfg I am using locally on my OSX machine and a modified mozbuild.py. Mozbuild.py contains all the buildbot steps used to test Mozilla. I have removed all non-OSX applicable code to minimize errors.

diff -r 9e48e21dd4f6 buildbot/buildbot.egg-info/SOURCES.txt
--- a/buildbot/buildbot.egg-info/SOURCES.txt	Thu Feb 05 00:39:57 2009 -0500
+++ b/buildbot/buildbot.egg-info/SOURCES.txt	Sat Feb 07 12:21:02 2009 -0500
@@ -16,6 +16,7 @@
 buildbot/locks.py
 buildbot/manhole.py
 buildbot/master.py
+buildbot/mozbuild.py
 buildbot/pbutil.py
 buildbot/scheduler.py
 buildbot/sourcestamp.py
diff -r 9e48e21dd4f6 buildbot/buildbot/mozbuild.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildbot/buildbot/mozbuild.py	Sat Feb 07 12:21:02 2009 -0500
@@ -0,0 +1,345 @@
+# -*- Python -*-
+
+from buildbot import steps
+from buildbot.steps.shell import ShellCommand
+from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, HEADER
+import re
+import os
+import copy
+
+MozillaEnvironments = { }
+
+MozillaEnvironments['osx'] = {
+    "MOZ_NO_REMOTE": '1',
+    "NO_EM_RESTART": '1',
+    "XPCOM_DEBUG_BREAK": 'warn',
+    "CVS_RSH": 'ssh'
+}
+
+
+
+class ShellCommandReportTimeout(ShellCommand):
+    """We subclass ShellCommand so that we can bubble up the timeout errors
+    to tinderbox that normally only get appended to the buildbot slave logs.
+    """
+
+    def evaluateCommand(self, cmd):
+        superResult = ShellCommand.evaluateCommand(self, cmd)
+        for line in cmd.logs['stdio'].readlines(channel=HEADER):
+            if "command timed out" in line:
+                self.addCompleteLog('timeout',
+                                    'buildbot.slave.commands.TimeoutError: ' +
+                                    line +
+                                    "TinderboxPrint: " +
+                                    self.name + ' <em class="testfail">timeout</em><br/>\n')
+                return WARNINGS
+        return superResult
+
+class CreateDir(ShellCommandReportTimeout):
+    name = "create dir"
+    haltOnFailure = False
+    warnOnFailure = True
+
+    def __init__(self, **kwargs):
+        if not 'platform' in kwargs:
+            return FAILURE
+        self.platform = kwargs['platform']
+        if 'dir' in kwargs:
+            self.dir = kwargs['dir']
+        if self.platform.startswith('win'):
+            self.command = r'if not exist ' + self.dir + r' mkdir ' + self.dir
+        else:
+            self.command = ['mkdir', '-p', self.dir]
+        ShellCommandReportTimeout.__init__(self, **kwargs)
+
+class TinderboxShellCommand(ShellCommand):
+    haltOnFailure = False
+    
+    def evaluateCommand(self, cmd):
+       return SUCCESS
+
+class MozillaCheck(ShellCommandReportTimeout):
+    name = "check"
+    warnOnFailure = True
+    description = ["checking"]
+    descriptionDone = ["check complete"]
+    command = ["make", "-k", "check"]
+   
+    def createSummary(self, log):
+        passCount = 0
+        failCount = 0
+        for line in log.readlines():
+            if "PASS" in line:
+                passCount = passCount + 1
+            if "FAIL" in line:
+                failCount = failCount + 1
+        summary = "TinderboxPrint: TUnit<br/>" + str(passCount) + "/" + str(failCount) + "\n"
+        self.addCompleteLog('summary', summary)
+    
+    def evaluateCommand(self, cmd):
+        superResult = ShellCommandReportTimeout.evaluateCommand(self, cmd)
+        if SUCCESS != superResult:
+            return WARNINGS
+        if None != re.search('FAIL', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        return SUCCESS
+    
+class MozillaReftest(ShellCommandReportTimeout):
+    warnOnFailure = True
+    name = "reftest"
+    description = ["reftest"]
+    descriptionDone = ["reftest complete"]
+   
+    def createSummary(self, log):
+        testCount = 0
+        passCount = 0
+        failCount = 0
+        knownFailCount = 0
+        for line in log.readlines():
+            if "REFTEST" not in line:
+                continue
+            if "IMAGE" in line:
+                continue
+            if "RESULT EXPECTED TO BE RANDOM" in line:
+                continue
+            testCount += 1
+            if "UNEXPECTED" in line:
+                failCount += 1
+                continue
+            if "KNOWN FAIL" in line:
+                knownFailCount += 1
+            else:
+                passCount += 1
+        summary = "TinderboxPrint: " + self.name + "<br/>" + str(passCount) + \
+            "/" + str(failCount) + "/" + str(knownFailCount) + "\n"
+        self.addCompleteLog('summary', summary)
+    
+    def evaluateCommand(self, cmd):
+        superResult = ShellCommandReportTimeout.evaluateCommand(self, cmd)
+        if SUCCESS != superResult:
+            return WARNINGS
+        if re.search('UNEXPECTED', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        return SUCCESS
+    
+class MozillaOSXReftest(MozillaReftest):
+    command = ["../../objdir/dist/Minefield.app/Contents/MacOS/firefox",
+               "-console",
+               "-P",
+               "default",
+               "-reftest",
+               "reftest.list"]
+
+class MozillaCrashtest(MozillaReftest):
+    name = "crashtest"
+    description = ["crashtest"]
+    descriptionDone = ["crashtest complete"]
+
+class MozillaOSXCrashtest(MozillaCrashtest):
+    command = ["../../objdir/dist/Minefield.app/Contents/MacOS/firefox",
+               "-console",
+               "-P",
+               "default",
+               "-reftest",
+               "crashtests.list"]
+
+class MozillaMochitest(ShellCommandReportTimeout):
+    name = "mochitest"
+    warnOnFailure = True
+    description = ["mochitest"]
+    descriptionDone = ["mochitest complete"]
+    command = ["python",
+               "runtests.py",
+               "--appname=../../../dist/bin/firefox",
+               "--autorun",
+               "--console-level=INFO",
+               "--close-when-done"]
+     
+    def createSummary(self, log):
+        passCount = 0
+        failCount = 0
+        todoCount = 0
+        for line in log.readlines():
+            if "INFO Passed:" in line:
+                passCount = int(line.split()[-1])
+            if "INFO Failed:" in line:
+                failCount = int(line.split()[-1])
+            if "INFO Todo:" in line:
+                todoCount = int(line.split()[-1])
+        summary = "TinderboxPrint: mochitest<br/>"
+        if not (passCount + failCount + todoCount):
+            summary += "FAIL\n"
+        else:
+            summary +=  str(passCount) + "/" + str(failCount) + "/" + str(todoCount) + "\n"
+        self.addCompleteLog('summary', summary)
+    
+    def evaluateCommand(self, cmd):
+        superResult = ShellCommandReportTimeout.evaluateCommand(self, cmd)
+        if SUCCESS != superResult:
+            return WARNINGS
+        if re.search('ERROR FAIL', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        if re.search('ERROR TODO WORKED', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        if re.search('FAIL Exited', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        if not re.search('INFO PASS', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        return SUCCESS
+
+class MozillaOSXMochitest(MozillaMochitest):
+    command = ["python",
+               "runtests.py",
+               "--appname=../../../objdir/dist/Minefield.app/Contents/MacOS/firefox",
+               "--autorun",
+               "--console-level=INFO",
+               "--close-when-done"]
+
+class MozillaMochichrome(ShellCommandReportTimeout):
+    name = "mochichrome"
+    warnOnFailure = True
+    description = ["mochichrome"]
+    descriptionDone = ["mochichrome complete"]
+    command = ["python",
+              "runtests.py",
+              "--appname=objdir/dist/bin/firefox",
+              "--chrome",
+              "--autorun",
+              "--console-level=INFO",
+              "--close-when-done"]
+    
+    def createSummary(self, log):
+        passCount = 0
+        failCount = 0
+        todoCount = 0
+        for line in log.readlines():
+            if "INFO Passed:" in line:
+                passCount = int(line.split()[-1])
+            if "INFO Failed:" in line:
+                failCount = int(line.split()[-1])
+            if "INFO Todo:" in line:
+                todoCount = int(line.split()[-1])
+        summary = "TinderboxPrint: chrome<br/>"
+        if not (passCount + failCount + todoCount):
+            summary += "FAIL\n"
+        else:
+            summary +=  str(passCount) + "/" + str(failCount) + "/" + str(todoCount) + "\n"
+        self.addCompleteLog('summary', summary)
+    
+    def evaluateCommand(self, cmd):
+        superResult = ShellCommandReportTimeout.evaluateCommand(self, cmd)
+        if SUCCESS != superResult:
+            return WARNINGS
+        if re.search('ERROR FAIL', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        if re.search('FAIL Exited', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        if not re.search('INFO PASS', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        return SUCCESS
+    
+
+class MozillaOSXMochichrome(MozillaMochichrome):
+   command = ["python",
+              "runtests.py",
+              "--appname=../../../objdir/dist/Minefield.app/Contents/MacOS/firefox",
+              "--chrome",
+              "--autorun",
+              "--console-level=INFO",
+              "--close-when-done"]
+
+class MozillaBrowserChromeTest(ShellCommandReportTimeout):
+    name = "browser chrome test"
+    warnOnFailure = True
+    description = ["browser chrome test"]
+    descriptionDone = ["browser chrome test complete"]
+    command = ["python",
+               "runtests.py",
+               "--appname=../../../dist/bin/firefox",
+               "--autorun",
+               "--browser-chrome", 
+               "--close-when-done"]
+    
+    def createSummary(self, log):
+        passCount = 0
+        failCount = 0
+        todoCount = 0
+        for line in log.readlines():
+            if "Pass:" in line:
+                passCount = int(line.split()[-1])
+            if "Fail:" in line:
+                failCount = int(line.split()[-1])
+            if "Todo:" in line:
+                todoCount = int(line.split()[-1])
+        summary = "TinderboxPrint: browser<br/>"
+        if not (passCount + failCount + todoCount):
+            summary += "FAIL\n"
+        else:
+            summary +=  str(passCount) + "/" + str(failCount) + "/" + str(todoCount) + "\n"
+        self.addCompleteLog('summary', summary)
+    
+    def evaluateCommand(self, cmd):
+        superResult = ShellCommandReportTimeout.evaluateCommand(self, cmd)
+        if SUCCESS != superResult:
+            return WARNINGS
+        if re.search('FAIL -', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        if re.search('FAIL Exited', cmd.logs['stdio'].getText()):
+            return WARNINGS
+        return SUCCESS
+    
+class MozillaOSXBrowserChromeTest(MozillaBrowserChromeTest):
+    command = ["python",
+               "runtests.py",
+               "--appname=../../../objdir/dist/Minefield.app/Contents/MacOS/firefox",
+               "--autorun",
+               "--browser-chrome",
+               "--close-when-done"]
+
+class MozillaA11YTest(MozillaMochichrome):
+    name = "a11y test"
+    warnOnFailure = True
+    description = ["a11y test"]
+    descriptionDone = ["a11y test complete"]
+    command = ["python",
+               "runtests.py",
+               "--appname=objdir/dist/bin/firefox",
+               "--console-level=INFO",
+               "--autorun",
+               "--a11y", 
+               "--close-when-done"]
+    
+    def createSummary(self, log):
+        passCount = 0
+        failCount = 0
+        todoCount = 0
+        for line in log.readlines():
+            if "INFO Passed:" in line:
+                passCount = int(line.split()[-1])
+            if "INFO Failed:" in line:
+                failCount = int(line.split()[-1])
+            if "INFO Todo:" in line:
+                todoCount = int(line.split()[-1])
+        summary = "TinderboxPrint: a11y<br/>"
+        if not (passCount + failCount + todoCount):
+            summary += "FAIL\n"
+        else:
+            summary +=  str(passCount) + "/" + str(failCount) + "/" + str(todoCount) + "\n"
+        self.addCompleteLog('summary', summary)
+    
+
+class MozillaOSXA11YTest(MozillaA11YTest):
+   command = ["python",
+              "runtests.py",
+              "--appname=../../../dist/Minefield.app/Contents/MacOS/firefox",
+              "--a11y",
+              "--autorun",
+              "--console-level=INFO",
+              "--close-when-done"]
+
+class CreateProfile(ShellCommandReportTimeout):
+    name = "create profile"
+    warnOnFailure = True
+    description = ["create profile"]
+    descriptionDone = ["create profile complete"]
+    command = r'python testing/tools/profiles/createTestingProfile.py --clobber --binary objdir/dist/bin/firefox'
diff -r 9e48e21dd4f6 master.cfg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master.cfg	Sat Feb 07 12:21:02 2009 -0500
@@ -0,0 +1,238 @@
+# -*- python -*-
+# ex: set syntax=python:
+
+# This is a sample buildmaster config file. It must be installed as
+# 'master.cfg' in your buildmaster's base directory (although the filename
+# can be changed with the --basedir option to 'mktap buildbot master').
+
+# It has one job: define a dictionary named BuildmasterConfig. This
+# dictionary has a variety of keys to control different aspects of the
+# buildmaster. They are documented in docs/config.xhtml .
+
+
+# This is the dictionary that the buildmaster pays attention to. We also use
+# a shorter alias to save typing.
+c = BuildmasterConfig = {}
+
+####### BUILDSLAVES
+
+# the 'slaves' list defines the set of allowable buildslaves. Each element is
+# a tuple of bot-name and bot-password. These correspond to values given to
+# the buildslave's mktap invocation.
+from buildbot.buildslave import BuildSlave
+#c['slaves'] = [BuildSlave("p6t-slave", "mozilla"), BuildSlave("macbook-slave", "mozilla"), BuildSlave("neb-slave", "mozilla")]
+c['slaves'] = [BuildSlave("local-slave", "mozilla")]
+
+# to limit to two concurrent builds on a slave, use
+#  c['slaves'] = [BuildSlave("bot1name", "bot1passwd", max_builds=2)]
+
+
+# 'slavePortnum' defines the TCP port to listen on. This must match the value
+# configured into the buildslaves (with their --master option)
+
+c['slavePortnum'] = 9989
+
+####### CHANGESOURCES
+
+# the 'change_source' setting tells the buildmaster how it should find out
+# about source code changes. Any class which implements IChangeSource can be
+# put here: there are several in buildbot/changes/*.py to choose from.
+
+#from buildbot.changes.pb import PBChangeSource
+#c['change_source'] = []
+#c['change_source'].append(PBChangeSource())
+
+# For example, if you had CVSToys installed on your repository, and your
+# CVSROOT/freshcfg file had an entry like this:
+#pb = ConfigurationSet([
+#    (None, None, None, PBService(userpass=('foo', 'bar'), port=4519)),
+#    ])
+
+# then you could use the following buildmaster Change Source to subscribe to
+# the FreshCVS daemon and be notified on every commit:
+#
+#from buildbot.changes.freshcvs import FreshCVSSource
+#fc_source = FreshCVSSource("cvs.example.com", 4519, "foo", "bar")
+#c['change_source'] = fc_source
+
+# or, use a PBChangeSource, and then have your repository's commit script run
+# 'buildbot sendchange', or use contrib/svn_buildbot.py, or
+# contrib/arch_buildbot.py :
+#
+#from buildbot.changes.pb import PBChangeSource
+#c['change_source'] = PBChangeSource()
+
+
+
+####### SCHEDULERS
+
+## configure the Schedulers
+
+from buildbot.scheduler import Scheduler
+c['schedulers'] = []
+#c['schedulers'].append(Scheduler(name="all", branch=None,
+#                                 treeStableTimer=5,
+#                                 builderNames=["buildbot-f10", "buildbot-osx", "buildbot-xp"]))
+#
+
+####### BUILDERS
+
+# the 'builders' list defines the Builders. Each one is configured with a
+# dictionary, using the following keys:
+#  name (required): the name used to describe this bilder
+#  slavename (required): which slave to use, must appear in c['bots']
+#  builddir (required): which subdirectory to run the builder in
+#  factory (required): a BuildFactory to define how the build is run
+#  periodicBuildTime (optional): if set, force a build every N seconds
+
+# buildbot/process/factory.py provides several BuildFactory classes you can
+# start with, which implement build processes for common targets (GNU
+# autoconf projects, CPAN perl modules, etc). The factory.BuildFactory is the
+# base class, and is configured with a series of BuildSteps. When the build
+# is run, the appropriate buildslave is told to execute each Step in turn.
+
+# the first BuildStep is typically responsible for obtaining a copy of the
+# sources. There are source-obtaining Steps in buildbot/steps/source.py for
+# CVS, SVN, and others.
+
+#John's Simple Factory
+from buildbot.process import factory
+from buildbot.steps.shell import ShellCommand, Compile
+from buildbot.steps.source import Mercurial
+f1 = factory.BuildFactory()
+import os
+f1.addStep(ShellCommand, name='current date-time', command='~/pytime.py')
+f1.addStep(Mercurial, repourl="http://hg.mozilla.org/mozilla-central/", mode='update');
+f1.addStep(ShellCommand, flunkOnFail=False, haltOnFail=False, name='clean-obj', command='rm -rf obj',)
+f1.addStep(Compile, name='build', command=['make', '-f',  'client.mk', 'build']) 
+
+
+##
+## Mac OS X
+##
+from buildbot.mozbuild import *
+
+osxFactory = factory.BuildFactory()
+
+osxFactory.addStep(ShellCommand, name='current date-time', command='~/pytime.py')
+osxFactory.addStep(ShellCommand, name="mozconfig contents",
+        command=["cat","/home/jhford/.mozconfig"])
+osxFactory.addStep(Mercurial, repourl="http://hg.mozilla.org/mozilla-central/", mode='update');
+osxFactory.addStep(ShellCommand, flunkOnFail=False, haltOnFail=False, name='clean-obj', command='rm -rf obj',)
+osxFactory.addStep(Compile, name='build', command=['make', '-f',  'client.mk', 'build']) 
+osxFactory.addStep(ShellCommand, name='check', workdir='build/objdir', command='make -k check')
+osxFactory.addStep(CreateProfile,
+        warnOnWarnings=True,
+        env=MozillaEnvironments['osx'],
+        clobber=True)
+osxFactory.addStep(MozillaOSXReftest, warnOnWarnings=True,
+        workdir="build/layout/reftests",
+        env=MozillaEnvironments['osx'])
+osxFactory.addStep(MozillaOSXCrashtest, warnOnWarnings=True,
+        workdir="build/testing/crashtest",
+        env=MozillaEnvironments['osx'])
+#osxFactory.addStep(MozillaMochitest, warnOnWarnings=True,
+#        workdir="build/objdir/_tests/testing/mochitest",
+#        env=MozillaEnvironments['osx'])
+#osxFactory.addStep(MozillaMochichrome, warnOnWarnings=True,
+#        workdir="build/objdir/_tests/testing/mochitest",
+#        env=MozillaEnvironments['osx'])
+#osxFactory.addStep(MozillaBrowserChromeTest, warnOnWarnings=True,
+#        workdir="build/objdir/_tests/testing/mochitest",
+#        env=MozillaEnvironments['osx'])
+
+
+b1 = {'name': "local-osx",
+      'slavename': "local-slave",
+      'builddir': "osx",
+      'factory': f1,
+      }
+
+mozbuilder = {'name': "mozilla-osx",
+      'slavename': "local-slave",
+      'builddir': "moz-osx",
+      'factory': osxFactory,
+      }
+
+
+b2 = {'name': "buildbot-f10",
+      'slavename': "p6t-slave",
+      'builddir': "linux",
+      'factory': f1,
+      }
+
+#b3 = {'name': "buildbot-xp",
+#      'slavename': "neb-slave",
+#      'builddir': "xp",
+#      'factory': f1,
+#      }
+
+
+c['builders'] = []
+c['builders'].append(b1)
+c['builders'].append(mozbuilder)
+#c['builders'].append(b2)
+#c['builders'].append(b3)
+
+
+####### STATUS TARGETS
+
+# 'status' is a list of Status Targets. The results of each build will be
+# pushed to these targets. buildbot/status/*.py has a variety to choose from,
+# including web pages, email senders, and IRC bots.
+
+c['status'] = []
+
+from buildbot.status import html
+c['status'].append(html.WebStatus(http_port=8010, allowForce=True))
+
+from buildbot.status import mail
+c['status'].append(mail.MailNotifier(fromaddr="buildbot@localhost",
+                                     extraRecipients=["buildlogs@johnford.info"],
+                                     sendToInterestedUsers=False))
+
+from buildbot.status import words
+c['status'].append(words.IRC(host="irc.mozilla.org", nick="buildbot-seneca",
+                             channels=["#seneca-build"]))
+
+from buildbot.status import client
+c['status'].append(client.PBListener(9988))
+
+
+####### DEBUGGING OPTIONS
+
+# if you set 'debugPassword', then you can connect to the buildmaster with
+# the diagnostic tool in contrib/debugclient.py . From this tool, you can
+# manually force builds and inject changes, which may be useful for testing
+# your buildmaster without actually commiting changes to your repository (or
+# before you have a functioning 'sources' set up). The debug tool uses the
+# same port number as the slaves do: 'slavePortnum'.
+
+#c['debugPassword'] = "debugpassword"
+
+# if you set 'manhole', you can ssh into the buildmaster and get an
+# interactive python shell, which may be useful for debugging buildbot
+# internals. It is probably only useful for buildbot developers. You can also
+# use an authorized_keys file, or plain telnet.
+#from buildbot import manhole
+#c['manhole'] = manhole.PasswordManhole("tcp:9999:interface=127.0.0.1",
+#                                       "admin", "password")
+
+
+####### PROJECT IDENTITY
+
+# the 'projectName' string will be used to describe the project that this
+# buildbot is working on. For example, it is used as the title of the
+# waterfall HTML page. The 'projectURL' string will be used to provide a link
+# from buildbot HTML pages to your project's home page.
+
+c['projectName'] = "Mozilla @ Seneca"
+c['projectURL'] = "http://zenit.senecac.on.ca/wiki"
+
+# the 'buildbotURL' string should point to the location where the buildbot's
+# internal web server (usually the html.Waterfall page) is visible. This
+# typically uses the port number set in the Waterfall 'status' entry, but
+# with an externally-visible host name which the buildbot cannot figure out
+# without some help.
+
+c['buildbotURL'] = "http://localhost:8010/"