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