js/src/tests/lib/tests.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial