Esempio n. 1
0
    def addNode(self, name: str) -> TestNode:

        if name in self.nodes:
            error("{} already added".format(name))

        assert name in self.nodeReg
        ha, cliname, cliha = self.nodeReg[name]

        if self.opVerificationPluginPath:
            pl = PluginLoader(self.opVerificationPluginPath)
            opVerifiers = pl.plugins['VERIFICATION']
        else:
            opVerifiers = None

        testNodeClass = self.testNodeClass
        node = self.enter_context(
                testNodeClass(name=name,
                              ha=ha,
                              cliname=cliname,
                              cliha=cliha,
                              nodeRegistry=copy(self.nodeReg),
                              basedirpath=self.tmpdir,
                              primaryDecider=self.primaryDecider,
                              opVerifiers=opVerifiers))
        self.nodes[name] = node
        self.__dict__[name] = node
        return node
Esempio n. 2
0
def checkDblImp():
    """
    Added this because I spent the better part of an evening troubleshooting an
    issue cause by double import. We were importing test.helper in one
    place, and test_helper in another, and python sees them as two different
    modules, and imported the same file twice. This caused genHa to be loaded
    twice, which caused overlapping ports to be assigned. Took a long time to
    track this down. I'm sure there's a better way to do this, but this seems
    to work for the basic testing I did.
    """
    logging.info("-------------checking for double imports-------------")
    ignore = {'posixpath.py',
              'helpers/pydev/pydevd.py',
              'importlib/_bootstrap.py',
              'importlib/_bootstrap_external.py',
              'helpers/pycharm/pytestrunner.py',
              'test/__init__.py',
              'site-packages/pytest.py',
              'python3.5/os.py',
              'python3.5/re.py'}

    files = [x.__file__ for x in list(sys.modules.values())
             if hasattr(x, "__file__")]
    dups = set([x for x in files if files.count(x) > 1])
    ignoreddups = {d for d in dups for i in ignore if i in d}
    filtereddups = dups - ignoreddups
    if filtereddups:
        error("Doubly imported files detected {}".format(filtereddups))
Esempio n. 3
0
def genTestClient(nodes: TestNodeSet = None,
                  nodeReg=None,
                  tmpdir=None,
                  signer=None,
                  testClientClass=TestClient,
                  bootstrapKeys=True) -> TestClient:
    nReg = nodeReg
    if nodeReg:
        assert isinstance(nodeReg, dict)
    elif hasattr(nodes, "nodeReg"):
        nReg = nodes.nodeReg.extractCliNodeReg()
    else:
        error("need access to nodeReg")

    for k, v in nReg.items():
        assert type(k) == str
        assert (type(v) == HA or type(v[0]) == HA)

    ha = genHa()
    identifier = "testClient{}".format(ha.port)

    signer = signer if signer else SimpleSigner(identifier)

    tc = testClientClass(identifier,
                         nodeReg=nReg,
                         ha=ha,
                         basedirpath=tmpdir,
                         signer=signer)
    if bootstrapKeys and nodes:
        bootstrapClientKeys(tc, nodes)
    return tc
Esempio n. 4
0
    def __init__(self, *args, **kwargs):
        checkPortAvailable(kwargs['ha'])
        basedirpath = kwargs.get('basedirpath')
        keep = RoadKeep(basedirpath=basedirpath,
                        stackname=kwargs['name'],
                        auto=kwargs.get('auto'),
                        baseroledirpath=basedirpath)  # type: RoadKeep
        kwargs['keep'] = keep
        localRoleData = keep.loadLocalRoleData()

        sighex = localRoleData['sighex']
        if not sighex:
            (sighex, _), (prihex, _) = getEd25519AndCurve25519Keys()
        else:
            prihex = ed25519SkToCurve25519(sighex, toHex=True)
        kwargs['sigkey'] = sighex
        kwargs['prikey'] = prihex
        self.msgHandler = kwargs.pop('msgHandler', None)  # type: Callable
        super().__init__(*args, **kwargs)
        if self.ha[1] != kwargs['ha'].port:
            error("the stack port number has changed, likely due to "
                  "information in the keep")
        self.created = time.perf_counter()
        self.coro = None
        config = getConfig()
        try:
            self.messageTimeout = config.RAETMessageTimeout
        except AttributeError:
            # if no timeout is set then message will never timeout
            self.messageTimeout = 0
