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.
4
5import shutil
6import tempfile
7import unittest
8
9from telemetry import benchmark as benchmark_module
10from telemetry import page as page_module
11from telemetry.page import legacy_page_test
12from telemetry import story as story_module
13from telemetry.testing import fakes
14from telemetry.testing import options_for_unittests
15import mock
16
17
18# pylint: disable=abstract-method
19class DummyPageTest(legacy_page_test.LegacyPageTest):
20
21  def __init__(self):
22    super(DummyPageTest, self).__init__()
23    # Without disabling the above warning, this complains that
24    # ValidateAndMeasurePage is abstract; but defining it complains
25    # that its definition is overridden here.
26    self.ValidateAndMeasurePage = mock.Mock() # pylint: disable=invalid-name
27
28
29# More end-to-end tests of Benchmark, shared_page_state and associated
30# classes using telemetry.testing.fakes, to avoid needing to construct
31# a real browser instance.
32
33
34class FakePage(page_module.Page):
35
36  def __init__(self, page_set):
37    super(FakePage, self).__init__(
38        url='http://nonexistentserver.com/nonexistentpage.html',
39        name='fake page',
40        page_set=page_set,
41        shared_page_state_class=fakes.FakeSharedPageState)
42    self.RunNavigateSteps = mock.Mock() # pylint: disable=invalid-name
43    self.RunPageInteractions = mock.Mock() # pylint: disable=invalid-name
44
45
46class FakeBenchmark(benchmark_module.Benchmark):
47
48  def __init__(self, max_failures=None):
49    super(FakeBenchmark, self).__init__(max_failures)
50    self._fake_pages = []
51    self._fake_story_set = story_module.StorySet()
52    self._created_story_set = False
53    self.validator = DummyPageTest()
54
55  def CreatePageTest(self, options):
56    return self.validator
57
58  def GetFakeStorySet(self):
59    return self._fake_story_set
60
61  def AddFakePage(self, page):
62    if self._created_story_set:
63      raise Exception('Can not add any more fake pages')
64    self._fake_pages.append(page)
65
66  def CreateStorySet(self, options):
67    if self._created_story_set:
68      raise Exception('Can only create the story set once per FakeBenchmark')
69    for page in self._fake_pages:
70      self._fake_story_set.AddStory(page)
71    self._created_story_set = True
72    return self._fake_story_set
73
74
75class FailingPage(FakePage):
76
77  def __init__(self, page_set):
78    super(FailingPage, self).__init__(page_set)
79    self.RunNavigateSteps.side_effect = Exception('Deliberate exception')
80
81
82class BenchmarkRunTest(unittest.TestCase):
83  def setUp(self):
84    self.options = options_for_unittests.GetRunOptions(
85        output_dir=tempfile.mkdtemp(),
86        benchmark_cls=FakeBenchmark,
87        fake_browser=True)
88    self.options.browser_options.platform = fakes.FakeLinuxPlatform()
89    self.benchmark = FakeBenchmark()
90
91  def tearDown(self):
92    shutil.rmtree(self.options.output_dir)
93
94  def testPassingPage(self):
95    manager = mock.Mock()
96    page = FakePage(self.benchmark.GetFakeStorySet())
97    page.RunNavigateSteps = manager.page.RunNavigateSteps
98    page.RunPageInteractions = manager.page.RunPageInteractions
99    self.benchmark.validator.ValidateAndMeasurePage = (
100        manager.validator.ValidateAndMeasurePage)
101    self.benchmark.AddFakePage(page)
102    self.assertEqual(
103        self.benchmark.Run(self.options), 0, 'Test should run with no errors')
104    expected = [
105        mock.call.page.RunNavigateSteps(mock.ANY),
106        mock.call.page.RunPageInteractions(mock.ANY),
107        mock.call.validator.ValidateAndMeasurePage(page, mock.ANY, mock.ANY)
108    ]
109    self.assertTrue(manager.mock_calls == expected)
110
111  def testFailingPage(self):
112    page = FailingPage(self.benchmark.GetFakeStorySet())
113    self.benchmark.AddFakePage(page)
114    self.assertNotEqual(
115        self.benchmark.Run(self.options), 0, 'Test should fail')
116    self.assertFalse(page.RunPageInteractions.called)
117