[Buildbot-commits] buildbot/buildbot/test test_properties.py,NONE,1.1 test_vc.py,1.47,1.48

Brian Warner warner at users.sourceforge.net
Mon Apr 24 06:45:38 UTC 2006


Update of /cvsroot/buildbot/buildbot/buildbot/test
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/buildbot/test

Modified Files:
	test_vc.py 
Added Files:
	test_properties.py 
Log Message:
Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506
Creator:  Brian Warner <warner at lothar.com>

add 'build properties', update test_vc

2006-04-23  Brian Warner  <warner at lothar.com>

	* buildbot/test/test_vc.py (VCBase.checkGotRevision): test
	'got_revision' build property for all VC systems that implement
	accurate ones: SVN, Darcs, Arch, Bazaar, Mercurial.

	* buildbot/slave/commands.py (SourceBase._handleGotRevision): try
	to determine which revision we actually obtained
	(CVS.parseGotRevision): implement this for CVS, which just means
	to grab a timestamp. Not ideal, and it depends upon the buildslave
	having a clock that is reasonably well syncronized with the server,
	but it's better than nothing.
	(SVN.parseGotRevision): implement it for SVN, which is accurate
	(Darcs.parseGotRevision): same
	(Arch.parseGotRevision): same
	(Bazaar.parseGotRevision): same
	(Mercurial.parseGotRevision): same

	* buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate):
	keep a record of all non-stdout/stderr/header/rc status updates,
	for the benefit of RemoteCommands that send other useful things,
	like got_revision
	(Source.commandComplete): put any 'got_revision' status values
	into a build property of the same name

	* buildbot/process/step_twisted.py (Trial): update to deal with
	new ShellCommand refactoring

	* docs/buildbot.texinfo (Build Properties): document new feature
	that allows BuildSteps to get/set Build-wide properties like which
	revision was requested and/or checked out.

	* buildbot/interfaces.py (IBuildStatus.getProperty): new method
	* buildbot/status/builder.py (BuildStatus.getProperty): implement
	it. Note that this bumps the persistenceVersion of the saved Build
	object, so add the necessary upgrade-old-version logic to include
	an empty properties dict.

	* buildbot/process/base.py (Build.setProperty): implement it
	(Build.getProperty): same
	(Build.startBuild): change build startup to set 'branch',
	'revision', and 'slavename' properties at the right time

	* buildbot/process/step.py (BuildStep.__init__): change setup to
	require 'build' argument in a better way
	(LoggingBuildStep): split ShellCommand into two pieces, for better
	subclassing elsewhere. LoggingBuildStep is a BuildStep which runs
	a single RemoteCommand that sends stdout/stderr status text. It
	also provides the usual commandComplete / createSummary /
	evaluateCommand / getText methods to be overridden...
	(ShellCommand): .. whereas ShellCommand is specifically for
	running RemoteShellCommands. Other shell-like BuildSteps (like
	Source) can inherit from LoggingBuildStep instead of ShellCommand
	(WithProperties): marker class to do build-property interpolation
	(Source): inherit from LoggingBuildStep instead of ShellCommand
	(RemoteDummy): same

	* buildbot/test/test_properties.py: test new functionality

2006-04-21  Brian Warner  <warner at lothar.com>

	* buildbot/test/test_vc.py: rename testBranch to
	testCheckoutBranch to keep the tests in about the right
	alphabetical order


--- NEW FILE: test_properties.py ---
# -*- test-case-name: buildbot.test.test_properties -*-

import os

from twisted.trial import unittest

from buildbot.sourcestamp import SourceStamp
from buildbot.process import base
from buildbot.process.step import ShellCommand, WithProperties
from buildbot.status import builder
from buildbot.slave.commands import rmdirRecursive

class MyBuildStep(ShellCommand):
    def _interpolateProperties(self, command):
        command = ["tar", "czf",
                   "build-%s.tar.gz" % self.getProperty("revision"),
                   "source"]
        return ShellCommand._interpolateProperties(self, command)


class FakeBuild:
    pass
class FakeBuilder:
    statusbag = None
    name = "fakebuilder"
class FakeSlave:
    slavename = "bot12"
class FakeSlaveBuilder:
    slave = FakeSlave()
    def getSlaveCommandVersion(self, command, oldversion=None):
        return "1.10"

