blob: 17205daf39ab31da173737ed15708680fa45ea28 [file] [log] [blame]
# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from collections import OrderedDict
import optparse
import unittest
from blinkpy.common.host_mock import MockHost
from blinkpy.common.system.output_capture import OutputCapture
from blinkpy.web_tests.models.test_configuration import (
TestConfiguration, TestConfigurationConverter)
from blinkpy.web_tests.models.test_expectations import (
TestExpectations, SystemConfigurationRemover, ParseError)
from blinkpy.web_tests.models.typ_types import ResultType, Expectation
class Base(unittest.TestCase):
# Note that all of these tests are written assuming the configuration
# being tested is Windows 7, Release build.
def __init__(self, testFunc):
host = MockHost()
self._port = host.port_factory.get('test-win-win7', None)
self._exp = None
unittest.TestCase.__init__(self, testFunc)
def get_basic_expectations(self):
return """
# results: [ Failure Crash ]
failures/expected/text.html [ Failure ]
failures/expected/crash.html [ Crash ] # foo and bar
failures/expected/image_checksum.html [ Crash ]
failures/expected/image.html [ Crash ]
"""
def parse_exp(self, expectations, overrides=None, is_lint_mode=False):
expectations_dict = OrderedDict()
expectations_dict['expectations'] = expectations
if overrides:
expectations_dict['overrides'] = overrides
self._port.expectations_dict = lambda: expectations_dict
expectations_to_lint = expectations_dict if is_lint_mode else None
self._exp = TestExpectations(
self._port, expectations_dict=expectations_to_lint)
def assert_exp_list(self, test, results):
exp = self._exp.get_expectations(test)
self.assertEqual(exp.test, test)
self.assertEqual(exp.results, set(results))
def assert_exp(self, test, result):
self.assert_exp_list(test, [result])
def assert_is_slow(self, test, is_slow):
self.assertEqual(
self._exp.get_expectations(test).is_slow_test, is_slow)
def assert_bad_expectations(self, expectations, overrides=None):
with self.assertRaises(ParseError):
self.parse_exp(
expectations, is_lint_mode=True, overrides=overrides)
def assert_trailing_comments(self, test, comments):
self.assertEqual(
self._exp.get_expectations(test).trailing_comments, comments)
def assert_basic(self):
self.assert_exp('failures/expected/text.html', ResultType.Failure)
self.assert_exp_list('failures/expected/image_checksum.html',
[ResultType.Crash])
self.assert_exp('passes/text.html', ResultType.Pass)
self.assert_exp('failures/expected/image.html', ResultType.Crash)
self.assert_trailing_comments('failures/expected/crash.html',
' # foo and bar\n')
class BasicTests(Base):
def test_basic(self):
self.parse_exp(self.get_basic_expectations())
self.assert_basic()
class VirtualExpectationsTest(Base):
def test_virtual_expectations(self):
# See test.TestPort.virtual_test_suite() for the mapping of the virtual
# test suites to bases.
self.parse_exp(
'# results: [ Pass Slow Skip ]\n' + self.get_basic_expectations() +
'passes/text.html [ Slow ]\n'
'passes/image.html [ Skip ]\n'
'virtual/virtual_passes/passes/text.html [ Failure ]\n'
'virtual/virtual_failures/failure/expected/crash.html [ Pass ]')
self.assert_basic()
# Overrides.
self.assert_exp('virtual/virtual_passes/passes/text.html',
ResultType.Failure)
self.assert_is_slow('virtual/virtual_passes/passes/text.html', True)
self.assert_exp('virtual/virtual_failures/failure/expected/text.html',
ResultType.Pass)
self.assert_is_slow(
'virtual/virtual_failures/failure/expected/text.html', False)
# Fallbacks.
self.assert_exp(
'virtual/virtual_failures/failures/expected/crash.html',
ResultType.Crash)
self.assert_exp('virtual/virtual_passes/passes/image.html',
ResultType.Skip)
# Non existence virtual suite doesn't fallback.
self.assert_exp('virtual/xyz/failures/expected/crash.html',
ResultType.Pass)
class FlagExpectationsTests(Base):
def setup_using_raw_expectations(self,
base_exps='',
flag_exps='',
flag_name=''):
self._general_exp_filename = 'TestExpectations'
expectations_dict = {self._general_exp_filename: base_exps}
# set up flag specific expectations
if flag_name:
self._flag_exp_filename = self._port.host.filesystem.join(
'FlagExpectations', flag_name)
expectations_dict[self._flag_exp_filename] = flag_exps
self._test_expectations = TestExpectations(self._port,
expectations_dict)
def assert_base_and_flag_exp(self, test, base_exp, flag_exp):
self.assertEqual(
self._test_expectations.get_base_expectations(test).results,
set([base_exp]))
actual_flag_exp = self._test_expectations.get_flag_expectations(test)
if flag_exp is None:
self.assertIsNone(actual_flag_exp)
else:
self.assertEqual(actual_flag_exp.results, set([flag_exp]))
def assert_exp(self, test, result):
self.assert_exp_list(test, [result])
def test_add_flag_test_expectations(self):
raw_flag_exps = """
# tags: [ Win ]
# results: [ Failure ]
[ Win ] failures/expected/text.html [ Failure ]
"""
self.setup_using_raw_expectations(
flag_exps=raw_flag_exps, flag_name='composite-after-paint')
flag_exp = self._test_expectations.get_flag_expectations(
'failures/expected/text.html')
self.assertEqual(flag_exp.results, set([ResultType.Failure]))
self.assertEqual(self._test_expectations.flag_name,
'/composite-after-paint')
def test_override_and_fallback(self):
raw_base_exps = """
# tags: [ Win ]
# results: [ Skip Slow Failure Crash Pass ]
[ Win ] failures/expected/text.html [ Slow ]
failures/expected/image.html [ Skip ]
failures/expected/reftest.html [ Slow Failure ]
failures/expected/crash.html [ Crash ]
"""
raw_flag_exps = """
# tags: [ Win ]
# results: [ Failure Pass Slow ]
[ Win ] failures/expected/text.html [ Failure ]
failures/expected/image.html [ Pass ]
failures/expected/reftest.html [ Pass ]
"""
self.setup_using_raw_expectations(base_exps=raw_base_exps,
flag_exps=raw_flag_exps,
flag_name='composite-after-paint')
self.assertEqual(self._test_expectations.flag_name,
'/composite-after-paint')
# Default pass without any explicit expectations.
exp = self._test_expectations.get_expectations('passes/text.html')
self.assertEqual(exp.results, set([ResultType.Pass]))
self.assertTrue(exp.is_default_pass)
self.assertFalse(exp.is_slow_test)
self.assert_base_and_flag_exp('passes/text.html', ResultType.Pass,
None)
# The test has a flag-specific expectation.
exp = self._test_expectations.get_expectations(
'failures/expected/text.html')
self.assertEqual(exp.results, set([ResultType.Failure]))
self.assertFalse(exp.is_default_pass)
self.assertTrue(exp.is_slow_test)
self.assert_base_and_flag_exp('failures/expected/text.html',
ResultType.Pass, ResultType.Failure)
# The flag-specific expectation overrides the base expectation.
exp = self._test_expectations.get_expectations(
'failures/expected/image.html')
self.assertEqual(exp.results, set([ResultType.Pass]))
self.assertFalse(exp.is_default_pass)
self.assertFalse(exp.is_slow_test)
self.assert_base_and_flag_exp('failures/expected/image.html',
ResultType.Skip, ResultType.Pass)
# The flag-specific expectation overrides the base expectation, but
# inherits [ Slow ] of the base expectation.
exp = self._test_expectations.get_expectations(
'failures/expected/reftest.html')
self.assertEqual(exp.results, set([ResultType.Pass]))
self.assertFalse(exp.is_default_pass)
self.assertTrue(exp.is_slow_test)
self.assert_base_and_flag_exp('failures/expected/reftest.html',
ResultType.Failure, ResultType.Pass)
# No flag-specific expectation. Fallback to the base expectation.
exp = self._test_expectations.get_expectations(
'failures/expected/crash.html')
self.assertEqual(exp.results, set([ResultType.Crash]))
self.assertFalse(exp.is_default_pass)
self.assertFalse(exp.is_slow_test)
self.assert_base_and_flag_exp('failures/expected/crash.html',
ResultType.Crash, None)
def test_override_and_fallback_virtual_test(self):
raw_base_exps = """
# tags: [ Win ]
# results: [ Skip Slow Failure Crash Pass ]
[ Win ] failures/expected/text.html [ Slow ]
failures/expected/image.html [ Skip ]
failures/expected/reftest.html [ Failure ]
failures/expected/crash.html [ Crash ]
virtual/virtual_failures/failures/expected/crash.html [ Pass ]
"""
raw_flag_exps = """
# tags: [ Win ]
# results: [ Failure Pass Timeout Slow ]
[ Win ] failures/expected/text.html [ Failure ]
failures/expected/image.html [ Pass ]
failures/expected/reftest.html [ Slow ]
failures/expected/crash.html [ Timeout ]
virtual/virtual_failures/failures/expected/image.html [ Failure ]
"""
self.setup_using_raw_expectations(base_exps=raw_base_exps,
flag_exps=raw_flag_exps,
flag_name='composite-after-paint')
self.assertEqual(self._test_expectations.flag_name,
'/composite-after-paint')
# Default pass of virtual test without any explicit expectations for
# either the virtual test or the base test.
exp = self._test_expectations.get_expectations(
'virtual/virtual_passes/passes/image.html')
self.assertEqual(exp.results, set([ResultType.Pass]))
self.assertTrue(exp.is_default_pass)
self.assertFalse(exp.is_slow_test)
self.assert_base_and_flag_exp(
'virtual/virtual_passes/passes/image.html', ResultType.Pass, None)
# No virtual test expectation. The flag-specific expectation of the
# base test override the base expectation of the base test, but [ Slow ]
# is inherited.
exp = self._test_expectations.get_expectations(
'virtual/virtual_failures/failures/expected/text.html')
self.assertEqual(exp.results, set([ResultType.Failure]))
self.assertFalse(exp.is_default_pass)
self.assertTrue(exp.is_slow_test)
self.assert_base_and_flag_exp(
'virtual/virtual_failures/failures/expected/text.html',
ResultType.Pass, ResultType.Failure)
# The flag-specific virtual test expectation wins.
exp = self._test_expectations.get_expectations(
'virtual/virtual_failures/failures/expected/image.html')
self.assertEqual(exp.results, set([ResultType.Failure]))
self.assertFalse(exp.is_default_pass)
self.assertFalse(exp.is_slow_test)
self.assert_base_and_flag_exp(
'virtual/virtual_failures/failures/expected/image.html',
ResultType.Skip, ResultType.Failure)
# No virtual test expectations. [ Slow ] in the flag-specific
# expectation of the base test and [ Failure ] in the base expectation
# of the base test merged.
exp = self._test_expectations.get_expectations(
'virtual/virtual_failures/failures/expected/reftest.html')
self.assertEqual(exp.results, set([ResultType.Failure]))
self.assertFalse(exp.is_default_pass)
self.assertTrue(exp.is_slow_test)
self.assert_base_and_flag_exp(
'virtual/virtual_failures/failures/expected/reftest.html',
ResultType.Failure, None)
# No virtual test flag-specific expectation. The virtual test
# expectation in the base expectation file wins.
exp = self._test_expectations.get_expectations(
'virtual/virtual_failures/failures/expected/crash.html')
self.assertEqual(exp.results, set([ResultType.Pass]))
self.assertFalse(exp.is_default_pass)
self.assertFalse(exp.is_slow_test)
self.assert_base_and_flag_exp(
'virtual/virtual_failures/failures/expected/crash.html',
ResultType.Pass, ResultType.Timeout)
class SystemConfigurationRemoverTests(Base):
def __init__(self, testFunc):
super(SystemConfigurationRemoverTests, self).__init__(testFunc)
self._port.configuration_specifier_macros_dict = {
'mac': ['mac10.10', 'mac10.11', 'mac10.12'],
'win': ['win7', 'win10'],
'linux': ['precise', 'trusty']
}
def set_up_using_raw_expectations(self, content):
self._general_exp_filename = self._port.host.filesystem.join(
self._port.web_tests_dir(), 'TestExpectations')
self._port.host.filesystem.write_text_file(self._general_exp_filename,
content)
expectations_dict = {self._general_exp_filename: content}
test_expectations = TestExpectations(self._port, expectations_dict)
self._system_config_remover = SystemConfigurationRemover(
test_expectations)
def test_remove_mac_version_from_mac_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be split\n'
'[ Mac ] failures/expected/text.html?\* [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html?*', set(['Mac10.10']))
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(
updated_exps,
('# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be split\n'
'[ Mac10.11 ] failures/expected/text.html?\* [ Failure ]\n'
'[ Mac10.12 ] failures/expected/text.html?\* [ Failure ]\n'))
def test_remove_mac_version_from_linux_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Linux ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be unaffected\n'
'[ Linux ] failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html', set(['Mac10.10']))
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(updated_exps, raw_expectations)
def test_remove_mac_version_from_all_config_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be split\n'
'failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html', set(['Mac10.10']))
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(
updated_exps,
('# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be split\n'
'[ Linux ] failures/expected/text.html [ Failure ]\n'
'[ Mac10.11 ] failures/expected/text.html [ Failure ]\n'
'[ Mac10.12 ] failures/expected/text.html [ Failure ]\n'
'[ Win ] failures/expected/text.html [ Failure ]\n'))
def test_remove_all_mac_versions_from_mac_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac ]\n'
'# results: [ Failure ]\n'
'# The expectation below and this comment block should be deleted\n'
'[ Mac ] failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html',
{'Mac10.10', 'Mac10.11', 'Mac10.12'})
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(updated_exps,
('# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac ]\n'
'# results: [ Failure ]\n'))
def test_remove_all_mac_versions_from_all_config_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be split\n'
'failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html',
{'Mac10.10', 'Mac10.11', 'Mac10.12'})
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(
updated_exps,
('# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be split\n'
'[ Linux ] failures/expected/text.html [ Failure ]\n'
'[ Win ] failures/expected/text.html [ Failure ]\n'))
def test_remove_all_mac_versions_from_linux_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be unaffected\n'
'[ Linux ] failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html',
{'Mac10.10', 'Mac10.11', 'Mac10.12'})
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(updated_exps, raw_expectations)
def test_remove_all_configs(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation and this comment should be deleted\n'
'failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
all_versions = reduce(
lambda x, y: x + y,
self._port.configuration_specifier_macros_dict.values())
self._system_config_remover.remove_os_versions(
'failures/expected/text.html', all_versions)
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(
updated_exps,
('# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'))
def test_remove_all_configs2(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'
'# Below Expectation and this comment should be deleted\n'
'[ Mac ] failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
all_versions = reduce(
lambda x, y: x + y,
self._port.configuration_specifier_macros_dict.values())
self._system_config_remover.remove_os_versions(
'failures/expected/text.html', all_versions)
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(
updated_exps,
('# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac Linux Win ]\n'
'# results: [ Failure ]\n'))
def test_remove_mac_version_from_another_mac_version_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Linux ]\n'
'# results: [ Failure ]\n'
'# Below Expectation should be unaffected\n'
'[ Mac10.11 ] failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html', set(['Mac10.10']))
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(updated_exps, raw_expectations)
def test_remove_mac_version_from_same_mac_version_expectation(self):
raw_expectations = (
'# tags: [ Mac10.10 Mac10.11 Linux ]\n'
'# results: [ Failure ]\n'
'# Below Expectation as well as this comment should be deleted\n'
'[ Mac10.10 ] failures/expected/text.html [ Failure ]\n')
self.set_up_using_raw_expectations(raw_expectations)
self._system_config_remover.remove_os_versions(
'failures/expected/text.html', set(['Mac10.10']))
self._system_config_remover.update_expectations()
updated_exps = self._port.host.filesystem.read_text_file(
self._general_exp_filename)
self.assertEqual(updated_exps, ('# tags: [ Mac10.10 Mac10.11 Linux ]\n'
'# results: [ Failure ]\n'))
class MiscTests(Base):
def test_parse_mac_legacy_names(self):
host = MockHost()
expectations_dict = OrderedDict()
expectations_dict['expectations'] = (
'# tags: [ Mac10.10 ]\n'
'# results: [ Failure ]\n'
'[ Mac10.10 ] failures/expected/text.html [ Failure ]\n')
port = host.port_factory.get('test-mac-mac10.10', None)
port.expectations_dict = lambda: expectations_dict
expectations = TestExpectations(port)
self.assertEqual(
expectations.get_expectations('failures/expected/text.html').
results, {ResultType.Failure})
port = host.port_factory.get('test-win-win7', None)
port.expectations_dict = lambda: expectations_dict
expectations = TestExpectations(port)
self.assertEqual(
expectations.get_expectations('failures/expected/text.html').
results, {ResultType.Pass})
def test_get_test_with_expected_result(self):
test_expectations = (
'# tags: [ win7 linux ]\n'
'# results: [ Failure ]\n'
'[ win7 ] failures/expected/text.html [ Failure ]\n'
'[ linux ] failures/expected/image_checksum.html [ Failure ]\n')
self.parse_exp(test_expectations)
self.assertEqual(
self._exp.get_tests_with_expected_result(ResultType.Failure),
set(['failures/expected/text.html']))
def test_multiple_results(self):
self.parse_exp(
'# results: [ Crash Failure ]\nfailures/expected/text.html [ Crash Failure ]'
)
self.assertEqual(
self._exp.get_expectations('failures/expected/text.html').results,
{ResultType.Failure, ResultType.Crash})
def test_overrides_include_slow(self):
self.parse_exp(
'# results: [ Failure ]\nfailures/expected/text.html [ Failure ]',
'# results: [ Slow ]\nfailures/expected/text.html [ Slow ]')
self.assert_exp_list('failures/expected/text.html',
set([ResultType.Failure]))
self.assertTrue(
self._exp.get_expectations('failures/expected/text.html').
is_slow_test)
def test_overrides(self):
self.parse_exp(
'# results: [ Failure ]\nfailures/expected/text.html [ Failure ]',
'# results: [ Timeout ]\nfailures/expected/text.html [ Timeout ]')
self.assert_exp_list('failures/expected/text.html',
{ResultType.Failure, ResultType.Timeout})
def test_more_specific_override_resets_skip(self):
self.parse_exp(
'# results: [ Skip ]\nfailures/expected* [ Skip ]',
'# results: [ Failure ]\nfailures/expected/text.html [ Failure ]')
self.assert_exp_list('failures/expected/text.html',
{ResultType.Failure, ResultType.Skip})
def test_bot_test_expectations(self):
"""Test that expectations are merged rather than overridden when using flaky option 'unexpected'."""
test_name1 = 'failures/expected/text.html'
test_name2 = 'passes/text.html'
expectations_dict = OrderedDict()
expectations_dict['expectations'] = (
'# results: [ Failure Crash ]\n%s [ Failure ]\n%s [ Crash ]\n' %
(test_name1, test_name2))
self._port.expectations_dict = lambda: expectations_dict
expectations = TestExpectations(self._port)
self.assertEqual(
expectations.get_expectations(test_name1).results,
set([ResultType.Failure]))
self.assertEqual(
expectations.get_expectations(test_name2).results,
set([ResultType.Crash]))
def bot_expectations():
return {
test_name1: [ResultType.Pass, ResultType.Timeout],
test_name2: [ResultType.Crash]
}
self._port.bot_expectations = bot_expectations
self._port._options.ignore_flaky_tests = 'unexpected'
expectations = TestExpectations(self._port)
self.assertEqual(
expectations.get_expectations(test_name1).results,
set([ResultType.Pass, ResultType.Failure, ResultType.Timeout]))
self.assertEqual(
expectations.get_expectations(test_name2).results,
set([ResultType.Crash]))
class RemoveExpectationsTest(Base):
def test_remove_expectation(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure ]\n'
'\n'
'# This comment will be deleted\n'
'[ mac ] test1 [ Failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_to_exps = test_expectations._expectations[1].individual_exps
test_expectations.remove_expectations('/tmp/TestExpectations2',
[test_to_exps['test1'][0]])
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations2')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure ]\n'))
def test_readd_removed_expectation_instance(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'[ mac ] test1 [ Failure ]\n'
'[ mac ] test2 [ Failure ]\n'
'[ mac ] test3 [ Failure ]\n'
'[ mac ] test4 [ Failure ]\n'
'[ mac ] test5 [ Failure ]\n'
'[ mac ] test6 [ Failure ]\n'
'[ mac ] test7 [ Failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_to_exps = test_expectations._expectations[1].individual_exps
exp = test_expectations._expectations[1].individual_exps['test1'][0]
exps_to_remove = [test_to_exps[
'test%d' % case_no][0] for case_no in range(1, 8)]
test_expectations.remove_expectations(
'/tmp/TestExpectations2', exps_to_remove)
test_expectations.add_expectations(
'/tmp/TestExpectations2',[exp],
lineno=4)
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations2')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'[ mac ] test1 [ Failure ]\n'))
def test_remove_added_expectations(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure ]\n'
'\n'
'# This comment will be deleted\n'
'[ mac ] test1 [ Failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_expectations.add_expectations('/tmp/TestExpectations2', [
Expectation(test='test2', results=set([ResultType.Failure])),
Expectation(
test='test3',
results=set([ResultType.Crash]),
tags=set(['win']))
], 5)
test_expectations.remove_expectations('/tmp/TestExpectations2', [
Expectation(
test='test2', results=set([ResultType.Failure]), lineno=5)
])
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations2')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure ]\n'
'\n'
'# This comment will be deleted\n'
'[ mac ] test1 [ Failure ]\n'
'[ Win ] test3 [ Crash ]\n'))
def test_remove_after_add(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'\n'
'# This comment will not be deleted\n'
'[ mac ] test1 [ Failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_to_exps = test_expectations._expectations[1].individual_exps
test_expectations.add_expectations('/tmp/TestExpectations2', [
Expectation(test='test2', results=set([ResultType.Failure])),
Expectation(
test='test3',
results=set([ResultType.Crash]),
tags=set(['mac']))
], 5)
test_expectations.remove_expectations('/tmp/TestExpectations2',
[test_to_exps['test1'][0]])
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations2')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'\n'
'# This comment will not be deleted\n'
'test2 [ Failure ]\n'
'[ Mac ] test3 [ Crash ]\n'))
class AddExpectationsTest(Base):
def test_add_expectation_end_of_file_nonzero_lineno(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# tags: [ release ]\n'
'# results: [ Failure ]\n'
'\n'
'# this is a block of expectations\n'
'test [ failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
with self.assertRaises(ValueError) as ctx:
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test3',
results=set([ResultType.Failure]))],
lineno=0)
test_expectations.commit_changes()
self.assertIn('append_to_end_of_file must be set to True',
str(ctx.exception))
def test_add_expectation_with_negative_lineno(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# tags: [ release ]\n'
'# results: [ Failure ]\n'
'\n'
'# this is a block of expectations\n'
'test [ failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
with self.assertRaises(ValueError) as ctx:
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test3',
results=set([ResultType.Failure]))],
lineno=-1)
test_expectations.commit_changes()
self.assertIn('cannot be negative', str(ctx.exception))
def test_add_expectation_outside_file_size_range(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# tags: [ release ]\n'
'# results: [ Failure ]\n'
'\n'
'# this is a block of expectations\n'
'test [ failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
with self.assertRaises(ValueError) as ctx:
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test3',
results=set([ResultType.Failure]))],
lineno=100)
test_expectations.commit_changes()
self.assertIn('greater than the total line count', str(ctx.exception))
def test_use_append_to_end_flag_non_zero_lineno(self):
# Use append_to_end_of_file=True with lineno != 0
# An exception should be raised.
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# tags: [ release ]\n'
'# results: [ Failure ]\n'
'\n'
'# this is a block of expectations\n'
'test [ failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
with self.assertRaises(ValueError) as ctx:
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test3',
results=set([ResultType.Failure]))],
lineno=100, append_to_end_of_file=True)
test_expectations.commit_changes()
self.assertIn('append_to_end_of_file is set then lineno must be 0',
str(ctx.exception))
def test_add_expectations_to_end_of_file(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# tags: [ release ]\n'
'# results: [ Failure ]\n'
'\n'
'# this is a block of expectations\n'
'test [ failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test3', results=set([ResultType.Failure]))],
append_to_end_of_file=True)
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test2', tags={'mac', 'release'},
results={ResultType.Crash, ResultType.Failure})],
append_to_end_of_file=True)
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test1', results=set([ResultType.Pass]))],
append_to_end_of_file=True)
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations2')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# tags: [ release ]\n'
'# results: [ Failure ]\n'
'\n'
'# this is a block of expectations\n'
'test [ failure ]\n'
'\n'
'test1 [ Pass ]\n'
'[ Release Mac ] test2 [ Failure Crash ]\n'
'test3 [ Failure ]\n'))
def test_add_after_remove(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'test1 [ Failure ]\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = ''
expectations_dict['/tmp/TestExpectations2'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_expectations.remove_expectations('/tmp/TestExpectations2', [
Expectation(
test='test1', results=set([ResultType.Failure]), lineno=3)
])
test_expectations.add_expectations(
'/tmp/TestExpectations2',
[Expectation(test='test2', results=set([ResultType.Crash]))], 3)
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations2')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'test2 [ Crash ]\n'))
def test_add_expectation_at_line(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'\n'
'# add expectations after this line\n'
'test1 [ Failure ]\n'
'\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_expectations.add_expectations('/tmp/TestExpectations', [
Expectation(
test='test2',
results=set([ResultType.Crash]),
tags=set(['win']))
], 4)
test_expectations.remove_expectations('/tmp/TestExpectations', [
Expectation(
test='test1', results=set([ResultType.Failure]), lineno=5)
])
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'\n'
'# add expectations after this line\n'
'[ Win ] test2 [ Crash ]\n'
'\n'))
class CommitChangesTests(Base):
def test_commit_changes_without_modifications(self):
port = MockHost().port_factory.get('test-win-win7')
raw_expectations = ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'\n'
'# add expectations after this line\n'
'test1 [ Failure ]\n'
'\n')
expectations_dict = OrderedDict()
expectations_dict['/tmp/TestExpectations'] = raw_expectations
test_expectations = TestExpectations(port, expectations_dict)
test_expectations.commit_changes()
content = port.host.filesystem.read_text_file('/tmp/TestExpectations')
self.assertEqual(content, ('# tags: [ Mac Win ]\n'
'# results: [ Failure Crash ]\n'
'\n'
'# add expectations after this line\n'
'test1 [ Failure ]\n'
'\n'))
class SkippedTests(Base):
def check(self,
expectations,
overrides,
ignore_tests,
lint=False,
expected_results=None):
expected_results = expected_results or [
ResultType.Skip, ResultType.Failure
]
port = MockHost().port_factory.get(
'test-win-win7',
options=optparse.Values({
'ignore_tests': ignore_tests
}))
port.host.filesystem.write_text_file(
port.host.filesystem.join(port.web_tests_dir(),
'failures/expected/text.html'), 'foo')
expectations_dict = OrderedDict()
expectations_dict['expectations'] = expectations
if overrides:
expectations_dict['overrides'] = overrides
port.expectations_dict = lambda: expectations_dict
expectations_to_lint = expectations_dict if lint else None
exp = TestExpectations(port, expectations_dict=expectations_to_lint)
self.assertEqual(
exp.get_expectations('failures/expected/text.html').results,
set(expected_results))
def test_skipped_file_overrides_expectations(self):
self.check(
expectations=
'# results: [ Failure Skip ]\nfailures/expected/text.html [ Failure ]\n',
overrides=None,
ignore_tests=['failures/expected/text.html'])
def test_skipped_file_overrides_overrides(self):
self.check(
expectations='# results: [ Skip Failure ]\n',
overrides=
'# results: [ Skip Failure ]\nfailures/expected/text.html [ Failure ]\n',
ignore_tests=['failures/expected/text.html'])
class PrecedenceTests(Base):
def test_file_over_directory(self):
# This tests handling precedence of specific lines over directories
# and tests expectations covering entire directories.
exp_str = """
# results: [ Failure Crash ]
failures/expected/text.html [ Failure ]
failures/expected* [ Crash ]
"""
self.parse_exp(exp_str)
self.assert_exp('failures/expected/text.html', ResultType.Failure)
self.assert_exp_list('failures/expected/crash.html',
[ResultType.Crash])
exp_str = """
# results: [ Failure Crash ]
failures/expected* [ Crash ]
failures/expected/text.html [ Failure ]
"""
self.parse_exp(exp_str)
self.assert_exp('failures/expected/text.html', ResultType.Failure)
self.assert_exp_list('failures/expected/crash.html',
[ResultType.Crash])