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