blob: 540e0f167bd67386dede0a10f2995b59db46fe8f [file] [log] [blame]
#!/usr/bin/env python
# Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
# Copyright (C) 2015 Canon 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:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "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 HOLDER 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.
"""
This script imports W3C tests into WebKit, either from a local folder or by cloning W3C CSS and WPT repositories.
This script will import the tests into WebKit following these rules:
- All tests are by default imported into LayoutTests/imported/w3c
- Tests will be imported into a directory tree that mirrors WPT repository in LayoutTests/imported/w3c/web-platform-tests.
- By default, only reftests and jstest are imported. This can be overridden with a -a or --all
argument
- Also by default, if test files by the same name already exist in the destination directory,
they are overwritten with the idea that running this script would refresh files periodically.
This can also be overridden by a -n or --no-overwrite flag
- If no import_directory is provided, the script will download the tests from the W3C github repositories.
The selection of tests and folders to import will be based on the following files:
1. LayoutTests/imported/w3c/resources/TestRepositories lists the repositories to clone, the corresponding revision to checkout and the infrastructure folders that need to be imported/skipped.
2. LayoutTests/imported/w3c/resources/ImportExpectations list the test suites or tests to NOT import.
- All files are converted to work in WebKit:
1. Paths to testharness.js files are modified to point to Webkit's copy of them in
LayoutTests/resources, using the correct relative path from the new location.
This is applied to CSS tests but not to WPT tests.
2. All CSS properties requiring the -webkit-vendor prefix are prefixed - this current
list of what needs prefixes is read from Source/WebCore/CSS/CSSProperties.in
3. Each reftest has its own copy of its reference file following the naming conventions
new-run-webkit-tests expects
4. If a reference files lives outside the directory of the test that uses it, it is checked
for paths to support files as it will be imported into a different relative position to the
test file (in the same directory)
- Upon completion, script outputs the total number tests imported, broken down by test type
- Also upon completion, each directory where files are imported will have w3c-import.log written
with a timestamp, the list of CSS properties used that require prefixes, the list of imported files,
and guidance for future test modification and maintenance.
- On subsequent imports, this file is read to determine if files have been removed in the newer changesets.
The script removes these files accordingly.
"""
import argparse
import json
import logging
import mimetypes
from webkitpy.common.host import Host
from webkitpy.common.system.filesystem import FileSystem
from webkitpy.common.webkit_finder import WebKitFinder
from webkitpy.w3c.common import WPT_GH_URL, WPTPaths
from webkitpy.w3c.test_parser import TestParser
from webkitpy.w3c.test_converter import convert_for_webkit
from webkitpy.w3c.test_downloader import TestDownloader
CHANGESET_NOT_AVAILABLE = 'Not Available'
_log = logging.getLogger(__name__)
def main(_argv, _stdout, _stderr):
options, test_paths = parse_args(_argv)
configure_logging()
test_importer = TestImporter(Host(), test_paths, options)
test_importer.do_import()
def configure_logging():
class LogHandler(logging.StreamHandler):
def format(self, record):
if record.levelno > logging.INFO:
return "%s: %s" % (record.levelname, record.getMessage())
return record.getMessage()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
handler = LogHandler()
handler.setLevel(logging.INFO)
logger.addHandler(handler)
return handler
# FIXME: We should decide whether we want to make this specific to web-platform-tests or to make it generic to any git repository containing tests.
def parse_args(args):
description = """
To import a web-platform-tests test suite named xyz, use: 'import-w3c-tests web-platform-tests/xyz'.
To import a web-platform-tests suite from a specific folder, use 'import-w3c-tests xyz -l -s my-folder-containing-web-platform-tests-folder'"""
parser = argparse.ArgumentParser(prog='import-w3c-tests [web-platform-tests/test-suite-name...]', description=description, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-n', '--no-overwrite', dest='overwrite', action='store_false', default=True,
help='Flag to prevent duplicate test files from overwriting existing tests. By default, they will be overwritten')
parser.add_argument('-l', '--no-links-conversion', dest='convert_test_harness_links', action='store_false', default=True,
help='Do not change links (testharness js or css e.g.). This option only applies when providing a source directory, in which case by default, links are converted to point to WebKit testharness files. When tests are downloaded from W3C repository, links are converted for CSS tests and remain unchanged for WPT tests')
parser.add_argument('-t', '--tip-of-tree', dest='use_tip_of_tree', action='store_true', default=False,
help='Import all tests using the latest repository revision')
parser.add_argument('-a', '--all', action='store_true', default=False,
help='Import all tests including reftests, JS tests, and manual/pixel tests. By default, only reftests and JS tests are imported')
fs = FileSystem()
parser.add_argument('-d', '--dest-dir', dest='destination', default=fs.join('imported', 'w3c'),
help='Import into a specified directory relative to the LayoutTests root. By default, imports into imported/w3c')
parser.add_argument('-s', '--src-dir', dest='source', default=None,
help='Import from a specific folder which contains web-platform-tests folder. If not provided, the script will clone the necessary repositories.')
parser.add_argument('-v', '--verbose', action='store_true', default=False,
help='Print maximal log')
parser.add_argument('--no-fetch', action='store_false', dest='fetch', default=True,
help='Do not fetch the repositories. By default, repositories are fetched if a source directory is not provided')
parser.add_argument('--import-all', action='store_true', default=False,
help='Ignore the import-expectations.json file. All tests will be imported. This option only applies when tests are downloaded from W3C repository')
parser.add_argument('--clean-dest-dir', action='store_true', dest='clean_destination_directory', default=False,
help='Clean destination directory. All files in the destination directory will be deleted except for WebKit specific files (test expectations, .gitignore...) before new tests import. Dangling test expectations (expectation file that is no longer related to a test) are removed after tests import.')
options, args = parser.parse_known_args(args)
return options, args
class TestImporter(object):
def __init__(self, host, test_paths, options):
self.host = host
self.source_directory = options.source
self.options = options
self.test_paths = test_paths if test_paths else []
self.filesystem = self.host.filesystem
webkit_finder = WebKitFinder(self.filesystem)
self._webkit_root = webkit_finder.webkit_base()
self.destination_directory = webkit_finder.path_from_webkit_base("LayoutTests", options.destination)
self.tests_w3c_relative_path = self.filesystem.join('imported', 'w3c')
self.layout_tests_path = webkit_finder.path_from_webkit_base('LayoutTests')
self.layout_tests_w3c_path = self.filesystem.join(self.layout_tests_path, self.tests_w3c_relative_path)
self.tests_download_path = WPTPaths.checkout_directory(webkit_finder)
self._test_downloader = None
self._potential_test_resource_files = []
self.import_list = []
self._importing_downloaded_tests = self.source_directory is None
self._test_resource_files_json_path = self.filesystem.join(self.layout_tests_w3c_path, "resources", "resource-files.json")
self._test_resource_files = json.loads(self.filesystem.read_text_file(self._test_resource_files_json_path)) if self.filesystem.exists(self._test_resource_files_json_path) else None
self._tests_options_json_path = self.filesystem.join(self.layout_tests_path, 'tests-options.json')
self._tests_options = json.loads(self.filesystem.read_text_file(self._tests_options_json_path)) if self.filesystem.exists(self._tests_options_json_path) else None
self._slow_tests = []
if self.options.clean_destination_directory and self._test_resource_files:
self._test_resource_files["files"] = []
if self._tests_options:
self.remove_slow_from_w3c_tests_options()
self.globalToSuffix = dict(
window='html',
worker='worker.html',
dedicatedworker='worker.html',
serviceworker='serviceworker.html')
def do_import(self):
if not self.source_directory:
_log.info('Downloading W3C test repositories')
self.source_directory = self.filesystem.join(self.tests_download_path, 'to-be-imported')
self.filesystem.maybe_make_directory(self.tests_download_path)
self.filesystem.maybe_make_directory(self.source_directory)
self.test_downloader().download_tests(self.source_directory, self.test_paths, self.options.use_tip_of_tree)
test_paths = self.test_paths if self.test_paths else [test_repository['name'] for test_repository in self.test_downloader().test_repositories]
for test_path in test_paths:
self.find_importable_tests(self.filesystem.join(self.source_directory, test_path))
if self.options.clean_destination_directory:
for test_path in test_paths:
self.clean_destination_directory(test_path)
self.import_tests()
for test_path in test_paths:
self.remove_dangling_expectations(test_path)
if self._importing_downloaded_tests:
self.generate_git_submodules_description_for_all_repositories()
self.test_downloader().update_import_expectations(self.test_paths)
def generate_git_submodules_description_for_all_repositories(self):
for test_repository in self._test_downloader.test_repositories:
if 'generate_git_submodules_description' in test_repository['import_options']:
self.filesystem.maybe_make_directory(self.filesystem.join(self.destination_directory, 'resources'))
self._test_downloader.generate_git_submodules_description(test_repository, self.filesystem.join(self.destination_directory, 'resources', test_repository['name'] + '-modules.json'))
if 'generate_gitignore' in test_repository['import_options']:
self._test_downloader.generate_gitignore(test_repository, self.destination_directory)
if 'generate_init_py' in test_repository['import_options']:
self.write_init_py(self.filesystem.join(self.destination_directory, test_repository['name'], '__init__.py'))
def write_init_py(self, filepath):
self.filesystem.write_text_file(filepath, '# This file is required for Python to search this directory for modules.')
def test_downloader(self):
if not self._test_downloader:
download_options = TestDownloader.default_options()
download_options.fetch = self.options.fetch
download_options.verbose = self.options.verbose
download_options.import_all = self.options.import_all
self._test_downloader = TestDownloader(self.tests_download_path, self.host, download_options)
return self._test_downloader
def should_skip_file(self, filename):
# For some reason the w3c repo contains random perl scripts we don't care about.
if filename.endswith('.pl'):
return True
if filename.startswith('.'):
return not filename == '.htaccess'
return False
def _is_baseline(self, filesystem, dirname, filename):
return filename.endswith('-expected.txt')
def _should_remove_before_importing(self, filesystem, dirname, filename):
if self._is_baseline(filesystem, dirname, filename):
return False
if filename.startswith("."):
return False
return True
def clean_destination_directory(self, filename):
directory = self.filesystem.join(self.destination_directory, filename)
for relative_path in self.filesystem.files_under(directory, file_filter=self._should_remove_before_importing):
self.filesystem.remove(self.filesystem.join(directory, relative_path))
def remove_dangling_expectations(self, filename):
#FIXME: Clean also the expected files stored in all platform specific folders.
directory = self.filesystem.join(self.destination_directory, filename)
for relative_path in self.filesystem.files_under(directory, file_filter=self._is_baseline):
path = self.filesystem.join(directory, relative_path)
if self.filesystem.glob(path.replace('-expected.txt', '*')) == [path]:
self.filesystem.remove(path)
def _source_root_directory_for_path(self, path):
if not self._importing_downloaded_tests:
return self.source_directory
for test_repository in self.test_downloader().load_test_repositories(self.filesystem):
source_directory = self.filesystem.join(self.source_directory, test_repository['name'])
if path.startswith(source_directory):
return source_directory
def find_importable_tests(self, directory):
def should_keep_subdir(filesystem, path):
if self._importing_downloaded_tests:
return True
subdir = path[len(directory):]
DIRS_TO_SKIP = ('work-in-progress', 'tools', 'support')
should_skip = filesystem.basename(subdir).startswith('.') or (subdir in DIRS_TO_SKIP)
return not should_skip
source_root_directory = self._source_root_directory_for_path(directory)
directories = self.filesystem.dirs_under(directory, should_keep_subdir)
for root in directories:
_log.info('Scanning ' + root + '...')
total_tests = 0
reftests = 0
jstests = 0
copy_list = []
for filename in self.filesystem.listdir(root):
if self.filesystem.isdir(self.filesystem.join(root, filename)):
continue
# FIXME: This block should really be a separate function, but the early-continues make that difficult.
if self.should_skip_file(filename):
continue
fullpath = self.filesystem.join(root, filename)
mimetype = mimetypes.guess_type(fullpath)
if not 'html' in str(mimetype[0]) and not 'application/xhtml+xml' in str(mimetype[0]) and not 'application/xml' in str(mimetype[0]):
copy_list.append({'src': fullpath, 'dest': filename})
continue
test_parser = TestParser(vars(self.options), filename=fullpath, host=self.host, source_root_directory=source_root_directory)
test_info = test_parser.analyze_test()
if test_info is None:
# This is probably a resource file, but we should generate WPT manifest instead and get the list of resource files from it.
if not self._is_in_resources_directory(fullpath):
self._potential_test_resource_files.append(fullpath)
copy_list.append({'src': fullpath, 'dest': filename})
continue
elif self._is_in_resources_directory(fullpath):
_log.warning('%s is a test located in a "resources" folder. This test will be skipped by WebKit test runners.', fullpath)
if 'manualtest' in test_info.keys():
continue
if 'slow' in test_info:
self._slow_tests.append(fullpath)
if 'referencefile' in test_info.keys():
# Skip it since, the corresponding reference test should have a link to this file
continue
if 'reference' in test_info.keys():
reftests += 1
total_tests += 1
test_basename = self.filesystem.basename(test_info['test'])
# Add the ref file, following WebKit style.
# FIXME: Ideally we'd support reading the metadata
# directly rather than relying on a naming convention.
# Using a naming convention creates duplicate copies of the
# reference files.
ref_file = self.filesystem.splitext(test_basename)[0] + '-expected'
ref_file += self.filesystem.splitext(test_info['reference'])[1]
copy_list.append({'src': test_info['reference'], 'dest': ref_file, 'reference_support_info': test_info['reference_support_info']})
copy_list.append({'src': test_info['test'], 'dest': filename})
elif 'jstest' in test_info.keys():
jstests += 1
total_tests += 1
copy_list.append({'src': fullpath, 'dest': filename})
else:
total_tests += 1
copy_list.append({'src': fullpath, 'dest': filename})
if copy_list:
# Only add this directory to the list if there's something to import
self.import_list.append({'dirname': root, 'copy_list': copy_list,
'reftests': reftests, 'jstests': jstests, 'total_tests': total_tests})
def should_convert_test_harness_links(self, test):
if self._importing_downloaded_tests:
for test_repository in self.test_downloader().test_repositories:
if test.startswith(test_repository['name']):
return 'convert_test_harness_links' in test_repository['import_options']
return True
return self.options.convert_test_harness_links
def _webkit_test_runner_options(self, path):
if not(self.filesystem.isfile(path)):
return ''
options_prefix = '<!-- webkit-test-runner'
contents = ''
try:
contents = self.filesystem.read_text_file(path).split('\n')
except:
_log.info('unable to read %s as a text file' % path)
if not len(contents):
return ''
first_line = contents[0]
return first_line[first_line.index(options_prefix):] if options_prefix in first_line else ''
def _add_webkit_test_runner_options_to_content(self, content, webkit_test_runner_options):
lines = content.split('\n')
if not len(lines):
return ''
lines[0] = lines[0] + webkit_test_runner_options
return '\n'.join(lines)
def _copy_html_file(self, source_filepath, new_filepath):
webkit_test_runner_options = self._webkit_test_runner_options(new_filepath)
if not webkit_test_runner_options:
self.filesystem.copyfile(source_filepath, new_filepath)
return
source_content = self.filesystem.read_text_file(source_filepath)
self.filesystem.write_text_file(new_filepath, self._add_webkit_test_runner_options_to_content(source_content, webkit_test_runner_options))
def _write_html_template(self, new_filepath):
webkit_test_runner_options = self._webkit_test_runner_options(new_filepath)
content = '<!-- This file is required for WebKit test infrastructure to run the templated test -->'
self.filesystem.write_text_file(new_filepath, content + webkit_test_runner_options)
def readEnvironmentsForTemplateTest(self, filepath):
environments = []
lines = self.filesystem.read_text_file(filepath).split('\n')
for line in lines:
if line.startswith('//') and 'META: global=' in line:
items = line.split('META: global=', 1)[1].split(',')
suffixes = [self.globalToSuffix.get(item.strip(), '') for item in items]
environments = list(filter(None, set(suffixes)))
if 'worker.html' in environments:
environments.append('serviceworker.html')
return set(environments) if len(environments) else ['html', 'worker.html', 'serviceworker.html']
def write_html_files_for_templated_js_tests(self, orig_filepath, new_filepath):
if (orig_filepath.endswith('.window.js')):
self._write_html_template(new_filepath.replace('.window.js', '.window.html'))
return
if (orig_filepath.endswith('.worker.js')):
self._write_html_template(new_filepath.replace('.worker.js', '.worker.html'))
return
if (orig_filepath.endswith('.any.js')):
for suffix in self.readEnvironmentsForTemplateTest(orig_filepath):
self._write_html_template(new_filepath.replace('.any.js', '.any.' + suffix))
return
def import_tests(self):
total_imported_tests = 0
total_imported_reftests = 0
total_imported_jstests = 0
total_prefixed_properties = {}
total_prefixed_property_values = {}
failed_conversion_files = []
# We currently need to rewrite css web-platform-tests because they use a separate "reference" folder for
# their ref-tests' results.
folders_needing_file_rewriting = ['web-platform-tests/']
for dir_to_copy in self.import_list:
total_imported_tests += dir_to_copy['total_tests']
total_imported_reftests += dir_to_copy['reftests']
total_imported_jstests += dir_to_copy['jstests']
prefixed_properties = []
prefixed_property_values = []
if not dir_to_copy['copy_list']:
continue
orig_path = dir_to_copy['dirname']
subpath = self.filesystem.relpath(orig_path, self.source_directory)
new_path = self.filesystem.join(self.destination_directory, subpath)
should_rewrite_files = False
for folder_needing_file_rewriting in folders_needing_file_rewriting:
if subpath.startswith(folder_needing_file_rewriting):
should_rewrite_files = True
break
if not(self.filesystem.exists(new_path)):
self.filesystem.maybe_make_directory(new_path)
copied_files = []
for file_to_copy in dir_to_copy['copy_list']:
# FIXME: Split this block into a separate function.
orig_filepath = self.filesystem.normpath(file_to_copy['src'])
if self.filesystem.isdir(orig_filepath):
# FIXME: Figure out what is triggering this and what to do about it.
_log.error('%s refers to a directory' % orig_filepath)
continue
if not(self.filesystem.exists(orig_filepath)):
_log.warning('%s not found. Possible error in the test.', orig_filepath)
continue
new_filepath = self.filesystem.join(new_path, file_to_copy['dest'])
if 'reference_support_info' in file_to_copy.keys() and file_to_copy['reference_support_info'] != {}:
reference_support_info = file_to_copy['reference_support_info']
else:
reference_support_info = None
if not(self.filesystem.exists(self.filesystem.dirname(new_filepath))):
self.filesystem.maybe_make_directory(self.filesystem.dirname(new_filepath))
if not self.options.overwrite and self.filesystem.exists(new_filepath):
_log.info('Skipping import of existing file ' + new_filepath)
else:
# FIXME: Maybe doing a file diff is in order here for existing files?
# In other words, there's no sense in overwriting identical files, but
# there's no harm in copying the identical thing.
_log.info('Importing: %s', orig_filepath)
_log.info(' As: %s', new_filepath)
# Only html, xml, or css should be converted
# FIXME: Eventually, so should js when support is added for this type of conversion
mimetype = mimetypes.guess_type(orig_filepath)
if should_rewrite_files and ('text/' in str(mimetype[0]) or 'application/' in str(mimetype[0])) \
and ('html' in str(mimetype[0]) or 'xml' in str(mimetype[0]) or 'css' in str(mimetype[0]) or 'javascript' in str(mimetype[0])):
_log.info("Rewriting: %s" % new_filepath)
try:
converted_file = convert_for_webkit(new_path, filename=orig_filepath, reference_support_info=reference_support_info, host=self.host, convert_test_harness_links=self.should_convert_test_harness_links(subpath), webkit_test_runner_options=self._webkit_test_runner_options(new_filepath))
except:
_log.warn('Failed converting %s', orig_filepath)
failed_conversion_files.append(orig_filepath)
converted_file = None
if not converted_file:
self.filesystem.copyfile(orig_filepath, new_filepath) # The file was unmodified.
else:
for prefixed_property in converted_file[0]:
total_prefixed_properties.setdefault(prefixed_property, 0)
total_prefixed_properties[prefixed_property] += 1
prefixed_properties.extend(set(converted_file[0]) - set(prefixed_properties))
for prefixed_value in converted_file[1]:
total_prefixed_property_values.setdefault(prefixed_value, 0)
total_prefixed_property_values[prefixed_value] += 1
prefixed_property_values.extend(set(converted_file[1]) - set(prefixed_property_values))
self.filesystem.write_binary_file(new_filepath, converted_file[2])
elif orig_filepath.endswith('__init__.py') and not self.filesystem.getsize(orig_filepath):
# Some bots dislike empty __init__.py.
self.write_init_py(new_filepath)
elif 'html' in str(mimetype[0]):
self._copy_html_file(orig_filepath, new_filepath)
else:
self.filesystem.copyfile(orig_filepath, new_filepath)
self.write_html_files_for_templated_js_tests(orig_filepath, new_filepath)
copied_files.append(new_filepath.replace(self._webkit_root, ''))
self.remove_deleted_files(new_path, copied_files)
self.write_import_log(new_path, copied_files, prefixed_properties, prefixed_property_values)
_log.info('Import complete')
_log.info('IMPORTED %d TOTAL TESTS', total_imported_tests)
_log.info('Imported %d reftests', total_imported_reftests)
_log.info('Imported %d JS tests', total_imported_jstests)
_log.info('Imported %d pixel/manual tests', total_imported_tests - total_imported_jstests - total_imported_reftests)
if len(failed_conversion_files):
_log.warn('Failed converting %d files (files copied without being converted)', len(failed_conversion_files))
_log.info('')
_log.info('Properties needing prefixes (by count):')
for prefixed_property in sorted(total_prefixed_properties, key=lambda p: total_prefixed_properties[p]):
_log.info(' %s: %s', prefixed_property, total_prefixed_properties[prefixed_property])
_log.info('')
_log.info('Property values needing prefixes (by count):')
for prefixed_value in sorted(total_prefixed_property_values, key=lambda p: total_prefixed_property_values[p]):
_log.info(' %s: %s', prefixed_value, total_prefixed_property_values[prefixed_value])
if self._potential_test_resource_files and self._test_resource_files:
# FIXME: We should check that actual tests are not in the test_resource_files list
should_update_json_file = False
files = self._test_resource_files["files"]
for full_path in self._potential_test_resource_files:
resource_file_path = self.filesystem.relpath(full_path, self.source_directory)
if not self._already_identified_as_resource_file(resource_file_path):
files.append(resource_file_path)
should_update_json_file = True
if should_update_json_file:
files.sort()
self.filesystem.write_text_file(self._test_resource_files_json_path, json.dumps(self._test_resource_files, sort_keys=True, indent=4).replace(' \n', '\n'))
if self._tests_options:
self.update_tests_options()
def _already_identified_as_resource_file(self, path):
if not self._test_resource_files:
return False
if path in self._test_resource_files["files"]:
return True
return any([path.find(directory) != -1 for directory in self._test_resource_files["directories"]])
def _is_in_resources_directory(self, path):
return "resources" in path.split(self.filesystem.sep)
def update_tests_options(self):
should_update = self.options.clean_destination_directory
for full_path in self._slow_tests:
w3c_test_path = self.filesystem.relpath(full_path, self.source_directory)
print(w3c_test_path)
# No need to mark tests as slow if they are in skipped directories
if self._already_identified_as_resource_file(w3c_test_path):
continue
test_path = self.filesystem.join(self.tests_w3c_relative_path, w3c_test_path)
options = self._tests_options.get(test_path, [])
if not 'slow' in options:
options.append('slow')
self._tests_options[test_path] = options
should_update = True
if should_update:
self.filesystem.write_text_file(self._tests_options_json_path, json.dumps(self._tests_options, sort_keys=True, indent=4).replace(' \n', '\n'))
def remove_slow_from_w3c_tests_options(self):
for test_path in self._tests_options.keys():
if self.tests_w3c_relative_path in test_path:
options = self._tests_options[test_path]
options.remove('slow')
if not options:
self._tests_options.pop(test_path)
def remove_deleted_files(self, import_directory, new_file_list):
""" Reads an import log in |import_directory|, compares it to the |new_file_list|, and removes files not in the new list."""
previous_file_list = []
import_log_file = self.filesystem.join(import_directory, 'w3c-import.log')
if not self.filesystem.exists(import_log_file):
return
contents = self.filesystem.read_text_file(import_log_file).split('\n')
if 'List of files:' in contents:
list_index = contents.index('List of files:') + 1
previous_file_list = [filename.strip() for filename in contents[list_index:] if len(filename)]
deleted_files = set(previous_file_list) - set(new_file_list)
for deleted_file in deleted_files:
_log.info('Deleting file removed from the W3C repo: %s', deleted_file)
deleted_file = self.filesystem.join(self._webkit_root, deleted_file[1:])
if not self.filesystem.exists(deleted_file):
_log.warning('%s no longer exists', deleted_file)
continue
self.filesystem.remove(deleted_file)
def write_import_log(self, import_directory, file_list, prop_list, property_values_list):
""" Writes a w3c-import.log file in each directory with imported files. """
import_log = []
import_log.append('The tests in this directory were imported from the W3C repository.\n')
import_log.append('Do NOT modify these tests directly in WebKit.\n')
import_log.append('Instead, create a pull request on the WPT github:\n')
import_log.append('\t%s\n\n' % WPT_GH_URL)
import_log.append('Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport\n\n')
import_log.append('Do NOT modify or remove this file.\n\n')
import_log.append('------------------------------------------------------------------------\n')
import_log.append('Properties requiring vendor prefixes:\n')
if prop_list:
for prop in prop_list:
import_log.append(prop + '\n')
else:
import_log.append('None\n')
import_log.append('Property values requiring vendor prefixes:\n')
if property_values_list:
for value in property_values_list:
import_log.append(value + '\n')
else:
import_log.append('None\n')
import_log.append('------------------------------------------------------------------------\n')
import_log.append('List of files:\n')
for item in sorted(file_list):
import_log.append(item + '\n')
self.filesystem.write_text_file(self.filesystem.join(import_directory, 'w3c-import.log'), ''.join(import_log))