js/src/tests/lib/tests.py

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 # Library for JSTest tests.
michael@0 2 #
michael@0 3 # This contains classes that represent an individual test, including
michael@0 4 # metadata, and know how to run the tests and determine failures.
michael@0 5
michael@0 6 import datetime, os, sys, time
michael@0 7 from subprocess import Popen, PIPE
michael@0 8 from threading import Thread
michael@0 9
michael@0 10 from results import TestOutput
michael@0 11
michael@0 12 # When run on tbpl, we run each test multiple times with the following arguments.
michael@0 13 TBPL_FLAGS = [
michael@0 14 [], # no flags, normal baseline and ion
michael@0 15 ['--ion-eager', '--ion-parallel-compile=off'], # implies --baseline-eager
michael@0 16 ['--ion-eager', '--ion-parallel-compile=off', '--ion-check-range-analysis', '--no-sse3'],
michael@0 17 ['--baseline-eager'],
michael@0 18 ['--baseline-eager', '--no-fpu'],
michael@0 19 ['--no-baseline', '--no-ion'],
michael@0 20 ]
michael@0 21
michael@0 22 def do_run_cmd(cmd):
michael@0 23 l = [ None, None ]
michael@0 24 th_run_cmd(cmd, l)
michael@0 25 return l[1]
michael@0 26
michael@0 27 def set_limits():
michael@0 28 # resource module not supported on all platforms
michael@0 29 try:
michael@0 30 import resource
michael@0 31 GB = 2**30
michael@0 32 resource.setrlimit(resource.RLIMIT_AS, (2*GB, 2*GB))
michael@0 33 except:
michael@0 34 return
michael@0 35
michael@0 36 def th_run_cmd(cmd, l):
michael@0 37 t0 = datetime.datetime.now()
michael@0 38
michael@0 39 # close_fds and preexec_fn are not supported on Windows and will
michael@0 40 # cause a ValueError.
michael@0 41 options = {}
michael@0 42 if sys.platform != 'win32':
michael@0 43 options["close_fds"] = True
michael@0 44 options["preexec_fn"] = set_limits
michael@0 45 p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, **options)
michael@0 46
michael@0 47 l[0] = p
michael@0 48 out, err = p.communicate()
michael@0 49 t1 = datetime.datetime.now()
michael@0 50 dd = t1-t0
michael@0 51 dt = dd.seconds + 1e-6 * dd.microseconds
michael@0 52 l[1] = (out, err, p.returncode, dt)
michael@0 53
michael@0 54 def run_cmd(cmd, timeout=60.0):
michael@0 55 if timeout is None:
michael@0 56 return do_run_cmd(cmd)
michael@0 57
michael@0 58 l = [ None, None ]
michael@0 59 timed_out = False
michael@0 60 th = Thread(target=th_run_cmd, args=(cmd, l))
michael@0 61 th.start()
michael@0 62 th.join(timeout)
michael@0 63 while th.isAlive():
michael@0 64 if l[0] is not None:
michael@0 65 try:
michael@0 66 # In Python 3, we could just do l[0].kill().
michael@0 67 import signal
michael@0 68 if sys.platform != 'win32':
michael@0 69 os.kill(l[0].pid, signal.SIGKILL)
michael@0 70 time.sleep(.1)
michael@0 71 timed_out = True
michael@0 72 except OSError:
michael@0 73 # Expecting a "No such process" error
michael@0 74 pass
michael@0 75 th.join()
michael@0 76 return l[1] + (timed_out,)
michael@0 77
michael@0 78 class Test(object):
michael@0 79 """A runnable test."""
michael@0 80 def __init__(self, path):
michael@0 81 self.path = path # str: path of JS file relative to tests root dir
michael@0 82
michael@0 83 @staticmethod
michael@0 84 def prefix_command(path):
michael@0 85 """Return the '-f shell.js' options needed to run a test with the given path."""
michael@0 86 if path == '':
michael@0 87 return [ '-f', 'shell.js' ]
michael@0 88 head, base = os.path.split(path)
michael@0 89 return Test.prefix_command(head) + [ '-f', os.path.join(path, 'shell.js') ]
michael@0 90
michael@0 91 def get_command(self, js_cmd_prefix):
michael@0 92 dirname, filename = os.path.split(self.path)
michael@0 93 cmd = js_cmd_prefix + self.options + Test.prefix_command(dirname) + [ '-f', self.path ]
michael@0 94 return cmd
michael@0 95
michael@0 96 def run(self, js_cmd_prefix, timeout=30.0):
michael@0 97 cmd = self.get_command(js_cmd_prefix)
michael@0 98 out, err, rc, dt, timed_out = run_cmd(cmd, timeout)
michael@0 99 return TestOutput(self, cmd, out, err, rc, dt, timed_out)
michael@0 100
michael@0 101 class TestCase(Test):
michael@0 102 """A test case consisting of a test and an expected result."""
michael@0 103 js_cmd_prefix = None
michael@0 104
michael@0 105 def __init__(self, path):
michael@0 106 Test.__init__(self, path)
michael@0 107 self.enable = True # bool: True => run test, False => don't run
michael@0 108 self.expect = True # bool: expected result, True => pass
michael@0 109 self.random = False # bool: True => ignore output as 'random'
michael@0 110 self.slow = False # bool: True => test may run slowly
michael@0 111 self.options = [] # [str]: Extra options to pass to the shell
michael@0 112
michael@0 113 # The terms parsed to produce the above properties.
michael@0 114 self.terms = None
michael@0 115
michael@0 116 # The tag between |...| in the test header.
michael@0 117 self.tag = None
michael@0 118
michael@0 119 # Anything occuring after -- in the test header.
michael@0 120 self.comment = None
michael@0 121
michael@0 122 def __str__(self):
michael@0 123 ans = self.path
michael@0 124 if not self.enable:
michael@0 125 ans += ', skip'
michael@0 126 if not self.expect:
michael@0 127 ans += ', fails'
michael@0 128 if self.random:
michael@0 129 ans += ', random'
michael@0 130 if self.slow:
michael@0 131 ans += ', slow'
michael@0 132 if '-d' in self.options:
michael@0 133 ans += ', debugMode'
michael@0 134 return ans
michael@0 135
michael@0 136 @classmethod
michael@0 137 def set_js_cmd_prefix(self, js_path, js_args, debugger_prefix):
michael@0 138 parts = []
michael@0 139 if debugger_prefix:
michael@0 140 parts += debugger_prefix
michael@0 141 parts.append(js_path)
michael@0 142 if js_args:
michael@0 143 parts += js_args
michael@0 144 self.js_cmd_prefix = parts
michael@0 145
michael@0 146 def __cmp__(self, other):
michael@0 147 if self.path == other.path:
michael@0 148 return 0
michael@0 149 elif self.path < other.path:
michael@0 150 return -1
michael@0 151 return 1
michael@0 152
michael@0 153 def __hash__(self):
michael@0 154 return self.path.__hash__()

mercurial