Reactos
1import subprocess
2import os
3import tempfile
4import sys
5import difflib
6
7# ${_spec_file} = ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
8# spec2def -n=${_dllname} -a=${ARCH} ${ARGN} --implib -d=${BIN_PATH}/${_libname}_implib.def ${_spec_file}
9# spec2def -n=${_dllname} -a=${ARCH} -d=${BIN_PATH}/${_file}.def -s=${BIN_PATH}/${_file}_stubs.c ${__with_relay_arg} ${__version_arg} ${_spec_file}
10# spec2def --ms -a=${_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} ${_spec_file}
11# spec2def --ms -a=${ARCH} -n=${_dllname} -d=${BIN_PATH}/${_file}.def -s=${BIN_PATH}/${_file}_stubs.c ${__with_relay_arg} ${__version_arg} ${_spec_file}
12
13SCRIPT_DIR = os.path.dirname(__file__)
14SPEC_FILE = os.path.join(SCRIPT_DIR, 'test.spec')
15DATA_DIR = os.path.join(SCRIPT_DIR, 'testdata')
16
17class ResultFile:
18 def __init__(self, datadir, filename):
19 self.filename = filename
20 with open(os.path.join(datadir, filename), 'r') as content:
21 self.data = content.read()
22
23 def normalize(self):
24 data = self.data.splitlines()
25 data = [line for line in data if line]
26 return '\n'.join(data)
27
28
29class TestCase:
30 def __init__(self, spec_args, prefix):
31 self.spec_args = spec_args
32 self.prefix = prefix
33 self.expect_files = []
34 self.result_files = []
35 self.stdout = self.stderr = None
36 self.returncode = None
37
38 def run(self, cmd, tmpdir, all_datafiles):
39 datafiles = [filename for filename in all_datafiles if filename.startswith(self.prefix)]
40 self.expect_files = [ResultFile(DATA_DIR, datafile) for datafile in datafiles]
41 tmppath = os.path.join(tmpdir, self.prefix)
42 args = [elem.replace('$tmp$', tmppath) for elem in self.spec_args]
43 args = [cmd] + args + [SPEC_FILE]
44 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
45 self.stdout, self.stderr = proc.communicate()
46 self.returncode = proc.returncode
47 self.result_files = [ResultFile(tmpdir, tmpfile) for tmpfile in os.listdir(tmpdir)]
48
49 def verify(self):
50 if False:
51 for result in self.result_files:
52 with open(os.path.join(DATA_DIR, result.filename), 'w') as content:
53 content.write(result.data)
54 return
55
56 if self.returncode != 0:
57 print('Failed return code', self.returncode, 'for', self.prefix)
58 return
59 self.expect_files.sort(key= lambda elem: elem.filename)
60 self.result_files.sort(key= lambda elem: elem.filename)
61 exp_len = len(self.expect_files)
62 res_len = len(self.result_files)
63 if exp_len != res_len:
64 print('Not enough files for', self.prefix, 'got:', res_len, 'wanted:', exp_len)
65 return
66
67 for n in range(len(self.expect_files)):
68 exp = self.expect_files[n]
69 res = self.result_files[n]
70 if exp.normalize() == res.normalize():
71 # Content 100% the same, ignoring empty newlines
72 continue
73
74 exp_name = 'expected/' + exp.filename
75 res_name = 'output/' + res.filename
76 exp = exp.data.splitlines()
77 res = res.data.splitlines()
78 diff = difflib.unified_diff(exp, res, fromfile=exp_name, tofile=res_name, lineterm='')
79 for line in diff:
80 print(line)
81
82
83TEST_CASES = [
84 # GCC implib
85 TestCase([ '-n=testdll.xyz', '-a=i386', '--implib', '-d=$tmp$test.def', '--no-private-warnings' ], '01-'),
86 TestCase([ '-n=testdll.xyz', '-a=x86_64', '--implib', '-d=$tmp$test.def', '--no-private-warnings' ], '02-'),
87 # GCC normal
88 TestCase([ '-n=testdll.xyz', '-a=i386', '-d=$tmp$test.def', '-s=$tmp$stubs.c' ], '03-'),
89 TestCase([ '-n=testdll.xyz', '-a=x86_64', '-d=$tmp$test.def', '-s=$tmp$stubs.c' ], '04-'),
90 TestCase([ '-n=testdll.xyz', '-a=i386', '-d=$tmp$test.def', '-s=$tmp$stubs.c', '--with-tracing' ], '05-'),
91 # MSVC implib
92 TestCase([ '--ms', '-n=testdll.xyz', '-a=i386', '--implib', '-d=$tmp$test.def', '-l=$tmp$stubs.asm' ], '06-'),
93 TestCase([ '--ms', '-n=testdll.xyz', '-a=x86_64', '--implib', '-d=$tmp$test.def', '-l=$tmp$stubs.asm' ], '07-'),
94 # MSVC normal
95 TestCase([ '--ms', '-n=testdll.xyz', '-a=i386', '-d=$tmp$test.def', '-s=$tmp$stubs.c' ], '08-'),
96 TestCase([ '--ms', '-n=testdll.xyz', '-a=x86_64', '-d=$tmp$test.def', '-s=$tmp$stubs.c' ], '09-'),
97 TestCase([ '--ms', '-n=testdll.xyz', '-a=i386', '-d=$tmp$test.def', '-s=$tmp$stubs.c', '--with-tracing' ], '10-'),
98]
99
100
101def run_test(testcase, cmd, all_files):
102 with tempfile.TemporaryDirectory() as tmpdirname:
103 testcase.run(cmd, tmpdirname, all_files)
104 testcase.verify()
105
106def main(args):
107 cmd = args[0] if args else 'spec2def'
108 all_files = os.listdir(DATA_DIR)
109 for testcase in TEST_CASES:
110 run_test(testcase, cmd, all_files)
111
112if __name__ == '__main__':
113 main(sys.argv[1:])