def test_emcc_multiprocess_cache_access(self): restore_and_set_up() create_file('test.c', r''' #include <stdio.h> int main() { printf("hello, world!\n"); return 0; } ''') cache_dir_name = self.in_dir('test_cache') libname = Cache.get_lib_name('libc.a') with env_modify({'EM_CACHE': cache_dir_name}): tasks = [] num_times_libc_was_built = 0 for i in range(3): p = self.run_process([EMCC, 'test.c', '-o', '%d.js' % i], stderr=STDOUT, stdout=PIPE) tasks += [p] for p in tasks: print('stdout:\n', p.stdout) if 'generating system library: ' + libname in p.stdout: num_times_libc_was_built += 1 # The cache directory must exist after the build self.assertExists(cache_dir_name) # The cache directory must contain a built libc self.assertExists(os.path.join(cache_dir_name, libname)) # Exactly one child process should have triggered libc build! self.assertEqual(num_times_libc_was_built, 1)
def test_wacky_env(self): restore_and_set_up() def build(): return self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '') def test(): self.assertContained('hello, world!', self.run_js('a.out.js')) print('normal build') with env_modify({'EMCC_FORCE_STDLIBS': None}): self.clear_cache() build() test() print('wacky env vars, these should not mess our bootstrapping') with env_modify({'EMCC_FORCE_STDLIBS': '1'}): self.clear_cache() build() test()
def test_cache_clearing_auto(self): # Changing LLVM_ROOT, even without altering .emscripten, clears the cache restore_and_set_up() self.ensure_cache() make_fake_clang(self.in_dir('fake', 'bin', 'clang'), EXPECTED_LLVM_VERSION) make_fake_llc(self.in_dir('fake', 'bin', 'llc'), 'got wasm32 backend! WebAssembly 32-bit') with env_modify({'EM_LLVM_ROOT': self.in_dir('fake', 'bin')}): self.assertExists(Cache.dirname) output = self.do([EMCC]) self.assertIn('clearing cache', output) self.assertCacheEmpty()
def test_emcc(self): SANITY_FAIL_MESSAGE = 'sanity check failed to run' # emcc should check sanity if no ${EM_CONFIG}_sanity restore_and_set_up() time.sleep(1) assert not os.path.exists( SANITY_FILE) # restore is just the settings, not the sanity output = self.check_working(EMCC) self.assertContained(SANITY_MESSAGE, output) # EMCC should have checked sanity successfully old_sanity = open(SANITY_FILE).read() self.assertNotContained(SANITY_FAIL_MESSAGE, output) # emcc run again should not sanity check, because the sanity file is newer output = self.check_working(EMCC) self.assertNotContained(SANITY_MESSAGE, output) self.assertNotContained(SANITY_FAIL_MESSAGE, output) # incorrect sanity contents mean we *must* check open(SANITY_FILE, 'w').write('wakawaka') output = self.check_working(EMCC) self.assertContained(SANITY_MESSAGE, output) # correct sanity contents mean we need not check open(SANITY_FILE, 'w').write(old_sanity) output = self.check_working(EMCC) self.assertNotContained(SANITY_MESSAGE, output) # but with EMCC_DEBUG=1 we should check with env_modify({'EMCC_DEBUG': '1'}): output = self.check_working(EMCC) try_delete(CANONICAL_TEMP_DIR) self.assertContained(SANITY_MESSAGE, output) output = self.check_working(EMCC) self.assertNotContained(SANITY_MESSAGE, output) # Make sure the test runner didn't do anything to the setup output = self.check_working(EMCC) self.assertNotContained(SANITY_MESSAGE, output) self.assertNotContained(SANITY_FAIL_MESSAGE, output) # emcc should also check sanity if the file is outdated open(EM_CONFIG, 'a').write('# extra stuff\n') output = self.check_working(EMCC) self.assertContained(SANITY_MESSAGE, output) self.assertNotContained(SANITY_FAIL_MESSAGE, output)
def test_em_config_env_var(self): # emcc should be configurable directly from EM_CONFIG without any config file restore_and_set_up() create_file('main.cpp', ''' #include <stdio.h> int main() { printf("hello from emcc with no config file\\n"); return 0; } ''') wipe() with env_modify({'EM_CONFIG': get_basic_config()}): out = self.expect_fail([EMCC, 'main.cpp', '-Wno-deprecated', '-o', 'a.out.js']) self.assertContained('error: Inline EM_CONFIG data no longer supported. Please use a config file.', out)
def test_with_fake(report, expected): make_fake(report) with env_modify({'EMCC_DEBUG': '1'}): self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], expected)
def test_firstrun(self): for command in commands: wipe() default_config = config.embedded_config try: temp_bin = tempfile.mkdtemp() def make_new_executable(name): open(os.path.join(temp_bin, name), 'w').close() make_executable(os.path.join(temp_bin, name)) make_new_executable('llvm-dis') make_new_executable('node') with env_modify({'PATH': temp_bin + os.pathsep + os.environ['PATH']}): output = self.do(command) finally: shutil.rmtree(temp_bin) config_data = open(default_config).read() try_delete(default_config) self.assertContained('Welcome to Emscripten!', output) self.assertContained('This is the first time any of the Emscripten tools has been run.', output) self.assertContained('A settings file has been copied to %s, at absolute path: %s' % (default_config, default_config), output) self.assertContained('It contains our best guesses for the important paths, which are:', output) self.assertContained('LLVM_ROOT', output) self.assertContained('NODE_JS', output) if platform.system() != 'Windows': # os.chmod can't make files executable on Windows self.assertIdentical(temp_bin, re.search("^ *LLVM_ROOT *= (.*)$", output, re.M).group(1)) possible_nodes = [os.path.join(temp_bin, 'node')] if os.path.exists('/usr/bin/nodejs'): possible_nodes.append('/usr/bin/nodejs') self.assertIdentical(possible_nodes, re.search("^ *NODE_JS *= (.*)$", output, re.M).group(1)) self.assertContained('Please edit the file if any of those are incorrect', output) self.assertContained('This command will now exit. When you are done editing those paths, re-run it.', output) self.assertTrue(output.strip().endswith('=============')) template_file = Path(path_from_root('tools/settings_template.py')).read_text() self.assertNotContained('{{{', config_data) self.assertNotContained('}}}', config_data) self.assertContained('{{{', template_file) self.assertContained('}}}', template_file) for content in ['EMSCRIPTEN_ROOT', 'LLVM_ROOT', 'NODE_JS', 'JS_ENGINES']: self.assertContained(content, config_data) # The guessed config should be ok # XXX This depends on your local system! it is possible `which` guesses wrong # try_delete('a.out.js') # output = self.run_process([EMCC, test_file('hello_world.c')], stdout=PIPE, stderr=PIPE).output # self.assertContained('hello, world!', self.run_js('a.out.js'), output) # Second run, with bad EM_CONFIG for settings in ['blah', 'LLVM_ROOT="blarg"; JS_ENGINES=[]; NODE_JS=[]; SPIDERMONKEY_ENGINE=[]']: try: with open(default_config, 'w') as f: f.write(settings) output = self.do(command) if 'blah' in settings: self.assertContained('Error in evaluating config file (%s)' % default_config, output) elif 'runner' not in ' '.join(command): self.assertContained('error: NODE_JS is set to empty value', output) # sanity check should fail finally: try_delete(default_config)