Example #1
0
    def startService(self):
        BuildSlave.startService(self)

        self._shutdown_callback_handle = reactor.addSystemEventTrigger(
            'before', 'shutdown', self._stopInstance)

        self.master.subscribeToBuildRequests(self.requestSubmitted)
Example #2
0
    def __init__(
        self,
        password,

        # On-Demand related stuff
        instance_booter,
        build_wait_timeout=60 * 10,
        keepalive_interval=None,

        # Generic stuff for the base class
        max_builds=None,
        notify_on_missing=[],
        missing_timeout=60 * 20,
        properties={},
        locks=None,
    ):
        # The buildslave name has already been supplied to the driver
        # responsible for booting the node, so we use that attribute here.
        name = instance_booter.driver.name
        BuildSlave.__init__(self, name, password, max_builds,
                            notify_on_missing, missing_timeout, properties,
                            locks)
        if build_wait_timeout < 0:
            config.error("%s: %s: Can't wait for negative time." %
                         (self.__class__, name))
        self.build_wait_timeout = build_wait_timeout
        # Uggh
        if keepalive_interval is not None:
            self.keepalive_interval = keepalive_interval

        self.building = set()

        self.instance_booter = instance_booter

        self.addService(TimerService(60, self.periodic))
    def startService(self):
        BuildSlave.startService(self)

        self._shutdown_callback_handle = reactor.addSystemEventTrigger(
            'before', 'shutdown', self._stopInstance)

        self.master.subscribeToBuildRequests(self.requestSubmitted)
    def __init__(self,
                 password,

                 # On-Demand related stuff
                 instance_booter,
                 build_wait_timeout=60 * 10,
                 keepalive_interval=None,

                 # Generic stuff for the base class
                 max_builds=None, notify_on_missing=[],
                 missing_timeout=60 * 20,
                 properties={}, locks=None,
                 ):
        # The buildslave name has already been supplied to the driver
        # responsible for booting the node, so we use that attribute here.
        name = instance_booter.driver.name
        BuildSlave.__init__(
            self, name, password, max_builds,
            notify_on_missing, missing_timeout, properties, locks
        )
        if build_wait_timeout < 0:
            config.error("%s: %s: Can't wait for negative time."
                         % (self.__class__, name))
        self.build_wait_timeout = build_wait_timeout
        # Uggh
        if keepalive_interval is not None:
            self.keepalive_interval = keepalive_interval

        self.building = set()

        self.instance_booter = instance_booter

        self.addService(TimerService(60, self.periodic))
    def buildFinished(self, sb):
        BuildSlave.buildFinished(self, sb)

        self.building.discard(sb.builder_name)
        if not self.building:
            if self.build_wait_timeout == 0:
                self._stopInstance()
            else:
                self._setBuildWaitTimer()
Example #6
0
    def buildFinished(self, sb):
        BuildSlave.buildFinished(self, sb)

        self.building.discard(sb.builder_name)
        if not self.building:
            if self.build_wait_timeout == 0:
                self._stopInstance()
            else:
                self._setBuildWaitTimer()