class Interpolate(unittest.TestCase):
    def setUp(self):
        self.builder = FakeBuilder()
        self.builder_status = builder.BuilderStatus("fakebuilder")
        self.builder_status.basedir = "test_properties"
        self.builder_status.nextBuildNumber = 0
        rmdirRecursive(self.builder_status.basedir)
        os.mkdir(self.builder_status.basedir)
        self.build_status = self.builder_status.newBuild()
        req = base.BuildRequest("reason", SourceStamp(branch="branch2",
                                                      revision=1234))
        self.build = base.Build([req])
        self.build.setBuilder(self.builder)
        self.build.setupStatus(self.build_status)
        self.build.setupSlaveBuilder(FakeSlaveBuilder())

    def testWithProperties(self):
        self.build.setProperty("revision", 47)
        self.failUnlessEqual(self.build_status.getProperty("revision"), 47)
        c = ShellCommand(workdir=dir, build=self.build,
                         command=["tar", "czf",
                                  WithProperties("build-%s.tar.gz",
                                                 "revision"),
                                  "source"])
        cmd = c._interpolateProperties(c.command)
        self.failUnlessEqual(cmd,
                             ["tar", "czf", "build-47.tar.gz", "source"])

    def testWithPropertiesDict(self):
        self.build.setProperty("other", "foo")
        self.build.setProperty("missing", None)
        c = ShellCommand(workdir=dir, build=self.build,
                         command=["tar", "czf",
                                  WithProperties("build-%(other)s.tar.gz"),
                                  "source"])
        cmd = c._interpolateProperties(c.command)
        self.failUnlessEqual(cmd,
                             ["tar", "czf", "build-foo.tar.gz", "source"])

    def testWithPropertiesMissing(self):
        self.build.setProperty("missing", None)
        c = ShellCommand(workdir=dir, build=self.build,
                         command=["tar", "czf",
                                  WithProperties("build-%(missing)s.tar.gz"),
                                  "source"])
        cmd = c._interpolateProperties(c.command)
        self.failUnlessEqual(cmd,
                             ["tar", "czf", "build-.tar.gz", "source"])

    def testCustomBuildStep(self):
        c = MyBuildStep(workdir=dir, build=self.build)
        cmd = c._interpolateProperties(c.command)
        self.failUnlessEqual(cmd,
                             ["tar", "czf", "build-1234.tar.gz", "source"])

    def testSourceStamp(self):
        c = ShellCommand(workdir=dir, build=self.build,
                         command=["touch",
                                  WithProperties("%s-dir", "branch"),
                                  WithProperties("%s-rev", "revision"),
                                  ])
        cmd = c._interpolateProperties(c.command)
        self.failUnlessEqual(cmd,
                             ["touch", "branch2-dir", "1234-rev"])

    def testSlaveName(self):
        c = ShellCommand(workdir=dir, build=self.build,
                         command=["touch",
                                  WithProperties("%s-slave", "slavename"),
                                  ])
        cmd = c._interpolateProperties(c.command)
        self.failUnlessEqual(cmd,
                             ["touch", "bot12-slave"])


# we test got_revision in test_vc

Index: test_vc.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_vc.py,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- test_vc.py	11 Apr 2006 06:12:59 -0000	1.47
+++ test_vc.py	24 Apr 2006 06:45:36 -0000	1.48
@@ -253,6 +253,8 @@
     httpServer = None
     httpPort = None
     skip = None
+    has_got_revision = False
+    has_got_revision_branches_are_merged = False # for SVN
 
     def failUnlessIn(self, substring, string, msg=None):
         # trial provides a version of this that requires python-2.3 to test
@@ -431,6 +433,16 @@
         c = open(os.path.join(d, f), "r").read()
         self.failUnlessIn(contents, c)
 
+    def checkGotRevision(self, bs, expected):
+        if self.has_got_revision:
+            self.failUnlessEqual(bs.getProperty("got_revision"), expected)
+
+    def checkGotRevisionIsLatest(self, bs):
+        expected = self.trunk[-1]
+        if self.has_got_revision_branches_are_merged:
+            expected = self.allrevs[-1]
+        self.checkGotRevision(bs, expected)
+
     def do_vctest(self, testRetry=True):
         vctype = self.vctype
         args = self.vcargs
@@ -473,12 +485,15 @@
         d = self.doBuild() # initial checkout
         d.addCallback(self._do_vctest_clobber_1)
         return d
