Пример #1
0
 def testNodePidDied(self):
     from rmake.multinode import workernode
     m = mock.mockClass(workernode.rMakeWorkerNodeServer)()
     m._mock.enableMethod('_pidDied')
     cmd = mock.mockClass(command.Command, mock_runInit=True)
     cmd = cmd(None, 'foo', 1)
     cmd.pid = 377
     cmd._mock.disable('readPipe')
     m._mock.set(commands=[cmd])
     m._pidDied(377, 255)
     # check to make sure self.client.commandErrored was called w/ the
     # right parameters
     f = failure.CommandFailed('foo', 'unexpectedly killed with signal 127')
     m.commandErrored._mock.assertCalled('foo', f)
     m._mock.enableMethod('commandErrored')
     m.commandErrored(cmd,
                      'Command foo unexpectedly died with exit code 4')
     assert(m.commands == [])
     m._mock.set(commands=[cmd])
     mock.mockMethod(m.commandErrored)
     m._pidDied(377, 1024)
     f = failure.CommandFailed('foo', 'unexpectedly died with exit code 4')
     m.commandErrored._mock.assertCalled( 'foo', f)
     assert(m.commands == [])
     m._pidDied(365, 1024)
     m.commandErrored._mock.assertNotCalled()
Пример #2
0
    def _setupMockCommand(self, jobId, troveTup):
        from rmake.worker import command
        from rmake.messagebus import messages
        from rmake.multinode import messages as mnmessages
        from rmake.multinode import workernode
        # test how the node responds to various messages sent in from our
        # fake client.
        buildTrove = self.newBuildTrove(jobId, *troveTup)

        commandClass = mock.mockClass(command.BuildCommand, mock_runInit=True)
        buildCommand = commandClass(self.getNodeCfg(),
                                    'CMD-1',
                                    jobId,
                                    mock.MockObject(),
                                    self.buildCfg,
                                    mock.MockObject(),
                                    buildTrove,
                                    targetLabel=self.cfg.buildLabel,
                                    builtTroves=[])
        buildCommand._mock.disable('chrootFactory')
        buildCommand._mock.disable('chroot')
        buildCommand.chroot._mock.set(pid=50)
        buildCommand.chroot._mock.set(
            buildTrove=lambda *args, **kw: ('/tmp/foo', 50))
        buildCommand._mock.disable('readPipe')
        buildCommand._mock.disable('writePipe')
        return buildCommand
Пример #3
0
 def testProductDirectoryError(self):
     productStoreClass = mock.mockClass(dirstore.CheckoutProductStore)
     productStore = productStoreClass()
     productStore._mock.enable('_testProductDirectory')
     err = self.assertRaises(errors.RbuildError,
                             productStore._testProductDirectory,
                             self.workDir)
     assert(str(err) == "No product directory at %r" %self.workDir)
Пример #4
0
 def testProductDirectoryError(self):
     productStoreClass = mock.mockClass(dirstore.CheckoutProductStore)
     productStore = productStoreClass()
     productStore._mock.enable('_testProductDirectory')
     err = self.assertRaises(errors.RbuildError,
                             productStore._testProductDirectory,
                             self.workDir)
     assert (str(err) == "No product directory at %r" % self.workDir)
