Prevent assignment to a builtin variable
[fur] / integration_tests.py
1 import os
2 import os.path
3 import subprocess
4 import unittest
5
6 # Go to the directory of the current file so we know where we are in the filesystem
7 os.chdir(os.path.dirname(os.path.abspath(__file__)))
8
9 class OutputTests(unittest.TestCase):
10     pass
11
12 def add_example_output_test(filename):
13     def test(self):
14         compile_fur_to_c_result = subprocess.call([
15             'python',
16             'main.py',
17             os.path.join('examples', filename),
18         ])
19
20         if compile_fur_to_c_result != 0:
21             raise Exception('Example "{}" did not compile'.format(filename))
22
23         compile_c_to_executable_result = subprocess.call([
24             'gcc',
25             os.path.join('examples', filename + '.c'),
26         ])
27
28         if compile_c_to_executable_result != 0:
29             raise Exception('Example output "{}" did not compile'.format(filename + '.c'))
30
31         try:
32             actual_output = subprocess.check_output(['./a.out'])
33
34             with open(os.path.join('examples', filename + '.output.txt'), 'rb') as f:
35                 expected_output = f.read()
36
37             self.assertEqual(expected_output, actual_output)
38
39             # We don't clean up the C file in the finally clause because it can be useful to have in case of errors
40             os.remove(os.path.join('examples', filename + '.c'))
41
42         finally:
43             try:
44                 os.remove('a.out')
45             except OSError:
46                 pass
47
48     setattr(OutputTests, 'test_' + filename, test)
49
50 class MemoryLeakTest(unittest.TestCase):
51     pass
52
53 def add_example_memory_leak_test(filename):
54     def test(self):
55         compile_fur_to_c_result = subprocess.call([
56             'python',
57             'main.py',
58             os.path.join('examples', filename),
59         ])
60
61         if compile_fur_to_c_result != 0:
62             raise Exception('Example "{}" did not compile'.format(filename))
63
64         compile_c_to_executable_result = subprocess.call([
65             'gcc',
66             '-ggdb3',
67             os.path.join('examples', filename + '.c'),
68         ])
69
70         if compile_c_to_executable_result != 0:
71             raise Exception('Example output "{}" did not compile'.format(filename + '.c'))
72
73         try:
74             with open(os.devnull, 'w') as devnull:
75                 expected_return = 0
76                 actual_return = subprocess.call(
77                     [
78                         'valgrind',
79                         '--tool=memcheck',
80                         '--leak-check=yes',
81                         '--show-reachable=yes',
82                         '--num-callers=20',
83                         '--track-fds=yes',
84                         '--error-exitcode=666',
85                         '-q',
86                         './a.out',
87                     ],
88                     stdout=devnull,
89                     stderr=devnull,
90                 )
91
92                 self.assertEqual(expected_return, actual_return)
93
94                 # We don't clean up the C file in the finally clause because it can be useful to have in case of errors
95                 os.remove(os.path.join('examples', filename + '.c'))
96
97         finally:
98             try:
99                 os.remove('a.out')
100             except OSError:
101                 pass
102
103     setattr(MemoryLeakTest, 'test_' + filename, test)
104
105 filenames = (
106     entry.name
107     for entry in os.scandir('examples')
108     if entry.is_file()
109     if entry.name.endswith('.fur')
110 )
111
112 for filename in filenames:
113     add_example_output_test(filename)
114     add_example_memory_leak_test(filename)
115
116 unittest.main()