def test_call_lines_return(self): trace_data = [ db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='call', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='return', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), ] collapsed = list(trace.collapse_trace(trace_data)) self.assertEqual(len(collapsed), 3) line_nos = [r.line_no for r in collapsed] self.assertEqual(line_nos, [(1, 1), (1, 2), (2, 2)])
def test_call_lines_return(self): trace_data = [ db.Trace( id='1', run_id='1', call_id='1', event='call', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', call_id='1', event='line', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', call_id='1', event='line', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', call_id='1', event='return', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), ] collapsed = list(trace.collapse_trace(trace_data)) self.assertEqual(len(collapsed), 3) line_nos = [r.line_no for r in collapsed] self.assertEqual(line_nos, [(1, 1), (1, 2), (2, 2)])
def test_non_consecutive_lines(self): trace_data = [ db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=20, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=40, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), ] collapsed = list(trace.collapse_trace(trace_data)) self.assertEqual(len(collapsed), 1) line_nos = [r.line_no for r in collapsed] self.assertEqual(line_nos, [(1, 40)])
def test_consecutive_lines(self): trace_data = [ db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=3, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), ] collapsed = list(trace.collapse_trace(trace_data)) self.assertEqual(len(collapsed), 1) line_nos = [r.line_no for r in collapsed] self.assertEqual(line_nos, [(1, 3)])
def test_changed_var(self): trace_data = [ db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={ 'v1': 1, 'v3': 3, }, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={ 'v1': 1, 'v2': 2, 'v3': 4, }, timestamp=1, ), ] collapsed = list(trace.collapse_trace(trace_data)) self.assertEqual(len(collapsed), 2) self.assertEqual(collapsed[0].local_vars, {'v1': 1, 'v3': 3}) self.assertEqual(collapsed[1].local_vars, {'v1': 1, 'v2': 2, 'v3': 4})
def get_one(self, run_id, page=1, per_page=20): run = request.db.get_run(run_id) if run_id == self._cached_run_id and self._cached_trace: LOG.debug('using cached trace for %s', run_id) trace_data = self._cached_trace else: LOG.debug('computing trace for %s', run_id) trace_data = list( trace.collapse_trace(request.db.get_trace(run_id)) ) self._cached_run_id = run_id self._cached_trace = trace_data syntax_line_cache = syntax.StyledLineCache(request.db, run_id) page_vals = pagination.get_pagination_values( page, per_page, len(trace_data), ) start = page_vals['start'] end = page_vals['end'] def getlines(filename, nums): start, end = nums return syntax_line_cache.getlines(filename, start, end, include_comments=True) context = { 'run_id': run_id, 'run': run, 'trace': trace_data[start:end], 'getlines': getlines, 'getfileid': functools.partial(request.db.get_file_signature, run_id=run_id), } context.update(page_vals) return context
def test_changed_var2(self): trace_data = [ db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=1, func_name='func', trace_arg={}, local_vars={ 'v1': 1, 'v3': 3, }, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=2, func_name='func', trace_arg={}, local_vars={ 'v1': 1, 'v2': 2, 'v3': 4, }, timestamp=1, ), # Force the previous data to be emitted, with the next set # of local variables being completely different to verify # that the variable change detection resets db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='call', filename='filename.py', line_no=3, func_name='func', trace_arg={}, local_vars={}, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=4, func_name='func', trace_arg={}, local_vars={ 'V1': 1, }, timestamp=1, ), db.Trace( id='1', run_id='1', thread_id='t1', call_id='1', event='line', filename='filename.py', line_no=5, func_name='func', trace_arg={}, local_vars={ 'V1': 1, 'V2': 2, }, timestamp=1, ), ] collapsed = list(trace.collapse_trace(trace_data)) self.assertEqual(len(collapsed), 4) self.assertEqual(collapsed[0].local_vars, {'v1': 1, 'v3': 3}) self.assertEqual(collapsed[1].local_vars, {'v1': 1, 'v2': 2, 'v3': 4}) self.assertEqual(collapsed[3].local_vars, {'V1': 1, 'V2': 2})
def get_one(self, run_id, page=None, per_page=None, thread_id=None): session = get_session() # Figure out which page and how many items to show. Look at # the session first, because if we don't have valid explicit # inputs we will use the session values as defaults. We track # the per_page value no matter the run_id for consistency. if session.get('run_id') == run_id: page = page or session.get('page') # Use the thread_id from the session if one has not been # provided as an explicit argument. if thread_id is None: thread_id = session.get('thread_id') if page is None: page = 1 per_page = per_page or session.get('per_page') or 20 # We can't pass None easily, so we pass an empty string when # we want to force all threads. None means no value was # passed, so we try to find the previous value from the # session (above) and fall back to None if there is no setting # in the session. thread_id = thread_id or None if (run_id, thread_id) == self._cached_ids and self._cached_trace: LOG.debug('using cached trace for %s', run_id) trace_data = self._cached_trace else: LOG.debug('computing trace for %s', run_id) trace_data = list( trace.collapse_trace(request.db.get_trace(run_id, thread_id)) ) self._cached_ids = (run_id, thread_id) self._cached_trace = trace_data syntax_line_cache = syntax.StyledLineCache(request.db, run_id) page_vals = pagination.get_pagination_values( page, per_page, len(trace_data), ) start = page_vals['start'] end = page_vals['end'] def getlines(filename, nums): start, end = nums return syntax_line_cache.getlines(filename, start, end, include_comments=True) try: context = run_context.get_context(request.db, run_id, thread_id) except db.NoSuchRun as e: # No such run. abort(404, six.text_type(e)) context.update({ 'trace': trace_data[start:end], 'getlines': getlines, 'getfileid': functools.partial(request.db.get_file_signature, run_id=run_id), }) context.update(page_vals) session['run_id'] = run_id session['thread_id'] = thread_id session['page'] = page session['per_page'] = per_page session.save() return context
def run(self): LOG.info('writing output to %s', self.output_dir) # Do some initial calculations to figure out how many pages we # have. trace_data = list(trace.collapse_trace(self.db.get_trace(self.run_id))) page_vals = pagination.get_pagination_values( 1, self.per_page, len(trace_data), ) last_page = page_vals['num_pages'] + 1 # Start producing output pages self._render_page( IndexPage(report=self, ), 'index.html', ) # The trace output is paginated, so we have multiple pages to # produce. for i in xrange(1, last_page): page_vals = pagination.get_pagination_values( i, self.per_page, len(trace_data), ) page_name = 'trace-%d.html' % i start = page_vals['start'] end = page_vals['end'] self._render_page( TracePage( report=self, trace=trace_data[start:end], pagination=page_vals, getlines=self._get_file_lines, ), page_name, ) # The source code from the run run_files = list(self.db.get_files_for_run(self.run_id)) self._render_page( FilesPage(self, run_files), 'files.html', ) for run_file in run_files: self._render_page( FilePage(self, run_file), 'file-%s.html' % run_file.signature, ) self._render_page( StatsPage(self), 'stats.html', ) self._render_page( CallGraphPage(self), 'call_graph.html', ) # Make sure we have all of the CSS and JavaScript files needed # by the templates. self._copy_static_files()
def get_one(self, run_id, page=None, per_page=None, thread_id=None): session = get_session() # Figure out which page and how many items to show. Look at # the session first, because if we don't have valid explicit # inputs we will use the session values as defaults. We track # the per_page value no matter the run_id for consistency. if session.get('run_id') == run_id: page = page or session.get('page') # Use the thread_id from the session if one has not been # provided as an explicit argument. if thread_id is None: thread_id = session.get('thread_id') if page is None: page = 1 per_page = per_page or session.get('per_page') or 20 # We can't pass None easily, so we pass an empty string when # we want to force all threads. None means no value was # passed, so we try to find the previous value from the # session (above) and fall back to None if there is no setting # in the session. thread_id = thread_id or None if (run_id, thread_id) == self._cached_ids and self._cached_trace: LOG.debug('using cached trace for %s', run_id) trace_data = self._cached_trace else: LOG.debug('computing trace for %s', run_id) trace_data = list( trace.collapse_trace(request.db.get_trace(run_id, thread_id))) self._cached_ids = (run_id, thread_id) self._cached_trace = trace_data syntax_line_cache = syntax.StyledLineCache(request.db, run_id) page_vals = pagination.get_pagination_values( page, per_page, len(trace_data), ) start = page_vals['start'] end = page_vals['end'] def getlines(filename, nums): start, end = nums return syntax_line_cache.getlines(filename, start, end, include_comments=True) try: context = run_context.get_context(request.db, run_id, thread_id) except db.NoSuchRun as e: # No such run. abort(404, six.text_type(e)) context.update({ 'trace': trace_data[start:end], 'getlines': getlines, 'getfileid': functools.partial(request.db.get_file_signature, run_id=run_id), }) context.update(page_vals) session['run_id'] = run_id session['thread_id'] = thread_id session['page'] = page session['per_page'] = per_page session.save() return context
def run(self): LOG.info('writing output to %s', self.output_dir) # Do some initial calculations to figure out how many pages we # have. trace_data = list( trace.collapse_trace(self.db.get_trace(self.run_id)) ) page_vals = pagination.get_pagination_values( 1, self.per_page, len(trace_data), ) last_page = page_vals['num_pages'] + 1 # Start producing output pages self._render_page( IndexPage( report=self, ), 'index.html', ) # The trace output is paginated, so we have multiple pages to # produce. for i in range(1, last_page): page_vals = pagination.get_pagination_values( i, self.per_page, len(trace_data), ) page_name = 'trace-%d.html' % i start = page_vals['start'] end = page_vals['end'] self._render_page( TracePage( report=self, trace=trace_data[start:end], pagination=page_vals, getlines=self._get_file_lines, ), page_name, ) # The source code from the run run_files = list(self.db.get_files_for_run(self.run_id)) self._render_page( FilesPage(self, run_files), 'files.html', ) for run_file in run_files: self._render_page( FilePage(self, run_file), 'file-%s.html' % run_file.signature, ) self._render_page( StatsPage(self), 'stats.html', ) self._render_page( CallGraphPage(self), 'call_graph.html', ) # Make sure we have all of the CSS and JavaScript files needed # by the templates. self._copy_static_files()