1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4import os 5import StringIO 6import unittest 7 8import mock 9 10from telemetry import story 11from telemetry.internal.results import csv_pivot_table_output_formatter 12from telemetry.internal.results import page_test_results 13from telemetry import page as page_module 14from telemetry.value import improvement_direction 15from telemetry.value import scalar 16from telemetry.value import trace 17from tracing.trace_data import trace_data 18 19 20def _MakeStorySet(): 21 story_set = story.StorySet(base_dir=os.path.dirname(__file__)) 22 story_set.AddStory( 23 page_module.Page('http://www.foo.com/', story_set, story_set.base_dir)) 24 story_set.AddStory( 25 page_module.Page('http://www.bar.com/', story_set, story_set.base_dir)) 26 return story_set 27 28 29class CsvPivotTableOutputFormatterTest(unittest.TestCase): 30 31 # The line separator used by CSV formatter. 32 _LINE_SEPARATOR = '\r\n' 33 34 def setUp(self): 35 self._output = StringIO.StringIO() 36 self._story_set = _MakeStorySet() 37 self._results = page_test_results.PageTestResults() 38 self._formatter = None 39 self.MakeFormatter() 40 41 def MakeFormatter(self, trace_tag=''): 42 self._formatter = ( 43 csv_pivot_table_output_formatter.CsvPivotTableOutputFormatter( 44 self._output, trace_tag)) 45 46 def SimulateBenchmarkRun(self, list_of_page_and_values): 47 """Simulate one run of a benchmark, using the supplied values. 48 49 Args: 50 list_of_pages_and_values: a list of tuple (page, list of values) 51 """ 52 for page, values in list_of_page_and_values: 53 self._results.WillRunPage(page) 54 for v in values: 55 v.page = page 56 self._results.AddValue(v) 57 self._results.DidRunPage(page) 58 59 def Format(self): 60 self._formatter.Format(self._results) 61 return self._output.getvalue() 62 63 def testSimple(self): 64 # Test a simple benchmark with only one value: 65 self.SimulateBenchmarkRun([ 66 (self._story_set[0], [scalar.ScalarValue( 67 None, 'foo', 'seconds', 3, 68 improvement_direction=improvement_direction.DOWN)])]) 69 expected = self._LINE_SEPARATOR.join([ 70 'story_set,page,name,value,units,run_index', 71 'story_set,http://www.foo.com/,foo,3,seconds,0', 72 '']) 73 74 self.assertEqual(expected, self.Format()) 75 76 @mock.patch('py_utils.cloud_storage.Insert') 77 def testMultiplePagesAndValues(self, cs_insert_mock): 78 cs_insert_mock.return_value = 'https://cloud_storage_url/foo' 79 trace_value = trace.TraceValue( 80 None, trace_data.CreateTraceDataFromRawData('{"traceEvents": []}')) 81 trace_value.UploadToCloud(bucket='foo') 82 self.SimulateBenchmarkRun([ 83 (self._story_set[0], [ 84 scalar.ScalarValue( 85 None, 'foo', 'seconds', 4, 86 improvement_direction=improvement_direction.DOWN)]), 87 (self._story_set[1], [ 88 scalar.ScalarValue( 89 None, 'foo', 'seconds', 3.4, 90 improvement_direction=improvement_direction.DOWN), 91 trace_value, 92 scalar.ScalarValue( 93 None, 'bar', 'km', 10, 94 improvement_direction=improvement_direction.DOWN), 95 scalar.ScalarValue( 96 None, 'baz', 'count', 5, 97 improvement_direction=improvement_direction.DOWN)])]) 98 99 # Parse CSV output into list of lists. 100 csv_string = self.Format() 101 lines = csv_string.split(self._LINE_SEPARATOR) 102 values = [s.split(',') for s in lines[1:-1]] 103 104 self.assertEquals(len(values), 5) # We expect 5 value in total. 105 self.assertEquals(len(set((v[1] for v in values))), 2) # 2 pages. 106 self.assertEquals(len(set((v[2] for v in values))), 4) # 4 value names. 107 self.assertEquals(values[2], 108 ['story_set', 'http://www.bar.com/', 'trace', 109 'https://cloud_storage_url/foo', '', '1']) 110 111 def testTraceTag(self): 112 self.MakeFormatter(trace_tag='date,option') 113 self.SimulateBenchmarkRun([ 114 (self._story_set[0], [ 115 scalar.ScalarValue( 116 None, 'foo', 'seconds', 3, 117 improvement_direction=improvement_direction.DOWN), 118 scalar.ScalarValue( 119 None, 'bar', 'tons', 5, 120 improvement_direction=improvement_direction.DOWN)])]) 121 output = self.Format().split(self._LINE_SEPARATOR) 122 123 self.assertTrue(output[0].endswith(',trace_tag_0,trace_tag_1')) 124 for line in output[1:-1]: 125 self.assertTrue(line.endswith(',date,option')) 126