Esempio n. 5
0
    def addAttribute(self, frm, txnId, raw=None, enc=None, hash=None, to=None):
        # Only one of `raw`, `enc`, `hash` should be provided so 2 should be
        # `None`
        if (raw, enc, hash).count(None) != 2:
            error("One and only one of raw, enc and hash should be provided")

        if raw:
            attrVertex = self.createVertex(Vertices.Attribute, raw=raw)
        elif enc:
            attrVertex = self.createVertex(Vertices.Attribute, enc=enc)
        elif hash:
            attrVertex = self.createVertex(Vertices.Attribute, hash=hash)

        frm = "(select from {} where {} = '{}')".format(Vertices.Nym, NYM,
                                                        frm)
        kwargs = {
            TARGET_NYM: to,
            TXN_ID: txnId,
        }
        self.createEdge(Edges.AddsAttribute, frm, attrVertex._rid, **kwargs)
        if to:
            to = "(select from {} where {} = '{}')".format(Vertices.Nym, NYM,
                                                           to)
            kwargs = {
                TXN_ID: txnId
            }
            self.createEdge(Edges.HasAttribute, to, attrVertex._rid, **kwargs)
Esempio n. 6
0
    def addNode(self, name: str) -> TestNode:

        if name in self.nodes:
            error("{} already added".format(name))

        assert name in self.nodeReg
        ha, cliname, cliha = self.nodeReg[name]

        if self.opVerificationPluginPath:
            pl = PluginLoader(self.opVerificationPluginPath)
            opVerifiers = pl.plugins['VERIFICATION']
        else:
            opVerifiers = None

        testNodeClass = self.testNodeClass
        node = self.enter_context(
            testNodeClass(name=name,
                          ha=ha,
                          cliname=cliname,
                          cliha=cliha,
                          nodeRegistry=copy(self.nodeReg),
                          basedirpath=self.tmpdir,
                          primaryDecider=self.primaryDecider,
                          opVerifiers=opVerifiers))
        self.nodes[name] = node
        self.__dict__[name] = node
        return node
Esempio n. 7
0
def checkDblImp():
    """
    Added this because I spent the better part of an evening troubleshooting an
    issue cause by double import. We were importing test.helper in one
    place, and test_helper in another, and python sees them as two different
    modules, and imported the same file twice. This caused genHa to be loaded
    twice, which caused overlapping ports to be assigned. Took a long time to
    track this down. I'm sure there's a better way to do this, but this seems
    to work for the basic testing I did.
    """
    logging.info("-------------checking for double imports-------------")
    ignore = {
        'posixpath.py', 'helpers/pydev/pydevd.py', 'importlib/_bootstrap.py',
        'importlib/_bootstrap_external.py', 'helpers/pycharm/pytestrunner.py',
        'test/__init__.py', 'site-packages/pytest.py', 'python3.5/os.py',
        'python3.5/re.py'
    }

    files = [
        x.__file__ for x in list(sys.modules.values())
        if hasattr(x, "__file__")
    ]
    dups = set([x for x in files if files.count(x) > 1])
    ignoreddups = {d for d in dups for i in ignore if i in d}
    filtereddups = dups - ignoreddups
    if filtereddups:
        error("Doubly imported files detected {}".format(filtereddups))
Esempio n. 8
0
def genTestClient(nodes: TestNodeSet = None,
                  nodeReg=None,
                  tmpdir=None,
                  signer=None,
                  testClientClass=TestClient,
                  bootstrapKeys=True) -> TestClient:
    nReg = nodeReg
    if nodeReg:
        assert isinstance(nodeReg, dict)
    elif hasattr(nodes, "nodeReg"):
        nReg = nodes.nodeReg.extractCliNodeReg()
    else:
        error("need access to nodeReg")

    for k, v in nReg.items():
        assert type(k) == str
        assert (type(v) == HA or type(v[0]) == HA)

    ha = genHa()
    identifier = "testClient{}".format(ha.port)

    signer = signer if signer else SimpleSigner(identifier)

    tc = testClientClass(identifier,
                         nodeReg=nReg,
                         ha=ha,
                         basedirpath=tmpdir,
                         signer=signer)
    if bootstrapKeys and nodes:
        bootstrapClientKeys(tc, nodes)
    return tc
