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