Backed out changeset a4ec3ddcfc37 due to failure parsing manifest file.
[mozilla-central.git] / js / src / tests / manifest.py
blobd3a278fd89d50da3fcfca6ef138fce5f2c04d96e
1 # Library for JSTest manifests.
3 # This includes classes for representing and parsing JS manifests.
5 import os, re, sys
6 from subprocess import *
8 from tests import TestCase
10 class XULInfo:
11 def __init__(self, abi, os, isdebug):
12 self.abi = abi
13 self.os = os
14 self.isdebug = isdebug
16 def as_js(self):
17 """Return JS that when executed sets up variables so that JS expression
18 predicates on XUL build info evaluate properly."""
20 return 'var xulRuntime = { OS: "%s", XPCOMABI: "%s", shell: true }; var isDebugBuild=%s;' % (
21 self.os,
22 self.abi,
23 str(self.isdebug).lower())
25 @classmethod
26 def create(cls, jsdir):
27 """Create a XULInfo based on the current platform's characteristics."""
29 # Our strategy is to find the autoconf.mk generated for the build and
30 # read the values from there.
32 # Find config/autoconf.mk.
33 dir = jsdir
34 while True:
35 path = os.path.join(dir, 'config/autoconf.mk')
36 if os.path.isfile(path):
37 break
38 if os.path.dirname(dir) == dir:
39 print "Can't find config/autoconf.mk on a directory containing the JS shell (searched from %s)"%jsdir
40 sys.exit(1)
41 dir = os.path.dirname(dir)
43 # Read the values.
44 val_re = re.compile(r'(TARGET_XPCOM_ABI|OS_TARGET|MOZ_DEBUG)\s*=\s*(.*)')
45 kw = {}
46 for line in open(path):
47 m = val_re.match(line)
48 if m:
49 key, val = m.groups()
50 val = val.rstrip()
51 if key == 'TARGET_XPCOM_ABI':
52 kw['abi'] = val
53 if key == 'OS_TARGET':
54 kw['os'] = val
55 if key == 'MOZ_DEBUG':
56 kw['isdebug'] = (val == '1')
57 return cls(**kw)
59 class XULInfoTester:
60 def __init__(self, xulinfo, js_bin):
61 self.js_prolog = xulinfo.as_js()
62 self.js_bin = js_bin
63 # Maps JS expr to evaluation result.
64 self.cache = {}
66 def test(self, cond):
67 """Test a XUL predicate condition against this local info."""
68 ans = self.cache.get(cond, None)
69 if ans is None:
70 cmd = [ self.js_bin, '-e', self.js_prolog, '-e', 'print(!!(%s))'%cond ]
71 p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
72 out, err = p.communicate()
73 if out in ('true\n', 'true\r\n'):
74 ans = True
75 elif out in ('false\n', 'false\r\n'):
76 ans = False
77 else:
78 raise Exception("Failed to test XUL condition '%s'"%cond)
79 self.cache[cond] = ans
80 return ans
82 class NullXULInfoTester:
83 """Can be used to parse manifests without a JS shell."""
84 def test(self, cond):
85 return False
87 def parse(filename, xul_tester, reldir = ''):
88 ans = []
89 comment_re = re.compile(r'#.*')
90 dir = os.path.dirname(filename)
92 try:
93 f = open(filename)
94 except IOError:
95 print "warning: include file not found: '%s'"%filename
96 return ans
98 for line in f:
99 sline = comment_re.sub('', line)
100 parts = sline.split()
101 if len(parts) == 0:
102 # line is empty or just a comment, skip
103 pass
104 elif parts[0] == 'include':
105 include_file = parts[1]
106 include_reldir = os.path.join(reldir, os.path.dirname(include_file))
107 ans += parse(os.path.join(dir, include_file), xul_tester, include_reldir)
108 elif parts[0] == 'url-prefix':
109 # Doesn't apply to shell tests
110 pass
111 else:
112 script = None
113 enable = True
114 expect = True
115 random = False
116 slow = False
118 pos = 0
119 while pos < len(parts):
120 if parts[pos] == 'fails':
121 expect = False
122 pos += 1
123 elif parts[pos] == 'skip':
124 expect = enable = False
125 pos += 1
126 elif parts[pos] == 'random':
127 random = True
128 pos += 1
129 elif parts[pos].startswith('fails-if'):
130 cond = parts[pos][len('fails-if('):-1]
131 if xul_tester.test(cond):
132 expect = False
133 pos += 1
134 elif parts[pos].startswith('asserts-if'):
135 # This directive means we may flunk some number of
136 # NS_ASSERTIONs in the browser. For the shell, ignore it.
137 pos += 1
138 elif parts[pos].startswith('skip-if'):
139 cond = parts[pos][len('skip-if('):-1]
140 if xul_tester.test(cond):
141 expect = enable = False
142 pos += 1
143 elif parts[pos].startswith('random-if'):
144 cond = parts[pos][len('random-if('):-1]
145 if xul_tester.test(cond):
146 random = True
147 pos += 1
148 elif parts[pos] == 'script':
149 script = parts[pos+1]
150 pos += 2
151 elif parts[pos] == 'slow':
152 slow = True
153 pos += 1
154 else:
155 print 'warning: invalid manifest line element "%s"'%parts[pos]
156 pos += 1
158 assert script is not None
159 ans.append(TestCase(os.path.join(reldir, script),
160 enable, expect, random, slow))
161 return ans