Example #7
0
 def checkConfig(self, name, workdir=None, usePty=False, **kwargs):
     BuildSlave.checkConfig(self, name, None, **kwargs)
     self.LocalBuildSlaveFactory = None
     try:
         # importing here to avoid dependency on buildbot slave package
         from buildslave.bot import LocalBuildSlave as RemoteLocalBuildSlave
         self.LocalBuildSlaveFactory = RemoteLocalBuildSlave
     except ImportError:
         error("LocalBuildSlave needs the buildbot-slave package installed (pip install buildbot-slave)")
     self.remote_slave = None
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self,
                                             wantData=True,
                                             wantMq=True,
                                             wantDb=True)
        self.master.db.insertTestData([
            fakedb.Builder(id=80, name='test'),
        ])

        self.builder = builder.Builder('test', _addServices=False)
        self.builder._builderid = 80
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test',
                                 slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigServiceWithBuildbotConfig(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.parent = mock.Mock()
        self.slave.master.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.botmaster.getBuildersForSlave = lambda sl: []
        self.slave.parent = self.master
        self.slave.startService()
        self.conn = fakeprotocol.FakeConnection(self.master, self.slave)
        yield self.slave.attached(self.conn)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, {})

        # add the buildset/request
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestamps=[{}],
            reason=u'x',
            properties={},
            builderids=[80],
            waited_for=False)

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids[80])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)
    def attached(self, bot):
        d = BuildSlave.attached(self, bot)

        def set_metadata_and_timer(result):
            try:
                self.properties.setProperty(
                    'image_metadata',
                    self.instance_booter.image_metadata,
                    "buildslave"
                )
            except WrongState:
                self.properties.setProperty(
                    'image_metadata', None, "buildslave")
            try:
                self.properties.setProperty(
                    'instance_metadata',
                    self.instance_booter.instance_metadata,
                    "buildslave")
            except WrongState:
                self.properties.setProperty(
                    'instance_metadata', None, "buildslave")
            self._setBuildWaitTimer()
            return result
        d.addCallback(set_metadata_and_timer)
        return d
Example #10
0
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self, wantDb=True)
        self.builder = builder.Builder('test', _addServices=False)
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test',
                                 slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.remote = FakeBot()
        yield self.slave.attached(self.remote)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, self.remote, {})

        # add the buildset/request
        sssid = yield self.master.db.sourcestampsets.addSourceStampSet()
        yield self.master.db.sourcestamps.addSourceStamp(
            branch='br',
            revision='1',
            repository='r://',
            project='',
            sourcestampsetid=sssid)
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestampsetid=sssid,
            reason=u'x',
            properties={},
            builderNames=['test'])

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids['test'])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)
Example #11
0
    def reconfigService(self, name, workdir=None, usePty=False, **kwargs):
        BuildSlave.reconfigService(self, name, None, **kwargs)
        if workdir is None:
            workdir = name
        workdir = os.path.abspath(os.path.join(self.master.basedir, "slaves", workdir))
        if not os.path.isdir(workdir):
            os.makedirs(workdir)

        if self.remote_slave is None:
            # create the actual slave as a child service
            # we only create at reconfig, to avoid poluting memory in case of reconfig
            self.remote_slave = self.LocalBuildSlaveFactory(name, workdir, usePty)
            yield self.remote_slave.setServiceParent(self)
        else:
            # The case of a reconfig, we forward the parameters
            self.remote_slave.bot.basedir = workdir
            self.remote_slave.usePty = usePty
    def __init__(self, name, password, instance_type, image_name,
                 identifier, secret_identifier,
                 user_data, region,
                 keypair_name, security_name,
                 max_builds=None, notify_on_missing=[],
                 missing_timeout=60 * 20,
                 build_wait_timeout=60 * 10, properties={}, locks=None,
                 keepalive_interval=None,
                 tags={}):

        BuildSlave.__init__(
            self, name, password, max_builds, notify_on_missing,
            missing_timeout, properties, locks)
        if build_wait_timeout < 0:
            config.error("%s: %s: Can't wait for negative time."
                         % (self.__class__, name))
        self.build_wait_timeout = build_wait_timeout
        # Uggh
        if keepalive_interval is not None:
            self.keepalive_interval = keepalive_interval

        self.building = set()

        self.ec2 = EC2(
            access_key=identifier,
            secret_access_token=secret_identifier,
            region=region,
            name=name,
            image_name=image_name,
            size=instance_type,
            keyname=keypair_name,
            security_groups=[security_name],
            userdata=user_data,
            metadata=tags,
        )

        self.addService(TimerService(60, self.periodic))
