X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=integration_tests.py;h=25550f61f5f4b2c63c078d32fe8056677ef0866b;hp=ddf444b3d5ff9803373b3f8c81521adf8e32c810;hb=7abf5e459b2ef02c8e59c05f0a83d8213ade0427;hpb=6c2894f00c8daca3d85c7ce850da711b9f7effc5 diff --git a/integration_tests.py b/integration_tests.py index ddf444b..25550f6 100644 --- a/integration_tests.py +++ b/integration_tests.py @@ -3,7 +3,8 @@ import os.path import subprocess import unittest -EXAMPLES_PATH = os.path.join(os.path.dirname(__file__), 'examples') +# Go to the directory of the current file so we know where we are in the filesystem +os.chdir(os.path.dirname(os.path.abspath(__file__))) class OutputTests(unittest.TestCase): pass @@ -13,7 +14,7 @@ def add_example_output_test(filename): compile_fur_to_c_result = subprocess.call([ 'python', 'main.py', - os.path.join(EXAMPLES_PATH, filename), + os.path.join('examples', filename), ]) if compile_fur_to_c_result != 0: @@ -21,29 +22,109 @@ def add_example_output_test(filename): compile_c_to_executable_result = subprocess.call([ 'gcc', - os.path.join(EXAMPLES_PATH, filename + '.c'), + os.path.join('examples', filename + '.c'), ]) if compile_c_to_executable_result != 0: raise Exception('Example output "{}" did not compile'.format(filename + '.c')) - actual_output = subprocess.check_output(['./a.out']) + try: + p = subprocess.Popen('./a.out', stdout=subprocess.PIPE, stderr=subprocess.PIPE) + actual_stdout, actual_stderr = p.communicate() - with open(os.path.join(EXAMPLES_PATH, filename + '.output.txt'), 'rb') as f: - expected_output = f.read() + expected_stdout_path = os.path.join('examples', filename + '.stdout.txt') - self.assertEqual(expected_output, actual_output) + if os.path.isfile(expected_stdout_path): + with open(expected_stdout_path, 'rb') as f: + expected_stdout = f.read() + else: + expected_stdout = b'' + + expected_stderr_path = os.path.join('examples', filename + '.stderr.txt') + + if os.path.isfile(expected_stderr_path): + with open(expected_stderr_path, 'rb') as f: + expected_stderr = f.read() + else: + expected_stderr = b'' + + self.assertEqual(expected_stderr, actual_stderr) + + # We don't clean up the C file in the finally clause because it can be useful to have in case of errors + os.remove(os.path.join('examples', filename + '.c')) + + finally: + try: + os.remove('a.out') + except OSError: + pass setattr(OutputTests, 'test_' + filename, test) +class MemoryLeakTests(unittest.TestCase): + pass + +def add_example_memory_leak_test(filename): + def test(self): + compile_fur_to_c_result = subprocess.call([ + 'python', + 'main.py', + os.path.join('examples', filename), + ]) + + if compile_fur_to_c_result != 0: + raise Exception('Example "{}" did not compile'.format(filename)) + + compile_c_to_executable_result = subprocess.call([ + 'gcc', + '-ggdb3', + os.path.join('examples', filename + '.c'), + ]) + + if compile_c_to_executable_result != 0: + raise Exception('Example output "{}" did not compile'.format(filename + '.c')) + + try: + with open(os.devnull, 'w') as devnull: + expected_return = 0 + actual_return = subprocess.call( + [ + 'valgrind', + '--tool=memcheck', + '--leak-check=yes', + '--show-reachable=yes', + '--num-callers=20', + '--track-fds=yes', + '--error-exitcode=42', + '-q', + './a.out', + ], + stdout=devnull, + stderr=devnull, + ) + + self.assertEqual(expected_return, actual_return) + + # We don't clean up the C file in the finally clause because it can be useful to have in case of errors + os.remove(os.path.join('examples', filename + '.c')) + + finally: + try: + os.remove('a.out') + except OSError: + pass + + setattr(MemoryLeakTests, 'test_' + filename, test) + filenames = ( entry.name - for entry in os.scandir(EXAMPLES_PATH) + for entry in os.scandir('examples') if entry.is_file() if entry.name.endswith('.fur') ) for filename in filenames: add_example_output_test(filename) + add_example_memory_leak_test(filename) unittest.main()