Skip to content

Commit c7f516e

Browse files
committed
[MOB-46781] Parse actionId for errors
- Jira: https://perforce.atlassian.net/browse/MOB-46781
1 parent 10fae44 commit c7f516e

File tree

4 files changed

+237
-24
lines changed

4 files changed

+237
-24
lines changed

bzt/modules/_apiritif/generator.py

Lines changed: 149 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,100 @@ def create_method_name(label):
6262

6363

6464
class ApiritifScriptGenerator(object):
65+
def _gen_class_actionid_tracking(self):
66+
# Add _current_actionId to the class and update it on each action_start
67+
return [
68+
ast.Assign(
69+
targets=[ast_attr("self._current_actionId")],
70+
value=ast.Constant(value=None, kind="")
71+
)
72+
]
73+
74+
def _gen_action_start_with_tracking(self, actionId):
75+
# Assign actionId to self._current_actionId before action_start
76+
return [
77+
ast.Assign(
78+
targets=[ast_attr("self._current_actionId")],
79+
value=ast.Constant(value=actionId, kind="")
80+
)
81+
]
82+
83+
def _gen_teardown_with_actionid(self):
84+
# Print the last actionId if an error/failure occurred
85+
return ast.FunctionDef(
86+
name="tearDown",
87+
args=[ast.Name(id='self', ctx=ast.Param())],
88+
body=[
89+
ast.Expr(ast_call(
90+
func=ast.Name(id="print", ctx=ast.Load()),
91+
args=[ast.Constant("[TAURUS] tearDown called", kind="")],
92+
keywords=[]
93+
)),
94+
ast.If(
95+
test=ast_attr("self.driver"),
96+
body=[ast.Expr(ast_call(func=ast_attr("self.driver.quit")))],
97+
orelse=[]
98+
),
99+
ast.Assign(
100+
targets=[ast.Name(id="outcome", ctx=ast.Store())],
101+
value=ast.Call(
102+
func=ast.Name(id="getattr", ctx=ast.Load()),
103+
args=[ast.Name(id="self", ctx=ast.Load()), ast.Constant("_outcome", kind=""),
104+
ast.Constant(None, kind="")],
105+
keywords=[]
106+
)
107+
),
108+
ast.Assign(
109+
targets=[ast.Name(id="result", ctx=ast.Store())],
110+
value=ast.Call(
111+
func=ast.Name(id="getattr", ctx=ast.Load()),
112+
args=[ast.Name(id="outcome", ctx=ast.Load()), ast.Constant("result", kind=""),
113+
ast.Constant(None, kind="")],
114+
keywords=[]
115+
)
116+
),
117+
ast.If(
118+
test=ast.BoolOp(
119+
op=ast.And(),
120+
values=[
121+
ast.Name(id="result", ctx=ast.Load()),
122+
ast.BoolOp(
123+
op=ast.Or(),
124+
values=[
125+
ast.Attribute(
126+
value=ast.Name(id="result", ctx=ast.Load()),
127+
attr="errors",
128+
ctx=ast.Load()
129+
),
130+
ast.Attribute(
131+
value=ast.Name(id="result", ctx=ast.Load()),
132+
attr="failures",
133+
ctx=ast.Load()
134+
)
135+
]
136+
)
137+
]
138+
),
139+
body=[
140+
ast.Expr(ast_call(
141+
func=ast.Name(id="print", ctx=ast.Load()),
142+
args=[ast.BinOp(
143+
left=ast.Constant("[TAURUS][actionId] ", kind=""),
144+
op=ast.Add(),
145+
right=ast.Call(
146+
func=ast.Name(id="str", ctx=ast.Load()),
147+
args=[ast_attr("self._current_actionId")],
148+
keywords=[]
149+
)
150+
)],
151+
keywords=[]
152+
))
153+
],
154+
orelse=[]
155+
),
156+
],
157+
decorator_list=[]
158+
)
65159
BYS = {
66160
'xpath': "XPATH",
67161
'css': "CSS_SELECTOR",
@@ -696,6 +790,10 @@ def _gen_action(self, action_config, parent_request=None, index_label=""):
696790

697791
wrapInTransaction = self._is_report_inside_actions(parent_request)
698792

793+
action_tracking = []
794+
if actionId:
795+
action_tracking.extend(self._gen_action_start_with_tracking(actionId))
796+
699797
action_elements = []
700798

701799
if atype in self.EXTERNAL_HANDLER_TAGS:
@@ -781,18 +879,65 @@ def _gen_action(self, action_config, parent_request=None, index_label=""):
781879
if atype.lower() in self.ACTIONS_WITH_WAITER:
782880
action_elements.append(ast_call(func=ast_attr("waiter"), args=[]))
783881

882+
action_body = [ast.Expr(element) for element in action_elements]
883+
if actionId:
884+
prefixed_error = ast.BinOp(
885+
left=ast.BinOp(
886+
left=ast.Constant("[TAURUS][actionId] ", kind=""),
887+
op=ast.Add(),
888+
right=ast.Call(
889+
func=ast.Name(id="str", ctx=ast.Load()),
890+
args=[ast_attr("self._current_actionId")],
891+
keywords=[]
892+
)
893+
),
894+
op=ast.Add(),
895+
right=ast.BinOp(
896+
left=ast.Constant(" | ", kind=""),
897+
op=ast.Add(),
898+
right=ast.Call(
899+
func=ast.Name(id="str", ctx=ast.Load()),
900+
args=[ast.Name(id="exc", ctx=ast.Load())],
901+
keywords=[]
902+
)
903+
)
904+
)
905+
906+
action_body = [ast.Try(
907+
body=action_body,
908+
handlers=[ast.ExceptHandler(
909+
type=ast.Name(id="Exception", ctx=ast.Load()),
910+
name="exc",
911+
body=[ast.Raise(
912+
exc=ast.Call(
913+
func=ast.Call(
914+
func=ast.Name(id="type", ctx=ast.Load()),
915+
args=[ast.Name(id="exc", ctx=ast.Load())],
916+
keywords=[]
917+
),
918+
args=[prefixed_error],
919+
keywords=[]
920+
),
921+
cause=ast.Name(id="exc", ctx=ast.Load())
922+
)]
923+
)],
924+
orelse=[],
925+
finalbody=[]
926+
)]
927+
784928
if wrapInTransaction:
785929
label = self._create_action_label(parent_request.label, index_label, action)
786930

931+
body = action_tracking + action_body
787932
return [ast.With(
788933
items=[ast.withitem(
789934
context_expr=ast_call(
790935
func=ast_attr("apiritif.transaction"),
791936
args=[self._gen_expr(label)]),
792937
optional_vars=None)],
793-
body=[ast.Expr(element) for element in action_elements])]
938+
body=body)]
794939