Example #13
0
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self,
                                             wantData=True, wantMq=True, wantDb=True)
        self.master.db.insertTestData([
            fakedb.Builder(id=80, name='test'), ])

        self.builder = builder.Builder('test', _addServices=False)
        self.builder._builderid = 80
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test', slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigServiceWithBuildbotConfig(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.parent = mock.Mock()
        self.slave.master.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.botmaster.getBuildersForSlave = lambda sl: []
        self.slave.parent = self.master
        self.slave.startService()
        self.conn = fakeprotocol.FakeConnection(self.master, self.slave)
        yield self.slave.attached(self.conn)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, {})

        # add the buildset/request
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestamps=[{}], reason=u'x', properties={},
            builderids=[80], waited_for=False)

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids[80])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self, wantDb=True)
        self.builder = builder.Builder('test', _addServices=False)
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test', slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.remote = FakeBot()
        yield self.slave.attached(self.remote)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, self.remote, {})

        # add the buildset/request
        sssid = yield self.master.db.sourcestampsets.addSourceStampSet()
        yield self.master.db.sourcestamps.addSourceStamp(branch='br',
                                                         revision='1', repository='r://', project='',
                                                         sourcestampsetid=sssid)
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestampsetid=sssid, reason=u'x', properties={},
            builderNames=['test'])

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids['test'])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)
Example #15
0
    def attached(self, bot):
        d = BuildSlave.attached(self, bot)

        def set_metadata_and_timer(result):
            try:
                self.properties.setProperty(
                    'image_metadata', self.instance_booter.image_metadata,
                    "buildslave")
            except WrongState:
                self.properties.setProperty('image_metadata', None,
                                            "buildslave")
            try:
                self.properties.setProperty(
                    'instance_metadata',
                    self.instance_booter.instance_metadata, "buildslave")
            except WrongState:
                self.properties.setProperty('instance_metadata', None,
                                            "buildslave")
            self._setBuildWaitTimer()
            return result

        d.addCallback(set_metadata_and_timer)
        return d
Example #16
0
class RunSteps(unittest.TestCase):
    @defer.inlineCallbacks
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self, wantDb=True)
        self.builder = builder.Builder('test', _addServices=False)
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test',
                                 slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.remote = FakeBot()
        yield self.slave.attached(self.remote)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, self.remote, {})

        # add the buildset/request
        sssid = yield self.master.db.sourcestampsets.addSourceStampSet()
        yield self.master.db.sourcestamps.addSourceStamp(
            branch='br',
            revision='1',
            repository='r://',
            project='',
            sourcestampsetid=sssid)
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestampsetid=sssid,
            reason=u'x',
            properties={},
            builderNames=['test'])

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids['test'])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)

    def tearDown(self):
        self.slave.stopKeepaliveTimer()
        return self.builder.stopService()

    @defer.inlineCallbacks
    def do_test_step(self):
        # patch builder.buildFinished to signal us with a deferred
        bfd = defer.Deferred()
        old_buildFinished = self.builder.buildFinished

        def buildFinished(*args):
            old_buildFinished(*args)
            bfd.callback(None)

        self.builder.buildFinished = buildFinished

        # start the builder
        self.failUnless((yield
                         self.builder.maybeStartBuild(self.slavebuilder,
                                                      [self.buildrequest])))

        # and wait for completion
        yield bfd

        # then get the BuildStatus and return it
        defer.returnValue(self.master.status.lastBuilderStatus.lastBuildStatus)

    def assertLogs(self, exp_logs):
        bs = self.master.status.lastBuilderStatus.lastBuildStatus
        # tell the steps they're not new-style anymore, so they don't assert
        for l in bs.getLogs():
            l._isNewStyle = False
        got_logs = dict((l.name, l.getText()) for l in bs.getLogs())
        self.assertEqual(got_logs, exp_logs)

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2))
        yield self.do_test_step()

        self.assertLogs({
            u'compl.html':
            u'<blink>A very short logfile</blink>\n',
            # this is one of the things that differs independently of
            # new/old style: encoding of logs and newlines
            u'foo':
            'stdout\n\xe2\x98\x83\nstderr\n',
            # u'ostdout\no\N{SNOWMAN}\nestderr\n',
            u'obs':
            'Observer saw [\'stdout\\n\', \'\\xe2\\x98\\x83\\n\']',
            # u'Observer saw [u\'stdout\\n\', u\'\\u2603\\n\']\n',
        })

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep_failure(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2, doFail=1))
        bs = yield self.do_test_step()
        self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
        self.assertEqual(bs.getResults(), results.EXCEPTION)

    @defer.inlineCallbacks
    def test_NewStyleCustomBuildStep(self):
        self.factory.addStep(NewStyleCustomBuildStep())
        yield self.do_test_step()
        self.assertLogs({
            'foo.html': '<head>\n',
            'testlog': 'stdout\nfromcmd\n',
            'obs': "Observer saw [u'stdout\\n']",
            'stdio': "stdio\nstderr\n",
        })

    @defer.inlineCallbacks
    def test_step_raising_buildstepfailed_in_start(self):
        self.factory.addStep(FailingCustomStep())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_step_raising_exception_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=ValueError))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.EXCEPTION)
        # self.expectOutcome(result=EXCEPTION, status_text=["generic", "exception"])
        self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)

    @defer.inlineCallbacks
    def test_step_raising_connectionlost_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=error.ConnectionLost))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.RETRY)

    @defer.inlineCallbacks
    def test_Latin1ProducingCustomBuildStep(self):
        self.factory.addStep(
            Latin1ProducingCustomBuildStep(logEncoding='latin-1'))
        yield self.do_test_step()
        self.assertLogs({
            u'xx': u'o\N{CENT SIGN}\n',
        })

    test_Latin1ProducingCustomBuildStep.skip = "logEncoding not supported in 0.8.x"

    @defer.inlineCallbacks
    def test_OldBuildEPYDoc(self):
        # test old-style calls to log.getText, figuring readlines will be ok
        self.factory.addStep(OldBuildEPYDoc())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_OldPerlModuleTest(self):
        # test old-style calls to self.getLog
        self.factory.addStep(OldPerlModuleTest())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.SUCCESS)
