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