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

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/>. 

19 

20import sys 

21import argparse 

22import os.path 

23import xml.etree.ElementTree as ET 

24 

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 

29 

30ap = argparse.ArgumentParser() 

31 

32 

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) 

40 

41 options = ap.parse_args() 

42 

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) 

64 

65 else: 

66 ap.error("%s is not a file or directory" % item) 

67 

68 file_list = {os.path.realpath(os.path.abspath(f)) 

69 for f in file_list} 

70 

71 items = [] 

72 

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"]) 

106 

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) 

118 

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" 

127 

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)) 

136 

137 items.append(item) 

138 

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() 

147 

148 

149if __name__ == "__main__": 

150 sys.exit(main())