# Copyright (C) 2011 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.
import json
import optparse
import textwrap
import unittest
from unittest import mock
from blinkpy.common.checkout.baseline_optimizer import BaselineOptimizer, ResultDigest
from blinkpy.common.host_mock import MockHost
from blinkpy.common.system.filesystem_mock import MockFileSystem
from blinkpy.common.path_finder import PathFinder
from blinkpy.common.path_finder import RELATIVE_WEB_TESTS
from blinkpy.web_tests.builder_list import BuilderList
from blinkpy.web_tests.models.testharness_results import ABBREVIATED_ALL_PASS
ALL_PASS_TESTHARNESS_RESULT = """This is a testharness.js-based test.
[PASS] woohoo
Harness: the test ran to completion.
"""
ALL_PASS_TESTHARNESS_RESULT2 = """This is a testharness.js-based test.
[PASS] woohoo
[PASS] yahoo
Harness: the test ran to completion.
"""
MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS
class BaselineTest(unittest.TestCase):
# TODO(crbug.com/1376646): Consider expanding `FileSystemTestCase` for this
# similar use case. Currently, `FileSystemTestCase` can neither write
# initial baselines nor assert that baselines are removed.
def setUp(self):
self.host = MockHost()
self.fs = self.host.filesystem
self.finder = PathFinder(self.fs)
def _write_baselines(self, baseline_name: str, results_by_directory):
for dirname, contents in results_by_directory.items():
self.fs.write_text_file(
self.finder.path_from_web_tests(dirname, baseline_name),
contents)
def _assert_baselines(self, baseline_name: str, directory_to_new_results):
for dirname, contents in directory_to_new_results.items():
path = self.finder.path_from_web_tests(dirname, baseline_name)
if contents is None:
# Check files that are explicitly marked as absent.
self.assertFalse(
self.fs.exists(path),
'%s should not exist for copy/optimization' % path)
else:
self.assertEqual(self.fs.read_text_file(path), contents,
'Content of %s != "%s"' % (path, contents))
@mock.patch(
'blinkpy.web_tests.port.test.TestPort.FALLBACK_PATHS', {
'trusty': ['linux', 'win'],
'mac11': ['mac'],
'mac10.11': ['mac-mac10.11', 'mac'],
'mac10.10': ['mac-mac10.10', 'mac-mac10.11', 'mac'],
'win10': ['win'],
'win10-arm64': ['win10-arm64', 'win'],
'win7': ['win7', 'win'],
})
class BaselineOptimizerTest(BaselineTest):
def setUp(self):
super().setUp()
self.host.builders = BuilderList({
'Fake Test Win7': {
'port_name': 'test-win-win7',
'specifiers': ['Win7', 'Release']
},
'Fake Test Win10': {
'port_name': 'test-win-win10',
'specifiers': ['Win11', 'Release']
},
'Fake Test Win10-arm64': {
'port_name': 'test-win-win10-arm64',
'specifiers': ['Win10-arm64', 'Release']
},
'Fake Test Linux': {
'port_name': 'test-linux-trusty',
'specifiers': ['Trusty', 'Release']
},
'Fake Test Linux HighDPI': {
'port_name': 'test-linux-trusty',
'specifiers': ['Trusty', 'Release'],
'steps': {
'high_dpi_blink_web_tests': {
'flag_specific': 'highdpi',
},
},
},
'Fake Test Mac11': {
'port_name': 'test-mac-mac11',
'specifiers': ['Mac11', 'Release'],
},
'Fake Test Mac10.11': {
'port_name': 'test-mac-mac10.11',
'specifiers': ['Mac10.11', 'Release']
},
'Fake Test Mac10.10': {
'port_name': 'test-mac-mac10.10',
'specifiers': ['Mac10.10', 'Release']
},
})
def _assert_optimization(self,
results_by_directory,
directory_to_new_results,
baseline_dirname='',
suffix='txt',
options=None,
virtual_suites=None):
test_name = 'mock-test.html'
baseline_name = 'mock-test-expected.' + suffix
virtual_suites = virtual_suites or [{
'prefix':
'gpu',
'platforms': ['Linux', 'Mac', 'Win'],
'bases': [
'webexposed',
'fast/canvas',
'slow/canvas/mock-test.html',
'virtual/virtual_empty_bases/',
],
'args': ['--foo'],
}, {
'prefix':
'virtual_empty_bases',
'platforms': ['Linux', 'Mac', 'Win'],
'bases': [],
'args': ['--foo'],
}, {
'prefix':
'stable',
'platforms': ['Linux', 'Mac', 'Win'],
'bases': ['webexposed'],
'args': ['--stable-release-mode'],
}]
self.fs.write_text_file(
self.finder.path_from_web_tests('VirtualTestSuites'),
json.dumps(virtual_suites))
self.fs.write_text_file(
self.finder.path_from_web_tests('FlagSpecificConfig'),
'[{"name": "highdpi", "args": ["--force-device-scale-factor=1.5"]}]'
)
self.fs.write_text_file(
self.finder.path_from_web_tests('NeverFixTests'),
'# tags: [ Linux Mac Mac10.10 Mac10.11 Mac11 Win Win7 Win10 Win10-arm64 ]\n'
'# results: [ Skip Pass ]\n'
'[ Win7 ] virtual/gpu/fast/canvas/mock-test.html [ Skip ] \n')
self._write_baselines(baseline_name, results_by_directory)
if options:
options = optparse.Values(options)
baseline_optimizer = BaselineOptimizer(
self.host, self.host.port_factory.get(options=options),
self.host.port_factory.all_port_names())
self.assertTrue(
baseline_optimizer.optimize(
self.fs.join(baseline_dirname, test_name), suffix))
self._assert_baselines(baseline_name, directory_to_new_results)
for dirname in results_by_directory:
path = self.finder.path_from_web_tests(dirname, baseline_name)
if (dirname not in directory_to_new_results
or directory_to_new_results[dirname] is None):
self.assertFalse(
self.fs.exists(path),
'%s should not exist after optimization' % path)
def _assert_reftest_optimization(self,
results_by_directory,
directory_to_new_results,
test_path='',
baseline_dirname=''):
self.fs.write_text_file(
self.finder.path_from_web_tests(test_path,
'mock-test-expected.html'), 'ref')
self._assert_optimization(
results_by_directory,
directory_to_new_results,
baseline_dirname,
suffix='png')
def test_linux_redundant_with_win(self):
self._assert_optimization(
{
'platform/win': '1',
'platform/linux': '1',
}, {
'platform/win': '1',
'platform/linux': None,
})
def test_covers_mac_win(self):
self._assert_optimization({
'platform/mac': '1',
'platform/win': '1',
}, {
'': '1',
'platform/mac': None,
'platform/win': None,
})
def test_overwrites_root(self):
self._assert_optimization(
{
'platform/mac': '1',
'platform/win': '1',
'platform/linux': '1',
'': '2',
}, {
'': '1',
'platform/mac': None,
'platform/win': None,
'platform/linux': None,
})
def test_no_new_common_directory(self):
self._assert_optimization(
{
'platform/mac': '1',
'platform/linux': '1',
'': '2',
}, {
'platform/mac': '1',
'platform/linux': '1',
'': '2',
})
def test_local_optimization(self):
self._assert_optimization(
{
'platform/mac': '1',
'platform/linux': '1',
'platform/mac-mac10.11': '1',
}, {
'platform/mac': '1',
'platform/linux': '1',
'platform/mac-mac10.11': None,
})
def test_local_optimization_skipping_a_port_in_the_middle(self):
# mac-mac10.10 -> mac-mac10.11 -> mac
self._assert_optimization(
{
'platform/mac': '1',
'platform/linux': '1',
'platform/mac-mac10.10': '1',
}, {
'platform/mac': '1',
'platform/linux': '1',
'platform/mac-mac10.10': None,
})
def test_baseline_redundant_with_root(self):
self._assert_optimization(
{
'platform/mac': '1',
'platform/win': '2',
'': '2',
}, {
'platform/mac': '1',
'platform/win': None,
'': '2',
})
def test_root_baseline_unused(self):
self._assert_optimization(
{
'platform/mac': '1',
'platform/win': '2',
'': '3',
}, {
'platform/mac': '1',
'platform/win': '2',
})
def test_root_baseline_unused_and_non_existant(self):
self._assert_optimization({
'platform/mac': '1',
'platform/win': '2',
}, {
'platform/mac': '1',
'platform/win': '2',
})
def test_virtual_baseline_redundant_with_non_virtual(self):
self._assert_optimization(
{
'platform/win/virtual/gpu/fast/canvas': '2',
'platform/win/fast/canvas': '2',
}, {
'platform/win/fast/canvas': '2',
'platform/win/virtual/gpu/fast/canvas': None,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_baseline_redundant_with_non_virtual_fallback(self):
# virtual linux -> virtual win -> virtual root -> linux -> win
self._assert_optimization(
{
'platform/linux/virtual/gpu/fast/canvas': '2',
'platform/win/fast/canvas': '2',
}, {
'platform/linux/virtual/gpu/fast/canvas': None,
'platform/win/virtual/gpu/fast/canvas': None,
'platform/win/fast/canvas': '2',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_baseline_redundant_with_actual_root(self):
self._assert_optimization(
{
'platform/win/virtual/gpu/fast/canvas': '2',
'fast/canvas': '2',
}, {
'fast/canvas': '2',
'platform/win/virtual/gpu/fast/canvas': None,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_test_fallback_to_same_baseline_after_optimization_1(self):
self._assert_optimization(
{
'platform/win/fast/canvas': '1',
'platform/win7/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'platform/mac/virtual/gpu/fast/canvas': '1',
}, {
'platform/win/fast/canvas': '1',
'platform/win7/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'virtual/gpu/fast/canvas': None,
'platform/win/virtual/gpu/fast/canvas': None,
'platform/win7/virtual/gpu/fast/canvas': None,
'platform/mac/virtual/gpu/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_test_fallback_to_same_baseline_after_optimization_2(self):
self._assert_optimization(
{
'platform/mac-mac10.10/virtual/gpu/fast/canvas': '3',
'platform/mac-mac10.11/fast/canvas': '1',
'fast/canvas': '2',
}, {
'platform/mac-mac10.10/virtual/gpu/fast/canvas': '3',
'platform/mac-mac10.11/virtual/gpu/fast/canvas': None,
'platform/mac/virtual/gpu/fast/canvas': None,
'virtual/gpu/fast/canvas': None,
'platform/mac-mac10.11/fast/canvas': '1',
'fast/canvas': '2',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_test_fallback_to_same_baseline_after_optimization_3(self):
self._assert_optimization(
{
'platform/win/fast/canvas': '1',
'platform/linux/fast/canvas': '2',
'platform/mac/fast/canvas': '3',
'platform/linux/virtual/gpu/fast/canvas': '1',
}, {
'platform/win/fast/canvas': '1',
'platform/linux/fast/canvas': '2',
'platform/mac/fast/canvas': '3',
'platform/win/virtual/gpu/fast/canvas': None,
'platform/linux/virtual/gpu/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_test_redundant_with_nonvirtual_successor(self):
self._assert_optimization(
{
'platform/win/fast/canvas': '1',
'platform/linux/fast/canvas': '2',
'platform/mac/fast/canvas': '3',
'platform/linux/virtual/gpu/fast/canvas': '2',
}, {
'platform/win/fast/canvas': '1',
'platform/linux/fast/canvas': '2',
'platform/mac/fast/canvas': '3',
'platform/linux/virtual/gpu/fast/canvas': None,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_baseline_not_redundant_with_actual_root(self):
self._assert_optimization(
{
'platform/mac-mac10.10/virtual/gpu/fast/canvas': '1',
'platform/mac-mac10.10/fast/canvas': '1',
'fast/canvas': '2',
}, {
'platform/mac-mac10.10/virtual/gpu/fast/canvas': None,
'platform/mac/virtual/gpu/fast/canvas': None,
'virtual/gpu/fast/canvas': None,
'platform/mac-mac10.10/fast/canvas': '1',
'fast/canvas': '2',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_root_redundant_with_actual_root(self):
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '2',
'fast/canvas': '2',
}, {
'fast/canvas': '2',
'virtual/gpu/fast/canvas': None,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_root_redundant_with_ancestors(self):
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'platform/win/fast/canvas': '2',
}, {
'fast/canvas': '2',
'virtual/gpu/fast/canvas': None,
'platform/mac/fast/canvas': None,
'platform/win/fast/canvas': None,
},
baseline_dirname='fast/canvas')
def test_virtual_root_redundant_with_ancestors_exclude_skipped(self):
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'platform/win/fast/canvas': '2',
'platform/win7/fast/canvas': '1',
},
{
'virtual/gpu/fast/canvas': None,
'fast/canvas': '2',
# win7 skips the virtual test, so it is not deleted.
'platform/win7/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_root_not_redundant_with_ancestors(self):
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '1',
}, {
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_root_not_redundant_with_some_ancestors(self):
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'platform/mac-mac10.10/fast/canvas': '1',
}, {
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'platform/mac-mac10.10/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_platform_not_redundant_with_some_ancestors(self):
self._assert_optimization(
{
'platform/mac-mac10.11/virtual/gpu/fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas': '1',
'platform/mac-mac10.11/fast/canvas': '2',
'platform/mac/fast/canvas': '1',
}, {
'platform/mac-mac10.11/virtual/gpu/fast/canvas': None,
'platform/mac/virtual/gpu/fast/canvas': '1',
'platform/mac-mac10.11/fast/canvas': '2',
'platform/mac/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_root_not_redundant_with_flag_specific_ancestors(self):
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': '2',
'platform/win/fast/canvas': '2',
'flag-specific/highdpi/fast/canvas': '1',
}, {
'virtual/gpu/fast/canvas': '2',
'platform/mac/fast/canvas': None,
'platform/win/fast/canvas': None,
'fast/canvas': '2',
'flag-specific/highdpi/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_covers_mac_win(self):
self._assert_optimization(
{
'platform/mac/virtual/gpu/fast/canvas': '1',
'platform/win/virtual/gpu/fast/canvas': '1',
}, {
'virtual/gpu/fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas': None,
'platform/win/virtual/gpu/fast/canvas': None,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_exclusive_virtual_roots(self):
virtual_suites = [{
'prefix': 'gpu',
'platforms': ['Linux', 'Mac', 'Win'],
'bases': ['fast/canvas'],
'exclusive_tests': ['fast/canvas'],
'args': ['--foo'],
}, {
'prefix': 'not-gpu',
'platforms': ['Linux', 'Mac', 'Win'],
'bases': ['fast/canvas'],
'exclusive_tests': 'ALL',
'args': ['--bar'],
}]
self._assert_optimization(
{
'fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas': '1',
'platform/win/virtual/gpu/fast/canvas': '1',
'platform/mac/virtual/not-gpu/fast/canvas': '1',
'platform/win/virtual/not-gpu/fast/canvas': '1',
}, {
'fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas': None,
'platform/win/virtual/gpu/fast/canvas': None,
'platform/mac/virtual/not-gpu/fast/canvas': None,
'platform/win/virtual/not-gpu/fast/canvas': None,
},
baseline_dirname='fast/canvas',
virtual_suites=virtual_suites)
def test_all_pass_testharness_at_root(self):
self._assert_optimization({'': ALL_PASS_TESTHARNESS_RESULT},
{'': None})
def test_all_pass_testharness_at_linux(self):
self._assert_optimization({
'platform/linux': ALL_PASS_TESTHARNESS_RESULT
}, {'platform/linux': None})
def test_all_pass_testharness_at_linux_and_win(self):
# https://crbug.com/805008
self._assert_optimization(
{
'platform/linux': ALL_PASS_TESTHARNESS_RESULT,
'platform/win': ALL_PASS_TESTHARNESS_RESULT
}, {
'platform/linux': None,
'platform/win': None
})
def test_all_pass_testharness_abbreviated_with_full(self):
self._assert_optimization(
{
'platform/mac-mac10.10': ALL_PASS_TESTHARNESS_RESULT,
'platform/mac-mac10.11': ABBREVIATED_ALL_PASS,
'platform/mac': ALL_PASS_TESTHARNESS_RESULT2,
}, {
'platform/mac-mac10.10': None,
'platform/mac-mac10.11': None,
'platform/mac': None,
})
def test_all_pass_testharness_at_win_and_mac_not_redundant(self):
self._assert_optimization(
{
'fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas':
ALL_PASS_TESTHARNESS_RESULT,
'platform/win/virtual/gpu/fast/canvas':
ALL_PASS_TESTHARNESS_RESULT
}, {
'fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas': None,
'platform/win/virtual/gpu/fast/canvas': None,
'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_all_pass_testharness_at_virtual_root(self):
self._assert_optimization(
{'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT},
{'virtual/gpu/fast/canvas': None},
baseline_dirname='virtual/gpu/fast/canvas')
def test_all_pass_testharness_at_virtual_linux(self):
self._assert_optimization(
{
'platform/linux/virtual/gpu/fast/canvas':
ALL_PASS_TESTHARNESS_RESULT
}, {'platform/linux/virtual/gpu/fast/canvas': None},
baseline_dirname='virtual/gpu/fast/canvas')
def test_all_pass_testharness_can_be_updated(self):
# https://crbug.com/866802
self._assert_optimization(
{
'fast/canvas':
'failure',
'virtual/gpu/fast/canvas':
ALL_PASS_TESTHARNESS_RESULT,
'platform/win/virtual/gpu/fast/canvas':
ALL_PASS_TESTHARNESS_RESULT2,
'platform/mac/virtual/gpu/fast/canvas':
ALL_PASS_TESTHARNESS_RESULT2,
}, {
'fast/canvas': 'failure',
'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT2,
'platform/win/virtual/gpu/fast/canvas': None,
'platform/mac/virtual/gpu/fast/canvas': None,
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_all_pass_testharness_falls_back_to_non_pass(self):
# The all-PASS baseline needs to be preserved in this case.
self._assert_optimization(
{
'platform/linux': ALL_PASS_TESTHARNESS_RESULT,
'': '1'
}, {
'platform/linux': ALL_PASS_TESTHARNESS_RESULT,
'': '1'
})
def test_virtual_all_pass_testharness_falls_back_to_base(self):
# The all-PASS baseline needs to be preserved in this case.
self._assert_optimization(
{
'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT,
'platform/linux/fast/canvas': '1',
}, {
'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT,
'platform/linux/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_all_pass_testharness_falls_back_to_full_base_name(self):
# The all-PASS baseline needs to be preserved in this case.
self._assert_optimization(
{
'virtual/gpu/slow/canvas': ALL_PASS_TESTHARNESS_RESULT,
'platform/linux/slow/canvas': '1',
}, {
'virtual/gpu/slow/canvas': ALL_PASS_TESTHARNESS_RESULT,
'platform/linux/slow/canvas': '1',
},
baseline_dirname='virtual/gpu/slow/canvas')
def test_physical_under_dir_falls_back_to_virtual(self):
self._assert_optimization(
{
'virtual/gpu/virtual/virtual_empty_bases/': '1',
'virtual/virtual_empty_bases/': '1',
}, {
'virtual/gpu/virtual/virtual_empty_bases/': None,
'virtual/virtual_empty_bases/': '1',
},
baseline_dirname='virtual/virtual_empty_bases/')
def test_empty_at_root(self):
self._assert_optimization({'': ''}, {'': None})
def test_empty_at_linux(self):
self._assert_optimization({
'platform/linux': ''
}, {'platform/linux': None})
def test_empty_at_linux_and_win(self):
# https://crbug.com/805008
self._assert_optimization({
'platform/linux': '',
'platform/win': '',
}, {
'platform/linux': None,
'platform/win': None,
})
def test_empty_at_virtual_root(self):
self._assert_optimization({'virtual/gpu/fast/canvas': ''},
{'virtual/gpu/fast/canvas': None},
baseline_dirname='virtual/gpu/fast/canvas')
def test_empty_at_virtual_linux(self):
self._assert_optimization(
{
'platform/linux/virtual/gpu/fast/canvas': ''
}, {'platform/linux/virtual/gpu/fast/canvas': None},
baseline_dirname='virtual/gpu/fast/canvas')
def test_empty_falls_back_to_non_empty(self):
# The empty baseline needs to be preserved in this case.
self._assert_optimization({
'platform/linux': '',
'': '1',
}, {
'platform/linux': '',
'': '1',
})
def test_virtual_empty_falls_back_to_non_empty(self):
# The empty baseline needs to be preserved in this case.
self._assert_optimization(
{
'virtual/gpu/fast/canvas': '',
'platform/linux/fast/canvas': '1',
}, {
'virtual/gpu/fast/canvas': '',
'platform/linux/fast/canvas': '1',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_subtree_identical_to_nonvirtual_alternating(self):
self._assert_optimization(
{
'platform/mac-mac10.11/virtual/gpu/fast/canvas': '1',
'platform/mac/virtual/gpu/fast/canvas': '2',
'virtual/gpu/fast/canvas': '3',
'platform/mac-mac10.11/fast/canvas': '1',
'platform/mac/fast/canvas': '2',
'fast/canvas': '3',
}, {
'platform/mac-mac10.11/fast/canvas': '1',
'platform/mac/fast/canvas': '2',
'fast/canvas': '3',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_virtual_stable_webexposed_preserved(self):
self._assert_optimization(
{
'platform/mac/virtual/gpu/webexposed': '1',
'platform/win/virtual/gpu/webexposed': '1',
'platform/mac/virtual/stable/webexposed': '1',
'platform/win/virtual/stable/webexposed': '1',
'platform/mac/webexposed': '1',
'platform/win/webexposed': '1',
},
{
'webexposed': '1',
# Baselines are optimized among platforms, but not between the
# virtual/nonvirtual trees for the "stable" suite, so this
# virtual root should still exist.
'virtual/stable/webexposed': '1',
},
baseline_dirname='webexposed')
def test_extra_png_for_reftest_at_root(self):
self._assert_reftest_optimization({'': 'extra'}, {'': None})
def test_extra_png_for_reftest_at_linux(self):
self._assert_reftest_optimization({
'platform/linux': 'extra'
}, {'platform/linux': None})
def test_extra_png_for_reftest_at_linux_and_win(self):
# https://crbug.com/805008
self._assert_reftest_optimization({
'platform/linux': 'extra1',
'platform/win': 'extra2',
}, {
'platform/linux': None,
'platform/win': None,
})
def test_extra_png_for_reftest_at_virtual_root(self):
self._assert_reftest_optimization(
{'virtual/gpu/fast/canvas': 'extra'},
{'virtual/gpu/fast/canvas': None},
test_path='fast/canvas',
baseline_dirname='virtual/gpu/fast/canvas')
def test_extra_png_for_reftest_at_virtual_linux(self):
self._assert_reftest_optimization(
{
'platform/linux/virtual/gpu/fast/canvas': 'extra'
}, {'platform/linux/virtual/gpu/fast/canvas': None},
test_path='fast/canvas',
baseline_dirname='virtual/gpu/fast/canvas')
def test_extra_png_for_reftest_falls_back_to_base(self):
# The extra png for reftest should be removed even if it's different
# from the fallback.
self._assert_reftest_optimization(
{
'platform/linux': 'extra1',
'': 'extra2',
}, {
'platform/linux': None,
'': None,
})
def test_virtual_extra_png_for_reftest_falls_back_to_base(self):
# The extra png for reftest should be removed even if it's different
# from the fallback.
self._assert_reftest_optimization(
{
'virtual/gpu/fast/canvas': 'extra',
'platform/linux/fast/canvas': 'extra2',
}, {
'virtual/gpu/fast/canvas': None,
'platform/linux/fast/canvas': None,
},
test_path='fast/canvas',
baseline_dirname='fast/canvas')
def test_flag_specific_falls_back_to_base(self):
self._assert_optimization(
{
'fast/canvas': '1',
'flag-specific/highdpi/fast/canvas': '1',
}, {
'fast/canvas': '1',
},
baseline_dirname='fast/canvas')
def test_flag_specific_virtual_falls_back_to_virtual_base(self):
self._assert_optimization(
{
'fast/canvas': '1',
'virtual/gpu/fast/canvas': '2',
'flag-specific/highdpi/fast/canvas': '3',
'flag-specific/highdpi/virtual/gpu/fast/canvas': '2',
}, {
'fast/canvas': '1',
'virtual/gpu/fast/canvas': '2',
'flag-specific/highdpi/fast/canvas': '3',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_flag_specific_virtual_falls_back_to_flag_specific(self):
self._assert_optimization(
{
'fast/canvas': '1',
'flag-specific/highdpi/fast/canvas': '2',
'flag-specific/highdpi/virtual/gpu/fast/canvas': '2',
}, {
'fast/canvas': '1',
'flag-specific/highdpi/fast/canvas': '2',
},
baseline_dirname='virtual/gpu/fast/canvas')
def test_both_flag_specific_falls_back_to_base(self):
self._assert_optimization(
{
'fast/canvas': '1',
'flag-specific/highdpi/fast/canvas': '1',
'flag-specific/highdpi/virtual/gpu/fast/canvas': '1',
}, {
'fast/canvas': '1',
},
baseline_dirname='fast/canvas')
def test_preorder_removal_more_favorable(self):
# Regression test for crbug.com/1512264
self._assert_optimization(
{
'platform/win10-arm64/slow/canvas': '3',
'platform/win7/slow/canvas': '2',
'platform/linux/slow/canvas': '1',
'platform/win/virtual/gpu/slow/canvas':
ALL_PASS_TESTHARNESS_RESULT,
'platform/win10-arm64/virtual/gpu/slow/canvas':
ALL_PASS_TESTHARNESS_RESULT,
'platform/win7/virtual/gpu/slow/canvas': '2',
'platform/linux/virtual/gpu/slow/canvas': '1',
}, {
'platform/win10-arm64/slow/canvas':
'3',
'platform/win7/slow/canvas':
'2',
'platform/linux/slow/canvas':
'1',
'platform/win10-arm64/virtual/gpu/slow/canvas':
ALL_PASS_TESTHARNESS_RESULT,
},
baseline_dirname='slow/canvas')
class ResultDigestTest(unittest.TestCase):
def setUp(self):
self.host = MockHost()
self.fs = MockFileSystem()
self.host.filesystem = self.fs
self.fs.write_text_file('/all-pass/foo-expected.txt',
ALL_PASS_TESTHARNESS_RESULT)
self.fs.write_text_file('/all-pass/bar-expected.txt',
ALL_PASS_TESTHARNESS_RESULT2)
self.fs.write_text_file('/failures/baz-expected.txt', 'failure')
self.fs.write_binary_file('/others/reftest-expected.png', b'extra')
self.fs.write_binary_file('/others/reftest2-expected.png', b'extra2')
self.fs.write_text_file('/others/empty-expected.txt', '')
self.fs.write_binary_file('/others/something-expected.png',
b'Something')
self.fs.write_binary_file('/others/empty-expected.png', b'')
def test_all_pass_testharness_result(self):
self.assertTrue(
ResultDigest.from_file(
self.fs, '/all-pass/foo-expected.txt').is_extra_result)
self.assertTrue(
ResultDigest.from_file(
self.fs, '/all-pass/bar-expected.txt').is_extra_result)
self.assertFalse(
ResultDigest.from_file(
self.fs, '/failures/baz-expected.txt').is_extra_result)
def test_canonicalize_testharness(self):
self.fs.write_text_file(
'/platform/x/failures/baz-expected.txt',
textwrap.dedent("""\
This is a testharness.js-based test.
[FAIL] failing subtest
Harness: the test ran to completion.
"""))
self.fs.write_text_file(
'/failures/baz-expected.txt',
textwrap.dedent("""\
This is a testharness.js-based test.
[FAIL] failing subtest
Harness: the test ran to completion.
"""))
self.assertEqual(
ResultDigest.from_file(self.fs,
'/platform/x/failures/baz-expected.txt'),
ResultDigest.from_file(self.fs, '/failures/baz-expected.txt'))
def test_empty_result(self):
self.assertFalse(
ResultDigest.from_file(
self.fs, '/others/something-expected.png').is_extra_result)
self.assertTrue(
ResultDigest.from_file(
self.fs, '/others/empty-expected.txt').is_extra_result)
self.assertTrue(
ResultDigest.from_file(
self.fs, '/others/empty-expected.png').is_extra_result)
def test_extra_png_for_reftest_result(self):
self.assertFalse(
ResultDigest.from_file(
self.fs, '/others/something-expected.png').is_extra_result)
self.assertTrue(
ResultDigest.from_file(self.fs,
'/others/reftest-expected.png',
is_reftest=True).is_extra_result)
def test_non_extra_result(self):
self.assertFalse(
ResultDigest.from_file(
self.fs, '/others/something-expected.png').is_extra_result)
def test_implicit_extra_result(self):
# Implicit empty equal to any extra result but not failures.
implicit = ResultDigest.from_file(None, None)
self.assertEqual(
implicit,
ResultDigest.from_file(self.fs, '/all-pass/foo-expected.txt'))
self.assertEqual(
implicit,
ResultDigest.from_file(self.fs, '/all-pass/bar-expected.txt'))
self.assertNotEqual(
implicit,
ResultDigest.from_file(self.fs, '/failures/baz-expected.txt'))
self.assertEqual(
implicit,
ResultDigest.from_file(self.fs,
'/others/reftest-expected.png',
is_reftest=True))
def test_different_all_pass_results(self):
x = ResultDigest.from_file(self.fs, '/all-pass/foo-expected.txt')
y = ResultDigest.from_file(self.fs, '/all-pass/bar-expected.txt')
self.assertTrue(x != y)
self.assertFalse(x == y)
def test_same_extra_png_for_reftest(self):
x = ResultDigest.from_file(self.fs,
'/others/reftest-expected.png',
is_reftest=True)
y = ResultDigest.from_file(self.fs,
'/others/reftest2-expected.png',
is_reftest=True)
self.assertTrue(x == y)
self.assertFalse(x != y)