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

Use decorators and UnexpectedPacketError exception instead of calls

handleUnexpectedPacket() in storage handlers.


git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@505 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 863a3207
This diff is collapsed.
...@@ -18,13 +18,14 @@ ...@@ -18,13 +18,14 @@
import logging import logging
from neo.handler import EventHandler from neo.handler import EventHandler
from neo.protocol import Packet, \ from neo.protocol import Packet, UnexpectedPacketError, \
INVALID_UUID, RUNNING_STATE, BROKEN_STATE, \ INVALID_UUID, RUNNING_STATE, BROKEN_STATE, \
MASTER_NODE_TYPE, STORAGE_NODE_TYPE, CLIENT_NODE_TYPE MASTER_NODE_TYPE, STORAGE_NODE_TYPE, CLIENT_NODE_TYPE
from neo.util import dump from neo.util import dump
from neo.node import MasterNode, StorageNode, ClientNode from neo.node import MasterNode, StorageNode, ClientNode
from neo.connection import ClientConnection from neo.connection import ClientConnection
from neo.exception import PrimaryFailure from neo.exception import PrimaryFailure
from neo.handler import identification_required, restrict_node_types
class StorageEventHandler(EventHandler): class StorageEventHandler(EventHandler):
"""This class implements a generic part of the event handlers.""" """This class implements a generic part of the event handlers."""
...@@ -69,24 +70,17 @@ class StorageEventHandler(EventHandler): ...@@ -69,24 +70,17 @@ class StorageEventHandler(EventHandler):
known_master_list): known_master_list):
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
@identification_required
@restrict_node_types(MASTER_NODE_TYPE)
def handleAnnouncePrimaryMaster(self, conn, packet): def handleAnnouncePrimaryMaster(self, conn, packet):
"""Theoretically speaking, I should not get this message, """Theoretically speaking, I should not get this message,
because the primary master election must happen when I am because the primary master election must happen when I am
not connected to any master node.""" not connected to any master node."""
uuid = conn.getUUID() uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
app = self.app app = self.app
node = app.nm.getNodeByUUID(uuid) node = app.nm.getNodeByUUID(uuid)
if node is None: if node is None:
raise RuntimeError('I do not know the uuid %r' % dump(uuid)) raise RuntimeError('I do not know the uuid %r' % dump(uuid))
if node.getNodeType() != MASTER_NODE_TYPE:
self.handleUnexpectedPacket(conn, packet)
return
if app.primary_master_node is None: if app.primary_master_node is None:
# Hmm... I am somehow connected to the primary master already. # Hmm... I am somehow connected to the primary master already.
app.primary_master_node = node app.primary_master_node = node
...@@ -106,19 +100,16 @@ class StorageEventHandler(EventHandler): ...@@ -106,19 +100,16 @@ class StorageEventHandler(EventHandler):
def handleReelectPrimaryMaster(self, conn, packet): def handleReelectPrimaryMaster(self, conn, packet):
raise PrimaryFailure('re-election occurs') raise PrimaryFailure('re-election occurs')
@identification_required
@restrict_node_types(MASTER_NODE_TYPE)
def handleNotifyNodeInformation(self, conn, packet, node_list): def handleNotifyNodeInformation(self, conn, packet, node_list):
"""Store information on nodes, only if this is sent by a primary """Store information on nodes, only if this is sent by a primary
master node.""" master node."""
# XXX it might be better to implement this callback in each handler. # XXX it might be better to implement this callback in each handler.
uuid = conn.getUUID() uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
app = self.app app = self.app
node = app.nm.getNodeByUUID(uuid) node = app.nm.getNodeByUUID(uuid)
if node.getNodeType() != MASTER_NODE_TYPE \ if app.primary_master_node is None \
or app.primary_master_node is None \
or app.primary_master_node.getUUID() != uuid: or app.primary_master_node.getUUID() != uuid:
return return
...@@ -209,21 +200,21 @@ class StorageEventHandler(EventHandler): ...@@ -209,21 +200,21 @@ class StorageEventHandler(EventHandler):
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
def handleAskObject(self, conn, packet, oid, serial, tid): def handleAskObject(self, conn, packet, oid, serial, tid):
self.handleUnexpectedPacket(conn, packet) raise UnexpectedPacketError
def handleAskTIDs(self, conn, packet, first, last, partition): def handleAskTIDs(self, conn, packet, first, last, partition):
self.handleUnexpectedPacket(conn, packet) raise UnexpectedPacketError
def handleAskObjectHistory(self, conn, packet, oid, first, last): def handleAskObjectHistory(self, conn, packet, oid, first, last):
self.handleUnexpectedPacket(conn, packet) raise UnexpectedPacketError
def handleAskStoreTransaction(self, conn, packet, tid, user, desc, def handleAskStoreTransaction(self, conn, packet, tid, user, desc,
ext, oid_list): ext, oid_list):
self.handleUnexpectedPacket(conn, packet) raise UnexpectedPacketError
def handleAskStoreObject(self, conn, packet, oid, serial, def handleAskStoreObject(self, conn, packet, oid, serial,
compression, checksum, data, tid): compression, checksum, data, tid):
self.handleUnexpectedPacket(conn, packet) raise UnexpectedPacketError
def handleAbortTransaction(self, conn, packet, tid): def handleAbortTransaction(self, conn, packet, tid):
logging.info('ignoring abort transaction') logging.info('ignoring abort transaction')
......
This diff is collapsed.
...@@ -109,6 +109,14 @@ server: 127.0.0.1:10020 ...@@ -109,6 +109,14 @@ server: 127.0.0.1:10020
def getLastUUID(self): def getLastUUID(self):
return self.uuid return self.uuid
def checkUnexpectedPacketRaised(self, method, *args, **kwargs):
""" Check if the UnexpectedPacketError exception wxas raised """
self.assertRaises(UnexpectedPacketError, method, *args, **kwargs)
def checkIdenficationRequired(self, method, *args, **kwargs):
""" Check is the identification_required decorator is applied """
self.checkUnexpectedPacketRaised(method, *args, **kwargs)
# Method to test the kind of packet returned in answer # Method to test the kind of packet returned in answer
def checkCalledRequestNodeIdentification(self, conn, packet_number=0): def checkCalledRequestNodeIdentification(self, conn, packet_number=0):
""" Check Request Node Identification has been send""" """ Check Request Node Identification has been send"""
......
...@@ -50,6 +50,14 @@ class StorageOperationTests(unittest.TestCase): ...@@ -50,6 +50,14 @@ class StorageOperationTests(unittest.TestCase):
return min(ptids), max(ptids) return min(ptids), max(ptids)
ptid = min(ptids) ptid = min(ptids)
def checkUnexpectedPacketRaised(self, method, *args, **kwargs):
""" Check if the UnexpectedPacketError exception wxas raised """
self.assertRaises(UnexpectedPacketError, method, *args, **kwargs)
def checkIdenficationRequired(self, method, *args, **kwargs):
""" Check is the identification_required decorator is applied """
self.checkUnexpectedPacketRaised(method, *args, **kwargs)
def checkCalledAbort(self, conn, packet_number=0): def checkCalledAbort(self, conn, packet_number=0):
"""Check the abort method has been called and an error packet has been sent""" """Check the abort method has been called and an error packet has been sent"""
# sometimes we answer an error, sometimes we just send it # sometimes we answer an error, sometimes we just send it
...@@ -81,9 +89,7 @@ class StorageOperationTests(unittest.TestCase): ...@@ -81,9 +89,7 @@ class StorageOperationTests(unittest.TestCase):
packet = Packet(msg_type=_msg_type) packet = Packet(msg_type=_msg_type)
# hook # hook
self.operation.peerBroken = lambda c: c.peerBrokendCalled() self.operation.peerBroken = lambda c: c.peerBrokendCalled()
_call(conn=conn, packet=packet, **kwargs) self.checkUnexpectedPacketRaised(_call, conn=conn, packet=packet, **kwargs)
self.checkCalledAbort(conn)
self.assertEquals(len(conn.mockGetNamedCalls("peerBrokendCalled")), 1)
def checkNoPacketSent(self, conn): def checkNoPacketSent(self, conn):
# no packet should be sent # no packet should be sent
......
...@@ -36,7 +36,7 @@ from neo.protocol import ACCEPT_NODE_IDENTIFICATION, REQUEST_NODE_IDENTIFICATION ...@@ -36,7 +36,7 @@ from neo.protocol import ACCEPT_NODE_IDENTIFICATION, REQUEST_NODE_IDENTIFICATION
UNLOCK_INFORMATION, TID_NOT_FOUND_CODE, ASK_TRANSACTION_INFORMATION, ANSWER_TRANSACTION_INFORMATION, \ UNLOCK_INFORMATION, TID_NOT_FOUND_CODE, ASK_TRANSACTION_INFORMATION, ANSWER_TRANSACTION_INFORMATION, \
ANSWER_PARTITION_TABLE,SEND_PARTITION_TABLE, COMMIT_TRANSACTION ANSWER_PARTITION_TABLE,SEND_PARTITION_TABLE, COMMIT_TRANSACTION
from neo.protocol import ERROR, BROKEN_NODE_DISALLOWED_CODE, ASK_PRIMARY_MASTER from neo.protocol import ERROR, BROKEN_NODE_DISALLOWED_CODE, ASK_PRIMARY_MASTER
from neo.protocol import ANSWER_PRIMARY_MASTER from neo.protocol import ANSWER_PRIMARY_MASTER, UnexpectedPacketError
from neo.exception import PrimaryFailure, OperationFailure from neo.exception import PrimaryFailure, OperationFailure
from neo.storage.mysqldb import MySQLDatabaseManager, p64, u64 from neo.storage.mysqldb import MySQLDatabaseManager, p64, u64
...@@ -127,6 +127,14 @@ server: 127.0.0.1:10020 ...@@ -127,6 +127,14 @@ server: 127.0.0.1:10020
return min(ptids), max(ptids) return min(ptids), max(ptids)
ptid = min(ptids) ptid = min(ptids)
def checkUnexpectedPacketRaised(self, method, *args, **kwargs):
""" Check if the UnexpectedPacketError exception wxas raised """
self.assertRaises(UnexpectedPacketError, method, *args, **kwargs)
def checkIdenficationRequired(self, method, *args, **kwargs):
""" Check is the identification_required decorator is applied """
self.checkUnexpectedPacketRaised(method, *args, **kwargs)
def checkCalledAbort(self, conn, packet_number=0): def checkCalledAbort(self, conn, packet_number=0):
"""Check the abort method has been called and an error packet has been sent""" """Check the abort method has been called and an error packet has been sent"""
# sometimes we answer an error, sometimes we just notify it # sometimes we answer an error, sometimes we just notify it
...@@ -306,9 +314,8 @@ server: 127.0.0.1:10020 ...@@ -306,9 +314,8 @@ server: 127.0.0.1:10020
"getAddress" : ("127.0.0.1", self.client_port), "getAddress" : ("127.0.0.1", self.client_port),
"isServerConnection" : True}) "isServerConnection" : True})
p = Packet(msg_type=ACCEPT_NODE_IDENTIFICATION) p = Packet(msg_type=ACCEPT_NODE_IDENTIFICATION)
self.verification.handleAcceptNodeIdentification(conn, p, CLIENT_NODE_TYPE, self.checkUnexpectedPacketRaised(self.verification.handleAcceptNodeIdentification,
self.getNewUUID(),"127.0.0.1", self.client_port, 1009, 2, uuid) conn, p, CLIENT_NODE_TYPE, self.getNewUUID(),"127.0.0.1", self.client_port, 1009, 2, uuid)
self.checkCalledAbort(conn)
def test_07_handleAnswerPrimaryMaster(self): def test_07_handleAnswerPrimaryMaster(self):
# reject server connection # reject server connection
...@@ -317,8 +324,7 @@ server: 127.0.0.1:10020 ...@@ -317,8 +324,7 @@ server: 127.0.0.1:10020
conn = Mock({"getUUID" : uuid, conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.client_port), "getAddress" : ("127.0.0.1", self.client_port),
"isServerConnection" : True}) "isServerConnection" : True})
self.verification.handleAnswerPrimaryMaster(conn, packet,self.getNewUUID(), ()) self.checkUnexpectedPacketRaised(self.verification.handleAnswerPrimaryMaster, conn, packet,self.getNewUUID(), ())
self.checkCalledAbort(conn)
# raise id uuid is different # raise id uuid is different
conn = Mock({"getUUID" : uuid, conn = Mock({"getUUID" : uuid,
...@@ -343,8 +349,7 @@ server: 127.0.0.1:10020 ...@@ -343,8 +349,7 @@ server: 127.0.0.1:10020
conn = Mock({"getUUID" : uuid, conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.client_port), "getAddress" : ("127.0.0.1", self.client_port),
"isServerConnection" : True}) "isServerConnection" : True})
self.verification.handleAskLastIDs(conn, packet) self.checkUnexpectedPacketRaised(self.verification.handleAskLastIDs, conn, packet)
self.checkCalledAbort(conn)
# return invalid if db store nothing # return invalid if db store nothing
conn = Mock({"getUUID" : uuid, conn = Mock({"getUUID" : uuid,
...@@ -402,8 +407,7 @@ server: 127.0.0.1:10020 ...@@ -402,8 +407,7 @@ server: 127.0.0.1:10020
conn = Mock({"getUUID" : uuid, conn = Mock({"getUUID" : uuid,
"getAddress" : ("127.0.0.1", self.client_port), "getAddress" : ("127.0.0.1", self.client_port),
"isServerConnection" : True}) "isServerConnection" : True})
self.verification.handleAskPartitionTable(conn, packet, [1,]) self.checkUnexpectedPacketRaised(self.verification.handleAskPartitionTable, conn, packet, [1,])
self.checkCalledAbort(conn)
# try to get unknown offset # try to get unknown offset
self.assertEqual(len(self.app.pt.getNodeList()), 0) self.assertEqual(len(self.app.pt.getNodeList()), 0)
...@@ -449,9 +453,8 @@ server: 127.0.0.1:10020 ...@@ -449,9 +453,8 @@ server: 127.0.0.1:10020
"getAddress" : ("127.0.0.1", self.client_port), "getAddress" : ("127.0.0.1", self.client_port),
"isServerConnection" : True}) "isServerConnection" : True})
self.app.ptid = 1 self.app.ptid = 1
self.verification.handleSendPartitionTable(conn, packet, 0, ()) self.checkUnexpectedPacketRaised(self.verification.handleSendPartitionTable, conn, packet, 0, ())
self.assertEquals(self.app.ptid, 1) self.assertEquals(self.app.ptid, 1)
self.checkCalledAbort(conn)
# send a table # send a table
conn = Mock({"getUUID" : uuid, conn = Mock({"getUUID" : uuid,
...@@ -496,9 +499,8 @@ server: 127.0.0.1:10020 ...@@ -496,9 +499,8 @@ server: 127.0.0.1:10020
"getAddress" : ("127.0.0.1", self.client_port), "getAddress" : ("127.0.0.1", self.client_port),
"isServerConnection" : True}) "isServerConnection" : True})
self.app.ptid = 1 self.app.ptid = 1
self.verification.handleNotifyPartitionChanges(conn, packet, 0, ()) self.checkUnexpectedPacketRaised(self.verification.handleNotifyPartitionChanges, conn, packet, 0, ())
self.assertEquals(self.app.ptid, 1) self.assertEquals(self.app.ptid, 1)
self.checkCalledAbort(conn)
# old partition change # old partition change
conn = Mock({ conn = Mock({
...@@ -534,8 +536,7 @@ server: 127.0.0.1:10020 ...@@ -534,8 +536,7 @@ server: 127.0.0.1:10020
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': True }) 'isServerConnection': True })
packet = Packet(msg_type=STOP_OPERATION) packet = Packet(msg_type=STOP_OPERATION)
self.verification.handleStartOperation(conn, packet) self.checkUnexpectedPacketRaised(self.verification.handleStartOperation, conn, packet)
self.checkCalledAbort(conn)
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': False }) 'isServerConnection': False })
self.assertFalse(self.app.operational) self.assertFalse(self.app.operational)
...@@ -547,8 +548,7 @@ server: 127.0.0.1:10020 ...@@ -547,8 +548,7 @@ server: 127.0.0.1:10020
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': True }) 'isServerConnection': True })
packet = Packet(msg_type=STOP_OPERATION) packet = Packet(msg_type=STOP_OPERATION)
self.verification.handleStopOperation(conn, packet) self.checkUnexpectedPacketRaised(self.verification.handleStopOperation, conn, packet)
self.checkCalledAbort(conn)
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': False }) 'isServerConnection': False })
packet = Packet(msg_type=STOP_OPERATION) packet = Packet(msg_type=STOP_OPERATION)
...@@ -559,8 +559,7 @@ server: 127.0.0.1:10020 ...@@ -559,8 +559,7 @@ server: 127.0.0.1:10020
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': True }) 'isServerConnection': True })
packet = Packet(msg_type=ASK_UNFINISHED_TRANSACTIONS) packet = Packet(msg_type=ASK_UNFINISHED_TRANSACTIONS)
self.verification.handleAskUnfinishedTransactions(conn, packet) self.checkUnexpectedPacketRaised(self.verification.handleAskUnfinishedTransactions, conn, packet)
self.checkCalledAbort(conn)
# client connection with no data # client connection with no data
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': False}) 'isServerConnection': False})
...@@ -688,8 +687,7 @@ server: 127.0.0.1:10020 ...@@ -688,8 +687,7 @@ server: 127.0.0.1:10020
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': True }) 'isServerConnection': True })
packet = Packet(msg_type=ASK_OBJECT_PRESENT) packet = Packet(msg_type=ASK_OBJECT_PRESENT)
self.verification.handleAskObjectPresent(conn, packet, p64(1), p64(2)) self.checkUnexpectedPacketRaised(self.verification.handleAskObjectPresent, conn, packet, p64(1), p64(2))
self.checkCalledAbort(conn)
# client connection with no data # client connection with no data
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': False}) 'isServerConnection': False})
...@@ -724,8 +722,7 @@ server: 127.0.0.1:10020 ...@@ -724,8 +722,7 @@ server: 127.0.0.1:10020
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': True }) 'isServerConnection': True })
packet = Packet(msg_type=ASK_OBJECT_PRESENT) packet = Packet(msg_type=ASK_OBJECT_PRESENT)
self.verification.handleDeleteTransaction(conn, packet, p64(1)) self.checkUnexpectedPacketRaised(self.verification.handleDeleteTransaction, conn, packet, p64(1))
self.checkCalledAbort(conn)
# client connection with no data # client connection with no data
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
'isServerConnection': False}) 'isServerConnection': False})
...@@ -747,8 +744,7 @@ server: 127.0.0.1:10020 ...@@ -747,8 +744,7 @@ server: 127.0.0.1:10020
dm = Mock() dm = Mock()
self.app.dm = dm self.app.dm = dm
packet = Packet(msg_type=COMMIT_TRANSACTION) packet = Packet(msg_type=COMMIT_TRANSACTION)
self.verification.handleCommitTransaction(conn, packet, p64(1)) self.checkUnexpectedPacketRaised(self.verification.handleCommitTransaction, conn, packet, p64(1))
self.checkCalledAbort(conn)
self.assertEqual(len(dm.mockGetNamedCalls("finishTransaction")), 0) self.assertEqual(len(dm.mockGetNamedCalls("finishTransaction")), 0)
# commit a transaction # commit a transaction
conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port), conn = Mock({ "getAddress" : ("127.0.0.1", self.master_port),
......
This diff is collapsed.
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