Coverage for lobster/tools/gtest/gtest.py: 0%
88 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-26 14:55 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-26 14:55 +0000
1#!/usr/bin/env python3
2#
3# lobster_gtest - Extract GoogleTest tracing tags for LOBSTER
4# Copyright (C) 2022-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU Affero General Public License as
8# published by the Free Software Foundation, either version 3 of the
9# License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14# Affero General Public License for more details.
15#
16# You should have received a copy of the GNU Affero General Public
17# License along with this program. If not, see
18# <https://www.gnu.org/licenses/>.
20import sys
21import argparse
22import os.path
23import xml.etree.ElementTree as ET
25from lobster.items import Tracing_Tag, Activity
26from lobster.location import Void_Reference, File_Reference
27from lobster.io import lobster_write
28from lobster.version import get_version
30ap = argparse.ArgumentParser()
33@get_version(ap)
34def main():
35 # lobster-trace: gtest_req.Dummy_Requirement
36 ap.add_argument("files",
37 nargs="+",
38 metavar="FILE|DIR")
39 ap.add_argument("--out", default=None)
41 options = ap.parse_args()
43 c_files_rel = {}
44 file_list = []
45 for item in options.files:
46 if os.path.isfile(item):
47 file_list.append(item)
48 elif os.path.isdir(item):
49 for path, _, files in os.walk(item, followlinks=True):
50 for filename in files:
51 if not os.path.isfile(os.path.join(path, filename)):
52 continue
53 _, ext = os.path.splitext(filename)
54 if ext in (".xml", ):
55 file_list.append(os.path.join(path, filename))
56 elif ext in (".cpp", ".cc", ".c"):
57 fullname = os.path.relpath(
58 os.path.realpath(os.path.join(path, filename)))
59 if ".cache" in fullname:
60 continue
61 if filename not in c_files_rel:
62 c_files_rel[filename] = set()
63 c_files_rel[filename].add(fullname)
65 else:
66 ap.error("%s is not a file or directory" % item)
68 file_list = {os.path.realpath(os.path.abspath(f))
69 for f in file_list}
71 items = []
73 for filename in file_list:
74 tree = ET.parse(filename)
75 root = tree.getroot()
76 if root.tag != "testsuites":
77 continue
78 for suite in root:
79 assert suite.tag == "testsuite"
80 suite_name = suite.attrib["name"]
81 for testcase in suite:
82 if testcase.tag != "testcase":
83 continue
84 test_name = testcase.attrib["name"]
85 test_executed = testcase.attrib["status"] == "run"
86 test_ok = True
87 test_tags = []
88 source_file = testcase.attrib.get("file", None)
89 source_line = int(testcase.attrib["line"]) \
90 if "line" in testcase.attrib \
91 else None
92 for props in testcase:
93 if props.tag == "failure":
94 test_ok = False
95 elif props.tag == "properties":
96 for prop in props:
97 assert prop.tag == "property"
98 if prop.attrib["name"] == "lobster-tracing":
99 test_tags += [
100 x.strip()
101 for x in prop.attrib["value"].split(",")]
102 elif prop.attrib["name"] == "lobster-tracing-file":
103 source_file = prop.attrib["value"]
104 elif prop.attrib["name"] == "lobster-tracing-line":
105 source_line = int(prop.attrib["value"])
107 if source_file in c_files_rel and \
108 len(c_files_rel[source_file]) == 1:
109 test_source = File_Reference(
110 filename = list(c_files_rel[source_file])[0],
111 line = source_line)
112 elif source_file is None:
113 test_source = Void_Reference()
114 else:
115 test_source = File_Reference(
116 filename = source_file,
117 line = source_line)
119 uid = "%s:%s" % (suite_name, test_name)
120 if test_executed:
121 if test_ok:
122 status = "ok"
123 else:
124 status = "fail"
125 else:
126 status = "not run"
128 tag = Tracing_Tag("gtest", uid)
129 item = Activity(tag = tag,
130 location = test_source,
131 framework = "GoogleTest",
132 kind = "test",
133 status = status)
134 for ref in test_tags:
135 item.add_tracing_target(Tracing_Tag("req", ref))
137 items.append(item)
139 if options.out:
140 with open(options.out, "w", encoding="UTF-8") as fd:
141 lobster_write(fd, Activity, "lobster_gtest", items)
142 print("Written output for %u items to %s" % (len(items),
143 options.out))
144 else:
145 lobster_write(sys.stdout, Activity, "lobster_gtest", items)
146 print()
149if __name__ == "__main__":
150 sys.exit(main())