class SynchronousMultiEngineTestCase(DeferredTestCase,
                                     IMultiEngineBaseTestCase):
    def setUp(self):
        self.controller = ControllerService()
        self.controller.startService()
        self.multiengine = IMultiEngine(self.controller)
        self.smultiengine = ISynchronousMultiEngine(self.multiengine)
        self.engines = []

    def tearDown(self):
        self.controller.stopService()
        for e in self.engines:
            e.stopService()

    def testExecuteNoBlock(self):
        self.addEngine(2)
        result = [{
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 0,
            'stderr': '',
            'stdout': ''
        }, {
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 1,
            'stderr': '',
            'stdout': ''
        }]
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, False, 'all', 'a=5')
        d.addCallback(
            lambda r: self.smultiengine.getPendingDeferred(cid, r, True))
        d.addCallback(lambda r: self.assert_(r == result))
        return d

    def testExecuteBlock(self):
        self.addEngine(2)
        result = [{
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 0,
            'stderr': '',
            'stdout': ''
        }, {
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 1,
            'stderr': '',
            'stdout': ''
        }]
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, True, 'all', 'a=5')
        d.addCallback(lambda r: self.assert_(r == result))
        return d
class SynchronousMultiEngineTestCase(DeferredTestCase,
                                     IMultiEngineBaseTestCase):
    def setUp(self):
        self.controller = ControllerService()
        self.controller.startService()
        self.multiengine = IMultiEngine(self.controller)
        self.smultiengine = ISynchronousMultiEngine(self.multiengine)
        self.engines = []

    def tearDown(self):
        self.controller.stopService()
        for e in self.engines:
            e.stopService()

    def testExecuteNoBlock(self):
        nengines = 2
        self.addEngine(nengines)
        cmd = 'a=5'
        results = [self.createShell().execute(cmd) for i in range(nengines)]
        for i, s in enumerate(results):
            s['id'] = i
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, False, 'all', cmd)
        d.addCallback(
            lambda r: self.smultiengine.getPendingDeferred(cid, r, True))
        d.addCallback(lambda r: self.assert_(r == results))
        return d

    def testExecuteBlock(self):
        nengines = 2
        self.addEngine(nengines)
        cmd = 'a=5'
        results = [self.createShell().execute(cmd) for i in range(nengines)]
        for i, s in enumerate(results):
            s['id'] = i
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, True, 'all', cmd)
        d.addCallback(lambda r: self.assert_(r == results))
        return d
