@@ -35,31 +35,48 @@ def __init__(self, plan: dict | None = None, table: str | None = None, ast: str
35
35
class WorkloadRunResult :
36
36
def __init__ (
37
37
self , stats : dict [str , dict [str , any ]] = {}, query_out : str = None , stdout : str = None , stderr : str = None ,
38
- error_message : str | None = None , plan : YdbCliHelper .QueuePlan | None = None
38
+ error_message : str | None = None , plans : list [YdbCliHelper .QueuePlan ] | None = None ,
39
+ errors_by_iter : dict [int , str ] | None = None
39
40
) -> None :
40
41
self .stats = stats
41
42
self .query_out = query_out if str != '' else None
42
43
self .stdout = stdout if stdout != '' else None
43
44
self .stderr = stderr if stderr != '' else None
44
45
self .success = error_message is None
45
46
self .error_message = '' if self .success else error_message
46
- self .plan = plan
47
+ self .plans = plans
48
+ self .errors_by_iter = errors_by_iter
47
49
48
50
@staticmethod
49
51
def workload_run (type : WorkloadType , path : str , query_num : int , iterations : int = 5 ,
50
52
timeout : float = 100. ) -> YdbCliHelper .WorkloadRunResult :
51
53
def _try_extract_error_message (stderr : str ) -> str :
54
+ result = {}
52
55
begin_str = f'{ query_num } :'
53
56
end_str = 'Query text:'
57
+ iter_str = 'iteration '
54
58
begin_pos = stderr .find (begin_str )
55
59
if begin_pos < 0 :
56
- return ''
57
- begin_pos += len (begin_str )
58
- end_pos = stderr .find (end_str , begin_pos )
59
- if end_pos < 0 :
60
- return stderr [begin_pos :].strip ()
61
- return stderr [begin_pos :end_pos ].strip ()
60
+ return result
61
+ while True :
62
+ begin_pos = stderr .find (iter_str , begin_pos )
63
+ if begin_pos < 0 :
64
+ return result
65
+ begin_pos += len (iter_str )
66
+ end_pos = stderr .find ('\n ' , begin_pos )
67
+ if end_pos < 0 :
68
+ iter = int (stderr [begin_pos :])
69
+ begin_pos = len (stderr ) - 1
70
+ else :
71
+ iter = int (stderr [begin_pos :end_pos ])
72
+ begin_pos = end_pos + 1
73
+ end_pos = stderr .find (end_str , begin_pos )
74
+ if end_pos < 0 :
75
+ result [iter ] = stderr [begin_pos :].strip ()
76
+ else :
77
+ result [iter ] = stderr [begin_pos :end_pos ].strip ()
62
78
79
+ errors_by_iter = {}
63
80
try :
64
81
wait_error = YdbCluster .wait_ydb_alive (300 , path )
65
82
if wait_error is not None :
@@ -88,7 +105,8 @@ def _try_extract_error_message(stderr: str) -> str:
88
105
exec : yatest .common .process ._Execution = yatest .common .process .execute (cmd , wait = False , check_exit_code = False )
89
106
exec .wait (check_exit_code = False , timeout = timeout )
90
107
if exec .returncode != 0 :
91
- err = _try_extract_error_message (exec .stderr .decode ('utf-8' ))
108
+ errors_by_iter = _try_extract_error_message (exec .stderr .decode ('utf-8' ))
109
+ err = '\n \n ' .join ([f'Iteration { i } : { e } ' for i , e in errors_by_iter .items ()])
92
110
if not err :
93
111
err = f'Invalid return code: { exec .returncode } instesd 0.'
94
112
except (yatest .common .process .TimeoutError , yatest .common .process .ExecutionTimeoutError ):
@@ -107,27 +125,31 @@ def _try_extract_error_message(stderr: str) -> str:
107
125
if (os .path .exists (qout_path )):
108
126
with open (qout_path , 'r' ) as r :
109
127
qout = r .read ()
110
- plan = YdbCliHelper .QueuePlan ()
111
- if (os .path .exists (plan_path + '.json' )):
112
- with open (plan_path + '.json' ) as f :
113
- plan .plan = json .load (f )
114
- if (os .path .exists (plan_path + '.table' )):
115
- with open (plan_path + '.table' ) as f :
116
- plan .table = f .read ()
117
- if (os .path .exists (plan_path + '.ast' )):
118
- with open (plan_path + '.ast' ) as f :
119
- plan .ast = f .read ()
120
- if (os .path .exists (plan_path + '.svg' )):
121
- with open (plan_path + '.svg' ) as f :
122
- plan .svg = f .read ()
128
+ plans = []
129
+ for i in range (iterations ):
130
+ plans .append (YdbCliHelper .QueuePlan ())
131
+ pp = f'{ plan_path } .{ i } '
132
+ if (os .path .exists (f'{ pp } .json' )):
133
+ with open (f'{ pp } .json' ) as f :
134
+ plans [i ].plan = json .load (f )
135
+ if (os .path .exists (f'{ pp } .table' )):
136
+ with open (f'{ pp } .table' ) as f :
137
+ plans [i ].table = f .read ()
138
+ if (os .path .exists (f'{ pp } .ast' )):
139
+ with open (f'{ pp } .ast' ) as f :
140
+ plans [i ].ast = f .read ()
141
+ if (os .path .exists (f'{ pp } .svg' )):
142
+ with open (f'{ pp } .svg' ) as f :
143
+ plans [i ].svg = f .read ()
123
144
124
145
return YdbCliHelper .WorkloadRunResult (
125
146
stats = stats ,
126
147
query_out = qout ,
127
- plan = plan ,
148
+ plans = plans ,
128
149
stdout = exec .stdout .decode ('utf-8' ),
129
150
stderr = exec .stderr .decode ('utf-8' ),
130
- error_message = err
151
+ error_message = err ,
152
+ errors_by_iter = errors_by_iter
131
153
)
132
154
except BaseException as e :
133
155
return YdbCliHelper .WorkloadRunResult (error_message = str (e ))
0 commit comments