Esempio n. 9
0
def malign3PhaseSendingMethod(replica: TestReplica, msgType: ThreePhaseMsg,
                              evilMethod):
    evilMethod = types.MethodType(evilMethod, replica)

    if msgType == PrePrepare:
        replica.doPrePrepare = evilMethod
    elif msgType == Prepare:
        replica.doPrepare = evilMethod
    elif msgType == Commit:
        replica.doCommit = evilMethod
    else:
        util.error("Not a 3 phase message")
def malign3PhaseSendingMethod(replica: TestReplica, msgType: ThreePhaseMsg,
                              evilMethod):
    evilMethod = types.MethodType(evilMethod, replica)

    if msgType == PrePrepare:
        replica.doPrePrepare = evilMethod
    elif msgType == Prepare:
        replica.doPrepare = evilMethod
    elif msgType == Commit:
        replica.doCommit = evilMethod
    else:
        util.error("Not a 3 phase message")
Esempio n. 11
0
 def hashAttribTxn(result):
     # Creating copy of result so that `RAW`, `ENC` or `HASH` can be
     # replaced by their hashes. We do not insert actual attribute data
     # in the ledger but only the hash of it.
     result = deepcopy(result)
     if RAW in result:
         result[RAW] = sha256(result[RAW].encode()).hexdigest()
     elif ENC in result:
         result[ENC] = sha256(result[ENC].encode()).hexdigest()
     elif HASH in result:
         result[HASH] = result[HASH]
     else:
         error("Transaction missing required field")
     return result
Esempio n. 12
0
    def __init__(self,
                 names: Iterable[str] = None,
                 count: int = None,
                 nodeReg=None,
                 tmpdir=None,
                 keyshare=True,
                 primaryDecider=None,
                 opVerificationPluginPath=None):
        super().__init__()

        self.tmpdir = tmpdir

        self.primaryDecider = primaryDecider
        self.opVerificationPluginPath = opVerificationPluginPath

        self.nodes = OrderedDict()  # type: Dict[str, TestNode]
        # Can use just self.nodes rather than maintaining a separate dictionary
        # but then have to pluck attributes from the `self.nodes` so keeping
        # it simple a the cost of extra memory and its test code so not a big
        # deal

        if nodeReg:
            self.nodeReg = nodeReg
        else:
            nodeNames = (names if names is not None and count is None else
                         genNodeNames(count) if count is not None else
                         error("only one of either names or count is required"))
            self.nodeReg = genNodeReg(
                    names=nodeNames)  # type: Dict[str, NodeDetail]
        for name in self.nodeReg.keys():
            node = self.addNode(name)

        # The following lets us access the nodes by name as attributes of the
        # NodeSet. It's not a problem unless a node name shadows a member.
        self.__dict__.update(self.nodes)
Esempio n. 13
0
    def newStack(cls, stack):
        """
        Create a new instance of the given RoadStackClass

        :param stack: a dictionary of Roadstack constructor arguments.
        :return: the new instance of stack created.
        """
        checkPortAvailable(stack['ha'])
        stk = cls(**stack)
        if stk.ha[1] != stack['ha'].port:
            error("the stack port number has changed, likely due to "
                  "information in the keep")
        logger.info("stack {} starting at {} in {} mode"
                    .format(stk.name, stk.ha, stk.keep.auto.name),
                    extra={"cli": False})
        return stk
Esempio n. 14
0
 def storeTxnInLedger(self, result):
     if result[TXN_TYPE] == ATTRIB:
         # Creating copy of result so that `RAW`, `ENC` or `HASH` can be
         # replaced by their hashes. We do not insert actual attribute data
         # in the ledger but only the hash of it.
         result = deepcopy(result)
         if RAW in result:
             result[RAW] = sha256(result[RAW].encode()).hexdigest()
         elif ENC in result:
             result[ENC] = sha256(result[ENC].encode()).hexdigest()
         elif HASH in result:
             result[HASH] = result[HASH]
         else:
             error("Transaction missing required field")
         merkleInfo = self.addToLedger(result)
     else:
         merkleInfo = self.addToLedger(result)
     result.update(merkleInfo)
     return result
Esempio n. 15
0
def serlize(obj, level=0, objname=None):
    """
    Create a string representation of the given object.

    Examples:
    ::
    >>> serlize("str")
    'str'
    >>> serlize([1,2,3,4,5])
    '1,2,3,4,5'
    >>> signing.serlize({1:'a', 2:'b'})
    '1:a|2:b'
    >>> signing.serlize({1:'a', 2:'b', 3:[1,{2:'k'}]})
    '1:a|2:b|3:1,2:k'

    :param obj: the object to serlize
    :param level: a parameter used internally for recursion to serialize nested data structures
    :return: a string representation of `obj`
    """
    if not isinstance(obj, acceptableTypes):
        error("invalid type found {}: {}".format(objname, obj))
    if isinstance(obj, str):
        return obj
    if isinstance(obj, dict):
        keys = [k for k in obj.keys()
                if level > 0 or k != f.SIG.nm]  # remove signature if top level
        keys.sort()
        strs = []
        for k in keys:
            onm = ".".join([objname, k]) if objname else k
            strs.append(str(k) + ":" + serlize(obj[k], level + 1, onm))
        return "|".join(strs)
    if isinstance(obj, Iterable):
        strs = []
        for o in obj:
            strs.append(serlize(o, level + 1, objname))
        return ",".join(strs)
    if obj is None:
        return ""
    else:
        return str(obj)
Esempio n. 16
0
def serlize(obj, level=0, objname=None):
    """
    Create a string representation of the given object.

    Examples:
    ::
    >>> serlize("str")
    'str'
    >>> serlize([1,2,3,4,5])
    '1,2,3,4,5'
    >>> signing.serlize({1:'a', 2:'b'})
    '1:a|2:b'
    >>> signing.serlize({1:'a', 2:'b', 3:[1,{2:'k'}]})
    '1:a|2:b|3:1,2:k'

    :param obj: the object to serlize
    :param level: a parameter used internally for recursion to serialize nested data structures
    :return: a string representation of `obj`
    """
    if not isinstance(obj, acceptableTypes):
        error("invalid type found {}: {}".format(objname, obj))
    if isinstance(obj, str):
        return obj
    if isinstance(obj, dict):
        keys = [k for k in obj.keys() if level > 0 or k != f.SIG.nm]  # remove signature if top level
        keys.sort()
        strs = []
        for k in keys:
            onm = ".".join([objname, k]) if objname else k
            strs.append(str(k) + ":" + serlize(obj[k], level+1, onm))
        return "|".join(strs)
    if isinstance(obj, Iterable):
        strs = []
        for o in obj:
            strs.append(serlize(o, level+1, objname))
        return ",".join(strs)
    if obj is None:
        return ""
    else:
        return str(obj)
Esempio n. 17
0
def getSymmetricallyEncryptedVal(val, secretKey: Union[str, bytes]=None) -> \
        Tuple[str, str]:
    """
    Encrypt the provided value with symmetric encryption

    :param val: the value to encrypt
    :param secretKey: Optional key, if provided should be either in hex or bytes
    :return: Tuple of the encrypted value and secret key encoded in hex
    """

    if isinstance(val, str):
        val = val.encode("utf-8")
    if secretKey:
        if isHex(secretKey):
            secretKey = bytes(bytearray.fromhex(secretKey))
        elif not isinstance(secretKey, bytes):
            error("Secret key must be either in hex or bytes")
        box = libnacl.secret.SecretBox(secretKey)
    else:
        box = libnacl.secret.SecretBox()

    return box.encrypt(val).hex(), box.sk.hex()
Esempio n. 18
0
 def __init__(self,
              user,
              password,
              dbName,
              host="localhost",
              port=2424,
              dbType=pyorient.DB_TYPE_GRAPH,
              storageType=pyorient.STORAGE_TYPE_MEMORY):
     self.dbType = dbType
     try:
         self.client = pyorient.OrientDB(host=host, port=port)
         self.session_id = self.client.connect(user, password)
     except pyorient.exceptions.PyOrientConnectionException:
         error("OrientDB connection failed. Check if DB is running "
               "on port {}".format(port))
     if not self.client.db_exists(dbName, storageType):
         self.createDb(dbName, dbType, storageType)
     self.client.db_open(dbName, user, password)
     if not (self.serverVersion and self.serverVersion[0] >= 2
             and self.serverVersion[1] >= 2):
         error(
             "OrientDB version should be atleast 2.2. Current version is {}"
             .format(".".join(map(str, self.serverVersion))))
