Skip to content

Commit 1d7807f

Browse files
authored
Fix iterations reporting (#10792)
1 parent cb09349 commit 1d7807f

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

ydb/tests/olap/lib/ydb_cli.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import yatest.common
44
import json
55
import os
6+
import re
67
from ydb.tests.olap.lib.ydb_cluster import YdbCluster
78
from ydb.tests.olap.lib.utils import get_external_param
89
from enum import StrEnum
@@ -39,12 +40,13 @@ class WorkloadRunResult:
3940
def __init__(self):
4041
self.stats: dict[str, dict[str, Any]] = {}
4142
self.query_out: Optional[str] = None
42-
self.stdout: Optional[str] = None
43-
self.stderr: Optional[str] = None
43+
self.stdout: str = ''
44+
self.stderr: str = ''
4445
self.error_message: str = ''
4546
self.plans: Optional[list[YdbCliHelper.QueryPlan]] = None
4647
self.explain_plan: Optional[YdbCliHelper.QueryPlan] = None
4748
self.errors_by_iter: dict[int, str] = {}
49+
self.time_by_iter: dict[int, float] = {}
4850
self.traceback: Optional[TracebackType] = None
4951

5052
@property
@@ -81,26 +83,26 @@ def _add_error(self, msg: Optional[str]):
8183
else:
8284
self.result.error_message = msg
8385

84-
def _process_returncode(self, returncode, stderr: str) -> None:
86+
def _process_returncode(self, returncode) -> None:
8587
begin_str = f'{self.query_num}:'
8688
end_str = 'Query text:'
8789
iter_str = 'iteration '
88-
begin_pos = stderr.find(begin_str)
90+
begin_pos = self.result.stderr.find(begin_str)
8991
if begin_pos >= 0:
9092
while True:
91-
begin_pos = stderr.find(iter_str, begin_pos)
93+
begin_pos = self.result.stderr.find(iter_str, begin_pos)
9294
if begin_pos < 0:
9395
break
9496
begin_pos += len(iter_str)
95-
end_pos = stderr.find('\n', begin_pos)
97+
end_pos = self.result.stderr.find('\n', begin_pos)
9698
if end_pos < 0:
97-
iter = int(stderr[begin_pos:])
98-
begin_pos = len(stderr) - 1
99+
iter = int(self.result.stderr[begin_pos:])
100+
begin_pos = len(self.result.stderr) - 1
99101
else:
100-
iter = int(stderr[begin_pos:end_pos])
102+
iter = int(self.result.stderr[begin_pos:end_pos])
101103
begin_pos = end_pos + 1
102-
end_pos = stderr.find(end_str, begin_pos)
103-
msg = (stderr[begin_pos:] if end_pos < 0 else stderr[begin_pos:end_pos]).strip()
104+
end_pos = self.result.stderr.find(end_str, begin_pos)
105+
msg = (self.result.stderr[begin_pos:] if end_pos < 0 else self.result.stderr[begin_pos:end_pos]).strip()
104106
self.result.errors_by_iter[iter] = msg
105107
self._add_error(f'Iteration {iter}: {msg}')
106108
if returncode != 0 and len(self.result.errors_by_iter) == 0:
@@ -167,6 +169,12 @@ def _check_nodes(self):
167169
node_errors.append(f'Node {node} is down')
168170
self._add_error('\n'.join(node_errors))
169171

172+
def _parse_stdout(self):
173+
for line in self.result.stdout.splitlines():
174+
m = re.search(r'iteration ([0-9]*):\s*ok\s*([\.0-9]*)s', line)
175+
if m is not None:
176+
self.result.time_by_iter[int(m.group(1))] = float(m.group(2))
177+
170178
def _get_cmd(self) -> list[str]:
171179
cmd = YdbCliHelper.get_cli_command() + [
172180
'-e', YdbCluster.ydb_endpoint,
@@ -192,7 +200,8 @@ def _exec_cli(self) -> None:
192200
process = yatest.common.process.execute(self._get_cmd(), check_exit_code=False)
193201
self.result.stdout = process.stdout.decode('utf-8', 'replace')
194202
self.result.stderr = process.stderr.decode('utf-8', 'replace')
195-
self._process_returncode(process.returncode, self.result.stderr)
203+
self._process_returncode(process.returncode)
204+
self._parse_stdout()
196205

197206
def process(self) -> YdbCliHelper.WorkloadRunResult:
198207
try:

ydb/tests/olap/load/conftest.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ def _get_duraton(stats, field):
7171
result = stats.get(field)
7272
return float(result) / 1e3 if result is not None else None
7373

74+
def _duration_text(duration: float | int):
75+
s = f'{int(duration)}s ' if duration >= 1 else ''
76+
return f'{s}{int(duration * 1000) % 1000}ms'
77+
7478
def _attach_plans(plan: YdbCliHelper.QueryPlan) -> None:
7579
if plan.plan is not None:
7680
allure.attach(json.dumps(plan.plan), 'Plan json', attachment_type=allure.attachment_type.JSON)
@@ -95,10 +99,15 @@ def _attach_plans(plan: YdbCliHelper.QueryPlan) -> None:
9599
_attach_plans(result.explain_plan)
96100

97101
if result.plans is not None:
98-
for i in range(self._get_iterations(query_num)):
102+
for i in range(iterations):
103+
s = allure.step(f'Iteration {i}')
104+
if i in result.time_by_iter:
105+
s.params['duration'] = _duration_text(result.time_by_iter[i])
99106
try:
100-
with allure.step(f'Iteration {i}'):
107+
with s:
101108
_attach_plans(result.plans[i])
109+
if i in result.time_by_iter:
110+
allure.dynamic.parameter('duration', _duration_text(result.time_by_iter[i]))
102111
if i in result.errors_by_iter:
103112
pytest.fail(result.errors_by_iter[i])
104113
except BaseException:
@@ -120,9 +129,7 @@ def _attach_plans(plan: YdbCliHelper.QueryPlan) -> None:
120129
allure.attach(result.stderr, 'Stderr', attachment_type=allure.attachment_type.TEXT)
121130
for p in ['Mean']:
122131
if p in stats:
123-
value = int(stats[p])
124-
s = f'{int(value / 1000)}s ' if value >= 1000 else ''
125-
allure.dynamic.parameter(p, f'{s}{value % 1000}ms')
132+
allure.dynamic.parameter(p, _duration_text(stats[p] / 1000.))
126133
error_message = ''
127134
success = True
128135
if not result.success:
@@ -191,4 +198,4 @@ def run_workload_test(self, path: str, query_num: int) -> None:
191198
check_canonical=self.check_canonical
192199
)
193200
allure_test_description(self.suite, self._test_name(query_num), refference_set=self.refference, start_time=start_time, end_time=time())
194-
self.process_query_result(result, query_num, self.iterations, True)
201+
self.process_query_result(result, query_num, self._get_iterations(query_num), True)

0 commit comments

Comments
 (0)