From 36779c0500ac77fbd5e442e98b2971bd3b321ff4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 30 Jan 2019 12:16:15 +0530 Subject: unit tests: Run native file tests on the CI The native file tests were never run on the CI since they were skipped on Windows and also skipped on Linux and macOS since CC/CXX/etc are always set by the CI. Also fix test failure on macOS. The test was assuming that because /usr/bin/gcc and /usr/bin/clang exist on macOS, they must be different compilers. They're not. gcc is just a wrapper around clang, and we correctly detect it as such. --- run_unittests.py | 55 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 16de56549..8c4093bed 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -104,6 +104,16 @@ def _git_init(project_dir): subprocess.check_call(['git', 'commit', '-a', '-m', 'I am a project'], cwd=project_dir, stdout=subprocess.DEVNULL) +@functools.lru_cache() +def is_real_gnu_compiler(path): + ''' + Check if the gcc we have is a real gcc and not a macOS wrapper around clang + ''' + if not path: + return False + out = subprocess.check_output([path, '--version'], universal_newlines=True, stderr=subprocess.STDOUT) + return 'Free Software Foundation' in out + def skipIfNoExecutable(exename): ''' Skip this test if the given executable is not found. @@ -165,14 +175,23 @@ def skip_if_not_language(lang): return wrapped return wrapper -def skip_if_env_value(value): +def skip_if_env_set(key): + ''' + Skip a test if a particular env is set, except when running under CI + ''' def wrapper(func): @functools.wraps(func) def wrapped(*args, **kwargs): - if value in os.environ: - raise unittest.SkipTest( - 'Environment variable "{}" set, skipping.'.format(value)) - return func(*args, **kwargs) + old = None + if key in os.environ: + if not is_ci(): + raise unittest.SkipTest('Env var {!r} set, skipping'.format(key)) + old = os.environ.pop(key) + try: + return func(*args, **kwargs) + finally: + if old is not None: + os.environ[key] = old return wrapped return wrapper @@ -5217,59 +5236,59 @@ class NativeFileTests(BasePlatformTests): self._simple_test('python', 'python') @unittest.skipIf(is_windows(), 'Setting up multiple compilers on windows is hard') - @skip_if_env_value('CC') + @skip_if_env_set('CC') def test_c_compiler(self): def cb(comp): if comp.id == 'gcc': if not shutil.which('clang'): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'clang', 'clang' - if not shutil.which('gcc'): + if not is_real_gnu_compiler(shutil.which('gcc')): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'gcc', 'gcc' self.helper_for_compiler('c', cb) @unittest.skipIf(is_windows(), 'Setting up multiple compilers on windows is hard') - @skip_if_env_value('CXX') + @skip_if_env_set('CXX') def test_cpp_compiler(self): def cb(comp): if comp.id == 'gcc': if not shutil.which('clang++'): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'clang++', 'clang' - if not shutil.which('g++'): + if not is_real_gnu_compiler(shutil.which('g++')): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'g++', 'gcc' self.helper_for_compiler('cpp', cb) @skip_if_not_language('objc') - @skip_if_env_value('OBJC') + @skip_if_env_set('OBJC') def test_objc_compiler(self): def cb(comp): if comp.id == 'gcc': if not shutil.which('clang'): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'clang', 'clang' - if not shutil.which('gcc'): + if not is_real_gnu_compiler(shutil.which('gcc')): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'gcc', 'gcc' self.helper_for_compiler('objc', cb) @skip_if_not_language('objcpp') - @skip_if_env_value('OBJCXX') + @skip_if_env_set('OBJCXX') def test_objcpp_compiler(self): def cb(comp): if comp.id == 'gcc': if not shutil.which('clang++'): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'clang++', 'clang' - if not shutil.which('g++'): + if not is_real_gnu_compiler(shutil.which('g++')): raise unittest.SkipTest('Only one compiler found, cannot test.') return 'g++', 'gcc' self.helper_for_compiler('objcpp', cb) @skip_if_not_language('d') - @skip_if_env_value('DC') + @skip_if_env_set('DC') def test_d_compiler(self): def cb(comp): if comp.id == 'dmd': @@ -5285,7 +5304,7 @@ class NativeFileTests(BasePlatformTests): self.helper_for_compiler('d', cb) @skip_if_not_language('cs') - @skip_if_env_value('CSC') + @skip_if_env_set('CSC') def test_cs_compiler(self): def cb(comp): if comp.id == 'csc': @@ -5298,7 +5317,7 @@ class NativeFileTests(BasePlatformTests): self.helper_for_compiler('cs', cb) @skip_if_not_language('fortran') - @skip_if_env_value('FC') + @skip_if_env_set('FC') def test_fortran_compiler(self): def cb(comp): if comp.id == 'gcc': @@ -5331,13 +5350,13 @@ class NativeFileTests(BasePlatformTests): self.assertEqual(compiler.version, version) @skip_if_not_language('vala') - @skip_if_env_value('VALAC') + @skip_if_env_set('VALAC') def test_vala_compiler(self): self._single_implementation_compiler( 'vala', 'valac', 'Vala 1.2345', '1.2345') @skip_if_not_language('rust') - @skip_if_env_value('RUSTC') + @skip_if_env_set('RUSTC') def test_rust_compiler(self): self._single_implementation_compiler( 'rust', 'rustc', 'rustc 1.2345', '1.2345') -- cgit v1.2.3