2019-06-30 20:14:03 +00:00
__filename__ = " tests.py "
__author__ = " Bob Mottram "
__license__ = " AGPL3+ "
2019-08-29 13:35:29 +00:00
__version__ = " 1.0.0 "
2019-06-30 20:14:03 +00:00
__maintainer__ = " Bob Mottram "
__email__ = " bob@freedombone.net "
__status__ = " Production "
import base64
import time
2019-07-04 20:36:12 +00:00
import os , os . path
2019-06-30 21:20:02 +00:00
import shutil
2019-07-09 14:20:23 +00:00
import commentjson
2019-08-16 10:36:41 +00:00
import json
2019-08-15 18:21:43 +00:00
from time import gmtime , strftime
2019-07-09 14:20:23 +00:00
from pprint import pprint
2019-06-30 20:14:03 +00:00
from person import createPerson
from Crypto . Hash import SHA256
from httpsig import signPostHeaders
from httpsig import verifyPostHeaders
2019-08-17 10:15:01 +00:00
from httpsig import messageContentDigest
2019-06-30 20:14:03 +00:00
from cache import storePersonInCache
from cache import getPersonFromCache
from threads import threadWithTrace
2019-06-30 21:20:02 +00:00
from daemon import runDaemon
from session import createSession
from posts import deleteAllPosts
from posts import createPublicPost
2019-06-30 22:56:37 +00:00
from posts import sendPost
2019-07-03 10:09:24 +00:00
from posts import archivePosts
2019-07-05 14:39:24 +00:00
from posts import noOfFollowersOnDomain
2019-07-08 08:51:33 +00:00
from posts import groupFollowersByDomain
2019-07-09 14:20:23 +00:00
from posts import sendCapabilitiesUpdate
2019-07-12 22:29:10 +00:00
from posts import archivePostsForPerson
2019-07-16 10:19:04 +00:00
from posts import sendPostViaServer
2019-07-01 11:09:09 +00:00
from follow import clearFollows
from follow import clearFollowers
2019-07-16 21:38:06 +00:00
from follow import sendFollowRequestViaServer
2019-07-17 11:54:13 +00:00
from follow import sendUnfollowRequestViaServer
2019-07-06 19:24:52 +00:00
from utils import followPerson
2019-08-21 16:35:46 +00:00
from utils import getNicknameFromActor
from utils import getDomainFromActor
2019-09-29 18:48:34 +00:00
from utils import copytree
2019-10-12 12:45:53 +00:00
from utils import getStatusNumber
2019-06-30 21:20:02 +00:00
from follow import followerOfPerson
2019-07-01 11:09:09 +00:00
from follow import unfollowPerson
from follow import unfollowerOfPerson
2019-07-05 12:35:29 +00:00
from follow import getFollowersOfPerson
2019-07-06 13:49:25 +00:00
from follow import sendFollowRequest
2019-07-03 10:04:23 +00:00
from person import createPerson
2019-08-22 18:36:07 +00:00
from person import setDisplayNickname
2019-07-03 10:04:23 +00:00
from person import setBio
2019-07-19 10:01:24 +00:00
from skills import setSkillLevel
2019-07-18 15:09:23 +00:00
from roles import setRole
2019-07-18 16:21:26 +00:00
from roles import getRoles
from roles import outboxDelegate
2019-07-03 18:24:44 +00:00
from auth import createBasicAuthHeader
from auth import authorizeBasic
from auth import storeBasicCredentials
2019-07-11 12:29:31 +00:00
from like import likePost
2019-07-18 09:26:47 +00:00
from like import sendLikeViaServer
2019-07-11 17:55:10 +00:00
from announce import announcePublic
2019-07-16 19:07:45 +00:00
from announce import sendAnnounceViaServer
2019-07-12 19:26:54 +00:00
from media import getMediaPath
2019-08-30 15:50:20 +00:00
from media import getAttachmentMediaType
2019-07-17 17:16:48 +00:00
from delete import sendDeleteViaServer
2019-07-18 09:26:47 +00:00
from inbox import validInbox
2019-07-18 11:35:48 +00:00
from inbox import validInboxFilenames
2019-09-01 08:55:05 +00:00
from content import addWebLinks
2019-09-29 18:48:34 +00:00
from content import replaceEmojiFromTags
from content import addHtmlTags
2019-11-04 20:39:14 +00:00
from content import removeLongWords
2019-06-30 20:14:03 +00:00
2019-06-30 21:27:25 +00:00
testServerAliceRunning = False
testServerBobRunning = False
2019-07-07 19:25:38 +00:00
testServerEveRunning = False
2019-06-30 21:27:25 +00:00
2019-06-30 20:14:03 +00:00
def testHttpsigBase ( withDigest ) :
print ( ' testHttpsig( ' + str ( withDigest ) + ' ) ' )
2019-08-09 09:46:33 +00:00
baseDir = os . getcwd ( )
path = baseDir + ' /.testHttpsigBase '
if os . path . isdir ( path ) :
shutil . rmtree ( path )
os . mkdir ( path )
os . chdir ( path )
2019-11-09 21:39:04 +00:00
contentType = ' application/activity+json '
2019-07-03 09:40:27 +00:00
nickname = ' socrates '
2019-06-30 20:14:03 +00:00
domain = ' argumentative.social '
2019-07-03 19:00:03 +00:00
httpPrefix = ' https '
2019-07-01 09:31:02 +00:00
port = 5576
2019-07-04 19:09:48 +00:00
password = ' SuperSecretPassword '
2019-07-13 09:37:17 +00:00
privateKeyPem , publicKeyPem , person , wfEndpoint = \
2019-08-09 09:46:33 +00:00
createPerson ( path , nickname , domain , port , httpPrefix , False , password )
assert privateKeyPem
2019-08-16 10:36:41 +00:00
messageBodyJson = { " a key " : " a value " , " another key " : " A string " , " yet another key " : " Another string " }
messageBodyJsonStr = json . dumps ( messageBodyJson )
2019-07-01 09:31:02 +00:00
headersDomain = domain
2019-08-16 20:35:11 +00:00
if port :
if port != 80 and port != 443 :
if ' : ' not in domain :
headersDomain = domain + ' : ' + str ( port )
2019-07-01 09:31:02 +00:00
2019-08-15 18:21:43 +00:00
dateStr = strftime ( " %a , %d % b % Y % H: % M: % S % Z " , gmtime ( ) )
2019-08-16 10:36:41 +00:00
boxpath = ' /inbox '
2019-06-30 20:14:03 +00:00
if not withDigest :
2019-11-09 21:39:04 +00:00
headers = { ' host ' : headersDomain , ' date ' : dateStr , ' content-type ' : ' application/json ' }
2019-08-16 10:36:41 +00:00
signatureHeader = \
2019-08-16 13:47:01 +00:00
signPostHeaders ( dateStr , privateKeyPem , nickname , \
domain , port , \
domain , port , \
boxpath , httpPrefix , None )
2019-06-30 20:14:03 +00:00
else :
2019-08-17 10:15:01 +00:00
bodyDigest = messageContentDigest ( messageBodyJsonStr )
2019-08-16 10:36:41 +00:00
headers = { ' host ' : headersDomain , ' date ' : dateStr , ' digest ' : f ' SHA-256= { bodyDigest } ' , ' content-type ' : contentType }
signatureHeader = \
2019-08-16 13:47:01 +00:00
signPostHeaders ( dateStr , privateKeyPem , nickname , \
domain , port , \
domain , port , \
2019-08-17 10:15:01 +00:00
boxpath , httpPrefix , messageBodyJsonStr )
2019-07-01 09:31:02 +00:00
2019-06-30 20:14:03 +00:00
headers [ ' signature ' ] = signatureHeader
2019-08-16 17:19:23 +00:00
assert verifyPostHeaders ( httpPrefix , publicKeyPem , headers , \
boxpath , False , None , \
2019-11-12 15:03:17 +00:00
messageBodyJsonStr , False )
2019-08-16 17:19:23 +00:00
assert verifyPostHeaders ( httpPrefix , publicKeyPem , headers , \
' /parambulator ' + boxpath , False , None , \
2019-11-12 15:03:17 +00:00
messageBodyJsonStr , False ) == False
2019-08-16 17:19:23 +00:00
assert verifyPostHeaders ( httpPrefix , publicKeyPem , headers , \
boxpath , True , None , \
2019-11-12 15:03:17 +00:00
messageBodyJsonStr , False ) == False
2019-06-30 20:14:03 +00:00
if not withDigest :
# fake domain
2019-11-09 21:39:04 +00:00
headers = { ' host ' : ' bogon.domain ' , ' date ' : dateStr , ' content-type ' : ' application/json ' }
2019-06-30 20:14:03 +00:00
else :
# correct domain but fake message
2019-08-15 21:34:25 +00:00
messageBodyJsonStr = ' { " a key " : " a value " , " another key " : " Fake GNUs " , " yet another key " : " More Fake GNUs " } '
2019-08-17 10:15:01 +00:00
bodyDigest = messageContentDigest ( messageBodyJsonStr )
2019-08-16 10:36:41 +00:00
headers = { ' host ' : domain , ' date ' : dateStr , ' digest ' : f ' SHA-256= { bodyDigest } ' , ' content-type ' : contentType }
2019-06-30 20:14:03 +00:00
headers [ ' signature ' ] = signatureHeader
2019-08-15 21:34:25 +00:00
assert verifyPostHeaders ( httpPrefix , publicKeyPem , headers , \
2019-08-16 17:19:23 +00:00
boxpath , True , None , \
2019-11-12 15:03:17 +00:00
messageBodyJsonStr , False ) == False
2019-08-09 09:46:33 +00:00
os . chdir ( baseDir )
shutil . rmtree ( path )
2019-06-30 20:14:03 +00:00
def testHttpsig ( ) :
testHttpsigBase ( True )
2019-08-15 21:34:25 +00:00
testHttpsigBase ( False )
2019-06-30 20:14:03 +00:00
def testCache ( ) :
print ( ' testCache ' )
personUrl = " cat@cardboard.box "
personJson = { " id " : 123456 , " test " : " This is a test " }
2019-07-01 14:30:48 +00:00
personCache = { }
2019-08-20 09:16:03 +00:00
storePersonInCache ( None , personUrl , personJson , personCache )
2019-08-20 09:37:09 +00:00
result = getPersonFromCache ( None , personUrl , personCache )
2019-06-30 20:14:03 +00:00
assert result [ ' id ' ] == 123456
assert result [ ' test ' ] == ' This is a test '
def testThreadsFunction ( param : str ) :
for i in range ( 10000 ) :
time . sleep ( 2 )
def testThreads ( ) :
print ( ' testThreads ' )
thr = threadWithTrace ( target = testThreadsFunction , args = ( ' test ' , ) , daemon = True )
thr . start ( )
assert thr . isAlive ( ) == True
time . sleep ( 1 )
thr . kill ( )
thr . join ( )
assert thr . isAlive ( ) == False
2019-06-30 21:20:02 +00:00
2019-07-13 09:37:17 +00:00
def createServerAlice ( path : str , domain : str , port : int , federationList : [ ] , \
2019-10-16 18:19:18 +00:00
hasFollows : bool , hasPosts : bool , ocapAlways : bool , sendThreads : [ ] ) :
2019-06-30 21:20:02 +00:00
print ( ' Creating test server: Alice on port ' + str ( port ) )
if os . path . isdir ( path ) :
shutil . rmtree ( path )
os . mkdir ( path )
os . chdir ( path )
2019-07-03 09:40:27 +00:00
nickname = ' alice '
2019-07-04 14:36:29 +00:00
httpPrefix = ' http '
2019-06-30 21:20:02 +00:00
useTor = False
2019-07-04 19:09:48 +00:00
password = ' alicepass '
2019-07-09 17:54:08 +00:00
noreply = False
nolike = False
2019-07-09 18:11:23 +00:00
nopics = False
noannounce = False
cw = False
2019-07-12 19:08:46 +00:00
useBlurhash = True
2019-07-13 21:00:12 +00:00
maxReplies = 64
2019-07-15 10:22:19 +00:00
domainMaxPostsPerDay = 1000
accountMaxPostsPerDay = 1000
2019-07-17 18:13:45 +00:00
allowDeletion = True
2019-07-13 09:37:17 +00:00
privateKeyPem , publicKeyPem , person , wfEndpoint = \
createPerson ( path , nickname , domain , port , httpPrefix , True , password )
2019-07-04 16:24:23 +00:00
deleteAllPosts ( path , nickname , domain , ' inbox ' )
deleteAllPosts ( path , nickname , domain , ' outbox ' )
2019-07-14 12:08:18 +00:00
assert setSkillLevel ( path , nickname , domain , ' hacking ' , 90 )
2019-07-14 12:25:16 +00:00
assert setRole ( path , nickname , domain , ' someproject ' , ' guru ' )
2019-07-06 13:49:25 +00:00
if hasFollows :
2019-07-13 09:37:17 +00:00
followPerson ( path , nickname , domain , ' bob ' , ' 127.0.0.100:61936 ' , \
2019-07-14 17:19:00 +00:00
federationList , False )
2019-07-13 09:37:17 +00:00
followerOfPerson ( path , nickname , domain , ' bob ' , ' 127.0.0.100:61936 ' , \
2019-07-14 17:19:00 +00:00
federationList , False )
2019-07-06 13:49:25 +00:00
if hasPosts :
2019-07-13 09:37:17 +00:00
createPublicPost ( path , nickname , domain , port , httpPrefix , \
" No wise fish would go anywhere without a porpoise " , \
False , True , clientToServer , None , None , useBlurhash )
createPublicPost ( path , nickname , domain , port , httpPrefix , \
" Curiouser and curiouser! " , False , True , \
clientToServer , None , None , useBlurhash )
createPublicPost ( path , nickname , domain , port , httpPrefix , \
" In the gardens of memory, in the palace of dreams, that is where you and I shall meet " , \
False , True , clientToServer , None , None , useBlurhash )
2019-06-30 21:27:25 +00:00
global testServerAliceRunning
testServerAliceRunning = True
2019-09-30 10:15:20 +00:00
maxMentions = 10
2019-06-30 21:20:02 +00:00
print ( ' Server running: Alice ' )
2019-11-11 17:49:08 +00:00
runDaemon ( ' en ' , __version__ , " instanceId " , False , path , domain , port , port , \
2019-09-30 10:15:20 +00:00
httpPrefix , federationList , maxMentions , False , \
2019-07-13 21:00:12 +00:00
noreply , nolike , nopics , noannounce , cw , ocapAlways , \
2019-07-15 10:22:19 +00:00
useTor , maxReplies , \
domainMaxPostsPerDay , accountMaxPostsPerDay , \
2019-10-16 18:19:18 +00:00
allowDeletion , True , True , False , sendThreads )
2019-06-30 21:20:02 +00:00
2019-07-13 09:37:17 +00:00
def createServerBob ( path : str , domain : str , port : int , federationList : [ ] , \
2019-10-16 18:19:18 +00:00
hasFollows : bool , hasPosts : bool , ocapAlways : bool , sendThreads : [ ] ) :
2019-06-30 21:20:02 +00:00
print ( ' Creating test server: Bob on port ' + str ( port ) )
if os . path . isdir ( path ) :
shutil . rmtree ( path )
os . mkdir ( path )
os . chdir ( path )
2019-07-03 09:40:27 +00:00
nickname = ' bob '
2019-07-03 19:00:03 +00:00
httpPrefix = ' http '
2019-06-30 21:20:02 +00:00
useTor = False
2019-07-03 15:10:18 +00:00
clientToServer = False
2019-07-04 19:09:48 +00:00
password = ' bobpass '
2019-07-09 17:54:08 +00:00
noreply = False
nolike = False
2019-07-09 18:11:23 +00:00
nopics = False
noannounce = False
cw = False
2019-07-12 19:08:46 +00:00
useBlurhash = False
2019-07-13 21:00:12 +00:00
maxReplies = 64
2019-07-15 10:22:19 +00:00
domainMaxPostsPerDay = 1000
accountMaxPostsPerDay = 1000
2019-07-17 19:31:52 +00:00
allowDeletion = True
2019-07-13 09:37:17 +00:00
privateKeyPem , publicKeyPem , person , wfEndpoint = \
createPerson ( path , nickname , domain , port , httpPrefix , True , password )
2019-07-04 16:24:23 +00:00
deleteAllPosts ( path , nickname , domain , ' inbox ' )
deleteAllPosts ( path , nickname , domain , ' outbox ' )
2019-07-14 12:25:16 +00:00
assert setRole ( path , nickname , domain , ' bandname ' , ' bass player ' )
assert setRole ( path , nickname , domain , ' bandname ' , ' publicist ' )
2019-07-06 13:49:25 +00:00
if hasFollows :
2019-07-13 09:37:17 +00:00
followPerson ( path , nickname , domain , \
2019-07-14 17:19:00 +00:00
' alice ' , ' 127.0.0.50:61935 ' , federationList , False )
2019-07-13 09:37:17 +00:00
followerOfPerson ( path , nickname , domain , \
2019-07-14 17:19:00 +00:00
' alice ' , ' 127.0.0.50:61935 ' , federationList , False )
2019-07-06 13:49:25 +00:00
if hasPosts :
2019-07-13 09:37:17 +00:00
createPublicPost ( path , nickname , domain , port , httpPrefix , \
" It ' s your life, live it your way. " , \
False , True , clientToServer , None , None , useBlurhash )
createPublicPost ( path , nickname , domain , port , httpPrefix , \
" One of the things I ' ve realised is that I am very simple " , \
False , True , clientToServer , None , None , useBlurhash )
createPublicPost ( path , nickname , domain , port , httpPrefix , \
" Quantum physics is a bit of a passion of mine " , \
False , True , clientToServer , None , None , useBlurhash )
2019-06-30 21:27:25 +00:00
global testServerBobRunning
testServerBobRunning = True
2019-09-30 10:15:20 +00:00
maxMentions = 10
2019-06-30 21:20:02 +00:00
print ( ' Server running: Bob ' )
2019-11-11 17:49:08 +00:00
runDaemon ( ' en ' , __version__ , " instanceId " , False , path , domain , port , port , \
2019-09-30 10:15:20 +00:00
httpPrefix , federationList , maxMentions , False , \
2019-07-13 21:00:12 +00:00
noreply , nolike , nopics , noannounce , cw , ocapAlways , \
2019-07-15 10:22:19 +00:00
useTor , maxReplies , \
domainMaxPostsPerDay , accountMaxPostsPerDay , \
2019-10-16 18:19:18 +00:00
allowDeletion , True , True , False , sendThreads )
2019-06-30 21:20:02 +00:00
2019-07-13 09:37:17 +00:00
def createServerEve ( path : str , domain : str , port : int , federationList : [ ] , \
2019-10-16 18:19:18 +00:00
hasFollows : bool , hasPosts : bool , ocapAlways : bool , sendThreads : [ ] ) :
2019-07-07 19:25:38 +00:00
print ( ' Creating test server: Eve on port ' + str ( port ) )
if os . path . isdir ( path ) :
shutil . rmtree ( path )
os . mkdir ( path )
os . chdir ( path )
nickname = ' eve '
httpPrefix = ' http '
useTor = False
clientToServer = False
password = ' evepass '
2019-07-09 17:54:08 +00:00
noreply = False
nolike = False
2019-07-09 18:11:23 +00:00
nopics = False
noannounce = False
cw = False
2019-07-13 21:00:12 +00:00
maxReplies = 64
2019-07-17 18:13:45 +00:00
allowDeletion = True
2019-07-13 09:37:17 +00:00
privateKeyPem , publicKeyPem , person , wfEndpoint = \
createPerson ( path , nickname , domain , port , httpPrefix , True , password )
2019-07-07 19:25:38 +00:00
deleteAllPosts ( path , nickname , domain , ' inbox ' )
deleteAllPosts ( path , nickname , domain , ' outbox ' )
global testServerEveRunning
testServerEveRunning = True
2019-09-30 10:15:20 +00:00
maxMentions = 10
2019-07-07 19:25:38 +00:00
print ( ' Server running: Eve ' )
2019-11-11 17:49:08 +00:00
runDaemon ( ' en ' , __version__ , " instanceId " , False , path , domain , port , port , \
2019-09-30 10:15:20 +00:00
httpPrefix , federationList , maxMentions , False , \
2019-07-13 21:00:12 +00:00
noreply , nolike , nopics , noannounce , cw , ocapAlways , \
2019-10-16 18:19:18 +00:00
useTor , maxReplies , allowDeletion , True , True , False , sendThreads )
2019-07-07 19:25:38 +00:00
2019-06-30 21:20:02 +00:00
def testPostMessageBetweenServers ( ) :
print ( ' Testing sending message from one server to the inbox of another ' )
2019-06-30 21:27:25 +00:00
global testServerAliceRunning
global testServerBobRunning
testServerAliceRunning = False
testServerBobRunning = False
2019-07-03 19:00:03 +00:00
httpPrefix = ' http '
2019-06-30 22:56:37 +00:00
useTor = False
2019-06-30 21:20:02 +00:00
baseDir = os . getcwd ( )
2019-07-06 13:49:25 +00:00
if os . path . isdir ( baseDir + ' /.tests ' ) :
shutil . rmtree ( baseDir + ' /.tests ' )
os . mkdir ( baseDir + ' /.tests ' )
2019-06-30 21:20:02 +00:00
2019-07-07 17:47:37 +00:00
ocapAlways = False
2019-06-30 21:20:02 +00:00
# create the servers
2019-06-30 22:56:37 +00:00
aliceDir = baseDir + ' /.tests/alice '
2019-07-02 09:25:29 +00:00
aliceDomain = ' 127.0.0.50 '
2019-06-30 22:56:37 +00:00
alicePort = 61935
bobDir = baseDir + ' /.tests/bob '
2019-07-02 09:25:29 +00:00
bobDomain = ' 127.0.0.100 '
2019-06-30 22:56:37 +00:00
bobPort = 61936
2019-07-11 12:29:31 +00:00
federationList = [ bobDomain , aliceDomain ]
2019-10-16 18:19:18 +00:00
aliceSendThreads = [ ]
bobSendThreads = [ ]
2019-07-11 12:29:31 +00:00
2019-07-13 09:37:17 +00:00
thrAlice = \
threadWithTrace ( target = createServerAlice , \
args = ( aliceDir , aliceDomain , alicePort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , aliceSendThreads ) , daemon = True )
2019-07-13 09:37:17 +00:00
thrBob = \
threadWithTrace ( target = createServerBob , \
args = ( bobDir , bobDomain , bobPort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , bobSendThreads ) , daemon = True )
2019-07-01 21:01:43 +00:00
thrAlice . start ( )
2019-06-30 21:20:02 +00:00
thrBob . start ( )
2019-07-01 21:01:43 +00:00
assert thrAlice . isAlive ( ) == True
2019-06-30 21:20:02 +00:00
assert thrBob . isAlive ( ) == True
2019-06-30 21:27:25 +00:00
# wait for both servers to be running
while not ( testServerAliceRunning and testServerBobRunning ) :
time . sleep ( 1 )
2019-07-04 20:25:19 +00:00
time . sleep ( 1 )
2019-06-30 21:20:02 +00:00
2019-07-11 12:29:31 +00:00
print ( ' \n \n ******************************************************* ' )
2019-06-30 22:56:37 +00:00
print ( ' Alice sends to Bob ' )
os . chdir ( aliceDir )
2019-07-02 09:25:29 +00:00
sessionAlice = createSession ( aliceDomain , alicePort , useTor )
2019-06-30 22:56:37 +00:00
inReplyTo = None
inReplyToAtomUri = None
subject = None
alicePostLog = [ ]
2019-07-01 12:51:55 +00:00
followersOnly = False
saveToFile = True
2019-07-03 15:10:18 +00:00
clientToServer = False
2019-07-01 12:51:55 +00:00
ccUrl = None
2019-07-01 14:30:48 +00:00
alicePersonCache = { }
aliceCachedWebfingers = { }
2019-07-12 19:26:54 +00:00
attachedImageFilename = baseDir + ' /img/logo.png '
2019-08-30 15:50:20 +00:00
mediaType = getAttachmentMediaType ( attachedImageFilename )
2019-07-12 19:26:54 +00:00
attachedImageDescription = ' Logo '
useBlurhash = True
2019-07-11 12:29:31 +00:00
# nothing in Alice's outbox
outboxPath = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /outbox '
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 0
2019-07-13 09:37:17 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPost ( __version__ , \
sessionAlice , aliceDir , ' alice ' , aliceDomain , alicePort , \
2019-07-13 09:37:17 +00:00
' bob ' , bobDomain , bobPort , ccUrl , httpPrefix , \
2019-11-09 21:39:04 +00:00
' Why is a mouse when it spins? यह एक परीक्षण है #sillyquestion ' , followersOnly , \
2019-08-30 15:50:20 +00:00
saveToFile , clientToServer , attachedImageFilename , mediaType , \
2019-07-13 09:37:17 +00:00
attachedImageDescription , useBlurhash , federationList , \
aliceSendThreads , alicePostLog , aliceCachedWebfingers , \
alicePersonCache , inReplyTo , inReplyToAtomUri , subject )
2019-06-30 22:56:37 +00:00
print ( ' sendResult: ' + str ( sendResult ) )
2019-07-04 20:36:12 +00:00
queuePath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /queue '
inboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /inbox '
2019-07-12 19:26:54 +00:00
mPath = getMediaPath ( )
mediaPath = aliceDir + ' / ' + mPath
2019-07-07 22:25:22 +00:00
for i in range ( 30 ) :
2019-07-04 20:36:12 +00:00
if os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) > 0 :
2019-07-11 12:29:31 +00:00
if len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 1 :
2019-07-12 19:26:54 +00:00
if len ( [ name for name in os . listdir ( mediaPath ) if os . path . isfile ( os . path . join ( mediaPath , name ) ) ] ) > 0 :
2019-10-19 17:50:05 +00:00
if len ( [ name for name in os . listdir ( queuePath ) if os . path . isfile ( os . path . join ( queuePath , name ) ) ] ) == 0 :
break
2019-07-01 21:01:43 +00:00
time . sleep ( 1 )
2019-07-09 08:52:53 +00:00
2019-07-12 19:26:54 +00:00
# Image attachment created
assert len ( [ name for name in os . listdir ( mediaPath ) if os . path . isfile ( os . path . join ( mediaPath , name ) ) ] ) > 0
2019-07-11 12:29:31 +00:00
# inbox item created
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1
# queue item removed
2019-10-16 18:19:18 +00:00
testval = len ( [ name for name in os . listdir ( queuePath ) if os . path . isfile ( os . path . join ( queuePath , name ) ) ] )
print ( ' queuePath: ' + queuePath + ' ' + str ( testval ) )
assert testval == 0
2019-07-18 09:31:29 +00:00
assert validInbox ( bobDir , ' bob ' , bobDomain )
2019-07-18 11:35:48 +00:00
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
2019-11-09 09:50:58 +00:00
print ( ' Check that message received from Alice contains the expected text ' )
for name in os . listdir ( inboxPath ) :
filename = os . path . join ( inboxPath , name )
assert os . path . isfile ( filename )
2019-11-09 09:52:09 +00:00
receivedJson = None
2019-11-09 09:50:58 +00:00
with open ( filename , ' r ' ) as fp :
receivedJson = commentjson . load ( fp )
pprint ( receivedJson [ ' object ' ] [ ' content ' ] )
2019-11-09 09:52:09 +00:00
assert receivedJson
assert ' Why is a mouse when it spins? ' in receivedJson [ ' object ' ] [ ' content ' ]
assert ' यह एक परीक्षण है ' in receivedJson [ ' object ' ] [ ' content ' ]
2019-07-11 12:59:00 +00:00
print ( ' \n \n ******************************************************* ' )
print ( " Bob likes Alice ' s post " )
2019-07-13 09:37:17 +00:00
followerOfPerson ( bobDir , ' bob ' , bobDomain , ' alice ' , \
2019-07-14 17:19:00 +00:00
aliceDomain + ' : ' + str ( alicePort ) , federationList , False )
2019-07-13 09:37:17 +00:00
followPerson ( aliceDir , ' alice ' , aliceDomain , ' bob ' , \
2019-07-14 17:19:00 +00:00
bobDomain + ' : ' + str ( bobPort ) , federationList , False )
2019-07-11 12:59:00 +00:00
sessionBob = createSession ( bobDomain , bobPort , useTor )
bobPostLog = [ ]
bobPersonCache = { }
bobCachedWebfingers = { }
statusNumber = None
outboxPostFilename = None
outboxPath = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /outbox '
for name in os . listdir ( outboxPath ) :
if ' #statuses# ' in name :
statusNumber = int ( name . split ( ' #statuses# ' ) [ 1 ] . replace ( ' .json ' , ' ' ) )
outboxPostFilename = outboxPath + ' / ' + name
2019-07-11 17:55:10 +00:00
assert statusNumber > 0
2019-07-11 12:59:00 +00:00
assert outboxPostFilename
assert likePost ( sessionBob , bobDir , federationList , \
' bob ' , bobDomain , bobPort , httpPrefix , \
' alice ' , aliceDomain , alicePort , [ ] , \
statusNumber , False , bobSendThreads , bobPostLog , \
2019-08-14 20:12:27 +00:00
bobPersonCache , bobCachedWebfingers , \
True , __version__ )
2019-07-11 12:59:00 +00:00
for i in range ( 20 ) :
if ' likes ' in open ( outboxPostFilename ) . read ( ) :
break
time . sleep ( 1 )
with open ( outboxPostFilename , ' r ' ) as fp :
alicePostJson = commentjson . load ( fp )
pprint ( alicePostJson )
2019-09-30 22:39:02 +00:00
2019-07-11 12:59:00 +00:00
assert ' likes ' in open ( outboxPostFilename ) . read ( )
2019-07-11 17:55:10 +00:00
print ( ' \n \n ******************************************************* ' )
print ( " Bob repeats Alice ' s post " )
objectUrl = httpPrefix + ' :// ' + aliceDomain + ' : ' + str ( alicePort ) + ' /users/alice/statuses/ ' + str ( statusNumber )
2019-07-11 19:31:02 +00:00
inboxPath = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /inbox '
2019-07-11 19:34:00 +00:00
outboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /outbox '
outboxBeforeAnnounceCount = len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] )
2019-07-11 19:31:02 +00:00
beforeAnnounceCount = len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] )
assert beforeAnnounceCount == 0
print ( ' inbox items before announce: ' + str ( beforeAnnounceCount ) )
2019-07-11 17:55:10 +00:00
announcePublic ( sessionBob , bobDir , federationList , \
' bob ' , bobDomain , bobPort , httpPrefix , \
objectUrl , \
False , bobSendThreads , bobPostLog , \
bobPersonCache , bobCachedWebfingers , \
2019-08-14 20:12:27 +00:00
True , __version__ )
2019-07-11 19:31:02 +00:00
announceMessageArrived = False
for i in range ( 10 ) :
time . sleep ( 1 )
if os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) > 0 :
announceMessageArrived = True
print ( ' Announce message sent to Alice! ' )
break
afterAnnounceCount = len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] )
2019-07-11 19:34:00 +00:00
outboxAfterAnnounceCount = len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] )
2019-07-11 19:31:02 +00:00
print ( ' inbox items after announce: ' + str ( afterAnnounceCount ) )
assert afterAnnounceCount == beforeAnnounceCount + 1
2019-07-11 19:34:00 +00:00
assert outboxAfterAnnounceCount == outboxBeforeAnnounceCount + 1
2019-06-30 21:20:02 +00:00
# stop the servers
thrAlice . kill ( )
thrAlice . join ( )
assert thrAlice . isAlive ( ) == False
thrBob . kill ( )
thrBob . join ( )
assert thrBob . isAlive ( ) == False
2019-07-05 12:35:29 +00:00
os . chdir ( baseDir )
shutil . rmtree ( aliceDir )
shutil . rmtree ( bobDir )
2019-10-15 09:31:10 +00:00
def testFollowBetweenServersWithCapabilities ( ) :
2019-07-06 13:49:25 +00:00
print ( ' Testing sending a follow request from one server to another ' )
global testServerAliceRunning
global testServerBobRunning
2019-07-07 19:25:38 +00:00
global testServerEveRunning
2019-07-06 13:49:25 +00:00
testServerAliceRunning = False
testServerBobRunning = False
2019-07-07 19:25:38 +00:00
testServerEveRunning = False
2019-07-06 13:49:25 +00:00
httpPrefix = ' http '
useTor = False
2019-07-07 19:25:38 +00:00
federationList = [ ]
2019-07-06 13:49:25 +00:00
baseDir = os . getcwd ( )
if os . path . isdir ( baseDir + ' /.tests ' ) :
shutil . rmtree ( baseDir + ' /.tests ' )
os . mkdir ( baseDir + ' /.tests ' )
2019-07-07 17:47:37 +00:00
ocapAlways = True
2019-07-06 13:49:25 +00:00
# create the servers
aliceDir = baseDir + ' /.tests/alice '
aliceDomain = ' 127.0.0.42 '
alicePort = 61935
2019-10-16 18:19:18 +00:00
aliceSendThreads = [ ]
2019-07-13 09:37:17 +00:00
thrAlice = \
threadWithTrace ( target = createServerAlice , \
args = ( aliceDir , aliceDomain , alicePort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , aliceSendThreads ) , daemon = True )
2019-07-06 13:49:25 +00:00
bobDir = baseDir + ' /.tests/bob '
bobDomain = ' 127.0.0.64 '
bobPort = 61936
2019-10-16 18:19:18 +00:00
bobSendThreads = [ ]
2019-07-13 09:37:17 +00:00
thrBob = \
threadWithTrace ( target = createServerBob , \
args = ( bobDir , bobDomain , bobPort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , bobSendThreads ) , daemon = True )
2019-07-06 13:49:25 +00:00
2019-07-07 19:25:38 +00:00
eveDir = baseDir + ' /.tests/eve '
eveDomain = ' 127.0.0.55 '
evePort = 61937
2019-10-16 18:19:18 +00:00
eveSendThreads = [ ]
2019-07-13 09:37:17 +00:00
thrEve = \
threadWithTrace ( target = createServerEve , \
args = ( eveDir , eveDomain , evePort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
False , eveSendThreads ) , daemon = True )
2019-07-07 19:25:38 +00:00
2019-07-06 13:49:25 +00:00
thrAlice . start ( )
thrBob . start ( )
2019-07-07 19:25:38 +00:00
thrEve . start ( )
2019-07-06 13:49:25 +00:00
assert thrAlice . isAlive ( ) == True
assert thrBob . isAlive ( ) == True
2019-07-07 19:25:38 +00:00
assert thrEve . isAlive ( ) == True
2019-07-06 13:49:25 +00:00
2019-07-07 22:38:35 +00:00
# wait for all servers to be running
2019-07-07 19:25:38 +00:00
ctr = 0
while not ( testServerAliceRunning and testServerBobRunning and testServerEveRunning ) :
2019-07-06 13:49:25 +00:00
time . sleep ( 1 )
2019-07-07 19:25:38 +00:00
ctr + = 1
2019-07-07 22:29:47 +00:00
if ctr > 60 :
2019-07-07 19:25:38 +00:00
break
print ( ' Alice online: ' + str ( testServerAliceRunning ) )
print ( ' Bob online: ' + str ( testServerBobRunning ) )
print ( ' Eve online: ' + str ( testServerEveRunning ) )
2019-07-07 22:29:47 +00:00
assert ctr < = 60
2019-07-06 13:49:25 +00:00
time . sleep ( 1 )
# In the beginning all was calm and there were no follows
2019-07-09 14:20:23 +00:00
print ( ' ********************************************************* ' )
2019-07-06 13:49:25 +00:00
print ( ' Alice sends a follow request to Bob ' )
2019-07-07 19:25:38 +00:00
print ( ' Both are strictly enforcing object capabilities ' )
2019-07-06 13:49:25 +00:00
os . chdir ( aliceDir )
sessionAlice = createSession ( aliceDomain , alicePort , useTor )
inReplyTo = None
inReplyToAtomUri = None
subject = None
alicePostLog = [ ]
followersOnly = False
saveToFile = True
clientToServer = False
ccUrl = None
alicePersonCache = { }
aliceCachedWebfingers = { }
alicePostLog = [ ]
sendResult = \
sendFollowRequest ( sessionAlice , aliceDir , \
' alice ' , aliceDomain , alicePort , httpPrefix , \
' bob ' , bobDomain , bobPort , httpPrefix , \
2019-07-09 15:51:31 +00:00
clientToServer , federationList , \
2019-07-06 13:49:25 +00:00
aliceSendThreads , alicePostLog , \
2019-08-14 20:12:27 +00:00
aliceCachedWebfingers , alicePersonCache , \
True , __version__ )
2019-07-06 13:49:25 +00:00
print ( ' sendResult: ' + str ( sendResult ) )
2019-07-09 14:20:23 +00:00
bobCapsFilename = bobDir + ' /accounts/bob@ ' + bobDomain + ' /ocap/accept/ ' + httpPrefix + ' :## ' + aliceDomain + ' : ' + str ( alicePort ) + ' #users#alice.json '
aliceCapsFilename = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /ocap/granted/ ' + httpPrefix + ' :## ' + bobDomain + ' : ' + str ( bobPort ) + ' #users#bob.json '
2019-07-06 17:15:03 +00:00
for t in range ( 10 ) :
if os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) :
2019-07-06 19:24:52 +00:00
if os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) :
2019-07-09 14:20:23 +00:00
if os . path . isfile ( bobCapsFilename ) :
if os . path . isfile ( aliceCapsFilename ) :
2019-07-07 16:06:38 +00:00
break
2019-07-06 17:15:03 +00:00
time . sleep ( 1 )
2019-07-09 14:20:23 +00:00
with open ( bobCapsFilename , ' r ' ) as fp :
bobCapsJson = commentjson . load ( fp )
if not bobCapsJson . get ( ' capability ' ) :
print ( " Unexpected format for Bob ' s capabilities " )
pprint ( bobCapsJson )
assert False
2019-07-18 09:31:29 +00:00
assert validInbox ( bobDir , ' bob ' , bobDomain )
2019-07-18 11:35:48 +00:00
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
2019-07-08 16:49:12 +00:00
2019-07-09 14:20:23 +00:00
print ( ' \n \n ********************************************************* ' )
print ( ' Eve tries to send to Bob ' )
2019-07-07 19:25:38 +00:00
sessionEve = createSession ( eveDomain , evePort , useTor )
evePostLog = [ ]
evePersonCache = { }
eveCachedWebfingers = { }
evePostLog = [ ]
2019-07-12 19:08:46 +00:00
useBlurhash = False
2019-07-13 09:37:17 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPost ( __version__ , \
sessionEve , eveDir , ' eve ' , eveDomain , evePort , \
2019-07-13 09:37:17 +00:00
' bob ' , bobDomain , bobPort , ccUrl , \
httpPrefix , ' Eve message ' , followersOnly , \
2019-08-30 15:50:20 +00:00
saveToFile , clientToServer , None , None , None , \
2019-07-13 09:37:17 +00:00
useBlurhash , federationList , eveSendThreads , \
evePostLog , eveCachedWebfingers , \
evePersonCache , inReplyTo , inReplyToAtomUri , subject )
2019-07-07 19:25:38 +00:00
print ( ' sendResult: ' + str ( sendResult ) )
queuePath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /queue '
inboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /inbox '
eveMessageArrived = False
2019-07-07 22:58:12 +00:00
for i in range ( 10 ) :
2019-07-07 19:25:38 +00:00
time . sleep ( 1 )
if os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) > 1 :
eveMessageArrived = True
print ( ' Eve message sent to Bob! ' )
break
# capabilities should have prevented delivery
assert eveMessageArrived == False
print ( ' Message from Eve to Bob was correctly rejected by object capabilities ' )
2019-07-09 14:20:23 +00:00
print ( ' \n \n ********************************************************* ' )
print ( ' Alice sends a message to Bob ' )
2019-07-07 19:25:38 +00:00
alicePostLog = [ ]
alicePersonCache = { }
aliceCachedWebfingers = { }
alicePostLog = [ ]
2019-07-12 19:08:46 +00:00
useBlurhash = False
2019-07-13 09:37:17 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPost ( __version__ , \
sessionAlice , aliceDir , ' alice ' , aliceDomain , alicePort , \
2019-07-13 09:37:17 +00:00
' bob ' , bobDomain , bobPort , ccUrl , \
httpPrefix , ' Alice message ' , followersOnly , saveToFile , \
2019-08-30 15:50:20 +00:00
clientToServer , None , None , None , useBlurhash , federationList , \
2019-07-13 09:37:17 +00:00
aliceSendThreads , alicePostLog , aliceCachedWebfingers , \
alicePersonCache , inReplyTo , inReplyToAtomUri , subject )
2019-07-07 19:25:38 +00:00
print ( ' sendResult: ' + str ( sendResult ) )
queuePath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /queue '
inboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /inbox '
2019-07-08 23:05:48 +00:00
aliceMessageArrived = False
2019-07-07 22:26:15 +00:00
for i in range ( 20 ) :
2019-07-07 19:25:38 +00:00
time . sleep ( 1 )
if os . path . isdir ( inboxPath ) :
2019-07-08 23:05:48 +00:00
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) > 0 :
2019-07-07 19:25:38 +00:00
aliceMessageArrived = True
print ( ' Alice message sent to Bob! ' )
break
assert aliceMessageArrived == True
print ( ' Message from Alice to Bob succeeded, since it was granted capabilities ' )
2019-07-13 09:37:17 +00:00
2019-07-09 14:20:23 +00:00
print ( ' \n \n ********************************************************* ' )
print ( " \n Bob changes Alice ' s capabilities so that she can ' t reply on his posts " )
2019-07-13 09:37:17 +00:00
bobCapsFilename = \
bobDir + ' /accounts/bob@ ' + bobDomain + ' /ocap/accept/ ' + \
httpPrefix + ' :## ' + aliceDomain + ' : ' + str ( alicePort ) + ' #users#alice.json '
aliceCapsFilename = \
aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /ocap/granted/ ' + \
httpPrefix + ' :## ' + bobDomain + ' : ' + str ( bobPort ) + ' #users#bob.json '
2019-07-09 14:20:23 +00:00
sessionBob = createSession ( bobDomain , bobPort , useTor )
bobPostLog = [ ]
bobPersonCache = { }
bobCachedWebfingers = { }
print ( " Bob ' s capabilities for Alice: " )
with open ( bobCapsFilename , ' r ' ) as fp :
bobCapsJson = commentjson . load ( fp )
pprint ( bobCapsJson )
assert " inbox:noreply " not in bobCapsJson [ ' capability ' ]
print ( " Alice ' s capabilities granted by Bob " )
with open ( aliceCapsFilename , ' r ' ) as fp :
aliceCapsJson = commentjson . load ( fp )
pprint ( aliceCapsJson )
assert " inbox:noreply " not in aliceCapsJson [ ' capability ' ]
newCapabilities = [ " inbox:write " , " objects:read " , " inbox:noreply " ]
sendCapabilitiesUpdate ( sessionBob , bobDir , httpPrefix , \
' bob ' , bobDomain , bobPort , \
2019-07-13 09:37:17 +00:00
httpPrefix + ' :// ' + aliceDomain + ' : ' + \
str ( alicePort ) + ' /users/alice ' ,
2019-07-09 14:20:23 +00:00
newCapabilities , \
bobSendThreads , bobPostLog , \
bobCachedWebfingers , bobPersonCache , \
2019-08-14 20:12:27 +00:00
federationList , True , __version__ )
2019-07-09 14:20:23 +00:00
bobChanged = False
bobNewCapsJson = None
for i in range ( 20 ) :
time . sleep ( 1 )
with open ( bobCapsFilename , ' r ' ) as fp :
bobNewCapsJson = commentjson . load ( fp )
if " inbox:noreply " in bobNewCapsJson [ ' capability ' ] :
print ( " Bob ' s capabilities were changed " )
pprint ( bobNewCapsJson )
bobChanged = True
break
assert bobChanged
aliceChanged = False
aliceNewCapsJson = None
for i in range ( 20 ) :
time . sleep ( 1 )
with open ( aliceCapsFilename , ' r ' ) as fp :
aliceNewCapsJson = commentjson . load ( fp )
if " inbox:noreply " in aliceNewCapsJson [ ' capability ' ] :
print ( " Alice ' s granted capabilities were changed " )
pprint ( aliceNewCapsJson )
aliceChanged = True
break
assert aliceChanged
# check that the capabilities id has changed
assert bobNewCapsJson [ ' id ' ] != bobCapsJson [ ' id ' ]
assert aliceNewCapsJson [ ' id ' ] != aliceCapsJson [ ' id ' ]
2019-07-06 13:49:25 +00:00
# stop the servers
thrAlice . kill ( )
thrAlice . join ( )
assert thrAlice . isAlive ( ) == False
thrBob . kill ( )
thrBob . join ( )
assert thrBob . isAlive ( ) == False
2019-07-07 22:38:35 +00:00
thrEve . kill ( )
thrEve . join ( )
assert thrEve . isAlive ( ) == False
2019-07-07 19:25:38 +00:00
2019-07-13 09:37:17 +00:00
assert os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + \
' /ocap/accept/ ' + httpPrefix + ' :## ' + \
aliceDomain + ' : ' + str ( alicePort ) + \
' #users#alice.json ' )
assert os . path . isfile ( aliceDir + ' /accounts/alice@ ' + \
aliceDomain + ' /ocap/granted/ ' + \
httpPrefix + ' :## ' + bobDomain + ' : ' + \
str ( bobPort ) + ' #users#bob.json ' )
2019-07-07 16:33:59 +00:00
2019-07-06 17:15:03 +00:00
assert ' alice@ ' + aliceDomain in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) . read ( )
2019-10-15 09:31:10 +00:00
assert ' bob@ ' + bobDomain in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) . read ( )
# queue item removed
assert len ( [ name for name in os . listdir ( queuePath ) if os . path . isfile ( os . path . join ( queuePath , name ) ) ] ) == 0
os . chdir ( baseDir )
shutil . rmtree ( baseDir + ' /.tests ' )
def testFollowBetweenServers ( ) :
print ( ' Testing sending a follow request from one server to another ' )
global testServerAliceRunning
global testServerBobRunning
testServerAliceRunning = False
testServerBobRunning = False
httpPrefix = ' http '
useTor = False
federationList = [ ]
baseDir = os . getcwd ( )
if os . path . isdir ( baseDir + ' /.tests ' ) :
shutil . rmtree ( baseDir + ' /.tests ' )
os . mkdir ( baseDir + ' /.tests ' )
ocapAlways = False
# create the servers
aliceDir = baseDir + ' /.tests/alice '
aliceDomain = ' 127.0.0.42 '
alicePort = 61935
2019-10-16 18:19:18 +00:00
aliceSendThreads = [ ]
2019-10-15 09:31:10 +00:00
thrAlice = \
threadWithTrace ( target = createServerAlice , \
args = ( aliceDir , aliceDomain , alicePort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , aliceSendThreads ) , daemon = True )
2019-10-15 09:31:10 +00:00
bobDir = baseDir + ' /.tests/bob '
bobDomain = ' 127.0.0.64 '
bobPort = 61936
2019-10-16 18:19:18 +00:00
bobSendThreads = [ ]
2019-10-15 09:31:10 +00:00
thrBob = \
threadWithTrace ( target = createServerBob , \
args = ( bobDir , bobDomain , bobPort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , bobSendThreads ) , daemon = True )
2019-10-15 09:31:10 +00:00
thrAlice . start ( )
thrBob . start ( )
assert thrAlice . isAlive ( ) == True
assert thrBob . isAlive ( ) == True
# wait for all servers to be running
ctr = 0
while not ( testServerAliceRunning and testServerBobRunning ) :
time . sleep ( 1 )
ctr + = 1
if ctr > 60 :
break
print ( ' Alice online: ' + str ( testServerAliceRunning ) )
print ( ' Bob online: ' + str ( testServerBobRunning ) )
assert ctr < = 60
time . sleep ( 1 )
# In the beginning all was calm and there were no follows
print ( ' ********************************************************* ' )
print ( ' Alice sends a follow request to Bob ' )
os . chdir ( aliceDir )
sessionAlice = createSession ( aliceDomain , alicePort , useTor )
inReplyTo = None
inReplyToAtomUri = None
subject = None
alicePostLog = [ ]
followersOnly = False
saveToFile = True
clientToServer = False
ccUrl = None
alicePersonCache = { }
aliceCachedWebfingers = { }
alicePostLog = [ ]
sendResult = \
sendFollowRequest ( sessionAlice , aliceDir , \
' alice ' , aliceDomain , alicePort , httpPrefix , \
' bob ' , bobDomain , bobPort , httpPrefix , \
clientToServer , federationList , \
aliceSendThreads , alicePostLog , \
aliceCachedWebfingers , alicePersonCache , \
True , __version__ )
print ( ' sendResult: ' + str ( sendResult ) )
for t in range ( 10 ) :
if os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) :
if os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) :
break
time . sleep ( 1 )
assert validInbox ( bobDir , ' bob ' , bobDomain )
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
print ( ' \n \n ********************************************************* ' )
print ( ' Alice sends a message to Bob ' )
alicePostLog = [ ]
alicePersonCache = { }
aliceCachedWebfingers = { }
alicePostLog = [ ]
useBlurhash = False
sendResult = \
sendPost ( __version__ , \
sessionAlice , aliceDir , ' alice ' , aliceDomain , alicePort , \
' bob ' , bobDomain , bobPort , ccUrl , \
httpPrefix , ' Alice message ' , followersOnly , saveToFile , \
clientToServer , None , None , None , useBlurhash , federationList , \
aliceSendThreads , alicePostLog , aliceCachedWebfingers , \
alicePersonCache , inReplyTo , inReplyToAtomUri , subject )
print ( ' sendResult: ' + str ( sendResult ) )
queuePath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /queue '
inboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /inbox '
aliceMessageArrived = False
for i in range ( 20 ) :
time . sleep ( 1 )
if os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) > 0 :
aliceMessageArrived = True
print ( ' Alice message sent to Bob! ' )
break
assert aliceMessageArrived == True
print ( ' Message from Alice to Bob succeeded ' )
# stop the servers
thrAlice . kill ( )
thrAlice . join ( )
assert thrAlice . isAlive ( ) == False
thrBob . kill ( )
thrBob . join ( )
assert thrBob . isAlive ( ) == False
assert ' alice@ ' + aliceDomain in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) . read ( )
2019-07-06 17:15:03 +00:00
assert ' bob@ ' + bobDomain in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) . read ( )
2019-07-09 08:52:53 +00:00
# queue item removed
2019-11-09 21:39:04 +00:00
time . sleep ( 4 )
2019-07-09 08:52:53 +00:00
assert len ( [ name for name in os . listdir ( queuePath ) if os . path . isfile ( os . path . join ( queuePath , name ) ) ] ) == 0
2019-07-06 17:15:03 +00:00
2019-07-06 13:49:25 +00:00
os . chdir ( baseDir )
2019-07-08 23:05:48 +00:00
shutil . rmtree ( baseDir + ' /.tests ' )
2019-07-06 13:49:25 +00:00
2019-07-05 12:35:29 +00:00
def testFollowersOfPerson ( ) :
print ( ' testFollowersOfPerson ' )
currDir = os . getcwd ( )
nickname = ' mxpop '
domain = ' diva.domain '
password = ' birb '
port = 80
httpPrefix = ' https '
federationList = [ ]
baseDir = currDir + ' /.tests_followersofperson '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
os . chdir ( baseDir )
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , password )
createPerson ( baseDir , ' maxboardroom ' , domain , port , httpPrefix , True , password )
createPerson ( baseDir , ' ultrapancake ' , domain , port , httpPrefix , True , password )
createPerson ( baseDir , ' drokk ' , domain , port , httpPrefix , True , password )
createPerson ( baseDir , ' sausagedog ' , domain , port , httpPrefix , True , password )
clearFollows ( baseDir , nickname , domain )
2019-07-14 17:19:00 +00:00
followPerson ( baseDir , nickname , domain , ' maxboardroom ' , domain , federationList , False )
followPerson ( baseDir , ' drokk ' , domain , ' ultrapancake ' , domain , federationList , False )
2019-07-05 12:35:29 +00:00
# deliberate duplication
2019-07-14 17:19:00 +00:00
followPerson ( baseDir , ' drokk ' , domain , ' ultrapancake ' , domain , federationList , False )
followPerson ( baseDir , ' sausagedog ' , domain , ' ultrapancake ' , domain , federationList , False )
followPerson ( baseDir , nickname , domain , ' ultrapancake ' , domain , federationList , False )
followPerson ( baseDir , nickname , domain , ' someother ' , ' randodomain.net ' , federationList , False )
2019-07-05 12:35:29 +00:00
followList = getFollowersOfPerson ( baseDir , ' ultrapancake ' , domain )
assert len ( followList ) == 3
assert ' mxpop@ ' + domain in followList
assert ' drokk@ ' + domain in followList
assert ' sausagedog@ ' + domain in followList
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-05 14:25:15 +00:00
def testNoOfFollowersOnDomain ( ) :
print ( ' testNoOfFollowersOnDomain ' )
currDir = os . getcwd ( )
nickname = ' mxpop '
domain = ' diva.domain '
otherdomain = ' soup.dragon '
password = ' birb '
port = 80
httpPrefix = ' https '
federationList = [ ]
baseDir = currDir + ' /.tests_nooffollowersOndomain '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
os . chdir ( baseDir )
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , password )
createPerson ( baseDir , ' maxboardroom ' , otherdomain , port , httpPrefix , True , password )
createPerson ( baseDir , ' ultrapancake ' , otherdomain , port , httpPrefix , True , password )
createPerson ( baseDir , ' drokk ' , otherdomain , port , httpPrefix , True , password )
createPerson ( baseDir , ' sausagedog ' , otherdomain , port , httpPrefix , True , password )
2019-07-14 17:19:00 +00:00
followPerson ( baseDir , ' drokk ' , otherdomain , nickname , domain , federationList , False )
followPerson ( baseDir , ' sausagedog ' , otherdomain , nickname , domain , federationList , False )
followPerson ( baseDir , ' maxboardroom ' , otherdomain , nickname , domain , federationList , False )
2019-07-05 12:35:29 +00:00
2019-07-14 17:19:00 +00:00
followerOfPerson ( baseDir , nickname , domain , ' cucumber ' , ' sandwiches.party ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' captainsensible ' , ' damned.zone ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' pilchard ' , ' zombies.attack ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' drokk ' , otherdomain , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' sausagedog ' , otherdomain , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' maxboardroom ' , otherdomain , federationList , False )
2019-07-05 14:25:15 +00:00
followersOnOtherDomain = noOfFollowersOnDomain ( baseDir , nickname + ' @ ' + domain , otherdomain )
assert followersOnOtherDomain == 3
unfollowerOfPerson ( baseDir , nickname , domain , ' sausagedog ' , otherdomain )
followersOnOtherDomain = noOfFollowersOnDomain ( baseDir , nickname + ' @ ' + domain , otherdomain )
assert followersOnOtherDomain == 2
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-08 08:51:33 +00:00
def testGroupFollowers ( ) :
print ( ' testGroupFollowers ' )
currDir = os . getcwd ( )
nickname = ' test735 '
domain = ' mydomain.com '
password = ' somepass '
port = 80
httpPrefix = ' https '
federationList = [ ]
baseDir = currDir + ' /.tests_testgroupfollowers '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
os . chdir ( baseDir )
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , password )
clearFollowers ( baseDir , nickname , domain )
followerOfPerson ( baseDir , nickname , domain , ' badger ' , ' wild.domain ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' squirrel ' , ' wild.domain ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' rodent ' , ' wild.domain ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' utterly ' , ' clutterly.domain ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' zonked ' , ' zzz.domain ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' nap ' , ' zzz.domain ' , federationList , False )
grouped = groupFollowersByDomain ( baseDir , nickname , domain )
assert len ( grouped . items ( ) ) == 3
assert grouped . get ( ' zzz.domain ' )
assert grouped . get ( ' clutterly.domain ' )
assert grouped . get ( ' wild.domain ' )
assert len ( grouped [ ' zzz.domain ' ] ) == 2
assert len ( grouped [ ' wild.domain ' ] ) == 3
assert len ( grouped [ ' clutterly.domain ' ] ) == 1
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-03 09:24:55 +00:00
def testFollows ( ) :
2019-07-03 10:04:23 +00:00
print ( ' testFollows ' )
2019-07-03 09:24:55 +00:00
currDir = os . getcwd ( )
2019-07-03 09:40:27 +00:00
nickname = ' test529 '
2019-07-03 09:24:55 +00:00
domain = ' testdomain.com '
2019-07-04 19:09:48 +00:00
password = ' mypass '
2019-07-03 09:24:55 +00:00
port = 80
2019-07-03 19:00:03 +00:00
httpPrefix = ' https '
2019-07-03 09:24:55 +00:00
federationList = [ ' wild.com ' , ' mesh.com ' ]
baseDir = currDir + ' /.tests_testfollows '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
2019-07-04 19:09:48 +00:00
os . chdir ( baseDir )
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , password )
2019-07-03 09:24:55 +00:00
2019-07-03 09:40:27 +00:00
clearFollows ( baseDir , nickname , domain )
2019-07-06 19:24:52 +00:00
followPerson ( baseDir , nickname , domain , ' badger ' , ' wild.com ' , federationList , False )
followPerson ( baseDir , nickname , domain , ' squirrel ' , ' secret.com ' , federationList , False )
followPerson ( baseDir , nickname , domain , ' rodent ' , ' drainpipe.com ' , federationList , False )
followPerson ( baseDir , nickname , domain , ' batman ' , ' mesh.com ' , federationList , False )
followPerson ( baseDir , nickname , domain , ' giraffe ' , ' trees.com ' , federationList , False )
2019-07-03 09:24:55 +00:00
2019-07-03 09:40:27 +00:00
f = open ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' /following.txt ' , " r " )
2019-07-03 09:33:28 +00:00
domainFound = False
2019-07-03 09:24:55 +00:00
for followingDomain in f :
testDomain = followingDomain . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' )
2019-07-03 09:33:28 +00:00
if testDomain == ' mesh.com ' :
domainFound = True
2019-07-03 09:24:55 +00:00
if testDomain not in federationList :
print ( testDomain )
assert ( False )
2019-07-03 09:33:28 +00:00
assert ( domainFound )
2019-07-03 09:40:27 +00:00
unfollowPerson ( baseDir , nickname , domain , ' batman ' , ' mesh.com ' )
2019-07-03 09:33:28 +00:00
domainFound = False
for followingDomain in f :
testDomain = followingDomain . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' )
if testDomain == ' mesh.com ' :
domainFound = True
assert ( domainFound == False )
2019-07-03 09:40:27 +00:00
clearFollowers ( baseDir , nickname , domain )
2019-07-06 19:24:52 +00:00
followerOfPerson ( baseDir , nickname , domain , ' badger ' , ' wild.com ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' squirrel ' , ' secret.com ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' rodent ' , ' drainpipe.com ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' batman ' , ' mesh.com ' , federationList , False )
followerOfPerson ( baseDir , nickname , domain , ' giraffe ' , ' trees.com ' , federationList , False )
2019-07-03 09:24:55 +00:00
2019-07-03 09:40:27 +00:00
f = open ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' /followers.txt ' , " r " )
2019-07-03 09:24:55 +00:00
for followerDomain in f :
testDomain = followerDomain . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' )
if testDomain not in federationList :
print ( testDomain )
assert ( False )
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-03 10:04:23 +00:00
def testCreatePerson ( ) :
print ( ' testCreatePerson ' )
currDir = os . getcwd ( )
nickname = ' test382 '
domain = ' badgerdomain.com '
2019-07-04 19:09:48 +00:00
password = ' mypass '
2019-07-03 10:04:23 +00:00
port = 80
2019-07-03 19:00:03 +00:00
httpPrefix = ' https '
2019-07-03 15:10:18 +00:00
clientToServer = False
2019-07-12 19:08:46 +00:00
useBlurhash = False
2019-07-03 10:04:23 +00:00
baseDir = currDir + ' /.tests_createperson '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
os . chdir ( baseDir )
2019-07-03 09:24:55 +00:00
2019-07-04 19:09:48 +00:00
privateKeyPem , publicKeyPem , person , wfEndpoint = createPerson ( baseDir , nickname , domain , port , httpPrefix , True , password )
assert os . path . isfile ( baseDir + ' /accounts/passwords ' )
2019-07-04 16:24:23 +00:00
deleteAllPosts ( baseDir , nickname , domain , ' inbox ' )
deleteAllPosts ( baseDir , nickname , domain , ' outbox ' )
2019-08-22 18:36:07 +00:00
setDisplayNickname ( baseDir , nickname , domain , ' badger ' )
2019-07-03 10:04:23 +00:00
setBio ( baseDir , nickname , domain , ' Randomly roaming in your backyard ' )
2019-07-12 20:43:55 +00:00
archivePostsForPerson ( nickname , domain , baseDir , ' inbox ' , None , 4 )
archivePostsForPerson ( nickname , domain , baseDir , ' outbox ' , None , 4 )
2019-07-12 19:08:46 +00:00
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " G ' day world! " , False , True , clientToServer , None , None , useBlurhash , None , None , ' Not suitable for Vogons ' )
2019-07-03 10:04:23 +00:00
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-18 16:21:26 +00:00
def testDelegateRoles ( ) :
print ( ' testDelegateRoles ' )
currDir = os . getcwd ( )
nickname = ' test382 '
nicknameDelegated = ' test383 '
domain = ' badgerdomain.com '
password = ' mypass '
port = 80
httpPrefix = ' https '
clientToServer = False
useBlurhash = False
baseDir = currDir + ' /.tests_delegaterole '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
os . chdir ( baseDir )
privateKeyPem , publicKeyPem , person , wfEndpoint = createPerson ( baseDir , nickname , domain , port , httpPrefix , True , password )
privateKeyPem , publicKeyPem , person , wfEndpoint = createPerson ( baseDir , nicknameDelegated , domain , port , httpPrefix , True , ' insecure ' )
httpPrefix = ' http '
project = ' artechoke '
role = ' delegator '
newRoleJson = {
' type ' : ' Delegate ' ,
' actor ' : httpPrefix + ' :// ' + domain + ' /users/ ' + nickname ,
' object ' : {
' type ' : ' Role ' ,
' actor ' : httpPrefix + ' :// ' + domain + ' /users/ ' + nicknameDelegated ,
' object ' : project + ' ; ' + role ,
' to ' : [ ] ,
' cc ' : [ ]
} ,
' to ' : [ ] ,
' cc ' : [ ]
}
2019-07-19 10:01:24 +00:00
assert outboxDelegate ( baseDir , nickname , newRoleJson , False )
2019-07-18 16:21:26 +00:00
# second time delegation has already happened so should return false
2019-07-19 10:01:24 +00:00
assert outboxDelegate ( baseDir , nickname , newRoleJson , False ) == False
2019-07-18 16:21:26 +00:00
assert ' " delegator " ' in open ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' .json ' ) . read ( )
assert ' " delegator " ' in open ( baseDir + ' /accounts/ ' + nicknameDelegated + ' @ ' + domain + ' .json ' ) . read ( )
newRoleJson = {
' type ' : ' Delegate ' ,
' actor ' : httpPrefix + ' :// ' + domain + ' /users/ ' + nicknameDelegated ,
' object ' : {
' type ' : ' Role ' ,
' actor ' : httpPrefix + ' :// ' + domain + ' /users/ ' + nickname ,
' object ' : ' otherproject;otherrole ' ,
' to ' : [ ] ,
' cc ' : [ ]
} ,
' to ' : [ ] ,
' cc ' : [ ]
}
# non-delegators cannot assign roles
2019-07-19 10:01:24 +00:00
assert outboxDelegate ( baseDir , nicknameDelegated , newRoleJson , False ) == False
2019-07-18 16:21:26 +00:00
assert ' " otherrole " ' not in open ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' .json ' ) . read ( )
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-03 18:24:44 +00:00
def testAuthentication ( ) :
print ( ' testAuthentication ' )
currDir = os . getcwd ( )
nickname = ' test8743 '
password = ' SuperSecretPassword12345 '
baseDir = currDir + ' /.tests_authentication '
if os . path . isdir ( baseDir ) :
shutil . rmtree ( baseDir )
os . mkdir ( baseDir )
os . chdir ( baseDir )
assert storeBasicCredentials ( baseDir , ' othernick ' , ' otherpass ' )
assert storeBasicCredentials ( baseDir , ' bad:nick ' , ' otherpass ' ) == False
assert storeBasicCredentials ( baseDir , ' badnick ' , ' otherpa:ss ' ) == False
assert storeBasicCredentials ( baseDir , nickname , password )
authHeader = createBasicAuthHeader ( nickname , password )
2019-07-04 08:56:15 +00:00
assert authorizeBasic ( baseDir , ' /users/ ' + nickname + ' /inbox ' , authHeader , False )
assert authorizeBasic ( baseDir , ' /users/ ' + nickname , authHeader , False ) == False
assert authorizeBasic ( baseDir , ' /users/othernick/inbox ' , authHeader , False ) == False
2019-07-03 18:24:44 +00:00
authHeader = createBasicAuthHeader ( nickname , password + ' 1 ' )
2019-07-04 08:56:15 +00:00
assert authorizeBasic ( baseDir , ' /users/ ' + nickname + ' /inbox ' , authHeader , False ) == False
2019-07-03 18:24:44 +00:00
2019-07-03 19:13:23 +00:00
password = ' someOtherPassword '
assert storeBasicCredentials ( baseDir , nickname , password )
authHeader = createBasicAuthHeader ( nickname , password )
2019-07-04 08:56:15 +00:00
assert authorizeBasic ( baseDir , ' /users/ ' + nickname + ' /inbox ' , authHeader , False )
2019-07-03 19:13:23 +00:00
2019-07-03 18:24:44 +00:00
os . chdir ( currDir )
shutil . rmtree ( baseDir )
2019-07-16 10:19:04 +00:00
def testClientToServer ( ) :
print ( ' Testing sending a post via c2s ' )
global testServerAliceRunning
global testServerBobRunning
testServerAliceRunning = False
testServerBobRunning = False
httpPrefix = ' http '
useTor = False
federationList = [ ]
baseDir = os . getcwd ( )
if os . path . isdir ( baseDir + ' /.tests ' ) :
shutil . rmtree ( baseDir + ' /.tests ' )
os . mkdir ( baseDir + ' /.tests ' )
ocapAlways = False
# create the servers
aliceDir = baseDir + ' /.tests/alice '
aliceDomain = ' 127.0.0.42 '
alicePort = 61935
2019-10-16 18:19:18 +00:00
aliceSendThreads = [ ]
2019-07-16 10:19:04 +00:00
thrAlice = \
threadWithTrace ( target = createServerAlice , \
args = ( aliceDir , aliceDomain , alicePort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , aliceSendThreads ) , daemon = True )
2019-07-16 10:19:04 +00:00
bobDir = baseDir + ' /.tests/bob '
bobDomain = ' 127.0.0.64 '
bobPort = 61936
2019-10-16 18:19:18 +00:00
bobSendThreads = [ ]
2019-07-16 10:19:04 +00:00
thrBob = \
threadWithTrace ( target = createServerBob , \
args = ( bobDir , bobDomain , bobPort , \
federationList , False , False , \
2019-10-16 18:19:18 +00:00
ocapAlways , bobSendThreads ) , daemon = True )
2019-07-16 10:19:04 +00:00
thrAlice . start ( )
thrBob . start ( )
assert thrAlice . isAlive ( ) == True
assert thrBob . isAlive ( ) == True
# wait for both servers to be running
ctr = 0
while not ( testServerAliceRunning and testServerBobRunning ) :
time . sleep ( 1 )
ctr + = 1
if ctr > 60 :
break
print ( ' Alice online: ' + str ( testServerAliceRunning ) )
print ( ' Bob online: ' + str ( testServerBobRunning ) )
time . sleep ( 1 )
print ( ' \n \n ******************************************************* ' )
print ( ' Alice sends to Bob via c2s ' )
sessionAlice = createSession ( aliceDomain , alicePort , useTor )
followersOnly = False
2019-07-16 14:23:06 +00:00
attachedImageFilename = baseDir + ' /img/logo.png '
2019-08-30 15:50:20 +00:00
mediaType = getAttachmentMediaType ( attachedImageFilename )
2019-07-16 14:23:06 +00:00
attachedImageDescription = ' Logo '
2019-07-16 10:19:04 +00:00
useBlurhash = False
cachedWebfingers = { }
personCache = { }
password = ' alicepass '
outboxPath = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /outbox '
2019-07-16 11:33:40 +00:00
inboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /inbox '
2019-07-16 10:19:04 +00:00
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 0
2019-07-16 11:33:40 +00:00
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 0
2019-07-16 10:19:04 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPostViaServer ( __version__ , \
aliceDir , sessionAlice , ' alice ' , password , \
2019-07-16 10:19:04 +00:00
aliceDomain , alicePort , \
' bob ' , bobDomain , bobPort , None , \
httpPrefix , ' Sent from my ActivityPub client ' , followersOnly , \
2019-08-30 15:50:20 +00:00
attachedImageFilename , mediaType , \
attachedImageDescription , useBlurhash , \
2019-07-16 10:19:04 +00:00
cachedWebfingers , personCache , \
True , None , None , None )
print ( ' sendResult: ' + str ( sendResult ) )
for i in range ( 30 ) :
if os . path . isdir ( outboxPath ) :
if len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 1 :
break
time . sleep ( 1 )
2019-07-16 11:33:40 +00:00
2019-07-16 10:19:04 +00:00
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 1
2019-07-16 11:33:40 +00:00
print ( " >>> c2s post arrived in Alice ' s outbox " )
2019-07-16 19:07:45 +00:00
2019-07-16 11:33:40 +00:00
for i in range ( 30 ) :
if os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1 :
break
time . sleep ( 1 )
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1
print ( " >>> s2s post arrived in Bob ' s inbox " )
print ( " c2s send success " )
2019-07-16 19:07:45 +00:00
print ( ' \n \n Getting message id for the post ' )
statusNumber = 0
outboxPostFilename = None
outboxPostId = None
for name in os . listdir ( outboxPath ) :
if ' #statuses# ' in name :
statusNumber = int ( name . split ( ' #statuses# ' ) [ 1 ] . replace ( ' .json ' , ' ' ) . replace ( ' #activity ' , ' ' ) )
outboxPostFilename = outboxPath + ' / ' + name
with open ( outboxPostFilename , ' r ' ) as fp :
postJsonObject = commentjson . load ( fp )
outboxPostId = postJsonObject [ ' id ' ] . replace ( ' /activity ' , ' ' )
assert outboxPostId
print ( ' message id obtained: ' + outboxPostId )
2019-07-18 09:26:47 +00:00
assert validInbox ( bobDir , ' bob ' , bobDomain )
2019-07-18 11:35:48 +00:00
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
2019-07-16 21:38:06 +00:00
print ( ' \n \n Alice follows Bob ' )
2019-08-20 09:16:03 +00:00
sendFollowRequestViaServer ( aliceDir , sessionAlice , \
' alice ' , password , \
2019-07-16 21:38:06 +00:00
aliceDomain , alicePort , \
' bob ' , bobDomain , bobPort , \
httpPrefix , \
cachedWebfingers , personCache , \
2019-08-14 20:12:27 +00:00
True , __version__ )
2019-07-16 21:38:06 +00:00
for t in range ( 10 ) :
if os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) :
2019-07-17 11:28:19 +00:00
if ' alice@ ' + aliceDomain + ' : ' + str ( alicePort ) in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) . read ( ) :
2019-07-17 11:24:11 +00:00
if os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) :
2019-07-17 11:28:19 +00:00
if ' bob@ ' + bobDomain + ' : ' + str ( bobPort ) in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) . read ( ) :
2019-07-17 11:24:11 +00:00
break
2019-07-16 21:38:06 +00:00
time . sleep ( 1 )
assert os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' )
assert os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' )
2019-07-17 11:30:26 +00:00
assert ' alice@ ' + aliceDomain + ' : ' + str ( alicePort ) in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) . read ( )
assert ' bob@ ' + bobDomain + ' : ' + str ( bobPort ) in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) . read ( )
2019-07-18 09:26:47 +00:00
assert validInbox ( bobDir , ' bob ' , bobDomain )
2019-07-18 11:35:48 +00:00
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
2019-07-17 17:16:48 +00:00
print ( ' \n \n Bob follows Alice ' )
2019-08-20 09:16:03 +00:00
sendFollowRequestViaServer ( aliceDir , sessionAlice , \
' bob ' , ' bobpass ' , \
2019-07-17 17:16:48 +00:00
bobDomain , bobPort , \
' alice ' , aliceDomain , alicePort , \
httpPrefix , \
cachedWebfingers , personCache , \
2019-08-14 20:12:27 +00:00
True , __version__ )
2019-07-17 17:16:48 +00:00
for t in range ( 10 ) :
if os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /followers.txt ' ) :
if ' bob@ ' + bobDomain + ' : ' + str ( bobPort ) in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /followers.txt ' ) . read ( ) :
if os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /following.txt ' ) :
if ' alice@ ' + aliceDomain + ' : ' + str ( alicePort ) in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /following.txt ' ) . read ( ) :
break
time . sleep ( 1 )
assert os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /followers.txt ' )
assert os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /following.txt ' )
assert ' bob@ ' + bobDomain + ' : ' + str ( bobPort ) in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /followers.txt ' ) . read ( )
assert ' alice@ ' + aliceDomain + ' : ' + str ( alicePort ) in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /following.txt ' ) . read ( )
2019-07-18 09:26:47 +00:00
print ( ' \n \n Bob likes the post ' )
2019-07-16 19:07:45 +00:00
sessionBob = createSession ( bobDomain , bobPort , useTor )
password = ' bobpass '
outboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /outbox '
2019-07-16 22:57:45 +00:00
inboxPath = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /inbox '
2019-07-17 17:16:48 +00:00
print ( str ( len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) ) )
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 1
print ( str ( len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) ) )
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1
2019-08-20 09:16:03 +00:00
sendLikeViaServer ( bobDir , sessionBob , \
' bob ' , ' bobpass ' , \
2019-07-18 09:26:47 +00:00
bobDomain , bobPort , \
httpPrefix , outboxPostId , \
cachedWebfingers , personCache , \
2019-08-14 20:12:27 +00:00
True , __version__ )
2019-07-18 09:26:47 +00:00
for i in range ( 20 ) :
if os . path . isdir ( outboxPath ) and os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 2 :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1 :
break
time . sleep ( 1 )
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 2
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1
print ( ' Post liked ' )
print ( ' \n \n Bob repeats the post ' )
print ( str ( len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) ) )
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 2
print ( str ( len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) ) )
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 1
2019-08-20 09:16:03 +00:00
sendAnnounceViaServer ( bobDir , sessionBob , ' bob ' , password , \
2019-07-16 19:07:45 +00:00
bobDomain , bobPort , \
httpPrefix , outboxPostId , \
2019-07-16 21:38:06 +00:00
cachedWebfingers , \
2019-08-14 20:12:27 +00:00
personCache , True , __version__ )
2019-07-16 22:57:45 +00:00
for i in range ( 20 ) :
if os . path . isdir ( outboxPath ) and os . path . isdir ( inboxPath ) :
2019-07-18 09:26:47 +00:00
if len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 3 :
2019-07-17 17:16:48 +00:00
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 2 :
2019-07-16 22:57:45 +00:00
break
2019-07-16 19:07:45 +00:00
time . sleep ( 1 )
2019-07-18 09:26:47 +00:00
assert len ( [ name for name in os . listdir ( outboxPath ) if os . path . isfile ( os . path . join ( outboxPath , name ) ) ] ) == 3
2019-07-17 17:16:48 +00:00
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == 2
2019-07-16 19:07:45 +00:00
print ( ' Post repeated ' )
2019-07-17 11:54:13 +00:00
2019-07-17 17:16:48 +00:00
inboxPath = bobDir + ' /accounts/bob@ ' + bobDomain + ' /inbox '
outboxPath = aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /outbox '
postsBefore = len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] )
print ( ' \n \n Alice deletes her post: ' + outboxPostId + ' ' + str ( postsBefore ) )
password = ' alicepass '
2019-08-20 09:16:03 +00:00
sendDeleteViaServer ( aliceDir , sessionAlice , ' alice ' , password ,
2019-07-17 17:16:48 +00:00
aliceDomain , alicePort , \
httpPrefix , outboxPostId , \
cachedWebfingers , personCache , \
2019-08-14 20:12:27 +00:00
True , __version__ )
2019-07-17 17:16:48 +00:00
for i in range ( 30 ) :
if os . path . isdir ( inboxPath ) :
if len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == postsBefore - 1 :
break
time . sleep ( 1 )
assert len ( [ name for name in os . listdir ( inboxPath ) if os . path . isfile ( os . path . join ( inboxPath , name ) ) ] ) == postsBefore - 1
print ( " >>> post deleted from Alice ' s outbox and Bob ' s inbox " )
2019-07-18 09:26:47 +00:00
assert validInbox ( bobDir , ' bob ' , bobDomain )
2019-07-18 11:35:48 +00:00
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
2019-07-17 17:16:48 +00:00
2019-07-17 11:54:13 +00:00
print ( ' \n \n Alice unfollows Bob ' )
password = ' alicepass '
2019-08-20 09:16:03 +00:00
sendUnfollowRequestViaServer ( baseDir , sessionAlice , \
' alice ' , password , \
2019-07-17 11:54:13 +00:00
aliceDomain , alicePort , \
' bob ' , bobDomain , bobPort , \
httpPrefix , \
cachedWebfingers , personCache , \
2019-08-14 20:12:27 +00:00
True , __version__ )
2019-07-17 11:54:13 +00:00
for t in range ( 10 ) :
if ' alice@ ' + aliceDomain + ' : ' + str ( alicePort ) not in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) . read ( ) :
if ' bob@ ' + bobDomain + ' : ' + str ( bobPort ) not in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) . read ( ) :
break
time . sleep ( 1 )
assert os . path . isfile ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' )
assert os . path . isfile ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' )
assert ' alice@ ' + aliceDomain + ' : ' + str ( alicePort ) not in open ( bobDir + ' /accounts/bob@ ' + bobDomain + ' /followers.txt ' ) . read ( )
assert ' bob@ ' + bobDomain + ' : ' + str ( bobPort ) not in open ( aliceDir + ' /accounts/alice@ ' + aliceDomain + ' /following.txt ' ) . read ( )
2019-07-18 09:26:47 +00:00
assert validInbox ( bobDir , ' bob ' , bobDomain )
2019-07-18 11:35:48 +00:00
assert validInboxFilenames ( bobDir , ' bob ' , bobDomain , aliceDomain , alicePort )
2019-07-18 11:38:52 +00:00
assert validInbox ( aliceDir , ' alice ' , aliceDomain )
assert validInboxFilenames ( aliceDir , ' alice ' , aliceDomain , bobDomain , bobPort )
2019-07-17 11:54:13 +00:00
2019-07-16 11:33:40 +00:00
# stop the servers
thrAlice . kill ( )
thrAlice . join ( )
assert thrAlice . isAlive ( ) == False
thrBob . kill ( )
thrBob . join ( )
assert thrBob . isAlive ( ) == False
os . chdir ( baseDir )
2019-07-16 21:38:06 +00:00
#shutil.rmtree(aliceDir)
#shutil.rmtree(bobDir)
2019-07-16 10:19:04 +00:00
2019-08-21 16:35:46 +00:00
def testActorParsing ( ) :
print ( ' testActorParsing ' )
actor = ' https://mydomain:72/users/mynick '
domain , port = getDomainFromActor ( actor )
assert domain == ' mydomain '
assert port == 72
nickname = getNicknameFromActor ( actor )
assert nickname == ' mynick '
actor = ' https://randomain/users/rando '
domain , port = getDomainFromActor ( actor )
assert domain == ' randomain '
nickname = getNicknameFromActor ( actor )
assert nickname == ' rando '
actor = ' https://otherdomain:49/@othernick '
domain , port = getDomainFromActor ( actor )
assert domain == ' otherdomain '
assert port == 49
nickname = getNicknameFromActor ( actor )
assert nickname == ' othernick '
2019-09-01 08:55:05 +00:00
def testWebLinks ( ) :
2019-09-01 08:57:51 +00:00
print ( ' testWebLinks ' )
2019-09-01 08:55:05 +00:00
exampleText = ' This post has a web links https://somesite.net \n \n And some other text '
linkedText = addWebLinks ( exampleText )
2019-09-01 08:57:51 +00:00
assert ' <a href= " https://somesite.net " rel= " nofollow noopener " target= " _blank " ><span class= " invisible " >https://</span><span class= " ellipsis " >somesite.net</span></a ' in linkedText
2019-10-01 10:36:51 +00:00
exampleText = ' This post has a very long web link \n \n http://cbwebewuvfuftdiudbqd33dddbbyuef23fyug3bfhcyu2fct2cuyqbcbucuwvckiwyfgewfvqejbchevbhwevuevwbqebqekveqvuvjfkf.onion \n \n And some other text '
linkedText = addWebLinks ( exampleText )
assert ' ellipsis ' in linkedText
2019-11-04 20:39:14 +00:00
exampleText = ' <p>1. HAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAH</p> '
resultText = removeLongWords ( exampleText , 40 , [ ] )
2019-11-04 20:45:10 +00:00
assert resultText == ' <p>1. HAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA</p> '
2019-09-29 18:48:34 +00:00
def testAddEmoji ( ) :
print ( ' testAddEmoji ' )
content = ' Emoji :lemon: :strawberry: :banana: '
httpPrefix = ' http '
nickname = ' testuser '
domain = ' testdomain.net '
port = 3682
recipients = [ ]
hashtags = { }
baseDir = os . getcwd ( )
baseDirOriginal = os . getcwd ( )
path = baseDir + ' /.tests '
if not os . path . isdir ( path ) :
os . mkdir ( path )
path = baseDir + ' /.tests/emoji '
if os . path . isdir ( path ) :
shutil . rmtree ( path )
os . mkdir ( path )
baseDir = path
path = baseDir + ' /emoji '
if os . path . isdir ( path ) :
shutil . rmtree ( path )
os . mkdir ( path )
copytree ( baseDirOriginal + ' /emoji ' , baseDir + ' /emoji ' )
os . chdir ( baseDir )
privateKeyPem , publicKeyPem , person , wfEndpoint = \
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , ' password ' )
contentModified = \
addHtmlTags ( baseDir , httpPrefix , \
nickname , domain , content , \
2019-10-29 13:04:38 +00:00
recipients , hashtags , True )
assert ' :lemon: ' in contentModified
2019-09-29 18:48:34 +00:00
tags = [ ]
for tagName , tag in hashtags . items ( ) :
tags . append ( tag )
content = contentModified
contentModified = replaceEmojiFromTags ( content , tags , ' content ' )
assert ' img src ' in contentModified
2019-10-29 13:04:38 +00:00
assert ' :lemon: ' not in contentModified
2019-09-29 18:48:34 +00:00
os . chdir ( baseDirOriginal )
shutil . rmtree ( baseDirOriginal + ' /.tests ' )
2019-10-12 12:45:53 +00:00
def testGetStatusNumber ( ) :
print ( ' testGetStatusNumber ' )
prevStatusNumber = None
for i in range ( 1 , 20 ) :
statusNumber , published = getStatusNumber ( )
if prevStatusNumber :
assert len ( statusNumber ) == 18
assert int ( statusNumber ) > prevStatusNumber
prevStatusNumber = int ( statusNumber )
2019-11-09 21:39:04 +00:00
def testCommentJson ( ) - > None :
2019-11-09 12:13:39 +00:00
print ( ' testCommentJson ' )
filename = ' /tmp/test.json '
messageStr = " Crème brûlée यह एक परीक्षण ह "
testJson = {
" content " : messageStr
}
with open ( filename , ' w ' ) as fp :
commentjson . dump ( testJson , fp , indent = 2 , sort_keys = False )
receivedJson = None
with open ( filename , ' r ' ) as fp :
receivedJson = commentjson . load ( fp )
assert receivedJson
assert receivedJson [ ' content ' ] == messageStr
2019-11-09 12:52:47 +00:00
encodedStr = json . dumps ( testJson , ensure_ascii = False )
assert messageStr in encodedStr
2019-11-09 12:13:39 +00:00
2019-06-30 21:20:02 +00:00
def runAllTests ( ) :
print ( ' Running tests... ' )
2019-11-09 12:13:39 +00:00
testCommentJson ( )
2019-10-12 12:45:53 +00:00
testGetStatusNumber ( )
2019-09-29 18:48:34 +00:00
testAddEmoji ( )
2019-09-01 08:55:05 +00:00
testWebLinks ( )
2019-08-21 16:35:46 +00:00
testActorParsing ( )
2019-06-30 21:20:02 +00:00
testHttpsig ( )
testCache ( )
testThreads ( )
2019-07-03 10:04:23 +00:00
testCreatePerson ( )
2019-07-03 18:24:44 +00:00
testAuthentication ( )
2019-07-05 12:35:29 +00:00
testFollowersOfPerson ( )
2019-07-05 14:25:15 +00:00
testNoOfFollowersOnDomain ( )
2019-07-08 08:51:33 +00:00
testFollows ( )
testGroupFollowers ( )
2019-07-18 16:21:26 +00:00
testDelegateRoles ( )
2019-07-03 18:24:44 +00:00
print ( ' Tests succeeded \n ' )