class RunSteps(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self, wantDb=True)
        self.builder = builder.Builder('test', _addServices=False)
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test', slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.remote = FakeBot()
        yield self.slave.attached(self.remote)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, self.remote, {})

        # add the buildset/request
        sssid = yield self.master.db.sourcestampsets.addSourceStampSet()
        yield self.master.db.sourcestamps.addSourceStamp(branch='br',
                                                         revision='1', repository='r://', project='',
                                                         sourcestampsetid=sssid)
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestampsetid=sssid, reason=u'x', properties={},
            builderNames=['test'])

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids['test'])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)

    def tearDown(self):
        self.slave.stopKeepaliveTimer()
        return self.builder.stopService()

    @defer.inlineCallbacks
    def do_test_step(self):
        # patch builder.buildFinished to signal us with a deferred
        bfd = defer.Deferred()
        old_buildFinished = self.builder.buildFinished

        def buildFinished(*args):
            old_buildFinished(*args)
            bfd.callback(None)
        self.builder.buildFinished = buildFinished

        # start the builder
        self.failUnless((yield self.builder.maybeStartBuild(
            self.slavebuilder, [self.buildrequest])))

        # and wait for completion
        yield bfd

        # then get the BuildStatus and return it
        defer.returnValue(self.master.status.lastBuilderStatus.lastBuildStatus)

    def assertLogs(self, exp_logs):
        bs = self.master.status.lastBuilderStatus.lastBuildStatus
        # tell the steps they're not new-style anymore, so they don't assert
        for l in bs.getLogs():
            l._isNewStyle = False
        got_logs = dict((l.name, l.getText()) for l in bs.getLogs())
        self.assertEqual(got_logs, exp_logs)

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2))
        yield self.do_test_step()

        self.assertLogs({
            u'compl.html': u'<blink>A very short logfile</blink>\n',
            # this is one of the things that differs independently of
            # new/old style: encoding of logs and newlines
            u'foo':
            'stdout\n\xe2\x98\x83\nstderr\n',
            # u'ostdout\no\N{SNOWMAN}\nestderr\n',
            u'obs':
            'Observer saw [\'stdout\\n\', \'\\xe2\\x98\\x83\\n\']',
            #u'Observer saw [u\'stdout\\n\', u\'\\u2603\\n\']\n',
        })

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep_failure(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2, doFail=1))
        bs = yield self.do_test_step()
        self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
        self.assertEqual(bs.getResults(), results.EXCEPTION)

    @defer.inlineCallbacks
    def test_NewStyleCustomBuildStep(self):
        self.factory.addStep(NewStyleCustomBuildStep())
        yield self.do_test_step()
        self.assertLogs({
            'foo.html': '<head>\n',
            'testlog': 'stdout\nfromcmd\n',
            'obs': "Observer saw [u'stdout\\n']",
            'stdio': "stdio\nstderr\n",
        })

    @defer.inlineCallbacks
    def test_step_raising_buildstepfailed_in_start(self):
        self.factory.addStep(FailingCustomStep())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_step_raising_exception_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=ValueError))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.EXCEPTION)
        #self.expectOutcome(result=EXCEPTION, status_text=["generic", "exception"])
        self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)

    @defer.inlineCallbacks
    def test_step_raising_connectionlost_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=error.ConnectionLost))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.RETRY)

    @defer.inlineCallbacks
    def test_Latin1ProducingCustomBuildStep(self):
        self.factory.addStep(Latin1ProducingCustomBuildStep(logEncoding='latin-1'))
        yield self.do_test_step()
        self.assertLogs({
            u'xx': u'o\N{CENT SIGN}\n',
        })
    test_Latin1ProducingCustomBuildStep.skip = "logEncoding not supported in 0.8.x"

    @defer.inlineCallbacks
    def test_OldBuildEPYDoc(self):
        # test old-style calls to log.getText, figuring readlines will be ok
        self.factory.addStep(OldBuildEPYDoc())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_OldPerlModuleTest(self):
        # test old-style calls to self.getLog
        self.factory.addStep(OldPerlModuleTest())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.SUCCESS)