class XMLRPCMultiEngineFromMultiEngine(xmlrpc.XMLRPC):
    """Adapt `IMultiEngine` -> `ISynchronousMultiEngine` -> `IXMLRPCMultiEngine`.
    """
    
    implements(IXMLRPCMultiEngine)
    
    addSlash = True
    
    def __init__(self, multiengine):
        xmlrpc.XMLRPC.__init__(self)
        # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
        # it.  This allow this class to do two adaptation steps.
        self.smultiengine = ISynchronousMultiEngine(multiengine)

    #---------------------------------------------------------------------------
    # Non interface methods
    #---------------------------------------------------------------------------
    
    def packageFailure(self, f):
        f.cleanFailure()
        return self.packageSuccess(f)

    def packageSuccess(self, obj):    
        serial = pickle.dumps(obj, 2)
        return xmlrpc.Binary(serial)
       
    #---------------------------------------------------------------------------
    # IEngineMultiplexer related methods
    #---------------------------------------------------------------------------
    
    @packageResult
    def xmlrpc_execute(self, request, clientID, block, targets, lines):     
        return self.smultiengine.execute(clientID, block, targets, lines)
    
    @packageResult    
    def xmlrpc_push(self, request, clientID, block, targets, binaryNS):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.push(clientID, block, targets, **namespace)
        return d

    @packageResult
    def xmlrpc_pull(self, request, clientID, block, targets, *keys):
        return self.smultiengine.pull(clientID, block, targets, *keys)
    
    @packageResult
    def xmlrpc_getResult(self, request, clientID, block, targets, i=None):
        if i == 'None':
            i = None
        return self.smultiengine.getResult(clientID, block, targets, i)
    
    @packageResult
    def xmlrpc_reset(self, request, clientID, block, targets):
        return self.smultiengine.reset(clientID, block, targets)
    
    @packageResult
    def xmlrpc_keys(self, request, clientID, block, targets):
        return self.smultiengine.keys(clientID, block, targets)
    
    @packageResult
    def xmlrpc_kill(self, request, clientID, block, targets, controller=False):
        return self.smultiengine.kill(clientID, block, targets, controller)

    @packageResult
    def xmlrpc_clearQueue(self, request, clientID, targets):
        return self.smultiengine.clearQueue(clientID, True, targets)

    @packageResult
    def xmlrpc_queueStatus(self, request, clientID, targets):
        return self.smultiengine.queueStatus(clientID, True, targets)
    
    #---------------------------------------------------------------------------
    # IMultiEngine related methods
    #---------------------------------------------------------------------------
    
    def xmlrpc_getIDs(self, request):
        return self.smultiengine.getIDs()
     
    #---------------------------------------------------------------------------
    # IEngineCoordinator related methods
    #---------------------------------------------------------------------------
    
    @packageResult
    def xmlrpc_scatter(self, request, clientID, block, targets, key, bseq, style='basic', flatten=False):
        try:
            seq = pickle.loads(bseq.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.scatter(clientID, block, targets, key, seq, style, flatten)
        return d      
    
    @packageResult
    def xmlrpc_gather(self, request, clientID, block, targets, key, style='basic'):
        return self.smultiengine.gather(clientID, block, targets, key, style)
    
    #---------------------------------------------------------------------------
    # Pending Deferred related methods
    #---------------------------------------------------------------------------            
    
    def xmlrpc_registerClient(self, request):
        """"""
        clientID = self.smultiengine.registerClient()
        return clientID
        
    def xmlrpc_unregisterClient(self, request, clientID):
        """"""
        try:
            self.smultiengine.unregisterClient(clientID)
        except error.InvalidClientID:
            f = failure.Failure()
            return self.packageFailure(f)
        else:
            return True
            
    @packageResult
    def xmlrpc_getPendingResult(self, request, clientID, resultID, block):
        """"""
        return self.smultiengine.getPendingDeferred(clientID, resultID, block)
        
    @packageResult
    def xmlrpc_getAllPendingResults(self, request, clientID):
        """"""    
        return self.smultiengine.getAllPendingDeferreds(clientID)

    @packageResult
    def xmlrpc_flush(self, request, clientID):
        """"""    
        return self.smultiengine.flush(clientID)
Beispiel #4
0
class XMLRPCMultiEngineFromMultiEngine(xmlrpc.XMLRPC):
    """Adapt `IMultiEngine` -> `ISynchronousMultiEngine` -> `IXMLRPCMultiEngine`.
    """

    implements(IXMLRPCMultiEngine)

    addSlash = True

    def __init__(self, multiengine):
        xmlrpc.XMLRPC.__init__(self)
        # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
        # it.  This allow this class to do two adaptation steps.
        self.smultiengine = ISynchronousMultiEngine(multiengine)

    #---------------------------------------------------------------------------
    # Non interface methods
    #---------------------------------------------------------------------------

    def packageFailure(self, f):
        f.cleanFailure()
        return self.packageSuccess(f)

    def packageSuccess(self, obj):
        serial = pickle.dumps(obj, 2)
        return xmlrpc.Binary(serial)

    #---------------------------------------------------------------------------
    # IEngineMultiplexer related methods
    #---------------------------------------------------------------------------

    @packageResult
    def xmlrpc_execute(self, request, clientID, block, targets, lines):
        return self.smultiengine.execute(clientID, block, targets, lines)

    @packageResult
    def xmlrpc_push(self, request, clientID, block, targets, binaryNS):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.push(clientID, block, targets, **namespace)
        return d

    @packageResult
    def xmlrpc_pull(self, request, clientID, block, targets, *keys):
        d = self.smultiengine.pull(clientID, block, targets, *keys)
        return d

    @packageResult
    def xmlrpc_pushFunction(self, request, clientID, block, targets, binaryNS):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            namespace = uncanDict(namespace)
            d = self.smultiengine.pushFunction(clientID, block, targets,
                                               **namespace)
        return d

    def _canMultipleKeys(self, result):
        return [canSequence(r) for r in result]

    @packageResult
    def xmlrpc_pullFunction(self, request, clientID, block, targets, *keys):
        d = self.smultiengine.pullFunction(clientID, block, targets, *keys)
        if len(keys) == 1:
            d.addCallback(canSequence)
        elif len(keys) > 1:
            d.addCallback(self._canMultipleKeys)
        return d

    @packageResult
    def xmlrpc_getResult(self, request, clientID, block, targets, i=None):
        if i == 'None':
            i = None
        return self.smultiengine.getResult(clientID, block, targets, i)

    @packageResult
    def xmlrpc_reset(self, request, clientID, block, targets):
        return self.smultiengine.reset(clientID, block, targets)

    @packageResult
    def xmlrpc_keys(self, request, clientID, block, targets):
        return self.smultiengine.keys(clientID, block, targets)

    @packageResult
    def xmlrpc_kill(self, request, clientID, block, targets, controller=False):
        return self.smultiengine.kill(clientID, block, targets, controller)

    @packageResult
    def xmlrpc_clearQueue(self, request, clientID, targets):
        """Clear the queue on targets.
        
        This method always blocks.  This means that it will always waits for
        the queues to be cleared before returning.  This method will never
        return the id of a pending deferred.
        """
        return self.smultiengine.clearQueue(clientID, True, targets)

    @packageResult
    def xmlrpc_queueStatus(self, request, clientID, targets):
        """Get the queue status on targets.
        
        This method always blocks.  This means that it will always return
        the queues status's.  This method will never return the id of a pending 
        deferred.    
        """
        return self.smultiengine.queueStatus(clientID, True, targets)

    @packageResult
    def xmlrpc_setProperties(self, request, clientID, block, targets,
                             binaryNS):
        try:
            ns = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.setProperties(clientID, block, targets, **ns)
        return d

    @packageResult
    def xmlrpc_getProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.getProperties(clientID, block, targets, *keys)

    @packageResult
    def xmlrpc_hasProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.hasProperties(clientID, block, targets, *keys)

    @packageResult
    def xmlrpc_delProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.delProperties(clientID, block, targets, *keys)

    @packageResult
    def xmlrpc_clearProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.clearProperties(clientID, block, targets,
                                                 *keys)

    #---------------------------------------------------------------------------
    # IMultiEngine related methods
    #---------------------------------------------------------------------------

    def xmlrpc_getIDs(self, request):
        """Get the ids of the registered engines.
        
        This method always blocks.
        """
        return self.smultiengine.getIDs()

    #---------------------------------------------------------------------------
    # Pending Deferred related methods
    #---------------------------------------------------------------------------

    def xmlrpc_registerClient(self, request):
        """"""
        clientID = self.smultiengine.registerClient()
        return clientID

    def xmlrpc_unregisterClient(self, request, clientID):
        """"""
        try:
            self.smultiengine.unregisterClient(clientID)
        except error.InvalidClientID:
            f = failure.Failure()
            return self.packageFailure(f)
        else:
            return True

    @packageResult
    def xmlrpc_getPendingResult(self, request, clientID, resultID, block):
        """"""
        return self.smultiengine.getPendingDeferred(clientID, resultID, block)

    @packageResult
    def xmlrpc_getAllPendingResults(self, request, clientID):
        """"""
        return self.smultiengine.getAllPendingDeferreds(clientID)

    @packageResult
    def xmlrpc_flush(self, request, clientID):
        """"""
        return self.smultiengine.flush(clientID)