-    def _do_vctest_clobber_1(self, res):
+    def _do_vctest_clobber_1(self, bs):
         self.shouldExist(self.workdir, "main.c")
         self.shouldExist(self.workdir, "version.c")
         self.shouldExist(self.workdir, "subdir", "subdir.c")
         if self.metadir:
             self.shouldExist(self.workdir, self.metadir)
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.failUnlessEqual(bs.getProperty("branch"), None)
+        self.checkGotRevisionIsLatest(bs)
 
         self.touch(self.workdir, "newfile")
         self.shouldExist(self.workdir, "newfile")
@@ -493,7 +508,7 @@
         d = self.doBuild() # rebuild with update
         d.addCallback(self._do_vctest_update_1)
         return d
-    def _do_vctest_update_1(self, res):
+    def _do_vctest_update_1(self, bs):
         log.msg("_do_vctest_update_1")
         self.shouldExist(self.workdir, "main.c")
         self.shouldExist(self.workdir, "version.c")
@@ -501,12 +516,14 @@
                            "version=%d" % self.version)
         if self.metadir:
             self.shouldExist(self.workdir, self.metadir)
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
 
         self.touch(self.workdir, "newfile")
         d = self.doBuild() # update rebuild leaves new files
         d.addCallback(self._do_vctest_update_2)
         return d
-    def _do_vctest_update_2(self, res):
+    def _do_vctest_update_2(self, bs):
         log.msg("_do_vctest_update_2")
         self.shouldExist(self.workdir, "main.c")
         self.shouldExist(self.workdir, "version.c")
@@ -516,33 +533,41 @@
         d.addCallback(lambda res: self.doBuild())
         d.addCallback(self._do_vctest_update_3)
         return d
-    def _do_vctest_update_3(self, res):
+    def _do_vctest_update_3(self, bs):
         log.msg("_do_vctest_update_3")
         self.shouldExist(self.workdir, "main.c")
         self.shouldExist(self.workdir, "version.c")
         self.shouldContain(self.workdir, "version.c",
                            "version=%d" % self.version)
         self.shouldExist(self.workdir, "newfile")
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
+
         # now "update" to an older revision
         d = self.doBuild(ss=SourceStamp(revision=self.trunk[-2]))
         d.addCallback(self._do_vctest_update_4)
         return d
-    def _do_vctest_update_4(self, res):
+    def _do_vctest_update_4(self, bs):
         log.msg("_do_vctest_update_4")
         self.shouldExist(self.workdir, "main.c")
         self.shouldExist(self.workdir, "version.c")
         self.shouldContain(self.workdir, "version.c",
                            "version=%d" % (self.version-1))
+        self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-2])
+        self.checkGotRevision(bs, self.trunk[-2])
+
         # now update to the newer revision
         d = self.doBuild(ss=SourceStamp(revision=self.trunk[-1]))
         d.addCallback(self._do_vctest_update_5)
         return d
-    def _do_vctest_update_5(self, res):
+    def _do_vctest_update_5(self, bs):
         log.msg("_do_vctest_update_5")
         self.shouldExist(self.workdir, "main.c")
         self.shouldExist(self.workdir, "version.c")
         self.shouldContain(self.workdir, "version.c",
                            "version=%d" % self.version)
+        self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-1])
+        self.checkGotRevision(bs, self.trunk[-1])
 
 
     def _do_vctest_update_retry(self, res):
@@ -558,46 +583,54 @@
         d = self.doBuild() # update, but must clobber to handle the error
         d.addCallback(self._do_vctest_update_retry_1)
         return d
-    def _do_vctest_update_retry_1(self, res):
+    def _do_vctest_update_retry_1(self, bs):
         self.shouldNotExist(self.workdir, "newfile")
 
     def _do_vctest_copy(self, res):
         d = self.doBuild() # copy rebuild clobbers new files
         d.addCallback(self._do_vctest_copy_1)
         return d
-    def _do_vctest_copy_1(self, res):
+    def _do_vctest_copy_1(self, bs):
         if self.metadir:
             self.shouldExist(self.workdir, self.metadir)
         self.shouldNotExist(self.workdir, "newfile")
         self.touch(self.workdir, "newfile")
         self.touch(self.vcdir, "newvcfile")
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
 
         d = self.doBuild() # copy rebuild clobbers new files
         d.addCallback(self._do_vctest_copy_2)
         return d
-    def _do_vctest_copy_2(self, res):
+    def _do_vctest_copy_2(self, bs):
         if self.metadir:
             self.shouldExist(self.workdir, self.metadir)
         self.shouldNotExist(self.workdir, "newfile")
         self.shouldExist(self.vcdir, "newvcfile")
         self.shouldExist(self.workdir, "newvcfile")
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
         self.touch(self.workdir, "newfile")
 
     def _do_vctest_export(self, res):
         d = self.doBuild() # export rebuild clobbers new files
         d.addCallback(self._do_vctest_export_1)
         return d
