Exemple #1
0
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.real_bot = base.BotBase(self.basedir, False)
        self.real_bot.startService()

        self.bot = FakeRemote(self.real_bot)
Exemple #2
0
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = base.BotBase(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        builders = yield self.bot.remote_setBuilderList([('sb', 'sb')])
        self.sb = FakeRemote(builders['sb'])

        self.setUpCommand()
    def test_truncated(self):
        self.fakemaster.count_writes = True  # get actual byte counts

        self.make_command(
            transfer.SlaveFileUploadCommand,
            dict(
                workdir='workdir',
                slavesrc='data',
                writer=FakeRemote(self.fakemaster),
                maxsize=100,
                blocksize=64,
                keepstamp=False,
            ))

        d = self.run_command()

        def check(_):
            self.assertUpdates([{
                'header': 'sending %s' % self.datafile
            }, 'write 64', 'write 36', 'close', {
                'rc':
                1,
                'stderr':
                "Maximum filesize reached, truncating file '%s'" %
                self.datafile
            }])

        d.addCallback(check)
        return d
Exemple #4
0
    def test_simple(self):
        self.fakemaster.count_writes = True  # get actual byte counts

        self.make_command(
            transfer.SlaveFileUploadCommand,
            dict(
                workdir='workdir',
                slavesrc='data',
                writer=FakeRemote(self.fakemaster),
                maxsize=1000,
                blocksize=64,
            ))

        d = self.run_command()

        def check(_):
            self.assertEqual(self.get_updates(),
                             [{
                                 'header': 'sending %s' % self.datafile
                             }, 'write 64', 'write 64', 'write 52', 'close', {
                                 'rc': 0
                             }])

        d.addCallback(check)
        return d
Exemple #5
0
    def test_mkdir(self):
        self.fakemaster.data = test_data = 'hi'

        self.make_command(
            transfer.SlaveFileDownloadCommand,
            dict(
                workdir='workdir',
                slavedest=os.path.join('subdir', 'data'),
                reader=FakeRemote(self.fakemaster),
                maxsize=None,
                blocksize=32,
                mode=0777,
            ))

        d = self.run_command()

        def check(_):
            self.assertEqual(self.get_updates(),
                             ['read(s)', 'close', {
                                 'rc': 0
                             }])
            datafile = os.path.join(self.basedir, 'workdir', 'subdir', 'data')
            self.assertTrue(os.path.exists(datafile))
            self.assertEqual(open(datafile).read(), test_data)

        d.addCallback(check)
        return d
    def test_missing(self):
        self.make_command(
            transfer.SlaveFileUploadCommand,
            dict(
                workdir='workdir',
                slavesrc='data-nosuch',
                writer=FakeRemote(self.fakemaster),
                maxsize=100,
                blocksize=64,
                keepstamp=False,
            ))

        d = self.run_command()

        def check(_):
            df = self.datafile + "-nosuch"
            self.assertUpdates([{
                'header': 'sending %s' % df
            }, 'close', {
                'rc':
                1,
                'stderr':
                "Cannot open file '%s' for upload" % df
            }])

        d.addCallback(check)
        return d
    def test_out_of_space_unpack(self):
        self.fakemaster.keep_data = True
        self.fakemaster.unpack_fail = True

        self.make_command(
            transfer.SlaveDirectoryUploadCommand,
            dict(workdir='workdir',
                 slavesrc='data',
                 writer=FakeRemote(self.fakemaster),
                 maxsize=None,
                 blocksize=512,
                 compress=None))

        d = self.run_command()
        self.assertFailure(d, RuntimeError)

        def check(_):
            self.assertUpdates([{
                'header': 'sending %s' % self.datadir
            }, 'write(s)', 'unpack', {
                'rc': 1
            }])

        d.addCallback(check)

        return d
    def test_timestamp(self):
        self.fakemaster.count_writes = True  # get actual byte counts
        timestamp = (os.path.getatime(self.datafile),
                     os.path.getmtime(self.datafile))

        self.make_command(
            transfer.SlaveFileUploadCommand,
            dict(
                workdir='workdir',
                slavesrc='data',
                writer=FakeRemote(self.fakemaster),
                maxsize=1000,
                blocksize=64,
                keepstamp=True,
            ))

        d = self.run_command()

        def check(_):
            self.assertUpdates([{
                'header': 'sending %s' % self.datafile
            }, 'write 64', 'write 64', 'write 52', 'close',
                                'utime - %s' % timestamp[0], {
                                    'rc': 0
                                }])

        d.addCallback(check)
        return d
    def test_failure(self):
        self.fakemaster.data = 'hi'

        os.makedirs(os.path.join(self.basedir, 'dir'))
        self.make_command(
            transfer.SlaveFileDownloadCommand,
            dict(
                workdir='.',
                slavedest='dir',  ## but that's a directory!
                reader=FakeRemote(self.fakemaster),
                maxsize=None,
                blocksize=32,
                mode=0777,
            ))

        d = self.run_command()

        def check(_):
            self.assertUpdates([
                'close', {
                    'rc':
                    1,
                    'stderr':
                    "Cannot open file '%s' for download" %
                    os.path.join(self.basedir, '.', 'dir')
                }
            ])

        d.addCallback(check)
        return d
    def test_simple(self):
        self.fakemaster.count_reads = True  # get actual byte counts
        self.fakemaster.data = test_data = '1234' * 13
        assert (len(self.fakemaster.data) == 52)

        self.make_command(
            transfer.SlaveFileDownloadCommand,
            dict(
                workdir='.',
                slavedest='data',
                reader=FakeRemote(self.fakemaster),
                maxsize=None,
                blocksize=32,
                mode=0777,
            ))

        d = self.run_command()

        def check(_):
            self.assertUpdates(
                ['read 32', 'read 32', 'read 32', 'close', {
                    'rc': 0
                }])
            datafile = os.path.join(self.basedir, 'data')
            self.assertTrue(os.path.exists(datafile))
            self.assertEqual(open(datafile).read(), test_data)
            if runtime.platformType != 'win32':
                self.assertEqual(os.stat(datafile).st_mode & 0777, 0777)

        d.addCallback(check)
        return d
    def test_interrupted(self):
        self.fakemaster.data = 'tenchars--' * 100  # 1k
        self.fakemaster.delay_read = True  # read veery slowly

        self.make_command(
            transfer.SlaveFileDownloadCommand,
            dict(
                workdir='.',
                slavedest='data',
                reader=FakeRemote(self.fakemaster),
                maxsize=100,
                blocksize=2,
                mode=0777,
            ))

        d = self.run_command()

        # wait a jiffy..
        interrupt_d = defer.Deferred()
        reactor.callLater(0.01, interrupt_d.callback, None)

        # and then interrupt the step
        def do_interrupt(_):
            return self.cmd.interrupt()

        interrupt_d.addCallback(do_interrupt)

        dl = defer.DeferredList([d, interrupt_d])

        def check(_):
            self.assertUpdates(['read(s)', 'close', {'rc': 1}])

        dl.addCallback(check)
        return dl
    def test_truncated(self):
        self.fakemaster.data = test_data = 'tenchars--' * 10

        self.make_command(
            transfer.SlaveFileDownloadCommand,
            dict(
                workdir='.',
                slavedest='data',
                reader=FakeRemote(self.fakemaster),
                maxsize=50,
                blocksize=32,
                mode=0777,
            ))

        d = self.run_command()

        def check(_):
            self.assertUpdates([
                'read(s)', 'close', {
                    'rc':
                    1,
                    'stderr':
                    "Maximum filesize reached, truncating file '%s'" %
                    os.path.join(self.basedir, '.', 'data')
                }
            ])
            datafile = os.path.join(self.basedir, 'data')
            self.assertTrue(os.path.exists(datafile))
            self.assertEqual(open(datafile).read(), test_data[:50])

        d.addCallback(check)
        return d
Exemple #13
0
 def do_start(_):
     return self.sb.callRemote(
         "startCommand", FakeRemote(st), "13", "shell",
         dict(
             command=['sleep', '10'],
             workdir='workdir',
         ))
    def test_simple(self, compress=None):
        self.fakemaster.keep_data = True

        self.make_command(transfer.SlaveDirectoryUploadCommand, dict(
            workdir='workdir',
            slavesrc='data',
            writer=FakeRemote(self.fakemaster),
            maxsize=None,
            blocksize=512,
            compress=compress,
        ))

        d = self.run_command()

        def check(_):
            self.assertUpdates([
                {'header': 'sending %s' % self.datadir},
                'write(s)', 'unpack',  # note no 'close"
                {'rc': 0}
            ])
        d.addCallback(check)

        def check_tarfile(_):
            f = io.BytesIO(self.fakemaster.data)
            a = tarfile.open(fileobj=f, name='check.tar')
            exp_names = ['.', 'aa', 'bb']
            got_names = [n.rstrip('/') for n in a.getnames()]
            # py27 uses '' instead of '.'
            got_names = sorted([n or '.' for n in got_names])
            self.assertEqual(got_names, exp_names, "expected archive contents")
            a.close()
            f.close()
        d.addCallback(check_tarfile)

        return d
    def test_interrupted(self):
        self.fakemaster.delay_write = True  # write veery slowly

        self.make_command(transfer.SlaveFileUploadCommand, dict(
            workdir='workdir',
            slavesrc='data',
            writer=FakeRemote(self.fakemaster),
            maxsize=100,
            blocksize=2,
            keepstamp=False,
        ))

        d = self.run_command()

        # wait a jiffy..
        interrupt_d = defer.Deferred()
        reactor.callLater(0.01, interrupt_d.callback, None)

        # and then interrupt the step
        def do_interrupt(_):
            return self.cmd.interrupt()
        interrupt_d.addCallback(do_interrupt)

        dl = defer.DeferredList([d, interrupt_d])

        def check(_):
            self.assertUpdates([
                {'header': 'sending %s' % self.datafile},
                'write(s)', 'close', {'rc': 1}
            ])
        dl.addCallback(check)
        return dl
    def test_out_of_space(self):
        self.fakemaster.write_out_of_space_at = 70
        self.fakemaster.count_writes = True  # get actual byte counts

        self.make_command(
            transfer.SlaveFileUploadCommand,
            dict(
                workdir='workdir',
                slavesrc='data',
                writer=FakeRemote(self.fakemaster),
                maxsize=1000,
                blocksize=64,
                keepstamp=False,
            ))

        d = self.run_command()
        self.assertFailure(d, RuntimeError)

        def check(_):
            self.assertUpdates([{
                'header': 'sending %s' % self.datafile
            }, 'write 64', 'close', {
                'rc': 1
            }])

        d.addCallback(check)
        return d
Exemple #17
0
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = bot.Bot(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        wfd = defer.waitForDeferred(
            self.bot.remote_setBuilderList([('sb', 'sb')]))
        yield wfd
        builders = wfd.getResult()
        self.sb = FakeRemote(builders['sb'])

        self.setUpCommand()
Exemple #18
0
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.real_bot = base.BotBase(self.basedir, False)
        self.real_bot.startService()

        self.bot = FakeRemote(self.real_bot)
Exemple #19
0
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = base.BotBase(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        builders = yield self.bot.remote_setBuilderList([("sb", "sb")])
        self.sb = FakeRemote(builders["sb"])

        self.setUpCommand()
Exemple #20
0
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = bot.Bot(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        wfd = defer.waitForDeferred(
            self.bot.remote_setBuilderList([('sb', 'sb')]))
        yield wfd
        builders = wfd.getResult()
        self.sb = FakeRemote(builders['sb'])

        self.setUpCommand()
Exemple #21
0
 def setUp(self):
     self.slavebuilder = FakeSlaveBuilder()
     self.pbbuilder = bot.PBSlaveBuilder(self.slavebuilder)
     self.sb = FakeRemote(self.pbbuilder)
Exemple #22
0
class TestBot(unittest.TestCase):
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.real_bot = base.BotBase(self.basedir, False)
        self.real_bot.startService()

        self.bot = FakeRemote(self.real_bot)

    def tearDown(self):
        d = defer.succeed(None)
        if self.real_bot and self.real_bot.running:
            d.addCallback(lambda _: self.real_bot.stopService())
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        return d

    def test_getCommands(self):
        d = self.bot.callRemote("getCommands")

        def check(cmds):
            # just check that 'shell' is present..
            self.assertTrue("shell" in cmds)

        d.addCallback(check)
        return d

    def test_getVersion(self):
        d = self.bot.callRemote("getVersion")

        def check(vers):
            self.assertEqual(vers, buildslave.version)

        d.addCallback(check)
        return d

    def test_getSlaveInfo(self):
        infodir = os.path.join(self.basedir, "info")
        os.makedirs(infodir)
        open(os.path.join(infodir, "admin"), "w").write("testy!")
        open(os.path.join(infodir, "foo"), "w").write("bar")
        open(os.path.join(infodir, "environ"), "w").write("something else")

        d = self.bot.callRemote("getSlaveInfo")

        def check(info):
            self.assertEqual(
                info,
                dict(
                    admin="testy!",
                    foo="bar",
                    environ=os.environ,
                    system=os.name,
                    basedir=self.basedir,
                    slave_commands=self.real_bot.remote_getCommands(),
                    version=self.real_bot.remote_getVersion(),
                ),
            )

        d.addCallback(check)
        return d

    def test_getSlaveInfo_nodir(self):
        d = self.bot.callRemote("getSlaveInfo")

        def check(info):
            self.assertEqual(set(info.keys()), set(["environ", "system", "basedir", "slave_commands", "version"]))

        d.addCallback(check)
        return d

    def test_setBuilderList_empty(self):
        d = self.bot.callRemote("setBuilderList", [])

        def check(builders):
            self.assertEqual(builders, {})

        d.addCallback(check)
        return d

    def test_setBuilderList_single(self):
        d = self.bot.callRemote("setBuilderList", [("mybld", "myblddir")])

        def check(builders):
            self.assertEqual(list(builders), ["mybld"])
            self.assertTrue(os.path.exists(os.path.join(self.basedir, "myblddir")))
            # note that we test the SlaveBuilder instance below

        d.addCallback(check)
        return d

    def test_setBuilderList_updates(self):
        d = defer.succeed(None)

        slavebuilders = {}

        def add_my(_):
            d = self.bot.callRemote("setBuilderList", [("mybld", "myblddir")])

            def check(builders):
                self.assertEqual(list(builders), ["mybld"])
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "myblddir")))
                slavebuilders["my"] = builders["mybld"]

            d.addCallback(check)
            return d

        d.addCallback(add_my)

        def add_your(_):
            d = self.bot.callRemote("setBuilderList", [("mybld", "myblddir"), ("yourbld", "yourblddir")])

            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(["mybld", "yourbld"]))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "myblddir")))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "yourblddir")))
                # 'my' should still be the same slavebuilder object
                self.assertEqual(id(slavebuilders["my"]), id(builders["mybld"]))
                slavebuilders["your"] = builders["yourbld"]

            d.addCallback(check)
            return d

        d.addCallback(add_your)

        def remove_my(_):
            d = self.bot.callRemote("setBuilderList", [("yourbld", "yourblddir2")])  # note new builddir

            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(["yourbld"]))
                # note that build dirs are not deleted..
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "myblddir")))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "yourblddir")))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "yourblddir2")))
                # 'your' should still be the same slavebuilder object
                self.assertEqual(id(slavebuilders["your"]), id(builders["yourbld"]))

            d.addCallback(check)
            return d

        d.addCallback(remove_my)

        def add_and_remove(_):
            d = self.bot.callRemote("setBuilderList", [("theirbld", "theirblddir")])

            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(["theirbld"]))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "myblddir")))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "yourblddir")))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, "theirblddir")))

            d.addCallback(check)
            return d

        d.addCallback(add_and_remove)

        return d

    def test_shutdown(self):
        d1 = defer.Deferred()
        self.patch(reactor, "stop", lambda: d1.callback(None))
        d2 = self.bot.callRemote("shutdown")
        # don't return until both the shutdown method has returned, and
        # reactor.stop has been called
        return defer.gatherResults([d1, d2])
