diff options
Diffstat (limited to 'buildbot/buildbot/test/test_slavecommand.py')
-rw-r--r-- | buildbot/buildbot/test/test_slavecommand.py | 294 |
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" |