77import sys
88import os
99import subprocess as SP
10+ import argparse , textwrap
11+ import xml .etree .ElementTree as ET
12+
13+ parser = argparse .ArgumentParser (
14+ description = 'ChakraCore *nix Test Script' ,
15+ formatter_class = argparse .RawDescriptionHelpFormatter ,
16+ epilog = textwrap .dedent ('''\
17+ Samples:
18+
19+ test all folders:
20+ {0}
21+
22+ test only Array:
23+ {0} Array
24+
25+ test a single file:
26+ {0} Basics/hello.js
27+ ''' .format (sys .argv [0 ]))
28+ )
29+ parser .add_argument ('folders' , metavar = 'folder' , nargs = '*' ,
30+ help = 'folder subset to run tests' )
31+ parser .add_argument ('-b' , '--binary' , metavar = 'binary' , help = 'ch full path' );
32+ parser .add_argument ('-d' , '--debug' , action = 'store_true' ,
33+ help = 'use debug build' );
34+ parser .add_argument ('-t' , '--test' , action = 'store_true' , help = 'use test build' );
35+ parser .add_argument ('--x86' , action = 'store_true' , help = 'use x86 build' );
36+ parser .add_argument ('--x64' , action = 'store_true' , help = 'use x64 build' );
37+ args = parser .parse_args ()
1038
11- test_all = True
12- test_root = os .path .dirname (os .path .realpath (__file__ ))
13-
14- # ugly trick
15- ch_path = os .path .join (os .path .dirname (test_root ), "BuildLinux/ch" )
1639
17- if not os .path .isfile (ch_path ):
18- print "BuildLinux/ch not found. Did you run ./build.sh already?"
40+ test_root = os .path .dirname (os .path .realpath (__file__ ))
41+ repo_root = os .path .dirname (test_root )
42+
43+ # arch: x86, x64
44+ arch = 'x86' if args .x86 else ('x64' if args .x64 else None )
45+ if arch == None :
46+ arch = os .environ .get ('_BuildArch' , 'x86' )
47+
48+ # flavor: debug, test, release
49+ flavor = 'debug' if args .debug else ('test' if args .test else None )
50+ if flavor == None :
51+ flavor = {'chk' :'debug' , 'test' :'test' , 'fre' :'release' }\
52+ [os .environ .get ('_BuildType' , 'fre' )]
53+
54+ # binary: full ch path
55+ binary = args .binary
56+ if binary == None :
57+ if sys .platform == 'win32' :
58+ binary = os .path .join (repo_root ,
59+ 'Build/VcBuild/bin/{}_{}/ch.exe' .format (arch , flavor ))
60+ else :
61+ binary = os .path .join (repo_root , "BuildLinux/ch" )
62+ if not os .path .isfile (binary ):
63+ print '{} not found. Did you run ./build.sh already?' .format (binary )
1964 sys .exit (1 )
2065
21- if len (sys .argv ) > 1 :
22- if sys .argv [1 ] in ['-?' , '--help' ]:
23- print "ChakraCore *nix Test Script\n "
24-
25- print "Usage:"
26- print "test.py <optional test path>\n "
27-
28- print "-?, --help : Show help\n "
29-
30- print "Samples:"
31- print "test only Array:"
32- print "\t ./test.py Array\n "
33-
34- print "test a single file:"
35- print "\t ./test.py Basics/hello.js\n "
36-
37- print "test all folders:"
38- print "\t ./test.py"
39- sys .exit (0 )
40- test_all = None
41-
42- test_dirs = ['' ]
43- if test_all :
44- test_dirs = os .listdir (test_root )
45- else :
46- test_dirs [0 ] = sys .argv [1 ]
66+ pass_count = 0
67+ fail_count = 0
4768
4869def show_failed (filename , output , exit_code , expected_output ):
4970 print "\n Failed ->" , filename
@@ -58,7 +79,7 @@ def show_failed(filename, output, exit_code, expected_output):
5879 ln = min (len (lst_output ), len (lst_expected ))
5980 for i in range (0 , ln ):
6081 if lst_output [i ] != lst_expected [i ]:
61- print "Output: (at line " + str (i ) + ")"
82+ print "Output: (at line " + str (i ) + ")"
6283 print "----------------------------"
6384 print lst_output [i ]
6485 print "----------------------------"
@@ -69,52 +90,88 @@ def show_failed(filename, output, exit_code, expected_output):
6990 break
7091
7192 print "exit code:" , exit_code
72- print "\n Failed!"
73- sys .exit (exit_code )
74-
75- def test_path (folder , is_file ):
76- files = ['' ]
77- if is_file == False :
78- print "Testing ->" , os .path .basename (folder )
79- files = os .listdir (folder )
93+ global fail_count
94+ fail_count += 1
95+
96+ def test_path (path ):
97+ if os .path .isfile (path ):
98+ folder , file = os .path .dirname (path ), os .path .basename (path )
8099 else :
81- files [0 ] = folder
82-
83- for js_file in files :
84- if is_file or os .path .splitext (js_file )[1 ] == '.js' :
85- js_file = os .path .join (folder , js_file )
86- js_output = ""
87-
88- if not os .path .isfile (js_file ):
89- print "Javascript file doesn't exist (" + js_file + ")"
90- sys .exit (1 )
91-
92- p = SP .Popen ([ch_path , js_file ], stdout = SP .PIPE , stderr = SP .STDOUT , close_fds = True )
93- js_output = p .communicate ()[0 ].replace ('\r ' ,'' )
94- exit_code = p .wait ()
95-
96- if exit_code != 0 :
97- show_failed (js_file , js_output , exit_code , None )
98- else : #compare outputs
99- baseline = os .path .splitext (js_file )[0 ] + '.baseline'
100- baseline = os .path .join (folder , baseline )
101- if os .path .isfile (baseline ):
102- expected_output = None
103- with open (baseline , 'r' ) as bs_file :
104- expected_output = bs_file .read ().replace ('\r ' , '' )
105- # todo: compare line by line and use/implement wild cards support
106- # todo: by default we discard line endings (xplat), make this optional
107- if expected_output .replace ('\n ' , '' ) != js_output .replace ('\n ' , '' ):
108- show_failed (js_file , js_output , exit_code , expected_output )
109-
110- if not is_file :
111- print "\t Passed ->" , os .path .basename (js_file )
112-
113- is_file = len (test_dirs ) == 1 and os .path .splitext (test_dirs [0 ])[1 ] == '.js'
114-
115- for folder in test_dirs :
116- full_path = os .path .join (test_root , folder )
117- if os .path .isdir (full_path ) or is_file :
118- test_path (full_path , is_file )
119-
120- print 'Success!'
100+ folder , file = path , None
101+
102+ tests = load_tests (folder , file )
103+ if len (tests ) == 0 :
104+ return
105+
106+ print "Testing ->" , os .path .basename (folder )
107+ for test in tests :
108+ test_one (folder , test )
109+
110+ def test_one (folder , test ):
111+ js_file = os .path .join (folder , test ['files' ])
112+ js_output = ""
113+
114+ cmd = [x for x in [binary ,
115+ '-WERExceptionSupport' ,
116+ '-ExtendedErrorStackForTestHost' ,
117+ test .get ('compile-flags' ),
118+ js_file ] if x != None ]
119+ p = SP .Popen (cmd , stdout = SP .PIPE , stderr = SP .STDOUT )
120+ js_output = p .communicate ()[0 ].replace ('\r ' ,'' )
121+ exit_code = p .wait ()
122+
123+ if exit_code != 0 :
124+ return show_failed (js_file , js_output , exit_code , None )
125+ else : #compare outputs
126+ baseline = os .path .splitext (js_file )[0 ] + '.baseline'
127+ if os .path .isfile (baseline ):
128+ expected_output = None
129+ with open (baseline , 'r' ) as bs_file :
130+ expected_output = bs_file .read ().replace ('\r ' , '' )
131+ # todo: compare line by line and use/implement wild cards support
132+ # todo: by default we discard line endings (xplat), make this optional
133+ if expected_output .replace ('\n ' , '' ) != js_output .replace ('\n ' , '' ):
134+ return show_failed (js_file , js_output , exit_code , expected_output )
135+
136+ print "\t Passed ->" , os .path .basename (js_file )
137+ global pass_count
138+ pass_count += 1
139+
140+ def load_tests (folder , file ):
141+ try :
142+ xmlpath = os .path .join (folder , 'rlexe.xml' )
143+ xml = ET .parse (xmlpath ).getroot ()
144+ except IOError :
145+ return []
146+
147+ tests = [load_test (x ) for x in xml ]
148+ if file != None :
149+ tests = [x for x in tests if x ['files' ] == file ]
150+ if len (tests ) == 0 and is_jsfile (file ):
151+ tests = [{'files' :file }]
152+ return tests
153+
154+ def load_test (testXml ):
155+ test = dict ()
156+ for c in testXml .find ('default' ):
157+ test [c .tag ] = c .text
158+ return test
159+
160+ def is_jsfile (path ):
161+ return os .path .splitext (path )[1 ] == '.js'
162+
163+ def main ():
164+ # By default run all tests
165+ if len (args .folders ) == 0 :
166+ args .folders = [os .path .join (test_root , x )
167+ for x in sorted (os .listdir (test_root ))]
168+
169+ for folder in args .folders :
170+ test_path (folder )
171+
172+ print 'Passed:' , pass_count , 'Failed:' , fail_count
173+ print 'Success!' if fail_count == 0 else 'Failed!'
174+ return 0
175+
176+ if __name__ == '__main__' :
177+ sys .exit (main ())
0 commit comments