-    def _do_vctest_export_1(self, res):
+    def _do_vctest_export_1(self, bs):
         self.shouldNotExist(self.workdir, self.metadir)
         self.shouldNotExist(self.workdir, "newfile")
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
         self.touch(self.workdir, "newfile")
 
         d = self.doBuild() # export rebuild clobbers new files
         d.addCallback(self._do_vctest_export_2)
         return d
-    def _do_vctest_export_2(self, res):
+    def _do_vctest_export_2(self, bs):
         self.shouldNotExist(self.workdir, self.metadir)
         self.shouldNotExist(self.workdir, "newfile")
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
 
     def do_patch(self):
         vctype = self.vctype
@@ -621,7 +654,7 @@
         d.addCallback(lambda res: self.doBuild(ss=ss))
         d.addCallback(self._doPatch_1)
         return d
-    def _doPatch_1(self, res):
+    def _doPatch_1(self, bs):
         self.shouldContain(self.workdir, "version.c",
                            "version=%d" % self.version)
         # make sure the file actually got patched
@@ -629,18 +662,22 @@
                                 "subdir", "subdir.c")
         data = open(subdir_c, "r").read()
         self.failUnlessIn("Hello patched subdir.\\n", data)
+        self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-1])
+        self.checkGotRevision(bs, self.trunk[-1])
 
         # make sure that a rebuild does not use the leftover patched workdir
         d = self.master.loadConfig(self.config % "update")
         d.addCallback(lambda res: self.doBuild(ss=None))
         d.addCallback(self._doPatch_2)
         return d
-    def _doPatch_2(self, res):
+    def _doPatch_2(self, bs):
         # make sure the file is back to its original
         subdir_c = os.path.join(self.slavebase, "vc-dir", "build",
                                 "subdir", "subdir.c")
         data = open(subdir_c, "r").read()
         self.failUnlessIn("Hello subdir.\\n", data)
+        self.failUnlessEqual(bs.getProperty("revision"), None)
+        self.checkGotRevisionIsLatest(bs)
 
         # now make sure we can patch an older revision. We need at least two
         # revisions here, so we might have to create one first
@@ -655,7 +692,7 @@
         d = self.doBuild(ss=ss)
         d.addCallback(self._doPatch_4)
         return d
-    def _doPatch_4(self, res):
+    def _doPatch_4(self, bs):
         self.shouldContain(self.workdir, "version.c",
                            "version=%d" % (self.version-1))
         # and make sure the file actually got patched
@@ -663,6 +700,8 @@
                                 "subdir", "subdir.c")
         data = open(subdir_c, "r").read()
         self.failUnlessIn("Hello patched subdir.\\n", data)
+        self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-2])
+        self.checkGotRevision(bs, self.trunk[-2])
 
         # now check that we can patch a branch
         ss = SourceStamp(branch=self.branchname, revision=self.branch[-1],
@@ -670,7 +709,7 @@
         d = self.doBuild(ss=ss)
         d.addCallback(self._doPatch_5)
         return d
-    def _doPatch_5(self, res):
+    def _doPatch_5(self, bs):
         self.shouldContain(self.workdir, "version.c",
                            "version=%d" % 1)
         self.shouldContain(self.workdir, "main.c", "Hello branch.")
@@ -678,6 +717,9 @@
                                 "subdir", "subdir.c")
         data = open(subdir_c, "r").read()
         self.failUnlessIn("Hello patched subdir.\\n", data)
+        self.failUnlessEqual(bs.getProperty("revision"), self.branch[-1])
+        self.failUnlessEqual(bs.getProperty("branch"), self.branchname)
+        self.checkGotRevision(bs, self.branch[-1])
 
 
     def do_vctest_once(self, shouldSucceed):
@@ -723,7 +765,7 @@
         d.addCallback(lambda res: self.doBuild(ss=SourceStamp()))
         d.addCallback(self._doBranch_1)
         return d
-    def _doBranch_1(self, res):
+    def _doBranch_1(self, bs):
         log.msg("_doBranch_1")
         # make sure the checkout was of the trunk
         main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c")
@@ -736,7 +778,7 @@
         d = self.doBuild(ss=SourceStamp(branch=self.branchname))
         d.addCallback(self._doBranch_2)
         return d
