def testBasic(self): value0 = {'foo': 0} value0_json = json.dumps(value0, separators=(',', ':')) render_histograms_viewer.RenderHistogramsViewer([], self.output_stream, False) self.output_stream.seek(0) self.assertCountEqual([], render_histograms_viewer.ReadExistingResults( self.output_stream.read())) render_histograms_viewer.RenderHistogramsViewer([value0], self.output_stream, False) self.output_stream.seek(0) self.assertCountEqual([value0], render_histograms_viewer.ReadExistingResults( self.output_stream.read())) self.assertIn(value0_json, self.GetOutputFileContent())
def testBasicWithSeparatorOften(self): data_list = [{'foo': i} for i in range(11)] render_histograms_viewer.RenderHistogramsViewer([], self.output_stream, False) self.output_stream.seek(0) self.assertCountEqual([], render_histograms_viewer.ReadExistingResults( self.output_stream.read())) # Write payload, forcing a new chunk after ever single item render_histograms_viewer.RenderHistogramsViewer( data_list, self.output_stream, False, max_chunk_size_hint_bytes=1) self.output_stream.seek(0) self.assertCountEqual( data_list, render_histograms_viewer.ReadExistingResults( self.output_stream.read())) for data in data_list: data_json = json.dumps(data, separators=(',', ':')) self.assertIn(data_json, self.GetOutputFileContent())
def testExistingResultsReset(self): value0 = {'foo': 0} value0_json = json.dumps(value0, separators=(',', ':')) value1 = {'bar': 1} value1_json = json.dumps(value1, separators=(',', ':')) render_histograms_viewer.RenderHistogramsViewer([value0], self.output_stream, False) render_histograms_viewer.RenderHistogramsViewer([value1], self.output_stream, True) self.output_stream.seek(0) self.assertEquals( sorted([value1]), sorted( render_histograms_viewer.ReadExistingResults( self.output_stream.read()))) self.assertNotIn(value0_json, self.GetOutputFileContent()) self.assertIn(value1_json, self.GetOutputFileContent())
def GenerateResults2(job): histogram_dicts = _FetchHistograms(job) vulcanized_html = _ReadVulcanizedHistogramsViewer() CachedResults2(job_id=job.job_id).put() filename = _GetCloudStorageName(job.job_id) gcs_file = _GcsFileStream( filename, 'w', content_type='text/html', retry_params=cloudstorage.RetryParams(backoff_factor=1.1)) render_histograms_viewer.RenderHistogramsViewer( histogram_dicts, gcs_file, reset_results=True, vulcanized_html=vulcanized_html) gcs_file.close()
def get(self, job_id): try: job_data = _GetJobData(job_id) histogram_dicts = _FetchHistogramsDataFromJobData(job_data) vulcanized_html = _ReadVulcanizedHistogramsViewer() vulcanized_html_and_histograms = StringIO.StringIO() render_histograms_viewer.RenderHistogramsViewer( histogram_dicts, vulcanized_html_and_histograms, vulcanized_html=vulcanized_html) self.response.out.write(vulcanized_html_and_histograms.getvalue()) except Results2Error as e: self.response.set_status(400) self.response.out.write(e.message) return
def GenerateResults2(job): logging.debug('Job [%s]: GenerateResults2', job.job_id) histogram_dicts = _FetchHistograms(job) vulcanized_html = _ReadVulcanizedHistogramsViewer() CachedResults2(job_id=job.job_id).put() filename = _GetCloudStorageName(job.job_id) gcs_file = _GcsFileStream( filename, 'w', content_type='text/html', retry_params=cloudstorage.RetryParams(backoff_factor=1.1)) render_histograms_viewer.RenderHistogramsViewer( histogram_dicts, gcs_file, reset_results=True, vulcanized_html=vulcanized_html) gcs_file.close() logging.debug('Generated %s; see https://storage.cloud.google.com%s', filename, filename)
def Profile(root, label=None, html_filename=None, html_stream=None, vulcanized_viewer=None, reset_results=False, diagnostics_callback=None): """Profiles memory consumed by the root object. Produces a HistogramSet containing 1 Histogram for each user-defined class encountered when recursing through the root object's properties. Each Histogram contains 1 sample for each instance of the class. Each sample contains 2 Breakdowns: - 'types' allows drilling down into memory profiles for other classes, and - 'properties' breaks down the size of an instance by its properties. Args: label: string label to distinguish these results from those produced by other Profile() calls. html_filename: string filename to write HTML results. html_stream: file-like string to write HTML results. vulcanized_viewer: HTML string reset_results: whether to delete pre-existing results in html_filename/html_stream diagnostics_callback: function that takes an instance of a class, and returns a dictionary from strings to Diagnostic objects. Returns: HistogramSet """ # TODO(4068): Package this and its dependencies and a vulcanized viewer in # order to remove the vulcanized_viewer parameter and simplify rendering the # viewer. profiler = _HeapProfiler(diagnostics_callback) histograms = profiler.Profile(root) if label: histograms.AddSharedDiagnosticToAllHistograms( reserved_infos.LABELS.name, generic_set.GenericSet([label])) if html_filename and not html_stream: open(html_filename, 'a').close() # Create file if it doesn't exist. html_stream = codecs.open(html_filename, mode='r+', encoding='utf-8') if html_stream: # Vulcanizing the viewer requires a full catapult checkout, which is not # available in some contexts such as appengine. # Merely rendering the viewer requires a pre-vulcanized viewer HTML string. # render_histograms_viewer does not require a full checkout, so it can run # in restricted contexts such as appengine as long as a pre-vulcanized # viewer is provided. if vulcanized_viewer: render_histograms_viewer.RenderHistogramsViewer( histograms.AsDicts(), html_stream, reset_results, vulcanized_viewer) else: from tracing_build import vulcanize_histograms_viewer vulcanize_histograms_viewer.VulcanizeAndRenderHistogramsViewer( histograms.AsDicts(), html_stream) return histograms
def VulcanizeAndRenderHistogramsViewer(histogram_dicts, output_stream, reset_results=False): render_histograms_viewer.RenderHistogramsViewer( histogram_dicts, output_stream, reset_results, VulcanizeHistogramsViewer())
def testHtmlEscape(self): render_histograms_viewer.RenderHistogramsViewer([{ 'name': '<a><b>' }], self.output_stream, False) self.assertIn('<a><b>', self.GetOutputFileContent())
def testHtmlEscape(self): # No escaping is needed since data is stored in an html comment. render_histograms_viewer.RenderHistogramsViewer([{ 'name': '<a><b>' }], self.output_stream, False) self.assertIn('<a><b>', self.GetOutputFileContent())