Пример #5
0
    def testNodeServer(self):
        from rmake.messagebus import messages
        from rmake.multinode import messages as mnmessages
        from rmake.multinode import workernode
        # test how the node responds to various messages sent in from our
        # fake client.
        server, sessionClient = self._setupMockNode()
        trv = self.addComponent('simple:source', '1',
                                [('simple.recipe', recipes.simpleRecipe)])

        # send a build command
        buildTrove = self.newBuildTrove(1, *trv.getNameVersionFlavor())
        m = mnmessages.BuildCommand('CMD-1', self.buildCfg, 1, buildTrove, [],
                                    [], self.cfg.buildLabel,
                                    targetNode='WORKER-foo')

        # this should result in the command being queued...
        mock.mockMethod(server.queueCommand)
        mock.mockMethod(server.chrootManager.getRootFactory)
        sessionClient.handle_message(m)
        commandClass = server.queueCommand._mock.calls[0][0][0]
        self.assertEquals(commandClass, command.BuildCommand)
        commandClass = mock.mockClass(command.BuildCommand,
                                      mock_enable=['pid'],
                                      getCommandId=lambda: 'CMD-1',
                                      isErrored=lambda: False)
        server.queueCommand._mock.method(commandClass, self.cfg, 1, 'CMD-1')
        assert(server.listQueuedCommands())

        # pretend we forked this command...
        mock.mockFunctionOnce(os, 'fork', 342)
        server._serveLoopHook()
        assert(server.listCommands())
        # and now it's died...
        mock.mockFunctionOnce(os, 'waitpid', (342, 0))
        server._serveLoopHook()
        assert(not server.listCommands())
        self._check(sessionClient, mnmessages.CommandStatus,
                    destination='/commandstatus', commandId='CMD-1',
                    status=mnmessages.CommandStatus.COMPLETED)

        # let's create another command, one that fails on initialization
        commandClass = command.Command
        def _raise(*args, **kw):
            raise RuntimeError('foo')
        mock.replaceFunctionOnce(commandClass, '__init__', _raise)
        server.queueCommand._mock.method(commandClass, self.cfg, 'CMD-1')

        server._serveLoopHook()
        self._check(sessionClient, mnmessages.CommandStatus,
                    destination='/commandstatus', commandId='CMD-1',
                    status=mnmessages.CommandStatus.ERROR)
Пример #6
0
 def testNodeServerInitializationFailure(self):
     from rmake.multinode import workernode
     serverClass = mock.mockClass(workernode.rMakeWorkerNodeServer,
                                  mockEnable='__init__')
     s = serverClass()
     err = RuntimeError('foo')
     s._mock.raiseErrorOnAccess(err)
     self.assertRaises(RuntimeError, 
                        workernode.rMakeWorkerNodeServer.__init__, 
                       s, self.getNodeCfg())
     args = s.error._mock.popCall()[0]
     assert(args[0] == 'Error initializing Node Server:\n  %s\n%s')
     assert(args[1] == err)
Пример #7
0
    def testGetSourceTrovesFromJob(self):
        repos = mock.mockClass(repocache.CachingTroveSource)()
        trv1 = self.newBuildTrove(1, *self.makeTroveTuple('bar:source'))
        trv1Tup = trv1.getNameVersionFlavor(True)
        trv1.setConfig(self.buildCfg)
        job = self.newJob()
        job.addBuildTrove(trv1)
        mock.mockFunction(recipeutil.loadSourceTroves, {trv1Tup: 'result'})

        rc = recipeutil.getSourceTrovesFromJob(job, [trv1], repos,
                                               self.rmakeCfg.reposName)
        self.failUnlessEqual(rc, {trv1Tup: 'result'})
        args, kw = recipeutil.loadSourceTroves._mock.popCall()
        assert (args[3] == [trv1])
Пример #8
0
    def testGetSourceTrovesFromJob(self):
        repos = mock.mockClass(repocache.CachingTroveSource)()
        trv1 = self.newBuildTrove(1, *self.makeTroveTuple('bar:source'))
        trv1Tup = trv1.getNameVersionFlavor(True)
        trv1.setConfig(self.buildCfg)
        job = self.newJob()
        job.addBuildTrove(trv1)
        mock.mockFunction(recipeutil.loadSourceTroves, {trv1Tup: 'result'})

        rc = recipeutil.getSourceTrovesFromJob(job, [trv1], repos,
            self.rmakeCfg.reposName)
        self.failUnlessEqual(rc, {trv1Tup: 'result'})
        args, kw = recipeutil.loadSourceTroves._mock.popCall()
        assert(args[3] == [trv1])