Exemple #23
0
class TestSlaveBuilder(command.CommandTestMixin, unittest.TestCase):
    @defer.inlineCallbacks
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = base.BotBase(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        builders = yield self.bot.remote_setBuilderList([("sb", "sb")])
        self.sb = FakeRemote(builders["sb"])

        self.setUpCommand()

    def tearDown(self):
        self.tearDownCommand()

        d = defer.succeed(None)
        if self.bot and self.bot.running:
            d.addCallback(lambda _: self.bot.stopService())
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        return d

    def test_print(self):
        return self.sb.callRemote("print", "Hello, SlaveBuilder.")

    def test_setMaster(self):
        # not much to check here - what the SlaveBuilder does with the
        # master is not part of the interface (and, in fact, it does very little)
        return self.sb.callRemote("setMaster", mock.Mock())

    def test_shutdown(self):
        # don't *actually* shut down the reactor - that would be silly
        stop = mock.Mock()
        self.patch(reactor, "stop", stop)
        d = self.sb.callRemote("shutdown")

        def check(_):
            self.assertTrue(stop.called)

        d.addCallback(check)
        return d

    def test_startBuild(self):
        return self.sb.callRemote("startBuild")

    def test_startCommand(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to handle the 'echo', below
        self.patch_runprocess(
            Expect(["echo", "hello"], os.path.join(self.basedir, "sb", "workdir"))
            + {"hdr": "headers"}
            + {"stdout": "hello\n"}
            + {"rc": 0}
            + 0
        )

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote(
                "startCommand", FakeRemote(st), "13", "shell", dict(command=["echo", "hello"], workdir="workdir")
            )

        d.addCallback(do_start)
        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(
                st.actions,
                [
                    ["update", [[{"hdr": "headers"}, 0]]],
                    ["update", [[{"stdout": "hello\n"}, 0]]],
                    ["update", [[{"rc": 0}, 0]]],
                    ["update", [[{"elapsed": 1}, 0]]],
                    ["complete", None],
                ],
            )

        d.addCallback(check)
        return d

    def test_startCommand_interruptCommand(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to pretend to sleep (it will really just hang forever,
        # except that we interrupt it)
        self.patch_runprocess(
            Expect(["sleep", "10"], os.path.join(self.basedir, "sb", "workdir")) + {"hdr": "headers"} + {"wait": True}
        )

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote(
                "startCommand", FakeRemote(st), "13", "shell", dict(command=["sleep", "10"], workdir="workdir")
            )

        d.addCallback(do_start)

        # wait a jiffy..
        def do_wait(_):
            d = defer.Deferred()
            reactor.callLater(0.01, d.callback, None)
            return d

        d.addCallback(do_wait)

        # and then interrupt the step
        def do_interrupt(_):
            return self.sb.callRemote("interruptCommand", "13", "tl/dr")

        d.addCallback(do_interrupt)

        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(
                st.actions,
                [
                    ["update", [[{"hdr": "headers"}, 0]]],
                    ["update", [[{"hdr": "killing"}, 0]]],
                    ["update", [[{"rc": -1}, 0]]],
                    ["complete", None],
                ],
            )

        d.addCallback(check)
        return d

    def test_startCommand_failure(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to generate a failure
        self.patch_runprocess(
            Expect(["sleep", "10"], os.path.join(self.basedir, "sb", "workdir")) + failure.Failure(Exception("Oops"))
        )
        # patch the log.err, otherwise trial will think something *actually* failed
        self.patch(log, "err", lambda f: None)

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote(
                "startCommand", FakeRemote(st), "13", "shell", dict(command=["sleep", "10"], workdir="workdir")
            )

        d.addCallback(do_start)
        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions[1][0], "complete")
            self.assertTrue(isinstance(st.actions[1][1], failure.Failure))

        d.addCallback(check)
        return d

    def test_startCommand_missing_args(self):
        # set up a fake step to receive updates
        st = FakeStep()

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote("startCommand", FakeRemote(st), "13", "shell", dict())

        d.addCallback(do_start)
        d.addCallback(lambda _: self.assertTrue(False))
        d.addErrback(lambda _: True)
        return d
Exemple #24
0
class TestSlaveBuilder(command.CommandTestMixin, unittest.TestCase):
    @defer.inlineCallbacks
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = base.BotBase(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        builders = yield self.bot.remote_setBuilderList([('sb', 'sb')])
        self.sb = FakeRemote(builders['sb'])

        self.setUpCommand()

    def tearDown(self):
        self.tearDownCommand()

        d = defer.succeed(None)
        if self.bot and self.bot.running:
            d.addCallback(lambda _: self.bot.stopService())
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        return d

    def test_print(self):
        return self.sb.callRemote("print", "Hello, SlaveBuilder.")

    def test_setMaster(self):
        # not much to check here - what the SlaveBuilder does with the
        # master is not part of the interface (and, in fact, it does very little)
        return self.sb.callRemote("setMaster", mock.Mock())

    def test_shutdown(self):
        # don't *actually* shut down the reactor - that would be silly
        stop = mock.Mock()
        self.patch(reactor, "stop", stop)
        d = self.sb.callRemote("shutdown")

        def check(_):
            self.assertTrue(stop.called)

        d.addCallback(check)
        return d

    def test_startBuild(self):
        return self.sb.callRemote("startBuild")

    def test_startCommand(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to handle the 'echo', below
        self.patch_runprocess(
            Expect(['echo', 'hello'],
                   os.path.join(self.basedir, 'sb', 'workdir')) +
            {'hdr': 'headers'} + {'stdout': 'hello\n'} + {'rc': 0} + 0, )

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote(
                "startCommand", FakeRemote(st), "13", "shell",
                dict(command=['echo', 'hello'], workdir='workdir'))

        d.addCallback(do_start)
        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions, [
                ['update', [[{
                    'hdr': 'headers'
                }, 0]]],
                ['update', [[{
                    'stdout': 'hello\n'
                }, 0]]],
                ['update', [[{
                    'rc': 0
                }, 0]]],
                ['update', [[{
                    'elapsed': 1
                }, 0]]],
                ['complete', None],
            ])

        d.addCallback(check)
        return d

    def test_startCommand_interruptCommand(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to pretend to sleep (it will really just hang forever,
        # except that we interrupt it)
        self.patch_runprocess(
            Expect(['sleep', '10'], os.path.join(
                self.basedir, 'sb', 'workdir')) + {'hdr': 'headers'} +
            {'wait': True})

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote(
                "startCommand", FakeRemote(st), "13", "shell",
                dict(command=['sleep', '10'], workdir='workdir'))

        d.addCallback(do_start)

        # wait a jiffy..
        def do_wait(_):
            d = defer.Deferred()
            reactor.callLater(0.01, d.callback, None)
            return d

        d.addCallback(do_wait)

        # and then interrupt the step
        def do_interrupt(_):
            return self.sb.callRemote("interruptCommand", "13", "tl/dr")

        d.addCallback(do_interrupt)

        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions, [
                ['update', [[{
                    'hdr': 'headers'
                }, 0]]],
                ['update', [[{
                    'hdr': 'killing'
                }, 0]]],
                ['update', [[{
                    'rc': -1
                }, 0]]],
                ['complete', None],
            ])

        d.addCallback(check)
        return d

    def test_startCommand_failure(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to generate a failure
        self.patch_runprocess(
            Expect(['sleep', '10'], os.path.join(self.basedir, 'sb',
                                                 'workdir')) +
            failure.Failure(Exception("Oops")))
        # patch the log.err, otherwise trial will think something *actually* failed
        self.patch(log, "err", lambda f: None)

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote(
                "startCommand", FakeRemote(st), "13", "shell",
                dict(command=['sleep', '10'], workdir='workdir'))

        d.addCallback(do_start)
        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions[1][0], 'complete')
            self.assertTrue(isinstance(st.actions[1][1], failure.Failure))

        d.addCallback(check)
        return d

    def test_startCommand_missing_args(self):
        # set up a fake step to receive updates
        st = FakeStep()

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote("startCommand", FakeRemote(st), "13",
                                      "shell", dict())

        d.addCallback(do_start)
        d.addCallback(lambda _: self.assertTrue(False))
        d.addErrback(lambda _: True)
        return d
Exemple #25
0
class TestSlaveBuilder(command.CommandTestMixin, unittest.TestCase):

    @defer.deferredGenerator
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.bot = bot.Bot(self.basedir, False)
        self.bot.startService()

        # get a SlaveBuilder object from the bot and wrap it as a fake remote
        wfd = defer.waitForDeferred(
            self.bot.remote_setBuilderList([('sb', 'sb')]))
        yield wfd
        builders = wfd.getResult()
        self.sb = FakeRemote(builders['sb'])

        self.setUpCommand()

    def tearDown(self):
        self.tearDownCommand()

        d = defer.succeed(None)
        if self.bot and self.bot.running:
            d.addCallback(lambda _: self.bot.stopService())
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        return d

    def test_print(self):
        return self.sb.callRemote("print", "Hello, SlaveBuilder.")

    def test_setMaster(self):
        # not much to check here - what the SlaveBuilder does with the
        # master is not part of the interface (and, in fact, it does very little)
        return self.sb.callRemote("setMaster", mock.Mock())

    def test_shutdown(self):
        # don't *actually* shut down the reactor - that would be silly
        stop = mock.Mock()
        self.patch(reactor, "stop", stop)
        d = self.sb.callRemote("shutdown")

        def check(_):
            self.assertTrue(stop.called)
        d.addCallback(check)
        return d

    def test_startBuild(self):
        return self.sb.callRemote("startBuild")

    def test_startCommand(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to handle the 'echo', below
        self.patch_runprocess(
            Expect(['echo', 'hello'], os.path.join(self.basedir, 'sb', 'workdir'))
            + {'hdr': 'headers'} + {'stdout': 'hello\n'} + {'rc': 0}
            + 0,
        )

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote("startCommand", FakeRemote(st),
                                      "13", "shell", dict(
                                          command=['echo', 'hello'],
                                          workdir='workdir',
                                      ))
        d.addCallback(do_start)
        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions, [
                ['update', [[{'hdr': 'headers'}, 0]]],
                ['update', [[{'stdout': 'hello\n'}, 0]]],
                ['update', [[{'rc': 0}, 0]]],
                ['update', [[{'elapsed': 1}, 0]]],
                ['complete', None],
            ])
        d.addCallback(check)
        return d

    def test_startCommand_interruptCommand(self):
        # set up a fake step to receive updates
        st = FakeStep()

        # patch runprocess to pretend to sleep (it will really just hang forever,
        # except that we interrupt it)
        self.patch_runprocess(
            Expect(['sleep', '10'], os.path.join(self.basedir, 'sb', 'workdir'))
            + {'hdr': 'headers'}
            + {'wait': True}
        )

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote("startCommand", FakeRemote(st),
                                      "13", "shell", dict(
                                          command=['sleep', '10'],
                                          workdir='workdir',
                                      ))
        d.addCallback(do_start)

        # wait a jiffy..
        def do_wait(_):
            d = defer.Deferred()
            reactor.callLater(0.01, d.callback, None)
            return d
        d.addCallback(do_wait)

        # and then interrupt the step
        def do_interrupt(_):
            return self.sb.callRemote("interruptCommand", "13", "tl/dr")
        d.addCallback(do_interrupt)

        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions, [
                ['update', [[{'hdr': 'headers'}, 0]]],
                ['update', [[{'hdr': 'killing'}, 0]]],
                ['update', [[{'rc': -1}, 0]]],
                ['complete', None],
            ])
        d.addCallback(check)
        return d

    def test_startCommand_failure(self):
        # similar to test_startCommand, but leave out some args so the slave
        # generates a failure

        # set up a fake step to receive updates
        st = FakeStep()

        # patch the log.err, otherwise trial will think something *actually* failed
        self.patch(log, "err", lambda f: None)

        d = defer.succeed(None)

        def do_start(_):
            return self.sb.callRemote("startCommand", FakeRemote(st),
                                      "13", "shell", dict(
                                          workdir='workdir',
                                      ))
        d.addCallback(do_start)
        d.addCallback(lambda _: st.wait_for_finish())

        def check(_):
            self.assertEqual(st.actions[1][0], 'complete')
            self.assertTrue(isinstance(st.actions[1][1], failure.Failure))
        d.addCallback(check)
        return d
Exemple #26
0
class TestPBSlaveBuilder(unittest.TestCase):

    def setUp(self):
        self.slavebuilder = FakeSlaveBuilder()
        self.pbbuilder = bot.PBSlaveBuilder(self.slavebuilder)
        self.sb = FakeRemote(self.pbbuilder)

    def tearDown(self):
        pass

    def test_startBuild(self):
        self.slavebuilder.startBuild = Mock()
        self.sb.callRemote("startBuild")
        self.slavebuilder.startBuild.assert_called_with()

    def test_shutdown(self):
        # don't *actually* shut down the reactor - that would be silly
        stop = mock.Mock()
        self.patch(reactor, "stop", stop)
        d = self.sb.callRemote("shutdown")
        def check(_):
            self.assertTrue(stop.called)
        d.addCallback(check)
        return d

    def test_setMaster(self):
        # not much to check here - what the SlaveBuilder does with the
        # master is not part of the interface (and, in fact, it does very little)
        return self.sb.callRemote("setMaster", mock.Mock())

    def test_startCommand(self):
        st = FakeStep()
        self.slavebuilder.startCommand = Mock()

        self.sb.callRemote("startCommand", FakeRemote(st),
                                      "13", "shell", dict(
                                                command=[ 'echo', 'hello' ],
                                                workdir='workdir',
                                            ))
        self.slavebuilder.startCommand.assert_called_with("13", "shell", dict(
                                                command=[ 'echo', 'hello' ],
                                                workdir='workdir',
                                            ) )

    def test_interruptCommand(self):
        self.slavebuilder.interruptCommand = Mock()

        self.sb.callRemote("interruptCommand", "13", "tl/dr" )
        self.slavebuilder.interruptCommand.assert_called_with("13", "tl/dr")

    def test_print(self):
        self.slavebuilder.printMessage = Mock()

        self.sb.callRemote("print", "Hello, SlaveBuilder.")
        self.slavebuilder.printMessage.assert_called_with("Hello, SlaveBuilder.")

    def test_sendUpdates(self):
        st = FakeStep()
        self.pbbuilder.remoteStep = FakeRemote(st)

        self.pbbuilder.remoteStep.callRemote("update", [[{'hdr': 'headers'}, 0]])
        self.assertEqual(st.actions, [
                      ['update', [[{'hdr': 'headers'}, 0]]]
                                  ])

    def test_sendComplete(self):
        st = FakeStep()
        self.pbbuilder.remoteStep = FakeRemote(st)
        f = Mock()
        self.pbbuilder.remoteStep.callRemote("complete", f)
        self.assertEqual(st.actions, [['complete', f]])
Exemple #27
0
 def do_start(_):
     return self.sb.callRemote(
         "startCommand", FakeRemote(st), "13", "shell",
         dict(command=['echo', 'hello'], workdir='workdir'))
Exemple #28
0
class TestBot(unittest.TestCase):
    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.real_bot = base.BotBase(self.basedir, False)
        self.real_bot.startService()

        self.bot = FakeRemote(self.real_bot)

    def tearDown(self):
        d = defer.succeed(None)
        if self.real_bot and self.real_bot.running:
            d.addCallback(lambda _: self.real_bot.stopService())
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        return d

    def test_getCommands(self):
        d = self.bot.callRemote("getCommands")

        def check(cmds):
            # just check that 'shell' is present..
            self.assertTrue('shell' in cmds)

        d.addCallback(check)
        return d

    def test_getVersion(self):
        d = self.bot.callRemote("getVersion")

        def check(vers):
            self.assertEqual(vers, buildslave.version)

        d.addCallback(check)
        return d

    def test_getSlaveInfo(self):
        infodir = os.path.join(self.basedir, "info")
        os.makedirs(infodir)
        open(os.path.join(infodir, "admin"), "w").write("testy!")
        open(os.path.join(infodir, "foo"), "w").write("bar")
        open(os.path.join(infodir, "environ"), "w").write("something else")

        d = self.bot.callRemote("getSlaveInfo")

        def check(info):
            self.assertEqual(
                info,
                dict(admin='testy!',
                     foo='bar',
                     environ=os.environ,
                     system=os.name,
                     basedir=self.basedir,
                     slave_commands=self.real_bot.remote_getCommands(),
                     version=self.real_bot.remote_getVersion()))

        d.addCallback(check)
        return d

    def test_getSlaveInfo_nodir(self):
        d = self.bot.callRemote("getSlaveInfo")

        def check(info):
            self.assertEqual(
                set(info.keys()),
                set([
                    'environ', 'system', 'basedir', 'slave_commands', 'version'
                ]))

        d.addCallback(check)
        return d

    def test_setBuilderList_empty(self):
        d = self.bot.callRemote("setBuilderList", [])

        def check(builders):
            self.assertEqual(builders, {})

        d.addCallback(check)
        return d

    def test_setBuilderList_single(self):
        d = self.bot.callRemote("setBuilderList", [('mybld', 'myblddir')])

        def check(builders):
            self.assertEqual(builders.keys(), ['mybld'])
            self.assertTrue(
                os.path.exists(os.path.join(self.basedir, 'myblddir')))
            # note that we test the SlaveBuilder instance below

        d.addCallback(check)
        return d

    def test_setBuilderList_updates(self):
        d = defer.succeed(None)

        slavebuilders = {}

        def add_my(_):
            d = self.bot.callRemote("setBuilderList", [('mybld', 'myblddir')])

            def check(builders):
                self.assertEqual(builders.keys(), ['mybld'])
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'myblddir')))
                slavebuilders['my'] = builders['mybld']

            d.addCallback(check)
            return d

        d.addCallback(add_my)

        def add_your(_):
            d = self.bot.callRemote("setBuilderList",
                                    [('mybld', 'myblddir'),
                                     ('yourbld', 'yourblddir')])

            def check(builders):
                self.assertEqual(sorted(builders.keys()),
                                 sorted(['mybld', 'yourbld']))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'myblddir')))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'yourblddir')))
                # 'my' should still be the same slavebuilder object
                self.assertEqual(id(slavebuilders['my']),
                                 id(builders['mybld']))
                slavebuilders['your'] = builders['yourbld']

            d.addCallback(check)
            return d

        d.addCallback(add_your)

        def remove_my(_):
            d = self.bot.callRemote(
                "setBuilderList",
                [('yourbld', 'yourblddir2')])  # note new builddir

            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(['yourbld']))
                # note that build dirs are not deleted..
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'myblddir')))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'yourblddir')))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'yourblddir2')))
                # 'your' should still be the same slavebuilder object
                self.assertEqual(id(slavebuilders['your']),
                                 id(builders['yourbld']))

            d.addCallback(check)
            return d

        d.addCallback(remove_my)

        def add_and_remove(_):
            d = self.bot.callRemote("setBuilderList",
                                    [('theirbld', 'theirblddir')])

            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(['theirbld']))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'myblddir')))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'yourblddir')))
                self.assertTrue(
                    os.path.exists(os.path.join(self.basedir, 'theirblddir')))

            d.addCallback(check)
            return d

        d.addCallback(add_and_remove)

        return d

    def test_shutdown(self):
        d1 = defer.Deferred()
        self.patch(reactor, "stop", lambda: d1.callback(None))
        d2 = self.bot.callRemote("shutdown")
        # don't return until both the shutdown method has returned, and
        # reactor.stop has been called
        return defer.gatherResults([d1, d2])
