Skip to content

[test] Add @with_both_compilers decorator. NFC #20751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 58 additions & 43 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,18 @@ def decorated(self):
return decorated


def with_both_compilers(f):
assert callable(f)

f._parameterize = {'': (EMCC,),
'emxx': (EMXX,)}
return f


def also_with_wasmfs(f):
assert callable(f)

@wraps(f)
def metafunc(self, wasmfs):
if wasmfs:
self.set_setting('WASMFS')
Expand All @@ -107,6 +118,9 @@ def metafunc(self, backend):


def also_with_wasmfs_all_backends(f):
assert callable(f)

@wraps(f)
def metafunc(self, backend):
if backend:
self.set_setting('WASMFS')
Expand Down Expand Up @@ -243,20 +257,20 @@ def parse_wasm(self, filename):
# This needs to work because many tools run `emcc -v` internally and it should
# always work even if the user has `EMCC_CFLAGS` set.
@with_env_modify({'EMCC_CFLAGS': '-should -be -ignored'})
@with_both_compilers
@crossplatform
def test_emcc_v(self):
for compiler in [EMCC, EMXX]:
# -v, without input files
proc = self.run_process([compiler, '-v'], stdout=PIPE, stderr=PIPE)
self.assertEqual(proc.stdout, '')
# assert that the emcc message comes first. We had a bug where the sub-process output
# from clang would be flushed to stderr first.
self.assertContained('emcc (Emscripten gcc/clang-like replacement', proc.stderr)
self.assertTrue(proc.stderr.startswith('emcc (Emscripten gcc/clang-like replacement'))
self.assertContained('clang version ', proc.stderr)
self.assertContained('GNU', proc.stderr)
self.assertContained('Target: wasm32-unknown-emscripten', proc.stderr)
self.assertNotContained('this is dangerous', proc.stderr)
def test_emcc_v(self, compiler):
# -v, without input files
proc = self.run_process([compiler, '-v'], stdout=PIPE, stderr=PIPE)
self.assertEqual(proc.stdout, '')
# assert that the emcc message comes first. We had a bug where the sub-process output
# from clang would be flushed to stderr first.
self.assertContained('emcc (Emscripten gcc/clang-like replacement', proc.stderr)
self.assertTrue(proc.stderr.startswith('emcc (Emscripten gcc/clang-like replacement'))
self.assertContained('clang version ', proc.stderr)
self.assertContained('GNU', proc.stderr)
self.assertContained('Target: wasm32-unknown-emscripten', proc.stderr)
self.assertNotContained('this is dangerous', proc.stderr)

def test_log_subcommands(self):
# `-v` when combined with other arguments will trace the subcommands
Expand All @@ -281,16 +295,16 @@ def test_emcc_check(self):
proc = self.run_process([EMCC, '--check'], stdout=PIPE, stderr=PIPE)
self.assertContained('Running sanity checks', proc.stderr)

def test_emcc_generate_config(self):
@with_both_compilers
def test_emcc_generate_config(self, compiler):
config_path = './emscripten_config'
with env_modify({'EM_CONFIG': config_path}):
for compiler in [EMCC, EMXX]:
self.assertNotExists(config_path)
self.run_process([compiler, '--generate-config'])
self.assertExists(config_path)
config_contents = read_file(config_path)
self.assertContained('LLVM_ROOT', config_contents)
os.remove(config_path)
self.assertNotExists(config_path)
self.run_process([compiler, '--generate-config'])
self.assertExists(config_path)
config_contents = read_file(config_path)
self.assertContained('LLVM_ROOT', config_contents)
os.remove(config_path)

@parameterized({
'': ([],),
Expand Down Expand Up @@ -385,7 +399,8 @@ def test_emcc_out_file(self):

@parameterized({
'c': [EMCC, '.c'],
'cxx': [EMXX, '.cpp']})
'cxx': [EMXX, '.cpp'],
})
def test_emcc_basics(self, compiler, suffix):
# emcc src.cpp ==> writes a.out.js and a.out.wasm
self.run_process([compiler, test_file('hello_world' + suffix)])
Expand Down Expand Up @@ -1050,23 +1065,23 @@ def verify_includes(stderr):
err = self.run_process([EMXX, test_file('hello_world.cpp'), '-v'], stderr=PIPE).stderr
verify_includes(err)