Пример #9
0
    def testNodeRPCClient(self):
        from rmake.multinode import workernode
        from rmake.worker import command
        server, sessionClient = self._setupMockNode()
        mock.mockMethod(server.client._logger.logRPCCall)
        rpcClient = workernode.WorkerNodeRPCClient(server.client.getBusClient(),
                                                   sessionClient.sessionId)
        assert(tuple(rpcClient.listCommands()) == ([], []))

        commandClass = mock.mockClass(command.BuildCommand,
                                      getCommandId=lambda: 'CMD-1',
                                      mock_enable=['pid', 'commandInfo'])
        server.queueCommand(commandClass, None, 'CMD-1')
        mock.mockFunctionOnce(os, 'fork', 342)
        server._serveLoopHook()
        self.assertEquals(rpcClient.listCommands(), ([], [('CMD-1', 342)]))
Пример #10
0
    def _setupMockCommand(self, jobId, troveTup):
        from rmake.worker import command
        from rmake.messagebus import messages
        from rmake.multinode import messages as mnmessages
        from rmake.multinode import workernode
        # test how the node responds to various messages sent in from our
        # fake client.
        buildTrove = self.newBuildTrove(jobId, *troveTup)

        commandClass = mock.mockClass(command.BuildCommand, mock_runInit=True)
        buildCommand = commandClass(self.getNodeCfg(), 'CMD-1', jobId, 
                                 mock.MockObject(), self.buildCfg, 
                                 mock.MockObject(), buildTrove,
                                 targetLabel=self.cfg.buildLabel, 
                                 builtTroves=[])
        buildCommand._mock.disable('chrootFactory')
        buildCommand._mock.disable('chroot')
        buildCommand.chroot._mock.set(pid=50)
        buildCommand.chroot._mock.set(
                            buildTrove=lambda *args, **kw: ('/tmp/foo', 50))
        buildCommand._mock.disable('readPipe')
        buildCommand._mock.disable('writePipe')
        return buildCommand
