diff options
author | Saw-jan <saw.jan.grg3e@gmail.com> | 2022-09-21 15:26:39 +0300 |
---|---|---|
committer | Sawjan Gurung <saw.jan.grg3e@gmail.com> | 2022-10-14 15:15:16 +0300 |
commit | f4238f402ab37883d4893f88c3d37ea03377a160 (patch) | |
tree | 355a7c9fd34951bd1508f9efc032f6da7334d49c /test | |
parent | 6a8c8ffab3c3975320fabd72dd841ab497acde4e (diff) |
wait for root sync to complete after adding account
Diffstat (limited to 'test')
-rw-r--r-- | test/gui/shared/scripts/bdd_hooks.py | 7 | ||||
-rw-r--r-- | test/gui/shared/scripts/helpers/SyncHelper.py | 89 | ||||
-rw-r--r-- | test/gui/shared/steps/steps.py | 76 |
3 files changed, 160 insertions, 12 deletions
diff --git a/test/gui/shared/scripts/bdd_hooks.py b/test/gui/shared/scripts/bdd_hooks.py index 1466bd659..2cd247def 100644 --- a/test/gui/shared/scripts/bdd_hooks.py +++ b/test/gui/shared/scripts/bdd_hooks.py @@ -27,6 +27,8 @@ from datetime import datetime previousFailResultCount = 0 previousErrorResultCount = 0 +# socket messages +socket_messages = [] @OnScenarioStart def hook(context): @@ -151,8 +153,9 @@ def scenarioFailed(): @OnScenarioEnd def hook(context): - # close socket connection - global socketConnect + # close socket connection and clear messages + global socketConnect, socket_messages + socket_messages.clear() if socketConnect: socketConnect.connected = False socketConnect._sock.close() diff --git a/test/gui/shared/scripts/helpers/SyncHelper.py b/test/gui/shared/scripts/helpers/SyncHelper.py new file mode 100644 index 000000000..242e967a2 --- /dev/null +++ b/test/gui/shared/scripts/helpers/SyncHelper.py @@ -0,0 +1,89 @@ +import re + + +# File syncing in client has the following status +SYNC_STATUS = { + 'SYNC': 'STATUS:SYNC', # sync in process + 'OK': 'STATUS:OK', # sync completed + 'ERROR': 'STATUS:ERROR', # file sync has error + 'IGNORE': 'STATUS:IGNORE', # file is igored + 'NOP': 'STATUS:NOP', # file yet to be synced + 'REGISTER': 'REGISTER_PATH', + 'UNREGISTER': 'UNREGISTER_PATH', + 'UPDATE': 'UPDATE_VIEW', +} + +# default sync patterns for the initial sync (after adding account) +SYNC_PATTERNS = { + 'root_sync': [ + { + 'length': 2, + 'pattern': { + SYNC_STATUS['UPDATE']: [0], + SYNC_STATUS['OK']: [1], + }, + }, + { + 'length': 2, + 'pattern': { + SYNC_STATUS['SYNC']: [0], + SYNC_STATUS['OK']: [1], + }, + }, + ], +} + + +# generate sync pattern from pattern meta data +# +# returns List +# e.g: ['UPDATE_VIEW', 'STATUS:OK'] +def generateSyncPattern(pattern_meta): + pattern = [None] * pattern_meta['length'] + for status in pattern_meta['pattern']: + for idx in pattern_meta['pattern'][status]: + pattern[idx] = status + return pattern + + +def getRootSyncPatterns(): + patterns = [] + for pattern_meta in SYNC_PATTERNS['root_sync']: + patterns.append(generateSyncPattern(pattern_meta)) + + return patterns + + +# generate sync pattern from the socket messages +# +# returns List +# e.g: ['UPDATE_VIEW', 'STATUS:OK'] +def generateSyncPatternFromMessages(messages): + pattern = [] + if not messages: + return pattern + + sync_messages = filterSyncMessages(messages) + for message in sync_messages: + # E.g; from "STATUS:OK:/tmp/client-bdd/Alice/" + # excludes ":/tmp/client-bdd/Alice/" + # adds only "STATUS:OK" to the pattern list + match = re.search(":/.*", message) + if match: + (end, _) = match.span() + pattern.append(message[:end]) + return pattern + + +# strip out the messages that are not related to sync +def filterSyncMessages(messages): + start_idx = 0 + if 'GET_STRINGS:END' in messages: + start_idx = messages.index('GET_STRINGS:END') + 1 + return messages[start_idx:] + + +def matchPatterns(p1, p2): + if p1 == p2: + return True + return False diff --git a/test/gui/shared/steps/steps.py b/test/gui/shared/steps/steps.py index 56c011105..84c351b36 100644 --- a/test/gui/shared/steps/steps.py +++ b/test/gui/shared/steps/steps.py @@ -11,7 +11,6 @@ import requests import builtins import shutil -from objectmaphelper import RegularExpression from pageObjects.AccountConnectionWizard import AccountConnectionWizard from helpers.SetupClientHelper import * from helpers.FilesHelper import buildConflictedRegex @@ -23,26 +22,80 @@ from pageObjects.Toolbar import Toolbar from pageObjects.Activity import Activity from pageObjects.AccountStatus import AccountStatus +from helpers.SyncHelper import ( + SYNC_STATUS, + getRootSyncPatterns, + generateSyncPatternFromMessages, + filterSyncMessages, + matchPatterns, +) + # the script needs to use the system wide python # to switch from the built-in interpreter see https://kb.froglogic.com/squish/howto/using-external-python-interpreter-squish-6-6/ # if the IDE fails to reference the script, add the folder in Edit->Preferences->PyDev->Interpreters->Libraries sys.path.append(os.path.realpath('../../../shell_integration/nautilus/')) from syncstate import SocketConnect -import functools socketConnect = None createdUsers = {} -# File syncing in client has the following status -SYNC_STATUS = { - 'SYNC': 'STATUS:SYNC', # sync in process - 'OK': 'STATUS:OK', # sync completed - 'ERROR': 'STATUS:ERROR', # file sync has error - 'IGNORE': 'STATUS:IGNORE', # file is igored - 'NOP': 'STATUS:NOP', # file yet to be synced -} + +def waitForRootSyncToComplete(context, timeout=None, pool_interval=500): + # listen for root folder status before syncing + listenSyncStatusForItem(context.userData['currentUserSyncPath']) + + if not timeout: + timeout = context.userData['maxSyncTimeout'] * 1000 + + synced = waitFor( + lambda: checkRootSyncPattern(pool_interval), + timeout, + ) + if not synced: + raise Exception( + "[Timeout Error] " + + timeout + + "ms timeout while waiting for sync to complete" + ) + + +def checkRootSyncPattern(pool_interval): + patterns = getRootSyncPatterns() + new_messages = getSocketMessagesDry() + messages = updateSocketMessages(new_messages) + for idx, _ in enumerate(messages): + next = idx + 1 + if next in range(len(messages)): + actual_pattern = generateSyncPatternFromMessages(messages[idx : next + 1]) + for pattern in patterns: + if matchPatterns(pattern, actual_pattern): + return True + # snooze takes time in seconds + # convert to milliseconds + snooze(pool_interval / 1000) + return False + + +def getSocketMessagesDry(): + socket_messages = [] + socketConnect = getSocketConnection() + socketConnect.read_socket_data_with_timeout(0.1) + for line in socketConnect.get_available_responses(): + socket_messages.append(line) + return socket_messages + + +def updateSocketMessages(messages): + global socket_messages + socket_messages.extend(filterSyncMessages(messages)) + return socket_messages + + +def listenSyncStatusForItem(item, type='FOLDER'): + socketConnect = getSocketConnection() + socketConnect.sendCommand("RETRIEVE_" + type.upper() + "_STATUS:" + item + "\n") # gets all users information created in a test scenario @@ -141,6 +194,9 @@ def step(context, username): enterUserPassword = EnterPassword() enterUserPassword.enterPassword(password) + # wait for files to sync + waitForRootSyncToComplete(context) + @Given('the user has started the client') def step(context): |