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