Пример #11
0
    def testGetChangeSet(self):
        # Now mock ChangesetCache, to log things
        origChangesetCache = netreposproxy.ChangesetCache
        lockLogFile = os.path.join(self.workDir, "locks.log")

        class MockChangesetCache(origChangesetCache):
            llf = file(lockLogFile, "a")

            def get(slf, key, shouldLock=True):
                csPath = origChangesetCache.hashKey(slf, key)
                ret = origChangesetCache.get(slf, key, shouldLock=shouldLock)
                if shouldLock and ret is None:
                    slf.llf.write("Lock acquired for %s\n" % csPath)
                    self.assertTrue(os.path.exists(csPath + '.lck'))
                return ret

            def set(slf, key, value):
                csPath = origChangesetCache.hashKey(slf, key)
                if csPath in slf.locksMap:
                    slf.llf.write("Releasing lock for %s\n" % csPath)
                return origChangesetCache.set(slf, key, value)

            def resetLocks(slf):
                for csPath in sorted(slf.locksMap):
                    slf.llf.write("Resetting unused lock for %s\n" % csPath)
                return origChangesetCache.resetLocks(slf)

        self.mock(netreposproxy, 'ChangesetCache', MockChangesetCache)

        cfg = netserver.ServerConfig()
        cfg.changesetCacheDir = os.path.join(self.workDir, "changesetCache")
        cfg.proxyContentsDir = os.path.join(self.workDir, "proxyContents")
        prs = netreposproxy.ProxyRepositoryServer(cfg, "/someUrl")
        rawUrl = '/blah'
        headers = {'X-Conary-Proxy-Host': 'repos.example.com'}
        prs.setBaseUrlOverride(rawUrl, headers, isSecure=True)
        # callWrapper normally sets this, but nothing here invokes it
        prs._serverName = 'repos.example.com'

        caller = mock.mockClass(netreposproxy.ProxyCaller)()
        caller._getBasicUrl._mock.setDefaultReturn('http://blah')
        caller.checkVersion._mock.setDefaultReturn([51, 52, 53])
        # Make sure we present the fingerprints in non-sorted order, we need
        # to verify we sort them
        suf = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        fingerprints = ['aac3aac3' + suf, 'aaa1aaa1' + suf, 'aab2aab2' + suf]
        caller.getChangeSetFingerprints._mock.setDefaultReturn(fingerprints)
        csSizes = [12, 13, 14]
        allInfo = [(str(x), 'trovesNeeded%d' % i, 'filesNeeded%d' % i,
                    'removedTroves%d' % i, str(x))
                   for i, x in enumerate(csSizes)]
        csFileObj = file(os.path.join(self.workDir, "changeset"), "w+")
        magic = netreposproxy.filecontainer.FILE_CONTAINER_MAGIC
        fver = netreposproxy.filecontainer.FILE_CONTAINER_VERSION_FILEID_IDX
        fver = netreposproxy.filecontainer.struct.pack("!I", fver)
        for i, csSize in enumerate(csSizes):
            csFileObj.write(magic)
            csFileObj.write(fver)
            rest = csSize - len(magic) - len(fver)
            csFileObj.write((chr(ord('a') + i) * rest))
        csFileObj.seek(0)

        changeSetList = [(x, (None, None), (None, None), False)
                         for x in ['a', 'b', 'c']]

        caller.getChangeSet._mock.appendReturn(
            ('http://repos.example.com/my-changeset-url', allInfo), 53,
            changeSetList, False, True, False, True, 2007022001, False, False)

        urlOpener = mock.MockObject()
        uo = mock.MockObject()
        self.mock(netreposproxy.transport, 'ConaryURLOpener', urlOpener)
        urlOpener._mock.setDefaultReturn(uo)
        uo.open._mock.appendReturn(csFileObj,
                                   'http://repos.example.com/my-changeset-url',
                                   forceProxy=caller._lastProxy,
                                   headers=[('X-Conary-Servername',
                                             'repos.example.com')])

        authToken = AuthToken(None, None, [])
        clientVersion = 51

        prs.getChangeSet(caller,
                         authToken,
                         clientVersion,
                         changeSetList,
                         recurse=False,
                         withFiles=True,
                         withFileContents=False,
                         excludeAutoSource=True)

        MockChangesetCache.llf.close()
        f = file(lockLogFile)
        contents = [x.strip() for x in f]
        sortedFP = sorted(fingerprints)

        logEntries1 = contents[:len(fingerprints)]
        self.assertEqual(logEntries1, [
            'Lock acquired for %s/%s/%s-2007022001.1' %
            (cfg.changesetCacheDir, fp[:2], fp[2:]) for fp in sortedFP
        ])
        logEntries2 = contents[len(fingerprints):2 * len(fingerprints)]
        self.assertEqual(logEntries2, [
            'Releasing lock for %s/%s/%s-2007022001.1' %
            (cfg.changesetCacheDir, fp[:2], fp[2:]) for fp in fingerprints
        ])
        # We're not releasing locks we didn't close
        self.assertEqual(len(contents), 2 * len(fingerprints))