795-
return [ast.Expr(element) for element in action_elements]
940+
return action_tracking + action_body
796941

797942
def _gen_foreach_mngr(self, action_config):
798943
self.selenium_extras.add("get_elements")
@@ -1706,6 +1851,7 @@ def _gen_classdef(self):
17061851

17071852
def _gen_class_setup(self):
17081853
data_sources = [self._gen_default_vars()]
1854+
data_sources.extend(self._gen_class_actionid_tracking())
17091855
for idx in range(len(self.data_sources)):
17101856
data_sources.append(ast.Expr(ast_call(func=ast_attr("reader_%s.read_vars" % (idx + 1)))))
17111857

@@ -1783,12 +1929,7 @@ def _gen_class_setup(self):
17831929
return [setup, gen_empty_line_stmt()]
17841930

17851931
def _gen_class_teardown(self):
1786-
body = [
1787-
ast.If(
1788-
test=ast_attr("self.driver"),
1789-
body=ast.Expr(ast_call(func=ast_attr("self.driver.quit"))), orelse=[])]
1790-
1791-
return ast.FunctionDef(name="tearDown", args=[ast_attr("self")], body=body, decorator_list=[])
1932+
return self._gen_teardown_with_actionid()
17921933

17931934
def _nfc_preprocess(self, requests):
17941935
setup = []

bzt/modules/aggregator.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ def __init__(self, perc_levels=(), hist_max_rt=1000.0, ext_aggregation=False):
232232
self[KPISet.RESP_CODES] = Counter()
233233
self[KPISet.PERCENTILES] = {}
234234
self.ext_aggregation = ext_aggregation
235+
self.log = logging.getLogger(self.__class__.__name__)
235236