Esempio n. 19
0
def createOrientDbInMemStore(config, name, dbType):
    """
    Create and return an OrientDb in-memory store used for test cases.
    """
    host = "localhost"
    port = 2424
    try:
        client = pyorient.OrientDB(host=host, port=port)
        client.connect(user=config.OrientDB['user'],
                       password=config.OrientDB['password'])
    except pyorient.exceptions.PyOrientConnectionException:
        error("OrientDB connection failed. Check if DB is running "
              "on port {}".format(port))
    try:
        if client.db_exists(name, pyorient.STORAGE_TYPE_MEMORY):
            client.db_drop(name, type=pyorient.STORAGE_TYPE_MEMORY)
    # This is to avoid a known bug in OrientDb.
    except pyorient.exceptions.PyOrientDatabaseException:
        client.db_drop(name, type=pyorient.STORAGE_TYPE_MEMORY)
    return OrientDbStore(user=config.OrientDB["user"],
                         password=config.OrientDB["password"],
                         dbName=name,
                         dbType=dbType,
                         storageType=pyorient.STORAGE_TYPE_MEMORY)
Esempio n. 20
0
    def __init__(self,
                 names: Iterable[str] = None,
                 count: int = None,
                 nodeReg=None,
                 tmpdir=None,
                 keyshare=True,
                 primaryDecider=None,
                 opVerificationPluginPath=None,
                 testNodeClass=TestNode):
        super().__init__()

        self.tmpdir = tmpdir

        self.primaryDecider = primaryDecider
        self.opVerificationPluginPath = opVerificationPluginPath

        self.testNodeClass = testNodeClass
        self.nodes = OrderedDict()  # type: Dict[str, TestNode]
        # Can use just self.nodes rather than maintaining a separate dictionary
        # but then have to pluck attributes from the `self.nodes` so keeping
        # it simple a the cost of extra memory and its test code so not a big
        # deal

        if nodeReg:
            self.nodeReg = nodeReg
        else:
            nodeNames = (names if names is not None and count is None else
                         genNodeNames(count) if count is not None else error(
                             "only one of either names or count is required"))
            self.nodeReg = genNodeReg(
                names=nodeNames)  # type: Dict[str, NodeDetail]
        for name in self.nodeReg.keys():

            self.addNode(name)

        # The following lets us access the nodes by name as attributes of the
        # NodeSet. It's not a problem unless a node name shadows a member.
        self.__dict__.update(self.nodes)
Esempio n. 21
0
 def getNodeName(node: NodeRef) -> str:
     return node if isinstance(node, str) \
         else node.name if isinstance(node, Node) \
         else error("Expected a node or node name")
Esempio n. 22
0
 def getNode(self, node: NodeRef) -> TestNode:
     return node if isinstance(node, Node) \
         else self.nodes.get(node) if isinstance(node, str) \
         else error("Expected a node or node name")
Esempio n. 23
0
    def reconcileNodeReg(self):
        """
        Handle remotes missing from the node registry and clean up old remotes
        no longer in this node's registry.

        1. nice bootstrap
        2. force bootstrap
        3. retry connections

        1. not in remotes
        2.     in remotes, not joined, not allowed, not join in process
        3.     in remotes, not joined, not allowed,     join in process
        4.     in remotes,     joined, not allowed, not allow in process
        5.     in remotes,     joined, not allowed,     allow in process
        6.     in remotes,     joined,     allowed,

        :return: the missing remotes
        """
        matches = set()  # good matches found in nodestack remotes
        legacy = set()  # old remotes that are no longer in registry
        conflicts = set()  # matches found, but the ha conflicts
        logging.debug("{} nodereg is {}".
                      format(self, self.nodeReg.items()))
        logging.debug("{} nodestack is {}".
                      format(self, self.nodestack.remotes.values()))
        for r in self.nodestack.remotes.values():
            if r.name in self.nodeReg:
                if self.sameAddr(r.ha, self.nodeReg[r.name]):
                    matches.add(r.name)
                    logging.debug("{} matched remote is {} {}".
                                  format(self, r.uid, r.ha))
                else:
                    conflicts.add((r.name, r.ha))
                    error("{} ha for {} doesn't match. ha of remote is {} but "
                          "should be {}".
                          format(self, r.name, r.ha, self.nodeReg[r.name]))
            else:
                regName = self.findInNodeRegByHA(r.ha)

                # This change fixes test
                # `testNodeConnectionAfterKeysharingRestarted` in
                # `test_node_connection`
                # regName = [nm for nm, ha in self.nodeReg.items() if ha ==
                #            r.ha and (r.joined or r.joinInProcess())]
                logging.debug("{} unmatched remote is {} {}".
                              format(self, r.uid, r.ha))
                if regName:
                    logger.debug("{} forgiving name mismatch for {} with same "
                                 "ha {} using another name {}".
                                 format(self, regName, r.ha, r.name))
                    matches.add(regName)
                else:
                    logger.debug("{} found a legacy remote {} "
                                 "without a matching ha {}".
                                 format(self, r.name, r.ha))
                    legacy.add(r)

        # missing from remotes... need to connect
        missing = set(self.nodeReg.keys()) - matches

        if len(missing) + len(matches) + len(conflicts) != len(self.nodeReg):
            logger.error("Error reconciling nodeReg with remotes")
            logger.error("missing: {}".format(missing))
            logger.error("matches: {}".format(matches))
            logger.error("conflicts: {}".format(conflicts))
            logger.error("nodeReg: {}".format(self.nodeReg.keys()))
            error("Error reconciling nodeReg with remotes; see logs")

        if conflicts:
            error("found conflicting address information {} in registry".format(conflicts))
        if legacy:
            for l in legacy:
                logger.error("{} found legacy entry [{}, {}] in remotes, "
                             "that were not in registry".
                             format(self, l.name, l.ha))
                # TODO probably need to reap
                l.reap()
        return missing