class RunSteps(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self,
                                             wantData=True, wantMq=True, wantDb=True)
        self.master.db.insertTestData([
            fakedb.Builder(id=80, name='test'), ])

        self.builder = builder.Builder('test', _addServices=False)
        self.builder._builderid = 80
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test', slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.conn = fakeprotocol.FakeConnection(self.master, self.slave)
        yield self.slave.attached(self.conn)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, {})

        # add the buildset/request
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestamps=[{}], reason=u'x', properties={},
            builderids=[80], waited_for=False)

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids[80])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)

    def tearDown(self):
        return self.builder.stopService()

    @defer.inlineCallbacks
    def do_test_step(self):
        # patch builder.buildFinished to signal us with a deferred
        bfd = defer.Deferred()
        old_buildFinished = self.builder.buildFinished

        def buildFinished(*args):
            old_buildFinished(*args)
            bfd.callback(None)
        self.builder.buildFinished = buildFinished

        # start the builder
        self.failUnless((yield self.builder.maybeStartBuild(
            self.slavebuilder, [self.buildrequest])))

        # and wait for completion
        yield bfd

        # then get the BuildStatus and return it
        defer.returnValue(self.master.status.lastBuilderStatus.lastBuildStatus)

    def assertLogs(self, exp_logs):
        got_logs = {}
        for id, l in self.master.data.updates.logs.iteritems():
            self.failUnless(l['finished'])
            got_logs[l['name']] = ''.join(l['content'])
        self.assertEqual(got_logs, exp_logs)

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2))
        yield self.do_test_step()

        self.assertLogs({
            u'compl.html': u'<blink>A very short logfile</blink>\n',
            # this is one of the things that differs independently of
            # new/old style: encoding of logs and newlines
            u'foo':
            # 'stdout\n\xe2\x98\x83\nstderr\n',
            u'ostdout\no\N{SNOWMAN}\nestderr\n',
            u'obs':
            # 'Observer saw [\'stdout\\n\', \'\\xe2\\x98\\x83\\n\']',
            u'Observer saw [u\'stdout\\n\', u\'\\u2603\\n\']\n',
        })

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep_failure(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2, doFail=1))
        bs = yield self.do_test_step()
        self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
        self.assertEqual(bs.getResults(), results.EXCEPTION)

    @defer.inlineCallbacks
    def test_step_raising_buildstepfailed_in_start(self):
        self.factory.addStep(FailingCustomStep())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_step_raising_exception_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=ValueError))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.EXCEPTION)
        self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)

    @defer.inlineCallbacks
    def test_step_raising_connectionlost_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=error.ConnectionLost))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.RETRY)

    @defer.inlineCallbacks
    def test_Latin1ProducingCustomBuildStep(self):
        self.factory.addStep(Latin1ProducingCustomBuildStep(logEncoding='latin-1'))
        yield self.do_test_step()
        self.assertLogs({
            u'xx': u'o\N{CENT SIGN}\n',
        })

    @defer.inlineCallbacks
    def test_OldBuildEPYDoc(self):
        # test old-style calls to log.getText, figuring readlines will be ok
        self.factory.addStep(OldBuildEPYDoc())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_OldPerlModuleTest(self):
        # test old-style calls to self.getLog
        self.factory.addStep(OldPerlModuleTest())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.SUCCESS)