236237
def __deepcopy__(self, memo):
237238
mycopy = KPISet(self.perc_levels, self[KPISet.RESP_TIMES].high)
@@ -248,10 +249,12 @@ def __deepcopy__(self, memo):
248249
@staticmethod
249250
def error_item_skel(
250251
error: str, ret_c: str, cnt: int, err_type: int,
251-
urls: Counter, tag: str, err_resp_data: Optional[ErrorResponseData] = None) -> dict:
252+
urls: Counter, tag: str, err_resp_data: Optional[ErrorResponseData] = None, action_id: str = None) -> dict:
252253
assert isinstance(urls, collections.Counter)
254+
logging.getLogger("DEV DEV").info("In error_item_skel, err_resp_data: {}".format(err_resp_data))
253255
response_bodies = KPISet._get_response_bodies(err_resp_data)
254-
return {
256+
logging.getLogger("DEV DEV").info("In error_item_skel, response_bodies: {}".format(response_bodies))
257+
item = {
255258
"cnt": cnt,
256259
"msg": error,
257260
"tag": tag, # just one more string qualifier
@@ -260,6 +263,9 @@ def error_item_skel(
260263
"urls": urls,
261264
"responseBodies": response_bodies
262265
}
266+
if action_id is not None:
267+
item["action_id"] = action_id
268+
return item
263269

264270
@staticmethod
265271
def _get_response_bodies(err_resp_data: Optional[ErrorResponseData]) -> list:
@@ -276,11 +282,15 @@ def _get_response_bodies(err_resp_data: Optional[ErrorResponseData]) -> list:
276282

277283
def add_sample(self, sample):
278284
"""
279-
Add sample, consisting of: cnc, rt, cn, lt, rc, error, trname, byte_count
285+
Add sample, consisting of: cnc, rt, cn, lt, rc, error, trname, byte_count, [action_id]
280286
281287
:type sample: tuple
282288
"""
283-
cnc, r_time, con_time, latency, r_code, error, trname, byte_count = sample
289+
if len(sample) == 9:
290+
cnc, r_time, con_time, latency, r_code, error, trname, byte_count, action_id = sample
291+
else:
292+
cnc, r_time, con_time, latency, r_code, error, trname, byte_count = sample
293+
action_id = None
284294
self[self.SAMPLE_COUNT] += 1
285295
if cnc:
286296
self.add_concurrency(cnc, trname)
@@ -297,8 +307,19 @@ def add_sample(self, sample):
297307

298308
if error is not None:
299309
self[self.FAILURES] += 1
300-
301-
item = self.error_item_skel(error, r_code, 1, KPISet.ERRTYPE_ERROR, Counter(), None)
310+
self.log.info(f"DEV DEV: error: {error}")
311+
self.log.info(f"DEV DEV: r_code: {r_code}")
312+
self.log.info(f"DEV DEV: error: {error}")
313+
self.log.info(f"DEV DEV: action_id: {action_id}")
314+
item = self.error_item_skel(
315+
error,
316+
r_code,
317+
1,
318+
KPISet.ERRTYPE_ERROR,
319+
Counter(),
320+
None,
321+
action_id=action_id)
322+
self.log.info(f"DEV DEV: item: {item}")
302323
self.inc_list(self[self.ERRORS], ("msg", error), item)
303324
else:
304325
self[self.SUCCESSES] += 1
@@ -739,7 +760,7 @@ def __aggregate_current(self, datapoint, samples):
739760

740761
if self.generalize_labels:
741762
base_label = self._generalize_label(base_label)
742-
763+
self.log.info(f"Sample: {sample}")
743764
self.__add_sample(current, base_label, sample[1:])
744765

745766
overall = KPISet(self.track_percentiles, self.__get_rtimes_max(''), ext_aggregation=self._redundant_aggregation)
@@ -767,7 +788,7 @@ def __add_sample(self, current, label, kpis):
767788
perc_levels=self.track_percentiles,
768789
hist_max_rt=self.__get_rtimes_max(label),
769790
ext_aggregation=self._redundant_aggregation)
770-
791+
self.log.info(f"kpis: {kpis}")
771792
current[label].add_sample(kpis)
772793

773794
def __get_rtimes_max(self, label):

0 commit comments

Comments
 (0)