Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/buildbot/buildbot/test/test_slavecommand.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildbot/buildbot/test/test_slavecommand.py')
-rw-r--r--buildbot/buildbot/test/test_slavecommand.py294
1 files changed, 0 insertions, 294 deletions
diff --git a/buildbot/buildbot/test/test_slavecommand.py b/buildbot/buildbot/test/test_slavecommand.py
deleted file mode 100644
index 9809163..0000000
--- a/buildbot/buildbot/test/test_slavecommand.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# -*- test-case-name: buildbot.test.test_slavecommand -*-
-
-from twisted.trial import unittest
-from twisted.internet import reactor, interfaces
-from twisted.python import runtime, failure, util
-
-import os, sys
-
-from buildbot.slave import commands
-SlaveShellCommand = commands.SlaveShellCommand
-
-from buildbot.test.runutils import SignalMixin, FakeSlaveBuilder
-
-# test slavecommand.py by running the various commands with a fake
-# SlaveBuilder object that logs the calls to sendUpdate()
-
-class Utilities(unittest.TestCase):
- def mkdir(self, basedir, path, mode=None):
- fn = os.path.join(basedir, path)
- os.makedirs(fn)
- if mode is not None:
- os.chmod(fn, mode)
-
- def touch(self, basedir, path, mode=None):
- fn = os.path.join(basedir, path)
- f = open(fn, "w")
- f.write("touch\n")
- f.close()
- if mode is not None:
- os.chmod(fn, mode)
-
- def test_rmdirRecursive(self):
- basedir = "slavecommand/Utilities/test_rmdirRecursive"
- os.makedirs(basedir)
- d = os.path.join(basedir, "doomed")
- self.mkdir(d, "a/b")
- self.touch(d, "a/b/1.txt")
- self.touch(d, "a/b/2.txt", 0444)
- self.touch(d, "a/b/3.txt", 0)
- self.mkdir(d, "a/c")
- self.touch(d, "a/c/1.txt")
- self.touch(d, "a/c/2.txt", 0444)
- self.touch(d, "a/c/3.txt", 0)
- os.chmod(os.path.join(d, "a/c"), 0444)
- self.mkdir(d, "a/d")
- self.touch(d, "a/d/1.txt")
- self.touch(d, "a/d/2.txt", 0444)
- self.touch(d, "a/d/3.txt", 0)
- os.chmod(os.path.join(d, "a/d"), 0)
-
- commands.rmdirRecursive(d)
- self.failIf(os.path.exists(d))
-
-
-class ShellBase(SignalMixin):
-
- def setUp(self):
- self.basedir = "test_slavecommand"
- if not os.path.isdir(self.basedir):
- os.mkdir(self.basedir)
- self.subdir = os.path.join(self.basedir, "subdir")
- if not os.path.isdir(self.subdir):
- os.mkdir(self.subdir)
- self.builder = FakeSlaveBuilder(self.usePTY, self.basedir)
- self.emitcmd = util.sibpath(__file__, "emit.py")
- self.subemitcmd = os.path.join(util.sibpath(__file__, "subdir"),
- "emit.py")
- self.sleepcmd = util.sibpath(__file__, "sleep.py")
-
- def failUnlessIn(self, substring, string):
- self.failUnless(string.find(substring) != -1,
- "'%s' not in '%s'" % (substring, string))
-
- def getfile(self, which):
- got = ""
- for r in self.builder.updates:
- if r.has_key(which):
- got += r[which]
- return got
-
- def checkOutput(self, expected):
- """
- @type expected: list of (streamname, contents) tuples
- @param expected: the expected output
- """
- expected_linesep = os.linesep
- if self.usePTY:
- # PTYs change the line ending. I'm not sure why.
- expected_linesep = "\r\n"
- expected = [(stream, contents.replace("\n", expected_linesep, 1000))
- for (stream, contents) in expected]
- if self.usePTY:
- # PTYs merge stdout+stderr into a single stream
- expected = [('stdout', contents)
- for (stream, contents) in expected]
- # now merge everything into one string per stream
- streams = {}
- for (stream, contents) in expected:
- streams[stream] = streams.get(stream, "") + contents
- for (stream, contents) in streams.items():
- got = self.getfile(stream)
- self.assertEquals(got, contents)
-
- def getrc(self):
- # updates[-2] is the rc, unless the step was interrupted
- # updates[-1] is the elapsed-time header
- u = self.builder.updates[-1]
- if "rc" not in u:
- self.failUnless(len(self.builder.updates) >= 2)
- u = self.builder.updates[-2]
- self.failUnless("rc" in u)
- return u['rc']
- def checkrc(self, expected):
- got = self.getrc()
- self.assertEquals(got, expected)
-
- def testShell1(self):
- targetfile = os.path.join(self.basedir, "log1.out")
- if os.path.exists(targetfile):
- os.unlink(targetfile)
- cmd = "%s %s 0" % (sys.executable, self.emitcmd)
- args = {'command': cmd, 'workdir': '.', 'timeout': 60}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- expected = [('stdout', "this is stdout\n"),
- ('stderr', "this is stderr\n")]
- d.addCallback(self._checkPass, expected, 0)
- def _check_targetfile(res):
- self.failUnless(os.path.exists(targetfile))
- d.addCallback(_check_targetfile)
- return d
-
- def _checkPass(self, res, expected, rc):
- self.checkOutput(expected)
- self.checkrc(rc)
-
- def testShell2(self):
- cmd = [sys.executable, self.emitcmd, "0"]
- args = {'command': cmd, 'workdir': '.', 'timeout': 60}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- expected = [('stdout', "this is stdout\n"),
- ('stderr', "this is stderr\n")]
- d.addCallback(self._checkPass, expected, 0)
- return d
-
- def testShellRC(self):
- cmd = [sys.executable, self.emitcmd, "1"]
- args = {'command': cmd, 'workdir': '.', 'timeout': 60}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- expected = [('stdout', "this is stdout\n"),
- ('stderr', "this is stderr\n")]
- d.addCallback(self._checkPass, expected, 1)
- return d
-
- def testShellEnv(self):
- cmd = "%s %s 0" % (sys.executable, self.emitcmd)
- args = {'command': cmd, 'workdir': '.',
- 'env': {'EMIT_TEST': "envtest"}, 'timeout': 60}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- expected = [('stdout', "this is stdout\n"),
- ('stderr', "this is stderr\n"),
- ('stdout', "EMIT_TEST: envtest\n"),
- ]
- d.addCallback(self._checkPass, expected, 0)
- return d
-
- def testShellSubdir(self):
- targetfile = os.path.join(self.basedir, "subdir", "log1.out")
- if os.path.exists(targetfile):
- os.unlink(targetfile)
- cmd = "%s %s 0" % (sys.executable, self.subemitcmd)
- args = {'command': cmd, 'workdir': "subdir", 'timeout': 60}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- expected = [('stdout', "this is stdout in subdir\n"),
- ('stderr', "this is stderr\n")]
- d.addCallback(self._checkPass, expected, 0)
- def _check_targetfile(res):
- self.failUnless(os.path.exists(targetfile))
- d.addCallback(_check_targetfile)
- return d
-
- def testShellMissingCommand(self):
- args = {'command': "/bin/EndWorldHungerAndMakePigsFly",
- 'workdir': '.', 'timeout': 10,
- 'env': {"LC_ALL": "C"},
- }
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- d.addCallback(self._testShellMissingCommand_1)
- return d
- def _testShellMissingCommand_1(self, res):
- self.failIfEqual(self.getrc(), 0)
- # we used to check the error message to make sure it said something
- # about a missing command, but there are a variety of shells out
- # there, and they emit message sin a variety of languages, so we
- # stopped trying.
-
- def testTimeout(self):
- args = {'command': [sys.executable, self.sleepcmd, "10"],
- 'workdir': '.', 'timeout': 2}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- d.addCallback(self._testTimeout_1)
- return d
- def _testTimeout_1(self, res):
- self.failIfEqual(self.getrc(), 0)
- got = self.getfile('header')
- self.failUnlessIn("command timed out: 2 seconds without output", got)
- if runtime.platformType == "posix":
- # the "killing pid" message is not present in windows
- self.failUnlessIn("killing pid", got)
- # but the process *ought* to be killed somehow
- self.failUnlessIn("process killed by signal", got)
- #print got
- if runtime.platformType != 'posix':
- testTimeout.todo = "timeout doesn't appear to work under windows"
-
- def testInterrupt1(self):
- args = {'command': [sys.executable, self.sleepcmd, "10"],
- 'workdir': '.', 'timeout': 20}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- reactor.callLater(1, c.interrupt)
- d.addCallback(self._testInterrupt1_1)
- return d
- def _testInterrupt1_1(self, res):
- self.failIfEqual(self.getrc(), 0)
- got = self.getfile('header')
- self.failUnlessIn("command interrupted", got)
- if runtime.platformType == "posix":
- self.failUnlessIn("process killed by signal", got)
- if runtime.platformType != 'posix':
- testInterrupt1.todo = "interrupt doesn't appear to work under windows"
-
-
- # todo: twisted-specific command tests
-
-class Shell(ShellBase, unittest.TestCase):
- usePTY = False
-
- def testInterrupt2(self):
- # test the backup timeout. This doesn't work under a PTY, because the
- # transport.loseConnection we do in the timeout handler actually
- # *does* kill the process.
- args = {'command': [sys.executable, self.sleepcmd, "5"],
- 'workdir': '.', 'timeout': 20}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- c.command.BACKUP_TIMEOUT = 1
- # make it unable to kill the child, by changing the signal it uses
- # from SIGKILL to the do-nothing signal 0.
- c.command.KILL = None
- reactor.callLater(1, c.interrupt)
- d.addBoth(self._testInterrupt2_1)
- return d
- def _testInterrupt2_1(self, res):
- # the slave should raise a TimeoutError exception. In a normal build
- # process (i.e. one that uses step.RemoteShellCommand), this
- # exception will be handed to the Step, which will acquire an ERROR
- # status. In our test environment, it isn't such a big deal.
- self.failUnless(isinstance(res, failure.Failure),
- "res is not a Failure: %s" % (res,))
- self.failUnless(res.check(commands.TimeoutError))
- self.checkrc(-1)
- return
- # the command is still actually running. Start another command, to
- # make sure that a) the old command's output doesn't interfere with
- # the new one, and b) the old command's actual termination doesn't
- # break anything
- args = {'command': [sys.executable, self.sleepcmd, "5"],
- 'workdir': '.', 'timeout': 20}
- c = SlaveShellCommand(self.builder, None, args)
- d = c.start()
- d.addCallback(self._testInterrupt2_2)
- return d
- def _testInterrupt2_2(self, res):
- self.checkrc(0)
- # N.B.: under windows, the trial process hangs out for another few
- # seconds. I assume that the win32eventreactor is waiting for one of
- # the lingering child processes to really finish.
-
-haveProcess = interfaces.IReactorProcess(reactor, None)
-if runtime.platformType == 'posix':
- # test with PTYs also
- class ShellPTY(ShellBase, unittest.TestCase):
- usePTY = True
- if not haveProcess:
- ShellPTY.skip = "this reactor doesn't support IReactorProcess"
-if not haveProcess:
- Shell.skip = "this reactor doesn't support IReactorProcess"