Example #19
0
 def detached(self, mind):
     BuildSlave.detached(self, mind)
     # If the slave disconnects, assuming it is a problem with the instance,
     # and stop it.
     self.instance_booter.stop()
 def detached(self, mind):
     BuildSlave.detached(self, mind)
     # If the slave disconnects, assuming it is a problem with the instance,
     # and stop it.
     self.instance_booter.stop()
Example #21
0
class BuildStepIntegrationMixin(object):
    """Support for *integration* testing of buildsteps.  This class runs as
    much "real" code as possible, unlike BuildStepMixin which focuses on the
    step itself."""
    @defer.inlineCallbacks
    def setUpBuildStepIntegration(self):
        self.master = fakemaster.make_master(testcase=self, wantDb=True)
        self.builder = builder.Builder('test', _addServices=False)
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test',
                                 slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.remote = FakeBot()
        yield self.slave.attached(self.remote)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, self.remote, {})

        # add the buildset/request
        sssid = yield self.master.db.sourcestampsets.addSourceStampSet()
        yield self.master.db.sourcestamps.addSourceStamp(
            branch='br',
            revision='1',
            repository='r://',
            project='',
            sourcestampsetid=sssid)
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestampsetid=sssid,
            reason=u'x',
            properties={},
            builderNames=['test'])

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids['test'])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)

    def tearDownBuildStepIntegration(self):
        self.slave.stopKeepaliveTimer()
        return self.builder.stopService()

    def setupStep(self, step):
        self.factory.addStep(step)

    @defer.inlineCallbacks
    def runStep(self):
        # patch builder.buildFinished to signal us with a deferred
        bfd = defer.Deferred()
        old_buildFinished = self.builder.buildFinished

        def buildFinished(*args):
            old_buildFinished(*args)
            bfd.callback(None)

        self.builder.buildFinished = buildFinished

        # start the builder
        self.failUnless((yield
                         self.builder.maybeStartBuild(self.slavebuilder,
                                                      [self.buildrequest])))

        # and wait for completion
        yield bfd

        # then get the BuildStatus and return it
        defer.returnValue(self.master.status.lastBuilderStatus.lastBuildStatus)
