11import dataclasses
2- import json
3- import os
42import traceback
53from typing import List
6- import re
7-
8- import yaml
94
105from praktika .result import Result
116
149TIMEOUT_SIGN = "[ Timeout! "
1510UNKNOWN_SIGN = "[ UNKNOWN "
1611SKIPPED_SIGN = "[ SKIPPED "
12+ BROKEN_SIGN = "[ BROKEN "
1713HUNG_SIGN = "Found hung queries in processlist"
1814SERVER_DIED_SIGN = "Server died, terminating all processes"
1915SERVER_DIED_SIGN2 = "Server does not respond to health check"
3329# out.writerow(status)
3430
3531
36- def get_broken_tests_rules () -> dict :
37- broken_tests_file_path = "tests/broken_tests.yaml"
38- if (
39- not os .path .isfile (broken_tests_file_path )
40- or os .path .getsize (broken_tests_file_path ) == 0
41- ):
42- raise ValueError (
43- "There is something wrong with getting broken tests rules: "
44- f"file '{ broken_tests_file_path } ' is empty or does not exist."
45- )
46-
47- with open (broken_tests_file_path , "r" , encoding = "utf-8" ) as broken_tests_file :
48- broken_tests = yaml .safe_load (broken_tests_file )
49-
50- compiled_rules = {"exact" : {}, "pattern" : {}}
51-
52- for test in broken_tests :
53- regex = test .get ("regex" ) is True
54- rule = {
55- "reason" : test ["reason" ],
56- }
57-
58- if test .get ("message" ):
59- rule ["message" ] = re .compile (test ["message" ]) if regex else test ["message" ]
60-
61- if test .get ("not_message" ):
62- rule ["not_message" ] = (
63- re .compile (test ["not_message" ]) if regex else test ["not_message" ]
64- )
65- if test .get ("check_types" ):
66- rule ["check_types" ] = test ["check_types" ]
67-
68- if regex :
69- rule ["regex" ] = True
70- compiled_rules ["pattern" ][re .compile (test ["name" ])] = rule
71- else :
72- compiled_rules ["exact" ][test ["name" ]] = rule
73-
74- print (
75- f"INFO: Compiled { len (compiled_rules ['exact' ])} exact rules and { len (compiled_rules ['pattern' ])} pattern rules"
76- )
77-
78- return compiled_rules
79-
80-
81- def test_is_known_fail (test_name , test_logs , known_broken_tests , test_options_string ):
82- matching_rules = []
83-
84- print (f"Checking known broken tests for failed test: { test_name } " )
85- print ("Potential matching rules:" )
86- exact_rule = known_broken_tests ["exact" ].get (test_name )
87- if exact_rule :
88- print (f"{ test_name } - { exact_rule } " )
89- matching_rules .append (exact_rule )
90-
91- for name_re , data in known_broken_tests ["pattern" ].items ():
92- if name_re .fullmatch (test_name ):
93- print (f"{ name_re } - { data } " )
94- matching_rules .append (data )
95-
96- if not matching_rules :
97- return False
98-
99- def matches_substring (substring , log , is_regex ):
100- if log is None :
101- return False
102- if is_regex :
103- return bool (substring .search (log ))
104- return substring in log
105-
106- for rule_data in matching_rules :
107- if rule_data .get ("check_types" ) and not any (
108- ct in test_options_string for ct in rule_data ["check_types" ]
109- ):
110- print (
111- f"Check types didn't match: '{ rule_data ['check_types' ]} ' not in '{ test_options_string } '"
112- )
113- continue # check_types didn't match → skip rule
114-
115- is_regex = rule_data .get ("regex" , False )
116- not_message = rule_data .get ("not_message" )
117- if not_message and matches_substring (not_message , test_logs , is_regex ):
118- print (f"Skip rule: Not message matched: '{ rule_data ['not_message' ]} '" )
119- continue # not_message matched → skip rule
120- message = rule_data .get ("message" )
121- if message and not matches_substring (message , test_logs , is_regex ):
122- print (f"Skip rule: Message didn't match: '{ rule_data ['message' ]} '" )
123- continue
124-
125- print (f"Test { test_name } matched rule: { rule_data } " )
126- return rule_data ["reason" ]
127-
128- return False
129-
130-
13132class FTResultsProcessor :
13233 @dataclasses .dataclass
13334 class Summary :
@@ -163,8 +64,6 @@ def _process_test_output(self):
16364 test_results = []
16465 test_end = True
16566
166- known_broken_tests = get_broken_tests_rules ()
167-
16867 with open (self .tests_output_file , "r" , encoding = "utf-8" ) as test_file :
16968 for line in test_file :
17069 original_line = line
@@ -183,7 +82,13 @@ def _process_test_output(self):
18382 retries = True
18483 if any (
18584 sign in line
186- for sign in (OK_SIGN , FAIL_SIGN , UNKNOWN_SIGN , SKIPPED_SIGN )
85+ for sign in (
86+ OK_SIGN ,
87+ FAIL_SIGN ,
88+ UNKNOWN_SIGN ,
89+ SKIPPED_SIGN ,
90+ BROKEN_SIGN ,
91+ )
18792 ):
18893 test_name = line .split (" " )[2 ].split (":" )[0 ]
18994
@@ -216,13 +121,16 @@ def _process_test_output(self):
216121 elif SKIPPED_SIGN in line :
217122 skipped += 1
218123 test_results .append ((test_name , "SKIPPED" , test_time , []))
124+ elif BROKEN_SIGN in line :
125+ broken += 1
126+ test_results .append ((test_name , "BROKEN" , test_time , []))
219127 else :
220128 success += int (OK_SIGN in line )
221129 test_results .append ((test_name , "OK" , test_time , []))
222130 test_end = False
223131 elif (
224132 len (test_results ) > 0
225- and test_results [- 1 ][1 ] in ("FAIL" , "SKIPPED" )
133+ and test_results [- 1 ][1 ] in ("FAIL" , "SKIPPED" , "BROKEN" )
226134 and not test_end
227135 ):
228136 test_results [- 1 ][3 ].append (original_line )
@@ -233,8 +141,6 @@ def _process_test_output(self):
233141 if DATABASE_SIGN in line :
234142 test_end = True
235143
236- test_options_string = ", " .join (self .test_options )
237-
238144 test_results_ = []
239145 for test in test_results :
240146 try :
@@ -248,21 +154,6 @@ def _process_test_output(self):
248154 )
249155 )
250156
251- if test [1 ] == "FAIL" :
252- broken_message = test_is_known_fail (
253- test [0 ],
254- test_results_ [- 1 ].info ,
255- known_broken_tests ,
256- test_options_string ,
257- )
258-
259- if broken_message :
260- broken += 1
261- failed -= 1
262- test_results_ [- 1 ].set_status (Result .StatusExtended .BROKEN )
263- test_results_ [- 1 ].set_label (Result .Label .BROKEN )
264- test_results_ [- 1 ].info += "\n Marked as broken: " + broken_message
265-
266157 except Exception as e :
267158 print (f"ERROR: Failed to parse test results: { test } " )
268159 traceback .print_exc ()
0 commit comments