[ABRT PATCH] testsuite: recognize uReport2

Martin Milata mmilata at redhat.com
Tue Jul 23 15:00:00 UTC 2013


Changes in ureport validator were backported from faf master, including
the support for uReport version 2.

Signed-off-by: Martin Milata <mmilata at redhat.com>
---
 tests/runtests/ureport/ureport-valid.py | 188 +++++++++++++++++++++++++++++++-
 1 file changed, 186 insertions(+), 2 deletions(-)

diff --git a/tests/runtests/ureport/ureport-valid.py b/tests/runtests/ureport/ureport-valid.py
index 7eaba05..d039121 100755
--- a/tests/runtests/ureport/ureport-valid.py
+++ b/tests/runtests/ureport/ureport-valid.py
@@ -9,13 +9,15 @@ import sys
 ABRT_VERSION_PARSER = re.compile("^([0-9]+)\.([0-9]+)\.([0-9]+)(\..*)?$")
 
 RE_ARCH = re.compile("^[0-9a-zA-Z_]+$")
-RE_EXEC = re.compile("^[0-9a-zA-Z/_\.\-\+]+$")
+RE_EXEC = re.compile("^[0-9a-zA-Z<>/_\.\-\+]+$")
 RE_FUNCHASH = re.compile("^[a-zA-Z0-9\;\_\:\,\?]+$")
 RE_HEX = re.compile("^(0[xX])?[0-9a-fA-F]+$")
 RE_NONEMPTY = re.compile("^.+$")
 RE_PACKAGE = re.compile("^[0-9a-zA-Z_\.\+\-~]+$")
 RE_PHRASE = re.compile("^[0-9a-zA-Z_<>:\*\+=~@\?\!\ &(),\/\|\`\'\^\-\.\[\]\$\#]+$")
 RE_PROJNAME = re.compile("^[0-9a-zA-Z \+\-\)\(\._~]+$")
+# 17, 12.2, 6.4, 7.0 Alpha3, 6.4 Beta, Rawhide, Tumbleweed
+RE_OSVERSION = re.compile("^[0-9a-zA-Z]+(\.[0-9]+)?( (Alpha|Beta)[0-9]*)?$")
 RE_SEPOL = re.compile("^[a-zA-Z0-9_\.\-]+(:[a-zA-Z0-9_\.\-]+){3,4}$")
 RE_TAINT = re.compile("^[A-Z ]+$")
 
@@ -68,6 +70,11 @@ PROC_LIMITS_CHECKER = {
 
 }
 
