mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:58:29 +00:00
Remove remaining traces of content_shell and DumpRenderTree
Change-Id: Iae15260fa588b101929095c865807efecfb678a2 Reviewed-on: https://dart-review.googlesource.com/71960 Reviewed-by: Jonas Termansen <sortie@google.com>
This commit is contained in:
parent
fa14dbcdfc
commit
3603bfaebd
14
DEPS
14
DEPS
|
@ -402,20 +402,6 @@ hooks = [
|
||||||
Var('dart_root') + "/third_party/firefox_jsshell",
|
Var('dart_root') + "/third_party/firefox_jsshell",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "drt_resources",
|
|
||||||
"pattern": ".",
|
|
||||||
"action": [
|
|
||||||
"download_from_google_storage",
|
|
||||||
"--no_auth",
|
|
||||||
"--no_resume",
|
|
||||||
"--bucket",
|
|
||||||
"dart-dependencies",
|
|
||||||
"--platform=win32",
|
|
||||||
"--directory",
|
|
||||||
Var('dart_root') + "/third_party/drt_resources",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "7zip",
|
"name": "7zip",
|
||||||
"pattern": ".",
|
"pattern": ".",
|
||||||
|
|
1
third_party/.gitignore
vendored
1
third_party/.gitignore
vendored
|
@ -6,7 +6,6 @@
|
||||||
!pkg
|
!pkg
|
||||||
!pkg_tested
|
!pkg_tested
|
||||||
!/tcmalloc
|
!/tcmalloc
|
||||||
!drt_resources
|
|
||||||
!d8
|
!d8
|
||||||
!7zip.tar.gz.sha1
|
!7zip.tar.gz.sha1
|
||||||
!firefox_jsshell
|
!firefox_jsshell
|
||||||
|
|
1
third_party/drt_resources/.gitignore
vendored
1
third_party/drt_resources/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
AHEM____.TTF
|
|
1
third_party/drt_resources/AHEM____.TTF.sha1
vendored
1
third_party/drt_resources/AHEM____.TTF.sha1
vendored
|
@ -1 +0,0 @@
|
||||||
8cdc9e68594fbb6db8c7b4bff643ab2432b51db6
|
|
6
third_party/drt_resources/README.md
vendored
6
third_party/drt_resources/README.md
vendored
|
@ -1,6 +0,0 @@
|
||||||
# Content-shell resources
|
|
||||||
|
|
||||||
The layout tests of content_shell (formerly called DumpRenderTree, drt)
|
|
||||||
require a font called AHEM____.TTF on Windows. This resource is downloaded
|
|
||||||
from cloud storage, using the hash in AHEM____.TTF.sha1, by a hook
|
|
||||||
in the DEPS file, that is run by gclient sync or gclient runhooks.
|
|
|
@ -1,342 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
||||||
# for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
# BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
# Gets or updates a content shell (a nearly headless build of chrome). This is
|
|
||||||
# used for running browser tests of client applications.
|
|
||||||
|
|
||||||
import json
|
|
||||||
import optparse
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import tempfile
|
|
||||||
import zipfile
|
|
||||||
|
|
||||||
import utils
|
|
||||||
|
|
||||||
def NormJoin(path1, path2):
|
|
||||||
return os.path.normpath(os.path.join(path1, path2))
|
|
||||||
|
|
||||||
# Change into the dart directory as we want the project to be rooted here.
|
|
||||||
dart_src = NormJoin(os.path.dirname(sys.argv[0]), os.pardir)
|
|
||||||
os.chdir(dart_src)
|
|
||||||
|
|
||||||
GSUTIL_DIR = os.path.join('third_party', 'gsutil')
|
|
||||||
GSUTIL = GSUTIL_DIR + '/gsutil'
|
|
||||||
|
|
||||||
DRT_DIR = os.path.join('client', 'tests', 'drt')
|
|
||||||
DRT_VERSION = os.path.join(DRT_DIR, 'LAST_VERSION')
|
|
||||||
DRT_LATEST_PATTERN = (
|
|
||||||
'gs://dartium-archive/latest/drt-%(osname)s-%(bot)s-*.zip')
|
|
||||||
DRT_PERMANENT_PATTERN = ('gs://dartium-archive/drt-%(osname)s-%(bot)s/drt-'
|
|
||||||
'%(osname)s-%(bot)s-%(num1)s.%(num2)s.zip')
|
|
||||||
|
|
||||||
DARTIUM_DIR = os.path.join('client', 'tests', 'dartium')
|
|
||||||
DARTIUM_VERSION = os.path.join(DARTIUM_DIR, 'LAST_VERSION')
|
|
||||||
DARTIUM_LATEST_PATTERN = (
|
|
||||||
'gs://dartium-archive/latest/dartium-%(osname)s-%(bot)s-*.zip')
|
|
||||||
DARTIUM_PERMANENT_PATTERN = ('gs://dartium-archive/dartium-%(osname)s-%(bot)s/'
|
|
||||||
'dartium-%(osname)s-%(bot)s-%(num1)s.%(num2)s.zip')
|
|
||||||
|
|
||||||
SDK_DIR = os.path.join(utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
|
|
||||||
'dart-sdk')
|
|
||||||
SDK_VERSION = os.path.join(SDK_DIR, 'LAST_VERSION')
|
|
||||||
SDK_LATEST_PATTERN = 'gs://dart-archive/channels/dev/raw/latest/VERSION'
|
|
||||||
# TODO(efortuna): Once the x64 VM also is optimized, select the version
|
|
||||||
# based on whether we are running on a 32-bit or 64-bit system.
|
|
||||||
SDK_PERMANENT = ('gs://dart-archive/channels/dev/raw/%(version_num)s/sdk/' +
|
|
||||||
'dartsdk-%(osname)s-ia32-release.zip')
|
|
||||||
|
|
||||||
# Dictionary storing the earliest revision of each download we have stored.
|
|
||||||
LAST_VALID = {'dartium': 4285, 'chromedriver': 7823, 'sdk': 9761, 'drt': 5342}
|
|
||||||
|
|
||||||
sys.path.append(os.path.join(GSUTIL_DIR, 'third_party', 'boto'))
|
|
||||||
import boto
|
|
||||||
|
|
||||||
|
|
||||||
def ExecuteCommand(*cmd):
|
|
||||||
"""Execute a command in a subprocess."""
|
|
||||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
output, error = pipe.communicate()
|
|
||||||
return pipe.returncode, output
|
|
||||||
|
|
||||||
|
|
||||||
def ExecuteCommandVisible(*cmd):
|
|
||||||
"""Execute a command in a subprocess, but show stdout/stderr."""
|
|
||||||
result = subprocess.call(cmd, stdout=sys.stdout, stderr=sys.stderr,
|
|
||||||
stdin=sys.stdin)
|
|
||||||
if result != 0:
|
|
||||||
raise Exception('Execution of "%s" failed' % ' '.join(cmd))
|
|
||||||
|
|
||||||
|
|
||||||
def Gsutil(*cmd):
|
|
||||||
return ExecuteCommand('python', GSUTIL, *cmd)
|
|
||||||
|
|
||||||
|
|
||||||
def GsutilVisible(*cmd):
|
|
||||||
ExecuteCommandVisible('python', GSUTIL, *cmd)
|
|
||||||
|
|
||||||
|
|
||||||
def HasBotoConfig():
|
|
||||||
"""Returns true if boto config exists."""
|
|
||||||
|
|
||||||
config_paths = boto.pyami.config.BotoConfigLocations
|
|
||||||
if 'AWS_CREDENTIAL_FILE' in os.environ:
|
|
||||||
config_paths.append(os.environ['AWS_CREDENTIAL_FILE'])
|
|
||||||
for config_path in config_paths:
|
|
||||||
if os.path.exists(config_path):
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def InRunhooks():
|
|
||||||
"""True if this script was called by "gclient runhooks" or "gclient sync\""""
|
|
||||||
return 'runhooks' in sys.argv
|
|
||||||
|
|
||||||
|
|
||||||
def GetDartiumRevision(name, bot, directory, version_file, latest_pattern,
|
|
||||||
permanent_prefix, revision_num=None):
|
|
||||||
"""Get the latest binary that is stored in the dartium archive.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name: the name of the desired download.
|
|
||||||
directory: target directory (recreated) to install binary
|
|
||||||
version_file: name of file with the current version stamp
|
|
||||||
latest_pattern: the google store url pattern pointing to the latest binary
|
|
||||||
permanent_prefix: stable google store folder used to download versions
|
|
||||||
revision_num: The desired revision number to retrieve. If revision_num is
|
|
||||||
None, we return the latest revision. If the revision number is specified
|
|
||||||
but unavailable, find the nearest older revision and use that instead.
|
|
||||||
"""
|
|
||||||
osdict = {'Darwin':'mac-x64', 'Linux':'linux-x64', 'Windows':'win-ia32'}
|
|
||||||
|
|
||||||
def FindPermanentUrl(out, osname, the_revision_num):
|
|
||||||
output_lines = out.split()
|
|
||||||
latest = output_lines[-1]
|
|
||||||
if not the_revision_num:
|
|
||||||
latest = (permanent_prefix[:permanent_prefix.rindex('/')] % { 'osname' :
|
|
||||||
osname, 'bot' : bot } + latest[latest.rindex('/'):])
|
|
||||||
else:
|
|
||||||
latest = (permanent_prefix % { 'osname' : osname, 'num1' : the_revision_num,
|
|
||||||
'num2' : the_revision_num, 'bot' : bot })
|
|
||||||
foundURL = False
|
|
||||||
while not foundURL:
|
|
||||||
# Test to ensure this URL exists because the dartium-archive builds can
|
|
||||||
# have unusual numbering (a range of CL numbers) sometimes.
|
|
||||||
result, out = Gsutil('ls', permanent_prefix % {'osname' : osname,
|
|
||||||
'num1': the_revision_num, 'num2': '*', 'bot': bot })
|
|
||||||
if result == 0:
|
|
||||||
# First try to find one with the second number the same as the
|
|
||||||
# requested number.
|
|
||||||
latest = out.split()[0]
|
|
||||||
# Now test that the permissions are correct so you can actually
|
|
||||||
# download it.
|
|
||||||
temp_dir = tempfile.mkdtemp()
|
|
||||||
temp_zip = os.path.join(temp_dir, 'foo.zip')
|
|
||||||
returncode, out = Gsutil('cp', latest, 'file://' + temp_zip)
|
|
||||||
if returncode == 0:
|
|
||||||
foundURL = True
|
|
||||||
else:
|
|
||||||
# Unable to download this item (most likely because something went
|
|
||||||
# wrong on the upload and the permissions are bad). Keep looking for
|
|
||||||
# a different URL.
|
|
||||||
the_revision_num = int(the_revision_num) - 1
|
|
||||||
shutil.rmtree(temp_dir)
|
|
||||||
else:
|
|
||||||
# Now try to find one with a nearby CL num.
|
|
||||||
the_revision_num = int(the_revision_num) - 1
|
|
||||||
if the_revision_num <= 0:
|
|
||||||
TooEarlyError()
|
|
||||||
return latest
|
|
||||||
|
|
||||||
GetFromGsutil(name, directory, version_file, latest_pattern, osdict,
|
|
||||||
FindPermanentUrl, revision_num, bot)
|
|
||||||
|
|
||||||
|
|
||||||
def GetSdkRevision(name, directory, version_file, latest_pattern,
|
|
||||||
permanent_prefix, revision_num):
|
|
||||||
"""Get a revision of the SDK from the editor build archive.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name: the name of the desired download
|
|
||||||
directory: target directory (recreated) to install binary
|
|
||||||
version_file: name of file with the current version stamp
|
|
||||||
latest_pattern: the google store url pattern pointing to the latest binary
|
|
||||||
permanent_prefix: stable google store folder used to download versions
|
|
||||||
revision_num: the desired revision number, or None for the most recent
|
|
||||||
"""
|
|
||||||
osdict = {'Darwin':'macos', 'Linux':'linux', 'Windows':'win32'}
|
|
||||||
def FindPermanentUrl(out, osname, not_used):
|
|
||||||
rev_num = revision_num
|
|
||||||
if not rev_num:
|
|
||||||
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
|
||||||
temp_file.close()
|
|
||||||
temp_file_url = 'file://' + temp_file.name
|
|
||||||
Gsutil('cp', latest_pattern % {'osname' : osname }, temp_file_url)
|
|
||||||
temp_file = open(temp_file.name)
|
|
||||||
temp_file.seek(0)
|
|
||||||
version_info = temp_file.read()
|
|
||||||
temp_file.close()
|
|
||||||
os.unlink(temp_file.name)
|
|
||||||
if version_info != '':
|
|
||||||
rev_num = json.loads(version_info)['revision']
|
|
||||||
else:
|
|
||||||
print 'Unable to get latest version information.'
|
|
||||||
return ''
|
|
||||||
latest = (permanent_prefix % { 'osname' : osname, 'version_num': rev_num})
|
|
||||||
return latest
|
|
||||||
|
|
||||||
GetFromGsutil(name, directory, version_file, latest_pattern, osdict,
|
|
||||||
FindPermanentUrl, revision_num)
|
|
||||||
|
|
||||||
|
|
||||||
def GetFromGsutil(name, directory, version_file, latest_pattern,
|
|
||||||
os_name_dict, get_permanent_url, revision_num = '', bot = None):
|
|
||||||
"""Download and unzip the desired file from Google Storage.
|
|
||||||
Args:
|
|
||||||
name: the name of the desired download
|
|
||||||
directory: target directory (recreated) to install binary
|
|
||||||
version_file: name of file with the current version stamp
|
|
||||||
latest_pattern: the google store url pattern pointing to the latest binary
|
|
||||||
os_name_dict: a dictionary of operating system names and their corresponding
|
|
||||||
strings on the google storage site.
|
|
||||||
get_permanent_url: a function that accepts a listing of available files
|
|
||||||
and the os name, and returns a permanent URL for downloading.
|
|
||||||
revision_num: the desired revision number to get (if not supplied, we get
|
|
||||||
the latest revision)
|
|
||||||
"""
|
|
||||||
system = platform.system()
|
|
||||||
try:
|
|
||||||
osname = os_name_dict[system]
|
|
||||||
except KeyError:
|
|
||||||
print >>sys.stderr, ('WARNING: platform "%s" does not support'
|
|
||||||
'%s.') % (system, name)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Query for the latest version
|
|
||||||
pattern = latest_pattern % { 'osname' : osname, 'bot' : bot }
|
|
||||||
result, out = Gsutil('ls', pattern)
|
|
||||||
if result == 0:
|
|
||||||
# use permanent link instead, just in case the latest zip entry gets deleted
|
|
||||||
# while we are downloading it.
|
|
||||||
latest = get_permanent_url(out, osname, revision_num)
|
|
||||||
else: # e.g. no access
|
|
||||||
print "Couldn't download %s: %s\n%s" % (name, pattern, out)
|
|
||||||
if not os.path.exists(version_file):
|
|
||||||
print "Using %s will not work. Please try again later." % name
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Check if we need to update the file
|
|
||||||
if os.path.exists(version_file):
|
|
||||||
v = open(version_file, 'r').read()
|
|
||||||
if v == latest:
|
|
||||||
if not InRunhooks():
|
|
||||||
print name + ' is up to date.\nVersion: ' + latest
|
|
||||||
return 0 # up to date
|
|
||||||
|
|
||||||
# download the zip file to a temporary path, and unzip to the target location
|
|
||||||
temp_dir = tempfile.mkdtemp()
|
|
||||||
try:
|
|
||||||
temp_zip = os.path.join(temp_dir, 'drt.zip')
|
|
||||||
temp_zip_url = 'file://' + temp_zip
|
|
||||||
# It's nice to show download progress
|
|
||||||
GsutilVisible('cp', latest, temp_zip_url)
|
|
||||||
|
|
||||||
if platform.system() != 'Windows':
|
|
||||||
# The Python zip utility does not preserve executable permissions, but
|
|
||||||
# this does not seem to be a problem for Windows, which does not have a
|
|
||||||
# built in zip utility. :-/
|
|
||||||
result, out = ExecuteCommand('unzip', temp_zip, '-d', temp_dir)
|
|
||||||
if result != 0:
|
|
||||||
raise Exception('Execution of "unzip %s -d %s" failed: %s' %
|
|
||||||
(temp_zip, temp_dir, str(out)))
|
|
||||||
unzipped_dir = temp_dir + '/' + os.path.basename(latest)[:-len('.zip')]
|
|
||||||
else:
|
|
||||||
z = zipfile.ZipFile(temp_zip)
|
|
||||||
z.extractall(temp_dir)
|
|
||||||
unzipped_dir = os.path.join(temp_dir,
|
|
||||||
os.path.basename(latest)[:-len('.zip')])
|
|
||||||
z.close()
|
|
||||||
if directory == SDK_DIR:
|
|
||||||
unzipped_dir = os.path.join(temp_dir, 'dart-sdk')
|
|
||||||
if os.path.exists(directory):
|
|
||||||
print 'Removing old %s tree %s' % (name, directory)
|
|
||||||
shutil.rmtree(directory)
|
|
||||||
if os.path.exists(directory):
|
|
||||||
raise Exception(
|
|
||||||
'Removal of directory %s failed. Is the executable running?' %
|
|
||||||
directory)
|
|
||||||
shutil.move(unzipped_dir, directory)
|
|
||||||
finally:
|
|
||||||
shutil.rmtree(temp_dir)
|
|
||||||
|
|
||||||
# create the version stamp
|
|
||||||
v = open(version_file, 'w')
|
|
||||||
v.write(latest)
|
|
||||||
v.close()
|
|
||||||
|
|
||||||
print 'Successfully downloaded to %s' % directory
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def TooEarlyError():
|
|
||||||
"""Quick shortcutting function, to return early if someone requests a revision
|
|
||||||
that is smaller than the earliest stored. This saves us from doing repeated
|
|
||||||
requests until we get down to 0."""
|
|
||||||
print ('Unable to download requested revision because it is earlier than the '
|
|
||||||
'earliest revision stored.')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def CopyDrtFont(drt_dir):
|
|
||||||
if platform.system() != 'Windows':
|
|
||||||
return
|
|
||||||
shutil.copy('third_party/drt_resources/AHEM____.TTF', drt_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = optparse.OptionParser(usage='usage: %prog [options] download_name')
|
|
||||||
parser.add_option('-r', '--revision', dest='revision',
|
|
||||||
help='Desired revision number to retrieve for the SDK. If '
|
|
||||||
'unspecified, retrieve the latest SDK build.',
|
|
||||||
action='store', default=None)
|
|
||||||
parser.add_option('-d', '--debug', dest='debug',
|
|
||||||
help='Download a debug archive instead of a release.',
|
|
||||||
action='store_true', default=False)
|
|
||||||
args, positional = parser.parse_args()
|
|
||||||
|
|
||||||
if args.revision and int(args.revision) < LAST_VALID[positional[0]]:
|
|
||||||
return TooEarlyError()
|
|
||||||
|
|
||||||
# Use the incremental release bot ('dartium-*-inc-be') by default.
|
|
||||||
# Issue 13399 Quick fix, update with channel support.
|
|
||||||
bot = 'inc-be'
|
|
||||||
if args.debug:
|
|
||||||
print >>sys.stderr, (
|
|
||||||
'Debug versions of Dartium and content_shell not available')
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if positional[0] == 'dartium':
|
|
||||||
GetDartiumRevision('Dartium', bot, DARTIUM_DIR, DARTIUM_VERSION,
|
|
||||||
DARTIUM_LATEST_PATTERN, DARTIUM_PERMANENT_PATTERN,
|
|
||||||
args.revision)
|
|
||||||
elif positional[0] == 'sdk':
|
|
||||||
GetSdkRevision('sdk', SDK_DIR, SDK_VERSION, SDK_LATEST_PATTERN,
|
|
||||||
SDK_PERMANENT, args.revision)
|
|
||||||
elif positional[0] == 'drt':
|
|
||||||
GetDartiumRevision('content_shell', bot, DRT_DIR, DRT_VERSION,
|
|
||||||
DRT_LATEST_PATTERN, DRT_PERMANENT_PATTERN,
|
|
||||||
args.revision)
|
|
||||||
CopyDrtFont(DRT_DIR)
|
|
||||||
else:
|
|
||||||
print ('Please specify the target you wish to download from Google Storage '
|
|
||||||
'("drt", "dartium", "chromedriver", or "sdk")')
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -25,7 +25,6 @@ POSIX_INFO = 'ps -p %s -o args'
|
||||||
EXECUTABLE_NAMES = {
|
EXECUTABLE_NAMES = {
|
||||||
'win32': {
|
'win32': {
|
||||||
'chrome': 'chrome.exe',
|
'chrome': 'chrome.exe',
|
||||||
'content_shell': 'content_shell.exe',
|
|
||||||
'dart_bootstrap': 'dart_bootstrap.exe',
|
'dart_bootstrap': 'dart_bootstrap.exe',
|
||||||
'dart': 'dart.exe',
|
'dart': 'dart.exe',
|
||||||
'dart_precompiled_runtime': 'dart_precompiled_runtime.exe',
|
'dart_precompiled_runtime': 'dart_precompiled_runtime.exe',
|
||||||
|
@ -38,7 +37,6 @@ EXECUTABLE_NAMES = {
|
||||||
},
|
},
|
||||||
'linux': {
|
'linux': {
|
||||||
'chrome': 'chrome',
|
'chrome': 'chrome',
|
||||||
'content_shell': 'content_shell',
|
|
||||||
'dart_bootstrap': 'dart_bootstrap',
|
'dart_bootstrap': 'dart_bootstrap',
|
||||||
'dart': 'dart',
|
'dart': 'dart',
|
||||||
'dart_precompiled_runtime': 'dart_precompiled_runtime',
|
'dart_precompiled_runtime': 'dart_precompiled_runtime',
|
||||||
|
@ -49,7 +47,6 @@ EXECUTABLE_NAMES = {
|
||||||
'macos': {
|
'macos': {
|
||||||
'chrome': 'Chrome',
|
'chrome': 'Chrome',
|
||||||
'chrome_helper': 'Chrome Helper',
|
'chrome_helper': 'Chrome Helper',
|
||||||
'content_shell': 'Content Shell',
|
|
||||||
'dart_bootstrap': 'dart_bootstrap',
|
'dart_bootstrap': 'dart_bootstrap',
|
||||||
'dart': 'dart',
|
'dart': 'dart',
|
||||||
'dart_precompiled_runtime': 'dart_precompiled_runtime',
|
'dart_precompiled_runtime': 'dart_precompiled_runtime',
|
||||||
|
@ -221,12 +218,6 @@ def KillBrowsers():
|
||||||
status += Kill('chrome_helper')
|
status += Kill('chrome_helper')
|
||||||
status += Kill('iexplore')
|
status += Kill('iexplore')
|
||||||
status += Kill('safari')
|
status += Kill('safari')
|
||||||
if os_name == "win32":
|
|
||||||
# TODO(29599): Let content_shell affect exit code on windows,
|
|
||||||
# once issue with zombie renderers is fixed.
|
|
||||||
Kill('content_shell')
|
|
||||||
else:
|
|
||||||
status += Kill('content_shell')
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def KillVCSystems():
|
def KillVCSystems():
|
||||||
|
|
|
@ -565,71 +565,6 @@ class IE extends Browser {
|
||||||
String toString() => "IE";
|
String toString() => "IE";
|
||||||
}
|
}
|
||||||
|
|
||||||
class AndroidBrowserConfig {
|
|
||||||
final String name;
|
|
||||||
final String package;
|
|
||||||
final String activity;
|
|
||||||
final String action;
|
|
||||||
AndroidBrowserConfig(this.name, this.package, this.activity, this.action);
|
|
||||||
}
|
|
||||||
|
|
||||||
final contentShellOnAndroidConfig = new AndroidBrowserConfig(
|
|
||||||
'ContentShellOnAndroid',
|
|
||||||
'org.chromium.content_shell_apk',
|
|
||||||
'.ContentShellActivity',
|
|
||||||
'android.intent.action.VIEW');
|
|
||||||
|
|
||||||
class AndroidBrowser extends Browser {
|
|
||||||
final bool checkedMode;
|
|
||||||
AdbDevice _adbDevice;
|
|
||||||
AndroidBrowserConfig _config;
|
|
||||||
|
|
||||||
AndroidBrowser(
|
|
||||||
this._adbDevice, this._config, this.checkedMode, String apkPath) {
|
|
||||||
_binary = apkPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> start(String url) {
|
|
||||||
var intent =
|
|
||||||
new Intent(_config.action, _config.package, _config.activity, url);
|
|
||||||
return _adbDevice.waitForBootCompleted().then((_) {
|
|
||||||
return _adbDevice.forceStop(_config.package);
|
|
||||||
}).then((_) {
|
|
||||||
return _adbDevice.killAll();
|
|
||||||
}).then((_) {
|
|
||||||
return _adbDevice.adbRoot();
|
|
||||||
}).then((_) {
|
|
||||||
return _adbDevice.setProp("DART_FORWARDING_PRINT", "1");
|
|
||||||
}).then((_) {
|
|
||||||
if (checkedMode) {
|
|
||||||
return _adbDevice.setProp("DART_FLAGS", "--checked");
|
|
||||||
} else {
|
|
||||||
return _adbDevice.setProp("DART_FLAGS", "");
|
|
||||||
}
|
|
||||||
}).then((_) {
|
|
||||||
return _adbDevice.installApk(new Path(_binary));
|
|
||||||
}).then((_) {
|
|
||||||
return _adbDevice.startActivity(intent).then((_) => true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> close() {
|
|
||||||
if (_adbDevice != null) {
|
|
||||||
return _adbDevice.forceStop(_config.package).then((_) {
|
|
||||||
return _adbDevice.killAll().then((_) => true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return new Future.value(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void logBrowserInfoToTestBrowserOutput() {
|
|
||||||
_testBrowserOutput.stdout
|
|
||||||
.write('Android device id: ${_adbDevice.deviceId}\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
String toString() => _config.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidChrome extends Browser {
|
class AndroidChrome extends Browser {
|
||||||
static const String viewAction = 'android.intent.action.VIEW';
|
static const String viewAction = 'android.intent.action.VIEW';
|
||||||
static const String mainAction = 'android.intent.action.MAIN';
|
static const String mainAction = 'android.intent.action.MAIN';
|
||||||
|
|
|
@ -16,16 +16,6 @@ import 'utils.dart';
|
||||||
|
|
||||||
/// A command executed as a step in a test case.
|
/// A command executed as a step in a test case.
|
||||||
class Command {
|
class Command {
|
||||||
static Command contentShell(
|
|
||||||
String executable,
|
|
||||||
String htmlFile,
|
|
||||||
List<String> options,
|
|
||||||
List<String> dartFlags,
|
|
||||||
Map<String, String> environment) {
|
|
||||||
return new ContentShellCommand._(
|
|
||||||
executable, htmlFile, options, dartFlags, environment);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Command browserTest(String url, TestConfiguration configuration,
|
static Command browserTest(String url, TestConfiguration configuration,
|
||||||
{bool retry}) {
|
{bool retry}) {
|
||||||
return new BrowserTestCommand._(url, configuration, retry);
|
return new BrowserTestCommand._(url, configuration, retry);
|
||||||
|
@ -403,46 +393,6 @@ class AddFlagsKey {
|
||||||
int get hashCode => flags.hashCode ^ env.hashCode;
|
int get hashCode => flags.hashCode ^ env.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContentShellCommand extends ProcessCommand {
|
|
||||||
ContentShellCommand._(
|
|
||||||
String executable,
|
|
||||||
String htmlFile,
|
|
||||||
List<String> options,
|
|
||||||
List<String> dartFlags,
|
|
||||||
Map<String, String> environmentOverrides)
|
|
||||||
: super._("content_shell", executable, _getArguments(options, htmlFile),
|
|
||||||
_getEnvironment(environmentOverrides, dartFlags));
|
|
||||||
|
|
||||||
// Cache the modified environments in a map from the old environment and
|
|
||||||
// the string of Dart flags to the new environment. Avoid creating new
|
|
||||||
// environment object for each command object.
|
|
||||||
static Map<AddFlagsKey, Map<String, String>> environments = {};
|
|
||||||
|
|
||||||
static Map<String, String> _getEnvironment(
|
|
||||||
Map<String, String> env, List<String> dartFlags) {
|
|
||||||
var needDartFlags = dartFlags != null && dartFlags.isNotEmpty;
|
|
||||||
if (needDartFlags) {
|
|
||||||
if (env == null) {
|
|
||||||
env = const <String, String>{};
|
|
||||||
}
|
|
||||||
var flags = dartFlags.join(' ');
|
|
||||||
return environments.putIfAbsent(
|
|
||||||
new AddFlagsKey(flags, env),
|
|
||||||
() => new Map<String, String>.from(env)
|
|
||||||
..addAll({'DART_FLAGS': flags, 'DART_FORWARDING_PRINT': '1'}));
|
|
||||||
}
|
|
||||||
return env;
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<String> _getArguments(List<String> options, String htmlFile) {
|
|
||||||
var arguments = options.toList();
|
|
||||||
arguments.add(htmlFile);
|
|
||||||
return arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get maxNumRetries => 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
class BrowserTestCommand extends Command {
|
class BrowserTestCommand extends Command {
|
||||||
Runtime get browser => configuration.runtime;
|
Runtime get browser => configuration.runtime;
|
||||||
final String url;
|
final String url;
|
||||||
|
|
|
@ -129,180 +129,6 @@ class CommandOutput extends UniqueObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContentShellCommandOutput extends CommandOutput {
|
|
||||||
// Although tests are reported as passing, content shell sometimes exits with
|
|
||||||
// a nonzero exitcode which makes our builders extremely flaky.
|
|
||||||
// See: http://dartbug.com/15139.
|
|
||||||
// TODO(rnystrom): Is this still needed? The underlying bug is closed.
|
|
||||||
static const _whitelistedContentShellExitCode = -1073740022;
|
|
||||||
|
|
||||||
static bool _failedBecauseOfFlakyInfrastructure(
|
|
||||||
Command command, bool timedOut, List<int> stderrBytes) {
|
|
||||||
// If the browser test failed, it may have been because content shell
|
|
||||||
// and the virtual framebuffer X server didn't hook up, or it crashed with
|
|
||||||
// a core dump. Sometimes content shell crashes after it has set the stdout
|
|
||||||
// to PASS, so we have to do this check first.
|
|
||||||
// Content shell also fails with a broken pipe message: Issue 26739
|
|
||||||
var zygoteCrash =
|
|
||||||
new RegExp(r"ERROR:zygote_linux\.cc\(\d+\)] write: Broken pipe");
|
|
||||||
var stderr = decodeUtf8(stderrBytes);
|
|
||||||
// TODO(7564): See http://dartbug.com/7564
|
|
||||||
// This may not be happening anymore. Test by removing this suppression.
|
|
||||||
if (stderr.contains(cannotOpenDisplayMessage) ||
|
|
||||||
stderr.contains(failedToRunCommandMessage)) {
|
|
||||||
DebugLogger.warning(
|
|
||||||
"Warning: Failure because of missing XDisplay. Test ignored");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// TODO(26739): See http://dartbug.com/26739
|
|
||||||
if (zygoteCrash.hasMatch(stderr)) {
|
|
||||||
DebugLogger.warning("Warning: Failure because of content_shell "
|
|
||||||
"zygote crash. Test ignored");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final bool _infraFailure;
|
|
||||||
|
|
||||||
ContentShellCommandOutput(
|
|
||||||
Command command,
|
|
||||||
int exitCode,
|
|
||||||
bool timedOut,
|
|
||||||
List<int> stdout,
|
|
||||||
List<int> stderr,
|
|
||||||
Duration time,
|
|
||||||
bool compilationSkipped)
|
|
||||||
: _infraFailure =
|
|
||||||
_failedBecauseOfFlakyInfrastructure(command, timedOut, stderr),
|
|
||||||
super(command, exitCode, timedOut, stdout, stderr, time,
|
|
||||||
compilationSkipped, 0);
|
|
||||||
|
|
||||||
Expectation result(TestCase testCase) {
|
|
||||||
if (_infraFailure) {
|
|
||||||
return Expectation.ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle crashes and timeouts first
|
|
||||||
if (hasCrashed) return Expectation.crash;
|
|
||||||
if (hasTimedOut) return Expectation.timeout;
|
|
||||||
if (hasNonUtf8) return Expectation.nonUtf8Error;
|
|
||||||
|
|
||||||
var outcome = _getOutcome();
|
|
||||||
|
|
||||||
if (testCase.hasRuntimeError) {
|
|
||||||
if (!outcome.canBeOutcomeOf(Expectation.runtimeError)) {
|
|
||||||
return Expectation.missingRuntimeError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (testCase.isNegative) {
|
|
||||||
if (outcome.canBeOutcomeOf(Expectation.fail)) return Expectation.pass;
|
|
||||||
return Expectation.fail;
|
|
||||||
}
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get successful => canRunDependendCommands;
|
|
||||||
|
|
||||||
bool get canRunDependendCommands {
|
|
||||||
// We cannot rely on the exit code of content_shell as a method to
|
|
||||||
// determine if we were successful or not.
|
|
||||||
return super.canRunDependendCommands && !_didFail(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get hasCrashed => super.hasCrashed || _rendererCrashed;
|
|
||||||
|
|
||||||
Expectation _getOutcome() {
|
|
||||||
if (_browserTestFailure) {
|
|
||||||
return Expectation.runtimeError;
|
|
||||||
}
|
|
||||||
return Expectation.pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get _rendererCrashed =>
|
|
||||||
decodeUtf8(super.stdout).contains("#CRASHED - rendere");
|
|
||||||
|
|
||||||
bool get _browserTestFailure {
|
|
||||||
// Browser tests fail unless stdout contains
|
|
||||||
// 'Content-Type: text/plain' followed by 'PASS'.
|
|
||||||
var hasContentType = false;
|
|
||||||
var stdoutLines = decodeUtf8(super.stdout).split("\n");
|
|
||||||
var containsFail = false;
|
|
||||||
var containsPass = false;
|
|
||||||
for (String line in stdoutLines) {
|
|
||||||
switch (line) {
|
|
||||||
case 'Content-Type: text/plain':
|
|
||||||
hasContentType = true;
|
|
||||||
break;
|
|
||||||
case 'FAIL':
|
|
||||||
if (hasContentType) {
|
|
||||||
containsFail = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'PASS':
|
|
||||||
if (hasContentType) {
|
|
||||||
containsPass = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasContentType) {
|
|
||||||
if (containsFail && containsPass) {
|
|
||||||
DebugLogger.warning("Test had 'FAIL' and 'PASS' in stdout. ($command)");
|
|
||||||
}
|
|
||||||
if (!containsFail && !containsPass) {
|
|
||||||
DebugLogger.warning("Test had neither 'FAIL' nor 'PASS' in stdout. "
|
|
||||||
"($command)");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (containsFail) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
assert(containsPass);
|
|
||||||
if (exitCode != 0) {
|
|
||||||
var message = "All tests passed, but exitCode != 0. "
|
|
||||||
"Actual exitcode: $exitCode. "
|
|
||||||
"($command)";
|
|
||||||
DebugLogger.warning(message);
|
|
||||||
diagnostics.add(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var isWindows = io.Platform.operatingSystem == 'windows';
|
|
||||||
return (!hasCrashed &&
|
|
||||||
exitCode != 0 &&
|
|
||||||
(!isWindows || exitCode != _whitelistedContentShellExitCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugLogger.warning("Couldn't find 'Content-Type: text/plain' in output. "
|
|
||||||
"($command).");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HtmlBrowserCommandOutput extends ContentShellCommandOutput {
|
|
||||||
HtmlBrowserCommandOutput(
|
|
||||||
Command command,
|
|
||||||
int exitCode,
|
|
||||||
bool timedOut,
|
|
||||||
List<int> stdout,
|
|
||||||
List<int> stderr,
|
|
||||||
Duration time,
|
|
||||||
bool compilationSkipped)
|
|
||||||
: super(command, exitCode, timedOut, stdout, stderr, time,
|
|
||||||
compilationSkipped);
|
|
||||||
|
|
||||||
bool _didFail(TestCase testCase) {
|
|
||||||
return _getOutcome() != Expectation.pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get _browserTestFailure {
|
|
||||||
// We should not need to convert back and forward.
|
|
||||||
var output = decodeUtf8(super.stdout);
|
|
||||||
if (output.contains("FAIL")) return true;
|
|
||||||
return !output.contains("PASS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BrowserTestJsonResult {
|
class BrowserTestJsonResult {
|
||||||
static const _allowedTypes = const [
|
static const _allowedTypes = const [
|
||||||
'sync_exception',
|
'sync_exception',
|
||||||
|
@ -976,13 +802,7 @@ class ScriptCommandOutput extends CommandOutput {
|
||||||
CommandOutput createCommandOutput(Command command, int exitCode, bool timedOut,
|
CommandOutput createCommandOutput(Command command, int exitCode, bool timedOut,
|
||||||
List<int> stdout, List<int> stderr, Duration time, bool compilationSkipped,
|
List<int> stdout, List<int> stderr, Duration time, bool compilationSkipped,
|
||||||
[int pid = 0]) {
|
[int pid = 0]) {
|
||||||
if (command is ContentShellCommand) {
|
if (command is AnalysisCommand) {
|
||||||
return new ContentShellCommandOutput(
|
|
||||||
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
|
|
||||||
} else if (command is BrowserTestCommand) {
|
|
||||||
return new HtmlBrowserCommandOutput(
|
|
||||||
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
|
|
||||||
} else if (command is AnalysisCommand) {
|
|
||||||
return new AnalysisCommandOutput(
|
return new AnalysisCommandOutput(
|
||||||
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
|
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
|
||||||
} else if (command is SpecParseCommand) {
|
} else if (command is SpecParseCommand) {
|
||||||
|
|
|
@ -113,18 +113,13 @@ flutter: Run Dart code on the Flutter engine.
|
||||||
dart_precompiled: Run a precompiled snapshot on the VM without a JIT.
|
dart_precompiled: Run a precompiled snapshot on the VM without a JIT.
|
||||||
d8: Run JavaScript from the command line using v8.
|
d8: Run JavaScript from the command line using v8.
|
||||||
jsshell: Run JavaScript from the command line using Firefox js-shell.
|
jsshell: Run JavaScript from the command line using Firefox js-shell.
|
||||||
drt: Run Dart or JavaScript in the headless version of Chrome,
|
|
||||||
Content shell.
|
|
||||||
|
|
||||||
ContentShellOnAndroid: Run Dart or JavaScript in content shell on Android.
|
firefox:
|
||||||
|
|
||||||
ff:
|
|
||||||
chrome:
|
chrome:
|
||||||
safari:
|
safari:
|
||||||
ie9:
|
ie9:
|
||||||
ie10:
|
ie10:
|
||||||
ie11:
|
ie11:
|
||||||
opera:
|
|
||||||
chromeOnAndroid: Run JavaScript in the specified browser.
|
chromeOnAndroid: Run JavaScript in the specified browser.
|
||||||
|
|
||||||
self_check: Pass each test or its compiled output to every file under
|
self_check: Pass each test or its compiled output to every file under
|
||||||
|
@ -238,7 +233,6 @@ compact, color, line, verbose, silent, status, buildbot, diff''',
|
||||||
new _Option.bool('time', 'Print timing information after running tests.'),
|
new _Option.bool('time', 'Print timing information after running tests.'),
|
||||||
new _Option('dart', 'Path to dart executable.', hide: true),
|
new _Option('dart', 'Path to dart executable.', hide: true),
|
||||||
new _Option('flutter', 'Path to flutter executable.', hide: true),
|
new _Option('flutter', 'Path to flutter executable.', hide: true),
|
||||||
new _Option('drt', 'Path to content shell executable.', hide: true),
|
|
||||||
new _Option('firefox', 'Path to firefox browser executable.', hide: true),
|
new _Option('firefox', 'Path to firefox browser executable.', hide: true),
|
||||||
new _Option('chrome', 'Path to chrome browser executable.', hide: true),
|
new _Option('chrome', 'Path to chrome browser executable.', hide: true),
|
||||||
new _Option('safari', 'Path to safari browser executable.', hide: true),
|
new _Option('safari', 'Path to safari browser executable.', hide: true),
|
||||||
|
|
|
@ -200,25 +200,7 @@ class DartVmRuntimeConfiguration extends RuntimeConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runtime configuration for Content Shell. We previously used a similar
|
//// The standalone Dart VM binary, "dart" or "dart.exe".
|
||||||
/// program named Dump Render Tree, hence the name.
|
|
||||||
class DrtRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
|
||||||
int timeoutMultiplier(
|
|
||||||
{Mode mode,
|
|
||||||
bool isChecked: false,
|
|
||||||
bool isReload: false,
|
|
||||||
Architecture arch}) {
|
|
||||||
return 4 // Allow additional time for browser testing to run.
|
|
||||||
// TODO(ahe): We might need to distinguish between DRT for running
|
|
||||||
// JavaScript and Dart code. I'm not convinced the inherited timeout
|
|
||||||
// multiplier is relevant for JavaScript.
|
|
||||||
*
|
|
||||||
super.timeoutMultiplier(
|
|
||||||
mode: mode, isChecked: isChecked, isReload: isReload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The standalone Dart VM binary, "dart" or "dart.exe".
|
|
||||||
class StandaloneDartRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
class StandaloneDartRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||||
List<Command> computeRuntimeCommands(
|
List<Command> computeRuntimeCommands(
|
||||||
TestSuite suite,
|
TestSuite suite,
|
||||||
|
|
|
@ -1360,14 +1360,6 @@ bool shouldRetryCommand(CommandOutput output) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As long as we use a legacy version of our custom content_shell (which
|
|
||||||
// became quite flaky after chrome-50 roll) we'll re-run tests on it.
|
|
||||||
// The plan is to use chrome's content_shell instead of our own.
|
|
||||||
// See http://dartbug.com/29655 .
|
|
||||||
if (command is ContentShellCommand) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io.Platform.operatingSystem == 'linux') {
|
if (io.Platform.operatingSystem == 'linux') {
|
||||||
decodeOutput();
|
decodeOutput();
|
||||||
// No matter which command we ran: If we get failures due to the
|
// No matter which command we ran: If we get failures due to the
|
||||||
|
|
|
@ -1062,7 +1062,7 @@ class StandardTestSuite extends TestSuite {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the command(s) that compile all the inputs needed by the
|
// Construct the command(s) that compile all the inputs needed by the
|
||||||
// browser test. For running Dart in DRT, this will be noop commands.
|
// browser test.
|
||||||
var commands = <Command>[];
|
var commands = <Command>[];
|
||||||
|
|
||||||
void addCompileCommand(String fileName, String toPath) {
|
void addCompileCommand(String fileName, String toPath) {
|
||||||
|
@ -1245,17 +1245,6 @@ class StandardTestSuite extends TestSuite {
|
||||||
alwaysCompile: !useSdk);
|
alwaysCompile: !useSdk);
|
||||||
}
|
}
|
||||||
|
|
||||||
String get contentShellFilename {
|
|
||||||
if (configuration.drtPath != null) return configuration.drtPath;
|
|
||||||
|
|
||||||
if (Platform.operatingSystem == 'macos') {
|
|
||||||
final path = dartDir.append(
|
|
||||||
'/client/tests/drt/Content Shell.app/Contents/MacOS/Content Shell');
|
|
||||||
return path.toNativePath();
|
|
||||||
}
|
|
||||||
return dartDir.append('client/tests/drt/content_shell').toNativePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> commonArgumentsFromFile(
|
List<String> commonArgumentsFromFile(
|
||||||
Path filePath, Map<String, dynamic> optionsFromFile) {
|
Path filePath, Map<String, dynamic> optionsFromFile) {
|
||||||
var args = configuration.standardOptions.toList();
|
var args = configuration.standardOptions.toList();
|
||||||
|
@ -1345,41 +1334,17 @@ class StandardTestSuite extends TestSuite {
|
||||||
*
|
*
|
||||||
* // OtherScripts=file1.dart file2.dart
|
* // OtherScripts=file1.dart file2.dart
|
||||||
*
|
*
|
||||||
* - You can indicate whether a test is treated as a web-only test by
|
* - Most tests are not web tests, but can (and will be) wrapped within
|
||||||
* using an explicit import to a part of the dart:html library:
|
* an HTML file and another script file to test them also on browser
|
||||||
|
* environments (e.g. language and corelib tests are run this way).
|
||||||
|
* We deduce that if a file with the same name as the test, but ending in
|
||||||
|
* .html instead of .dart exists, the test was intended to be a web test
|
||||||
|
* and no wrapping is necessary.
|
||||||
*
|
*
|
||||||
* import 'dart:html';
|
* - 'test.dart' assumes tests fail if
|
||||||
* import 'dart:web_audio';
|
* the process returns a non-zero exit code (in the case of web tests, we
|
||||||
* import 'dart:indexed_db';
|
|
||||||
* import 'dart:svg';
|
|
||||||
* import 'dart:web_sql';
|
|
||||||
*
|
|
||||||
* Most tests are not web tests, but can (and will be) wrapped within
|
|
||||||
* another script file to test them also on browser environments (e.g.
|
|
||||||
* language and corelib tests are run this way). We deduce that if this
|
|
||||||
* import is specified, the test was intended to be a web test and no
|
|
||||||
* wrapping is necessary.
|
|
||||||
*
|
|
||||||
* - You can convert DRT web-tests into layout-web-tests by specifying a
|
|
||||||
* test expectation file. An expectation file is located in the same
|
|
||||||
* location as the test, it has the same file name, except for the extension
|
|
||||||
* (which can be either .txt or .png).
|
|
||||||
*
|
|
||||||
* When there are no expectation files, 'test.dart' assumes tests fail if
|
|
||||||
* the process return a non-zero exit code (in the case of web tests, we
|
|
||||||
* check for PASS/FAIL indications in the test output).
|
* check for PASS/FAIL indications in the test output).
|
||||||
*
|
*
|
||||||
* When there is an expectation file, tests are run differently: the test
|
|
||||||
* code is run to the end of the event loop and 'test.dart' takes a snapshot
|
|
||||||
* of what is rendered in the page at that moment. This snapshot is
|
|
||||||
* represented either in text form, if the expectation ends in .txt, or as
|
|
||||||
* an image, if the expectation ends in .png. 'test.dart' will compare the
|
|
||||||
* snapshot to the expectation file. When tests fail, 'test.dart' saves the
|
|
||||||
* new snapshot into a file so it can be visualized or copied over.
|
|
||||||
* Expectations can be recorded for the first time by creating an empty file
|
|
||||||
* with the right name (touch test_name_test.png), running the test, and
|
|
||||||
* executing the copy command printed by the test script.
|
|
||||||
*
|
|
||||||
* This method is static as the map is cached and shared amongst
|
* This method is static as the map is cached and shared amongst
|
||||||
* configurations, so it may not use [configuration].
|
* configurations, so it may not use [configuration].
|
||||||
*/
|
*/
|
||||||
|
@ -1643,7 +1608,7 @@ class StandardTestSuite extends TestSuite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used for testing packages in on off settings, i.e., we pass in the actual
|
/// Used for testing packages in one-off settings, i.e., we pass in the actual
|
||||||
/// directory that we want to test.
|
/// directory that we want to test.
|
||||||
class PKGTestSuite extends StandardTestSuite {
|
class PKGTestSuite extends StandardTestSuite {
|
||||||
PKGTestSuite(TestConfiguration configuration, Path directoryPath)
|
PKGTestSuite(TestConfiguration configuration, Path directoryPath)
|
||||||
|
|
Loading…
Reference in a new issue