SF.net SVN: fclient: [528] trunk/fcp2/src
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2008-07-06 21:40:29
|
Revision: 528
http://fclient.svn.sourceforge.net/fclient/?rev=528&view=rev
Author: jUrner
Date: 2008-07-06 14:40:37 -0700 (Sun, 06 Jul 2008)
Log Message:
-----------
...
Added Paths:
-----------
trunk/fcp2/src/test/
trunk/fcp2/src/test/__init__.py
trunk/fcp2/src/test/dummy_io.py
trunk/fcp2/src/test/test_all.py
trunk/fcp2/src/test/test_client.py
trunk/fcp2/src/test/test_config.py
trunk/fcp2/src/test/test_iohandler.py
trunk/fcp2/src/test/test_key.py
trunk/fcp2/src/test/test_message.py
trunk/fcp2/src/test/test_types.py
Added: trunk/fcp2/src/test/__init__.py
===================================================================
--- trunk/fcp2/src/test/__init__.py (rev 0)
+++ trunk/fcp2/src/test/__init__.py 2008-07-06 21:40:37 UTC (rev 528)
@@ -0,0 +1 @@
+
Added: trunk/fcp2/src/test/dummy_io.py
===================================================================
--- trunk/fcp2/src/test/dummy_io.py (rev 0)
+++ trunk/fcp2/src/test/dummy_io.py 2008-07-06 21:40:37 UTC (rev 528)
@@ -0,0 +1,108 @@
+"""Dummy socket object for testing"""
+
+import os, sys
+
+#--> rel import hack
+class _RelImportHack(object):
+ def __init__(self, n):
+ fpath = os.path.abspath(__file__)
+ for i in xrange(n): fpath = os.path.dirname(fpath)
+ sys.path.insert(0, fpath)
+ def __del__(self): sys.path.pop(0)
+hack = _RelImportHack(3)
+
+import fcp2
+from fcp2 import iohandler
+
+del hack
+#<-- rel import hack
+#********************************************************************
+#
+#********************************************************************
+class DummyIO(iohandler.IOObjectBase):
+
+ def __init__(self):
+ self.readBuffer = '' # buffer client reads from
+ self.writeBuffer = '' # buffer client writes to
+
+ self._isOpen = False
+ self._isBroken = False
+ self._allowConnect = True
+ self._reverseDirection = False
+
+ def connect(self, **kwargs):
+ if not self._allowConnect:
+ raise fcp2.ErrorIOConnectFailed('Refused')
+ self._isOpen = True
+
+ def read(self, n):
+ if self._isBroken:
+ raise fcp2.ErrorIOBroken('Broken')
+ if not self.isOpen():
+ raise fcp2.ErrorIOClosed('Closed')
+
+ if self._reverseDirection:
+ if not self.writeBuffer:
+ raise fcp2.ErrorIOTimeout('Timeout')
+ bytes, self.writeBuffer = self.writeBuffer[ :n], self.writeBuffer[n: ]
+ else:
+ if not self.readBuffer:
+ raise fcp2.ErrorIOTimeout('Timeout')
+ bytes, self.readBuffer = self.readBuffer[ :n], self.readBuffer[n: ]
+ return bytes
+
+ def write(self, bytes):
+ if self._isBroken:
+ raise fcp2.ErrorIOBroken('Broken')
+ if not self.isOpen():
+ raise fcp2.ErrorIOClosed('Closed')
+ self.writeBuffer += bytes
+
+ def close(self):
+ self._isBroken = False
+ self._allowConnect = True
+ self._reverseDirection = False
+ if self.isOpen():
+ self._isOpen = False
+ self.readBuffer = ''
+ self.writeBuffer = ''
+ else:
+ raise fcp2.ErrorIOClosed('Closed')
+
+ def isOpen(self):
+ return self._isOpen
+
+ def setTimeout(self, n):
+ pass
+
+
+ ############################
+ ## for testing...
+
+ def setOpen(self, flag):
+ self._isOpen = flag
+
+ def setBroken(self, flag):
+ self._isBroken = flag
+
+ def setAllowConnect(self, flag):
+ self._allowConnect = flag
+
+ def setReverseDirection(self, flag):
+ self._reverseDirection = flag
+
+ def sendResponseMessage(self, name, data=None, **params):
+ buf = [name, ]
+ for name, value in params.items():
+ buf.append('%s=%s' % (name, value) )
+ if data is None:
+ buf.append('EndMessage\n')
+ else:
+ buf.append('Data\n')
+ self.readBuffer += '\n'.join(buf)
+ if data:
+ assert 'DataLength' in params
+ assert params['DataLength'] == len(data)
+ self.readBuffer += data
+
+
Added: trunk/fcp2/src/test/test_all.py
===================================================================
--- trunk/fcp2/src/test/test_all.py (rev 0)
+++ trunk/fcp2/src/test/test_all.py 2008-07-06 21:40:37 UTC (rev 528)
@@ -0,0 +1,27 @@
+"""Runs all unittests in the current folder"""
+
+import os, sys
+import unittest
+#*************************************************************************************************
+#
+#*************************************************************************************************
+if __name__ == '__main__':
+ Dir, SelfName= os.path.split(os.path.abspath(__file__))
+ sys.path.insert(0, Dir)
+
+ for file in os.walk(Dir).next()[2]:
+ filename, ext = os.path.splitext(file)
+ if ext.lower() == '.py':
+ if filename.startswith('test_') and file != SelfName:
+ mod = __import__(filename)
+ suite = getattr(mod, 'suite')
+ unittest.TextTestRunner(verbosity=1).run(suite())
+
+
+
+
+
+
+
+
+
Added: trunk/fcp2/src/test/test_client.py
===================================================================
--- trunk/fcp2/src/test/test_client.py (rev 0)
+++ trunk/fcp2/src/test/test_client.py 2008-07-06 21:40:37 UTC (rev 528)
@@ -0,0 +1,3010 @@
+"""Unittests for fcp2.client.py"""
+from __future__ import with_statement
+
+import os, sys
+import copy
+import socket
+import tempfile
+import time
+import unittest
+
+import fcp2
+from dummy_io import DummyIO
+#***********************************************************************************
+#
+#***********************************************************************************
+DIR = os.path.dirname(os.path.abspath(__file__))
+##TestAgainstNode = 0 # don't know how to test against node. Do not touch this!
+
+# for testing some valid key data
+DummyKeyData = 'aaa,bbb,ccc'
+#***********************************************************************************
+#
+#***********************************************************************************
+class BaseTestClient(unittest.TestCase):
+ """Base class for all tests"""
+
+ client = fcp2.Client(
+ #debugVerbosity=fcp2.ConstDebugVerbosity.Debug,
+ debugVerbosity=fcp2.ConstDebugVerbosity.Quiet
+ )
+
+ client.ioHandler.setIOPrototype(DummyIO)
+
+
+ def __init__(self, *args, **kwargs):
+ unittest.TestCase.__init__(self, *args, **kwargs)
+
+ self.events = [] # events received from the client
+ self.tmpfiles = [] # temp files used for testing (will be removed on tearDown)
+
+
+ def _captureEventsFromClient(self, event, msg):
+ """Captures events the client send"""
+ # have to copy message here, to get exact state
+ msg = copy.deepcopy(msg)
+ self.events.append( (event, msg) )
+
+
+ def connectClient(self):
+ """Connects to the client"""
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ msg = self.getNextMessage()
+ if msg is not None:
+ self.failUnless(msg.name == 'ClientHello')
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='2.0',
+ Build='9999999999',
+
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='999999999999',
+ ExRevision='9999999999',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientConnected,
+ fcp2.MsgNodeHello,
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def closeClient(self):
+ """Closes the client"""
+ self.client.close()
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.Close),
+ )
+
+
+ def assertHasNextEvent(self,
+ expectedEvent=None,
+ message=None,
+ param1=None,
+ param2=None,
+ param3=None,
+ param4=None,
+ param5=None,
+ data=None
+ ):
+ """Tests if we received a certain event from the client
+ @param expectedEvent: the event expected or None if no event is expected
+ @param message: expected mesage or None if no message is expected
+ @param param1: tuple(paramName, value) of a message parameter expected
+ @param data: data expected along with the message or None
+
+ @return: message if a message was received or None
+ """
+ if expectedEvent is None:
+ self.failIf(self.events)
+ else:
+ self.failUnless(self.events)
+ event, msg = self.events.pop(0)
+ self.assertEqual(event, expectedEvent)
+
+ if message is not None:
+ self.assertEqual(msg.name, message.name)
+ if param1 is not None:
+ param1, value1 = param1
+ self.failUnless(param1 in msg.params)
+ self.assertEqual(value1, msg[param1])
+ if param2 is not None:
+ param2, value2 = param2
+ self.failUnless(param2 in msg.params)
+ self.assertEqual(value2, msg[param2])
+ if param3 is not None:
+ param3, value3 = param3
+ self.failUnless(param3 in msg.params)
+ self.assertEqual(value3, msg[param3])
+ if param4 is not None:
+ param4, value4 = param4
+ self.failUnless(param4 in msg.params)
+ self.assertEqual(value4, msg[param4])
+ if param5 is not None:
+ param5, value5 = param5
+ self.failUnless(param5 in msg.params)
+ self.assertEqual(value5, msg[param5])
+
+ if data is not None:
+ self.assertEqual(data, msg.data)
+
+ return msg
+
+ def assertHasNextMessage(self,
+ message,
+ param1=None,
+ param2=None,
+ param3=None,
+ param4=None,
+ param5=None,
+ param6=None,
+ param7=None,
+ param8=None,
+ param9=None,
+ param10=None,
+ param11=None,
+ param12=None,
+ param13=None,
+ param14=None,
+ param15=None,
+ data=None
+ ):
+ """Tests if we received a certain message from the client
+ @param message: expected mesage or None if no message is expected
+ @param param1: tuple(paramName, value) of a message parameter expected
+ @param data: data expected along with the message or None
+
+ @return: message if a message was received or None
+ """
+ msg = self.getNextMessage()
+ if message is None:
+ self.failUnless(msg is None)
+ else:
+ self.failIf(msg is None)
+ self.assertEqual(msg.name, message.name)
+ if param1 is not None:
+ param1, value1 = param1
+ self.failUnless(param1 in msg.params)
+ self.assertEqual(value1, msg[param1])
+ if param2 is not None:
+ param2, value2 = param2
+ self.assertEqual(value2, msg[param2])
+ if param3 is not None:
+ param3, value3 = param3
+ self.failUnless(param3 in msg.params)
+ self.assertEqual(value3, msg[param3])
+ if param4 is not None:
+ param4, value4 = param4
+ self.failUnless(param4 in msg.params)
+ self.assertEqual(value4, msg[param4])
+ if param5 is not None:
+ param5, value5 = param5
+ self.failUnless(param5 in msg.params)
+ self.assertEqual(value5, msg[param5])
+ if param6 is not None:
+ param6, value6 = param6
+ self.failUnless(param6 in msg.params)
+ self.assertEqual(value6, msg[param6])
+ if param7 is not None:
+ param7, value7 = param7
+ self.failUnless(param7 in msg.params)
+ self.assertEqual(value7, msg[param7])
+ if param8 is not None:
+ param8, value8 = param8
+ self.failUnless(param8 in msg.params)
+ self.assertEqual(value8, msg[param8])
+ if param9 is not None:
+ param9, value9 = param9
+ self.failUnless(param9 in msg.params)
+ self.assertEqual(value9, msg[param9])
+ if param10 is not None:
+ param10, value10 = param10
+ self.failUnless(param10 in msg.params)
+ self.assertEqual(value10, msg[param10])
+ if param11 is not None:
+ param11, value11 = param11
+ self.failUnless(param11 in msg.params)
+ self.assertEqual(value11, msg[param11])
+ if param12 is not None:
+ param12, value12 = param12
+ self.failUnless(param12 in msg.params)
+ self.assertEqual(value12, msg[param12])
+ if param13 is not None:
+ param13, value13 = param13
+ self.failUnless(param13 in msg.params)
+ self.assertEqual(value13, msg[param13])
+ if param14 is not None:
+ param14, value14 = param14
+ self.failUnless(param14 in msg.params)
+ self.assertEqual(value14, msg[param14])
+ if param15 is not None:
+ param15, value15 = param15
+ self.failUnless(param15 in msg.params)
+ self.assertEqual(value15, msg[param15])
+
+ if data is not None:
+ self.assertEqual(data, msg.data)
+ return msg
+
+ def sendResponseMessage(self, messageName, data=None, callNext=True, **params):
+ """Sends a message to the client"""
+ if messageName in fcp2.MessagesAll:
+ msgClass = fcp2.MessagesAll[messageName]
+ else:
+ msgClass = fcp2.newMessageClass(messageName)
+ msg = msgClass(data=data, **params)
+ self.client.ioHandler.io.readBuffer += msg.toString()
+ if callNext:
+ self.client.next()
+
+
+ #NOTE: iohandler is buffered
+ # ..so be careful not to get messages you send
+ #
+ # 1. sendResponseMessage('blah')
+ # 2. getNextMessage()
+ # 3. >>> 'blah'
+ def getNextMessage(self):
+ """Returns the next message the client send"""
+
+ # cheat a bit to get iohandler to read a message from writeBuffer
+ if self.ioOpen():
+ self.client.ioHandler.io.setReverseDirection(True)
+ try:
+ msg = self.client.ioHandler.readMessage()
+ except fcp2.ErrorIOTimeout:
+ return None
+ finally:
+ self.client.ioHandler.io.setReverseDirection(False)
+ return msg
+
+
+ def ioOpen(self):
+ """Checks if the clients io is open"""
+ return self.client.ioHandler.isOpen()
+
+
+ def getIO(self):
+ """Returns the clients io"""
+ return self.client.ioHandler.io
+
+
+ def setUp(self):
+ # conect all events
+ self.events = [] # events received from the client
+ for event in self.client.events:
+ event += self._captureEventsFromClient
+
+ def tearDown(self):
+ # disconnect all events
+ for event in self.client.events:
+ event -= self._captureEventsFromClient
+ # clean up tmpfiles
+ for fpath in self.tmpfiles: os.remove(fpath)
+ if self.client.isOpen():
+ self.client.close()
+
+
+#***********************************************************************************
+#
+#***********************************************************************************
+#TODO: class Test.... set/getDebugVerbosity / connectionName and friends... (BaseTestConnectedClient):
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_close(BaseTestClient):
+
+ #NOTE: currently ClientDisconnected() is triggered even if the client was not connected
+ def test_close_disconnected_client(self):
+ self.client.close()
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.Close),
+ )
+
+ def test_close_connected_client(self):
+ self.connectClient()
+ self.client.close()
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.Close),
+ )
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_isOpen(BaseTestClient):
+
+ def test_isOpen(self):
+ self.failIf(self.client.isOpen())
+ self.connectClient()
+ self.failUnless(self.client.isOpen())
+ self.closeClient()
+ self.failIf(self.client.isOpen())
+
+#***********************************************************************************
+#
+#***********************************************************************************
+#TODO: not idea how to test this
+class Test_connect(BaseTestClient):
+ pass
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_iterConnect(BaseTestClient):
+
+ def test_iterConnect_success(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ msg = self.getNextMessage()
+ if msg is not None:
+ self.failUnless(msg.name == 'ClientHello')
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='2.0',
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='999999999999',
+ Build='9999999999',
+ ExRevision='9999999999',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientConnected,
+ fcp2.MsgNodeHello,
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+ self.client.close()
+
+
+ def test_iterConnect_ioRefusesConnection(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ self.getIO().setAllowConnect(False)
+
+ self.failUnless(nodeHello is None)
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.IOConnectFailed),
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+
+
+ def test_iterConnect_nodeHelloNeverArrives(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ pass
+
+ self.failUnless(nodeHello is None)
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.NoNodeHello),
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+
+
+ def test_iterConnect_socketDies(self):
+ enum = self.client.iterConnect(duration=0.2, timeout=0.1)
+ errorRaised = False
+ while True:
+ try:
+ enum.next()
+ except StopIteration:
+ break
+ except fcp2.ErrorIOBroken, d:
+ errorRaised = True
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.ConnectionDied),
+ #('Param', None),
+ )
+ break
+ self.getIO().setBroken(True)
+
+ self.failUnless(errorRaised)
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+
+
+ def test_iterIterConnect_unknownNodehello(self):
+
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ self.sendResponseMessage(
+ 'i-am-invalid',
+ callNext=False,
+ )
+
+ self.failUnless(nodeHello is None)
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.UnknownNodeHello),
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+
+
+ def test_iterIterConnect_connect(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='2.0',
+ Build='9999999999',
+
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='999999999999',
+ ExRevision='9999999999',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientConnected,
+ fcp2.MsgNodeHello,
+ )
+ self.assertHasNextEvent(None)
+ #self.assertHasNextMessage(None) # due to our message hacking, NodeHello is still in io
+ self.failUnless(self.ioOpen())
+ self.closeClient()
+
+
+ def test_iterIterConnect_reconnect(self):
+ self.connectClient()
+
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='2.0',
+ Build='9999999999',
+
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='999999999999',
+ ExRevision='9999999999',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.Reconnect)
+ )
+ self.assertHasNextEvent(
+ self.client.events.ClientConnected,
+ fcp2.MsgNodeHello,
+ )
+ self.assertHasNextEvent(None)
+ #self.assertHasNextMessage(None) # due to our message hacking, NodeHello is still in io
+ self.failUnless(self.ioOpen())
+ self.closeClient()
+
+
+ def test_iterIterConnect_VersionMissmatch_FCPVersion(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='0.0',
+ Build='9999999999',
+
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='999999999999',
+ ExRevision='9999999999',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.VersionMissmatch)
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+ self.closeClient()
+
+
+ def test_iterIterConnect_VersionMissmatch_Build(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=0.2, timeout=0.1)):
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='2.0',
+ Build='0',
+
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='999999999999',
+ ExRevision='9999999999',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.VersionMissmatch)
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+ self.closeClient()
+
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_CloseConnectionDuplicateClientName(BaseTestClient):
+
+ def test_CloseConnectionDuplicateClientName(self):
+ self.connectClient()
+ self.sendResponseMessage(
+ 'CloseConnectionDuplicateClientName',
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.DuplicateClientName)
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+ self.closeClient()
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_closeNode(BaseTestClient):
+
+ def test_closeNode(self):
+ self.connectClient()
+ self.client.closeNode()
+ self.assertHasNextMessage(fcp2.MsgShutdown)
+ self.sendResponseMessage(
+ 'ProtocolError',
+ Code='18'
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.NodeClosing)
+ )
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+ self.closeClient()
+
+#***********************************************************************************
+#
+#***********************************************************************************
+# TODO: no idea how to test this
+class Test_startNode(BaseTestClient):
+ pass
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_get_setConnectionName(BaseTestClient):
+
+ def test_get_setConnectionName(self):
+
+ self.failIf(self.client.setConnectionName() == 'foo')
+ self.client.setConnectionName('foo')
+ self.failIf(self.client.getConnectionName() != 'foo')
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_get_setDebugVerbosity(BaseTestClient):
+
+ def test_get_setDebugVerbosity(self):
+ oldVerbosity = self.client.getDebugVerbosity()
+ self.client.setDebugVerbosity(fcp2.ConstDebugVerbosity.Quiet)
+ self.client.setDebugVerbosity(oldVerbosity)
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_versionCheckNodeHello(BaseTestClient):
+
+ def test_get_versionCheckNodeHello(self):
+
+ msg = {
+ 'FCPVersion': self.client.ExpectedFcpVersion,
+ 'Build':self.client.ExpectedNodeBuild,
+ }
+ result = self.client.versionCheckNodeHello(msg)
+ self.failUnless(result == True)
+
+ msg = {
+ 'FCPVersion': self.client.ExpectedFcpVersion -1,
+ 'Build':self.client.ExpectedNodeBuild,
+ }
+ result = self.client.versionCheckNodeHello(msg)
+ self.failUnless(result == False)
+
+ msg = {
+ 'FCPVersion': self.client.ExpectedFcpVersion,
+ 'Build':self.client.ExpectedNodeBuild -1,
+ }
+ result = self.client.versionCheckNodeHello(msg)
+ self.failUnless(result == False)
+
+ msg = {
+ 'FCPVersion': self.client.ExpectedFcpVersion +1,
+ 'Build':self.client.ExpectedNodeBuild,
+ }
+ result = self.client.versionCheckNodeHello(msg)
+ self.failUnless(result == False)
+
+ msg = {
+ 'FCPVersion': self.client.ExpectedFcpVersion,
+ 'Build':self.client.ExpectedNodeBuild +1,
+ }
+ result = self.client.versionCheckNodeHello(msg)
+ self.failUnless(result == True)
+
+#***********************************************************************************
+#
+#***********************************************************************************
+# TODO: not tested
+class Test_handleMessage(BaseTestClient):
+ pass
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_next(BaseTestClient):
+
+ def test_idle(self):
+ self.connectClient()
+ msg = self.client.next()
+ msg2 = self.assertHasNextEvent(
+ self.client.events.Idle,
+ fcp2.MsgClientSocketTimeout,
+ )
+ self.failUnless(msg == msg2)
+
+
+ def test_io_broken(self):
+ self.connectClient()
+ self.getIO().setBroken(True)
+
+ self.assertRaises(fcp2.ErrorIOBroken, self.client.next, )
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.ConnectionDied)
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+
+
+ def test_hasMessage(self):
+ self.connectClient()
+ self.sendResponseMessage(
+ 'HiThere',
+ callNext=False
+ )
+ msg = self.client.next()
+ self.assertEqual(msg.name, 'HiThere')
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+#***********************************************************************************
+#
+#***********************************************************************************
+#TODO: not tested
+class Test_run(BaseTestClient):
+ pass
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_sendMessage(BaseTestClient):
+
+ def test_io_broken(self):
+ self.connectClient()
+ self.getIO().setBroken(True)
+
+ self.assertRaises(fcp2.ErrorIOBroken, self.client.sendMessage, fcp2.MsgClientHello())
+ self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.ConnectionDied)
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(self.ioOpen())
+
+
+ def test_messageSend(self):
+ self.connectClient()
+ self.client.sendMessage(fcp2.MsgClientHello())
+ msg = self.client.next()
+ self.assertHasNextMessage(fcp2.MsgClientHello)
+ self.assertHasNextEvent(self.client.events.Idle)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_getConfig(BaseTestClient):
+
+ def test_getConfig(self):
+ self.connectClient()
+ self.client.getConfig(
+ withCurrent=True,
+ withDefaults=True,
+ withExpertFlag=True,
+ withForceWriteFlag=True,
+ withSortOrder=True,
+ withShortDescription=True,
+ withLongDescription=True,
+ withDataTypes=True,
+ )
+ msg = self.client.next()
+ self.assertHasNextMessage(fcp2.MsgGetConfig,
+ ('WithCurrent', True),
+ ('WithDefaults', True),
+ ('WithExpertFlag', True),
+ ('WithForceWriteFlag', True),
+ ('WithSortOrder', True),
+ ('WithShortDescription', True),
+ ('WithLongDescription', True),
+ ('WithDataTypes', True),
+ )
+ self.assertHasNextEvent(self.client.events.Idle)
+
+
+ self.sendResponseMessage('ConfigData',
+ foo='1234',
+ )
+ self.assertHasNextEvent(
+ self.client.events.ConfigData,
+ fcp2.MsgConfigData,
+ ('foo', '1234')
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_modifyConfig(BaseTestClient):
+
+ def test_getConfig(self):
+ self.connectClient()
+ self.client.modifyConfig(
+ {'foo': '1234'}
+ )
+ msg = self.client.next()
+ self.assertHasNextMessage(fcp2.MsgModifyConfig,
+ ('foo', '1234'),
+ )
+ self.assertHasNextEvent(self.client.events.Idle)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+#***********************************************************************************
+#
+#***********************************************************************************
+#TODO: not tested
+class Test_clientGet(BaseTestClient): pass
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_getData(BaseTestClient):
+
+ def test_100_request_registered(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey)
+ requestsAll = self.client.getRequests()
+ self.failUnless(myIdentifier in requestsAll)
+ myRequest = self.client.getRequest(myIdentifier)
+ self.assertEqual(myRequest['RequestType'], fcp2.ConstRequestType.GetData)
+
+
+ def test_300_message_send(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(
+ fcp2.MsgClientGet,
+ ('URI', myKey),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_400_progress(self):
+
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ self.sendResponseMessage(
+ 'SimpleProgress',
+ Identifier=myIdentifier,
+ Total=0,
+ Required=0,
+ Failed=0,
+ FatallyFailed=0,
+ Succeeded=0,
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestProgress,
+ fcp2.MsgClientGet,
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_500_completed_successfuly(self):
+
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ data = 'foo'
+ params = {
+ 'Identifier': myIdentifier,
+ 'Global': 'false',
+ 'DataLength': len(data),
+ 'Metadata.ContentType': 'any',
+ }
+ self.sendResponseMessage(
+ 'DataFound',
+ **params
+ )
+ # we don't expect an event here....
+ self.assertHasNextEvent(None)
+ self.sendResponseMessage(
+ 'AllData',
+ data=data,
+ Identifier=myIdentifier,
+ Global='false',
+ DataLength=len(data),
+ )
+
+ # client should complete and remove the request
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientGet,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ data=data
+ )
+
+ # non persistent requests are removed emidiately
+ self.failIf(myIdentifier in requestsAll)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_600_completed_with_error(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ self.sendResponseMessage(
+ fcp2.MsgGetFailed.name,
+ Code='28', # All data not found
+ Identifier=myIdentifier,
+ Global='false',
+ # blah.. more here
+ )
+ self.assertHasNextEvent(
+ self.client.events.RequestFailed,
+ fcp2.MsgClientGet,
+ ('RequestStatus', fcp2.ConstRequestStatus.Error |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ # non persistent requests are removed emidiately
+ self.failIf(myIdentifier in requestsAll)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_700_peristent_request_auto_retrieve_data(self):
+
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey, persistence=fcp2.ConstPersistence.Forever)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+
+ data = 'foo'
+ params = {
+ 'Identifier': myIdentifier,
+ 'Global': 'false',
+ 'DataLength': len(data),
+ 'Metadata.ContentType': 'any',
+ }
+ self.sendResponseMessage(
+ 'DataFound',
+ **params
+ )
+
+ self.assertHasNextMessage(fcp2.MsgGetRequestStatus)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+
+ def test_800_peristent_request_not_removed_on_success(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey, persistence=fcp2.ConstPersistence.Forever)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ data = 'foo'
+ self.sendResponseMessage(
+ 'AllData',
+ data=data,
+ Identifier=myIdentifier,
+ Global='false',
+ DataLength=len(data),
+ )
+
+ self.assertHasNextEvent(self.client.events.RequestCompleted)
+
+ # persistent requests are not removed emidiately
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_900_peristent_request_not_removed_on_error(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey, persistence=fcp2.ConstPersistence.Forever)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ self.sendResponseMessage(
+ 'GetFailed',
+ Code='28', # All data not found
+ Identifier=myIdentifier,
+ Global='false',
+ # blah.. more here
+ )
+
+ self.assertHasNextEvent(self.client.events.RequestFailed)
+
+ # persistent requests are not removed emidiately
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_910_restore_peristent_request_failure(self):
+ self.connectClient()
+ requestsAll = self.client.getRequests()
+ myIdentifier = '123456789'
+ self.sendResponseMessage(
+ 'PersistentGet',
+ Identifier=myIdentifier,
+ ClientToken='i-am-invalid',
+ Global='false',
+
+ callNext=False
+ )
+ self.assertRaises(fcp2.ErrorMessageParse, self.client.next)
+ self.failIf(myIdentifier in requestsAll)
+
+
+ def test_920_restore_peristent_request_success(self):
+ self.connectClient()
+ requestsAll = self.client.getRequests()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getData(myKey, persistence=fcp2.ConstPersistence.Forever)
+ self.failUnless(myIdentifier in requestsAll)
+ myRequest = self.client.getRequest(myIdentifier)
+ del requestsAll[myIdentifier]
+
+ self.sendResponseMessage(
+ 'PersistentGet',
+ **myRequest.params
+ )
+ self.failUnless(myIdentifier in requestsAll)
+ myRequest = self.client.getRequest(myIdentifier)
+ msg = self.assertHasNextEvent(
+ self.client.events.RequestRestored,
+ fcp2.MsgClientGet,
+ ('Identifier', myIdentifier),
+ ('RequestStatus', fcp2.ConstRequestStatus.Restored), # no RequestStatus.Pending flag should be set here
+ )
+
+
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_getFile(BaseTestClient):
+
+ def test_100_request_registered(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getFile(myKey, 'foo.txt')
+ requestsAll = self.client.getRequests()
+ self.failUnless(myIdentifier in requestsAll)
+ myRequest = self.client.getRequest(myIdentifier)
+ self.assertEqual(myRequest['RequestType'], fcp2.ConstRequestType.GetFile)
+
+
+ def test_200_key_object_is_accepted(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getFile(myKey, 'foo.txt')
+ requestsAll = self.client.getRequests()
+
+
+ def test_300_dda_denied(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getFile(
+ myKey,
+ os.path.join(DIR, 'DDATest.txt')
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ self.sendResponseMessage(
+ 'ProtocolError',
+ Code=25, # DDADenied
+ Identifier=myIdentifier,
+ ExtraDescription='An error occured',
+ Fatal='false',
+ Global='false',
+ )
+
+ # client should respond with a TestDDARequest
+ self.assertHasNextMessage(
+ fcp2.MsgTestDDARequest,
+ ('Directory', DIR),
+ ('WantWriteDirectory', True)
+ )
+
+ # respond with a TestDDAReply message
+ writeContent = 'blah'
+ fd, fpath = tempfile.mkstemp(dir=DIR)
+ os.close(fd)
+ self.sendResponseMessage(
+ 'TestDDAReply',
+ Directory=DIR,
+ WriteFilename=fpath,
+ ContentToWrite=writeContent,
+ )
+
+ # client should respond with a TestDDAResponse
+ self.assertHasNextMessage(
+ fcp2.MsgTestDDAResponse,
+ ('Directory', DIR)
+ )
+
+ # check if content was written
+ with open(fpath) as fp:
+ self.failUnless(fp.read() == writeContent)
+
+ # respond with a TestDDAComplete message
+ self.sendResponseMessage(
+ 'TestDDAComplete',
+ Directory=DIR,
+ WriteDirectoryAllowed='true',
+ )
+
+ # check if our tempfile was removed
+ self.failIf(os.path.isfile(fpath))
+
+ # client sahould send a new ClientGet
+ msg = self.assertHasNextMessage(fcp2.MsgClientGet)
+
+ # no events should have been triggered upo to now
+ self.assertHasNextEvent(None)
+
+ # respond with a PersistentGet
+ self.sendResponseMessage(
+ 'PersistentGet',
+ Started='false',
+ **msg.params
+ )
+
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_getKeyInfo(BaseTestClient):
+
+
+ def test_100_request_registered(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getKeyInfo(myKey)
+ requestsAll = self.client.getRequests()
+ self.failUnless(myIdentifier in requestsAll)
+ myRequest = self.client.getRequest(myIdentifier)
+ self.assertEqual(myRequest['RequestType'], fcp2.ConstRequestType.GetKeyInfo)
+
+ def test_200_key_object_is_accepted(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+
+ myIdentifier = self.client.getKeyInfo(myKey)
+ requestsAll = self.client.getRequests()
+
+
+ def test_300_getKeyInfo_Success(self):
+ self.connectClient()
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getKeyInfo(myKey)
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+
+ data = 'foo'
+ params = {
+ 'Identifier': myIdentifier,
+ 'Global': 'false',
+ 'DataLength': 123456,
+ 'Metadata.ContentType': 'any',
+ }
+ self.sendResponseMessage(
+ 'DataFound',
+ **params
+ )
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientGet,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+ self.failIf(myIdentifier in requestsAll)
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_400_GetKeyInfo_TooBig(self):
+ self.connectClient()
+
+ # test specdial case where ProtocolError.TooBig is handled as success
+ # request a arbitrary uri
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getKeyInfo(myKey)
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ self.sendResponseMessage(
+ 'GetFailed',
+ Code='21', # Too big
+ Identifier=myIdentifier,
+ Global='false',
+ # blah.. more here
+ )
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientGet,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+ self.failIf(myIdentifier in requestsAll)
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+
+ def test_500_GetKeyInfo_Failure(self):
+ self.connectClient()
+
+ # request a arbitrary file
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getKeyInfo(myKey)
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientGet)
+ self.sendResponseMessage(
+ 'GetFailed',
+ Code='28', # All data not found
+ Identifier=myIdentifier,
+ Global='false',
+ # blah.. more here
+ )
+ self.assertHasNextEvent(
+ self.client.events.RequestFailed,
+ fcp2.MsgClientGet,
+ ('RequestStatus', fcp2.ConstRequestStatus.Error |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+ self.failIf(myIdentifier in requestsAll)
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failUnless(self.ioOpen())
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_disconnectReason(BaseTestClient):
+
+ def test_1000_DuplicateClientName(self):
+ self.connectClient()
+ self.sendResponseMessage('CloseConnectionDuplicateClientName')
+ msg = self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.DuplicateClientName),
+ )
+
+ self.failIf(self.ioOpen())
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+
+
+ def test_1001_SocketDied_Receive(self):
+ self.connectClient()
+ self.getIO().setBroken(True)
+ self.assertRaises(fcp2.ErrorIOBroken, self.client.next)
+
+ # check if ClientDisconnected events has been triggered
+ msg = self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.ConnectionDied),
+ )
+
+ self.failIf(self.ioOpen())
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.connectClient()
+
+
+ def test_1002_SocketDied_Send(self):
+ self.connectClient()
+ self.getIO().setBroken(True)
+
+ # send a test message
+ self.assertRaises(fcp2.ErrorIOBroken, self.client.sendMessage, fcp2.newMessageClass('test')())
+
+ # check if ClientDisconnected events has been triggered
+ msg = self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.ConnectionDied),
+ )
+
+ self.failIf(self.ioOpen())
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.connectClient()
+
+
+ def test_1003_Shutdown(self):
+ self.connectClient()
+ self.client.closeNode()
+
+ msg = self.assertHasNextMessage(fcp2.MsgShutdown)
+ self.sendResponseMessage(
+ 'ProtocolError',
+ Code='18', # Shutting down
+ )
+
+ # check events the client triggered
+ msg = self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.NodeClosing)
+ )
+
+ self.failIf(self.ioOpen())
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.connectClient()
+
+
+
+ def test_1004_VersionMismatch(self):
+ for n, nodeHello in enumerate(self.client.iterConnect(duration=1, timeout=0.1)):
+ if n == 2:
+ self.assertHasNextMessage(
+ fcp2.MsgClientHello
+ )
+ self.sendResponseMessage(
+ 'NodeHello',
+ FCPVersion='0.0',
+ Node='Fred',
+ Version=str(self.client.ExpectedFcpVersion),
+ Revision='0',
+ Build='0',
+ ExRevision='0',
+ Testnet='false',
+ CompressionCodecs='1',
+ ConnectionIdentifier='any',
+ NodeLanguage='en',
+
+ callNext=False
+ )
+
+ # check events the client triggered
+ msg = self.assertHasNextEvent(
+ self.client.events.ClientDisconnected,
+ fcp2.MsgClientDisconnected,
+ ('DisconnectReason', fcp2.ConstDisconnectReason.VersionMissmatch)
+ )
+
+ self.failIf(self.ioOpen())
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.connectClient()
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_clientPut(BaseTestClient):
+
+ def test_keyTailIsDisallowed(self):
+ self.connectClient()
+
+ # key.tail is not allowed in all put actions
+ myKey = fcp2.KeyCHK(keyData=DummyKeyData, tail='foo')
+ self.assertRaises(ValueError, self.client.clientPut, fcp2.ConstRequestType.PutData, myKey, data='foo')
+
+ myKey = fcp2.KeySSK(keyData=DummyKeyData, tail='foo')
+ self.assertRaises(ValueError, self.client.clientPut, fcp2.ConstRequestType.PutData, myKey, data='foo')
+
+ myKey = fcp2.KeyUSK(keyData=DummyKeyData, tail='foo')
+ self.assertRaises(ValueError, self.client.clientPut, fcp2.ConstRequestType.PutData, myKey, data='foo')
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_putData(BaseTestClient):
+
+ def test_putData_Success(self):
+ self.connectClient()
+
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putData(
+ myKey,
+ 'any data here'
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPut)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutSuccessful',
+ Identifier=myIdentifier,
+ URI=myKey
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientPut,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+
+ def test_putData_Failure(self):
+ self.connectClient()
+
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putData(
+ myKey,
+ 'any data here'
+ )
+
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPut)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutFailed',
+ Identifier=myIdentifier,
+ Code='5', # rout not found
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestFailed,
+ fcp2.MsgClientPut,
+ ('RequestStatus', fcp2.ConstRequestStatus.Error |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_putDir(BaseTestClient):
+ def test_putDir_Success(self):
+ self.connectClient()
+
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putDir(
+ myKey,
+ 'myDirectory'
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPutDiskDir)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutSuccessful',
+ Identifier=myIdentifier,
+ URI=myKey
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientPutDiskDir,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+
+ def test_putDir_Failure(self):
+ self.connectClient()
+
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putDir(
+ myKey,
+ 'myDirectory'
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPutDiskDir)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutFailed',
+ Identifier=myIdentifier,
+ Code='5', # rout not found
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestFailed,
+ fcp2.MsgClientPutDiskDir,
+ ('RequestStatus', fcp2.ConstRequestStatus.Error |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_putFile(BaseTestClient):
+
+ def test_putFile_Success(self):
+ self.connectClient()
+
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putFile(
+ myKey,
+ 'myFile.txt'
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPut)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutSuccessful',
+ Identifier=myIdentifier,
+ URI=myKey
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientPut,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+
+ def test_putFile_Failure(self):
+ self.connectClient()
+
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putFile(
+ myKey,
+ 'myFile.txt'
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPut)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutFailed',
+ Identifier=myIdentifier,
+ Code='5', # rout not found
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestFailed,
+ fcp2.MsgClientPut,
+ ('RequestStatus', fcp2.ConstRequestStatus.Error |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_putMultiple(BaseTestClient):
+ def test_putMultiple_Success(self):
+ self.connectClient()
+
+ items = [
+ {
+ 'RequestType': fcp2.ConstRequestType.PutData,
+ 'Data': '12345',
+ 'Name': 'myItem0',
+ },
+ {
+ 'RequestType': fcp2.ConstRequestType.PutFile,
+ 'Filename': 'myFile.txt',
+ 'Name': 'myItem1',
+ },
+ {
+ 'RequestType': fcp2.ConstRequestType.PutRedirect,
+ 'TargetURI': 'CHK@123456789',
+ 'Name': 'myItem2',
+ },
+ {
+ 'RequestType': fcp2.ConstRequestType.PutData,
+ 'Data': '67890',
+ 'Name': 'myItem3',
+ },
+ ]
+
+ # request a arbitrary file
+ myKey = fcp2.KeyKSK('foo')
+ myIdentifier = self.client.putMultiple(
+ myKey,
+ items
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ msg = self.assertHasNextMessage(
+ fcp2.MsgClientPutComplexDir,
+ ('Files.0.Name', 'myItem0'),
+ ('Files.0.UploadFrom', 'direct'),
+ ('Files.0.DataLength', 5),
+
+ ('Files.1.Name', 'myItem1'),
+ ('Files.1.UploadFrom', 'disk'),
+ ('Files.1.Filename', 'myFile.txt'),
+
+ ('Files.2.Name', 'myItem2'),
+ ('Files.2.UploadFrom', 'redirect'),
+ ('Files.2.TargetURI', 'CHK@123456789'),
+
+ ('Files.3.Name', 'myItem3'),
+ ('Files.3.UploadFrom', 'direct'),
+ ('Files.3.DataLength', 5),
+
+ data='1234567890'
+ )
+
+ #for k, v in sorted(msg.params.items()):
+ # print k, v
+
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutSuccessful',
+ Identifier=myIdentifier,
+ URI=myKey
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientPutComplexDir,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+
+ def test_putMultiple_ItemErrors(self):
+ self.connectClient()
+
+ # upload directory is not allowed
+ items = [
+ {
+ 'RequestType': fcp2.ConstRequestType.PutDir,
+ 'Data': '12345',
+ 'Name': 'myItem0',
+ },
+ ]
+ myKey = fcp2.KeyKSK('foo')
+ self.assertRaises(ValueError, self.client.putMultiple, myKey, items)
+
+ #TODO: how to test required params?
+ # ...just some samples below
+
+ # no request type specified
+ items = [
+ {
+ #'RequestType': fcp2.ConstRequestType.PutData,
+ 'Data': '12345',
+ 'Name': 'myItem0',
+ },
+ ]
+ self.assertRaises(ValueError, self.client.putMultiple, myKey, items)
+
+ # param missing (we enforce all required parameters)
+ items = [
+ {
+ 'RequestType': fcp2.ConstRequestType.PutData,
+ #'Data': '12345',
+ #'Name': 'myItem0',
+ },
+ ]
+ self.assertRaises(ValueError, self.client.putMultiple, myKey, items)
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_putRedirect(BaseTestClient):
+
+
+ def testPutRedirect_Success(self):
+ self.connectClient()
+
+ # request a arbitrary file
+ myRedirect = fcp2.KeyKSK('foo')
+ myKey = fcp2.Key('CHK@' + DummyKeyData)
+ myIdentifier = self.client.putRedirect(
+ myRedirect,
+ myKey,
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPut)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutSuccessful',
+ Identifier=myIdentifier,
+ URI=myRedirect
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestCompleted,
+ fcp2.MsgClientPut,
+ ('RequestStatus', fcp2.ConstRequestStatus.Success |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+
+ def testPutRedirect_Failure(self):
+ self.connectClient()
+
+ # request a arbitrary file
+ myRedirect = fcp2.KeyKSK('foo')
+ myKey = fcp2.Key('CHK@' + DummyKeyData)
+ myIdentifier = self.client.putRedirect(
+ myRedirect,
+ myKey,
+ )
+ myRequest = self.client.getRequest(myIdentifier)
+ requestsAll = self.client.getRequests()
+
+ self.assertHasNextMessage(fcp2.MsgClientPut)
+ self.failUnless(myIdentifier in requestsAll)
+
+ self.sendResponseMessage(
+ 'PutFailed',
+ Identifier=myIdentifier,
+ Code='5', # rout not found
+ )
+
+ self.assertHasNextEvent(
+ self.client.events.RequestFailed,
+ fcp2.MsgClientPut,
+ ('RequestStatus', fcp2.ConstRequestStatus.Error |
+ fcp2.ConstRequestStatus.RemovedFromQueue |
+ fcp2.ConstRequestStatus.Completed
+ ),
+ )
+
+ self.assertHasNextEvent(None)
+ self.assertHasNextMessage(None)
+ self.failIf(requestsAll)
+
+#***********************************************************************************
+#
+#***********************************************************************************
+class Test_modifyRequest(BaseTestClient):
+
+ def test_modifyRequest_Persistent(self):
+ self.connectClient()
+
+
+ # request a arbitrary file
+ myKey = fcp2.Key('KSK@foo')
+ myIdentifier = self.client.getFile(
+ myKey,
+ 'arbitryry.txt...
[truncated message content] |