[FIX] profiling: fix speedscope with empty ctx

Since de077243 the iter(False) will occur when trying to render a
speedscope output with `use_context=False` since the context given in
parameter of `stack_to_ids` won't be an iterable.

This simple fix avoid this by always giving an empty iterable
in this case.

closes odoo/odoo#75851

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
This commit is contained in:
Xavier-Do
2021-09-02 04:41:46 +00:00
parent 7d78dd42c0
commit babf021812
2 changed files with 40 additions and 2 deletions
+38
View File
@@ -332,6 +332,44 @@ class TestSpeedscope(BaseCase):
('C', 'level4'),
])
def test_converts_no_context(self):
stack = [
['file.py', 10, 'level4', 'level4'],
['file.py', 11, 'level5', 'level5'],
]
profile = {
'init_stack_trace': [
['file.py', 1, 'level0', 'level0'],
['file.py', 1, 'level1', 'level1'],
['file.py', 1, 'level2', 'level2'],
['file.py', 1, 'level3', 'level3'],
],
'result': [{ # init frame
'start': 2.0,
'exec_context': ((2, {'a': '1'}), (6, {'b': '1'})),
'stack': list(stack),
}, { # final frame
'start': 10.35,
'exec_context': (),
'stack': None,
}],
}
sp = Speedscope(init_stack_trace=profile['init_stack_trace'])
sp.add('profile', profile['result'])
sp.add_output(['profile'], complete=False, use_context=False)
res = sp.make()
events = [
(e['type'], res['shared']['frames'][e['frame']]['name'])
for e in res['profiles'][0]['events']
]
self.assertEqual(events, [
# pylint: disable=bad-continuation
('O', 'level4'),
('O', 'level5'),
('C', 'level5'),
('C', 'level4'),
])
@tagged('post_install', '-at_install', 'profiling')
class TestProfiling(TransactionCase):
+2 -2
View File
@@ -131,7 +131,7 @@ class Speedscope:
level.
"""
stack_ids = []
context_iterator = iter(context)
context_iterator = iter(context or ())
context_level, context_value = next(context_iterator, (None, None))
# consume iterator until we are over stack_offset
while context_level is not None and context_level < stack_offset:
@@ -178,7 +178,7 @@ class Speedscope:
entry_end = None if entry_time is None else entry_start + entry_time
entry_stack_ids = self.stack_to_ids(
entry['stack'] or [],
use_context and entry.get('exec_context', {}),
use_context and entry.get('exec_context'),
self.init_stack_trace_level
)
level = 0