Example #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)
Example #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 WorkerBuilder 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()
Example #3
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, buildworker.version)
        d.addCallback(check)
        return d

    def test_getWorkerInfo(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("getWorkerInfo")

        def check(info):
            self.assertEqual(info, dict(
                admin='testy!', foo='bar',
                environ=os.environ, system=os.name, basedir=self.basedir,
                worker_commands=self.real_bot.remote_getCommands(),
                version=self.real_bot.remote_getVersion(),
                numcpus=multiprocessing.cpu_count()))
        d.addCallback(check)
        return d

    def test_getWorkerInfo_nodir(self):
        d = self.bot.callRemote("getWorkerInfo")

        def check(info):
            self.assertEqual(set(info.keys()), set(['environ', 'system', 'numcpus', 'basedir', 'worker_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 WorkerBuilder instance below
        d.addCallback(check)
        return d

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

        workerbuilders = {}

        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')))
                workerbuilders['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 workerbuilder object
                self.assertEqual(id(workerbuilders['my']), id(builders['mybld']))
                workerbuilders['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 workerbuilder object
                self.assertEqual(id(workerbuilders['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])
Example #4
0
class TestWorkerBuilder(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 WorkerBuilder 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, WorkerBuilder.")

    def test_setMaster(self):
        # not much to check here - what the WorkerBuilder 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