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