Commit e966eee6 authored by Grégory Wisniewski's avatar Grégory Wisniewski

- Move master handlers in the handlers module.

- Split service.py file in two, one for the client sercice handler and the
  second for the storage.
- Base class for those two handlers as moved in the module python file (as done
  in client and storage applications).
- Remove moved storages from previous commit.
- Update application code to use new module location
- Fix a part of master tests.

git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@841 71dcc9de-d417-0410-9af5-da40c76e7ee4
git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@842 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 5b3beccb
......@@ -32,14 +32,7 @@ from neo.event import EventManager
from neo.connection import ListeningConnection, ClientConnection, ServerConnection
from neo.exception import ElectionFailure, PrimaryFailure, VerificationFailure, \
OperationFailure
from neo.master.identification import IdentificationEventHandler
from neo.master.administration import AdministrationEventHandler
from neo.master.election import ClientElectionEventHandler, ServerElectionEventHandler
from neo.master.recovery import RecoveryEventHandler
from neo.master.verification import VerificationEventHandler
from neo.master.service import ClientServiceEventHandler, StorageServiceEventHandler
from neo.master.secondary import PrimaryMasterEventHandler, SecondaryMasterEventHandler
from neo.master.shutdown import ShutdownEventHandler
from neo.master import handlers
from neo.master.pt import PartitionTable
from neo.util import dump
from neo.connector import getConnectorHandler
......@@ -132,8 +125,8 @@ class Application(object):
self.unconnected_master_node_set = set()
self.negotiating_master_node_set = set()
self.listening_conn.setHandler(ServerElectionEventHandler(self))
client_handler = ClientElectionEventHandler(self)
self.listening_conn.setHandler(handlers.ServerElectionHandler(self))
client_handler = handlers.ClientElectionHandler(self)
em = self.em
nm = self.nm
......@@ -618,7 +611,7 @@ class Application(object):
dump(self.uuid), *(self.server))
# all incoming connections identify through this handler
self.listening_conn.setHandler(IdentificationEventHandler(self))
self.listening_conn.setHandler(handlers.IdentificationHandler(self))
# If I know any storage node, make sure that they are not in the running state,
# because they are not connected at this stage.
......@@ -641,7 +634,7 @@ class Application(object):
logging.info('play the secondary role with %s (%s:%d)',
dump(self.uuid), *(self.server))
handler = PrimaryMasterEventHandler(self)
handler = handlers.PrimaryMasterHandler(self)
em = self.em
# Make sure that every connection has the secondary event handler.
......@@ -659,13 +652,13 @@ class Application(object):
# select the storage handler
if state == protocol.BOOTING:
storage_handler = RecoveryEventHandler
storage_handler = handlers.RecoveryHandler
elif state == protocol.RECOVERING:
storage_handler = RecoveryEventHandler
storage_handler = handlers.RecoveryHandler
elif state == protocol.VERIFYING:
storage_handler = VerificationEventHandler
storage_handler = handlers.VerificationHandler
elif state == protocol.RUNNING:
storage_handler = StorageServiceEventHandler
storage_handler = handlers.StorageServiceHandler
else:
RuntimeError('Unexpected node type')
......@@ -684,7 +677,7 @@ class Application(object):
if node_type == CLIENT_NODE_TYPE:
if state != protocol.RUNNING:
conn.close()
handler = ClientServiceEventHandler
handler = handlers.ClientServiceHandler
elif node_type == STORAGE_NODE_TYPE:
handler = storage_handler
handler = handler(self)
......@@ -754,7 +747,7 @@ class Application(object):
def shutdown(self):
"""Close all connections and exit"""
# change handler
handler = ShutdownEventHandler(self)
handler = handlers.ShutdownHandler(self)
for c in self.em.getConnectionList():
c.setHandler(handler)
......@@ -795,20 +788,20 @@ class Application(object):
if uuid == protocol.INVALID_UUID:
logging.info('reject empty storage node')
raise protocol.NotReadyError
handler = RecoveryEventHandler
handler = handlers.RecoveryHandler
elif self.cluster_state == protocol.VERIFYING:
if uuid == INVALID_UUID or node is None:
# if node is unknown, it has been forget when the current
# partition was validated by the admin
uuid = INVALID_UUID
state = protocol.PENDING_STATE
handler = VerificationEventHandler
handler = handlers.VerificationHandler
elif self.cluster_state == protocol.RUNNING:
if uuid == INVALID_UUID or node is None:
# same as for verification
uuid = INVALID_UUID
state = protocol.PENDING_STATE
handler = StorageServiceEventHandler
handler = handlers.StorageServiceHandler
elif self.cluster_state == protocol.STOPPING:
# FIXME: raise a ShutdowningError ?
raise protocol.NotReadyError
......@@ -819,17 +812,17 @@ class Application(object):
def identifyNode(self, node_type, uuid, node):
state = protocol.RUNNING_STATE
handler = IdentificationEventHandler
handler = handlers.IdentificationHandler
if node_type == protocol.ADMIN_NODE_TYPE:
# always accept admin nodes
klass = AdminNode
handler = AdministrationEventHandler
handler = handlers.AdministrationHandler
logging.info('Accept an admin %s' % dump(uuid))
elif node_type == protocol.MASTER_NODE_TYPE:
# always put other master in waiting state
klass = MasterNode
handler = SecondaryMasterEventHandler
handler = handlers.SecondaryMasterHandler
logging.info('Accept a master %s' % dump(uuid))
elif node_type == protocol.CLIENT_NODE_TYPE:
# refuse any client before running
......@@ -837,8 +830,7 @@ class Application(object):
logging.info('reject a connection from a client')
raise protocol.NotReadyError
klass = ClientNode
# FIXME: Apply an handler dedicated to client nodes
handler = ClientServiceEventHandler
handler = handlers.ClientServiceHandler
logging.info('Accept a client %s' % dump(uuid))
elif node_type == protocol.STORAGE_NODE_TYPE:
klass = StorageNode
......
......@@ -20,7 +20,7 @@ import logging
from neo import protocol
from neo.handler import EventHandler
class MasterEventHandler(EventHandler):
class MasterHandler(EventHandler):
"""This class implements a generic part of the event handlers."""
def _nodeLost(self, conn, node):
......@@ -144,3 +144,81 @@ class MasterEventHandler(EventHandler):
app.sendPartitionTable(conn)
conn.answer(protocol.answerPartitionTable(app.pt.getID(), []), packet)
class BaseServiceHandler(MasterHandler):
"""This class deals with events for a service phase."""
def handleNotifyNodeInformation(self, conn, packet, node_list):
app = self.app
for node_type, ip_address, port, uuid, state in node_list:
if node_type in (protocol.CLIENT_NODE_TYPE, protocol.ADMIN_NODE_TYPE):
# No interest.
continue
if uuid == protocol.INVALID_UUID:
# No interest.
continue
if app.uuid == uuid:
# This looks like me...
if state == protocol.RUNNING_STATE:
# Yes, I know it.
continue
else:
# What?! What happened to me?
raise RuntimeError, 'I was told that I am bad'
addr = (ip_address, port)
node = app.nm.getNodeByUUID(uuid)
if node is None:
node = app.nm.getNodeByServer(addr)
if node is None:
# I really don't know such a node. What is this?
continue
else:
if node.getServer() != addr:
# This is different from what I know.
continue
if node.getState() == state:
# No change. Don't care.
continue
node.setState(state)
# Something wrong happened possibly. Cut the connection to
# this node, if any, and notify the information to others.
# XXX this can be very slow.
# XXX does this need to be closed in all cases ?
c = app.em.getConnectionByUUID(uuid)
if c is not None:
c.close()
app.broadcastNodeInformation(node)
if node.getNodeType() == protocol.STORAGE_NODE_TYPE:
if state == protocol.TEMPORARILY_DOWN_STATE:
cell_list = app.pt.outdate()
if len(cell_list) != 0:
ptid = app.pt.setNextID()
app.broadcastPartitionChanges(ptid, cell_list)
def handleAskLastIDs(self, conn, packet):
app = self.app
conn.answer(protocol.answerLastIDs(app.loid, app.ltid, app.pt.getID()), packet)
def handleAskUnfinishedTransactions(self, conn, packet):
app = self.app
p = protocol.answerUnfinishedTransactions(app.finishing_transaction_dict.keys())
conn.answer(p, packet)
# Import all master handlers in the current namespace
from neo.master.handlers.administration import AdministrationHandler
from neo.master.handlers.election import ClientElectionHandler, ServerElectionHandler
from neo.master.handlers.identification import IdentificationHandler
from neo.master.handlers.recovery import RecoveryHandler
from neo.master.handlers.secondary import SecondaryMasterHandler, PrimaryMasterHandler
from neo.master.handlers.shutdown import ShutdownHandler
from neo.master.handlers.verification import VerificationHandler
from neo.master.handlers.storage import StorageServiceHandler
from neo.master.handlers.client import ClientServiceHandler
......@@ -18,12 +18,12 @@
import logging
from neo import protocol
from neo.master.handler import MasterEventHandler
from neo.master.handlers import MasterHandler
from neo.protocol import RUNNING_STATE, TEMPORARILY_DOWN_STATE, DOWN_STATE, \
STORAGE_NODE_TYPE, HIDDEN_STATE, PENDING_STATE, RUNNING
from neo.util import dump
class AdministrationEventHandler(MasterEventHandler):
class AdministrationHandler(MasterHandler):
"""This class deals with messages from the admin node only"""
def _nodeLost(self, conn, node):
......
#
# Copyright (C) 2006-2009 Nexedi SA
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import logging
from neo import protocol
from neo.protocol import CLIENT_NODE_TYPE, \
RUNNING_STATE, BROKEN_STATE, TEMPORARILY_DOWN_STATE, \
UP_TO_DATE_STATE, FEEDING_STATE, DISCARDED_STATE, \
STORAGE_NODE_TYPE, ADMIN_NODE_TYPE, OUT_OF_DATE_STATE, \
HIDDEN_STATE, INVALID_UUID, INTERNAL_ERROR_CODE
from neo.master.handlers import BaseServiceHandler
from neo.protocol import UnexpectedPacketError
from neo.util import dump
class FinishingTransaction(object):
"""This class describes a finishing transaction."""
def __init__(self, conn):
self._conn = conn
self._msg_id = None
self._oid_list = None
self._uuid_set = None
self._locked_uuid_set = set()
def getConnection(self):
return self._conn
def setMessageId(self, msg_id):
self._msg_id = msg_id
def getMessageId(self):
return self._msg_id
def setOIDList(self, oid_list):
self._oid_list = oid_list
def getOIDList(self):
return self._oid_list
def setUUIDSet(self, uuid_set):
self._uuid_set = uuid_set
def getUUIDSet(self):
return self._uuid_set
def addLockedUUID(self, uuid):
if uuid in self._uuid_set:
self._locked_uuid_set.add(uuid)
def allLocked(self):
return self._uuid_set == self._locked_uuid_set
class ClientServiceHandler(BaseServiceHandler):
""" Handler dedicated to client during service state """
def connectionCompleted(self, conn):
pass
def _nodeLost(self, conn, node):
app = self.app
for tid, t in app.finishing_transaction_dict.items():
if t.getConnection() is conn:
del app.finishing_transaction_dict[tid]
def handleAbortTransaction(self, conn, packet, tid):
try:
del self.app.finishing_transaction_dict[tid]
except KeyError:
logging.warn('aborting transaction %s does not exist', dump(tid))
pass
def handleAskNewTID(self, conn, packet):
app = self.app
tid = app.getNextTID()
app.finishing_transaction_dict[tid] = FinishingTransaction(conn)
conn.answer(protocol.answerNewTID(tid), packet)
def handleAskNewOIDs(self, conn, packet, num_oids):
app = self.app
oid_list = app.getNewOIDList(num_oids)
conn.answer(protocol.answerNewOIDs(oid_list), packet)
def handleFinishTransaction(self, conn, packet, oid_list, tid):
app = self.app
# If the given transaction ID is later than the last TID, the peer
# is crazy.
if app.ltid < tid:
raise UnexpectedPacketError
# Collect partitions related to this transaction.
getPartition = app.getPartition
partition_set = set()
partition_set.add(getPartition(tid))
partition_set.update((getPartition(oid) for oid in oid_list))
# Collect the UUIDs of nodes related to this transaction.
uuid_set = set()
for part in partition_set:
uuid_set.update((cell.getUUID() for cell in app.pt.getCellList(part) \
if cell.getNodeState() != HIDDEN_STATE))
# Request locking data.
# build a new set as we may not send the message to all nodes as some
# might be not reachable at that time
used_uuid_set = set()
for c in app.em.getConnectionList():
if c.getUUID() in uuid_set:
c.ask(protocol.lockInformation(tid), timeout=60)
used_uuid_set.add(c.getUUID())
try:
t = app.finishing_transaction_dict[tid]
t.setOIDList(oid_list)
t.setUUIDSet(used_uuid_set)
t.setMessageId(packet.getId())
except KeyError:
logging.warn('finishing transaction %s does not exist', dump(tid))
pass
......@@ -21,12 +21,12 @@ from neo import protocol
from neo.protocol import MASTER_NODE_TYPE, \
RUNNING_STATE, BROKEN_STATE, TEMPORARILY_DOWN_STATE, \
DOWN_STATE
from neo.master.handler import MasterEventHandler
from neo.master.handlers import MasterHandler
from neo.exception import ElectionFailure
from neo.protocol import INVALID_UUID
from neo.node import MasterNode
class ElectionEventHandler(MasterEventHandler):
class ElectionHandler(MasterHandler):
"""This class deals with events for a primary master election."""
def handleNotifyNodeInformation(self, conn, packet, node_list):
......@@ -72,32 +72,32 @@ class ElectionEventHandler(MasterEventHandler):
c.close()
node.setState(state)
class ClientElectionEventHandler(MasterEventHandler):
class ClientElectionHandler(MasterHandler):
def packetReceived(self, conn, packet):
node = self.app.nm.getNodeByServer(conn.getAddress())
if node.getState() != BROKEN_STATE:
node.setState(RUNNING_STATE)
MasterEventHandler.packetReceived(self, conn, packet)
MasterHandler.packetReceived(self, conn, packet)
def connectionStarted(self, conn):
app = self.app
addr = conn.getAddress()
app.unconnected_master_node_set.remove(addr)
app.negotiating_master_node_set.add(addr)
MasterEventHandler.connectionStarted(self, conn)
MasterHandler.connectionStarted(self, conn)
def connectionCompleted(self, conn):
conn.ask(protocol.askPrimaryMaster())
MasterEventHandler.connectionCompleted(self, conn)
MasterHandler.connectionCompleted(self, conn)
def connectionClosed(self, conn):
self.connectionFailed(conn)
MasterEventHandler.connectionClosed(self, conn)
MasterHandler.connectionClosed(self, conn)
def timeoutExpired(self, conn):
self.connectionFailed(conn)
MasterEventHandler.timeoutExpired(self, conn)
MasterHandler.timeoutExpired(self, conn)
def connectionFailed(self, conn):
app = self.app
......@@ -109,7 +109,7 @@ class ClientElectionEventHandler(MasterEventHandler):
node.setState(TEMPORARILY_DOWN_STATE)
elif node.getState() == TEMPORARILY_DOWN_STATE:
app.unconnected_master_node_set.add(addr)
MasterEventHandler.connectionFailed(self, conn)
MasterHandler.connectionFailed(self, conn)
def peerBroken(self, conn):
app = self.app
......@@ -118,7 +118,7 @@ class ClientElectionEventHandler(MasterEventHandler):
if node is not None:
node.setState(DOWN_STATE)
app.negotiating_master_node_set.discard(addr)
MasterEventHandler.peerBroken(self, conn)
MasterHandler.peerBroken(self, conn)
def handleAcceptNodeIdentification(self, conn, packet, node_type,
uuid, ip_address, port, num_partitions,
......@@ -208,7 +208,7 @@ class ClientElectionEventHandler(MasterEventHandler):
app.uuid, app.server[0], app.server[1], app.name))
class ServerElectionEventHandler(MasterEventHandler):
class ServerElectionHandler(MasterHandler):
def handleReelectPrimaryMaster(self, conn, packet):
raise ElectionFailure, 'reelection requested'
......@@ -219,7 +219,7 @@ class ServerElectionEventHandler(MasterEventHandler):
node = app.nm.getNodeByServer(addr)
if node is not None and node.getUUID() is not None:
node.setState(BROKEN_STATE)
MasterEventHandler.peerBroken(self, conn)
MasterHandler.peerBroken(self, conn)
def handleRequestNodeIdentification(self, conn, packet, node_type,
uuid, ip_address, port, name):
......
......@@ -18,13 +18,13 @@
import logging
from neo import protocol
from neo.master.handler import MasterEventHandler
from neo.master.handlers import MasterHandler
class IdentificationEventHandler(MasterEventHandler):
class IdentificationHandler(MasterHandler):
"""This class deals with messages from the admin node only"""
def _nodeLost(self, conn, node):
logging.warning('lost a node in IdentificationEventHandler : %s' % node)
logging.warning('lost a node in IdentificationHandler : %s' % node)
def handleRequestNodeIdentification(self, conn, packet, node_type,
uuid, ip_address, port, name):
......
......@@ -20,12 +20,12 @@ import logging
from neo import protocol
from neo.protocol import RUNNING_STATE, BROKEN_STATE, \
TEMPORARILY_DOWN_STATE, CLIENT_NODE_TYPE, ADMIN_NODE_TYPE
from neo.master.handler import MasterEventHandler
from neo.master.handlers import MasterHandler
from neo.protocol import UnexpectedPacketError, INVALID_UUID, INVALID_PTID
from neo.node import StorageNode
from neo.util import dump
class RecoveryEventHandler(MasterEventHandler):
class RecoveryHandler(MasterHandler):
"""This class deals with events for a recovery phase."""
def connectionCompleted(self, conn):
......
......@@ -19,12 +19,12 @@ import logging
from neo.protocol import MASTER_NODE_TYPE, \
RUNNING_STATE, BROKEN_STATE, DOWN_STATE
from neo.master.handler import MasterEventHandler
from neo.master.handlers import MasterHandler
from neo.exception import ElectionFailure, PrimaryFailure
from neo.protocol import UnexpectedPacketError, INVALID_UUID
from neo.node import MasterNode
class SecondaryMasterEventHandler(MasterEventHandler):
class SecondaryMasterHandler(MasterHandler):
""" Handler used by primary to handle secondary masters"""
def connectionCompleted(self, conn):
......@@ -40,7 +40,7 @@ class SecondaryMasterEventHandler(MasterEventHandler):
logging.error('/!\ NotifyNodeInformation packet from secondary master')
class PrimaryMasterEventHandler(MasterEventHandler):
class PrimaryMasterHandler(MasterHandler):
""" Handler used by secondaries to handle primary master"""
def _nodeLost(self, conn, node):
......@@ -53,7 +53,7 @@ class PrimaryMasterEventHandler(MasterEventHandler):
node = self.app.nm.getNodeByServer(conn.getAddress())
if node.getState() != BROKEN_STATE:
node.setState(RUNNING_STATE)
MasterEventHandler.packetReceived(self, conn, packet)
MasterHandler.packetReceived(self, conn, packet)
def handleAnnouncePrimaryMaster(self, conn, packet):
raise UnexpectedPacketError
......
......@@ -19,11 +19,11 @@ import logging
from neo import protocol
from neo.protocol import CLIENT_NODE_TYPE, ADMIN_NODE_TYPE, INVALID_UUID, \
RUNNING_STATE, STORAGE_NODE_TYPE, TEMPORARILY_DOWN_STATE, STOPPING
from neo.master.service import ServiceEventHandler
from neo.master.handlers import BaseServiceHandler
from neo import decorators
from neo.util import dump
class ShutdownEventHandler(ServiceEventHandler):
class ShutdownHandler(BaseServiceHandler):
"""This class deals with events for a shutting down phase."""
......
......@@ -23,186 +23,13 @@ from neo.protocol import CLIENT_NODE_TYPE, \
UP_TO_DATE_STATE, FEEDING_STATE, DISCARDED_STATE, \
STORAGE_NODE_TYPE, ADMIN_NODE_TYPE, OUT_OF_DATE_STATE, \
HIDDEN_STATE, INVALID_UUID, INTERNAL_ERROR_CODE
from neo.master.handler import MasterEventHandler
from neo.master.handlers import BaseServiceHandler
from neo.protocol import UnexpectedPacketError
from neo.exception import OperationFailure
from neo.util import dump
class ServiceEventHandler(MasterEventHandler):
"""This class deals with events for a service phase."""
def handleNotifyNodeInformation(self, conn, packet, node_list):
app = self.app
for node_type, ip_address, port, uuid, state in node_list:
if node_type in (CLIENT_NODE_TYPE, ADMIN_NODE_TYPE):
# No interest.
continue
if uuid == INVALID_UUID:
# No interest.
continue
if app.uuid == uuid:
# This looks like me...
if state == RUNNING_STATE:
# Yes, I know it.
continue
else:
# What?! What happened to me?
raise RuntimeError, 'I was told that I am bad'
addr = (ip_address, port)
node = app.nm.getNodeByUUID(uuid)
if node is None:
node = app.nm.getNodeByServer(addr)
if node is None:
# I really don't know such a node. What is this?
continue
else:
if node.getServer() != addr:
# This is different from what I know.
continue
if node.getState() == state:
# No change. Don't care.
continue
node.setState(state)
# Something wrong happened possibly. Cut the connection to
# this node, if any, and notify the information to others.
# XXX this can be very slow.
# XXX does this need to be closed in all cases ?
c = app.em.getConnectionByUUID(uuid)
if c is not None:
c.close()
app.broadcastNodeInformation(node)
if node.getNodeType() == STORAGE_NODE_TYPE:
if state == TEMPORARILY_DOWN_STATE:
cell_list = app.pt.outdate()
if len(cell_list) != 0:
ptid = app.pt.setNextID()
app.broadcastPartitionChanges(ptid, cell_list)
def handleAskLastIDs(self, conn, packet):
app = self.app
conn.answer(protocol.answerLastIDs(app.loid, app.ltid, app.pt.getID()), packet)
def handleAskUnfinishedTransactions(self, conn, packet):
app = self.app
p = protocol.answerUnfinishedTransactions(app.finishing_transaction_dict.keys())
conn.answer(p, packet)
class FinishingTransaction(object):
"""This class describes a finishing transaction."""
def __init__(self, conn):
self._conn = conn
self._msg_id = None
self._oid_list = None
self._uuid_set = None
self._locked_uuid_set = set()
def getConnection(self):
return self._conn
def setMessageId(self, msg_id):
self._msg_id = msg_id
def getMessageId(self):
return self._msg_id
def setOIDList(self, oid_list):
self._oid_list = oid_list
def getOIDList(self):
return self._oid_list
def setUUIDSet(self, uuid_set):
self._uuid_set = uuid_set
def getUUIDSet(self):
return self._uuid_set
def addLockedUUID(self, uuid):
if uuid in self._uuid_set:
self._locked_uuid_set.add(uuid)
def allLocked(self):
return self._uuid_set == self._locked_uuid_set
class ClientServiceEventHandler(ServiceEventHandler):
""" Handler dedicated to client during service state """
def connectionCompleted(self, conn):
pass
def _nodeLost(self, conn, node):
app = self.app
for tid, t in app.finishing_transaction_dict.items():
if t.getConnection() is conn:
del app.finishing_transaction_dict[tid]
def handleAbortTransaction(self, conn, packet, tid):
try:
del self.app.finishing_transaction_dict[tid]
except KeyError:
logging.warn('aborting transaction %s does not exist', dump(tid))
pass
def handleAskNewTID(self, conn, packet):
app = self.app
tid = app.getNextTID()
app.finishing_transaction_dict[tid] = FinishingTransaction(conn)
conn.answer(protocol.answerNewTID(tid), packet)
def handleAskNewOIDs(self, conn, packet, num_oids):
app = self.app
oid_list = app.getNewOIDList(num_oids)
conn.answer(protocol.answerNewOIDs(oid_list), packet)
def handleFinishTransaction(self, conn, packet, oid_list, tid):
app = self.app
# If the given transaction ID is later than the last TID, the peer
# is crazy.
if app.ltid < tid:
raise UnexpectedPacketError
# Collect partitions related to this transaction.
getPartition = app.getPartition
partition_set = set()
partition_set.add(getPartition(tid))
partition_set.update((getPartition(oid) for oid in oid_list))
# Collect the UUIDs of nodes related to this transaction.
uuid_set = set()
for part in partition_set:
uuid_set.update((cell.getUUID() for cell in app.pt.getCellList(part) \
if cell.getNodeState() != HIDDEN_STATE))
# Request locking data.
# build a new set as we may not send the message to all nodes as some
# might be not reachable at that time
used_uuid_set = set()
for c in app.em.getConnectionList():
if c.getUUID() in uuid_set:
c.ask(protocol.lockInformation(tid), timeout=60)
used_uuid_set.add(c.getUUID())
try:
t = app.finishing_transaction_dict[tid]
t.setOIDList(oid_list)
t.setUUIDSet(used_uuid_set)
t.setMessageId(packet.getId())
except KeyError:
logging.warn('finishing transaction %s does not exist', dump(tid))
pass
class StorageServiceEventHandler(ServiceEventHandler):
class StorageServiceHandler(BaseServiceHandler):
""" Handler dedicated to storages during service state """
def connectionCompleted(self, conn):
......
......@@ -19,12 +19,12 @@ import logging
from neo.protocol import CLIENT_NODE_TYPE, RUNNING_STATE, BROKEN_STATE, \
TEMPORARILY_DOWN_STATE, ADMIN_NODE_TYPE
from neo.master.handler import MasterEventHandler
from neo.master.handlers import MasterHandler
from neo.exception import VerificationFailure
from neo.protocol import INVALID_UUID
from neo.util import dump
class VerificationEventHandler(MasterEventHandler):
class VerificationHandler(MasterHandler):
"""This class deals with events for a verification phase."""
def connectionCompleted(self, conn):
......
from neo.master.tests.testMasterApp import MasterAppTests
from neo.master.tests.testMasterPT import MasterPartitionTableTests
from neo.master.tests.testMasterElectionHandler import MasterElectionTests
from neo.master.tests.testMasterRecoveryHandler import MasterRecoveryTests
from neo.master.tests.testMasterService import MasterServiceTests
from neo.master.tests.testMasterVerificationHandler import MasterVerificationTests
from neo.master.tests.testElectionHandler import MasterServerElectionTests
from neo.master.tests.testElectionHandler import MasterClientElectionTests
from neo.master.tests.testRecoveryHandler import MasterRecoveryTests
from neo.master.tests.testClientHandler import MasterClientHandlerTests
from neo.master.tests.testStorageHandler import MasterStorageHandlerTests
from neo.master.tests.testVerificationHandler import MasterVerificationTests
__all__ = [
'MasterAppTests',
'MasterElectionTests',
'MasterServerElectionTests',
'MasterClientElectionTests',
'MasterRecoveryTests',
'MasterServiceTests',
'MasterClientHandlerTests',
'MasterStorageHandlerTests',
'MasterVerificationeTests',
'MasterPartitionTableTests',
]
......
#
# Copyright (C) 2009 Nexedi SA
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os
import unittest
import logging
from mock import Mock
from struct import pack, unpack
from neo.tests.base import NeoTestBase
import neo.master
from neo import protocol
from neo.protocol import Packet, INVALID_UUID
from neo.master.handlers import ClientServiceHandler
from neo.master.app import Application
from neo.protocol import ERROR, PING, PONG, ANNOUNCE_PRIMARY_MASTER, \
REELECT_PRIMARY_MASTER, NOTIFY_NODE_INFORMATION, \
ASK_LAST_IDS, ANSWER_LAST_IDS, NOTIFY_PARTITION_CHANGES, \
ASK_UNFINISHED_TRANSACTIONS, ASK_NEW_TID, FINISH_TRANSACTION, \
NOTIFY_INFORMATION_LOCKED, ASK_NEW_OIDS, ABORT_TRANSACTION, \
STORAGE_NODE_TYPE, CLIENT_NODE_TYPE, MASTER_NODE_TYPE, \
RUNNING_STATE, BROKEN_STATE, TEMPORARILY_DOWN_STATE, DOWN_STATE, \
UP_TO_DATE_STATE, OUT_OF_DATE_STATE, FEEDING_STATE, DISCARDED_STATE
from neo.exception import OperationFailure, ElectionFailure
from neo.node import MasterNode, StorageNode
class MasterClientHandlerTests(NeoTestBase):
def setUp(self):
logging.basicConfig(level = logging.WARNING)
# create an application object
config = self.getConfigFile(master_number=1, replicas=1)
self.app = Application(config, "master1")
self.app.pt.clear()
self.app.pt.setID(pack('!Q', 1))
self.app.em = Mock({"getConnectionList" : []})
self.app.finishing_transaction_dict = {}
for server in self.app.master_node_list:
self.app.nm.add(MasterNode(server = server))
self.service = ClientServiceHandler(self.app)
# define some variable to simulate client and storage node
self.client_port = 11022
self.storage_port = 10021
self.master_port = 10010
self.master_address = ('127.0.0.1', self.master_port)
self.client_address = ('127.0.0.1', self.client_port)
self.storage_address = ('127.0.0.1', self.storage_port)
# register the storage
kw = {'uuid':self.getNewUUID(), 'server': self.master_address}
self.app.nm.add(StorageNode(**kw))
def tearDown(self):
NeoTestBase.tearDown(self)
def getLastUUID(self):
return self.uuid
def identifyToMasterNode(self, node_type=STORAGE_NODE_TYPE, ip="127.0.0.1",
port=10021):
"""Do first step of identification to MN """
# register the master itself
uuid = self.getNewUUID()
self.app.nm.add(MasterNode(uuid, (ip, port)))
return uuid
# Tests
def test_05_handleNotifyNodeInformation(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=NOTIFY_NODE_INFORMATION)
# tell the master node that is not running any longer, it must raises
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(MASTER_NODE_TYPE, '127.0.0.1', self.master_port, self.app.uuid, DOWN_STATE),]
self.assertRaises(RuntimeError, service.handleNotifyNodeInformation, conn, packet, node_list)
# tell the master node that it's running, nothing change
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(MASTER_NODE_TYPE, '127.0.0.1', self.master_port, self.app.uuid, RUNNING_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
# notify about a client node, don't care
new_uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(CLIENT_NODE_TYPE, '127.0.0.1', self.client_port, new_uuid, BROKEN_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
# notify about an unknown node, don't care
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(STORAGE_NODE_TYPE, '127.0.0.1', 11010, new_uuid, BROKEN_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
# notify about a known node but with bad address, don't care
self.app.nm.add(StorageNode(("127.0.0.1", 11011), self.getNewUUID()))
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(STORAGE_NODE_TYPE, '127.0.0.1', 11012, uuid, BROKEN_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
# notify node is running, as PMN already know it, nothing is done
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(STORAGE_NODE_TYPE, '127.0.0.1', self.storage_port, uuid, RUNNING_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
# notify node is temp down, must be taken into account
ptid = self.app.pt.getID()
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(STORAGE_NODE_TYPE, '127.0.0.1', self.storage_port, uuid, TEMPORARILY_DOWN_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getState(), TEMPORARILY_DOWN_STATE)
self.assertEquals(ptid, self.app.pt.getID())
# notify node is broken, must be taken into account and partition must changed
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(STORAGE_NODE_TYPE, '127.0.0.1', self.storage_port, uuid, BROKEN_STATE),]
service.handleNotifyNodeInformation(conn, packet, node_list)
for call in conn.mockGetAllCalls():
self.assertEquals(call.getName(), "getUUID")
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getState(), BROKEN_STATE)
self.failUnless(ptid < self.app.pt.getID())
def test_06_handleAnswerLastIDs(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ANSWER_LAST_IDS)
loid = self.app.loid
ltid = self.app.ltid
lptid = self.app.pt.getID()
# do not care if client node call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
node_list = []
self.checkUnexpectedPacketRaised(service.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# send information which are later to what PMN knows, this must raise
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
new_ptid = unpack('!Q', lptid)[0]
new_ptid = pack('!Q', new_ptid + 1)
self.failUnless(new_ptid > self.app.pt.getID())
self.assertRaises(OperationFailure, service.handleAnswerLastIDs, conn, packet, None, None, new_ptid)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
def test_07_handleAskNewTID(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_NEW_TID)
ltid = self.app.ltid
# client call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewTID(conn, packet)
self.failUnless(ltid < self.app.ltid)
self.assertEquals(len(self.app.finishing_transaction_dict), 1)
tid = self.app.finishing_transaction_dict.keys()[0]
self.assertEquals(tid, self.app.ltid)
def test_08_handleAskNewOIDs(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_NEW_OIDS)
loid = self.app.loid
# client call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewOIDs(conn, packet, 1)
self.failUnless(loid < self.app.loid)
def test_09_handleFinishTransaction(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=FINISH_TRANSACTION)
packet.setId(9)
# give an older tid than the PMN known, must abort
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
oid_list = []
upper, lower = unpack('!LL', self.app.ltid)
new_tid = pack('!LL', upper, lower + 10)
self.checkUnexpectedPacketRaised(service.handleFinishTransaction, conn, packet, oid_list, new_tid)
old_node = self.app.nm.getNodeByUUID(uuid)
self.app.nm.remove(old_node)
self.app.pt.dropNode(old_node)
# do the right job
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
storage_uuid = self.identifyToMasterNode()
storage_conn = self.getFakeConnection(storage_uuid, self.storage_address)
self.assertNotEquals(uuid, client_uuid)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewTID(conn, packet)
oid_list = []
tid = self.app.ltid
conn = self.getFakeConnection(client_uuid, self.client_address)
self.app.em = Mock({"getConnectionList" : [conn, storage_conn]})
service.handleFinishTransaction(conn, packet, oid_list, tid)
self.checkLockInformation(storage_conn)
self.assertEquals(len(self.app.finishing_transaction_dict), 1)
apptid = self.app.finishing_transaction_dict.keys()[0]
self.assertEquals(tid, apptid)
txn = self.app.finishing_transaction_dict.values()[0]
self.assertEquals(len(txn.getOIDList()), 0)
self.assertEquals(len(txn.getUUIDSet()), 1)
self.assertEquals(txn.getMessageId(), 9)
def test_11_handleAbortTransaction(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ABORT_TRANSACTION)
# give a bad tid, must not failed, just ignored it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 0)
service.handleAbortTransaction(conn, packet, None)
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 0)
# give a known tid
conn = self.getFakeConnection(client_uuid, self.client_address)
tid = self.app.ltid
self.app.finishing_transaction_dict[tid] = None
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 1)
service.handleAbortTransaction(conn, packet, tid)
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 0)
def test_12_handleAskLastIDs(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_LAST_IDS)
# give a uuid
conn = self.getFakeConnection(uuid, self.storage_address)
ptid = self.app.pt.getID()
tid = self.app.ltid
oid = self.app.loid
service.handleAskLastIDs(conn, packet)
packet = self.checkAnswerLastIDs(conn, answered_packet=packet)
loid, ltid, lptid = protocol._decodeAnswerLastIDs(packet._body)
self.assertEqual(loid, oid)
self.assertEqual(ltid, tid)
self.assertEqual(lptid, ptid)
def test_13_handleAskUnfinishedTransactions(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_UNFINISHED_TRANSACTIONS)
# give a uuid
conn = self.getFakeConnection(uuid, self.storage_address)
service.handleAskUnfinishedTransactions(conn, packet)
packet = self.checkAnswerUnfinishedTransactions(conn, answered_packet=packet)
tid_list = protocol._decodeAnswerUnfinishedTransactions(packet._body)[0]
self.assertEqual(len(tid_list), 0)
# create some transaction
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE,
port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
conn = self.getFakeConnection(uuid, self.storage_address)
service.handleAskUnfinishedTransactions(conn, packet)
packet = self.checkAnswerUnfinishedTransactions(conn, answered_packet=packet)
tid_list = protocol._decodeAnswerUnfinishedTransactions(packet._body)[0]
self.assertEqual(len(tid_list), 3)
def test_15_peerBroken(self):
service = self.service
uuid = self.identifyToMasterNode()
# add a second storage node and then declare it as broken
self.identifyToMasterNode(port = self.storage_port+2)
storage_uuid = self.identifyToMasterNode(port = self.storage_port+1)
# filled the pt
self.app.pt.make(self.app.nm.getStorageNodeList())
self.assertTrue(self.app.pt.filled())
self.assertTrue(self.app.pt.operational())
conn = self.getFakeConnection(storage_uuid, ('127.0.0.1', self.storage_port+1))
lptid = self.app.pt.getID()
self.assertEquals(self.app.nm.getNodeByUUID(storage_uuid).getState(), RUNNING_STATE)
service.peerBroken(conn)
self.assertEquals(self.app.nm.getNodeByUUID(storage_uuid).getState(), BROKEN_STATE)
self.failUnless(lptid < self.app.pt.getID())
# give an uuid, must raise as no other storage node available
conn = self.getFakeConnection(uuid, self.storage_address)
lptid = self.app.pt.getID()
self.assertEquals(self.app.nm.getNodeByUUID(uuid).getState(), RUNNING_STATE)
self.assertRaises(OperationFailure, service.peerBroken, conn)
self.assertEquals(self.app.nm.getNodeByUUID(uuid).getState(), BROKEN_STATE)
self.failUnless(lptid < self.app.pt.getID())
# give a client uuid which have unfinished transactions
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE,
port = self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
lptid = self.app.pt.getID()
packet = Packet(msg_type=ASK_NEW_TID)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
self.assertEquals(self.app.nm.getNodeByUUID(client_uuid).getState(), RUNNING_STATE)
self.assertEquals(len(self.app.finishing_transaction_dict.keys()), 3)
service.peerBroken(conn)
# node must be have been remove, and no more transaction must remains
self.assertEquals(self.app.nm.getNodeByUUID(client_uuid), None)
self.assertEquals(lptid, self.app.pt.getID())
self.assertEquals(len(self.app.finishing_transaction_dict.keys()), 0)
def test_16_timeoutExpired(self):
service = self.service
uuid = self.identifyToMasterNode()
# add a second storage node and then declare it as temp down
self.identifyToMasterNode(port = self.storage_port+2)
storage_uuid = self.identifyToMasterNode(port = self.storage_port+1)
# filled the pt
self.app.pt.make(self.app.nm.getStorageNodeList())
self.assertTrue(self.app.pt.filled())
self.assertTrue(self.app.pt.operational())
conn = self.getFakeConnection(storage_uuid, ('127.0.0.1', self.storage_port+1))
lptid = self.app.pt.getID()
self.assertEquals(self.app.nm.getNodeByUUID(storage_uuid).getState(), RUNNING_STATE)
service.timeoutExpired(conn)
self.assertEquals(self.app.nm.getNodeByUUID(storage_uuid).getState(), TEMPORARILY_DOWN_STATE)
self.assertEquals(lptid, self.app.pt.getID())
# give an uuid, must raise as no other storage node available
conn = self.getFakeConnection(uuid, self.storage_address)
lptid = self.app.pt.getID()
self.assertEquals(self.app.nm.getNodeByUUID(uuid).getState(), RUNNING_STATE)
self.assertRaises(OperationFailure, service.timeoutExpired, conn)
self.assertEquals(self.app.nm.getNodeByUUID(uuid).getState(), TEMPORARILY_DOWN_STATE)
self.assertEquals(lptid, self.app.pt.getID())
# give a client uuid which have unfinished transactions
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE,
port = self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
lptid = self.app.pt.getID()
packet = Packet(msg_type=ASK_NEW_TID)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
self.assertEquals(self.app.nm.getNodeByUUID(client_uuid).getState(), RUNNING_STATE)
self.assertEquals(len(self.app.finishing_transaction_dict.keys()), 3)
service.timeoutExpired(conn)
# node must be have been remove, and no more transaction must remains
self.assertEquals(self.app.nm.getNodeByUUID(client_uuid), None)
self.assertEquals(lptid, self.app.pt.getID())
self.assertEquals(len(self.app.finishing_transaction_dict.keys()), 0)
def test_17_connectionClosed(self):
service = self.service
uuid = self.identifyToMasterNode()
# add a second storage node and then declare it as temp down
self.identifyToMasterNode(port = self.storage_port+2)
storage_uuid = self.identifyToMasterNode(port = self.storage_port+1)
# filled the pt
self.app.pt.make(self.app.nm.getStorageNodeList())
self.assertTrue(self.app.pt.filled())
self.assertTrue(self.app.pt.operational())
conn = self.getFakeConnection(storage_uuid, ('127.0.0.1', self.storage_port+1))
lptid = self.app.pt.getID()
self.assertEquals(self.app.nm.getNodeByUUID(storage_uuid).getState(), RUNNING_STATE)
service.connectionClosed(conn)
self.assertEquals(self.app.nm.getNodeByUUID(storage_uuid).getState(), TEMPORARILY_DOWN_STATE)
self.assertEquals(lptid, self.app.pt.getID())
# give an uuid, must raise as no other storage node available
conn = self.getFakeConnection(uuid, self.storage_address)
lptid = self.app.pt.getID()
self.assertEquals(self.app.nm.getNodeByUUID(uuid).getState(), RUNNING_STATE)
self.assertRaises(OperationFailure, service.connectionClosed, conn)
self.assertEquals(self.app.nm.getNodeByUUID(uuid).getState(), TEMPORARILY_DOWN_STATE)
self.assertEquals(lptid, self.app.pt.getID())
# give a client uuid which have unfinished transactions
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE,
port = self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
lptid = self.app.pt.getID()
packet = Packet(msg_type=ASK_NEW_TID)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
service.handleAskNewTID(conn, packet)
self.assertEquals(self.app.nm.getNodeByUUID(client_uuid).getState(), RUNNING_STATE)
self.assertEquals(len(self.app.finishing_transaction_dict.keys()), 3)
service.connectionClosed(conn)
# node must be have been remove, and no more transaction must remains
self.assertEquals(self.app.nm.getNodeByUUID(client_uuid), None)
self.assertEquals(lptid, self.app.pt.getID())
self.assertEquals(len(self.app.finishing_transaction_dict.keys()), 0)
if __name__ == '__main__':
unittest.main()
......@@ -23,7 +23,7 @@ from struct import pack, unpack
from neo.tests.base import NeoTestBase
from neo import protocol
from neo.protocol import Packet, INVALID_UUID
from neo.master.election import ElectionEventHandler
from neo.master.handlers import ClientElectionHandler, ServerElectionHandler
from neo.master.app import Application
from neo.protocol import ERROR, REQUEST_NODE_IDENTIFICATION, ACCEPT_NODE_IDENTIFICATION, \
PING, PONG, ASK_PRIMARY_MASTER, ANSWER_PRIMARY_MASTER, ANNOUNCE_PRIMARY_MASTER, \
......@@ -61,8 +61,73 @@ def expectMessage(self, packet):
self.connector.expectMessage(packet)
class MasterClientElectionTests(NeoTestBase):
def setUp(self):
logging.basicConfig(level = logging.WARNING)
# create an application object
config = self.getConfigFile()
self.app = Application(config, "master1")
self.app.pt.clear()
self.app.em = Mock({"getConnectionList" : []})
self.app.finishing_transaction_dict = {}
for server in self.app.master_node_list:
self.app.nm.add(MasterNode(server = server))
self.election = ClientElectionHandler(self.app)
self.app.unconnected_master_node_set = set()
self.app.negotiating_master_node_set = set()
for node in self.app.nm.getMasterNodeList():
self.app.unconnected_master_node_set.add(node.getServer())
node.setState(RUNNING_STATE)
# define some variable to simulate client and storage node
self.client_port = 11022
self.storage_port = 10021
self.master_port = 10011
# apply monkey patches
self._addPacket = ClientConnection._addPacket
self.expectMessage = ClientConnection.expectMessage
ClientConnection._addPacket = _addPacket
ClientConnection.expectMessage = expectMessage
def tearDown(self):
NeoTestBase.tearDown(self)
def test_01_connectionStarted(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.master_port)})
self.assertEqual(len(self.app.unconnected_master_node_set), 1)
self.assertEqual(len(self.app.negotiating_master_node_set), 0)
self.election.connectionStarted(conn)
self.assertEqual(len(self.app.unconnected_master_node_set), 0)
self.assertEqual(len(self.app.negotiating_master_node_set), 1)
def test_02_connectionCompleted(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.master_port)})
self.election.connectionCompleted(conn)
self.checkCalledRequestNodeIdentification(conn)
def test_03_connectionFailed(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.master_port)})
self.assertEqual(len(self.app.unconnected_master_node_set), 1)
self.assertEqual(len(self.app.negotiating_master_node_set), 0)
self.election.connectionStarted(conn)
self.assertEqual(len(self.app.unconnected_master_node_set), 0)
self.assertEqual(len(self.app.negotiating_master_node_set), 1)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()).getState(), RUNNING_STATE)
self.election.connectionFailed(conn)
self.assertEqual(len(self.app.unconnected_master_node_set), 1)
self.assertEqual(len(self.app.negotiating_master_node_set), 0)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()).getState(), TEMPORARILY_DOWN_STATE)
class MasterElectionTests(NeoTestBase):
class MasterServerElectionTests(NeoTestBase):
def setUp(self):
logging.basicConfig(level = logging.WARNING)
......@@ -74,7 +139,7 @@ class MasterElectionTests(NeoTestBase):
self.app.finishing_transaction_dict = {}
for server in self.app.master_node_list:
self.app.nm.add(MasterNode(server = server))
self.election = ElectionEventHandler(self.app)
self.election = ServerElectionHandler(self.app)
self.app.unconnected_master_node_set = set()
self.app.negotiating_master_node_set = set()
for node in self.app.nm.getMasterNodeList():
......@@ -112,19 +177,6 @@ class MasterElectionTests(NeoTestBase):
"""Do first step of identification to MN
"""
uuid = self.getNewUUID()
args = (node_type, uuid, ip, port, self.app.name)
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = Mock({"_addPacket" : None, "abort" : None, "expectMessage" : None,
"isServerConnection" : True})
self.election.handleRequestNodeIdentification(conn,
packet=packet,
node_type=node_type,
uuid=uuid,
ip_address=ip,
port=port,
name=self.app.name,)
self.checkAcceptNodeIdentification(conn, answered_packet=packet)
return uuid
# Method to test the kind of packet returned in answer
......@@ -153,39 +205,6 @@ class MasterElectionTests(NeoTestBase):
self.assertEquals(packet.getType(), ANSWER_PRIMARY_MASTER)
# Tests
def test_01_connectionStarted(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.master_port)})
self.assertEqual(len(self.app.unconnected_master_node_set), 1)
self.assertEqual(len(self.app.negotiating_master_node_set), 0)
self.election.connectionStarted(conn)
self.assertEqual(len(self.app.unconnected_master_node_set), 0)
self.assertEqual(len(self.app.negotiating_master_node_set), 1)
def test_02_connectionCompleted(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.master_port)})
self.election.connectionCompleted(conn)
self.checkCalledRequestNodeIdentification(conn)
def test_03_connectionFailed(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.master_port)})
self.assertEqual(len(self.app.unconnected_master_node_set), 1)
self.assertEqual(len(self.app.negotiating_master_node_set), 0)
self.election.connectionStarted(conn)
self.assertEqual(len(self.app.unconnected_master_node_set), 0)
self.assertEqual(len(self.app.negotiating_master_node_set), 1)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()).getState(), RUNNING_STATE)
self.election.connectionFailed(conn)
self.assertEqual(len(self.app.unconnected_master_node_set), 1)
self.assertEqual(len(self.app.negotiating_master_node_set), 0)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()).getState(), TEMPORARILY_DOWN_STATE)
def test_04_connectionClosed(self):
uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
......
......@@ -23,7 +23,7 @@ from struct import pack, unpack
from neo.tests.base import NeoTestBase
from neo import protocol
from neo.protocol import Packet, INVALID_UUID
from neo.master.recovery import RecoveryEventHandler
from neo.master.handlers import RecoveryHandler
from neo.master.app import Application
from neo.protocol import ERROR, REQUEST_NODE_IDENTIFICATION, ACCEPT_NODE_IDENTIFICATION, \
PING, PONG, ASK_PRIMARY_MASTER, ANSWER_PRIMARY_MASTER, ANNOUNCE_PRIMARY_MASTER, \
......@@ -62,7 +62,7 @@ class MasterRecoveryTests(NeoTestBase):
self.app.finishing_transaction_dict = {}
for server in self.app.master_node_list:
self.app.nm.add(MasterNode(server = server))
self.recovery = RecoveryEventHandler(self.app)
self.recovery = RecoveryHandler(self.app)
self.app.unconnected_master_node_set = set()
self.app.negotiating_master_node_set = set()
for node in self.app.nm.getMasterNodeList():
......@@ -88,12 +88,6 @@ class MasterRecoveryTests(NeoTestBase):
"""Do first step of identification to MN
"""
uuid = self.getNewUUID()
args = (node_type, uuid, ip, port,self.app.name)
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = Mock({})
self.recovery.handleRequestNodeIdentification(conn, packet, *args)
self.checkAcceptNodeIdentification(conn)
return uuid
# Tests
......@@ -119,287 +113,10 @@ class MasterRecoveryTests(NeoTestBase):
self.recovery.peerBroken(conn)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()).getState(), BROKEN_STATE)
def test_04_handleRequestNodeIdentification(self):
recovery = self.recovery
uuid = self.getNewUUID()
args = (MASTER_NODE_TYPE, uuid, '127.0.0.1', self.storage_port, "INVALID_NAME")
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = Mock({})
self.checkProtocolErrorRaised(
recovery.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name="INVALID_NAME",)
# test connection from a client node, rejectet
uuid = self.getNewUUID()
conn = Mock({})
self.checkNotReadyErrorRaised(
recovery.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=CLIENT_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.client_port,
name=self.app.name,)
# 1. unknown storage node with known address, must be rejected
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkProtocolErrorRaised(
recovery.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
# 2. unknown master node with known address, will be accepted
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
recovery.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
# 3. unknown master node with known address but different uuid, will be replaced
old_uuid = uuid
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
self.assertEqual(node.getUUID(), old_uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkProtocolErrorRaised(
recovery.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
# 4. unknown master node with known address but different uuid and broken state, will be accepted
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
node.setState(DOWN_STATE)
self.assertEqual(node.getState(), DOWN_STATE)
self.assertEqual(node.getUUID(), old_uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
recovery.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
known_uuid = uuid
# 5. known by uuid, but different address -> conflict / new master
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
recovery.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.2',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.checkAcceptNodeIdentification(conn)
# a new uuid is sent
call = conn.mockGetNamedCalls('answer')[0]
body = call.getParam(0)._body
new_uuid = body[:-16]
self.assertNotEquals(new_uuid, uuid)
# 6.known by uuid, but different address and non running state -> conflict
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
node.setState(DOWN_STATE)
self.assertEqual(node.getState(), DOWN_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.checkProtocolErrorRaised(
recovery.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.2',
port=self.master_port,
name=self.app.name,)
# 7. known node but broken
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), DOWN_STATE)
node.setState(BROKEN_STATE)
self.assertEqual(node.getState(), BROKEN_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.checkBrokenNodeDisallowedErrorRaised(
recovery.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
# 8. known node but down
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), BROKEN_STATE)
node.setState(DOWN_STATE)
self.assertEqual(node.getState(), DOWN_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
recovery.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
# 9. New node
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, ('127.0.0.3', self.master_port))
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
recovery.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.3',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 3)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
def test_05_handleAskPrimaryMaster(self):
recovery = self.recovery
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = protocol.askPrimaryMaster()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
recovery.handleAskPrimaryMaster(conn, packet)
self.checkNotAborted(conn)
self.checkAnswerPrimaryMaster(conn)
self.checkNotifyNodeInformation(conn)
# if storage node, expect message
uuid = self.identifyToMasterNode(STORAGE_NODE_TYPE, port=self.storage_port)
packet = protocol.askPrimaryMaster()
conn = self.getFakeConnection(uuid, self.storage_port)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
recovery.handleAskPrimaryMaster(conn, packet)
self.checkNotAborted(conn)
self.checkAnswerPrimaryMaster(conn)
self.checkNotifyNodeInformation(conn)
self.checkAskLastIDs(conn)
def test_06_handleAnnouncePrimaryMaster(self):
recovery = self.recovery
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = Packet(msg_type=ANNOUNCE_PRIMARY_MASTER)
# No uuid
conn = self.getFakeConnection(None, self.master_address)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkIdenficationRequired(recovery.handleAnnouncePrimaryMaster, conn, packet)
# announce
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(self.app.primary, None)
self.assertEqual(self.app.primary_master_node, None)
self.assertRaises(ElectionFailure, recovery.handleAnnouncePrimaryMaster, conn, packet)
def test_07_handleReelectPrimaryMaster(self):
recovery = self.recovery
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = protocol.askPrimaryMaster()
# No uuid
conn = self.getFakeConnection(uuid, self.master_address)
self.assertRaises(ElectionFailure, recovery.handleReelectPrimaryMaster, conn, packet)
def test_08_handleNotifyNodeInformation(self):
recovery = self.recovery
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = Packet(msg_type=NOTIFY_NODE_INFORMATION)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.master_address)
node_list = []
self.checkIdenficationRequired(recovery.handleNotifyNodeInformation, conn, packet, node_list)
# tell about a client node, do nothing
conn = self.getFakeConnection(uuid, self.master_address)
node_list = [(CLIENT_NODE_TYPE, '127.0.0.1', self.client_port, self.getNewUUID(), DOWN_STATE),]
......@@ -455,21 +172,6 @@ class MasterRecoveryTests(NeoTestBase):
loid = self.app.loid
ltid = self.app.ltid
lptid = self.app.pt.getID()
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_port)
node_list = []
self.checkIdenficationRequired(recovery.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# do not care if master node call it
master_uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.master_address)
node_list = []
self.checkUnexpectedPacketRaised(recovery.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# send information which are later to what PMN knows, this must update target node
conn = self.getFakeConnection(uuid, self.storage_port)
node_list = []
......@@ -494,12 +196,6 @@ class MasterRecoveryTests(NeoTestBase):
recovery = self.recovery
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = Packet(msg_type=ANSWER_PARTITION_TABLE)
# No uuid
conn = self.getFakeConnection(None, self.master_address)
self.checkIdenficationRequired(recovery.handleAnswerPartitionTable, conn, packet, None, [])
# not a storage node
conn = self.getFakeConnection(uuid, self.master_address)
self.checkUnexpectedPacketRaised(recovery.handleAnswerPartitionTable, conn, packet, None, [])
# not from target node, ignore
uuid = self.identifyToMasterNode(STORAGE_NODE_TYPE, port=self.storage_port)
conn = self.getFakeConnection(uuid, self.storage_port)
......
......@@ -24,7 +24,7 @@ from neo.tests.base import NeoTestBase
import neo.master
from neo import protocol
from neo.protocol import Packet, INVALID_UUID
from neo.master.service import ServiceEventHandler
from neo.master.handlers import StorageServiceHandler
from neo.master.app import Application
from neo.protocol import ERROR, PING, PONG, ANNOUNCE_PRIMARY_MASTER, \
REELECT_PRIMARY_MASTER, NOTIFY_NODE_INFORMATION, \
......@@ -37,7 +37,7 @@ from neo.protocol import ERROR, PING, PONG, ANNOUNCE_PRIMARY_MASTER, \
from neo.exception import OperationFailure, ElectionFailure
from neo.node import MasterNode, StorageNode
class MasterServiceTests(NeoTestBase):
class MasterStorageHandlerTests(NeoTestBase):
def setUp(self):
logging.basicConfig(level = logging.WARNING)
......@@ -50,7 +50,7 @@ class MasterServiceTests(NeoTestBase):
self.app.finishing_transaction_dict = {}
for server in self.app.master_node_list:
self.app.nm.add(MasterNode(server = server))
self.service = ServiceEventHandler(self.app)
self.service = StorageServiceHandler(self.app)
# define some variable to simulate client and storage node
self.client_port = 11022
self.storage_port = 10021
......@@ -71,218 +71,13 @@ class MasterServiceTests(NeoTestBase):
"""Do first step of identification to MN
"""
uuid = self.getNewUUID()
args = (node_type, uuid, ip, port, self.app.name)
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = self.getFakeConnection()
self.service.handleRequestNodeIdentification(conn, packet, *args)
self.checkAcceptNodeIdentification(conn, answered_packet=packet)
return uuid
# Tests
def test_01_handleRequestNodeIdentification(self):
service = self.service
uuid = self.getNewUUID()
args = (STORAGE_NODE_TYPE, uuid, '127.0.0.1', self.storage_port, 'INVALID_NAME')
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
self.checkProtocolErrorRaised(service.handleRequestNodeIdentification, conn, packet, *args)
self.assertEquals(len(self.app.nm.getStorageNodeList()), 0)
self.assertEquals(self.app.pt.getID(), ptid)
# test connection of a storage node
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
service.handleRequestNodeIdentification(conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name=self.app.name,)
self.checkAcceptNodeIdentification(conn, answered_packet=packet)
self.assertEquals(len(self.app.nm.getStorageNodeList()), 1)
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getServer(), ('127.0.0.1', self.storage_port))
self.assertEquals(sn.getUUID(), uuid)
self.assertEquals(sn.getState(), RUNNING_STATE)
self.failUnless(self.app.pt.getID() > ptid)
# send message again for the same storage node, MN must recognize it
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
service.handleRequestNodeIdentification(conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name=self.app.name,)
self.checkAcceptNodeIdentification(conn, answered_packet=packet)
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getServer(), ('127.0.0.1', self.storage_port))
self.assertEquals(sn.getUUID(), uuid)
self.assertEquals(sn.getState(), RUNNING_STATE)
# No change of partition table
self.assertEquals(self.app.pt.getID(), ptid)
# send message again for the same storage node but different uuid
# must be rejected as SN is considered as running
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
new_uuid = self.getNewUUID()
self.checkProtocolErrorRaised(
service.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=new_uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name=self.app.name,)
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getServer(), ('127.0.0.1', self.storage_port))
self.assertEquals(sn.getUUID(), uuid)
self.assertEquals(sn.getState(), RUNNING_STATE)
# No change of partition table
self.assertEquals(self.app.pt.getID(), ptid)
# same test, but set SN as not running before
# this new node must replaced the old one
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getState(), RUNNING_STATE)
sn.setState(TEMPORARILY_DOWN_STATE)
self.assertEquals(sn.getState(), TEMPORARILY_DOWN_STATE)
service.handleRequestNodeIdentification(conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=new_uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name=self.app.name,)
self.checkAcceptNodeIdentification(conn, answered_packet=packet)
self.assertEquals(len(self.app.nm.getStorageNodeList()), 1)
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getServer(), ('127.0.0.1', self.storage_port))
self.assertEquals(sn.getUUID(), new_uuid)
self.assertEquals(sn.getState(), RUNNING_STATE)
# Partition table changed
self.failUnless(self.app.pt.getID() > ptid)
uuid = new_uuid
# send message again for the same storage node but different address
# A new UUID should be send and the node is added to the storage node list
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
service.handleRequestNodeIdentification(conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.2',
port=10022,
name=self.app.name,)
self.checkAcceptNodeIdentification(conn, answered_packet=packet)
call = conn.mockGetNamedCalls('answer')[0]
new_uuid = call.getParam(0)._body[-16:]
self.assertNotEquals(uuid, new_uuid)
self.assertEquals(len(self.app.nm.getStorageNodeList()), 2)
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getServer(), ('127.0.0.1', self.storage_port))
self.assertEquals(sn.getUUID(), uuid)
self.assertEquals(sn.getState(), RUNNING_STATE)
sn = self.app.nm.getStorageNodeList()[1]
self.assertEquals(sn.getServer(), ('127.0.0.2', 10022))
self.assertEquals(sn.getUUID(), new_uuid)
self.assertEquals(sn.getState(), RUNNING_STATE)
# Partition table changed
self.failUnless(self.app.pt.getID() > ptid)
# mark the node as broken and request identification, this must be forbidden
conn = self.getFakeConnection()
ptid = self.app.pt.getID()
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getState(), RUNNING_STATE)
sn.setState(BROKEN_STATE)
self.assertEquals(sn.getState(), BROKEN_STATE)
self.checkBrokenNodeDisallowedErrorRaised(
service.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name=self.app.name,)
self.assertEquals(len(self.app.nm.getStorageNodeList()), 2)
sn = self.app.nm.getStorageNodeList()[0]
self.assertEquals(sn.getServer(), ('127.0.0.1', self.storage_port))
self.assertEquals(sn.getUUID(), uuid)
self.assertEquals(sn.getState(), BROKEN_STATE)
# No change of partition table
self.assertEqual(self.app.pt.getID(), ptid)
def test_02_handleAskPrimaryMaster(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = protocol.askPrimaryMaster()
# test answer to a storage node
conn = self.getFakeConnection(uuid, self.storage_address)
service.handleAskPrimaryMaster(conn, packet)
self.checkNotAborted(conn)
self.checkAnswerPrimaryMaster(conn, answered_packet=packet)
self.checkNotifyNodeInformation(conn, packet_number=0)
self.checkSendPartitionTable(conn, packet_number=1)
self.checkSendPartitionTable(conn, packet_number=2)
self.checkStartOperation(conn, packet_number=3)
# Same but identify as a client node, must not get start operation message
uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=11021)
packet = protocol.askPrimaryMaster()
conn = self.getFakeConnection(uuid, ("127.0.0.1", 11021))
service.handleAskPrimaryMaster(conn, packet)
self.checkNotAborted(conn)
self.checkAnswerPrimaryMaster(conn, answered_packet=packet)
self.checkNotifyNodeInformation(conn, packet_number=0)
self.checkSendPartitionTable(conn, packet_number=1)
self.checkSendPartitionTable(conn, packet_number=2)
def test_03_handleAnnouncePrimaryMaster(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ANNOUNCE_PRIMARY_MASTER)
conn = self.getFakeConnection(uuid, self.storage_address)
# must do a relection
self.assertRaises(ElectionFailure, service.handleAnnouncePrimaryMaster, conn, packet)
# if no uuid in conn, no reelection done
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(service.handleAnnouncePrimaryMaster, conn, packet)
def test_04_handleReelectPrimaryMaster(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=REELECT_PRIMARY_MASTER)
conn = self.getFakeConnection(uuid, self.storage_address)
# must do a relection
self.assertRaises(ElectionFailure, service.handleReelectPrimaryMaster, conn, packet)
def test_05_handleNotifyNodeInformation(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=NOTIFY_NODE_INFORMATION)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleNotifyNodeInformation, conn, packet, node_list)
# tell the master node that is not running any longer, it must raises
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = [(MASTER_NODE_TYPE, '127.0.0.1', self.master_port, self.app.uuid, DOWN_STATE),]
......@@ -346,21 +141,6 @@ class MasterServiceTests(NeoTestBase):
loid = self.app.loid
ltid = self.app.ltid
lptid = self.app.pt.getID()
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# do not care if client node call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
node_list = []
self.checkUnexpectedPacketRaised(service.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# send information which are later to what PMN knows, this must raise
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
......@@ -372,110 +152,10 @@ class MasterServiceTests(NeoTestBase):
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
def test_07_handleAskNewTID(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_NEW_TID)
ltid = self.app.ltid
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleAskNewTID, conn, packet)
self.assertEquals(ltid, self.app.ltid)
# do not care if storage node call it
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
self.checkUnexpectedPacketRaised(service.handleAskNewTID, conn, packet)
self.assertEquals(ltid, self.app.ltid)
# client call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewTID(conn, packet)
self.failUnless(ltid < self.app.ltid)
self.assertEquals(len(self.app.finishing_transaction_dict), 1)
tid = self.app.finishing_transaction_dict.keys()[0]
self.assertEquals(tid, self.app.ltid)
def test_08_handleAskNewOIDs(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_NEW_OIDS)
loid = self.app.loid
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleAskNewOIDs, conn, packet, 1)
self.assertEquals(loid, self.app.loid)
# do not care if storage node call it
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
self.checkUnexpectedPacketRaised(service.handleAskNewOIDs, conn, packet, 1)
self.assertEquals(loid, self.app.loid)
# client call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewOIDs(conn, packet, 1)
self.failUnless(loid < self.app.loid)
def test_09_handleFinishTransaction(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=FINISH_TRANSACTION)
packet.setId(9)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleFinishTransaction, conn, packet, [], None, )
# do not care if storage node call it
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
self.checkUnexpectedPacketRaised(service.handleFinishTransaction, conn, packet, [], None)
# give an older tid than the PMN known, must abort
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
oid_list = []
upper, lower = unpack('!LL', self.app.ltid)
new_tid = pack('!LL', upper, lower + 10)
self.checkUnexpectedPacketRaised(service.handleFinishTransaction, conn, packet, oid_list, new_tid)
old_node = self.app.nm.getNodeByUUID(uuid)
self.app.nm.remove(old_node)
self.app.pt.dropNode(old_node)
# do the right job
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
storage_uuid = self.identifyToMasterNode()
storage_conn = self.getFakeConnection(storage_uuid, self.storage_address)
self.assertNotEquals(uuid, client_uuid)
conn = self.getFakeConnection(client_uuid, self.client_address)
service.handleAskNewTID(conn, packet)
oid_list = []
tid = self.app.ltid
conn = self.getFakeConnection(client_uuid, self.client_address)
self.app.em = Mock({"getConnectionList" : [conn, storage_conn]})
service.handleFinishTransaction(conn, packet, oid_list, tid)
self.checkLockInformation(storage_conn)
self.assertEquals(len(self.app.finishing_transaction_dict), 1)
apptid = self.app.finishing_transaction_dict.keys()[0]
self.assertEquals(tid, apptid)
txn = self.app.finishing_transaction_dict.values()[0]
self.assertEquals(len(txn.getOIDList()), 0)
self.assertEquals(len(txn.getUUIDSet()), 1)
self.assertEquals(txn.getMessageId(), 9)
def test_10_handleNotifyInformationLocked(self):
service = self.service
uuid = self.identifyToMasterNode(port=10020)
packet = Packet(msg_type=NOTIFY_INFORMATION_LOCKED)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleNotifyInformationLocked, conn, packet, None, )
# do not care if client node call it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=11021)
client = self.getFakeConnection(client_uuid, ('127.0.0.1', 11020))
self.checkUnexpectedPacketRaised(service.handleNotifyInformationLocked, conn, packet, None)
# give an older tid than the PMN known, must abort
conn = self.getFakeConnection(uuid, self.storage_address)
oid_list = []
......@@ -515,40 +195,10 @@ class MasterServiceTests(NeoTestBase):
self.checkLockInformation(storage_conn_2)
def test_11_handleAbortTransaction(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ABORT_TRANSACTION)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(service.handleAbortTransaction, conn, packet, None, )
# do not answer if not a client
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
self.checkUnexpectedPacketRaised(service.handleAbortTransaction, conn, packet, None)
# give a bad tid, must not failed, just ignored it
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE, port=self.client_port)
conn = self.getFakeConnection(client_uuid, self.client_address)
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 0)
service.handleAbortTransaction(conn, packet, None)
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 0)
# give a known tid
conn = self.getFakeConnection(client_uuid, self.client_address)
tid = self.app.ltid
self.app.finishing_transaction_dict[tid] = None
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 1)
service.handleAbortTransaction(conn, packet, tid)
self.assertEqual(len(self.app.finishing_transaction_dict.keys()), 0)
def test_12_handleAskLastIDs(self):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_LAST_IDS)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(service.handleAskLastIDs, conn, packet )
# give a uuid
conn = self.getFakeConnection(uuid, self.storage_address)
ptid = self.app.pt.getID()
......@@ -566,10 +216,6 @@ class MasterServiceTests(NeoTestBase):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ASK_UNFINISHED_TRANSACTIONS)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(service.handleAskUnfinishedTransactions,
conn, packet)
# give a uuid
conn = self.getFakeConnection(uuid, self.storage_address)
service.handleAskUnfinishedTransactions(conn, packet)
......@@ -594,10 +240,6 @@ class MasterServiceTests(NeoTestBase):
service = self.service
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=NOTIFY_PARTITION_CHANGES)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(service.handleNotifyPartitionChanges,
conn, packet, None, None)
# do not answer if not a storage node
client_uuid = self.identifyToMasterNode(node_type=CLIENT_NODE_TYPE,
port=self.client_port)
......
......@@ -23,7 +23,7 @@ from struct import pack, unpack
import neo
from neo.tests.base import NeoTestBase
from neo.protocol import Packet, INVALID_UUID
from neo.master.verification import VerificationEventHandler
from neo.master.handlers import VerificationHandler
from neo.master.app import Application
from neo import protocol
from neo.protocol import ERROR, ANNOUNCE_PRIMARY_MASTER, \
......@@ -50,7 +50,7 @@ class MasterVerificationTests(NeoTestBase):
self.app.finishing_transaction_dict = {}
for server in self.app.master_node_list:
self.app.nm.add(MasterNode(server = server))
self.verification = VerificationEventHandler(self.app)
self.verification = VerificationHandler(self.app)
self.app.unconnected_master_node_set = set()
self.app.negotiating_master_node_set = set()
self.app.asking_uuid_dict = {}
......@@ -78,13 +78,6 @@ class MasterVerificationTests(NeoTestBase):
"""Do first step of identification to MN
"""
uuid = self.getNewUUID()
args = (node_type, uuid, ip, port, self.app.name)
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = self.getFakeConnection()
self.verification.handleRequestNodeIdentification(conn, packet, *args)
self.app.nm.getNodeByServer((ip, port)).setState(RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
return uuid
# Tests
......@@ -127,282 +120,10 @@ class MasterVerificationTests(NeoTestBase):
self.assertRaises(VerificationFailure, self.verification.connectionClosed,conn)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()).getState(), TEMPORARILY_DOWN_STATE)
def test_04_handleRequestNodeIdentification(self):
verification = self.verification
uuid = self.getNewUUID()
args = ( MASTER_NODE_TYPE, uuid, '127.0.0.1', self.storage_port, "INVALID_NAME")
packet = protocol.requestNodeIdentification(*args)
# test alien cluster
conn = self.getFakeConnection()
self.checkProtocolErrorRaised(
verification.handleRequestNodeIdentification,
conn, packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.storage_port,
name="INVALID_NAME",)
# test connection from a client node, rejectet
uuid = self.getNewUUID()
conn = self.getFakeConnection()
self.checkNotReadyErrorRaised(
verification.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=CLIENT_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.client_port,
name=self.app.name,)
# 1. unknown storage node with known address, must be rejected
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkProtocolErrorRaised(
verification.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=STORAGE_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
# 2. unknown master node with known address, will be accepted
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
verification.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkUUIDSet(conn, uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
# 3. unknown master node with known address but different uuid, will be replaced
old_uuid = uuid
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
self.assertEqual(node.getUUID(), old_uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkProtocolErrorRaised(
verification.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
# 4. unknown master node with known address but different uuid and broken state, will be accepted
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
node.setState(DOWN_STATE)
self.assertEqual(node.getState(), DOWN_STATE)
self.assertEqual(node.getUUID(), old_uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
verification.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
# 5. known by uuid, but different address
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
verification.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.2',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.checkAcceptNodeIdentification(conn)
# a new uuid is sent
call = conn.mockGetNamedCalls('answer')[0]
body = call.getParam(0)._body
new_uuid = body[:-16]
self.assertNotEquals(new_uuid, uuid)
# 6.known by uuid, but different address and non running state
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), RUNNING_STATE)
node.setState(DOWN_STATE)
self.assertEqual(node.getState(), DOWN_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.checkProtocolErrorRaised(
verification.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.2',
port=self.master_port,
name=self.app.name,)
# 7. known node but broken
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), DOWN_STATE)
node.setState(BROKEN_STATE)
self.assertEqual(node.getState(), BROKEN_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.checkBrokenNodeDisallowedErrorRaised(
verification.handleRequestNodeIdentification,
conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
# 8. known node but down
conn = self.getFakeConnection(uuid, self.master_address)
self.assertNotEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertNotEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
node = self.app.nm.getNodeByServer(conn.getAddress())
self.assertEqual(node.getState(), BROKEN_STATE)
node.setState(DOWN_STATE)
self.assertEqual(node.getState(), DOWN_STATE)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
verification.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.1',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
# 9. New node
uuid = self.getNewUUID()
conn = self.getFakeConnection(uuid, ('127.0.0.3', self.master_port))
self.assertEqual(self.app.nm.getNodeByUUID(conn.getUUID()), None)
self.assertEqual(self.app.nm.getNodeByServer(conn.getAddress()), None)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 2)
verification.handleRequestNodeIdentification(conn,
packet=packet,
node_type=MASTER_NODE_TYPE,
uuid=uuid,
ip_address='127.0.0.3',
port=self.master_port,
name=self.app.name,)
node = self.app.nm.getNodeByUUID(conn.getUUID())
self.assertEqual(len(self.app.nm.getMasterNodeList()), 3)
self.assertEqual(node.getUUID(), uuid)
self.assertEqual(node.getState(), RUNNING_STATE)
self.checkAcceptNodeIdentification(conn)
def test_05_handleAskPrimaryMaster(self):
verification = self.verification
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = protocol.askPrimaryMaster()
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
verification.handleAskPrimaryMaster(conn, packet)
self.checkNotAborted(conn)
self.checkAnswerPrimaryMaster(conn)
self.checkNotifyNodeInformation(conn)
# if storage node, expect messages
uuid = self.identifyToMasterNode(STORAGE_NODE_TYPE, port=self.storage_port)
packet = protocol.askPrimaryMaster()
conn = self.getFakeConnection(uuid, self.storage_address)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
verification.handleAskPrimaryMaster(conn, packet)
self.checkNotAborted(conn)
self.checkAnswerPrimaryMaster(conn)
self.checkNotifyNodeInformation(conn, packet_number=0)
self.checkSendPartitionTable(conn, packet_number=1)
self.checkSendPartitionTable(conn, packet_number=2)
def test_06_handleAnnouncePrimaryMaster(self):
verification = self.verification
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = Packet(msg_type=ANNOUNCE_PRIMARY_MASTER)
# No uuid
conn = self.getFakeConnection(None, self.master_address)
self.assertEqual(len(self.app.nm.getMasterNodeList()), 1)
self.checkIdenficationRequired(verification.handleAnnouncePrimaryMaster, conn, packet)
# announce
conn = self.getFakeConnection(uuid, self.master_address)
self.assertEqual(self.app.primary, None)
self.assertEqual(self.app.primary_master_node, None)
self.assertRaises(ElectionFailure, verification.handleAnnouncePrimaryMaster, conn, packet)
def test_07_handleReelectPrimaryMaster(self):
verification = self.verification
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = protocol.askPrimaryMaster()
# No uuid
conn = self.getFakeConnection(None, self.master_address)
self.assertRaises(ElectionFailure, verification.handleReelectPrimaryMaster, conn, packet)
def test_08_handleNotifyNodeInformation(self):
verification = self.verification
uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
packet = Packet(msg_type=NOTIFY_NODE_INFORMATION)
# do not answer if no uuid
conn = self.getFakeConnection(None, self.master_address)
node_list = []
self.checkIdenficationRequired(verification.handleNotifyNodeInformation, conn, packet, node_list)
# tell about a client node, do nothing
conn = self.getFakeConnection(uuid, self.master_address)
node_list = [(CLIENT_NODE_TYPE, '127.0.0.1', self.client_port, self.getNewUUID(), DOWN_STATE),]
......@@ -457,21 +178,6 @@ class MasterVerificationTests(NeoTestBase):
loid = self.app.loid
ltid = self.app.ltid
lptid = self.app.pt.getID()
# do not answer if no uuid
conn = self.getFakeConnection(None, self.storage_address)
node_list = []
self.checkIdenficationRequired(verification.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# do not care if master node call it
master_uuid = self.identifyToMasterNode(node_type=MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.master_address)
node_list = []
self.checkUnexpectedPacketRaised(verification.handleAnswerLastIDs, conn, packet, None, None, None)
self.assertEquals(loid, self.app.loid)
self.assertEquals(ltid, self.app.ltid)
self.assertEquals(lptid, self.app.pt.getID())
# send information which are later to what PMN knows, this must raise
conn = self.getFakeConnection(uuid, self.storage_address)
node_list = []
......@@ -501,13 +207,6 @@ class MasterVerificationTests(NeoTestBase):
verification = self.verification
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ANSWER_UNFINISHED_TRANSACTIONS)
# reject when no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(verification.handleAnswerUnfinishedTransactions, conn, packet, [])
# reject master node
master_uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.master_address)
self.checkUnexpectedPacketRaised(verification.handleAnswerUnfinishedTransactions, conn, packet, [])
# do nothing
conn = self.getFakeConnection(uuid, self.storage_address)
self.assertEquals(len(self.app.asking_uuid_dict), 0)
......@@ -535,13 +234,6 @@ class MasterVerificationTests(NeoTestBase):
verification = self.verification
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ANSWER_TRANSACTION_INFORMATION)
# reject when no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(verification.handleAnswerTransactionInformation, conn, packet, None, None, None, None, None)
# reject master node
master_uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.storage_address)
self.checkUnexpectedPacketRaised(verification.handleAnswerTransactionInformation, conn, packet, None, None, None, None, None)
# do nothing, as unfinished_oid_set is None
conn = self.getFakeConnection(uuid, self.storage_address)
self.assertEquals(len(self.app.asking_uuid_dict), 0)
......@@ -593,13 +285,6 @@ class MasterVerificationTests(NeoTestBase):
verification = self.verification
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=TID_NOT_FOUND_CODE)
# reject when no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(verification.handleTidNotFound, conn, packet, [])
# reject master node
master_uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.master_address)
self.checkUnexpectedPacketRaised(verification.handleTidNotFound, conn, packet, [])
# do nothing as asking_uuid_dict is True
conn = self.getFakeConnection(uuid, self.storage_address)
self.assertEquals(len(self.app.asking_uuid_dict), 0)
......@@ -621,13 +306,6 @@ class MasterVerificationTests(NeoTestBase):
verification = self.verification
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=ANSWER_OBJECT_PRESENT)
# reject when no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(verification.handleAnswerObjectPresent, conn, packet, None, None)
# reject master node
master_uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.master_address)
self.checkUnexpectedPacketRaised(verification.handleAnswerObjectPresent, conn, packet, None, None)
# do nothing as asking_uuid_dict is True
upper, lower = unpack('!LL', self.app.ltid)
new_tid = pack('!LL', upper, lower + 10)
......@@ -650,13 +328,6 @@ class MasterVerificationTests(NeoTestBase):
verification = self.verification
uuid = self.identifyToMasterNode()
packet = Packet(msg_type=OID_NOT_FOUND_CODE)
# reject when no uuid
conn = self.getFakeConnection(None, self.storage_address)
self.checkIdenficationRequired(verification.handleOidNotFound, conn, packet, [])
# reject master node
master_uuid = self.identifyToMasterNode(MASTER_NODE_TYPE, port=self.master_port)
conn = self.getFakeConnection(master_uuid, self.master_address)
self.checkUnexpectedPacketRaised(verification.handleOidNotFound, conn, packet, [])
# do nothinf as asking_uuid_dict is True
conn = self.getFakeConnection(uuid, self.storage_address)
self.assertEquals(len(self.app.asking_uuid_dict), 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment