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-03-25 12:48:36 +0300
committerSawjan Gurung <saw.jan.grg3e@gmail.com>2022-03-31 09:12:51 +0300
commit6a106b86246548a78f7842e51ec445c01b8edf17 (patch)
tree18fcc8d87c04c1c636e70ee72f86c0715fa69b52 /test
parent06f70b0d53f318b396555f39e5e23ac653cb74c2 (diff)
save stacktrace of AUT crash to a file
move to helper file
Diffstat (limited to 'test')
-rw-r--r--test/gui/shared/scripts/bdd_hooks.py15
-rw-r--r--test/gui/shared/scripts/helpers/SetupClientHelper.py66
-rw-r--r--test/gui/shared/scripts/helpers/StacktraceHelper.py68
3 files changed, 83 insertions, 66 deletions
diff --git a/test/gui/shared/scripts/bdd_hooks.py b/test/gui/shared/scripts/bdd_hooks.py
index f36132868..564ae0863 100644
--- a/test/gui/shared/scripts/bdd_hooks.py
+++ b/test/gui/shared/scripts/bdd_hooks.py
@@ -19,6 +19,7 @@ import shutil
import urllib.request
import os
import builtins
+from helpers.StacktraceHelper import getCoredump, generateStacktrace
@OnScenarioStart
@@ -64,7 +65,7 @@ def hook(context):
for key, value in context.userData.items():
if value == '':
context.userData[key] = DEFAULT_CONFIG[key]
- elif key == 'maxSyncTimeout':
+ elif key == 'maxSyncTimeout' or key == 'minSyncTimeout':
context.userData[key] = builtins.int(value)
elif key == 'clientRootSyncPath':
# make sure there is always one trailing slash
@@ -93,6 +94,18 @@ def hook(context):
@OnScenarioEnd
def hook(context):
+ # search coredumps after every test scenario
+ # CI pipeline might fail although all tests are passing
+ coredumps = getCoredump()
+ if len(coredumps) > 0:
+ try:
+ generateStacktrace(context, coredumps)
+ print("Stacktrace generated.")
+ except Exception as err:
+ print(err)
+ else:
+ print("No coredump found!")
+
# capture screenshot if there is error in the scenario execution, and if the test is being run in CI
if test.resultCount("errors") > 0 and os.getenv('CI'):
import gi
diff --git a/test/gui/shared/scripts/helpers/SetupClientHelper.py b/test/gui/shared/scripts/helpers/SetupClientHelper.py
index 19d3783dc..fb996d63e 100644
--- a/test/gui/shared/scripts/helpers/SetupClientHelper.py
+++ b/test/gui/shared/scripts/helpers/SetupClientHelper.py
@@ -1,10 +1,7 @@
from urllib.parse import urlparse
import squish
-from os import makedirs, environ
+from os import makedirs
from os.path import exists, join
-import test
-import subprocess
-from configparser import ConfigParser
confdir = '/tmp/bdd-tests-owncloud-client/'
@@ -78,71 +75,10 @@ def startClient(context):
+ " --confdir "
+ confdir
)
- squish.installEventHandler("Crash", "crashHandler")
squish.snooze(1)
-def crashHandler():
- # The core dump is generated in the folder /var/lib/apport/coredump/
- coredumpFolderPath = '/var/lib/apport/coredump/'
- cfg = ConfigParser()
-
- # Select appropriate AUT binary with respect to the test run environment
- try:
- if environ.get('CI'):
- cfg.read('/drone/src/test/gui/drone/server.ini')
-
- else:
- from pathlib import Path
-
- HOME = str(Path.home())
- cfg.read(HOME + '/.squish/ver1/server.ini')
-
- except Exception as err:
- test.log("the binary path can not be read")
- test.log(err)
-
- owncloudBinary = cfg.get('General', 'AUT/owncloud')
- owncloudBinary = owncloudBinary.replace('"', '') + '/owncloud'
-
- # GUI test stacktrace on crash
- test.log("Started printing the GUI test stacktrace of crash")
- test.log("############################################################")
- test.log("Backtracking...")
- test.log("%s" % test.stackTrace())
- test.log("############################################################")
- test.log("Finished printing GUI test stacktrace")
-
- test.log("Started printing the AUT stacktrace of crash")
- test.log("############################################################")
- ls = subprocess.run(
- ['ls', '-t', coredumpFolderPath], stdout=subprocess.PIPE
- ).stdout.decode('utf-8')
- coredumpFilename = ls.split('\n')[0]
- test.log("located latest core dump file: %s" % coredumpFilename)
-
- if coredumpFilename:
- test.log("Backtracking...")
- test.log(
- "%s"
- % subprocess.run(
- [
- 'gdb',
- owncloudBinary,
- coredumpFolderPath + coredumpFilename.strip(),
- '-batch',
- '-ex',
- 'bt full',
- ],
- stdout=subprocess.PIPE,
- ).stdout.decode('utf-8')
- )
-
- test.log("############################################################")
- test.log("Finished printing AUT stacktrace")
-
-
def getPollingInterval():
pollingInterval = '''[ownCloud]
remotePollInterval={pollingInterval}
diff --git a/test/gui/shared/scripts/helpers/StacktraceHelper.py b/test/gui/shared/scripts/helpers/StacktraceHelper.py
new file mode 100644
index 000000000..01133ff2d
--- /dev/null
+++ b/test/gui/shared/scripts/helpers/StacktraceHelper.py
@@ -0,0 +1,68 @@
+import os
+import builtins
+import subprocess
+import glob
+import re
+from datetime import datetime
+
+
+def getCoredump():
+ # read coredump location
+ with open("/proc/sys/kernel/core_pattern", "r") as f:
+ coredumpPath = f.read().strip("\n")
+
+ # yields something like: /tmp/core-*-*-*-*
+ coredumpFilePattern = re.sub(r'%[a-zA-Z]{1}', '*', coredumpPath)
+ return glob.glob(coredumpFilePattern)
+
+
+def generateStacktrace(context, coredumps):
+ message = ["###########################################"]
+ message.append("Scenario: " + context._data["title"])
+
+ for coredumpFile in coredumps:
+ message.append(parseStacktrace(coredumpFile))
+
+ message.append("###########################################")
+ message.append("")
+ message = "\n".join(message)
+
+ stacktrace_file = os.environ.get("STACKTRACE_FILE", "../stacktrace")
+ # save stacktrace to a file
+ open(stacktrace_file, "a").write(message)
+
+
+def parseStacktrace(coredumpFile):
+ message = []
+ if builtins.bool(coredumpFile):
+ coredumpFilename = os.path.basename(coredumpFile)
+ # example coredump file: core-1648445754-1001-11-!drone!src!build-GUI-tests!bin!owncloud
+ patterns = coredumpFilename.split('-')
+ appBinary = "-".join(patterns[4:]).replace('!', '/')
+
+ message.append("-------------------------------------------")
+ message.append("Executable: " + appBinary)
+ message.append("Timestamp: " + str(datetime.fromtimestamp(float(patterns[1]))))
+ message.append("Process ID: " + patterns[2])
+ message.append("Signal Number: " + patterns[3])
+ message.append("-------------------------------------------")
+ message.append("<<<<< STACKTRACE START >>>>>")
+ message.append(
+ subprocess.run(
+ [
+ 'gdb',
+ appBinary,
+ coredumpFile,
+ '-batch',
+ '-ex',
+ 'bt full',
+ ],
+ stdout=subprocess.PIPE,
+ ).stdout.decode('utf-8')
+ )
+ message.append("<<<<< STACKTRACE END >>>>>")
+
+ # remove coredump file
+ os.unlink(coredumpFile)
+
+ return "\n".join(message)