5
5
import os
6
6
import sys
7
7
import urllib .parse
8
+ import zipfile
8
9
from xml .etree import ElementTree as ET
9
10
from mute_utils import mute_target , pattern_to_re
10
11
from junit_utils import add_junit_link_property , is_faulty_testcase
@@ -53,6 +54,10 @@ class YTestReportTrace:
53
54
def __init__ (self , out_root ):
54
55
self .out_root = out_root
55
56
self .traces = {}
57
+ self .logs_dir = None
58
+
59
+ def abs_path (self , path ):
60
+ return path .replace ("$(BUILD_ROOT)" , self .out_root )
56
61
57
62
def load (self , subdir ):
58
63
test_results_dir = os .path .join (self .out_root , f"{ subdir } /test-results/" )
@@ -61,6 +66,7 @@ def load(self, subdir):
61
66
log_print (f"Directory { test_results_dir } doesn't exist" )
62
67
return
63
68
69
+ # find the test result
64
70
for folder in os .listdir (test_results_dir ):
65
71
fn = os .path .join (self .out_root , test_results_dir , folder , "ytest.report.trace" )
66
72
@@ -76,6 +82,9 @@ def load(self, subdir):
76
82
subtest = event ["subtest" ]
77
83
cls = cls .replace ("::" , "." )
78
84
self .traces [(cls , subtest )] = event
85
+ logs_dir = self .abs_path (event ['logs' ]['logsdir' ])
86
+ self .logs_dir = logs_dir
87
+ break
79
88
80
89
def has (self , cls , name ):
81
90
return (cls , name ) in self .traces
@@ -93,7 +102,7 @@ def get_logs(self, cls, name):
93
102
if k == "logsdir" :
94
103
continue
95
104
96
- result [k ] = path . replace ( "$(BUILD_ROOT)" , self .out_root )
105
+ result [k ] = self .abs_path ( path )
97
106
98
107
return result
99
108
@@ -135,7 +144,26 @@ def save_log(build_root, fn, out_dir, log_url_prefix, trunc_size):
135
144
return f"{ log_url_prefix } { quoted_fpath } "
136
145
137
146
138
- def transform (fp , mute_check : YaMuteCheck , ya_out_dir , save_inplace , log_url_prefix , log_out_dir , log_trunc_size ):
147
+ def save_zip (suite_name , out_dir , url_prefix , logs_dir ):
148
+ arc_name = f"{ suite_name .replace ('/' , '-' )} .zip"
149
+
150
+ arc_fn = os .path .join (out_dir , arc_name )
151
+
152
+ zf = zipfile .ZipFile (arc_fn , mode = "w" , compression = zipfile .ZIP_DEFLATED , compresslevel = 9 )
153
+
154
+ log_print (f"put { logs_dir } into { arc_name } " )
155
+ for root , dirs , files in os .walk (logs_dir ):
156
+ for f in files :
157
+ filename = os .path .join (root , f )
158
+ zf .write (filename , os .path .relpath (filename , logs_dir ))
159
+ zf .close ()
160
+
161
+ quoted_fpath = urllib .parse .quote (arc_name )
162
+ return f"{ url_prefix } { quoted_fpath } "
163
+
164
+
165
+ def transform (fp , mute_check : YaMuteCheck , ya_out_dir , save_inplace , log_url_prefix , log_out_dir , log_trunc_size ,
166
+ test_stuff_out , test_stuff_prefix ):
139
167
tree = ET .parse (fp )
140
168
root = tree .getroot ()
141
169
@@ -144,11 +172,14 @@ def transform(fp, mute_check: YaMuteCheck, ya_out_dir, save_inplace, log_url_pre
144
172
traces = YTestReportTrace (ya_out_dir )
145
173
traces .load (suite_name )
146
174
175
+ has_fail_tests = False
176
+
147
177
for case in suite .findall ("testcase" ):
148
178
test_name = case .get ("name" )
149
179
case .set ("classname" , suite_name )
150
180
151
181
is_fail = is_faulty_testcase (case )
182
+ has_fail_tests |= is_fail
152
183
153
184
if mute_check (suite_name , test_name ):
154
185
log_print ("mute" , suite_name , test_name )
@@ -164,6 +195,16 @@ def transform(fp, mute_check: YaMuteCheck, ya_out_dir, save_inplace, log_url_pre
164
195
url = save_log (ya_out_dir , fn , log_out_dir , log_url_prefix , log_trunc_size )
165
196
add_junit_link_property (case , name , url )
166
197
198
+ if has_fail_tests :
199
+ if not traces .logs_dir :
200
+ log_print (f"no logsdir for { suite_name } " )
201
+ continue
202
+
203
+ url = save_zip (suite_name , test_stuff_out , test_stuff_prefix , traces .logs_dir )
204
+
205
+ for case in suite .findall ("testcase" ):
206
+ add_junit_link_property (case , 'logsdir' , url )
207
+
167
208
if save_inplace :
168
209
tree .write (fp .name )
169
210
else :
@@ -187,6 +228,8 @@ def main():
187
228
help = "truncate log after specific size, 0 disables truncation" ,
188
229
)
189
230
parser .add_argument ("--ya-out" , help = "ya make output dir (for searching logs and artifacts)" )
231
+ parser .add_argument ('--test-stuff-out' , help = 'output folder for archive testing_out_stuff' )
232
+ parser .add_argument ('--test-stuff-prefix' , help = 'url prefix for testing_out_stuff' )
190
233
parser .add_argument ("in_file" , type = argparse .FileType ("r" ))
191
234
192
235
args = parser .parse_args ()
@@ -204,6 +247,8 @@ def main():
204
247
args .log_url_prefix ,
205
248
args .log_out_dir ,
206
249
args .log_trunc_size ,
250
+ args .test_stuff_out ,
251
+ args .test_stuff_prefix ,
207
252
)
208
253
209
254
0 commit comments