Exemple #29
0
class TestBot(unittest.TestCase):

    def setUp(self):
        self.basedir = os.path.abspath("basedir")
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        os.makedirs(self.basedir)

        self.real_bot = bot.Bot(self.basedir, False)
        self.real_bot.startService()

        self.bot = FakeRemote(self.real_bot)

    def tearDown(self):
        d = defer.succeed(None)
        if self.real_bot and self.real_bot.running:
            d.addCallback(lambda _ : self.real_bot.stopService())
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)
        return d

    def test_getCommands(self):
        d = self.bot.callRemote("getCommands")
        def check(cmds):
            # just check that 'shell' is present..
            self.assertTrue('shell' in cmds)
        d.addCallback(check)
        return d

    def test_getVersion(self):
        d = self.bot.callRemote("getVersion")
        def check(vers):
            self.assertEqual(vers, buildslave.version)
        d.addCallback(check)
        return d

    def test_getSlaveInfo(self):
        infodir = os.path.join(self.basedir, "info")
        os.makedirs(infodir)
        open(os.path.join(infodir, "admin"), "w").write("testy!")
        open(os.path.join(infodir, "foo"), "w").write("bar")

        d = self.bot.callRemote("getSlaveInfo")
        def check(info):
            self.assertEqual(info, dict(admin='testy!', foo='bar'))
        d.addCallback(check)
        return d

    def test_getSlaveInfo_nodir(self):
        d = self.bot.callRemote("getSlaveInfo")
        def check(info):
            self.assertEqual(info, {})
        d.addCallback(check)
        return d

    def test_setBuilderList_empty(self):
        d = self.bot.callRemote("setBuilderList", [])
        def check(builders):
            self.assertEqual(builders, {})
        d.addCallback(check)
        return d

    def test_setBuilderList_single(self):
        d = self.bot.callRemote("setBuilderList", [ ('mybld', 'myblddir') ])
        def check(builders):
            self.assertEqual(builders.keys(), ['mybld'])
            self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
            # note that we test the SlaveBuilder instance below
        d.addCallback(check)
        return d

    def test_setBuilderList_updates(self):
        d = defer.succeed(None)

        slavebuilders = {}

        def add_my(_):
            d = self.bot.callRemote("setBuilderList", [
                        ('mybld', 'myblddir') ])
            def check(builders):
                self.assertEqual(builders.keys(), ['mybld'])
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
                slavebuilders['my'] = builders['mybld']
            d.addCallback(check)
            return d
        d.addCallback(add_my)

        def add_your(_):
            d = self.bot.callRemote("setBuilderList", [
                        ('mybld', 'myblddir'), ('yourbld', 'yourblddir') ])
            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(['mybld', 'yourbld']))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir')))
                # 'my' should still be the same slavebuilder object
                self.assertEqual(id(slavebuilders['my']), id(builders['mybld']))
                slavebuilders['your'] = builders['yourbld']
            d.addCallback(check)
            return d
        d.addCallback(add_your)

        def remove_my(_):
            d = self.bot.callRemote("setBuilderList", [
                        ('yourbld', 'yourblddir2') ]) # note new builddir
            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(['yourbld']))
                # note that build dirs are not deleted..
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir')))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir2')))
                # 'your' should still be the same slavebuilder object
                self.assertEqual(id(slavebuilders['your']), id(builders['yourbld']))
            d.addCallback(check)
            return d
        d.addCallback(remove_my)

        def add_and_remove(_):
            d = self.bot.callRemote("setBuilderList", [
                        ('theirbld', 'theirblddir') ])
            def check(builders):
                self.assertEqual(sorted(builders.keys()), sorted(['theirbld']))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir')))
                self.assertTrue(os.path.exists(os.path.join(self.basedir, 'theirblddir')))
            d.addCallback(check)
            return d
        d.addCallback(add_and_remove)

        return d
Exemple #30
0
 def do_start(_):
     return self.sb.callRemote("startCommand", FakeRemote(st), "13",
                               "shell", dict())