summaryrefslogtreecommitdiffstats
path: root/chrome/test/chromeos
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-27 00:38:42 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-27 00:38:42 +0000
commite8554cb59d7d0613a4fe442089893bd69e60bdd0 (patch)
treef10aa8020464c06c0223df6c54b9542f7928f1d8 /chrome/test/chromeos
parent7fb7886fa9ca23f19b8bfe8fd767cd1876ef2cbb (diff)
downloadchromium_src-e8554cb59d7d0613a4fe442089893bd69e60bdd0.zip
chromium_src-e8554cb59d7d0613a4fe442089893bd69e60bdd0.tar.gz
chromium_src-e8554cb59d7d0613a4fe442089893bd69e60bdd0.tar.bz2
Added back chromeos autotests that were reverted due to a check_deps bug.
TBR=zbehan TEST=none BUG=none Review URL: http://codereview.chromium.org/3156052 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57618 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/chromeos')
-rw-r--r--chrome/test/chromeos/autotest/files/client/deps/chrome_test/README7
-rw-r--r--chrome/test/chromeos/autotest/files/client/deps/chrome_test/chrome_test.py28
-rw-r--r--chrome/test/chromeos/autotest/files/client/deps/chrome_test/common.py12
-rw-r--r--chrome/test/chromeos/autotest/files/client/deps/chrome_test/control5
-rw-r--r--chrome/test/chromeos/autotest/files/client/deps/chrome_test/setup_test_links.sh16
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/control20
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/desktopui_BrowserTest.py38
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/control28
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/desktopui_PageCyclerTests.py39
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/page_cycler_results_parser.py112
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/control20
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/desktopui_SyncIntegrationTests.py39
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/control18
-rw-r--r--chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/desktopui_UITest.py38
14 files changed, 420 insertions, 0 deletions
diff --git a/chrome/test/chromeos/autotest/files/client/deps/chrome_test/README b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/README
new file mode 100644
index 0000000..445211e
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/README
@@ -0,0 +1,7 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+This deps brings install Chrome test files into an image. This includes all
+resource and test servers for HTTP and FTP. Tests that depend
+on chrome_test should add this as a dep in the setup. \ No newline at end of file
diff --git a/chrome/test/chromeos/autotest/files/client/deps/chrome_test/chrome_test.py b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/chrome_test.py
new file mode 100644
index 0000000..a535cfa
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/chrome_test.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+
+# Copyright (c) 2010 The Chromium OS 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 common, commands, logging, os
+from autotest_lib.client.bin import utils
+
+version = 1
+
+def setup(top_dir):
+ if 'CHROME_ORIGIN' not in os.environ.keys() or \
+ (os.environ['CHROME_ORIGIN'] != 'LOCAL_SOURCE' and
+ os.environ['CHROME_ORIGIN'] != 'SERVER_SOURCE'):
+ logging.info('Skipping Chrome test resource setup for non-local builds')
+ return
+
+ chrome_test_files = os.environ['SYSROOT'] + '/usr/local/autotest-chrome'
+ logging.info('Configuring chrome test resources in %s' % top_dir)
+ testsrc_dir = top_dir + '/test_src'
+
+ # Copy test build outputs.
+ utils.run('cp -ral %s %s' % (chrome_test_files, testsrc_dir))
+
+
+pwd = os.getcwd()
+utils.update_version(pwd + '/src', False, version, setup, pwd)
diff --git a/chrome/test/chromeos/autotest/files/client/deps/chrome_test/common.py b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/common.py
new file mode 100644
index 0000000..ac26b5d
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/common.py
@@ -0,0 +1,12 @@
+# Copyright (c) 2010 The Chromium OS 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 os, sys
+dirname = os.path.dirname(sys.modules[__name__].__file__)
+client_dir = os.path.abspath(os.path.join(dirname, "../../"))
+sys.path.insert(0, client_dir)
+import setup_modules
+sys.path.pop(0)
+setup_modules.setup(base_path=client_dir,
+ root_module_name="autotest_lib.client")
diff --git a/chrome/test/chromeos/autotest/files/client/deps/chrome_test/control b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/control
new file mode 100644
index 0000000..865c725
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/control
@@ -0,0 +1,5 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+job.setup_dep(['chrome_test'])
diff --git a/chrome/test/chromeos/autotest/files/client/deps/chrome_test/setup_test_links.sh b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/setup_test_links.sh
new file mode 100644
index 0000000..a938868
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/deps/chrome_test/setup_test_links.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#
+# Copyright (c) 2009 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.
+#
+# A script to setup symbolic links needed for Chrome's automated UI tests.
+
+ln -f -s /opt/google/chrome/chrome $(dirname $0)/chrome
+ln -f -s /opt/google/chrome/chrome.pak $(dirname $0)/chrome.pak
+ln -f -s /opt/google/chrome/locales $(dirname $0)/locales
+ln -f -s /opt/google/chrome/resources $(dirname $0)/resources
+
+mkdir -p $(dirname $0)/chromeos
+ln -f -s /opt/google/chrome/chromeos/libcros.so \
+ $(dirname $0)/chromeos/libcros.so
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/control b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/control
new file mode 100644
index 0000000..281a830
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/control
@@ -0,0 +1,20 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Chrome OS Team"
+NAME = "desktopui_BrowserTest"
+PURPOSE = "Verify basic browsing capability of Chrome."
+CRITERIA = """
+This test will fail if any of the commands chrome executes returns an error.
+"""
+TIME = "LONG"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "desktopui"
+TEST_TYPE = "client"
+
+DOC = """
+This is a wrapper test for Chrome browser_test.
+"""
+
+job.run_test('desktopui_BrowserTest')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/desktopui_BrowserTest.py b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/desktopui_BrowserTest.py
new file mode 100644
index 0000000..3f3402b
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_BrowserTest/desktopui_BrowserTest.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2010 The Chromium OS 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 logging, os, utils
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import error, site_ui
+
+class desktopui_BrowserTest(test.test):
+ version = 1
+
+ def setup(self):
+ self.job.setup_dep(['chrome_test'])
+ # create a empty srcdir to prevent the error that checks .version file
+ if not os.path.exists(self.srcdir):
+ os.mkdir(self.srcdir)
+
+
+ def run_once(self):
+ dep = 'chrome_test'
+ dep_dir = os.path.join(self.autodir, 'deps', dep)
+ self.job.install_pkg(dep, 'dep', dep_dir)
+
+ chrome_dir = '/opt/google/chrome'
+ test_binary_dir = '%s/test_src/out/Release' % dep_dir
+
+ try:
+ setup_cmd = '%s/%s' % (test_binary_dir,
+ 'setup_test_links.sh')
+ utils.system(setup_cmd)
+
+ cmd = '%s/%s' % (test_binary_dir, 'browser_tests')
+ cmd = site_ui.xcommand(cmd)
+ logging.info("Running %s" % cmd)
+ utils.system(cmd)
+ except error.CmdError, e:
+ logging.debug(e)
+ raise error.TestFail('browser_test failed.')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/control b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/control
new file mode 100644
index 0000000..91c6eb0
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/control
@@ -0,0 +1,28 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Chrome OS Team"
+NAME = "desktopui_PageCyclerTests"
+PURPOSE = "Benchmark page loading times of the Chrome web browser."
+CRITERIA = """
+No specific criteria.
+"""
+TIME = "LONG"
+TEST_CATEGORY = "Benchmark"
+TEST_CLASS = "desktopui"
+TEST_TYPE = "client"
+
+DOC = """
+The page cycler consists of the following tests:
+ 'PageCyclerTest.Alexa_usFile', 'PageCyclerTest.MozFile',
+ 'PageCyclerTest.Intl1File', 'PageCyclerTest.Intl2File',
+ 'PageCyclerTest.DhtmlFile', 'PageCyclerTest.Moz2File',
+ 'PageCyclerTest.BloatFile', 'PageCyclerTest.DomFile',
+ 'PageCyclerTest.MorejsFile', 'PageCyclerTest.MorejsnpFile'
+
+At the end of the test, a message is printed with the median latency.
+
+"""
+
+job.run_test('desktopui_PageCyclerTests')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/desktopui_PageCyclerTests.py b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/desktopui_PageCyclerTests.py
new file mode 100644
index 0000000..24c64c9
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/desktopui_PageCyclerTests.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2010 The Chromium OS 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 commands, logging, os, shutil, time
+from autotest_lib.client.bin import test, utils
+from autotest_lib.client.common_lib import error, site_httpd, site_ui
+from page_cycler_results_parser import PageCyclerResultsParser
+
+
+class desktopui_PageCyclerTests(test.test):
+ version = 1
+ results = {}
+
+ def run_page_cycler(self, gtest_filter = ''):
+ # TODO: Disable screensaver?
+ assert(gtest_filter != ''), gtest_filter+' cannot be empty!'
+ cmd = ('CR_SOURCE_ROOT=/home/chronos/chromium/src /home/chronos/'
+ 'chromium/src/x86-generic_out/Release/page_cycler_tests'
+ ' --gtest_filter=')+gtest_filter
+ xcmd = site_ui.xcommand(cmd)
+ logging.debug('Running: '+gtest_filter)
+ output = utils.system_output(xcmd)
+ pcrp = PageCyclerResultsParser()
+ result = pcrp.parse_results(output)
+ logging.debug(result)
+ self.results[gtest_filter] = result
+
+ def run_once(self):
+ # Use a smaller input set for testing purposes, if needed:
+### testNames=['PageCyclerTest.MozFile']
+ testNames=['PageCyclerTest.Alexa_usFile', 'PageCyclerTest.MozFile',
+ 'PageCyclerTest.Intl1File', 'PageCyclerTest.Intl2File',
+ 'PageCyclerTest.DhtmlFile', 'PageCyclerTest.Moz2File',
+ 'PageCyclerTest.BloatFile', 'PageCyclerTest.DomFile',
+ 'PageCyclerTest.MorejsFile', 'PageCyclerTest.MorejsnpFile']
+ for testName in testNames:
+ self.run_page_cycler(testName)
+ self.write_perf_keyval(self.results)
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/page_cycler_results_parser.py b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/page_cycler_results_parser.py
new file mode 100644
index 0000000..1d8e15a
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_PageCyclerTests/page_cycler_results_parser.py
@@ -0,0 +1,112 @@
+import subprocess as sub
+import re
+import sys
+import math, functools
+
+class SiteTimes(object):
+ def __init__(self):
+ self.site='UNDEFINED'
+ self.times=[]
+
+# helper function found online here:
+# http://code.activestate.com/recipes/511478-finding-the-percentile-
+# of-the-values/
+def percentile(N, percent, key=lambda x:x):
+ """
+ Find the percentile of a list of values.
+
+ @parameter N - is a list of values. Note N MUST BE already sorted.
+ @parameter percent - a float value from 0.0 to 1.0.
+ @parameter key - optional key function to compute value from each
+ element of N.
+
+ @return - the percentile of the values
+ """
+ if not N:
+ return None
+ k = (len(N)-1) * percent
+ f = math.floor(k)
+ c = math.ceil(k)
+ if f == c:
+ return key(N[int(k)])
+ d0 = key(N[int(f)]) * (k-f)
+ d1 = key(N[int(c)]) * (c-k)
+ return d0+d1
+
+def mean(numbers):
+ assert(len(numbers) != 0), 'list should not be empty!'
+ return sum(numbers)/len(numbers)
+
+class PageCyclerResultsParser:
+ def parse_file(self, outfile = 'out.txt'):
+ # output is the output of the page_cycler tests.
+ output = open(outfile).read()
+ return self.parse_results(output)
+
+ def parse_results(self, output = ''):
+ # median is 50th percentile.
+ median = functools.partial(percentile, percent=0.5)
+
+ assert(output != ''), 'Output cannot be empty!'
+
+ # split it up into lines
+ lines = output.split('\n')
+
+ # figure out where the results are...
+ found = False
+ # This is our anchor in the text
+ token = '*RESULT times:'
+ for index, line in enumerate(lines):
+ if(line.startswith(token)):
+ found = True
+ break
+
+ assert(found==True), token+' not found!?'
+ timesline = lines[index]
+ sitesline = lines[index-1]
+
+ # we have a line called times and a line called sites
+ m = re.search('\[(.*?)\]', sitesline)
+ sites = m.group(1).split(',')
+
+ m = re.search('\[(.*?)\]', timesline)
+ times = m.group(1).split(',')
+
+ assert(len(times) % len(sites) == 0), 'Times not divisible by sites!'
+
+ iterations = len(times)/len(sites)
+
+ # now we have a list called sites and a list called times
+ # let's do some statistics on it.
+ stList = []
+
+ # go over all the sites and populate the stlist data structure
+ for ii, site in enumerate(sites):
+ st = SiteTimes()
+ st.site = site
+ for jj in range(0, iterations):
+ mytime = float(times[jj*len(sites)+ii])
+ st.times.append(mytime)
+ stList.append(st)
+
+ # For debugging use something like this:
+ ###for ii, st in enumerate(stList):
+ ### print st.site
+ ### print st.times
+
+ # now remove the lowest element and print out mean of medians
+ medianList = []
+
+ totalTime = 0
+ for ii, st in enumerate(stList):
+ sortedTimes=sorted(st.times)
+ # drop highest time in the sortedTimes
+ sortedTimes.pop()
+ # TODO: Perhaps this should be a weighted mean?
+ totalTime += mean(sortedTimes)
+
+ return totalTime/len(stList)
+
+# This is how to use this class
+###pcrp=PageCyclerResultsParser()
+###print pcrp.parse_file('out.txt')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/control b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/control
new file mode 100644
index 0000000..f45a852
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/control
@@ -0,0 +1,20 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Chrome OS Team"
+NAME = "desktopui_SyncIntegrationTests"
+PURPOSE = "Verify sync capability of Chrome."
+CRITERIA = """
+This test will fail if any of the commands chrome executes returns an error.
+"""
+TIME = "LONG"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "desktopui"
+TEST_TYPE = "client"
+
+DOC = """
+This is a wrapper test for Chrome sync_integration_tests.
+"""
+
+job.run_test('desktopui_SyncIntegrationTests')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/desktopui_SyncIntegrationTests.py b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/desktopui_SyncIntegrationTests.py
new file mode 100644
index 0000000..5b53dba
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_SyncIntegrationTests/desktopui_SyncIntegrationTests.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2010 The Chromium OS 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 logging, os, utils
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import error, site_ui
+
+class desktopui_SyncIntegrationTests(test.test):
+ version = 1
+
+ def setup(self):
+ self.job.setup_dep(['chrome_test'])
+ # create a empty srcdir to prevent the error that checks .version file
+ if not os.path.exists(self.srcdir):
+ os.mkdir(self.srcdir)
+
+
+ def run_once(self):
+ dep = 'chrome_test'
+ dep_dir = os.path.join(self.autodir, 'deps', dep)
+ self.job.install_pkg(dep, 'dep', dep_dir)
+
+ chrome_dir = '/opt/google/chrome'
+ test_binary_dir = '%s/test_src/out/Release' % dep_dir
+ password_file = '%s/sync_password.txt' % dep_dir
+
+ try:
+ setup_cmd = '%s/%s' % (test_binary_dir,
+ 'setup_test_links.sh')
+ utils.system(setup_cmd)
+
+ cmd = '%s/sync_integration_tests --password-file-for-test=%s --test-terminate-timeout=300000' % (test_binary_dir, password_file)
+ cmd = site_ui.xcommand(cmd)
+ logging.info("Running %s" % cmd)
+ utils.system(cmd)
+ except error.CmdError, e:
+ logging.debug(e)
+ raise error.TestFail('sync_integration_tests failed.')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/control b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/control
new file mode 100644
index 0000000..b76e395
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/control
@@ -0,0 +1,18 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Chrome OS Team"
+NAME = "desktopui_UITest"
+PURPOSE = "Verify Chrome executes and renders basic pages."
+CRITERIA = "This test will fail if running Chrome returns a command error."
+TIME = "LONG"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "desktopui"
+TEST_TYPE = "client"
+
+DOC = """
+This is a wrapper test for Chrome ui_tests
+"""
+
+job.run_test('desktopui_UITest')
diff --git a/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/desktopui_UITest.py b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/desktopui_UITest.py
new file mode 100644
index 0000000..fcbb04b
--- /dev/null
+++ b/chrome/test/chromeos/autotest/files/client/site_tests/desktopui_UITest/desktopui_UITest.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2010 The Chromium OS 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 logging, os, utils
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import error, site_ui
+
+class desktopui_UITest(test.test):
+ version = 1
+
+ def setup(self):
+ self.job.setup_dep(['chrome_test'])
+ # create a empty srcdir to prevent the error that checks .version file
+ if not os.path.exists(self.srcdir):
+ os.mkdir(self.srcdir)
+
+
+ def run_once(self):
+ dep = 'chrome_test'
+ dep_dir = os.path.join(self.autodir, 'deps', dep)
+ self.job.install_pkg(dep, 'dep', dep_dir)
+
+ chrome_dir = '/opt/google/chrome'
+ test_binary_dir = '%s/test_src/out/Release' % dep_dir
+
+ try:
+ setup_cmd = '%s/%s' % (test_binary_dir,
+ 'setup_test_links.sh')
+ utils.system(setup_cmd)
+
+ cmd = '%s/%s' % (test_binary_dir, 'ui_tests')
+ cmd = site_ui.xcommand(cmd)
+ logging.info("Running %s" % cmd)
+ utils.system(cmd)
+ except error.CmdError, e:
+ logging.debug(e)
+ raise error.TestFail('browser_test failed.')