Example #22
0
class BuildStepIntegrationMixin(object):

    """Support for *integration* testing of buildsteps.  This class runs as
    much "real" code as possible, unlike BuildStepMixin which focuses on the
    step itself."""

    @defer.inlineCallbacks
    def setUpBuildStepIntegration(self):
        self.master = fakemaster.make_master(testcase=self, wantDb=True)
        self.builder = builder.Builder("test", _addServices=False)
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(config.BuilderConfig(name="test", slavename="testsl", factory=self.factory))
        yield self.builder.reconfigService(new_config)

        self.slave = BuildSlave("bsl", "pass")
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.master = self.master
        self.slave.startService()
        self.remote = FakeBot()
        yield self.slave.attached(self.remote)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, self.remote, {})

        # add the buildset/request
        sssid = yield self.master.db.sourcestampsets.addSourceStampSet()
        yield self.master.db.sourcestamps.addSourceStamp(
            branch="br", revision="1", repository="r://", project="", sourcestampsetid=sssid
        )
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestampsetid=sssid, reason=u"x", properties={}, builderNames=["test"]
        )

        self.brdict = yield self.master.db.buildrequests.getBuildRequest(brids["test"])

        self.buildrequest = yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)

    def tearDownBuildStepIntegration(self):
        self.slave.stopKeepaliveTimer()
        return self.builder.stopService()

    def setupStep(self, step):
        self.factory.addStep(step)

    @defer.inlineCallbacks
    def runStep(self):
        # patch builder.buildFinished to signal us with a deferred
        bfd = defer.Deferred()
        old_buildFinished = self.builder.buildFinished

        def buildFinished(*args):
            old_buildFinished(*args)
            bfd.callback(None)

        self.builder.buildFinished = buildFinished

        # start the builder
        self.failUnless((yield self.builder.maybeStartBuild(self.slavebuilder, [self.buildrequest])))

        # and wait for completion
        yield bfd

        # then get the BuildStatus and return it
        defer.returnValue(self.master.status.lastBuilderStatus.lastBuildStatus)