+OS_CHECKER = {
+  "name":    { "mand": True, "type": basestring, "re": RE_PROJNAME, "maxlen": 255 },
+  "version": { "mand": True, "type": basestring, "re": RE_OSVERSION, "maxlen": 255 }
+}
+
 OS_STATE_CHECKER = {
     "suspend":  { "mand": True, "type": basestring, "re": re.compile("^(yes|no)$", re.IGNORECASE) },
     "boot":     { "mand": True, "type": basestring, "re": re.compile("^(yes|no)$", re.IGNORECASE) },
@@ -86,7 +93,7 @@ UREPORT_CHECKER = {
   "installed_package": { "mand": True,  "type": dict, "checker": PACKAGE_CHECKER },
   "running_package":   { "mand": False, "type": dict, "checker": PACKAGE_CHECKER },
   "related_packages":  { "mand": True,  "type": list, "checker": RELATED_PACKAGES_CHECKER },
-  "os":                { "mand": True,  "type": dict, "checker": NV_CHECKER },
+  "os":                { "mand": True,  "type": dict, "checker": OS_CHECKER },
   "architecture":      { "mand": True,  "type": basestring,  "re": RE_ARCH, "maxlen": 255 },
   "reporter":          { "mand": True,  "type": dict, "checker": NV_CHECKER },
   "crash_thread":      { "mand": True,  "type": int },
@@ -107,7 +114,184 @@ ATTACHMENT_CHECKER = {
   "data":   { "mand": True, "type": basestring, "re": RE_PHRASE, "maxlen": 1024 },
 }
 
+def ureport2to1(ureport2):
+    if "ureport_version" not in ureport2 or ureport2["ureport_version"] != 2:
+        raise ValueError, "uReport2 is required"
+
+    ureport1 = { "ureport_version": 1, }
+
+    if "reporter" in ureport2:
+        reporter = ureport2["reporter"]
+
+        ureport1["reporter"] = {}
+        if "name" in reporter:
+            ureport1["reporter"]["name"] = reporter["name"]
+
+        if "version" in reporter:
+            ureport1["reporter"]["version"] = reporter["version"]
+
+    if "os" in ureport2:
+        opsys = ureport2["os"]
+
+        ureport1["os"] = {}
+        if "name" in opsys:
+            ureport1["os"]["name"] = opsys["name"].capitalize()
+
+        if "version" in opsys:
+            ureport1["os"]["version"] = opsys["version"]
+
+        if "architecture" in opsys:
+            ureport1["architecture"] = opsys["architecture"]
+
+    if "packages" in ureport2:
+        ureport1["related_packages"] = []
+
+        for package in ureport2["packages"]:
+            pkg1 = {}
+            if "name" in package:
+                 pkg1["name"] = package["name"]
+
+            if "epoch" in package:
+                 pkg1["epoch"] = package["epoch"]
+
+            if "version" in package:
+                 pkg1["version"] = package["version"]
+
+            if "release" in package:
+                 pkg1["release"] = package["release"]
+
+            if "architecture" in package:
+                 pkg1["architecture"] = package["architecture"]
+
+            if ("package_role" in package and
+                package["package_role"] == "affected"):
+                 ureport1["installed_package"] = pkg1
+            else:
+                 ureport1["related_packages"].append({"installed_package": pkg1})
+
+    if "problem" in ureport2:
+        prob = ureport2["problem"]
+        if "type" in prob:
+            if prob["type"].lower() == "core":
+                ureport1["type"] = "userspace"
+            else:
+                ureport1["type"] = prob["type"]
+
+        if "component" in prob:
+            ureport1["component"] = prob["component"]
+
+        if "executable" in prob:
+            ureport1["executable"] = prob["executable"]
+
+        if "user" in prob:
+            user = prob["user"]
+
+            if "root" in user and user["root"]:
+                ureport1["user_type"] = "root"
+            elif "local" in user and not user["local"]:
+                ureport1["user_type"] = "remote"
+            else:
+                ureport1["user_type"] = "local"
+
+        if "stacktrace" in prob or "frames" in prob:
+            ureport1["core_backtrace"] = []
+
+            if ureport1["type"] == "userspace":
+                threads = prob["stacktrace"]
+            elif ureport1["type"] == "kerneloops":
+                threads = [{ "crash_thread": True,
+                             "frames": prob["frames"], }]
+            else:
+                threads = [{ "crash_thread": True,
+                             "frames": prob["stacktrace"], }]
+
+            tid = 0
+            for thread in threads:
+                tid += 1
+
+                if "crash_thread" in thread and thread["crash_thread"]:
+                    ureport1["crash_thread"] = tid
+
+                fid = 0
+                for frame in thread["frames"]:
+                    fid += 1
+
+                    new_frame = { "thread": tid, "frame": fid, }
+
+                    if ureport1["type"] == "userspace":
+                        if "build_id" in frame:
+                            new_frame["buildid"] = frame["build_id"]
+
+                        if "build_id_offset" in frame:
+                            new_frame["offset"] = frame["build_id_offset"]
+
+                        if "file_name" in frame:
+                            new_frame["path"] = frame["file_name"]
+
+                        if "fingerprint" in frame:
+                            new_frame["funchash"] = frame["fingerprint"]
+
+                        if "function_name" in frame:
+                            new_frame["funcname"] = frame["function_name"]
+                        else:
+                            new_frame["funcname"] = "??"
+                    elif ureport1["type"] == "kerneloops":
+                        new_frame["buildid"] = ("{0}-{1}.{2}"
+                            .format(ureport1["installed_package"]["version"],
+                                    ureport1["installed_package"]["release"],
+                                    ureport1["installed_package"]["architecture"]))
+
+                        if ureport1["installed_package"]["name"].startswith("kernel-"):
+                            new_frame["buildid"] += (".{0}"
+                                .format(ureport1["installed_package"]["name"][7:]))
+
+                        if "function_name" in frame:
+                            new_frame["funcname"] = frame["function_name"]
+
+                        if "reliable" in frame and not frame["reliable"]:
+                            new_frame["funchash"] = "?"
+
+                        if "function_offset" in frame:
+                            new_frame["offset"] = frame["function_offset"]
+
+                        if "module_name" in frame:
+                            new_frame["path"] = frame["module_name"]
+                        else:
+                            new_frame["path"] = "vmlinux"
+                    elif ureport1["type"] == "python":
+                        if "file_name" in frame:
+                            new_frame["path"] = frame["file_name"]
+
+                        if "special_file" in frame:
+                            new_frame["path"] = ("<{0}>"
+                                .format(frame["special_file"]))
+
+                        if "file_line" in frame:
+                            new_frame["offset"] = frame["file_line"]
+
+                        if "function_name" in frame:
+                            new_frame["funcname"] = frame["function_name"]
+
+                        if "special_function" in frame:
+                            new_frame["funcname"] = ("<{0}>"
+                                .format(frame["special_function"]))
+                    else:
+                        raise ValueError, ("type '{0}' is not supported"
+                                           .format(ureport1["type"]))
+
+                    ureport1["core_backtrace"].append(new_frame)
+
+    if "reason" in ureport2:
+        ureport1["reason"] = ureport2["reason"]
+
+    return ureport1
+
 def validate(obj, checker=UREPORT_CHECKER):
+    if (checker == UREPORT_CHECKER and
+        "ureport_version" in obj and
+        obj["ureport_version"] == 2):
+        obj = ureport2to1(obj)
+
     expected = dict
     if "type" in checker and isinstance(checker["type"], type):
         expected = checker["type"]
-- 
1.7.11.7



More information about the Crash-catcher mailing list