Home | History | Annotate | Download | only in performance_tests
      1 # Copyright (C) 2012 Google Inc. All rights reserved.
      2 #
      3 # Redistribution and use in source and binary forms, with or without
      4 # modification, are permitted provided that the following conditions are
      5 # met:
      6 #
      7 #     * Redistributions of source code must retain the above copyright
      8 # notice, this list of conditions and the following disclaimer.
      9 #     * Redistributions in binary form must reproduce the above
     10 # copyright notice, this list of conditions and the following disclaimer
     11 # in the documentation and/or other materials provided with the
     12 # distribution.
     13 #     * Neither the name of Google Inc. nor the names of its
     14 # contributors may be used to endorse or promote products derived from
     15 # this software without specific prior written permission.
     16 #
     17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 """Unit tests for run_perf_tests."""
     30 
     31 import StringIO
     32 import json
     33 import re
     34 import unittest2 as unittest
     35 
     36 from webkitpy.common.host_mock import MockHost
     37 from webkitpy.common.system.outputcapture import OutputCapture
     38 from webkitpy.layout_tests.port.test import TestPort
     39 from webkitpy.performance_tests.perftest import DEFAULT_TEST_RUNNER_COUNT
     40 from webkitpy.performance_tests.perftestsrunner import PerfTestsRunner
     41 
     42 
     43 class MainTest(unittest.TestCase):
     44     def create_runner(self, args=[]):
     45         options, parsed_args = PerfTestsRunner._parse_args(args)
     46         test_port = TestPort(host=MockHost(), options=options)
     47         runner = PerfTestsRunner(args=args, port=test_port)
     48         runner._host.filesystem.maybe_make_directory(runner._base_path, 'inspector')
     49         runner._host.filesystem.maybe_make_directory(runner._base_path, 'Bindings')
     50         runner._host.filesystem.maybe_make_directory(runner._base_path, 'Parser')
     51         return runner, test_port
     52 
     53     def _add_file(self, runner, dirname, filename, content=True):
     54         dirname = runner._host.filesystem.join(runner._base_path, dirname) if dirname else runner._base_path
     55         runner._host.filesystem.maybe_make_directory(dirname)
     56         runner._host.filesystem.files[runner._host.filesystem.join(dirname, filename)] = content
     57 
     58     def test_collect_tests(self):
     59         runner, port = self.create_runner()
     60         self._add_file(runner, 'inspector', 'a_file.html', 'a content')
     61         tests = runner._collect_tests()
     62         self.assertEqual(len(tests), 1)
     63 
     64     def _collect_tests_and_sort_test_name(self, runner):
     65         return sorted([test.test_name() for test in runner._collect_tests()])
     66 
     67     def test_collect_tests_with_multile_files(self):
     68         runner, port = self.create_runner(args=['PerformanceTests/test1.html', 'test2.html'])
     69 
     70         def add_file(filename):
     71             port.host.filesystem.files[runner._host.filesystem.join(runner._base_path, filename)] = 'some content'
     72 
     73         add_file('test1.html')
     74         add_file('test2.html')
     75         add_file('test3.html')
     76         port.host.filesystem.chdir(runner._port.perf_tests_dir()[:runner._port.perf_tests_dir().rfind(runner._host.filesystem.sep)])
     77         self.assertItemsEqual(self._collect_tests_and_sort_test_name(runner), ['test1.html', 'test2.html'])
     78 
     79     def test_collect_tests_with_skipped_list(self):
     80         runner, port = self.create_runner()
     81 
     82         self._add_file(runner, 'inspector', 'test1.html')
     83         self._add_file(runner, 'inspector', 'unsupported_test1.html')
     84         self._add_file(runner, 'inspector', 'test2.html')
     85         self._add_file(runner, 'inspector/resources', 'resource_file.html')
     86         self._add_file(runner, 'unsupported', 'unsupported_test2.html')
     87         port.skipped_perf_tests = lambda: ['inspector/unsupported_test1.html', 'unsupported']
     88         self.assertItemsEqual(self._collect_tests_and_sort_test_name(runner), ['inspector/test1.html', 'inspector/test2.html'])
     89 
     90     def test_collect_tests_with_skipped_list_and_files(self):
     91         runner, port = self.create_runner(args=['Suite/Test1.html', 'Suite/SkippedTest1.html', 'SkippedSuite/Test1.html'])
     92 
     93         self._add_file(runner, 'SkippedSuite', 'Test1.html')
     94         self._add_file(runner, 'SkippedSuite', 'Test2.html')
     95         self._add_file(runner, 'Suite', 'Test1.html')
     96         self._add_file(runner, 'Suite', 'Test2.html')
     97         self._add_file(runner, 'Suite', 'SkippedTest1.html')
     98         self._add_file(runner, 'Suite', 'SkippedTest2.html')
     99         port.skipped_perf_tests = lambda: ['Suite/SkippedTest1.html', 'Suite/SkippedTest1.html', 'SkippedSuite']
    100         self.assertItemsEqual(self._collect_tests_and_sort_test_name(runner),
    101             ['SkippedSuite/Test1.html', 'Suite/SkippedTest1.html', 'Suite/Test1.html'])
    102 
    103     def test_collect_tests_with_ignored_skipped_list(self):
    104         runner, port = self.create_runner(args=['--force'])
    105 
    106         self._add_file(runner, 'inspector', 'test1.html')
    107         self._add_file(runner, 'inspector', 'unsupported_test1.html')
    108         self._add_file(runner, 'inspector', 'test2.html')
    109         self._add_file(runner, 'inspector/resources', 'resource_file.html')
    110         self._add_file(runner, 'unsupported', 'unsupported_test2.html')
    111         port.skipped_perf_tests = lambda: ['inspector/unsupported_test1.html', 'unsupported']
    112         self.assertItemsEqual(self._collect_tests_and_sort_test_name(runner), ['inspector/test1.html', 'inspector/test2.html', 'inspector/unsupported_test1.html', 'unsupported/unsupported_test2.html'])
    113 
    114     def test_default_args(self):
    115         runner, port = self.create_runner()
    116         options, args = PerfTestsRunner._parse_args([])
    117         self.assertTrue(options.build)
    118         self.assertEqual(options.time_out_ms, 600 * 1000)
    119         self.assertTrue(options.generate_results)
    120         self.assertTrue(options.show_results)
    121         self.assertTrue(options.use_skipped_list)
    122         self.assertEqual(options.repeat, 1)
    123         self.assertEqual(options.test_runner_count, DEFAULT_TEST_RUNNER_COUNT)
    124 
    125     def test_parse_args(self):
    126         runner, port = self.create_runner()
    127         options, args = PerfTestsRunner._parse_args([
    128                 '--build-directory=folder42',
    129                 '--platform=platform42',
    130                 '--builder-name', 'webkit-mac-1',
    131                 '--build-number=56',
    132                 '--time-out-ms=42',
    133                 '--no-show-results',
    134                 '--reset-results',
    135                 '--output-json-path=a/output.json',
    136                 '--slave-config-json-path=a/source.json',
    137                 '--test-results-server=somehost',
    138                 '--additional-drt-flag=--enable-threaded-parser',
    139                 '--additional-drt-flag=--awesomesauce',
    140                 '--repeat=5',
    141                 '--test-runner-count=5',
    142                 '--debug'])
    143         self.assertTrue(options.build)
    144         self.assertEqual(options.build_directory, 'folder42')
    145         self.assertEqual(options.platform, 'platform42')
    146         self.assertEqual(options.builder_name, 'webkit-mac-1')
    147         self.assertEqual(options.build_number, '56')
    148         self.assertEqual(options.time_out_ms, '42')
    149         self.assertEqual(options.configuration, 'Debug')
    150         self.assertFalse(options.show_results)
    151         self.assertTrue(options.reset_results)
    152         self.assertEqual(options.output_json_path, 'a/output.json')
    153         self.assertEqual(options.slave_config_json_path, 'a/source.json')
    154         self.assertEqual(options.test_results_server, 'somehost')
    155         self.assertEqual(options.additional_drt_flag, ['--enable-threaded-parser', '--awesomesauce'])
    156         self.assertEqual(options.repeat, 5)
    157         self.assertEqual(options.test_runner_count, 5)
    158 
    159     def test_upload_json(self):
    160         runner, port = self.create_runner()
    161         port.host.filesystem.files['/mock-checkout/some.json'] = 'some content'
    162 
    163         class MockFileUploader:
    164             called = []
    165             upload_single_text_file_throws = False
    166             upload_single_text_file_return_value = None
    167 
    168             @classmethod
    169             def reset(cls):
    170                 cls.called = []
    171                 cls.upload_single_text_file_throws = False
    172                 cls.upload_single_text_file_return_value = None
    173 
    174             def __init__(mock, url, timeout):
    175                 self.assertEqual(url, 'https://some.host/some/path')
    176                 self.assertTrue(isinstance(timeout, int) and timeout)
    177                 mock.called.append('FileUploader')
    178 
    179             def upload_single_text_file(mock, filesystem, content_type, filename):
    180                 self.assertEqual(filesystem, port.host.filesystem)
    181                 self.assertEqual(content_type, 'application/json')
    182                 self.assertEqual(filename, 'some.json')
    183                 mock.called.append('upload_single_text_file')
    184                 if mock.upload_single_text_file_throws:
    185                     raise Exception
    186                 return mock.upload_single_text_file_return_value
    187 
    188         MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('OK')
    189         self.assertTrue(runner._upload_json('some.host', 'some.json', '/some/path', MockFileUploader))
    190         self.assertEqual(MockFileUploader.called, ['FileUploader', 'upload_single_text_file'])
    191 
    192         MockFileUploader.reset()
    193         MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('Some error')
    194         output = OutputCapture()
    195         output.capture_output()
    196         self.assertFalse(runner._upload_json('some.host', 'some.json', '/some/path', MockFileUploader))
    197         _, _, logs = output.restore_output()
    198         self.assertEqual(logs, 'Uploaded JSON to https://some.host/some/path but got a bad response:\nSome error\n')
    199 
    200         # Throwing an exception upload_single_text_file shouldn't blow up _upload_json
    201         MockFileUploader.reset()
    202         MockFileUploader.upload_single_text_file_throws = True
    203         self.assertFalse(runner._upload_json('some.host', 'some.json', '/some/path', MockFileUploader))
    204         self.assertEqual(MockFileUploader.called, ['FileUploader', 'upload_single_text_file'])
    205 
    206         MockFileUploader.reset()
    207         MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('{"status": "OK"}')
    208         self.assertTrue(runner._upload_json('some.host', 'some.json', '/some/path', MockFileUploader))
    209         self.assertEqual(MockFileUploader.called, ['FileUploader', 'upload_single_text_file'])
    210 
    211         MockFileUploader.reset()
    212         MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('{"status": "SomethingHasFailed", "failureStored": false}')
    213         output = OutputCapture()
    214         output.capture_output()
    215         self.assertFalse(runner._upload_json('some.host', 'some.json', '/some/path', MockFileUploader))
    216         _, _, logs = output.restore_output()
    217         serialized_json = json.dumps({'status': 'SomethingHasFailed', 'failureStored': False}, indent=4)
    218         self.assertEqual(logs, 'Uploaded JSON to https://some.host/some/path but got an error:\n%s\n' % serialized_json)
    219