Пример #12
0
    def testGetChangeSet(self):
        # Now mock ChangesetCache, to log things
        origChangesetCache = netreposproxy.ChangesetCache
        lockLogFile = os.path.join(self.workDir, "locks.log")
        class MockChangesetCache(origChangesetCache):
            llf = file(lockLogFile, "a")
            def get(slf, key, shouldLock = True):
                csPath = origChangesetCache.hashKey(slf, key)
                ret = origChangesetCache.get(slf, key, shouldLock=shouldLock)
                if shouldLock and ret is None:
                    slf.llf.write("Lock acquired for %s\n" % csPath)
                    self.assertTrue(os.path.exists(csPath + '.lck'))
                return ret

            def set(slf, key, value):
                csPath = origChangesetCache.hashKey(slf, key)
                if csPath in slf.locksMap:
                    slf.llf.write("Releasing lock for %s\n" % csPath)
                return origChangesetCache.set(slf, key, value)

            def resetLocks(slf):
                for csPath in sorted(slf.locksMap):
                    slf.llf.write("Resetting unused lock for %s\n" % csPath)
                return origChangesetCache.resetLocks(slf)

        self.mock(netreposproxy, 'ChangesetCache', MockChangesetCache)


        cfg = netserver.ServerConfig()
        cfg.changesetCacheDir = os.path.join(self.workDir, "changesetCache")
        cfg.proxyContentsDir = os.path.join(self.workDir, "proxyContents")
        prs = netreposproxy.ProxyRepositoryServer(cfg, "/someUrl")
        rawUrl = '/blah'
        headers = {'X-Conary-Proxy-Host' : 'repos.example.com'}
        prs.setBaseUrlOverride(rawUrl, headers, isSecure = True)
        # callWrapper normally sets this, but nothing here invokes it
        prs._serverName = 'repos.example.com'

        caller = mock.mockClass(netreposproxy.ProxyCaller)()
        caller._getBasicUrl._mock.setDefaultReturn('http://blah')
        caller.checkVersion._mock.setDefaultReturn([51, 52, 53])
        # Make sure we present the fingerprints in non-sorted order, we need
        # to verify we sort them
        suf = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        fingerprints = ['aac3aac3' + suf, 'aaa1aaa1' + suf, 'aab2aab2' + suf]
        caller.getChangeSetFingerprints._mock.setDefaultReturn(fingerprints)
        csSizes = [ 12, 13, 14 ]
        allInfo = [
            (str(x), 'trovesNeeded%d' % i, 'filesNeeded%d' % i,
                'removedTroves%d' % i, str(x))
            for i, x in enumerate(csSizes) ]
        csFileObj = file(os.path.join(self.workDir, "changeset"), "w+")
        magic = netreposproxy.filecontainer.FILE_CONTAINER_MAGIC
        fver = netreposproxy.filecontainer.FILE_CONTAINER_VERSION_FILEID_IDX
        fver = netreposproxy.filecontainer.struct.pack("!I", fver)
        for i, csSize in enumerate(csSizes):
            csFileObj.write(magic)
            csFileObj.write(fver)
            rest = csSize - len(magic) - len(fver)
            csFileObj.write((chr(ord('a') + i) * rest))
        csFileObj.seek(0)

        changeSetList = [ (x, (None, None), (None, None), False) for x in
                            ['a', 'b', 'c'] ]

        caller.getChangeSet._mock.appendReturn(
            ('http://repos.example.com/my-changeset-url', allInfo),
            53, changeSetList, False, True, False, True, 2007022001,
            False, False)

        urlOpener = mock.MockObject()
        uo = mock.MockObject()
        self.mock(netreposproxy.transport, 'ConaryURLOpener', urlOpener)
        urlOpener._mock.setDefaultReturn(uo)
        uo.open._mock.appendReturn(
            csFileObj,
            'http://repos.example.com/my-changeset-url',
            forceProxy=caller._lastProxy,
            headers=[('X-Conary-Servername', 'repos.example.com')])

        authToken = AuthToken(None, None, [])
        clientVersion = 51

        prs.getChangeSet(caller, authToken, clientVersion, changeSetList,
            recurse = False, withFiles = True, withFileContents = False,
            excludeAutoSource = True)

        MockChangesetCache.llf.close()
        f = file(lockLogFile)
        contents = [ x.strip() for x in f ]
        sortedFP = sorted(fingerprints)

        logEntries1 = contents[:len(fingerprints)]
        self.assertEqual(logEntries1,
            [ 'Lock acquired for %s/%s/%s-2007022001.1' %
                (cfg.changesetCacheDir, fp[:2], fp[2:])
              for fp in sortedFP ])
        logEntries2 = contents[len(fingerprints):2 * len(fingerprints)]
        self.assertEqual(logEntries2,
            [ 'Releasing lock for %s/%s/%s-2007022001.1' %
                (cfg.changesetCacheDir, fp[:2], fp[2:])
              for fp in fingerprints ])
        # We're not releasing locks we didn't close
        self.assertEqual(len(contents), 2 * len(fingerprints))