blob: a62e9ade831a7af66ab47cc307965d780d7264a7 [file] [log] [blame]
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import logging
from blinkpy.common.host_mock import MockHost
from blinkpy.common.net.git_cl import TryJobStatus
from blinkpy.common.net.git_cl_mock import MockGitCL
from blinkpy.common.net.results_fetcher import Build
from blinkpy.common.net.web_test_results import WebTestResults
from blinkpy.common.system.log_testing import LoggingTestCase
from blinkpy.w3c.wpt_manifest import BASE_MANIFEST_NAME
from blinkpy.web_tests.builder_list import BuilderList
from blinkpy.web_tests.port.factory_mock import MockPortFactory
from blinkpy.web_tests.port.android import (
PRODUCTS_TO_EXPECTATION_FILE_PATHS, ANDROID_DISABLED_TESTS,
ANDROID_WEBLAYER, ANDROID_WEBVIEW, CHROME_ANDROID,
PRODUCTS_TO_STEPNAMES)
from blinkpy.w3c.android_wpt_expectations_updater import (
AndroidWPTExpectationsUpdater)
WEBLAYER_WPT_STEP = PRODUCTS_TO_STEPNAMES[ANDROID_WEBLAYER]
WEBVIEW_WPT_STEP = PRODUCTS_TO_STEPNAMES[ANDROID_WEBVIEW]
CHROME_ANDROID_WPT_STEP = PRODUCTS_TO_STEPNAMES[CHROME_ANDROID]
class AndroidWPTExpectationsUpdaterTest(LoggingTestCase):
_raw_android_expectations = (
'# results: [ Failure Crash Timeout]\n'
'\n'
'# Add untriaged failures in this block\n'
'external/wpt/abc.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/def.html [ Crash ]\n'
'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n'
'crbug.com/1111111 external/wpt/jkl.html [ Failure ]\n'
'external/wpt/www.html [ Crash Failure ]\n'
'crbug.com/1050754 external/wpt/cat.html [ Failure ]\n'
'external/wpt/dog.html [ Crash Timeout ]\n'
'crbug.com/6789043 external/wpt/van.html [ Failure ]\n'
'external/wpt/unexpected_pass.html [ Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n')
_raw_android_never_fix_tests = (
'# tags: [ android-weblayer android-webview chrome-android ]\n'
'# results: [ Skip ]\n'
'\n'
'# Add untriaged disabled tests in this block\n'
'crbug.com/1050754 [ android-webview ] external/wpt/disabled.html [ Skip ]\n')
def _setup_host(self):
"""Returns a mock host with fake values set up for testing."""
self.set_logging_level(logging.DEBUG)
host = MockHost()
host.port_factory = MockPortFactory(host)
host.executive._output = ''
# Set up a fake list of try builders.
host.builders = BuilderList({
'MOCK Try Precise': {
'port_name': 'test-linux-precise',
'specifiers': ['Precise', 'Release'],
'is_try_builder': True,
},
'MOCK Android Weblayer - Pie': {
'port_name': 'test-android-pie',
'specifiers': ['Precise', 'Release',
'anDroid', 'android_Weblayer'],
'is_try_builder': True,
},
'MOCK Android Pie': {
'port_name': 'test-android-pie',
'specifiers': ['Precise', 'Release', 'anDroid',
'Android_Webview', 'Chrome_Android'],
'is_try_builder': True,
},
})
host.filesystem.write_text_file(
host.port_factory.get().web_tests_dir() + '/external/' +
BASE_MANIFEST_NAME,
json.dumps({
'items': {
'testharness': {
'ghi.html': ['abcdef123', [None, {}]],
'van.html': ['abcdef123', [None, {}]],
},
},
}))
# Write dummy expectations
for path in PRODUCTS_TO_EXPECTATION_FILE_PATHS.values():
host.filesystem.write_text_file(
path, self._raw_android_expectations)
host.filesystem.write_text_file(
ANDROID_DISABLED_TESTS, self._raw_android_never_fix_tests)
return host
def testUpdateTestExpectationsForWebview(self):
host = self._setup_host()
host.results_fetcher.set_results(
Build('MOCK Android Pie', 123),
WebTestResults({
'tests': {
'abc.html': {
'expected': 'PASS',
'actual': 'CRASH TIMEOUT',
'is_unexpected': True,
},
'jkl.html': {
'expected': 'PASS',
'actual': 'FAIL',
'is_unexpected': True,
},
'cat.html': {
'expected': 'PASS',
'actual': 'CRASH CRASH TIMEOUT',
'is_unexpected': True,
},
'unexpected_pass.html': {
'expected': 'FAIL',
'actual': 'PASS',
'is_unexpected': True
},
'dog.html': {
'expected': 'SKIP',
'actual': 'SKIP',
'is_unexpected': True,
},
},
}, step_name=WEBVIEW_WPT_STEP + ' (with patch)'),
step_name=WEBVIEW_WPT_STEP + ' (with patch)')
updater = AndroidWPTExpectationsUpdater(
host, ['-vvv', '--android-product', ANDROID_WEBVIEW,
'--clean-up-test-expectations',
'--clean-up-affected-tests-only',
'--include-unexpected-pass'])
updater.git_cl = MockGitCL(host, {
Build('MOCK Android Pie', 123):
TryJobStatus('COMPLETED', 'FAILURE')})
# Run command
updater.run()
# Get new expectations
content = host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[ANDROID_WEBVIEW])
self.assertEqual(
content,
('# results: [ Failure Crash Timeout]\n'
'\n'
'# Add untriaged failures in this block\n'
'crbug.com/1050754 external/wpt/abc.html [ Crash Failure Timeout ]\n'
'crbug.com/1050754 external/wpt/cat.html [ Crash Failure Timeout ]\n'
'crbug.com/1050754 external/wpt/def.html [ Crash ]\n'
'external/wpt/dog.html [ Crash Timeout ]\n'
'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n'
'crbug.com/1111111 crbug.com/1050754'
' external/wpt/jkl.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/unexpected_pass.html [ Failure Pass ]\n'
'crbug.com/6789043 external/wpt/van.html [ Failure ]\n'
'external/wpt/www.html [ Crash Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n'))
neverfix_content = host.filesystem.read_text_file(
ANDROID_DISABLED_TESTS)
self.assertEqual(
neverfix_content,
('# tags: [ android-weblayer android-webview chrome-android ]\n'
'# results: [ Skip ]\n'
'\n'
'# Add untriaged disabled tests in this block\n'
'crbug.com/1050754 [ android-webview ] external/wpt/disabled.html [ Skip ]\n'
'crbug.com/1050754 [ android-webview ] external/wpt/dog.html [ Skip ]\n'))
# check that chrome android's expectation file was not modified
# since the same bot is used to update chrome android & webview
# expectations
self.assertEqual(
host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[CHROME_ANDROID]),
self._raw_android_expectations)
# Check logs
logs = ''.join(self.logMessages()).lower()
self.assertNotIn(WEBLAYER_WPT_STEP, logs)
self.assertNotIn(CHROME_ANDROID_WPT_STEP, logs)
# Check that weblayer and chrome expectation files were not changed
self.assertEqual(
self._raw_android_expectations,
host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[CHROME_ANDROID]))
self.assertEqual(
self._raw_android_expectations,
host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[ANDROID_WEBLAYER]))
def testUpdateTestExpectationsForWeblayer(self):
host = self._setup_host()
host.results_fetcher.set_results(
Build('MOCK Android Weblayer - Pie', 123),
WebTestResults({
'tests': {
'abc.html': {
'expected': 'PASS',
'actual': 'CRASH TIMEOUT',
'is_unexpected': True,
},
'jkl.html': {
'expected': 'PASS',
'actual': 'FAIL',
'is_unexpected': True,
},
'cat.html': {
'expected': 'PASS',
'actual': 'CRASH CRASH TIMEOUT',
'is_unexpected': True,
},
'unexpected_pass.html': {
'expected': 'FAIL',
'actual': 'PASS',
'is_unexpected': True,
},
'new.html': {
'expected': 'PASS',
'actual': 'CRASH CRASH FAIL',
'is_unexpected': True,
},
},
}, step_name=WEBLAYER_WPT_STEP + ' (with patch)'),
step_name=WEBLAYER_WPT_STEP + ' (with patch)')
updater = AndroidWPTExpectationsUpdater(
host, ['-vvv', '--android-product', ANDROID_WEBLAYER,
'--clean-up-test-expectations',
'--clean-up-affected-tests-only',
'--include-unexpected-pass'])
updater.git_cl = MockGitCL(host, {
Build('MOCK Android Weblayer - Pie', 123):
TryJobStatus('COMPLETED', 'FAILURE')})
# Run command
updater.run()
# Get new expectations
content = host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[ANDROID_WEBLAYER])
self.assertEqual(
content,
('# results: [ Failure Crash Timeout]\n'
'\n'
'# Add untriaged failures in this block\n'
'crbug.com/1050754 external/wpt/abc.html [ Crash Failure Timeout ]\n'
'crbug.com/1050754 external/wpt/cat.html [ Crash Failure Timeout ]\n'
'crbug.com/1050754 external/wpt/def.html [ Crash ]\n'
'external/wpt/dog.html [ Crash Timeout ]\n'
'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n'
'crbug.com/1111111 crbug.com/1050754'
' external/wpt/jkl.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/new.html [ Failure Crash ]\n'
'crbug.com/1050754 external/wpt/unexpected_pass.html [ Failure Pass ]\n'
'crbug.com/6789043 external/wpt/van.html [ Failure ]\n'
'external/wpt/www.html [ Crash Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n'))
# Check logs
logs = ''.join(self.logMessages()).lower()
self.assertNotIn(WEBVIEW_WPT_STEP, logs)
self.assertNotIn(CHROME_ANDROID_WPT_STEP, logs)
# Check that webview and chrome expectation files were not changed
self.assertEqual(
self._raw_android_expectations,
host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[CHROME_ANDROID]))
self.assertEqual(
self._raw_android_expectations,
host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[ANDROID_WEBVIEW]))
self.assertEqual(
self._raw_android_never_fix_tests,
host.filesystem.read_text_file(ANDROID_DISABLED_TESTS))
def testCleanupAndUpdateTestExpectationsForAll(self):
# Full integration test for expectations cleanup and update
# using builder results.
host = self._setup_host()
# Add results for Weblayer
host.results_fetcher.set_results(
Build('MOCK Android Weblayer - Pie', 123),
WebTestResults({
'tests': {
'abc.html': {
'expected': 'PASS',
'actual': 'CRASH TIMEOUT',
'is_unexpected': True,
},
'weblayer_only.html': {
'expected': 'PASS',
'actual': 'CRASH CRASH FAIL',
'is_unexpected': True,
},
'disabled_weblayer_only.html': {
'expected': 'SKIP',
'actual': 'SKIP',
'is_unexpected': True,
},
'unexpected_pass.html': {
'expected': 'FAIL',
'actual': 'PASS',
'is_unexpected': True
},
},
}, step_name=WEBLAYER_WPT_STEP + ' (with patch)'),
step_name=WEBLAYER_WPT_STEP + ' (with patch)')
# Add Results for Webview
host.results_fetcher.set_results(
Build('MOCK Android Pie', 101),
WebTestResults({
'tests': {
'cat.html': {
'expected': 'PASS',
'actual': 'CRASH FAIL TIMEOUT',
'is_unexpected': True,
},
'webview_only.html': {
'expected': 'PASS',
'actual': 'TIMEOUT',
'is_unexpected': True,
},
'disabled.html': {
'expected': 'SKIP',
'actual': 'SKIP',
},
'unexpected_pass.html': {
'expected': 'FAIL',
'actual': 'PASS',
'is_unexpected': True
},
},
}, step_name=WEBVIEW_WPT_STEP + ' (with patch)'),
step_name=WEBVIEW_WPT_STEP + ' (with patch)')
# Add Results for Chrome
host.results_fetcher.set_results(
Build('MOCK Android Pie', 101),
WebTestResults({
'tests': {
'jkl.html': {
'expected': 'PASS',
'actual': 'FAIL',
'is_unexpected': True,
},
'chrome_only.html': {
'expected': 'PASS',
'actual': 'CRASH CRASH TIMEOUT',
'is_unexpected': True,
},
'disabled.html': {
'expected': 'SKIP',
'actual': 'SKIP',
'is_unexpected': True,
},
'unexpected_pass.html': {
'expected': 'FAIL',
'actual': 'PASS',
'is_unexpected': True
},
},
}, step_name=CHROME_ANDROID_WPT_STEP + ' (with patch)'),
step_name=CHROME_ANDROID_WPT_STEP + ' (with patch)')
updater = AndroidWPTExpectationsUpdater(
host, ['-vvv',
'--clean-up-test-expectations',
'--clean-up-affected-tests-only',
'--include-unexpected-pass',
'--android-product', ANDROID_WEBLAYER,
'--android-product', CHROME_ANDROID,
'--android-product', ANDROID_WEBVIEW])
def _git_command_return_val(cmd):
if '--diff-filter=D' in cmd:
return 'external/wpt/ghi.html'
if '--diff-filter=R' in cmd:
return 'C external/wpt/van.html external/wpt/wagon.html'
return ''
updater.git_cl = MockGitCL(host, {
Build('MOCK Android Weblayer - Pie', 123):
TryJobStatus('COMPLETED', 'FAILURE'),
Build('MOCK Android Pie', 101):
TryJobStatus('COMPLETED', 'FAILURE')})
updater.git.run = _git_command_return_val
updater._relative_to_web_test_dir = lambda test_path: test_path
# Run command
updater.run()
# Check expectations for weblayer
content = host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[ANDROID_WEBLAYER])
self.assertEqual(
content,
('# results: [ Failure Crash Timeout]\n'
'\n'
'# Add untriaged failures in this block\n'
'crbug.com/1050754 external/wpt/abc.html [ Crash Failure Timeout ]\n'
'crbug.com/1050754 external/wpt/cat.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/def.html [ Crash ]\n'
'external/wpt/dog.html [ Crash Timeout ]\n'
'crbug.com/1111111 external/wpt/jkl.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/unexpected_pass.html [ Failure Pass ]\n'
'crbug.com/6789043 external/wpt/wagon.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/weblayer_only.html [ Failure Crash ]\n'
'external/wpt/www.html [ Crash Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n'))
# Check expectations for webview
content = host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[ANDROID_WEBVIEW])
self.assertEqual(
content,
('# results: [ Failure Crash Timeout]\n'
'\n'
'# Add untriaged failures in this block\n'
'external/wpt/abc.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/cat.html [ Crash Failure Timeout ]\n'
'crbug.com/1050754 external/wpt/def.html [ Crash ]\n'
'external/wpt/dog.html [ Crash Timeout ]\n'
'crbug.com/1111111 external/wpt/jkl.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/unexpected_pass.html [ Failure Pass ]\n'
'crbug.com/6789043 external/wpt/wagon.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/webview_only.html [ Timeout ]\n'
'external/wpt/www.html [ Crash Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n'))
# Check expectations chrome
content = host.filesystem.read_text_file(
PRODUCTS_TO_EXPECTATION_FILE_PATHS[CHROME_ANDROID])
self.assertEqual(
content,
('# results: [ Failure Crash Timeout]\n'
'\n'
'# Add untriaged failures in this block\n'
'external/wpt/abc.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/cat.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/chrome_only.html [ Crash Timeout ]\n'
'crbug.com/1050754 external/wpt/def.html [ Crash ]\n'
'external/wpt/dog.html [ Crash Timeout ]\n'
'crbug.com/1111111 crbug.com/1050754'
' external/wpt/jkl.html [ Failure ]\n'
'crbug.com/1050754 external/wpt/unexpected_pass.html [ Failure Pass ]\n'
'crbug.com/6789043 external/wpt/wagon.html [ Failure ]\n'
'external/wpt/www.html [ Crash Failure ]\n'
'\n'
'# This comment will not be deleted\n'
'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n'))
# Check disabled test file
neverfix_content = host.filesystem.read_text_file(ANDROID_DISABLED_TESTS)
self.assertEqual(
neverfix_content,
('# tags: [ android-weblayer android-webview chrome-android ]\n'
'# results: [ Skip ]\n'
'\n'
'# Add untriaged disabled tests in this block\n'
'crbug.com/1050754 [ android-webview ] external/wpt/disabled.html [ Skip ]\n'
'crbug.com/1050754 [ chrome-android ] external/wpt/disabled.html [ Skip ]\n'
'crbug.com/1050754 [ android-weblayer ] external/wpt/disabled_weblayer_only.html [ Skip ]\n'))