Commit 7b86a853 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Rewrite of client's master handler tests.

git-svn-id: https://svn.erp5.org/repos/neo/trunk@1626 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 57f41fbd
...@@ -16,16 +16,13 @@ ...@@ -16,16 +16,13 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import unittest import unittest
import threading
from mock import Mock, ReturnValues from mock import Mock, ReturnValues
from neo.tests import NeoTestBase from neo.tests import NeoTestBase
from neo import protocol
from neo.pt import PartitionTable from neo.pt import PartitionTable
from neo.protocol import UnexpectedPacketError, INVALID_UUID, INVALID_PTID from neo.protocol import NodeTypes, NodeStates
from neo.protocol import NodeTypes, NodeStates, CellStates, Packets
from neo.client.handlers import BaseHandler
from neo.client.handlers.master import PrimaryBootstrapHandler from neo.client.handlers.master import PrimaryBootstrapHandler
from neo.client.handlers.master import PrimaryNotificationsHandler, PrimaryAnswersHandler from neo.client.handlers.master import PrimaryNotificationsHandler, \
PrimaryAnswersHandler
MARKER = [] MARKER = []
...@@ -35,640 +32,218 @@ class MasterHandlerTests(NeoTestBase): ...@@ -35,640 +32,218 @@ class MasterHandlerTests(NeoTestBase):
def setUp(self): def setUp(self):
pass pass
def getConnection(self):
return Mock({'getAddress': ('fake-conn', 0)})
class MasterBootstrapHandlerTests(NeoTestBase):
class MasterBootstrapHandlerTests(MasterHandlerTests):
def setUp(self): def setUp(self):
self.app = Mock() self.app = Mock()
self.handler = PrimaryBootstrapHandler(self.app) self.handler = PrimaryBootstrapHandler(self.app)
def checkCalledOnApp(self, method, index=0):
calls = self.app.mockGetNamedCalls(method)
self.assertTrue(len(calls) > index)
return calls[index].params
def test_notReady(self): def test_notReady(self):
app = Mock({'setNodeNotReady': None})
dispatcher = self.getDispatcher()
conn = self.getConnection() conn = self.getConnection()
client_handler = StorageBootstrapHandler(app) self.handler.notReady(conn, 'message')
client_handler.notReady(conn, None) self.assertEqual(self.app.trying_master_node, None)
self.assertEquals(len(app.mockGetNamedCalls('setNodeNotReady')), 1) self.checkCalledOnApp('setNodeNotReady')
def test_clientAcceptIdentification(self): def test_acceptIdentification1(self):
class App: """ Non-master node """
nm = Mock({'getByAddress': None})
storage_node = None
pt = None
app = App()
dispatcher = self.getDispatcher()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection() conn = self.getConnection()
uuid = self.getNewUUID() uuid = self.getNewUUID()
app.uuid = 'C' * 16 self.handler.acceptIdentification(conn, NodeTypes.CLIENT,
client_handler.acceptIdentification(conn, NodeTypes.CLIENT, uuid, 100, 0, None)
uuid, 0, 0, INVALID_UUID)
self.checkClosed(conn) self.checkClosed(conn)
self.assertEquals(app.storage_node, None)
self.assertEquals(app.pt, None) def test_acceptIdentification2(self):
self.assertEquals(app.uuid, 'C' * 16) """ No UUID supplied """
def test_masterAcceptIdentification(self):
node = Mock({'setUUID': None})
class FakeLocal:
from Queue import Queue
queue = Queue()
class App:
nm = Mock({'getByAddress': node})
storage_node = None
pt = None
local_var = FakeLocal()
app = App()
dispatcher = self.getDispatcher()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection() conn = self.getConnection()
uuid = self.getNewUUID() uuid = self.getNewUUID()
your_uuid = 'C' * 16 self.checkProtocolErrorRaised(self.handler.acceptIdentification,
app.uuid = INVALID_UUID conn, NodeTypes.MASTER, uuid, 100, 0, None)
client_handler.acceptIdentification(conn, NodeTypes.MASTER,
uuid, 10, 2, your_uuid) def test_acceptIdentification3(self):
self.checkNotClosed(conn) """ identification accepted """
self.checkUUIDSet(conn, uuid) node = Mock()
self.assertEquals(app.storage_node, None)
self.assertTrue(app.pt is not None)
self.assertEquals(app.uuid, your_uuid)
def test_storageAcceptIdentification(self):
node = Mock({'setUUID': None})
class App:
nm = Mock({'getByAddress': node})
storage_node = None
pt = None
app = App()
dispatcher = self.getDispatcher()
client_handler = StorageBootstrapHandler(app)
conn = self.getConnection() conn = self.getConnection()
uuid = self.getNewUUID() uuid = self.getNewUUID()
app.uuid = 'C' * 16 your_uuid = self.getNewUUID()
client_handler.acceptIdentification(conn, NodeTypes.STORAGE, partitions = 100
uuid, 0, 0, INVALID_UUID) replicas = 2
self.checkNotClosed(conn) self.app.nm = Mock({'getByAddress': node})
self.handler.acceptIdentification(conn, NodeTypes.MASTER, uuid,
partitions, replicas, your_uuid)
self.assertEqual(self.app.uuid, your_uuid)
self.checkUUIDSet(conn, uuid) self.checkUUIDSet(conn, uuid)
self.assertEquals(app.pt, None) self.checkUUIDSet(node, uuid)
self.assertEquals(app.uuid, 'C' * 16) self.assertTrue(isinstance(self.app.pt, PartitionTable))
def test_nonMasterAnswerPrimary(self): def _getMasterList(self, uuid_list):
for node_type in (NodeTypes.CLIENT, NodeTypes.STORAGE): port = 1000
node = Mock({'getType': node_type}) master_list = []
class App: for uuid in uuid_list:
nm = Mock({'getByUUID': node, 'getByAddress': None, 'add': None}) master_list.append((('127.0.0.1', port), uuid))
trying_master_node = None port += 1
app = App() return master_list
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection() def test_answerPrimary1(self):
client_handler.answerPrimary(conn, 0, []) """ Primary not known, master udpated """
# Check that nothing happened node, uuid = Mock(), self.getNewUUID()
self.assertEqual(len(app.nm.mockGetNamedCalls('getByAddress')), 0) conn = self.getConnection()
self.assertEqual(len(app.nm.mockGetNamedCalls('add')), 0) master_list = [(('127.0.0.1', 1000), uuid)]
self.app.primary_master_node = Mock()
def test_unknownNodeAnswerPrimary(self): self.app.trying_master_node = Mock()
node = Mock({'getType': NodeTypes.MASTER}) self.app.nm = Mock({'getByAddress': node})
class App: self.handler.answerPrimary(conn, None, master_list)
nm = Mock({'getByAddress': None, 'add': None}) self.checkUUIDSet(node, uuid)
primary_master_node = None # previously known primary master forgoten
app = App() self.assertEqual(self.app.primary_master_node, None)
client_handler = PrimaryBootstrapHandler(app) self.assertEqual(self.app.trying_master_node, None)
conn = self.getConnection() self.checkClosed(conn)
test_master_list = [(('127.0.0.1', 10010), self.getNewUUID())]
client_handler.answerPrimary(conn, INVALID_UUID, test_master_list)
# Check that yet-unknown master node got added
getByAddress_call_list = app.nm.mockGetNamedCalls('getByAddress')
add_call_list = app.nm.mockGetNamedCalls('add')
self.assertEqual(len(getByAddress_call_list), 1)
self.assertEqual(len(add_call_list), 1)
(address, port), test_uuid = test_master_list[0]
getByAddress_call = getByAddress_call_list[0]
add_call = add_call_list[0]
self.assertEquals((address, port), getByAddress_call.getParam(0))
node_instance = add_call.getParam(0)
self.assertEquals(test_uuid, node_instance.getUUID())
# Check that primary master was not updated (it is not known yet,
# hence INVALID_UUID in call).
self.assertEquals(app.primary_master_node, None)
def test_knownNodeUnknownUUIDNodeAnswerPrimary(self):
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': None, 'setUUID': None})
class App:
nm = Mock({'getByAddress': node, 'add': None})
primary_master_node = None
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection()
test_node_uuid = self.getNewUUID()
test_master_list = [(('127.0.0.1', 10010), test_node_uuid)]
client_handler.answerPrimary(conn, INVALID_UUID, test_master_list)
# Test sanity checks
getByAddress_call_list = app.nm.mockGetNamedCalls('getByAddress')
self.assertEqual(len(getByAddress_call_list), 1)
self.assertEqual(getByAddress_call_list[0].getParam(0), test_master_list[0][0])
# Check that known master node did not get added
getByAddress_call_list = app.nm.mockGetNamedCalls('getByAddress')
add_call_list = app.nm.mockGetNamedCalls('add')
self.assertEqual(len(getByAddress_call_list), 1)
self.assertEqual(len(add_call_list), 0)
# Check that node UUID got updated
self.checkUUIDSet(node, test_node_uuid)
# Check that primary master was not updated (it is not known yet,
# hence INVALID_UUID in call).
self.assertEquals(app.primary_master_node, None)
def test_knownNodeKnownUUIDNodeAnswerPrimary(self):
test_node_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': test_node_uuid, 'setUUID': None})
class App:
nm = Mock({'getByAddress': node, 'add': None})
primary_master_node = None
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection()
test_master_list = [(('127.0.0.1', 10010), test_node_uuid)]
client_handler.answerPrimary(conn, INVALID_UUID, test_master_list)
# Test sanity checks
getByAddress_call_list = app.nm.mockGetNamedCalls('getByAddress')
self.assertEqual(len(getByAddress_call_list), 1)
self.assertEqual(getByAddress_call_list[0].getParam(0), test_master_list[0][0])
# Check that known master node did not get added
add_call_list = app.nm.mockGetNamedCalls('add')
self.assertEqual(len(add_call_list), 0)
# Check that node UUID was untouched
setUUIDCalls = node.mockGetNamedCalls('setUUID')
if len(setUUIDCalls) == 1:
self.assertEquals(setUUIDCalls[0].getParam(0), test_node_uuid)
# Check that primary master was not updated (it is not known yet,
# hence INVALID_UUID in call).
self.assertEquals(app.primary_master_node, None)
# TODO: test known node, known but different uuid (not detected in code,
# desired behaviour unknown)
def test_alreadyDifferentPrimaryAnswerPrimary(self):
test_node_uuid = self.getNewUUID()
test_primary_node_uuid = test_node_uuid
while test_primary_node_uuid == test_node_uuid:
test_primary_node_uuid = self.getNewUUID()
test_primary_master_node = Mock({'getUUID': test_primary_node_uuid})
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': test_node_uuid, 'setUUID': None})
class App:
nm = Mock({'getByUUID': node, 'getByAddress': node, 'add': None})
primary_master_node = test_primary_master_node
trying_master_node = None
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection()
# If primary master is already set *and* is not given primary master
# handle call raises.
# Check that the call doesn't raise
client_handler.answerPrimary(conn, test_node_uuid, [])
# Check that the primary master changed
self.assertTrue(app.primary_master_node is node)
# Test sanity checks
getByUUID_call_list = app.nm.mockGetNamedCalls('getByUUID')
self.assertEqual(len(getByUUID_call_list), 1)
self.assertEqual(getByUUID_call_list[0].getParam(0), test_node_uuid)
getByAddress_call_list = app.nm.mockGetNamedCalls('getByAddress')
self.assertEqual(len(getByAddress_call_list), 0)
def test_alreadySamePrimaryAnswerPrimary(self):
test_node_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': test_node_uuid, 'setUUID': None})
class App:
nm = Mock({'getByUUID': node, 'getByAddress': node, 'add': None})
primary_master_node = node
trying_master_node = node
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection()
client_handler.answerPrimary(conn, test_node_uuid, [])
# Check that primary node is (still) node.
self.assertTrue(app.primary_master_node is node)
def test_unknownNewPrimaryAnswerPrimary(self):
test_node_uuid = self.getNewUUID()
test_primary_node_uuid = test_node_uuid
while test_primary_node_uuid == test_node_uuid:
test_primary_node_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': test_node_uuid, 'setUUID': None})
class App:
nm = Mock({'getByUUID': None, 'getByAddress': node, 'add': None})
primary_master_node = None
trying_master_node = None
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection()
client_handler.answerPrimary(conn, test_primary_node_uuid, [])
# Test sanity checks
getByUUID_call_list = app.nm.mockGetNamedCalls('getByUUID')
self.assertEqual(len(getByUUID_call_list), 1)
self.assertEqual(getByUUID_call_list[0].getParam(0), test_primary_node_uuid)
# Check that primary node was not updated.
self.assertTrue(app.primary_master_node is None)
def test_AnswerPrimary(self):
test_node_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': test_node_uuid, 'setUUID': None})
class App:
nm = Mock({'getByUUID': node, 'getByAddress': node, 'add': None})
primary_master_node = None
trying_master_node = None
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = self.getConnection()
test_master_list = [(('127.0.0.1', 10010), test_node_uuid)]
client_handler.answerPrimary(conn, test_node_uuid, test_master_list)
# Test sanity checks
getByUUID_call_list = app.nm.mockGetNamedCalls('getByUUID')
self.assertEqual(len(getByUUID_call_list), 1)
self.assertEqual(getByUUID_call_list[0].getParam(0), test_node_uuid)
getByAddress_call_list = app.nm.mockGetNamedCalls('getByAddress')
self.assertEqual(len(getByAddress_call_list), 1)
self.assertEqual(getByAddress_call_list[0].getParam(0), test_master_list[0][0])
# Check that primary master was updated to known node
self.assertTrue(app.primary_master_node is node)
def test_answerPrimary2(self):
""" Primary known """
current_node = Mock({'__repr__': '1'})
node, uuid = Mock({'__repr__': '2'}), self.getNewUUID()
conn = self.getConnection()
master_list = [(('127.0.0.1', 1000), uuid)]
self.app.primary_master_node = None
self.app.trying_master_node = current_node
self.app.nm = Mock({
'getByAddress': node,
'getByUUID': node,
})
self.handler.answerPrimary(conn, uuid, [])
self.assertEqual(self.app.trying_master_node, None)
self.assertTrue(self.app.primary_master_node is node)
self.checkClosed(conn)
class MasterNotificationsHandlerTests(NeoTestBase): class MasterNotificationsHandlerTests(MasterHandlerTests):
def setUp(self): def setUp(self):
self.app = Mock() self.db = Mock()
self.dispatcher = Mock() self.app = Mock({'getDB': self.db})
self.handler = PrimaryNotificationsHandler(self.app, self.dispatcher) self.app.nm = Mock()
self.app.dispatcher = Mock()
def test_StopOperation(self): self.handler = PrimaryNotificationsHandler(self.app)
def test_connectionClosed(self):
conn = self.getConnection()
node = Mock()
self.app.master_conn = conn
self.app.primary_master_node = node
self.handler.connectionClosed(conn)
self.assertEqual(self.app.master_conn, None)
self.assertEqual(self.app.primary_master_node, None)
def test_stopOperation(self):
raise NotImplementedError raise NotImplementedError
def test_InvalidateObjects(self): def test_invalidateObjects(self):
class App: conn = self.getConnection()
def _cache_lock_acquire(self): tid = self.getNextTID()
pass oid1, oid2 = self.getOID(1), self.getOID(2)
self.app.mq_cache = {
def _cache_lock_release(self): oid1: tid,
pass oid2: tid,
}
def registerDB(self, db, limit): self.handler.invalidateObjects(conn, [oid1], tid)
self.db = db self.assertFalse(oid1 in self.app.mq_cache)
self.assertTrue(oid2 in self.app.mq_cache)
def getDB(self): invalidation_calls = self.db.mockGetNamedCalls('invalidate')
return self.db self.assertEqual(len(invalidation_calls), 1)
invalidation_calls[0].checkArgs(tid, {oid1:tid})
mq_cache = Mock({'__delitem__': None})
app = App() def test_notifyPartitionChanges(self):
dispatcher = self.getDispatcher() conn = self.getConnection()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher()) self.app.pt = Mock({'filled': True})
conn = self.getConnection() ptid = 0
test_tid = 1 cell_list = (Mock(), Mock())
test_oid_list = ['\x00\x00\x00\x00\x00\x00\x00\x01', '\x00\x00\x00\x00\x00\x00\x00\x02'] self.handler.notifyPartitionChanges(conn, ptid, cell_list)
test_db = Mock({'invalidate': None}) update_calls = self.app.pt.mockGetNamedCalls('update')
app.registerDB(test_db, None) self.assertEqual(len(update_calls), 1)
client_handler.invalidateObjects(conn, test_oid_list[:], test_tid) update_calls[0].checkArgs(ptid, cell_list, self.app.nm)
# 'invalidate' is called just once
db = app.getDB() def test_sendPartitionTable(self):
self.assertTrue(db is test_db) conn = self.getConnection()
invalidate_call_list = db.mockGetNamedCalls('invalidate') self.app.pt = Mock()
self.assertEquals(len(invalidate_call_list), 1) ptid = 0
invalidate_call = invalidate_call_list[0] row_list = (Mock(), Mock())
invalidate_tid = invalidate_call.getParam(0) self.handler.sendPartitionTable(conn, ptid, row_list)
self.assertEquals(invalidate_tid, test_tid) load_calls = self.app.pt.mockGetNamedCalls('load')
invalidate_oid_dict = invalidate_call.getParam(1) self.assertEqual(len(load_calls), 1)
self.assertEquals(len(invalidate_oid_dict), len(test_oid_list)) load_calls[0].checkArgs(ptid, row_list, self.app.nm)
self.assertEquals(set(invalidate_oid_dict), set(test_oid_list))
self.assertEquals(set(invalidate_oid_dict.itervalues()), set([test_tid])) def test_notifyNodeInformation(self):
# '__delitem__' is called once per invalidated object conn = self.getConnection()
delitem_call_list = app.mq_cache.mockGetNamedCalls('__delitem__') addr = ('127.0.0.1', 1000)
self.assertEquals(len(delitem_call_list), len(test_oid_list)) node_list = [
oid_list = [x.getParam(0) for x in delitem_call_list] (NodeTypes.CLIENT, addr, self.getNewUUID(), NodeStates.UNKNOWN),
self.assertEquals(set(oid_list), set(test_oid_list)) (NodeTypes.STORAGE, addr, self.getNewUUID(), NodeStates.DOWN),
def test_newSendPartitionTable(self):
node = Mock({'getType': NodeTypes.MASTER})
test_ptid = 0
class App:
nm = Mock({'getByUUID': node})
pt = PartitionTable(1, 1)
app = App()
client_handler = PrimaryNotificationsHandler(app, Mock())
conn = self.getConnection()
client_handler.sendPartitionTable(conn, test_ptid + 1, [])
# Check that partition table got cleared and ptid got updated
self.assertEquals(app.pt.getID(), 1)
def test_nonMasterNotifyNodeInformation(self):
for node_type in (NodeTypes.CLIENT, NodeTypes.STORAGE):
test_master_uuid = self.getNewUUID()
node = Mock({'getType': node_type})
class App:
nm = Mock({'getByUUID': node})
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection(uuid=test_master_uuid)
client_handler.notifyNodeInformation(conn, ())
def test_nonIterableParameterRaisesNotifyNodeInformation(self):
# XXX: this test is here for sanity self-check: it verifies the
# assumption described in test_nonMasterNotifyNodeInformation
# by making a valid call with a non-iterable parameter given as
# node_list value.
test_master_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER})
class App:
nm = Mock({'getByUUID': node})
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection(uuid=test_master_uuid)
self.assertRaises(TypeError, client_handler.notifyNodeInformation,
conn, None)
def _testNotifyNodeInformation(self, test_node, getByAddress=None, getByUUID=MARKER):
invalid_uid_test_node = (test_node[0], (test_node[1][0],
test_node[1][1] + 1), INVALID_UUID, test_node[3])
test_node_list = [test_node, invalid_uid_test_node]
test_master_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER})
if getByUUID is not MARKER:
getByUUID = ReturnValues(node, getByUUID)
class App:
nm = Mock({'getByUUID': getByUUID,
'getByAddress': getByAddress,
'add': None,
'remove': None})
app = App()
dispatcher = self.getDispatcher()
client_handler = PrimaryNotificationsHandler(app, dispatcher)
conn = self.getConnection(uuid=test_master_uuid)
client_handler.notifyNodeInformation(conn, test_node_list)
# Return nm so caller can check handler actions.
return app.nm
def test_unknownMasterNotifyNodeInformation(self):
# first notify unknown master nodes
uuid = self.getNewUUID()
test_node = (NodeTypes.MASTER, ('127.0.0.1', 10010), uuid,
NodeStates.RUNNING)
nm = self._testNotifyNodeInformation(test_node, getByUUID=None)
# Check that two nodes got added (second is with INVALID_UUID)
update_call_list = nm.mockGetNamedCalls('update')
self.assertEqual(len(update_call_list), 1)
updated_node_list = update_call_list[0].getParam(0)
self.assertEquals(len(updated_node_list), 2)
def test_knownMasterNotifyNodeInformation(self):
node = Mock({})
uuid = self.getNewUUID()
test_node = (NodeTypes.MASTER, ('127.0.0.1', 10010), uuid,
NodeStates.RUNNING)
nm = self._testNotifyNodeInformation(test_node, getByAddress=node,
getByUUID=node)
# Check that node got replaced
update_call_list = nm.mockGetNamedCalls('update')
self.assertEquals(len(update_call_list), 1)
def test_unknownStorageNotifyNodeInformation(self):
test_node = (NodeTypes.STORAGE, ('127.0.0.1', 10010), self.getNewUUID(),
NodeStates.RUNNING)
nm = self._testNotifyNodeInformation(test_node, getByUUID=None)
# Check that node got added
update_call_list = nm.mockGetNamedCalls('update')
self.assertEqual(len(update_call_list), 1)
updateed_node = update_call_list[0].getParam(0)
# XXX: this test does not check that node state got updated.
# This is because there would be no way to tell the difference between
# an updated state and default state if they are the same value (we
# don't control node class/instance here)
# Likewise for server address and node uuid.
def test_knownStorageNotifyNodeInformation(self):
node = Mock({'setState': None, 'setAddress': None})
test_node = (NodeTypes.STORAGE, ('127.0.0.1', 10010), self.getNewUUID(),
NodeStates.RUNNING)
nm = self._testNotifyNodeInformation(test_node, getByUUID=node)
# Check that node got replaced
update_call_list = nm.mockGetNamedCalls('update')
self.assertEquals(len(update_call_list), 1)
def test_initialNotifyPartitionChanges(self):
class App:
nm = None
pt = None
ptid = INVALID_PTID
app = App()
client_handler = PrimaryBootstrapHandler(app)
conn = Mock({'getUUID': None})
self._testHandleUnexpectedPacketCalledWithMedhod(
client_handler.notifyPartitionChanges,
args=(conn, None, None, None))
def test_nonMasterNotifyPartitionChanges(self):
for node_type in (NodeTypes.CLIENT, NodeTypes.STORAGE):
test_master_uuid = self.getNewUUID()
node = Mock({'getType': node_type, 'getUUID': test_master_uuid})
class App:
nm = Mock({'getByUUID': node})
pt = Mock()
ptid = INVALID_PTID
primary_master_node = node
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection(uuid=test_master_uuid)
client_handler.notifyPartitionChanges(conn, 0, [])
# Check that nothing happened
self.assertEquals(len(app.pt.mockGetNamedCalls('setCell')), 0)
self.assertEquals(len(app.pt.mockGetNamedCalls('removeCell')), 0)
def test_noPrimaryNotifyPartitionChanges(self):
node = Mock({'getType': NodeTypes.MASTER})
class App:
nm = Mock({'getByUUID': node})
pt = Mock()
ptid = INVALID_PTID
primary_master_node = None
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection()
client_handler.notifyPartitionChanges(conn, 0, [])
# Check that nothing happened
self.assertEquals(len(app.pt.mockGetNamedCalls('setCell')), 0)
self.assertEquals(len(app.pt.mockGetNamedCalls('removeCell')), 0)
def test_nonPrimaryNotifyPartitionChanges(self):
test_master_uuid = self.getNewUUID()
test_sender_uuid = test_master_uuid
while test_sender_uuid == test_master_uuid:
test_sender_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER})
test_master_node = Mock({'getUUID': test_master_uuid})
class App:
nm = Mock({'getByUUID': node})
pt = Mock()
ptid = INVALID_PTID
primary_master_node = test_master_node
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection(uuid=test_sender_uuid)
client_handler.notifyPartitionChanges(conn, 0, [])
# Check that nothing happened
self.assertEquals(len(app.pt.mockGetNamedCalls('setCell')), 0)
self.assertEquals(len(app.pt.mockGetNamedCalls('removeCell')), 0)
def test_ignoreOutdatedPTIDNotifyPartitionChanges(self):
test_master_uuid = self.getNewUUID()
node = Mock({'getType': NodeTypes.MASTER, 'getUUID': test_master_uuid})
test_ptid = 1
class App:
nm = Mock({'getByUUID': node})
pt = Mock()
primary_master_node = node
ptid = test_ptid
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection(uuid=test_master_uuid)
client_handler.notifyPartitionChanges(conn, test_ptid, [])
# Check that nothing happened
self.assertEquals(len(app.pt.mockGetNamedCalls('setCell')), 0)
self.assertEquals(len(app.pt.mockGetNamedCalls('removeCell')), 0)
self.assertEquals(app.ptid, test_ptid)
# TODO: confirm condition under which an unknown node should be added with a TEMPORARILY_DOWN (implementation is unclear)
def test_knownNodeNotifyPartitionChanges(self):
test_ptid = 1
uuid1, uuid2 = self.getNewUUID(), self.getNewUUID()
uuid3, uuid4 = self.getNewUUID(), self.getNewUUID()
test_node = Mock({'getType': NodeTypes.MASTER, 'getUUID': uuid1})
class App:
nm = Mock({'getByUUID': ReturnValues(test_node, None, None, None), 'add': None})
pt = Mock({'setCell': None})
primary_master_node = test_node
ptid = test_ptid
uuid = uuid4
app = App()
client_handler = PrimaryNotificationsHandler(app, self.getDispatcher())
conn = self.getConnection(uuid=uuid1)
test_cell_list = [
(0, uuid1, CellStates.UP_TO_DATE),
(0, uuid2, CellStates.DISCARDED),
(0, uuid3, CellStates.FEEDING),
(0, uuid4, CellStates.UP_TO_DATE),
] ]
client_handler.notifyPartitionChanges(conn, None, test_ptid + 1, test_cell_list) conn1, conn2 = Mock({'__repr__': 'conn1'}), Mock({'__repr__': 'conn2'})
# Check that the three last node got added self.app.em = Mock({'getConnectionByUUID': ReturnValues(conn1, conn2)})
calls = app.nm.mockGetNamedCalls('add') self.app.cp = Mock()
self.assertEquals(len(calls), 3) self.handler.notifyNodeInformation(conn, node_list)
self.assertEquals(calls[0].getParam(0).getUUID(), uuid2) # node manager updated
self.assertEquals(calls[1].getParam(0).getUUID(), uuid3) update_calls = self.app.nm.mockGetNamedCalls('update')
self.assertEquals(calls[2].getParam(0).getUUID(), uuid4) self.assertEqual(len(update_calls), 1)
self.assertEquals(calls[0].getParam(0).getState(), NodeStates.TEMPORARILY_DOWN) update_calls[0].checkArgs(node_list)
self.assertEquals(calls[1].getParam(0).getState(), NodeStates.TEMPORARILY_DOWN) # connections closed
# and the others are updated self.checkClosed(conn1)
self.assertEqual(app.ptid, test_ptid + 1) self.checkClosed(conn2)
calls = app.pt.mockGetNamedCalls('setCell') # storage removed from connection pool
self.assertEqual(len(calls), 4) remove_calls = self.app.cp.mockGetNamedCalls('removeConnection')
self.assertEquals(calls[0].getParam(1).getUUID(), uuid1) self.assertEqual(len(remove_calls), 1)
self.assertEquals(calls[1].getParam(1).getUUID(), uuid2) remove_calls[0].checkArgs(conn2)
self.assertEquals(calls[2].getParam(1).getUUID(), uuid3) # storage unregistered
self.assertEquals(calls[3].getParam(1).getUUID(), uuid4) unregister_calls = self.app.dispatcher.mockGetNamedCalls('unregister')
self.assertEqual(len(unregister_calls), 1)
unregister_calls[0].checkArgs(conn2)
class MasterAnswersHandlerTests(NeoTestBase):
class MasterAnswersHandlerTests(MasterHandlerTests):
def setUp(self): def setUp(self):
self.app = Mock() self.app = Mock()
self.handler = PrimaryAnswersHandler(self.app) self.handler = PrimaryAnswersHandler(self.app)
def test_AnswerBeginTransaction(self): def test_answerBeginTransaction(self):
app = Mock({'setTID': None}) tid = self.getNextTID()
dispatcher = self.getDispatcher() conn = self.getConnection()
client_handler = PrimaryAnswersHandler(app) self.handler.answerBeginTransaction(conn, tid)
conn = self.getConnection() calls = self.app.mockGetNamedCalls('setTID')
test_tid = 1 self.assertEqual(len(calls), 1)
client_handler.answerBeginTransaction(conn, test_tid) calls[0].checkArgs(tid)
setTID_call_list = app.mockGetNamedCalls('setTID')
self.assertEquals(len(setTID_call_list), 1) def test_answerNewOIDs(self):
self.assertEquals(setTID_call_list[0].getParam(0), test_tid) conn = self.getConnection()
oid1, oid2, oid3 = self.getOID(0), self.getOID(1), self.getOID(2)
def test_AnswerTransactionFinished(self): self.handler.answerNewOIDs(conn, [oid1, oid2, oid3])
test_tid = 1 self.assertEqual(self.app.new_oid_list, [oid3, oid2, oid1])
app = Mock({'getTID': test_tid, 'setTransactionFinished': None})
dispatcher = self.getDispatcher() def test_answerTransactionFinished(self):
client_handler = PrimaryAnswersHandler(app) conn = self.getConnection()
conn = self.getConnection() tid1 = self.getNextTID()
client_handler.answerTransactionFinished(conn, test_tid) tid2 = self.getNextTID(tid1)
self.assertEquals(len(app.mockGetNamedCalls('setTransactionFinished')), 1) # wrong TID
# TODO: decide what to do when non-current transaction is notified as finished, and test that behaviour self.app = Mock({'getTID': tid1})
self.checkProtocolErrorRaised(self.handler.answerTransactionFinished,
def test_AnswerNewOIDs(self): conn, tid2)
class App: # matching TID
new_oid_list = [] app = Mock({'getTID': tid2})
app = App() handler = PrimaryAnswersHandler(app=app)
dispatcher = self.getDispatcher() handler.answerTransactionFinished(conn, tid2)
client_handler = PrimaryAnswersHandler(app) calls = app.mockGetNamedCalls('setTransactionFinished')
conn = self.getConnection() self.assertEqual(len(calls), 1)
test_oid_list = ['\x00\x00\x00\x00\x00\x00\x00\x01', '\x00\x00\x00\x00\x00\x00\x00\x02']
client_handler.answerNewOIDs(conn, test_oid_list[:])
self.assertEquals(set(app.new_oid_list), set(test_oid_list))
class _(object):
def getConnection(self, uuid=None, port=10010, next_id=None, ip='127.0.0.1'):
if uuid is None:
uuid = self.getNewUUID()
return Mock({'_addPacket': None,
'getUUID': uuid,
'getAddress': (ip, port),
'getNextId': next_id,
'getPeerId': 0,
'lock': None,
'unlock': None})
def getDispatcher(self, queue=None):
return Mock({'getQueue': queue, 'connectToPrimaryNode': None})
def buildHandler(self, handler_class, app, dispatcher):
# some handlers do not accept the second argument
try:
return handler_class(app, dispatcher)
except TypeError:
return handler_class(app)
def test_ping(self):
"""
Simplest test: check that a PING packet is answered by a PONG
packet.
"""
dispatcher = self.getDispatcher()
client_handler = BaseHandler(None, dispatcher)
conn = self.getConnection()
packet = protocol.Ping()
client_handler.packetReceived(conn, packet)
self.checkAnswerPacket(conn, protocol.PONG)
def _testInitialMasterWithMethod(self, method):
class App:
primary_master_node = None
trying_master_node = 1
app = App()
method(self.getDispatcher(), app, PrimaryBootstrapHandler)
self.assertEqual(app.primary_master_node, None)
def _testMasterWithMethod(self, method, handler_class):
uuid = self.getNewUUID()
app = Mock({'connectToPrimaryNode': None})
app.primary_master_node = Mock({'getUUID': uuid})
app.master_conn = Mock({'close': None, 'getUUID': uuid, 'getAddress': ('127.0.0.1', 10000)})
dispatcher = self.getDispatcher()
method(dispatcher, app, handler_class, uuid=uuid, conn=app.master_conn)
# XXX: should connection closure be tested ? It's not implemented in all cases
#self.assertEquals(len(App.master_conn.mockGetNamedCalls('close')), 1)
#self.assertEquals(app.master_conn, None)
#self.assertEquals(app.primary_master_node, None)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
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