Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
1
gaia/tests/python/gaia-unit-tests/gaia_unit_test/__init__.py
Executable file
1
gaia/tests/python/gaia-unit-tests/gaia_unit_test/__init__.py
Executable file
|
|
@ -0,0 +1 @@
|
|||
#
|
||||
5
gaia/tests/python/gaia-unit-tests/gaia_unit_test/disabled.json
Executable file
5
gaia/tests/python/gaia-unit-tests/gaia_unit_test/disabled.json
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"communications/facebook/test/unit/facebook_connector_test.js",
|
||||
"ftu/test/unit/tutorial_test.js",
|
||||
"keyboard/test/unit/imes/jspinyin/jspinyin_test.js"
|
||||
]
|
||||
265
gaia/tests/python/gaia-unit-tests/gaia_unit_test/main.py
Executable file
265
gaia/tests/python/gaia-unit-tests/gaia_unit_test/main.py
Executable file
|
|
@ -0,0 +1,265 @@
|
|||
import json
|
||||
import logging
|
||||
import mozlog
|
||||
from mozprofile import Profile
|
||||
from mozrunner import Runner
|
||||
from optparse import OptionParser
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import tornado.websocket
|
||||
import tornado.ioloop
|
||||
import tornado.httpserver
|
||||
import traceback
|
||||
|
||||
import reporters
|
||||
|
||||
|
||||
class TestAgentServer(tornado.websocket.WebSocketHandler):
|
||||
|
||||
increment = 0
|
||||
envs = {}
|
||||
pending_envs = []
|
||||
passes = 0
|
||||
failures = 0
|
||||
current_test = 'None'
|
||||
timer = None
|
||||
timeout = 120
|
||||
|
||||
def initialize(self, tests=None, runner=None, logger=None):
|
||||
self.tests = tests
|
||||
self.runner = runner
|
||||
self.logger = logger
|
||||
|
||||
|
||||
def emit(self, event, data):
|
||||
command = (event, data)
|
||||
self.write_message(json.dumps(command))
|
||||
|
||||
def open(self):
|
||||
self.increment = self.increment + 1
|
||||
self.run_tests(self.tests)
|
||||
|
||||
def timer_fn(self):
|
||||
message = "Timed out after %d seconds" % self.timeout
|
||||
self.logger.test_end(self.current_test, status='TIMEOUT', message=message)
|
||||
self.runner.cleanup()
|
||||
sys.exit(1)
|
||||
|
||||
def run_tests(self, tests):
|
||||
self.tests = tests
|
||||
self.run_next_test()
|
||||
|
||||
def run_next_test(self):
|
||||
self.current_test = self.tests.pop()
|
||||
self.emit('run tests', {'tests': ["/%s" % self.current_test] })
|
||||
|
||||
def on_envs_complete(self):
|
||||
exitCode = 0
|
||||
if self.failures or not self.passes:
|
||||
# Magic non-zero value to match the expectations of the mozharness
|
||||
# script.
|
||||
exitCode = 10
|
||||
|
||||
for env in self.envs:
|
||||
if len(self.envs[env].output):
|
||||
self.logger.info('\ntest report: (' + env + ')')
|
||||
self.logger.info('\n'.join(self.envs[env].output))
|
||||
|
||||
self.close()
|
||||
|
||||
self.logger.info('passed: %d' % self.passes)
|
||||
self.logger.info('failed: %d' % self.failures)
|
||||
self.logger.info('todo: 0')
|
||||
self.logger.suite_end()
|
||||
|
||||
crashed = self.runner.cleanup()
|
||||
sys.exit(1 if crashed else exitCode)
|
||||
|
||||
def handle_event(self, event, data):
|
||||
if event == 'set test envs':
|
||||
self.pending_envs = data[0]
|
||||
|
||||
if event == 'test data':
|
||||
# the 'test data' event is a nested event
|
||||
# inside of the main event body. It is a direct
|
||||
# copy of the mocha reporter data with the addition
|
||||
# of the 'testAgentEnvId' which is used to group
|
||||
# the results of different test runs.
|
||||
(test_event, test_data) = json.loads(data[0])
|
||||
|
||||
# gaia & test agent both use environment ids because
|
||||
# they nest test runners. This is a very special case
|
||||
# most test agent runners will not do this so add a
|
||||
# fallback environment name to make this simpler.
|
||||
if ('testAgentEnvId' in test_data):
|
||||
test_env = test_data['testAgentEnvId']
|
||||
else:
|
||||
test_env = 'global'
|
||||
|
||||
# add to pending
|
||||
if (test_event == 'start'):
|
||||
self.envs[test_env] = reporters.StructuredLogReporter(stream=False,
|
||||
logger=self.logger)
|
||||
|
||||
# don't process out of order commands
|
||||
if not (test_env in self.envs):
|
||||
return
|
||||
|
||||
self.envs[test_env].handle_event(test_event, test_data, self.current_test)
|
||||
|
||||
# remove from pending and trigger test complete check.
|
||||
if (test_event == 'end'):
|
||||
if test_env in self.pending_envs:
|
||||
idx = self.pending_envs.index(test_env)
|
||||
del self.pending_envs[idx]
|
||||
|
||||
self.passes += self.envs[test_env].passes
|
||||
self.failures += self.envs[test_env].failures
|
||||
|
||||
if self.tests:
|
||||
self.run_next_test()
|
||||
|
||||
# now that envs are totally complete show results.
|
||||
elif (len(self.pending_envs) == 0):
|
||||
self.on_envs_complete()
|
||||
|
||||
def on_close(self):
|
||||
self.logger.warning("Build shut down unexpectedly")
|
||||
self.runner.cleanup()
|
||||
sys.exit(1)
|
||||
|
||||
def on_message(self, message):
|
||||
# Instantiate a timer that will get called after self.timeout seconds;
|
||||
# this timer is used to detect hangs/crashes and shut down the test
|
||||
# run after checking for crashes.
|
||||
loop = tornado.ioloop.IOLoop.instance()
|
||||
if self.timer:
|
||||
loop.remove_timeout(self.timer)
|
||||
self.timer = loop.add_timeout(time.time() + self.timeout, self.timer_fn)
|
||||
|
||||
command = json.loads(message)
|
||||
# test agent protocol always uses the [event, data] format.
|
||||
self.handle_event(command[0], [command[1]])
|
||||
|
||||
|
||||
class GaiaUnitTestRunner(object):
|
||||
|
||||
def __init__(self, binary=None, profile=None, symbols_path=None,
|
||||
browser_arg=()):
|
||||
self.binary = binary
|
||||
self.profile = profile
|
||||
self.symbols_path = symbols_path
|
||||
self.browser_arg = browser_arg
|
||||
|
||||
def run(self):
|
||||
self.profile_dir = os.path.join(tempfile.mkdtemp(suffix='.gaiaunittest'),
|
||||
'profile')
|
||||
shutil.copytree(self.profile, self.profile_dir)
|
||||
|
||||
cmdargs = ['--runapp', 'Test Agent']
|
||||
if self.browser_arg:
|
||||
cmdargs += list(self.browser_arg)
|
||||
|
||||
profile = Profile(profile=self.profile_dir)
|
||||
self.runner = Runner(binary=self.binary,
|
||||
profile=profile,
|
||||
clean_profile=False,
|
||||
cmdargs=cmdargs,
|
||||
symbols_path=self.symbols_path)
|
||||
self.runner.start()
|
||||
|
||||
def cleanup(self):
|
||||
print 'checking for crashes'
|
||||
crashed = self.runner.check_for_crashes()
|
||||
self.runner.cleanup()
|
||||
shutil.rmtree(os.path.dirname(self.profile_dir))
|
||||
return crashed
|
||||
|
||||
__del__ = cleanup
|
||||
|
||||
|
||||
def cli():
|
||||
parser = OptionParser(usage='%prog [options] <test_file> <test_file> ...')
|
||||
parser.add_option("--binary",
|
||||
action="store", dest="binary",
|
||||
default=None,
|
||||
help="path to B2G desktop build binary")
|
||||
parser.add_option("--profile",
|
||||
action="store", dest="profile",
|
||||
default=None,
|
||||
help="path to gaia profile directory")
|
||||
parser.add_option("--symbols-path",
|
||||
action="store", dest="symbols_path",
|
||||
default=None,
|
||||
help="path or url to breakpad symbols")
|
||||
parser.add_option("--browser-arg",
|
||||
action="append", dest="browser_arg",
|
||||
default=[],
|
||||
help="optional command-line arg to pass to the browser")
|
||||
|
||||
mozlog.structured.commandline.add_logging_group(parser)
|
||||
options, tests = parser.parse_args()
|
||||
|
||||
if not options.binary or not options.profile:
|
||||
parser.print_usage()
|
||||
parser.exit('--binary and --profile required')
|
||||
|
||||
if not tests:
|
||||
# Read in a list of tests to skip from disabled.json, if it exists;
|
||||
# disabled.json should contain filenames with paths relative to the
|
||||
# apps directory, e.g., "wallpaper/test/unit/pick_test.js".
|
||||
disabled = []
|
||||
disabled_file = os.path.join(os.path.dirname(__file__), 'disabled.json')
|
||||
if os.access(disabled_file, os.F_OK):
|
||||
with open(disabled_file, 'r') as f:
|
||||
disabled_contents = f.read()
|
||||
try:
|
||||
disabled = json.loads(disabled_contents)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
print "Error while decoding disabled.json; please make sure this file has valid JSON syntax."
|
||||
sys.exit(1)
|
||||
|
||||
# build a list of tests
|
||||
for path in ('apps', 'tv_apps'):
|
||||
appsdir = os.path.join(os.path.dirname(os.path.abspath(options.profile)), path)
|
||||
for root, dirs, files in os.walk(appsdir):
|
||||
files.sort()
|
||||
for f in files:
|
||||
# only include tests in a 'unit' directory
|
||||
roots = root.split(os.path.sep)
|
||||
if 'unit' in roots:
|
||||
full_path = os.path.relpath(os.path.join(root, f), appsdir)
|
||||
if full_path.endswith('_test.js') and full_path not in disabled:
|
||||
tests.append(full_path)
|
||||
|
||||
logger_defaults = { 'tbpl': sys.stdout }
|
||||
upload_dir = os.environ.get('MOZ_UPLOAD_DIR')
|
||||
if upload_dir:
|
||||
logger_defaults['raw'] = open(os.path.join(upload_dir, "gu_structured_full.log"), "w")
|
||||
logger = mozlog.structured.commandline.setup_logging('gaia-unit-tests',
|
||||
options,
|
||||
logger_defaults)
|
||||
|
||||
logger.suite_start(tests)
|
||||
runner = GaiaUnitTestRunner(binary=options.binary,
|
||||
profile=options.profile,
|
||||
symbols_path=options.symbols_path,
|
||||
browser_arg=options.browser_arg)
|
||||
runner.run()
|
||||
|
||||
logger.info('starting WebSocket Server')
|
||||
application = tornado.web.Application([
|
||||
(r"/", TestAgentServer, {'tests': tests,
|
||||
'runner': runner,
|
||||
'logger': logger}),
|
||||
])
|
||||
http_server = tornado.httpserver.HTTPServer(application)
|
||||
http_server.listen(8789)
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
4
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/__init__.py
Executable file
4
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/__init__.py
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
from base import Base
|
||||
from spec import Spec
|
||||
from tbpl import TBPLLogger
|
||||
from structuredlog import StructuredLogReporter
|
||||
107
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/base.py
Executable file
107
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/base.py
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
""" Base class which reporters should all inherit from.
|
||||
The design is based on the original Mocha (javascript)
|
||||
reporter architecture.
|
||||
"""
|
||||
|
||||
|
||||
PASS_MARK = u"\u2713"
|
||||
FAIL_MARK = u"\u2716"
|
||||
|
||||
|
||||
class Base:
|
||||
|
||||
def __init__(self, stream=True):
|
||||
# reporter output
|
||||
self.output = []
|
||||
self.stream_output = stream
|
||||
|
||||
# test details
|
||||
self.passes = 0
|
||||
self.failures = 0
|
||||
self.pending = 0
|
||||
self.duration = 0
|
||||
|
||||
self.failed_tests = []
|
||||
|
||||
# analytics
|
||||
self.indent = 0
|
||||
self.tests = 0
|
||||
self.suites = 0
|
||||
|
||||
def formatError(self, data):
|
||||
if not ('err' in data):
|
||||
return ''
|
||||
|
||||
err = data['err']
|
||||
|
||||
out = data['fullTitle']
|
||||
out += '\n ' + err['message'] + '\n'
|
||||
|
||||
def indent(item):
|
||||
return ' ' + item
|
||||
|
||||
if ('stack' in err):
|
||||
out += '\n'.join(map(indent, err['stack'].split('\n')))
|
||||
|
||||
return out
|
||||
|
||||
def epilogue(self):
|
||||
self.report('\n')
|
||||
|
||||
if self.failed_tests:
|
||||
for test in self.failed_tests:
|
||||
self.report(self.formatError(test))
|
||||
|
||||
if self.failures:
|
||||
self.report(FAIL_MARK + ' %d of %d test(s) failed' % (self.failures, self.tests))
|
||||
else:
|
||||
self.report(PASS_MARK + ' %d test(s) complete' % (self.tests))
|
||||
|
||||
self.report('took %d ms' % (self.duration))
|
||||
|
||||
def on_end(self, data):
|
||||
self.epilogue()
|
||||
|
||||
def report(self, string, indent=False):
|
||||
""" When self.stream_output is true will instantly
|
||||
print results otherwise the results are added
|
||||
to self.output.
|
||||
"""
|
||||
if indent:
|
||||
string = (' ' * self.indent) + string
|
||||
|
||||
if self.stream_output:
|
||||
print string
|
||||
else:
|
||||
self.output.append(string)
|
||||
|
||||
def handle_event(self, event, data, testname):
|
||||
""" handles test events. The base class
|
||||
is mostly responsible for incrementing the
|
||||
reusable logic that the children then use.
|
||||
"""
|
||||
if event == 'pass':
|
||||
self.passes += 1
|
||||
|
||||
if event == 'fail':
|
||||
self.failures += 1
|
||||
self.failed_tests.append(data)
|
||||
|
||||
if event == 'pending':
|
||||
self.pending += 1
|
||||
|
||||
if event == 'suite':
|
||||
self.indent += 1
|
||||
|
||||
if event == 'suite end':
|
||||
self.indent -= 1
|
||||
|
||||
if event == 'end':
|
||||
self.tests = data['tests']
|
||||
self.duration = data['duration']
|
||||
self.suites = data['suites']
|
||||
|
||||
methodName = 'on_' + event.replace(' ', '_')
|
||||
|
||||
if (hasattr(self, methodName)):
|
||||
getattr(self, methodName)(data, testname)
|
||||
19
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/spec.py
Executable file
19
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/spec.py
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
from base import Base
|
||||
|
||||
from base import FAIL_MARK, PASS_MARK
|
||||
|
||||
class Spec(Base):
|
||||
|
||||
def on_test_end(self, data, testname):
|
||||
mark = ' ';
|
||||
|
||||
if data['state'] == 'passed':
|
||||
mark += PASS_MARK
|
||||
else:
|
||||
mark += FAIL_MARK
|
||||
|
||||
self.report(' ' + data['title'] + mark, True)
|
||||
|
||||
def on_suite(self, data, testname):
|
||||
#print self.indent
|
||||
self.report(data['title'], True)
|
||||
53
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/structuredlog.py
Executable file
53
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/structuredlog.py
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
from base import Base
|
||||
import json
|
||||
|
||||
class StructuredLogReporter(Base):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.logger = kwargs.pop('logger')
|
||||
Base.__init__(self, *args, **kwargs)
|
||||
|
||||
def log_message(self, log_type, data, testname):
|
||||
message = []
|
||||
for item in data.get('messages', []):
|
||||
if isinstance(item, basestring):
|
||||
message += [item]
|
||||
else:
|
||||
message += [json.dumps(item)]
|
||||
self.logger.info('TEST-INFO | %s | %s: %s' % (testname, log_type, ' '.join(message)))
|
||||
|
||||
def on_log(self, data, testname):
|
||||
self.log_message('log', data, testname)
|
||||
|
||||
def on_info(self, data, testname):
|
||||
self.log_message('info', data, testname)
|
||||
|
||||
def on_warn(self, data, testname):
|
||||
self.log_message('warn', data, testname)
|
||||
|
||||
def on_dir(self, data, testname):
|
||||
self.log_message('dir', data, testname)
|
||||
|
||||
def on_error(self, data, testname):
|
||||
self.log_message('error', data, testname)
|
||||
|
||||
def on_pass(self, data, testname):
|
||||
self.logger.test_status(testname, data['fullTitle'], 'PASS')
|
||||
|
||||
def on_fail(self, data, testname):
|
||||
subtest = data['fullTitle']
|
||||
msg = None
|
||||
stack = None
|
||||
if 'err' in data:
|
||||
if 'message' in data['err']:
|
||||
msg = data['err']['message']
|
||||
if 'stack' in data['err']:
|
||||
stack = '\n'.join([' %s' % x for x in data['err']['stack'].split('\n')])
|
||||
self.logger.test_status(testname, subtest, status='FAIL', message=msg, stack=stack)
|
||||
|
||||
def on_start(self, data, testname):
|
||||
self.logger.test_start(testname)
|
||||
|
||||
def on_end(self, data, testname):
|
||||
self.logger.test_end(testname, 'OK')
|
||||
self.logger.info('suite results (pass/fail): %d/%d' %
|
||||
(self.passes, self.failures))
|
||||
30
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/tbpl.py
Executable file
30
gaia/tests/python/gaia-unit-tests/gaia_unit_test/reporters/tbpl.py
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
from base import Base
|
||||
|
||||
|
||||
class TBPLLogger(Base):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.logger = kwargs['logger']
|
||||
del kwargs['logger']
|
||||
Base.__init__(self, *args, **kwargs)
|
||||
|
||||
def on_pass(self, data, testname):
|
||||
self.logger.testPass("%s | %s" % (testname, data['fullTitle']))
|
||||
|
||||
def on_fail(self, data, testname):
|
||||
msg = data['fullTitle']
|
||||
if 'err' in data:
|
||||
if 'message' in data['err']:
|
||||
msg += " | %s" % data['err']['message']
|
||||
self.logger.testFail("%s | %s" % (testname, msg))
|
||||
if 'err' in data and 'stack' in data['err']:
|
||||
self.logger.info('stack trace:\n%s' % '\n'.join(' %s' % x for x in data['err']['stack'].split('\n')))
|
||||
|
||||
def on_suite(self, data, testname):
|
||||
self.logger.testStart("%s | %s" % (testname, data['title']))
|
||||
|
||||
def on_suite_end(self, data, testname):
|
||||
self.logger.testEnd("%s | %s" % (testname, data['title']))
|
||||
|
||||
def on_end(self, data, testname):
|
||||
self.logger.info('suite results (pass/fail): %d/%d' %
|
||||
(self.passes, self.failures))
|
||||
43
gaia/tests/python/gaia-unit-tests/gaia_unit_test/samples/reference.txt
Executable file
43
gaia/tests/python/gaia-unit-tests/gaia_unit_test/samples/reference.txt
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
["set test envs",["TA"]]
|
||||
["test data","[\"start\",{\"total\":3,\"testAgentEnvId\":\"TA\"}]"]
|
||||
start {u'total': 3, u'testAgentEnvId': u'TA'}
|
||||
["test data","[\"suite\",{\"title\":\"\",\"fullTitle\":\"\",\"root\":true,\"indentation\":0,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite {u'fullTitle': u'', u'root': True, u'testAgentEnvId': u'TA', u'indentation': 0, u'title': u''}
|
||||
["test data","[\"suite\",{\"title\":\"test-agent/inspect\",\"fullTitle\":\"test-agent/inspect\",\"root\":false,\"indentation\":1,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite {u'fullTitle': u'test-agent/inspect', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 1, u'title': u'test-agent/inspect'}
|
||||
["test data","[\"suite\",{\"title\":\".inspect\",\"fullTitle\":\"test-agent/inspect .inspect\",\"root\":false,\"indentation\":2,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite {u'fullTitle': u'test-agent/inspect .inspect', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 2, u'title': u'.inspect'}
|
||||
["test data","[\"test\",{\"fn\":\"function () {\\n expect(0).to.be(1);\\n }\",\"title\":\"should fail\",\"fullTitle\":\"test-agent/inspect .inspect should fail\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
test {u'fullTitle': u'test-agent/inspect .inspect should fail', u'type': u'test', u'testAgentEnvId': u'TA', u'fn': u'function () {\n expect(0).to.be(1);\n }', u'title': u'should fail'}
|
||||
["test data","[\"fail\",{\"fn\":\"function () {\\n expect(0).to.be(1);\\n }\",\"title\":\"should fail\",\"fullTitle\":\"test-agent/inspect .inspect should fail\",\"state\":\"failed\",\"type\":\"test\",\"err\":{\"stack\":\"Error: expected 0 to equal 1\\n at assert (http://localhost:7771/vendor/expect.js:99)\\n at equal (http://localhost:7771/vendor/expect.js:203)\\n at (anonymous) (http://localhost:7771/vendor/expect.js:73)\\n at (anonymous) (http://localhost:7771/test/test-agent/inspect-test.js:20)\\n at run (http://localhost:7771/vendor/mocha/mocha.js:3001)\\n at runTest (http://localhost:7771/vendor/mocha/mocha.js:3305)\\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:3349)\\n at next (http://localhost:7771/vendor/mocha/mocha.js:3233)\\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:3242)\\n at next (http://localhost:7771/vendor/mocha/mocha.js:3192)\\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:3210)\\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:4022)\\n\",\"message\":\"expected 0 to equal 1\",\"type\":\"Error\",\"constructorName\":\"Error\",\"expected\":null,\"actual\":null},\"testAgentEnvId\":\"TA\"}]"]
|
||||
fail {u'err': {u'actual': None, u'constructorName': u'Error', u'expected': None, u'message': u'expected 0 to equal 1', u'type': u'Error', u'stack': u'Error: expected 0 to equal 1\n at assert (http://localhost:7771/vendor/expect.js:99)\n at equal (http://localhost:7771/vendor/expect.js:203)\n at (anonymous) (http://localhost:7771/vendor/expect.js:73)\n at (anonymous) (http://localhost:7771/test/test-agent/inspect-test.js:20)\n at run (http://localhost:7771/vendor/mocha/mocha.js:3001)\n at runTest (http://localhost:7771/vendor/mocha/mocha.js:3305)\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:3349)\n at next (http://localhost:7771/vendor/mocha/mocha.js:3233)\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:3242)\n at next (http://localhost:7771/vendor/mocha/mocha.js:3192)\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:3210)\n at (anonymous) (http://localhost:7771/vendor/mocha/mocha.js:4022)\n'}, u'title': u'should fail', u'state': u'failed', u'testAgentEnvId': u'TA', u'fullTitle': u'test-agent/inspect .inspect should fail', u'type': u'test', u'fn': u'function () {\n expect(0).to.be(1);\n }'}
|
||||
["test data","[\"test end\",{\"fn\":\"function () {\\n expect(0).to.be(1);\\n }\",\"title\":\"should fail\",\"fullTitle\":\"test-agent/inspect .inspect should fail\",\"state\":\"failed\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
test end {u'title': u'should fail', u'state': u'failed', u'testAgentEnvId': u'TA', u'fullTitle': u'test-agent/inspect .inspect should fail', u'type': u'test', u'fn': u'function () {\n expect(0).to.be(1);\n }'}
|
||||
["test data","[\"suite\",{\"title\":\"without color\",\"fullTitle\":\"test-agent/inspect .inspect without color\",\"root\":false,\"indentation\":3,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite {u'fullTitle': u'test-agent/inspect .inspect without color', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 3, u'title': u'without color'}
|
||||
["test data","[\"test\",{\"fn\":\"function () {\\n var result = TestAgent.inspect(object);\\n expect(result).to.contain('error');\\n expect(result).to.contain('details');\\n expect(result).to.contain('three');\\n }\",\"title\":\"should return formatted string\",\"fullTitle\":\"test-agent/inspect .inspect without color should return formatted string\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
test {u'fullTitle': u'test-agent/inspect .inspect without color should return formatted string', u'type': u'test', u'testAgentEnvId': u'TA', u'fn': u"function () {\n var result = TestAgent.inspect(object);\n expect(result).to.contain('error');\n expect(result).to.contain('details');\n expect(result).to.contain('three');\n }", u'title': u'should return formatted string'}
|
||||
["test data","[\"pass\",{\"fn\":\"function () {\\n var result = TestAgent.inspect(object);\\n expect(result).to.contain('error');\\n expect(result).to.contain('details');\\n expect(result).to.contain('three');\\n }\",\"title\":\"should return formatted string\",\"fullTitle\":\"test-agent/inspect .inspect without color should return formatted string\",\"duration\":13,\"state\":\"passed\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
pass {u'title': u'should return formatted string', u'state': u'passed', u'testAgentEnvId': u'TA', u'duration': 13, u'fullTitle': u'test-agent/inspect .inspect without color should return formatted string', u'type': u'test', u'fn': u"function () {\n var result = TestAgent.inspect(object);\n expect(result).to.contain('error');\n expect(result).to.contain('details');\n expect(result).to.contain('three');\n }"}
|
||||
["test data","[\"test end\",{\"fn\":\"function () {\\n var result = TestAgent.inspect(object);\\n expect(result).to.contain('error');\\n expect(result).to.contain('details');\\n expect(result).to.contain('three');\\n }\",\"title\":\"should return formatted string\",\"fullTitle\":\"test-agent/inspect .inspect without color should return formatted string\",\"duration\":13,\"state\":\"passed\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
test end {u'title': u'should return formatted string', u'state': u'passed', u'testAgentEnvId': u'TA', u'duration': 13, u'fullTitle': u'test-agent/inspect .inspect without color should return formatted string', u'type': u'test', u'fn': u"function () {\n var result = TestAgent.inspect(object);\n expect(result).to.contain('error');\n expect(result).to.contain('details');\n expect(result).to.contain('three');\n }"}
|
||||
["test data","[\"suite end\",{\"title\":\"without color\",\"fullTitle\":\"test-agent/inspect .inspect without color\",\"root\":false,\"indentation\":3,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite end {u'fullTitle': u'test-agent/inspect .inspect without color', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 3, u'title': u'without color'}
|
||||
["test data","[\"suite\",{\"title\":\"with color\",\"fullTitle\":\"test-agent/inspect .inspect with color\",\"root\":false,\"indentation\":3,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite {u'fullTitle': u'test-agent/inspect .inspect with color', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 3, u'title': u'with color'}
|
||||
["test data","[\"test\",{\"fn\":\"function () {\\n var result = TestAgent.inspect(object, false, 2, true);\\n expect(result).to.contain('error');\\n expect(result).to.contain('details');\\n expect(result).to.contain('three');\\n }\",\"title\":\"should return formatted string\",\"fullTitle\":\"test-agent/inspect .inspect with color should return formatted string\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
test {u'fullTitle': u'test-agent/inspect .inspect with color should return formatted string', u'type': u'test', u'testAgentEnvId': u'TA', u'fn': u"function () {\n var result = TestAgent.inspect(object, false, 2, true);\n expect(result).to.contain('error');\n expect(result).to.contain('details');\n expect(result).to.contain('three');\n }", u'title': u'should return formatted string'}
|
||||
["test data","[\"pass\",{\"fn\":\"function () {\\n var result = TestAgent.inspect(object, false, 2, true);\\n expect(result).to.contain('error');\\n expect(result).to.contain('details');\\n expect(result).to.contain('three');\\n }\",\"title\":\"should return formatted string\",\"fullTitle\":\"test-agent/inspect .inspect with color should return formatted string\",\"duration\":15,\"state\":\"passed\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
pass {u'title': u'should return formatted string', u'state': u'passed', u'testAgentEnvId': u'TA', u'duration': 15, u'fullTitle': u'test-agent/inspect .inspect with color should return formatted string', u'type': u'test', u'fn': u"function () {\n var result = TestAgent.inspect(object, false, 2, true);\n expect(result).to.contain('error');\n expect(result).to.contain('details');\n expect(result).to.contain('three');\n }"}
|
||||
["test data","[\"test end\",{\"fn\":\"function () {\\n var result = TestAgent.inspect(object, false, 2, true);\\n expect(result).to.contain('error');\\n expect(result).to.contain('details');\\n expect(result).to.contain('three');\\n }\",\"title\":\"should return formatted string\",\"fullTitle\":\"test-agent/inspect .inspect with color should return formatted string\",\"duration\":15,\"state\":\"passed\",\"type\":\"test\",\"testAgentEnvId\":\"TA\"}]"]
|
||||
test end {u'title': u'should return formatted string', u'state': u'passed', u'testAgentEnvId': u'TA', u'duration': 15, u'fullTitle': u'test-agent/inspect .inspect with color should return formatted string', u'type': u'test', u'fn': u"function () {\n var result = TestAgent.inspect(object, false, 2, true);\n expect(result).to.contain('error');\n expect(result).to.contain('details');\n expect(result).to.contain('three');\n }"}
|
||||
["test data","[\"suite end\",{\"title\":\"with color\",\"fullTitle\":\"test-agent/inspect .inspect with color\",\"root\":false,\"indentation\":3,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite end {u'fullTitle': u'test-agent/inspect .inspect with color', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 3, u'title': u'with color'}
|
||||
["test data","[\"suite end\",{\"title\":\".inspect\",\"fullTitle\":\"test-agent/inspect .inspect\",\"root\":false,\"indentation\":2,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite end {u'fullTitle': u'test-agent/inspect .inspect', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 2, u'title': u'.inspect'}
|
||||
["test data","[\"suite end\",{\"title\":\"test-agent/inspect\",\"fullTitle\":\"test-agent/inspect\",\"root\":false,\"indentation\":1,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite end {u'fullTitle': u'test-agent/inspect', u'root': False, u'testAgentEnvId': u'TA', u'indentation': 1, u'title': u'test-agent/inspect'}
|
||||
["test data","[\"suite end\",{\"title\":\"\",\"fullTitle\":\"\",\"root\":true,\"indentation\":0,\"testAgentEnvId\":\"TA\"}]"]
|
||||
suite end {u'fullTitle': u'', u'root': True, u'testAgentEnvId': u'TA', u'indentation': 0, u'title': u''}
|
||||
["test data","[\"end\",{\"suites\":4,\"tests\":3,\"passes\":2,\"pending\":0,\"failures\":1,\"start\":\"2012-10-13T03:02:43.824Z\",\"end\":\"2012-10-13T03:02:43.934Z\",\"duration\":110,\"testAgentEnvId\":\"TA\"}]"]
|
||||
end {u'suites': 4, u'tests': 3, u'end': u'2012-10-13T03:02:43.934Z', u'passes': 2, u'start': u'2012-10-13T03:02:43.824Z', u'testAgentEnvId': u'TA', u'duration': 110, u'failures': 1, u'pending': 0}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import unittest
|
||||
from gaia_unit_test.reporters.base import Base
|
||||
import factory
|
||||
|
||||
|
||||
class BaseExtended(Base):
|
||||
def __init__(self, flag):
|
||||
Base.__init__(self, flag)
|
||||
self.calledWith = None
|
||||
|
||||
# whitespace case
|
||||
def on_test_end(self, data):
|
||||
self.calledWith = data
|
||||
|
||||
|
||||
class BaseTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.subject = Base(False)
|
||||
|
||||
def test_initailize(self):
|
||||
self.assertEqual(self.subject.passes, 0)
|
||||
self.assertEqual(self.subject.failures, 0)
|
||||
self.assertEqual(self.subject.duration, 0)
|
||||
self.assertEqual(self.subject.indent, 0)
|
||||
|
||||
def test_report(self):
|
||||
subject = self.subject
|
||||
|
||||
subject.report('foo')
|
||||
self.assertEqual(subject.output[0], 'foo')
|
||||
|
||||
subject.indent = 2
|
||||
|
||||
subject.report('xfoo', True)
|
||||
self.assertEqual(subject.output[1], ' xfoo')
|
||||
|
||||
def test_handle_event(self):
|
||||
subject = self.subject
|
||||
# pass
|
||||
subject.handle_event('pass', factory.passed())
|
||||
self.assertEqual(subject.passes, 1)
|
||||
|
||||
# fail
|
||||
expected_fail = factory.failed()
|
||||
subject.handle_event('fail', expected_fail)
|
||||
self.assertEqual(subject.failures, 1)
|
||||
self.assertEqual(subject.failed_tests[0], expected_fail)
|
||||
|
||||
# indent
|
||||
subject.handle_event('suite', factory.suite())
|
||||
self.assertEqual(subject.indent, 1)
|
||||
subject.handle_event('suite end', factory.suite())
|
||||
self.assertEqual(subject.indent, 0)
|
||||
|
||||
# end
|
||||
subject.handle_event('end', {
|
||||
'tests': 10,
|
||||
'duration': 123,
|
||||
'suites': 10
|
||||
})
|
||||
|
||||
self.assertEqual(subject.tests, 10)
|
||||
self.assertEqual(subject.duration, 123)
|
||||
self.assertEqual(subject.suites, 10)
|
||||
|
||||
def test_handle_event_extended(self):
|
||||
subject = BaseExtended(False)
|
||||
|
||||
inputObj = {'foo': 'bar'}
|
||||
|
||||
subject.handle_event('test end', inputObj)
|
||||
self.assertDictContainsSubset(inputObj, subject.calledWith)
|
||||
|
||||
self.calledWith = None
|
||||
|
||||
# should be silently ignored...
|
||||
subject.handle_event('random thing', 'foo')
|
||||
self.assertEqual(self.calledWith, None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
17
gaia/tests/python/gaia-unit-tests/gaia_unit_test/tests/reporters/factory.py
Executable file
17
gaia/tests/python/gaia-unit-tests/gaia_unit_test/tests/reporters/factory.py
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
def passed():
|
||||
return {};
|
||||
|
||||
def failed():
|
||||
return {};
|
||||
|
||||
def suite():
|
||||
return {};
|
||||
|
||||
def suite_end():
|
||||
return {};
|
||||
|
||||
def test():
|
||||
return {};
|
||||
|
||||
def test_end():
|
||||
return {};
|
||||
Loading…
Reference in a new issue