Patch to add 'flags' that can be set in BuildSteps and tested for in
the test harness.  These are useful in determining which steps have
and have not run.
Index: triggers/buildbot/test/runutils.py
===================================================================
--- triggers.orig/buildbot/test/runutils.py	2007-06-17 21:52:49.000000000 -0500
+++ triggers/buildbot/test/runutils.py	2007-07-02 10:09:20.492144509 -0500
@@ -413,3 +413,45 @@
     def filterArgs(self, args):
         # this can be overridden
         return args
+
+# ----------------------------------------
+
+_flags = {}
+
+def setTestFlag(flagname, value):
+    _flags[flagname] = value
+
+class SetTestFlagStep(BuildStep):
+    """
+    A special BuildStep to set a named flag; this can be used with the
+    TestFlagMixin to monitor what has and has not run in a particular
+    configuration.
+    """
+    def __init__(self, flagname='flag', value=1, **kwargs):
+        BuildStep.__init__(self, **kwargs)
+        self.flagname = flagname
+        self.value = value
+
+    def start(self):
+        _flags[self.flagname] = self.value
+        self.finished(builder.SUCCESS)
+
+class TestFlagMixin:
+    def clearFlags(self):
+        """
+        Set up for a test by clearing all flags; call this from your test
+        function.
+        """
+        _flags.clear()
+
+    def failIfFlagSet(self, flagname, msg=None):
+        if not msg: msg = "flag '%s' is set" % flagname
+        self.failIf(_flags.has_key(flagname), msg=msg)
+
+    def failIfFlagNotSet(self, flagname, msg=None):
+        if not msg: msg = "flag '%s' is not set" % flagname
+        self.failUnless(_flags.has_key(flagname), msg=msg)
+
+    def getFlag(self, flagname):
+        self.failIfFlagNotSet(flagname, "flag '%s' not set" % flagname)
+        return _flags.get(flagname)
Index: triggers/buildbot/test/test_run.py
===================================================================
--- triggers.orig/buildbot/test/test_run.py	2007-07-02 09:33:48.229148500 -0500
+++ triggers/buildbot/test/test_run.py	2007-07-02 10:28:39.596836658 -0500
@@ -10,7 +10,7 @@
 from buildbot.status import builder
 from buildbot.process.base import BuildRequest
 
-from buildbot.test.runutils import RunMixin, rmtree
+from buildbot.test.runutils import RunMixin, TestFlagMixin, rmtree
 
 config_base = """
 from buildbot.process import factory
@@ -506,6 +506,43 @@
         d = self.master.loadConfig(config_4_newbuilder)
         return d
 
+config_test_flag = config_base + """
+from buildbot.scheduler import Scheduler
+c['schedulers'] = [Scheduler('quick', None, 0.1, ['dummy'])]
+
+from buildbot.test.runutils import SetTestFlagStep
+f3 = factory.BuildFactory([
+    s(SetTestFlagStep, flagname='foo', value='bar'),
+    ])
+
+c['builders'] = [{'name': 'dummy', 'slavename': 'bot1',
+                  'builddir': 'dummy', 'factory': f3}]
+"""
+
+class TestFlag(RunMixin, TestFlagMixin, unittest.TestCase):
+    """Test for the TestFlag functionality in runutils"""
+    def testTestFlag(self):
+        m = self.master
+        m.loadConfig(config_test_flag)
+        m.readConfig = True
+        m.startService()
+
+        c = changes.Change("bob", ["Makefile", "foo/bar.c"], "changed stuff")
+        m.change_svc.addChange(c)
+
+        d = self.connectSlave()
+        d.addCallback(self._testTestFlag_1)
+        return d
+
+    def _testTestFlag_1(self, res):
+        d = defer.Deferred()
+        reactor.callLater(0.5, d.callback, None)
+        d.addCallback(self._testTestFlag_2)
+        return d
+
+    def _testTestFlag_2(self, res):
+        self.failUnlessEqual(self.getFlag('foo'), 'bar')
+
 # TODO: test everything, from Change submission to Scheduler to Build to
 # Status. Use all the status types. Specifically I want to catch recurrences
 # of the bug where I forgot to make Waterfall inherit from StatusReceiver

