From babf021812bb65ee7eb16bcc55ff033770a3c993 Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Wed, 1 Sep 2021 13:01:23 +0000 Subject: [PATCH] [FIX] profiling: fix speedscope with empty ctx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- odoo/addons/base/tests/test_profiler.py | 38 +++++++++++++++++++++++++ odoo/tools/speedscope.py | 4 +-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/odoo/addons/base/tests/test_profiler.py b/odoo/addons/base/tests/test_profiler.py index c7cd735b012..5d1dc32cbd9 100644 --- a/odoo/addons/base/tests/test_profiler.py +++ b/odoo/addons/base/tests/test_profiler.py @@ -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): diff --git a/odoo/tools/speedscope.py b/odoo/tools/speedscope.py index 8ec778024a2..c0ffa03f732 100644 --- a/odoo/tools/speedscope.py +++ b/odoo/tools/speedscope.py @@ -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