diff options
author | Saw-jan <saw.jan.grg3e@gmail.com> | 2022-10-11 13:20:23 +0300 |
---|---|---|
committer | Sawjan Gurung <saw.jan.grg3e@gmail.com> | 2022-10-14 15:15:16 +0300 |
commit | b528ce0721e5851a5037ccc2b22ecec915282e5b (patch) | |
tree | 67e61a93c18dcb165e947f40b80b11f81c5636ce | |
parent | f3e57dc2d3186a9d32806838c71ded2981c4c003 (diff) |
use pattern matching for wait for sync
-rw-r--r-- | test/gui/shared/scripts/helpers/SyncHelper.py | 48 | ||||
-rw-r--r-- | test/gui/shared/steps/steps.py | 204 | ||||
-rw-r--r-- | test/gui/tst_editFiles/test.feature | 2 |
3 files changed, 103 insertions, 151 deletions
diff --git a/test/gui/shared/scripts/helpers/SyncHelper.py b/test/gui/shared/scripts/helpers/SyncHelper.py index 242e967a2..04c5ce602 100644 --- a/test/gui/shared/scripts/helpers/SyncHelper.py +++ b/test/gui/shared/scripts/helpers/SyncHelper.py @@ -15,43 +15,21 @@ SYNC_STATUS = { # 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], - }, - }, + 'initial': [ + [SYNC_STATUS['UPDATE'], SYNC_STATUS['OK']], + [SYNC_STATUS['SYNC'], SYNC_STATUS['OK']], ], + 'synced': [SYNC_STATUS['SYNC'], SYNC_STATUS['OK']], + 'error': [SYNC_STATUS['ERROR']], } -# 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 getInitialSyncPatterns(): + return SYNC_PATTERNS['initial'] -def getRootSyncPatterns(): - patterns = [] - for pattern_meta in SYNC_PATTERNS['root_sync']: - patterns.append(generateSyncPattern(pattern_meta)) - - return patterns +def getSyncedPattern(): + return SYNC_PATTERNS['synced'] # generate sync pattern from the socket messages @@ -83,6 +61,14 @@ def filterSyncMessages(messages): return messages[start_idx:] +def filterMessageForItem(messages, item): + filteredMsg = [] + for msg in messages: + if msg.rstrip('/').endswith(item.rstrip('/')): + filteredMsg.append(msg) + return filteredMsg + + def matchPatterns(p1, p2): if p1 == p2: return True diff --git a/test/gui/shared/steps/steps.py b/test/gui/shared/steps/steps.py index 4f4add5e2..d735b4e66 100644 --- a/test/gui/shared/steps/steps.py +++ b/test/gui/shared/steps/steps.py @@ -24,9 +24,11 @@ from pageObjects.AccountStatus import AccountStatus from helpers.SyncHelper import ( SYNC_STATUS, - getRootSyncPatterns, + getInitialSyncPatterns, + getSyncedPattern, generateSyncPatternFromMessages, filterSyncMessages, + filterMessageForItem, matchPatterns, ) @@ -42,16 +44,61 @@ socketConnect = None createdUsers = {} -def waitForRootSyncToComplete(context): - # listen for root folder status before syncing - listenSyncStatusForItem(context.userData['currentUserSyncPath']) +def readSocketMessages(): + 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 readAndUpdateSocketMessages(): + messages = readSocketMessages() + return updateSocketMessages(messages) + + +def updateSocketMessages(messages): + global socket_messages + socket_messages.extend(filterSyncMessages(messages)) + return socket_messages + + +def clearSocketMessages(resource=''): + global socket_messages + if resource: + print('---top---') + print(socket_messages) + resource_messages = set(filterMessageForItem(socket_messages, resource)) + socket_messages = [msg for msg in socket_messages if msg not in resource_messages] + else: + socket_messages.clear() + print('---low---') + print(socket_messages) + + +def listenSyncStatusForItem(item, type='FOLDER'): + type = type.upper() + if type != 'FILE' and type != 'FOLDER': + raise Exception("type must be 'FILE' or 'FOLDER'") + socketConnect = getSocketConnection() + socketConnect.sendCommand("RETRIEVE_" + type + "_STATUS:" + item + "\n") + + +def waitForSyncToComplete(context, patterns=None, resource='', resourceType='FOLDER'): + resource = join(context.userData['currentUserSyncPath'], resource) + listenSyncStatusForItem(resource, resourceType) timeout = context.userData['maxSyncTimeout'] * 1000 + if patterns is None: + patterns = getSyncedPattern() + synced = waitFor( - lambda: checkRootSyncPattern(), + lambda: hasSyncPattern(patterns), timeout, ) + clearSocketMessages(resource) if not synced: raise Exception( "Timeout while waiting for sync to complete for " @@ -60,15 +107,19 @@ def waitForRootSyncToComplete(context): ) -def checkRootSyncPattern(): - 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: +def waitForInitialSyncToComplete(context): + waitForSyncToComplete(context, getInitialSyncPatterns(), context.userData['currentUserSyncPath'], 'FOLDER') + + +def hasSyncPattern(patterns): + if isinstance(patterns[0], str): + patterns = [patterns] + messages = readAndUpdateSocketMessages() + for pattern in patterns: + for idx, _ in enumerate(messages): + next = idx + 1 + if next in range(len(messages)): + actual_pattern = generateSyncPatternFromMessages(messages[idx : next + (len(pattern) - 1)]) if matchPatterns(pattern, actual_pattern): return True # 100 milliseconds polling interval @@ -76,26 +127,6 @@ def checkRootSyncPattern(): 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 def getCreatedUsersFromMiddleware(context): createdUsers = {} @@ -193,7 +224,7 @@ def step(context, username): enterUserPassword.enterPassword(password) # wait for files to sync - waitForRootSyncToComplete(context) + waitForInitialSyncToComplete(context) @Given('the user has started the client') @@ -225,45 +256,30 @@ def getSocketConnection(): # Using socket API to check file sync status -def hasSyncStatus(type, itemName, status): - if type != 'FILE' and type != 'FOLDER': - raise Exception("type must be 'FILE' or 'FOLDER'") - socketConnect = getSocketConnection() - socketConnect.sendCommand("RETRIEVE_" + type + "_STATUS:" + itemName + "\n") - - if not socketConnect.read_socket_data_with_timeout(0.1): - return False - for line in socketConnect.get_available_responses(): - if line.startswith(status) and line.endswith(itemName): +def hasSyncStatus(itemName, status): + sync_messages = readAndUpdateSocketMessages() + sync_messages = filterMessageForItem(sync_messages, itemName) + for line in sync_messages: + if line.startswith(status) and line.rstrip('/').endswith(itemName.rstrip('/')): return True - elif line.endswith(itemName): - return False - - -def folderHasSyncStatus(folderName, status): - return hasSyncStatus('FOLDER', folderName, status) - - -def fileHasSyncStatus(fileName, status): - return hasSyncStatus('FILE', fileName, status) + return False +# useful for checking sync status such as 'error', 'ignore' +# but not quit so reliable for checking 'ok' sync status def waitForFileOrFolderToHaveSyncStatus( context, resource, resourceType, status=SYNC_STATUS['OK'], timeout=None ): + resource = sanitizePath(join(context.userData['currentUserSyncPath'], resource)) + + listenSyncStatusForItem(resource, resourceType) + if not timeout: timeout = context.userData['maxSyncTimeout'] * 1000 - resource = join(context.userData['currentUserSyncPath'], resource) - if resourceType.lower() == "file": - result = waitFor( - lambda: fileHasSyncStatus(sanitizePath(resource), status), - timeout, - ) - elif resourceType.lower() == "folder": - result = waitFor( - lambda: folderHasSyncStatus(sanitizePath(resource), status), - timeout, + result = waitFor( + lambda: hasSyncStatus(resource, status), + timeout, ) if not result: @@ -284,62 +300,13 @@ def waitForFileOrFolderToHaveSyncStatus( ) -def waitForSyncToStart(context, resource, resourceType): - resource = join(context.userData['currentUserSyncPath'], resource) - - hasStatusNOP = hasSyncStatus(resourceType.upper(), resource, SYNC_STATUS['NOP']) - hasStatusSYNC = hasSyncStatus(resourceType.upper(), resource, SYNC_STATUS['SYNC']) - - if hasStatusSYNC: - return - - try: - if hasStatusNOP: - waitForFileOrFolderToHaveSyncStatus( - context, resource, resourceType, SYNC_STATUS['SYNC'] - ) - else: - waitForFileOrFolderToHaveSyncStatus( - context, - resource, - resourceType, - SYNC_STATUS['SYNC'], - context.userData['minSyncTimeout'] * 1000, - ) - except: - hasStatusNOP = hasSyncStatus(resourceType.upper(), resource, SYNC_STATUS['NOP']) - if hasStatusNOP: - raise Exception( - "Expected " - + resourceType - + " '" - + resource - + "' to have sync started but not." - ) - - -def waitForFileOrFolderToSync(context, resource, resourceType): - waitForSyncToStart(context, resource, resourceType) - waitForFileOrFolderToHaveSyncStatus( - context, resource, resourceType, SYNC_STATUS['OK'] - ) - - -def waitForRootFolderToSync(context): - waitForFileOrFolderToSync( - context, context.userData['currentUserSyncPath'], 'folder' - ) - - def waitForFileOrFolderToHaveSyncError(context, resource, resourceType): - waitForSyncToStart(context, resource, resourceType) waitForFileOrFolderToHaveSyncStatus( context, resource, resourceType, SYNC_STATUS['ERROR'] ) def waitForFileOrFolderToBeSyncIgnored(context, resource, resourceType): - waitForSyncToStart(context, resource, resourceType) waitForFileOrFolderToHaveSyncStatus( context, resource, resourceType, SYNC_STATUS['IGNORE'] ) @@ -501,12 +468,12 @@ def collaboratorShouldBeListed( @When('the user waits for the files to sync') def step(context): - waitForRootFolderToSync(context) + waitForSyncToComplete(context) @When(r'the user waits for (file|folder) "([^"]*)" to be synced', regexp=True) def step(context, type, resource): - waitForFileOrFolderToSync(context, resource, type) + waitForSyncToComplete(context, resource, type) @When(r'the user waits for (file|folder) "([^"]*)" to have sync error', regexp=True) @@ -521,12 +488,12 @@ def step(context, type, resource): @Given('user has waited for the files to be synced') def step(context): - waitForRootFolderToSync(context) + waitForSyncToComplete(context) @Given(r'the user has waited for (file|folder) "([^"]*)" to be synced', regexp=True) def step(context, type, resource): - waitForFileOrFolderToSync(context, resource, type) + waitForSyncToComplete(context, resource, type) @Given( @@ -1029,7 +996,6 @@ def step(context, username): @Given('user "|any|" has logged out of the client-UI') def step(context, username): - waitForRootFolderToSync(context) accountStatus = AccountStatus(context, getDisplaynameForUser(context, username)) accountStatus.accountAction("Log out") isUserSignedOut(context, username) diff --git a/test/gui/tst_editFiles/test.feature b/test/gui/tst_editFiles/test.feature index 9855a4e19..37b2f1be6 100644 --- a/test/gui/tst_editFiles/test.feature +++ b/test/gui/tst_editFiles/test.feature @@ -13,5 +13,5 @@ Feature: edit files Given user "Alice" has uploaded file with content "ownCloud test text file 0" to "S@mpleFile!With,$pecial?Characters.txt" on the server And user "Alice" has set up a client with default settings When the user overwrites the file "S@mpleFile!With,$pecial?Characters.txt" with content "overwrite ownCloud test text file" - And the user waits for file "S@mpleFile!With,$pecial?Characters.txt" to be synced + When the user waits for file "S@mpleFile!With,$pecial?Characters.txt" to be synced Then as "Alice" the file "S@mpleFile!With,$pecial?Characters.txt" on the server should have the content "overwrite ownCloud test text file"
\ No newline at end of file |