Thread: SF.net SVN: fclient: [507] trunk/fcp2/src/fcp2
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2008-07-05 21:20:17
|
Revision: 507
http://fclient.svn.sourceforge.net/fclient/?rev=507&view=rev
Author: jUrner
Date: 2008-07-05 14:20:24 -0700 (Sat, 05 Jul 2008)
Log Message:
-----------
fix. in keys trailing slash seems to be significant
Modified Paths:
--------------
trunk/fcp2/src/fcp2/key.py
trunk/fcp2/src/fcp2/test_fcp/test_key.py
Modified: trunk/fcp2/src/fcp2/key.py
===================================================================
--- trunk/fcp2/src/fcp2/key.py 2008-07-05 21:18:25 UTC (rev 506)
+++ trunk/fcp2/src/fcp2/key.py 2008-07-05 21:20:24 UTC (rev 507)
@@ -50,9 +50,11 @@
result = urlparse.urlsplit(string)[2]
while result.startswith('/'):
result = result[1: ]
+ hasTrailingSlash = False
while result.endswith('/'):
result = result[ :-1]
- if result:
+ hasTrailingSlash = True
+ if result and hasTrailingSlash:
result += '/'
return result
@@ -147,25 +149,27 @@
(?P<cryptoKey>[a-z0-9\-~]+?),
(?P<extra>[a-z0-9\-~]+?)
)
- /
(
- (?P<docName> (?: [^/]+?)) /
- ((?P<tail>.+) /)?
+ / (?P<docName> (?: [^/]+?))
+ (/ (?P<tail>.+?))?
)?
+ (?P<pManifest> /)?
'''
KeyPattern = re.compile(_ReMatchExact % _key_pattern_, re.I | re.X)
KeyType = consts.ConstKeyType.CHK
- def __init__(self, keyData=None, docName=None, tail=None):
+ def __init__(self, keyData=None, docName=None, tail=None, pManifest=False):
"""Creates a CHK key
@param keyData: (str) key data or None
@param docName: (str) docName to add to the key or None
@param tail: (str) for containers, path to item in container or None
+ @param pManifest: (bool) if True, the key points to a manifest
"""
self.keyData = keyData
self.docName = docName
self.tail = tail
+ self.pManifest= pManifest
def toString(self):
if self.keyData is None:
@@ -176,7 +180,10 @@
out.append(urllib.quote(self.docName))
if self.tail is not None:
out.append(urllib.quote(self.tail))
- return posixpath.join(*out)
+ result = posixpath.join(*out)
+ if self.pManifest:
+ result += '/'
+ return result
@classmethod
def fromString(clss, string):
@@ -185,7 +192,7 @@
result = clss.KeyPattern.match(key)
if result is not None:
d = result.groupdict()
- return clss(d['keyData'], docName=d['docName'], tail=d['tail'])
+ return clss(d['keyData'], docName=d['docName'], tail=d['tail'], pManifest=bool(d['pManifest']))
@@ -197,27 +204,29 @@
(?P<cryptoKey>[a-z0-9\-~]+?),
(?P<extra>[a-z0-9\-~]+?)
)
- /
(
- (?: (?P<docName>[^/]+?)) - (?: (?P<edition>[\d]+)) /
- ((?P<tail>.+) /)?
+ / (?: (?P<docName>[^/]+?)) - (?: (?P<edition>[\d]+))
+ (/ (?P<tail>.+?))?
)?
+ (?P<pManifest> /)?
'''
KeyPattern = re.compile(_ReMatchExact % _key_pattern_, re.I | re.X)
KeyType = consts.ConstKeyType.SSK
- def __init__(self, keyData=None, docName=None, edition=0, tail=None):
+ def __init__(self, keyData=None, docName=None, edition=0, tail=None, pManifest=False):
"""Creates a SSK key
@param keyData: (str) key data or None
@param docName: (str) docName to add to the key or None
@param edition: (int) desired edition
@param tail: (str) for containers, path to item in container or None
+ @param pManifest: (bool) if True, the key points to a manifest
"""
self.docName = docName
self.edition = edition
self.keyData = keyData
self.tail = tail
+ self.pManifest= pManifest
def toString(self):
if self.keyData is None:
@@ -230,7 +239,10 @@
out.append(urllib.quote(self.docName + '-' + str(self.edition)))
if self.tail is not None:
out.append(urllib.quote(self.tail))
- return posixpath.join(*out)
+ result = posixpath.join(*out)
+ if self.pManifest:
+ result += '/'
+ return result
@classmethod
def fromString(clss, string):
@@ -242,7 +254,7 @@
edition = d['edition']
if edition is not None:
edition = int(edition)
- return clss(d['keyData'], docName=d['docName'], edition=edition, tail=d['tail'])
+ return clss(d['keyData'], docName=d['docName'], edition=edition, tail=d['tail'], pManifest=bool(d['pManifest']))
@@ -250,7 +262,7 @@
class KeyKSK(_KeyBase):
_key_pattern_ = '''
(?P<keyType>KSK@)
- (?P<docName>[^/]+?) /
+ (?P<docName>[^/]+?)
'''
KeyPattern = re.compile(_ReMatchExact % _key_pattern_, re.I | re.X)
KeyType = consts.ConstKeyType.KSK
@@ -288,29 +300,31 @@
(?P<cryptoKey>[a-z0-9\-~]+?),
(?P<extra>[a-z0-9\-~]+?)
)
- /
(
- (?P<docName>[^/]+?) /
- (?P<edition>-?\d+) /
- ((?P<tail>.+) /)?
+ / (?P<docName>[^/]+?)
+ / (?P<edition>-?\d+)
+ (/ (?P<tail>.+?))?
)?
+ (?P<pManifest> /)?
'''
KeyPattern = re.compile(_ReMatchExact % _key_pattern_, re.I | re.X)
KeyType = consts.ConstKeyType.USK
- def __init__(self, keyData=None, docName=None, edition=-1, tail=None):
+ def __init__(self, keyData=None, docName=None, edition=-1, tail=None, pManifest=False):
"""Creates a USK key
@param keyData: (str) key data or None
@param docName: (str) docName to add to the key or None
@param edition: (int) desired edition
@param tail: (str) for containers, path to item in container or None
+ @param pManifest: (bool) if True, the key points to a manifest
"""
self.edition = edition
self.docName = docName
self.keyData = keyData
self.tail = tail
+ self.pManifest= pManifest
def toString(self):
if self.keyData is None:
@@ -324,7 +338,11 @@
out.append(urllib.quote(str(self.edition)))
if self.tail is not None:
out.append(urllib.quote(self.tail))
- return posixpath.join(*out)
+ result = posixpath.join(*out)
+ if self.pManifest:
+ result += '/'
+ return result
+
@classmethod
def fromString(clss, string, isQuoted=True):
@@ -336,7 +354,7 @@
edition = d['edition']
if edition is not None:
edition = int(edition)
- return clss(d['keyData'], docName=d['docName'], edition=edition, tail=d['tail'])
+ return clss(d['keyData'], docName=d['docName'], edition=edition, tail=d['tail'], pManifest=bool(d['pManifest']))
Modified: trunk/fcp2/src/fcp2/test_fcp/test_key.py
===================================================================
--- trunk/fcp2/src/fcp2/test_fcp/test_key.py 2008-07-05 21:18:25 UTC (rev 506)
+++ trunk/fcp2/src/fcp2/test_fcp/test_key.py 2008-07-05 21:20:24 UTC (rev 507)
@@ -29,17 +29,20 @@
#****************************************************************************************
class Test_normkey(unittest.TestCase):
- def test_01_addSlash(self):
+ def test_01_slashIsSignificant(self):
p = 'CHK@foo'
+ self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo')
+
+ p = 'CHK@foo/'
self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo/')
-
+
def test_02_stripHost(self):
p = 'freenet:CHK@foo'
- self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo/')
+ self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo')
p = 'http:///CHK@foo'
- self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo/')
-
+ self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo')
+
def test_stripSlashes(self):
p = 'http://////CHK@foo///////'
self.assertEqual(fcp2.keyNormkey(p), 'CHK@foo/')
@@ -59,21 +62,50 @@
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, None)
self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'CHK@' + DummyKeyData + '/'
+ myKey = fcp2.KeyCHK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, None)
+ self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
+
p = 'CHK@' + DummyKeyData + '/foo'
myKey = fcp2.KeyCHK.fromString(p)
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, 'foo')
self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'CHK@' + DummyKeyData + '/foo/'
+ myKey = fcp2.KeyCHK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, 'foo')
+ self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
+
p = 'CHK@' + DummyKeyData + '/foo/bar/baz'
myKey = fcp2.KeyCHK.fromString(p)
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, 'foo')
self.assertEqual(myKey.tail, 'bar/baz')
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+
+ p = 'CHK@' + DummyKeyData + '/foo/bar/baz/'
+ myKey = fcp2.KeyCHK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, 'foo')
+ self.assertEqual(myKey.tail, 'bar/baz')
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
def test_quote(self):
@@ -99,24 +131,56 @@
self.assertEqual(myKey.docName, None)
self.assertEqual(myKey.edition, None)
self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'SSK@' + DummyKeyData + '/'
+ myKey = fcp2.KeySSK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, None)
+ self.assertEqual(myKey.edition, None)
+ self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest,True)
+ self.assertEqual(myKey.toString(), p)
+
+
p = 'SSK@' + DummyKeyData + '/foo-1'
myKey = fcp2.KeySSK.fromString(p)
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, 'foo')
self.assertEqual(myKey.edition, 1)
self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'SSK@' + DummyKeyData + '/foo-1/'
+ myKey = fcp2.KeySSK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, 'foo')
+ self.assertEqual(myKey.edition, 1)
+ self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
+
p = 'SSK@' + DummyKeyData + '/foo-1/bar/baz'
myKey = fcp2.KeySSK.fromString(p)
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, 'foo')
self.assertEqual(myKey.edition, 1)
self.assertEqual(myKey.tail, 'bar/baz')
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'SSK@' + DummyKeyData + '/foo-1/bar/baz/'
+ myKey = fcp2.KeySSK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, 'foo')
+ self.assertEqual(myKey.edition, 1)
+ self.assertEqual(myKey.tail, 'bar/baz')
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
def test_quote(self):
p = 'SSK@' + DummyKeyData + '/foo -1'
@@ -166,24 +230,56 @@
self.assertEqual(myKey.docName, None)
self.assertEqual(myKey.edition, None)
self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'USK@' + DummyKeyData + '/'
+ myKey = fcp2.KeyUSK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, None)
+ self.assertEqual(myKey.edition, None)
+ self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
+
p = 'USK@' + DummyKeyData + '/foo/1'
myKey = fcp2.KeyUSK.fromString(p)
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, 'foo')
self.assertEqual(myKey.edition, 1)
self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'USK@' + DummyKeyData + '/foo/1/'
+ myKey = fcp2.KeyUSK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, 'foo')
+ self.assertEqual(myKey.edition, 1)
+ self.assertEqual(myKey.tail, None)
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
+
p = 'USK@' + DummyKeyData + '/foo/1/bar/baz'
myKey = fcp2.KeyUSK.fromString(p)
self.assertEqual(myKey.keyData, DummyKeyData)
self.assertEqual(myKey.docName, 'foo')
self.assertEqual(myKey.edition, 1)
self.assertEqual(myKey.tail, 'bar/baz')
+ self.assertEqual(myKey.pManifest, False)
self.assertEqual(myKey.toString(), p)
+ p = 'USK@' + DummyKeyData + '/foo/1/bar/baz/'
+ myKey = fcp2.KeyUSK.fromString(p)
+ self.assertEqual(myKey.keyData, DummyKeyData)
+ self.assertEqual(myKey.docName, 'foo')
+ self.assertEqual(myKey.edition, 1)
+ self.assertEqual(myKey.tail, 'bar/baz')
+ self.assertEqual(myKey.pManifest, True)
+ self.assertEqual(myKey.toString(), p)
+
def test_edition(self):
@@ -270,8 +366,8 @@
Test_SSK,
Test_KSK,
Test_USK,
- Test_TypeKey,
- Test_Key,
+ #Test_TypeKey,
+ #Test_Key,
)
suite = unittest.TestSuite()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jU...@us...> - 2008-07-06 05:52:01
|
Revision: 515
http://fclient.svn.sourceforge.net/fclient/?rev=515&view=rev
Author: jUrner
Date: 2008-07-05 22:52:07 -0700 (Sat, 05 Jul 2008)
Log Message:
-----------
fcp_lib is now lib
Modified Paths:
--------------
trunk/fcp2/src/fcp2/client.py
trunk/fcp2/src/fcp2/events.py
trunk/fcp2/src/fcp2/message.py
Modified: trunk/fcp2/src/fcp2/client.py
===================================================================
--- trunk/fcp2/src/fcp2/client.py 2008-07-06 05:38:42 UTC (rev 514)
+++ trunk/fcp2/src/fcp2/client.py 2008-07-06 05:52:07 UTC (rev 515)
@@ -231,7 +231,7 @@
import random
from fcp2.fcp_lib import namespace
-from fcp2.fcp_lib import tools
+from fcp2.lib import tools
del hack, _RelImportHack
#<-- rel import hack
Modified: trunk/fcp2/src/fcp2/events.py
===================================================================
--- trunk/fcp2/src/fcp2/events.py 2008-07-06 05:38:42 UTC (rev 514)
+++ trunk/fcp2/src/fcp2/events.py 2008-07-06 05:52:07 UTC (rev 515)
@@ -15,7 +15,7 @@
from fcp2 import consts
from fcp2 import types
-from fcp2.fcp_lib import events
+from fcp2.lib import events
del hack, _RelImportHack
Modified: trunk/fcp2/src/fcp2/message.py
===================================================================
--- trunk/fcp2/src/fcp2/message.py 2008-07-06 05:38:42 UTC (rev 514)
+++ trunk/fcp2/src/fcp2/message.py 2008-07-06 05:52:07 UTC (rev 515)
@@ -18,7 +18,7 @@
from fcp2 import config
from fcp2 import types
from fcp2 import key
-from fcp2.fcp_lib import node
+from fcp2.lib import node
del hack, _RelImportHack
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jU...@us...> - 2008-07-06 05:52:18
|
Revision: 516
http://fclient.svn.sourceforge.net/fclient/?rev=516&view=rev
Author: jUrner
Date: 2008-07-05 22:52:28 -0700 (Sat, 05 Jul 2008)
Log Message:
-----------
fcp_lib is now lib
Added Paths:
-----------
trunk/fcp2/src/fcp2/lib/
Removed Paths:
-------------
trunk/fcp2/src/fcp2/fcp_lib/
Copied: trunk/fcp2/src/fcp2/lib (from rev 513, trunk/fcp2/src/fcp2/fcp_lib)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jU...@us...> - 2008-07-06 05:54:39
|
Revision: 519
http://fclient.svn.sourceforge.net/fclient/?rev=519&view=rev
Author: jUrner
Date: 2008-07-05 22:54:48 -0700 (Sat, 05 Jul 2008)
Log Message:
-----------
...
Added Paths:
-----------
trunk/fcp2/src/fcp2/test/
Removed Paths:
-------------
trunk/fcp2/src/fcp2/test_fcp/
Copied: trunk/fcp2/src/fcp2/test (from rev 513, trunk/fcp2/src/fcp2/test_fcp)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jU...@us...> - 2008-07-07 07:14:37
|
Revision: 530
http://fclient.svn.sourceforge.net/fclient/?rev=530&view=rev
Author: jUrner
Date: 2008-07-07 00:14:44 -0700 (Mon, 07 Jul 2008)
Log Message:
-----------
still struggling with relative imports. hopefuly fixed now
Modified Paths:
--------------
trunk/fcp2/src/fcp2/__init__.py
trunk/fcp2/src/fcp2/client.py
trunk/fcp2/src/fcp2/config.py
trunk/fcp2/src/fcp2/consts.py
trunk/fcp2/src/fcp2/events.py
trunk/fcp2/src/fcp2/iohandler.py
trunk/fcp2/src/fcp2/key.py
trunk/fcp2/src/fcp2/message.py
trunk/fcp2/src/fcp2/types.py
Modified: trunk/fcp2/src/fcp2/__init__.py
===================================================================
--- trunk/fcp2/src/fcp2/__init__.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/__init__.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -4,33 +4,46 @@
@requires: python >= 2.5
"""
-import os, sys
-
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
+
__author__ = 'Juergen Urner'
__copyright__ = '(c) 2008 - Juergen Urner'
__email__ = 'jue...@ar...'
__licence__ = 'Mit'
__version__ = '0.0.1'
-
-#--> 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(2)
-
-from fcp2.client import *
-from fcp2.config import *
-from fcp2.consts import *
-from fcp2.key import *
-from fcp2.message import *
-from fcp2.types import *
-
-del hack, _RelImportHack
-#<-- rel import hack
+from .client import Client
+from .config import (Config, ConfigDataType, ConfigItem, ConfigKeySep, ConfigValueClass)
+from .consts import (ConstByteAmountPostfix, ConstConnectReason, ConstDebugVerbosity, ConstDisconnectReason,
+ ConstFetchError, ConstFilenameCollision, ConstInsertError, ConstKeyType, ConstLogMessages,
+ ConstLogger, ConstMessage, ConstPeerNodeStatus, ConstPeerNoteType, ConstPersistence,
+ ConstPriority, ConstProtocolError, ConstPutDirType, ConstRequestModified, ConstRequestStatus,
+ ConstRequestType, ConstReturnType, ConstTimeDeltaPostfix, ConstUploadFrom, ConstVerbosity,
+ Error, ErrorIOBroken, ErrorIOClosed, ErrorIOConnectFailed, ErrorIOTimeout, ErrorMessageParse,
+ FcpFalse, FcpTrue)
+from .key import (Key, KeyCHK, KeyKSK, KeySSK, KeyTypesAll, KeyUSK, TypeKey, base64UrlsaveDecode, keyNormkey)
+from .message import (MessagesAll, MsgAddPeer, MsgAllData, MsgClientDisconnected, MsgClientGet, MsgClientHello,
+ MsgClientPut, MsgClientPutComplexDir, MsgClientPutDiskDir, MsgClientSocketDied,
+ MsgClientSocketTimeout, MsgCloseConnectionDuplicateClientName, MsgConfigData, MsgDataFound,
+ MsgEndListPeerNotes, MsgEndListPeers, MsgEndListPersistentRequests, MsgFCPPluginMessage,
+ MsgFCPPluginReply, MsgFinishedCompression, MsgGenerateSSK, MsgGetConfig, MsgGetFailed,
+ MsgGetNode, MsgGetPluginInfo, MsgGetRequestStatus, MsgIdentifierCollision, MsgListPeer,
+ MsgListPeerNotes, MsgListPeers, MsgListPersistentRequests, MsgModifyConfig, MsgModifyPeer,
+ MsgModifyPeerNote, MsgModifyPersistentRequest, MsgNodeData, MsgNodeHello, MsgPeer, MsgPeerNote,
+ MsgPeerRemoved, MsgPersistentGet, MsgPersistentPut, MsgPersistentPutDir, MsgPersistentRequestModified,
+ MsgPersistentRequestRemoved, MsgPluginInfo, MsgProtocolError, MsgPutFailed, MsgPutFetchable,
+ MsgPutSuccessful, MsgRemovePeer, MsgRemoveRequest, MsgSSKKeypair, MsgShutdown, MsgSimpleProgress,
+ MsgStartedCompression, MsgSubscribeUSK, MsgSubscribedUSK, MsgSubscribedUSKUpdate,
+ MsgTestDDAComplete, MsgTestDDAReply, MsgTestDDARequest, MsgTestDDAResponse, MsgURIGenerated,
+ MsgUnknownNodeIdentifier, MsgUnknownPeerNoteType, MsgWatchGlobal, PersistentParamsSep,
+ newMessageClass)
+from .types import (Type, TypeBase64EncodedString, TypeBool, TypeByteAmount, TypeChoiceFProxyCss, TypeChoiceLoggerPriority,
+ TypeChoiceNodeDownloadAllowedDirs, TypeChoiceNodeUploadAllowedDirs, TypeChoicePriorityPolicy,
+ TypeChoiceSSLVersion, TypeDirname, TypeFilename, TypeFloat, TypeIP, TypeIPList, TypeIPort, TypeInt,
+ TypeIntWithBounds, TypeInt_GetFailed_ExpectedDataLenght, TypePercent, TypeString, TypeStringList, TypeTime,
+ TypeTimeDelta, TypeUri)
#****************************************************************************************
#
#****************************************************************************************
Modified: trunk/fcp2/src/fcp2/client.py
===================================================================
--- trunk/fcp2/src/fcp2/client.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/client.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -201,41 +201,33 @@
# someday to handle this
#
#------------------------------------------------------------------------------------------------------------------------------------------------
-
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
+
+
import os, sys
import atexit
import copy
-import logging
+import logging
+import random
import subprocess
import time
-import uuid
-#--> 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(2)
+from . import consts
+from . import config
+from . import events
+from . import message
+from . import iohandler
+from . import types
+from . import key
-from fcp2 import consts
-from fcp2 import config
-from fcp2 import events
-from fcp2 import message
-from fcp2 import iohandler
-from fcp2 import types
-from fcp2 import key
-import random
+from .lib import namespace
+from .lib import tools
-from fcp2.lib import namespace
-from fcp2.lib import tools
-del hack, _RelImportHack
-#<-- rel import hack
-
__all__ = ['Client', ]
#*************************************************************************************************
#
Modified: trunk/fcp2/src/fcp2/config.py
===================================================================
--- trunk/fcp2/src/fcp2/config.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/config.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -45,25 +45,16 @@
as L{types.Type}.
"""
-import os, sys
-import logging
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
-#--> 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(2)
-from fcp2 import consts
-from fcp2 import types
-from fcp2 import key
+import logging
-
-del hack, _RelImportHack
-#<-- rel import hack
+from . import consts
+from . import types
+from . import key
#****************************************************************************************
#
#****************************************************************************************
@@ -123,6 +114,7 @@
"""
# all known config keys (param class stripped)
+
Params = {
'console.allowedHosts': types.TypeIPList, # host names, single IPs CIDR-maskip IPs likee 192.168.0.0/24
@@ -460,11 +452,19 @@
yield x
return walker(self)
-
-__all__ = [i for i in dir() if i[0].isupper() and not i.startswith('_')]
+
#****************************************************************************************************
#
#****************************************************************************************************
+def _all_():
+ '''* imports are disallowed for relative imports. this print out the list of exported names'''
+ L = [i for i in globals() if i[0].isupper() and not i.startswith('_')]
+ L.sort()
+ print '(' + ', '.join(L) + ')'
+#_all_()
+
+
+
Modified: trunk/fcp2/src/fcp2/consts.py
===================================================================
--- trunk/fcp2/src/fcp2/consts.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/consts.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -523,5 +523,13 @@
ReportProgress = 0x1
ReportCompression = 0x200
-
-__all__ = [i for i in dir() if i[0].isupper() and not i.startswith('_')]
+#****************************************************************************************************
+#
+#****************************************************************************************************
+def _all_():
+ '''* imports are disallowed for relative imports. this print out the list of exported names'''
+ L = [i for i in globals() if i[0].isupper() and not i.startswith('_')]
+ L.sort()
+ print '(' + ', '.join(L) + ')'
+#_all_()
+
Modified: trunk/fcp2/src/fcp2/events.py
===================================================================
--- trunk/fcp2/src/fcp2/events.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/events.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -1,25 +1,14 @@
"""Fcp events
"""
+from __future__ import absolute_import
+
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(2)
-
-from fcp2 import consts
-from fcp2 import types
-from fcp2.lib import events
-
-
-del hack, _RelImportHack
-#<-- rel import hack
+from . import consts
+from . import types
+from .lib import events
#*******************************************************************************
#
#*******************************************************************************
Modified: trunk/fcp2/src/fcp2/iohandler.py
===================================================================
--- trunk/fcp2/src/fcp2/iohandler.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/iohandler.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -3,28 +3,17 @@
The module can be used to handle reading and writing of messages io from sockeet, file or whatever
"""
-
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
+
+
import os, sys
-import logging
import socket
import time
-
-#--> rel import hack, so we don't have to put the package on sys.path
-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(2)
-
-from fcp2 import consts
-from fcp2 import message
-from fcp2 import types
-
-del hack, _RelImportHack
-#<-- rel import hack
+from . import consts
+from . import message
#*****************************************************************************
#
#*****************************************************************************
@@ -359,10 +348,4 @@
raise ValueError('IOObject.BufferSize must be > 0')
self._ioPrototype = ioObject
-
-#***********************************************************************************************
-#
-#***********************************************************************************************
-if __name__ == '__main__':
- pass
\ No newline at end of file
Modified: trunk/fcp2/src/fcp2/key.py
===================================================================
--- trunk/fcp2/src/fcp2/key.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/key.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -1,4 +1,7 @@
-"""Fcp keys"""
+"""Fcp keys"""
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
import os, sys
import base64
@@ -7,19 +10,7 @@
import urllib
import urlparse
-#--> 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(2)
-
-from fcp2 import consts
-
-del hack, _RelImportHack
-#<-- rel import hack
+from . import consts
#**************************************************************************************
# consts
#**************************************************************************************
@@ -357,7 +348,14 @@
return clss(d['keyData'], docName=d['docName'], edition=edition, tail=d['tail'], pManifest=bool(d['pManifest']))
-
-__all__ = [i for i in dir() if i[0].isupper() and not i.startswith('_')]
-__all__.append('base64UrlsaveDecode')
-__all__.append('keyNormkey')
+#****************************************************************************************************
+#
+#****************************************************************************************************
+def _all_():
+ '''* imports are disallowed for relative imports. this print out the list of exported names'''
+ L = [i for i in globals() if i[0].isupper() and not i.startswith('_')]
+ L.append('base64UrlsaveDecode')
+ L.append('keyNormkey')
+ L.sort()
+ print '(' + ', '.join(L) + ')'
+#_all_()
Modified: trunk/fcp2/src/fcp2/message.py
===================================================================
--- trunk/fcp2/src/fcp2/message.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/message.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -1,28 +1,19 @@
"""Freennet Client Protocol messages
"""
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
+
import os, sys
import base64
import socket
-#--> 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(2)
-
-from fcp2 import consts
-from fcp2 import config
-from fcp2 import types
-from fcp2 import key
-from fcp2.lib import node
-
-
-del hack, _RelImportHack
-#<-- rel import hack
+from . import consts
+from . import config
+from . import types
+from . import key
+from .lib import node
#********************************************************************************
# consts
#********************************************************************************
@@ -1159,5 +1150,13 @@
}
-__all__ = [i for i in dir() if i[0].isupper() and not i.startswith('_')]
-__all__.append('newMessageClass')
\ No newline at end of file
+#****************************************************************************************************
+#
+#****************************************************************************************************
+def _all_():
+ '''* imports are disallowed for relative imports. this print out the list of exported names'''
+ L = [i for i in globals() if i[0].isupper() and not i.startswith('_')]
+ L.append('newMessageClass')
+ L.sort()
+ print '(' + ', '.join(L) + ')'
+#_all_()
Modified: trunk/fcp2/src/fcp2/types.py
===================================================================
--- trunk/fcp2/src/fcp2/types.py 2008-07-06 21:41:05 UTC (rev 529)
+++ trunk/fcp2/src/fcp2/types.py 2008-07-07 07:14:44 UTC (rev 530)
@@ -2,25 +2,15 @@
This module handles type conversions from Fcp to Python and vice versa
"""
+from __future__ import absolute_import
+if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below
+ import os; __path__ = [os.path.dirname(__file__)]
import os, sys
import base64
import re
-#--> 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(2)
-
-from fcp2 import consts
-
-
-del hack
-#<-- rel import hack
+from . import consts
#*************************************************************************************
#
#*************************************************************************************
@@ -263,11 +253,14 @@
ChoicesAllowMultiple = False
-__all__ = [i for i in dir() if i[0].isupper() and not i.startswith('_')]
-#********************************************************************************************
+#****************************************************************************************************
#
-#********************************************************************************************
-if __name__ == '__main__':
- import doctest
- doctest.testmod()
+#****************************************************************************************************
+def _all_():
+ '''* imports are disallowed for relative imports. this print out the list of exported names'''
+ L = [i for i in globals() if i[0].isupper() and not i.startswith('_')]
+ L.sort()
+ print '(' + ', '.join(L) + ')'
+#_all_()
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jU...@us...> - 2008-07-07 08:03:28
|
Revision: 533
http://fclient.svn.sourceforge.net/fclient/?rev=533&view=rev
Author: jUrner
Date: 2008-07-07 01:03:36 -0700 (Mon, 07 Jul 2008)
Log Message:
-----------
...
Added Paths:
-----------
trunk/fcp2/src/fcp2/test/
trunk/fcp2/src/fcp2/test/__init__.py
trunk/fcp2/src/fcp2/test/dummy_io.py
trunk/fcp2/src/fcp2/test/test_all.py
trunk/fcp2/src/fcp2/test/test_client.py
trunk/fcp2/src/fcp2/test/test_config.py
trunk/fcp2/src/fcp2/test/test_iohandler.py
trunk/fcp2/src/fcp2/test/test_key.py
trunk/fcp2/src/fcp2/test/test_message.py
trunk/fcp2/src/fcp2/test/test_types.py
Added: trunk/fcp2/src/fcp2/test/__init__.py
===================================================================
--- trunk/fcp2/src/fcp2/test/__init__.py (rev 0)
+++ trunk/fcp2/src/fcp2/test/__init__.py 2008-07-07 08:03:36 UTC (rev 533)
@@ -0,0 +1 @@
+
Added: trunk/fcp2/src/fcp2/test/dummy_io.py
===================================================================
--- trunk/fcp2/src/fcp2/test/dummy_io.py (rev 0)
+++ trunk/fcp2/src/fcp2/test/dummy_io.py 2008-07-07 08:03:36 UTC (rev 533)
@@ -0,0 +1,119 @@
+"""Dummy socket object for testing"""
+
+import os, sys
+
+
+def relimport(what):
+ import imp, os, sys
+ L = what.split('.')
+ if not L or L[0]:
+ raise ValueError('relative import must start with a dot')
+ name = os.path.abspath(__file__)
+ while L:
+ p = L.pop(0)
+ if p: name = os.path.join(name, p)
+ else:
+ name, _ = os.path.split(name)
+ if not _: break
+ if L: raise ValueError('root level exceeded')
+ mod = sys.modules.get(name, None)
+ if mod is None:
+ fpath, fname = os.path.split(name)
+ fp, fpath, suffixes = imp.find_module(fname, [fpath, ])
+ print fp, fpath, suffixes
+ try: mod = imp.load_module(name, fp, fpath, suffixes)
+ finally:
+ if fp is not None: fp.close()
+ return mod
+
+fcp2 = relimport('...fcp2')
+#********************************************************************
+#
+#********************************************************************
+class DummyIO(fcp2.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/fcp2/test/test_all.py
===================================================================
--- trunk/fcp2/src/fcp2/test/test_all.py (rev 0)
+++ trunk/fcp2/src/fcp2/test/test_all.py 2008-07-07 08:03:36 UTC (rev 533)
@@ -0,0 +1,19 @@
+"""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/fcp2/test/test_client.py
===================================================================
--- trunk/fcp2/src/fcp2/test/test_client.py (rev 0)
+++ trunk/fcp2/src/fcp2/test/test_client.py 2008-07-07 08:03:36 UTC (rev 533)
@@ -0,0 +1,3034 @@
+"""Unittests for fcp2.client.py"""
+from __future__ import with_statement
+
+import os, sys
+import copy
+import socket
+import tempfile
+import time
+import unittest
+
+
+# hack relative imports to make in-place testing work
+def relimport(what):
+ import imp, os, sys
+ L = what.split('.')
+ if not L or L[0]:
+ raise ValueError('relative import must start with a dot')
+ name = os.path.abspath(__file__)
+ while L:
+ p = L.pop(0)
+ if p: name = os.path.join(name, p)
+ else:
+ name, _ = os.path.split(name)
+ if not _: break
+ if L: raise ValueError('root level exceeded')
+ mod = sys.modules.get(name, None)
+ if mod is None:
+ fpath, fname = os.path.split(name)
+ fp, fpath, suffixes = imp.find_module(fname, [fpath, ])
+ try: mod = imp.load_module(name, fp, fpath, suffixes)
+ finally:
+ if fp is not None: fp.close()
+ return mod
+
+fcp2 = relimport('...fcp2')
+dummy_io = relimport('.dummy_io')
+#***********************************************************************************
+#
+#***********************************************************************************
+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(dummy_io.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())
+
+#***************************************...
[truncated message content] |