Start of unit test for groups

merge-requests/30/head
Bob Mottram 2021-07-30 20:20:49 +01:00
parent 71cabd74a2
commit 4efb5c9a30
4 changed files with 254 additions and 17 deletions

View File

@ -54,6 +54,7 @@ from follow import clearFollows
from follow import followerOfPerson from follow import followerOfPerson
from follow import sendFollowRequestViaServer from follow import sendFollowRequestViaServer
from follow import sendUnfollowRequestViaServer from follow import sendUnfollowRequestViaServer
from tests import testGroupFollow
from tests import testPostMessageBetweenServers from tests import testPostMessageBetweenServers
from tests import testFollowBetweenServers from tests import testFollowBetweenServers
from tests import testClientToServer from tests import testClientToServer
@ -608,6 +609,7 @@ if args.tests:
sys.exit() sys.exit()
if args.testsnetwork: if args.testsnetwork:
print('Network Tests') print('Network Tests')
testGroupFollow()
testPostMessageBetweenServers() testPostMessageBetweenServers()
testFollowBetweenServers() testFollowBetweenServers()
testClientToServer() testClientToServer()

View File

@ -297,7 +297,7 @@ def unfollowerOfAccount(baseDir: str, nickname: str, domain: str,
def clearFollows(baseDir: str, nickname: str, domain: str, def clearFollows(baseDir: str, nickname: str, domain: str,
followFile='following.txt') -> None: followFile: str = 'following.txt') -> None:
"""Removes all follows """Removes all follows
""" """
handle = nickname + '@' + domain handle = nickname + '@' + domain
@ -452,10 +452,14 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str,
if currPage == pageNumber: if currPage == pageNumber:
line2 = \ line2 = \
line.lower().replace('\n', '').replace('\r', '') line.lower().replace('\n', '').replace('\r', '')
url = httpPrefix + '://' + \ nick = line2.split('@')[0]
line2.split('@')[1] + \ dom = line2.split('@')[1]
'/users/' + \ if not nick.startswith('!'):
line2.split('@')[0] # person actor
url = httpPrefix + '://' + dom + '/users/' + nick
else:
# group actor
url = httpPrefix + '://' + dom + '/c/' + nick
following['orderedItems'].append(url) following['orderedItems'].append(url)
elif ((line.startswith('http') or elif ((line.startswith('http') or
line.startswith('hyper')) and line.startswith('hyper')) and
@ -563,16 +567,13 @@ def _storeFollowRequest(baseDir: str,
if approveHandle in followersStr: if approveHandle in followersStr:
alreadyFollowing = True alreadyFollowing = True
elif '://' + domainFull + '/profile/' + nickname in followersStr: else:
alreadyFollowing = True usersPaths = getUserPaths()
elif '://' + domainFull + '/channel/' + nickname in followersStr: for possibleUsersPath in usersPaths:
alreadyFollowing = True url = '://' + domainFull + possibleUsersPath + nickname
elif '://' + domainFull + '/accounts/' + nickname in followersStr: if url in followersStr:
alreadyFollowing = True
elif '://' + domainFull + '/u/' + nickname in followersStr:
alreadyFollowing = True
elif '://' + domainFull + '/c/' + nickname in followersStr:
alreadyFollowing = True alreadyFollowing = True
break
if alreadyFollowing: if alreadyFollowing:
if debug: if debug:
@ -754,13 +755,18 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
followersFilename + ' adding ' + approveHandle) followersFilename + ' adding ' + approveHandle)
if os.path.isfile(followersFilename): if os.path.isfile(followersFilename):
if approveHandle not in open(followersFilename).read(): if approveHandle not in open(followersFilename).read():
groupAccount = hasGroupPath(messageJson['object'])
try: try:
with open(followersFilename, 'r+') as followersFile: with open(followersFilename, 'r+') as followersFile:
content = followersFile.read() content = followersFile.read()
if approveHandle + '\n' not in content: if approveHandle + '\n' not in content:
followersFile.seek(0, 0) followersFile.seek(0, 0)
followersFile.write(approveHandle + '\n' + if not groupAccount:
content) followersFile.write(approveHandle +
'\n' + content)
else:
followersFile.write('!' + approveHandle +
'\n' + content)
except Exception as e: except Exception as e:
print('WARN: ' + print('WARN: ' +
'Failed to write entry to followers file ' + 'Failed to write entry to followers file ' +
@ -915,9 +921,13 @@ def sendFollowRequest(session, baseDir: str,
statusNumber, published = getStatusNumber() statusNumber, published = getStatusNumber()
groupAccount = False
if followNickname: if followNickname:
followedId = followedActor followedId = followedActor
followHandle = followNickname + '@' + requestDomain followHandle = followNickname + '@' + requestDomain
groupAccount = hasGroupPath(followedActor)
if groupAccount:
followHandle = '!' + followHandle
else: else:
if debug: if debug:
print('DEBUG: sendFollowRequest - assuming single user instance') print('DEBUG: sendFollowRequest - assuming single user instance')

View File

@ -1945,6 +1945,8 @@ def _sendToGroupMembers(session, baseDir: str, handle: str, port: int,
return return
if not postJsonObject.get('object'): if not postJsonObject.get('object'):
return return
if not hasObjectDict(postJsonObject):
return
nickname = handle.split('@')[0] nickname = handle.split('@')[0]
# groupname = _getGroupName(baseDir, handle) # groupname = _getGroupName(baseDir, handle)
domain = handle.split('@')[1] domain = handle.split('@')[1]
@ -1960,6 +1962,7 @@ def _sendToGroupMembers(session, baseDir: str, handle: str, port: int,
senderStr = '@' + sendingActorNickname + '@' + sendingActorDomainFull senderStr = '@' + sendingActorNickname + '@' + sendingActorDomainFull
contentStr = getBaseContentFromPost(postJsonObject, systemLanguage) contentStr = getBaseContentFromPost(postJsonObject, systemLanguage)
if not contentStr.startswith(senderStr): if not contentStr.startswith(senderStr):
pprint(postJsonObject)
postJsonObject['object']['content'] = \ postJsonObject['object']['content'] = \
senderStr + ' ' + contentStr senderStr + ' ' + contentStr
postJsonObject['object']['contentMap'][systemLanguage] = \ postJsonObject['object']['contentMap'][systemLanguage] = \

222
tests.py
View File

@ -69,6 +69,7 @@ from follow import unfollowAccount
from follow import unfollowerOfAccount from follow import unfollowerOfAccount
from follow import sendFollowRequest from follow import sendFollowRequest
from person import createPerson from person import createPerson
from person import createGroup
from person import setDisplayNickname from person import setDisplayNickname
from person import setBio from person import setBio
# from person import generateRSAKey # from person import generateRSAKey
@ -136,9 +137,11 @@ from shares import createSharedItemFederationToken
from shares import updateSharedItemFederationToken from shares import updateSharedItemFederationToken
from shares import mergeSharedItemTokens from shares import mergeSharedItemTokens
testServerGroupRunning = False
testServerAliceRunning = False testServerAliceRunning = False
testServerBobRunning = False testServerBobRunning = False
testServerEveRunning = False testServerEveRunning = False
thrGroup = None
thrAlice = None thrAlice = None
thrBob = None thrBob = None
thrEve = None thrEve = None
@ -773,6 +776,72 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
sendThreads, False) sendThreads, False)
def createServerGroup(path: str, domain: str, port: int,
federationList: [],
hasFollows: bool, hasPosts: bool,
sendThreads: []):
print('Creating test server: Group on port ' + str(port))
if os.path.isdir(path):
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
sharedItemsFederatedDomains = []
# systemLanguage = 'en'
nickname = 'testgroup'
httpPrefix = 'http'
proxyType = None
password = 'testgrouppass'
maxReplies = 64
domainMaxPostsPerDay = 1000
accountMaxPostsPerDay = 1000
allowDeletion = True
privateKeyPem, publicKeyPem, person, wfEndpoint = \
createGroup(path, nickname, domain, port, httpPrefix, True,
password)
deleteAllPosts(path, nickname, domain, 'inbox')
deleteAllPosts(path, nickname, domain, 'outbox')
global testServerGroupRunning
testServerGroupRunning = True
maxMentions = 10
maxEmoji = 10
onionDomain = None
i2pDomain = None
allowLocalNetworkAccess = True
maxNewswirePosts = 20
dormantMonths = 3
sendThreadsTimeoutMins = 30
maxFollowers = 10
verifyAllSignatures = True
brochMode = False
showNodeInfoAccounts = True
showNodeInfoVersion = True
city = 'London, England'
logLoginFailures = False
userAgentsBlocked = []
print('Server running: Group')
runDaemon(sharedItemsFederatedDomains,
userAgentsBlocked,
logLoginFailures, city,
showNodeInfoAccounts,
showNodeInfoVersion,
brochMode,
verifyAllSignatures,
sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess,
2048, False, True, False, False, True, maxFollowers,
0, 100, 1024, 5, False,
0, False, 1, False, False, False,
5, True, True, 'en', __version__,
"instanceId", False, path, domain,
onionDomain, i2pDomain, None, port, port,
httpPrefix, federationList, maxMentions, maxEmoji, False,
proxyType, maxReplies,
domainMaxPostsPerDay, accountMaxPostsPerDay,
allowDeletion, True, True, False, sendThreads,
False)
def testPostMessageBetweenServers(): def testPostMessageBetweenServers():
print('Testing sending message from one server to the inbox of another') print('Testing sending message from one server to the inbox of another')
@ -1246,6 +1315,158 @@ def testFollowBetweenServers():
shutil.rmtree(baseDir + '/.tests') shutil.rmtree(baseDir + '/.tests')
def testGroupFollow():
print('Testing following of a group')
global testServerAliceRunning
testServerAliceRunning = False
# systemLanguage = 'en'
httpPrefix = 'http'
proxyType = None
federationList = []
baseDir = os.getcwd()
if os.path.isdir(baseDir + '/.tests'):
shutil.rmtree(baseDir + '/.tests')
os.mkdir(baseDir + '/.tests')
# create the servers
aliceDir = baseDir + '/.tests/alice'
aliceDomain = '127.0.0.57'
alicePort = 61927
aliceSendThreads = []
# aliceAddress = aliceDomain + ':' + str(alicePort)
testgroupDir = baseDir + '/.tests/testgroup'
testgroupDomain = '127.0.0.63'
testgroupPort = 61925
testgroupSendThreads = []
testgroupAddress = testgroupDomain + ':' + str(testgroupPort)
global thrAlice
if thrAlice:
while thrAlice.is_alive():
thrAlice.stop()
time.sleep(1)
thrAlice.kill()
thrAlice = \
threadWithTrace(target=createServerAlice,
args=(aliceDir, aliceDomain, alicePort,
testgroupAddress,
federationList, False, False,
aliceSendThreads),
daemon=True)
global thrGroup
if thrGroup:
while thrGroup.is_alive():
thrGroup.stop()
time.sleep(1)
thrGroup.kill()
thrGroup = \
threadWithTrace(target=createServerGroup,
args=(testgroupDir, testgroupDomain, testgroupPort,
federationList, False, False,
testgroupSendThreads),
daemon=True)
thrAlice.start()
thrGroup.start()
assert thrAlice.is_alive() is True
assert thrGroup.is_alive() is True
# wait for all servers to be running
ctr = 0
while not (testServerAliceRunning and testServerGroupRunning):
time.sleep(1)
ctr += 1
if ctr > 60:
break
print('Alice online: ' + str(testServerAliceRunning))
print('Test Group online: ' + str(testServerGroupRunning))
assert ctr <= 60
time.sleep(1)
queuePath = \
testgroupDir + '/accounts/testgroup@' + testgroupDomain + '/queue'
# In the beginning the test group had no followers
print('*********************************************************')
print('Alice sends a follow request to the test group')
os.chdir(aliceDir)
sessionAlice = createSession(proxyType)
# inReplyTo = None
# inReplyToAtomUri = None
# subject = None
alicePostLog = []
# followersOnly = False
# saveToFile = True
clientToServer = False
# ccUrl = None
alicePersonCache = {}
aliceCachedWebfingers = {}
alicePostLog = []
testgroupActor = httpPrefix + '://' + testgroupAddress + '/users/testgroup'
sendResult = \
sendFollowRequest(sessionAlice, aliceDir,
'alice', aliceDomain, alicePort, httpPrefix,
'testgroup', testgroupDomain, testgroupActor,
testgroupPort, httpPrefix,
clientToServer, federationList,
aliceSendThreads, alicePostLog,
aliceCachedWebfingers, alicePersonCache,
True, __version__)
print('sendResult: ' + str(sendResult))
for t in range(16):
if os.path.isfile(testgroupDir + '/accounts/testgroup@' +
testgroupDomain + '/followers.txt'):
if os.path.isfile(aliceDir + '/accounts/alice@' +
aliceDomain + '/following.txt'):
if os.path.isfile(aliceDir + '/accounts/alice@' +
aliceDomain + '/followingCalendar.txt'):
break
time.sleep(1)
assert validInbox(testgroupDir, 'testgroup', testgroupDomain)
assert validInboxFilenames(testgroupDir, 'testgroup', testgroupDomain,
aliceDomain, alicePort)
assert 'alice@' + aliceDomain in open(testgroupDir +
'/accounts/testgroup@' +
testgroupDomain +
'/followers.txt').read()
assert 'testgroup@' + testgroupDomain in open(aliceDir +
'/accounts/alice@' +
aliceDomain +
'/following.txt').read()
testgroupHandle = 'testgroup@' + testgroupDomain
assert testgroupHandle in open(aliceDir +
'/accounts/alice@' +
aliceDomain +
'/followingCalendar.txt').read()
# stop the servers
thrAlice.kill()
thrAlice.join()
assert thrAlice.is_alive() is False
thrGroup.kill()
thrGroup.join()
assert thrGroup.is_alive() is False
# queue item removed
time.sleep(4)
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 _testFollowersOfPerson(): def _testFollowersOfPerson():
print('testFollowersOfPerson') print('testFollowersOfPerson')
currDir = os.getcwd() currDir = os.getcwd()
@ -3285,6 +3506,7 @@ def _testFunctions():
'getThisWeeksEvents', 'getThisWeeksEvents',
'getAvailability', 'getAvailability',
'_testThreadsFunction', '_testThreadsFunction',
'createServerGroup',
'createServerAlice', 'createServerAlice',
'createServerBob', 'createServerBob',
'createServerEve', 'createServerEve',