def test_failure_error_code(self):
for compiler in [EMCC, EMXX]:
# Test that if one file is missing from the build, then emcc shouldn't succeed, and shouldn't produce an output file.
self.expect_fail([compiler, test_file('hello_world.c'), 'this_file_is_missing.c', '-o', 'out.js'])
self.assertFalse(os.path.exists('out.js'))
@with_both_compilers
def test_failure_error_code(self, compiler):
# Test that if one file is missing from the build, then emcc shouldn't succeed, and shouldn't produce an output file.
self.expect_fail([compiler, test_file('hello_world.c'), 'this_file_is_missing.c', '-o', 'out.js'])
self.assertFalse(os.path.exists('out.js'))

def test_failure_modularize_and_catch_rejection(self):
for compiler in [EMCC, EMXX]:
# Test that if sMODULARIZE and sNODEJS_CATCH_REJECTION are both enabled, then emcc shouldn't succeed, and shouldn't produce an output file.
self.expect_fail([compiler, test_file('hello_world.c'), '-sMODULARIZE', '-sNODEJS_CATCH_REJECTION', '-o', 'out.js'])
self.assertFalse(os.path.exists('out.js'))
@with_both_compilers
def test_failure_modularize_and_catch_rejection(self, compiler):
# Test that if sMODULARIZE and sNODEJS_CATCH_REJECTION are both enabled, then emcc shouldn't succeed, and shouldn't produce an output file.
self.expect_fail([compiler, test_file('hello_world.c'), '-sMODULARIZE', '-sNODEJS_CATCH_REJECTION', '-o', 'out.js'])
self.assertFalse(os.path.exists('out.js'))

def test_failure_modularize_and_catch_exit(self):
for compiler in [EMCC, EMXX]:
# Test that if sMODULARIZE and sNODEJS_CATCH_EXIT are both enabled, then emcc shouldn't succeed, and shouldn't produce an output file.
self.expect_fail([compiler, test_file('hello_world.c'), '-sMODULARIZE', '-sNODEJS_CATCH_EXIT', '-o', 'out.js'])
self.assertFalse(os.path.exists('out.js'))
@with_both_compilers
def test_failure_modularize_and_catch_exit(self, compiler):
# Test that if sMODULARIZE and sNODEJS_CATCH_EXIT are both enabled, then emcc shouldn't succeed, and shouldn't produce an output file.
self.expect_fail([compiler, test_file('hello_world.c'), '-sMODULARIZE', '-sNODEJS_CATCH_EXIT', '-o', 'out.js'])
self.assertFalse(os.path.exists('out.js'))

def test_use_cxx(self):
create_file('empty_file', ' ')
Expand All @@ -1075,18 +1090,18 @@ def test_use_cxx(self):
dash_xcpp = self.run_process([EMCC, '-v', '-xc++', 'empty_file'], stderr=PIPE).stderr
self.assertContained('-x c++', dash_xcpp)

def test_cxx11(self):
@with_both_compilers
def test_cxx11(self, compiler):
for std in ['-std=c++11', '--std=c++11']:
for compiler in [EMCC, EMXX]:
self.run_process([compiler, std, test_file('hello_cxx11.cpp')])
self.run_process([compiler, std, test_file('hello_cxx11.cpp')])

# Regression test for issue #4522: Incorrect CC vs CXX detection
def test_incorrect_c_detection(self):
@with_both_compilers
def test_incorrect_c_detection(self, compiler):
# This auto-detection only works for the compile phase.
# For linking you need to use `em++` or pass `-x c++`
create_file('test.c', 'foo\n')
for compiler in [EMCC, EMXX]:
self.run_process([compiler, '-c', '-lembind', '--embed-file', 'test.c', test_file('hello_world.cpp')])
self.run_process([compiler, '-c', '-lembind', '--embed-file', 'test.c', test_file('hello_world.cpp')])

def test_odd_suffixes(self):
for suffix in ['CPP', 'c++', 'C++', 'cxx', 'CXX', 'cc', 'CC']:
Expand Down