-    def _doBranch_2(self, res):
+    def _doBranch_2(self, bs):
         log.msg("_doBranch_2")
         # make sure it was on the branch
         main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c")
@@ -750,7 +792,7 @@
         d = self.doBuild(ss=SourceStamp(branch=self.branchname))
         d.addCallback(self._doBranch_3)
         return d
-    def _doBranch_3(self, res):
+    def _doBranch_3(self, bs):
         log.msg("_doBranch_3")
         # make sure it is still on the branch
         main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c")
@@ -763,7 +805,7 @@
         d = self.doBuild(ss=SourceStamp())
         d.addCallback(self._doBranch_4)
         return d
-    def _doBranch_4(self, res):
+    def _doBranch_4(self, bs):
         log.msg("_doBranch_4")
         # make sure it was on the trunk
         main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c")
@@ -938,6 +980,11 @@
     try_branchname = "branch"
     vctype = "step.CVS"
     vctype_try = "cvs"
+    # CVS gives us got_revision, but it is based entirely upon the local
+    # clock, which means it is unlikely to match the timestamp taken earlier.
+    # This might be enough for common use, but won't be good enough for our
+    # tests to accept, so pretend it doesn't have got_revision at all.
+    has_got_revision = False
 
     def capable(self):
         global VCS
@@ -1042,7 +1089,7 @@
         d = self.do_patch()
         return maybeWait(d)
 
-    def testBranch(self):
+    def testCheckoutBranch(self):
         d = self.do_branch()
         return maybeWait(d)
         
@@ -1057,6 +1104,8 @@
     try_branchname = "sample/branch"
     vctype = "step.SVN"
     vctype_try = "svn"
+    has_got_revision = True
+    has_got_revision_branches_are_merged = True
 
     def capable(self):
         global VCS
@@ -1171,7 +1220,7 @@
 
     def testCheckout(self):
         # we verify this one with the svnurl style of vcargs. We test the
-        # baseURL/defaultBranch style in testPatch and testBranch.
+        # baseURL/defaultBranch style in testPatch and testCheckoutBranch.
         self.vcargs = { 'svnurl': self.svnurl_trunk }
         d = self.do_vctest()
         return maybeWait(d)
@@ -1183,7 +1232,7 @@
         d = self.do_patch()
         return maybeWait(d)
 
-    def testBranch(self):
+    def testCheckoutBranch(self):
         self.vcargs = { 'baseURL': self.svnurl + "/",
                         'defaultBranch': "sample/trunk",
                         }
@@ -1208,6 +1257,7 @@
     try_branchname = "branch"
     vctype = "step.Darcs"
     vctype_try = "darcs"
+    has_got_revision = True
 
     def capable(self):
         global VCS
@@ -1312,7 +1362,7 @@
         d = self.do_patch()
         return maybeWait(d)
 
-    def testBranch(self):
+    def testCheckoutBranch(self):
         self.vcargs = { 'baseURL': self.darcs_base + "/",
                         'defaultBranch': "trunk" }
         d = self.do_branch()
@@ -1367,6 +1417,7 @@
     vctype = "step.Arch"
     vctype_try = "tla"
     archcmd = "tla"
+    has_got_revision = True
 
     def capable(self):
         global VCS
@@ -1624,7 +1675,7 @@
         d = self.do_patch()
         return maybeWait(d)
 
-    def testBranch(self):
+    def testCheckoutBranch(self):
         d = self.do_branch()
         return maybeWait(d)
 
@@ -1636,6 +1687,7 @@
     vctype = "step.Bazaar"
     vctype_try = "baz"
     archcmd = "baz"
+    has_got_revision = True
 
     def capable(self):
         global VCS
@@ -1687,7 +1739,7 @@
         d = self.do_patch()
         return maybeWait(d)
 
-    def testBranch(self):
+    def testCheckoutBranch(self):
         d = self.do_branch()
         return maybeWait(d)
 
@@ -1767,6 +1819,7 @@
     try_branchname = "branch"
     vctype = "step.Mercurial"
     vctype_try = "hg"
+    has_got_revision = True
 
     def capable(self):
         global VCS
@@ -1879,7 +1932,7 @@
         d = self.do_patch()
         return maybeWait(d)
 
-    def testBranch(self):
+    def testCheckoutBranch(self):
         self.vcargs = { 'baseURL': self.hg_base + "/",
                         'defaultBranch': "trunk" }
         d = self.do_branch()





More information about the Commits mailing list