Commit 13c848f9 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Remove decorators used in shutdown handler, the handler implied those tests.

Decorators defined in decorators.py are no more used in NEO, all extracted
patterns are now implied by the handlers.


git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@1142 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 55ca6714
#
# 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.
from neo import protocol
# Some decorators useful to avoid duplication of patterns in handlers
def identification_required(handler):
""" Raise UnexpectedPacketError if the identification has not succeed """
def wrapper(self, conn, packet, *args, **kwargs):
# check if node identification succeed
if conn.getUUID() is None:
raise protocol.UnexpectedPacketError
# identified, call the handler
handler(self, conn, packet, *args, **kwargs)
return wrapper
def restrict_node_types(*node_types):
""" Raise UnexpectedPacketError if the node type is node in the supplied
list, if the uuid is None or if the node is not known. This decorator
should be applied after identification_required """
def inner(handler):
def wrapper(self, conn, packet, *args, **kwargs):
# check if node type is allowed
uuid = conn.getUUID()
if uuid is None:
raise protocol.UnexpectedPacketError
node = self.app.nm.getNodeByUUID(uuid)
if node is None:
raise protocol.UnexpectedPacketError
if node.getType() not in node_types:
raise protocol.UnexpectedPacketError
# all is ok, call the handler
handler(self, conn, packet, *args, **kwargs)
return wrapper
return inner
def client_connection_required(handler):
""" Raise UnexpectedPacketError if the packet comes from a client connection """
def wrapper(self, conn, packet, *args, **kwargs):
if conn.isServer():
raise protocol.UnexpectedPacketError
# it's a client connection, call the handler
handler(self, conn, packet, *args, **kwargs)
return wrapper
def server_connection_required(handler):
""" Raise UnexpectedPacketError if the packet comes from a server connection """
def wrapper(self, conn, packet, *args, **kwargs):
if not conn.isServer():
raise protocol.UnexpectedPacketError
# it's a server connection, call the handler
handler(self, conn, packet, *args, **kwargs)
return wrapper
...@@ -19,7 +19,6 @@ from neo import logging ...@@ -19,7 +19,6 @@ from neo import logging
from neo import protocol from neo import protocol
from neo.protocol import CLIENT_NODE_TYPE from neo.protocol import CLIENT_NODE_TYPE
from neo.master.handlers import BaseServiceHandler from neo.master.handlers import BaseServiceHandler
from neo import decorators
class ShutdownHandler(BaseServiceHandler): class ShutdownHandler(BaseServiceHandler):
"""This class deals with events for a shutting down phase.""" """This class deals with events for a shutting down phase."""
...@@ -34,13 +33,10 @@ class ShutdownHandler(BaseServiceHandler): ...@@ -34,13 +33,10 @@ class ShutdownHandler(BaseServiceHandler):
logging.error('reject any new demand for primary master') logging.error('reject any new demand for primary master')
raise protocol.ProtocolError('cluster is shutting down') raise protocol.ProtocolError('cluster is shutting down')
@decorators.identification_required
@decorators.restrict_node_types(CLIENT_NODE_TYPE)
def handleAskBeginTransaction(self, conn, packet, tid): def handleAskBeginTransaction(self, conn, packet, tid):
logging.error('reject any new demand for new tid') logging.error('reject any new demand for new tid')
raise protocol.ProtocolError('cluster is shutting down') raise protocol.ProtocolError('cluster is shutting down')
@decorators.identification_required
def handleNotifyNodeInformation(self, conn, packet, node_list): def handleNotifyNodeInformation(self, conn, packet, node_list):
# don't care about notifications since we are shutdowning # don't care about notifications since we are shutdowning
pass pass
...@@ -23,122 +23,6 @@ from neo.protocol import UnexpectedPacketError, MASTER_NODE_TYPE, \ ...@@ -23,122 +23,6 @@ from neo.protocol import UnexpectedPacketError, MASTER_NODE_TYPE, \
CLIENT_NODE_TYPE, STORAGE_NODE_TYPE, ADMIN_NODE_TYPE CLIENT_NODE_TYPE, STORAGE_NODE_TYPE, ADMIN_NODE_TYPE
from neo.protocol import PacketMalformedError, UnexpectedPacketError, \ from neo.protocol import PacketMalformedError, UnexpectedPacketError, \
BrokenNodeDisallowedError, NotReadyError, ProtocolError BrokenNodeDisallowedError, NotReadyError, ProtocolError
from neo import decorators
class HandlerDecoratorsTests(NeoTestBase):
class FakeApp(object):
nm = None
def setUp(self):
self.handler_called = False
self.app = HandlerDecoratorsTests.FakeApp()
def fakeHandler(self, conn, packet):
self.handler_called = True
def checkHandlerCalled(self, handler):
calls = handler.mockGetNamedCalls('__call__')
self.assertEquals(len(calls), 1)
def checkHandlerNotCalled(self, handler):
calls = handler.mockGetNamedCalls('__call__')
self.assertEquals(len(calls), 0)
def test_identification_required(self):
packet = Mock({})
handler = Mock({})
wrapped = decorators.identification_required(handler)
# no UUID -> fail
conn = Mock({ 'getUUID': None, })
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
# UUID set -> ok
conn = Mock({ 'getUUID': '\x01' * 8, })
wrapped(self, conn, packet)
self.checkHandlerCalled(handler)
def test_restrict_node_types(self):
uuid = self.getNewUUID()
packet = Mock({})
handler = Mock({})
storage = Mock({'getType': STORAGE_NODE_TYPE})
master = Mock({'getType': MASTER_NODE_TYPE})
client = Mock({'getType': CLIENT_NODE_TYPE})
admin = Mock({'getType': ADMIN_NODE_TYPE})
nodes = (storage, master, client, admin)
# no uuid -> fail
wrapped = decorators.restrict_node_types()(handler)
conn = Mock({ 'getUUID': None, })
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
# unknown node -> fail
wrapped = decorators.restrict_node_types()(handler)
self.app.nm = Mock({'getNodeByUUID': uuid, })
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
# no node allowed at all -> all fail
wrapped = decorators.restrict_node_types()(handler)
conn = Mock({ 'getUUID': uuid, })
self.app.nm = Mock({'getNodeByUUID': ReturnValues(*nodes)})
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
# Only master nodes allowed
handler = Mock()
wrapped = decorators.restrict_node_types(MASTER_NODE_TYPE)(handler)
conn = Mock({ 'getUUID': uuid, })
self.app.nm = Mock({'getNodeByUUID': ReturnValues(*nodes)})
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
wrapped(self, conn, packet) # admin
self.checkHandlerCalled(handler)
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerCalled(handler) # fail if re-called
# storage or client nodes
handler = Mock()
wrapped = decorators.restrict_node_types(STORAGE_NODE_TYPE, CLIENT_NODE_TYPE)(handler)
conn = Mock({ 'getUUID': uuid, })
self.app.nm = Mock({'getNodeByUUID': ReturnValues(*nodes)})
wrapped(self, conn, packet) # storage
self.checkHandlerCalled(handler)
handler.mockCalledMethods = {} # reset mock object
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
wrapped(self, conn, packet) # client
self.checkHandlerCalled(handler)
handler.mockCalledMethods = {} # reset mock object
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
def test_client_connection_required(self):
packet = Mock({})
handler = Mock({})
wrapped = decorators.client_connection_required(handler)
# server connection -> fail
conn = Mock({ 'isServer': True, })
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
# client connection -> ok
conn = Mock({ 'isServer': False, })
wrapped(self, conn, packet)
self.checkHandlerCalled(handler)
def test_server_connection_required(self):
packet = Mock({})
handler = Mock({})
wrapped = decorators.server_connection_required(handler)
# client connection -> fail
conn = Mock({ 'isServer': False, })
self.assertRaises(UnexpectedPacketError, wrapped, self, conn, packet)
self.checkHandlerNotCalled(handler)
# server connection -> ok
conn = Mock({ 'isServer': True, })
wrapped(self, conn, packet)
self.checkHandlerCalled(handler)
class HandlerTests(NeoTestBase): class HandlerTests(NeoTestBase):
......
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