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] |