class RunSteps(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self,
                                             wantData=True, wantMq=True, wantDb=True)
        self.master.db.insertTestData([
            fakedb.Builder(id=80, name='test'), ])

        self.builder = builder.Builder('test', _addServices=False)
        self.builder._builderid = 80
        self.builder.master = self.master
        yield self.builder.startService()

        self.factory = factory.BuildFactory()  # will have steps added later
        new_config = config.MasterConfig()
        new_config.builders.append(
            config.BuilderConfig(name='test', slavename='testsl',
                                 factory=self.factory))
        yield self.builder.reconfigServiceWithBuildbotConfig(new_config)

        self.slave = BuildSlave('bsl', 'pass')
        self.slave.sendBuilderList = lambda: defer.succeed(None)
        self.slave.parent = mock.Mock()
        self.slave.master.botmaster = mock.Mock()
        self.slave.botmaster.maybeStartBuildsForSlave = lambda sl: None
        self.slave.botmaster.getBuildersForSlave = lambda sl: []
        self.slave.parent = self.master
        self.slave.startService()
        self.conn = fakeprotocol.FakeConnection(self.master, self.slave)
        yield self.slave.attached(self.conn)

        sb = self.slavebuilder = slavebuilder.SlaveBuilder()
        sb.setBuilder(self.builder)
        yield sb.attached(self.slave, {})

        # add the buildset/request
        self.bsid, brids = yield self.master.db.buildsets.addBuildset(
            sourcestamps=[{}], reason=u'x', properties={},
            builderids=[80], waited_for=False)

        self.brdict = \
            yield self.master.db.buildrequests.getBuildRequest(brids[80])

        self.buildrequest = \
            yield buildrequest.BuildRequest.fromBrdict(self.master, self.brdict)

    def tearDown(self):
        return self.builder.stopService()

    @defer.inlineCallbacks
    def do_test_step(self):
        # patch builder.buildFinished to signal us with a deferred
        bfd = defer.Deferred()
        old_buildFinished = self.builder.buildFinished

        def buildFinished(*args):
            old_buildFinished(*args)
            bfd.callback(None)
        self.builder.buildFinished = buildFinished

        # start the builder
        self.failUnless((yield self.builder.maybeStartBuild(
            self.slavebuilder, [self.buildrequest])))

        # and wait for completion
        yield bfd

        # then get the BuildStatus and return it
        defer.returnValue(self.master.status.lastBuilderStatus.lastBuildStatus)

    def assertLogs(self, exp_logs):
        got_logs = {}
        for id, l in self.master.data.updates.logs.iteritems():
            self.failUnless(l['finished'])
            got_logs[l['name']] = ''.join(l['content'])
        self.assertEqual(got_logs, exp_logs)

    @defer.inlineCallbacks
    def doOldStyleCustomBuildStep(self, slowDB=False):
        # patch out addLog to delay until we're ready
        newLogDeferreds = []
        oldNewLog = self.master.data.updates.addLog

        def finishNewLog(self):
            for d in newLogDeferreds:
                reactor.callLater(0, d.callback, None)

        def delayedNewLog(*args, **kwargs):
            d = defer.Deferred()
            d.addCallback(lambda _: oldNewLog(*args, **kwargs))
            newLogDeferreds.append(d)
            return d
        if slowDB:
            self.patch(self.master.data.updates,
                       "addLog", delayedNewLog)
            self.patch(OldStyleCustomBuildStep,
                       "_run_finished_hook", finishNewLog)

        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2))
        yield self.do_test_step()

        self.assertLogs({
            u'compl.html': u'<blink>A very short logfile</blink>\n',
            # this is one of the things that differs independently of
            # new/old style: encoding of logs and newlines
            u'foo':
            # 'stdout\n\xe2\x98\x83\nstderr\n',
            u'ostdout\no\N{SNOWMAN}\nestderr\n',
            u'obs':
            # if slowDB, the observer wont see anything before the end of this instant step
            u'Observer saw []\n' if slowDB else
            # 'Observer saw [\'stdout\\n\', \'\\xe2\\x98\\x83\\n\']',
            u'Observer saw [u\'stdout\\n\', u\'\\u2603\\n\']\n',
        })

    def test_OldStyleCustomBuildStep(self):
        return self.doOldStyleCustomBuildStep(False)

    def test_OldStyleCustomBuildStepSlowDB(self):
        return self.doOldStyleCustomBuildStep(True)

    @defer.inlineCallbacks
    def test_OldStyleCustomBuildStep_failure(self):
        self.factory.addStep(OldStyleCustomBuildStep(arg1=1, arg2=2, doFail=1))
        bs = yield self.do_test_step()
        self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
        self.assertEqual(bs.getResults(), results.EXCEPTION)

    @defer.inlineCallbacks
    def test_step_raising_buildstepfailed_in_start(self):
        self.factory.addStep(FailingCustomStep())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_step_raising_exception_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=ValueError))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.EXCEPTION)
        self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)

    @defer.inlineCallbacks
    def test_step_raising_connectionlost_in_start(self):
        self.factory.addStep(FailingCustomStep(exception=error.ConnectionLost))
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.RETRY)

    @defer.inlineCallbacks
    def test_Latin1ProducingCustomBuildStep(self):
        self.factory.addStep(Latin1ProducingCustomBuildStep(logEncoding='latin-1'))
        yield self.do_test_step()
        self.assertLogs({
            u'xx': u'o\N{CENT SIGN}\n',
        })

    @defer.inlineCallbacks
    def test_OldBuildEPYDoc(self):
        # test old-style calls to log.getText, figuring readlines will be ok
        self.factory.addStep(OldBuildEPYDoc())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.FAILURE)

    @defer.inlineCallbacks
    def test_OldPerlModuleTest(self):
        # test old-style calls to self.getLog
        self.factory.addStep(OldPerlModuleTest())
        bs = yield self.do_test_step()
        self.assertEqual(bs.getResults(), results.SUCCESS)