Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSaw-jan <saw.jan.grg3e@gmail.com>2022-09-21 15:26:39 +0300
committerSawjan Gurung <saw.jan.grg3e@gmail.com>2022-10-14 15:15:16 +0300
commitf4238f402ab37883d4893f88c3d37ea03377a160 (patch)
tree355a7c9fd34951bd1508f9efc032f6da7334d49c /test
parent6a8c8ffab3c3975320fabd72dd841ab497acde4e (diff)
wait for root sync to complete after adding account
Diffstat (limited to 'test')
-rw-r--r--test/gui/shared/scripts/bdd_hooks.py7
-rw-r--r--test/gui/shared/scripts/helpers/SyncHelper.py89
-rw-r--r--test/gui/shared/steps/steps.py76
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):