Esempio n. 24
0
    def reconcileNodeReg(self):
        """
        Handle remotes missing from the node registry and clean up old remotes
        no longer in this node's registry.

        1. nice bootstrap
        2. force bootstrap
        3. retry connections

        1. not in remotes
        2.     in remotes, not joined, not allowed, not join in process
        3.     in remotes, not joined, not allowed,     join in process
        4.     in remotes,     joined, not allowed, not allow in process
        5.     in remotes,     joined, not allowed,     allow in process
        6.     in remotes,     joined,     allowed,

        :return: the missing remotes
        """
        matches = set()  # good matches found in nodestack remotes
        legacy = set()  # old remotes that are no longer in registry
        conflicts = set()  # matches found, but the ha conflicts
        logging.debug("{} nodereg is {}".
                      format(self, self.nodeReg.items()))
        logging.debug("{} nodestack is {}".
                      format(self, self.nodestack.remotes.values()))
        for r in self.nodestack.remotes.values():
            if r.name in self.nodeReg:
                if r.ha == self.nodeReg[r.name]:
                    matches.add(r.name)
                    logging.debug("{} matched remote is {} {}".
                                  format(self, r.uid, r.ha))
                else:
                    conflicts.add((r.name, r.ha))
                    error("{} ha for {} doesn't match".format(self, r.name))
            else:
                regName = self.findInNodeRegByHA(r.ha)

                # This change fixes test
                # `testNodeConnectionAfterKeysharingRestarted` in
                # `test_node_connection`
                # regName = [nm for nm, ha in self.nodeReg.items() if ha ==
                #            r.ha and (r.joined or r.joinInProcess())]
                logging.debug("{} unmatched remote is {} {}".
                              format(self, r.uid, r.ha))
                if regName:
                    logger.debug("{} forgiving name mismatch for {} with same "
                                 "ha {} using another name {}".
                                 format(self, regName, r.ha, r.name))
                    matches.add(regName)
                else:
                    logger.debug("{} found a legacy remote {} "
                                 "without a matching ha {}".
                                 format(self, r.name, r.ha))
                    legacy.add(r)

        # missing from remotes... need to connect
        missing = set(self.nodeReg.keys()) - matches

        if len(missing) + len(matches) + len(conflicts) != len(self.nodeReg):
            logger.error("Error reconciling nodeReg with remotes")
            logger.error("missing: {}".format(missing))
            logger.error("matches: {}".format(matches))
            logger.error("conflicts: {}".format(conflicts))
            logger.error("nodeReg: {}".format(self.nodeReg.keys()))
            error("Error reconciling nodeReg with remotes; see logs")

        if conflicts:
            error("found conflicting address information {} in registry".format(conflicts))
        if legacy:
            for l in legacy:
                logger.error("{} found legacy entry [{}, {}] in remotes, "
                             "that were not in registry".
                             format(self, l.name, l.ha))
                # TODO probably need to reap
                l.reap()
        return missing
Esempio n. 25
0
 def getNodeName(node: NodeRef) -> str:
     return node if isinstance(node, str) \
         else node.name if isinstance(node, Node) \
         else error("Expected a node or node name")
Esempio n. 26
0
 def getNode(self, node: NodeRef) -> TestNode:
     return node if isinstance(node, Node) \
         else self.nodes.get(node) if isinstance(node, str) \
         else error("Expected a node or node name")