Пример #1
0
  def test_emcc_caching(self):
    INCLUDING_MESSAGE = 'including X'
    BUILDING_MESSAGE = 'building X for cache'
    ERASING_MESSAGE = 'clearing cache'

    EMCC_CACHE = Cache.dirname

    restore_and_set_up()

    Cache.erase()
    assert not os.path.exists(EMCC_CACHE)

    with env_modify({'EMCC_DEBUG': '1'}):
      # Building a file that *does* need something *should* trigger cache
      # generation, but only the first time
      for filename, libname in [('hello_libcxx.cpp', 'libcxx')]:
        for i in range(3):
          print(filename, libname, i)
          self.clear()
          output = self.do([EMCC, '-O' + str(i), '-s', '--llvm-lto', '0', path_from_root('tests', filename), '--save-bc', 'a.bc', '-s', 'DISABLE_EXCEPTION_CATCHING=0'])
          # print '\n\n\n', output
          assert INCLUDING_MESSAGE.replace('X', libname) in output
          if libname == 'libc':
            assert INCLUDING_MESSAGE.replace('X', 'libcxx') not in output # we don't need libcxx in this code
          else:
            assert INCLUDING_MESSAGE.replace('X', 'libc') in output # libcxx always forces inclusion of libc
          assert (BUILDING_MESSAGE.replace('X', libname) in output) == (i == 0), 'Must only build the first time'
          self.assertContained('hello, world!', run_js('a.out.js'))
          assert os.path.exists(EMCC_CACHE)
          full_libname = libname + '.bc' if libname != 'libcxx' else libname + '.a'
          assert os.path.exists(os.path.join(EMCC_CACHE, full_libname))

    try_delete(CANONICAL_TEMP_DIR)
    restore_and_set_up()

    def ensure_cache():
      self.do([PYTHON, EMCC, '-O2', path_from_root('tests', 'hello_world.c')])

    # Manual cache clearing
    ensure_cache()
    self.assertTrue(os.path.exists(EMCC_CACHE))
    output = self.do([PYTHON, EMCC, '--clear-cache'])
    self.assertIn(ERASING_MESSAGE, output)
    self.assertFalse(os.path.exists(EMCC_CACHE))
    self.assertIn(SANITY_MESSAGE, output)

    # Changing LLVM_ROOT, even without altering .emscripten, clears the cache
    ensure_cache()
    with env_modify({'LLVM': 'waka'}):
      self.assertTrue(os.path.exists(EMCC_CACHE))
      output = self.do([PYTHON, EMCC])
      self.assertIn(ERASING_MESSAGE, output)
      self.assertFalse(os.path.exists(EMCC_CACHE))
Пример #2
0
 def test_with_fake(report, expected):
     make_fake(report)
     with env_modify({'EMCC_DEBUG': '1'}):
         output = self.check_working([EMCC] + MINIMAL_HELLO_WORLD +
                                     ['-c'], expected)
         self.assertContained(
             'config file changed since we checked vanilla', output)
Пример #3
0
    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)
Пример #4
0
  def test_llvm(self):
    LLVM_WARNING = 'LLVM version appears incorrect'

    restore_and_set_up()

    # Clang should report the version number we expect, and emcc should not warn
    assert shared.check_llvm_version()
    output = self.check_working(EMCC)
    self.assertNotContained(LLVM_WARNING, output)

    # Fake a different llvm version
    restore_and_set_up()
    with open(config_file, 'a') as f:
      f.write('LLVM_ROOT = "' + self.in_dir('fake') + '"')

    real_version_x, real_version_y = (int(x) for x in EXPECTED_LLVM_VERSION.split('.'))
    make_fake_llc(self.in_dir('fake', 'llc'), 'wasm32 - WebAssembly 32-bit')
    make_fake_lld(self.in_dir('fake', 'wasm-ld'))

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      for inc_x in range(-2, 3):
        for inc_y in range(-2, 3):
          expected_x = real_version_x + inc_x
          expected_y = real_version_y + inc_y
          if expected_x < 0 or expected_y < 0:
            continue # must be a valid llvm version
          print("mod LLVM version: %d %d -> %d %d" % (real_version_x, real_version_x, expected_x, expected_y))
          make_fake_clang(self.in_dir('fake', 'clang'), '%s.%s' % (expected_x, expected_y))
          did_modify = inc_x != 0 or inc_y != 0
          if did_modify:
            output = self.check_working(EMCC, LLVM_WARNING)
          else:
            output = self.check_working(EMCC)
            self.assertNotContained(LLVM_WARNING, output)
Пример #5
0
  def test_js_engine_path(self):
    # Test that running JS commands works for node, d8, and jsc and is not path dependent
    restore_and_set_up()

    sample_script = path_from_root('tests', 'print_args.js')

    # Fake some JS engines
    # Note that the path contains 'd8'.
    test_path = self.in_dir('fake', 'abcd8765')
    ensure_dir(test_path)

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      jsengines = [('d8',     V8_ENGINE),
                   ('d8_g',   V8_ENGINE),
                   ('js',     SPIDERMONKEY_ENGINE),
                   ('node',   NODE_JS),
                   ('nodejs', NODE_JS)]
      for filename, engine in jsengines:
        if type(engine) is list:
          engine = engine[0]
        if not engine:
          print('WARNING: Not testing engine %s, not configured.' % (filename))
          continue

        print(filename, engine)

        test_engine_path = os.path.join(test_path, filename)
        with open(test_engine_path, 'w') as f:
          f.write('#!/bin/sh\n')
          f.write('exec %s $@\n' % (engine))
        os.chmod(test_engine_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

        out = run_js(sample_script, engine=test_engine_path, args=['--foo'])

        self.assertEqual('0: --foo', out.strip())
Пример #6
0
  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!', run_js('a.out.js'))

    print('normal build')
    with env_modify({'EMCC_FORCE_STDLIBS': None}):
      Cache.erase()
      build()
      test()

    print('wacky env vars, these should not mess our bootstrapping')
    with env_modify({'EMCC_FORCE_STDLIBS': '1'}):
      Cache.erase()
      build()
      test()
Пример #7
0
 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()
Пример #8
0
    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()
Пример #9
0
    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)

        # also with -v, with or without inputs
        output = self.check_working([EMCC, '-v'], SANITY_MESSAGE)
        output = self.check_working([EMCC, '-v'] + MINIMAL_HELLO_WORLD + [],
                                    SANITY_MESSAGE)

        # 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(CONFIG_FILE, 'a').write('# extra stuff\n')
        output = self.check_working(EMCC)
        self.assertContained(SANITY_MESSAGE, output)
        self.assertNotContained(SANITY_FAIL_MESSAGE, output)
Пример #10
0
    def test_emcc_caching(self):
        BUILDING_MESSAGE = 'generating system library: X'
        ERASING_MESSAGE = 'clearing cache'

        restore_and_set_up()
        self.erase_cache()

        # Building a file that *does* need something *should* trigger cache
        # generation, but only the first time
        libname = 'libc++'
        for i in range(3):
            print(i)
            self.clear()
            output = self.do([
                EMCC, '-O' + str(i), '-s', '--llvm-lto', '0',
                path_from_root('tests', 'hello_libcxx.cpp'), '--save-bc',
                'a.bc', '-s', 'DISABLE_EXCEPTION_CATCHING=0'
            ])
            print('\n\n\n', output)
            assert (BUILDING_MESSAGE.replace('X', libname)
                    in output) == (i == 0), 'Must only build the first time'
            self.assertContained('hello, world!', run_js('a.out.js'))
            self.assertExists(Cache.dirname)
            full_libname = libname + '.bc' if libname != 'libc++' else libname + '.a'
            self.assertExists(os.path.join(Cache.dirname, full_libname))

        restore_and_set_up()

        # Manual cache clearing
        self.ensure_cache()
        self.assertTrue(os.path.exists(Cache.dirname))
        self.assertTrue(os.path.exists(Cache.root_dirname))
        output = self.do([PYTHON, EMCC, '--clear-cache'])
        self.assertIn(ERASING_MESSAGE, output)
        self.assertFalse(os.path.exists(Cache.dirname))
        self.assertFalse(os.path.exists(Cache.root_dirname))
        self.assertIn(SANITY_MESSAGE, output)

        # Changing LLVM_ROOT, even without altering .emscripten, clears the cache
        self.ensure_cache()
        make_fake_clang(path_from_root('tests', 'fake', 'bin', 'clang'),
                        expected_llvm_version())
        make_fake_llc(path_from_root('tests', 'fake', 'bin', 'llc'),
                      'js - JavaScript (asm.js, emscripten)')
        with env_modify({'LLVM': path_from_root('tests', 'fake', 'bin')}):
            self.assertTrue(os.path.exists(Cache.dirname))
            output = self.do([PYTHON, EMCC])
            self.assertIn(ERASING_MESSAGE, output)
            self.assertFalse(os.path.exists(Cache.dirname))
Пример #11
0
    def test_d8_path(self):
        """ Test that running JS commands works for node, d8, and jsc and is not path dependent """
        # Fake some JS engines
        restore_and_set_up()

        sample_script = path_from_root('tests', 'print_args.js')

        # Note that the path contains 'd8'.
        test_path = path_from_root('tests', 'fake', 'abcd8765')
        if not os.path.exists(test_path):
            os.makedirs(test_path)

        with env_modify({'EM_IGNORE_SANITY': '1'}):
            jsengines = [('d8', V8_ENGINE), ('d8_g', V8_ENGINE),
                         ('js', SPIDERMONKEY_ENGINE), ('node', NODE_JS),
                         ('nodejs', NODE_JS)]
            for filename, engine in jsengines:
                if type(engine) is list:
                    engine = engine[0]
                if engine == '':
                    print('WARNING: Not testing engine %s, not configured.' %
                          (filename))
                    continue

                print(filename, engine)

                test_engine_path = os.path.join(test_path, filename)
                f = open(test_engine_path, 'w')
                f.write('#!/bin/sh\n')
                f.write('%s $@\n' % (engine))
                f.close()
                os.chmod(test_engine_path,
                         stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

                try:
                    out = jsrun.run_js(sample_script,
                                       engine=test_engine_path,
                                       args=['--foo'],
                                       full_output=True,
                                       assert_returncode=0,
                                       skip_check=True)
                except Exception as e:
                    if 'd8' in filename:
                        assert False, 'Your d8 version does not correctly parse command-line arguments, please upgrade or delete from ~/.emscripten config file: %s' % (
                            e)
                    else:
                        assert False, 'Error running script command: %s' % (e)

                self.assertEqual('0: --foo', out.strip())
Пример #12
0
  def test_em_config_env_var(self):
    # emcc should be configurable directly from EM_CONFIG without any config file
    restore_and_set_up()
    create_test_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()}):
      self.run_process([EMCC, 'main.cpp', '-Wno-deprecated', '-o', 'a.out.js'])

    self.assertContained('hello from emcc with no config file', self.run_js('a.out.js'))
Пример #13
0
  def test_node(self):
    NODE_WARNING = 'node version appears too old'
    NODE_WARNING_2 = 'cannot check node version'

    restore_and_set_up()

    # Clang should report the version number we expect, and emcc should not warn
    assert shared.check_node_version()
    output = self.check_working(EMCC)
    self.assertNotIn(NODE_WARNING, output)

    # Fake a different node version
    restore_and_set_up()
    f = open(CONFIG_FILE, 'a')
    f.write('NODE_JS = "' + path_from_root('tests', 'fake', 'nodejs') + '"')
    f.close()

    if not os.path.exists(path_from_root('tests', 'fake')):
      os.makedirs(path_from_root('tests', 'fake'))

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      for version, succeed in [('v0.8.0', False),
                               ('v4.1.0', False),
                               ('v4.1.1', True),
                               ('v4.2.3-pre', True),
                               ('cheez', False)]:
        print(version, succeed)
        f = open(path_from_root('tests', 'fake', 'nodejs'), 'w')
        f.write('#!/bin/sh\n')
        f.write('''if [ $1 = "--version" ]; then
echo "%s"
else
%s $@
fi
''' % (version, NODE_JS))
        f.close()
        os.chmod(path_from_root('tests', 'fake', 'nodejs'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
        if not succeed:
          if version[0] == 'v':
            self.check_working(EMCC, NODE_WARNING)
          else:
            self.check_working(EMCC, NODE_WARNING_2)
        else:
          output = self.check_working(EMCC)
          assert NODE_WARNING not in output, output
Пример #14
0
  def test_node(self):
    NODE_WARNING = 'node version appears too old'
    NODE_WARNING_2 = 'cannot check node version'

    restore_and_set_up()

    # Clang should report the version number we expect, and emcc should not warn
    assert shared.check_node_version()
    output = self.check_working(EMCC)
    self.assertNotIn(NODE_WARNING, output)

    # Fake a different node version
    restore_and_set_up()
    with open(CONFIG_FILE, 'a') as f:
      f.write('NODE_JS = "' + self.in_dir('fake', 'nodejs') + '"')

    ensure_dir('fake')

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      for version, succeed in [('v0.8.0', False),
                               ('v4.1.0', False),
                               ('v4.1.1', True),
                               ('v4.2.3-pre', True),
                               ('cheez', False)]:
        print(version, succeed)
        f = open(self.in_dir('fake', 'nodejs'), 'w')
        f.write('#!/bin/sh\n')
        f.write('''if [ $1 = "--version" ]; then
echo "%s"
else
%s $@
fi
''' % (version, NODE_JS))
        f.close()
        os.chmod(self.in_dir('fake', 'nodejs'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
        if not succeed:
          if version[0] == 'v':
            self.check_working(EMCC, NODE_WARNING)
          else:
            self.check_working(EMCC, NODE_WARNING_2)
        else:
          output = self.check_working(EMCC)
          assert NODE_WARNING not in output, output
Пример #15
0
  def test_d8_path(self):
    """ Test that running JS commands works for node, d8, and jsc and is not path dependent """
    # Fake some JS engines
    restore_and_set_up()

    sample_script = path_from_root('tests', 'print_args.js')

    # Note that the path contains 'd8'.
    test_path = path_from_root('tests', 'fake', 'abcd8765')
    if not os.path.exists(test_path):
      os.makedirs(test_path)

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      jsengines = [('d8',     V8_ENGINE),
                   ('d8_g',   V8_ENGINE),
                   ('js',     SPIDERMONKEY_ENGINE),
                   ('node',   NODE_JS),
                   ('nodejs', NODE_JS)]
      for filename, engine in jsengines:
        if type(engine) is list:
          engine = engine[0]
        if engine == '':
            print('WARNING: Not testing engine %s, not configured.' % (filename))
            continue

        print(filename, engine)

        test_engine_path = os.path.join(test_path, filename)
        f = open(test_engine_path, 'w')
        f.write('#!/bin/sh\n')
        f.write('%s $@\n' % (engine))
        f.close()
        os.chmod(test_engine_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

        try:
          out = jsrun.run_js(sample_script, engine=test_engine_path, args=['--foo'], full_output=True, assert_returncode=0, skip_check=True)
        except Exception as e:
          if 'd8' in filename:
            assert False, 'Your d8 version does not correctly parse command-line arguments, please upgrade or delete from ~/.emscripten config file: %s' % (e)
          else:
            assert False, 'Error running script command: %s' % (e)

        self.assertEqual('0: --foo', out.strip())
Пример #16
0
    def test_llvm(self):
        LLVM_WARNING = 'LLVM version appears incorrect'

        restore_and_set_up()

        # Clang should report the version number we expect, and emcc should not warn
        assert shared.check_llvm_version()
        output = self.check_working(EMCC)
        self.assertNotContained(LLVM_WARNING, output)

        # Fake a different llvm version
        restore_and_set_up()
        with open(CONFIG_FILE, 'a') as f:
            f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake') + '"')

        real_version_x, real_version_y = (
            int(x) for x in expected_llvm_version().split('.'))
        if shared.get_llvm_target() == shared.WASM_TARGET:
            make_fake_llc(path_from_root('tests', 'fake', 'llc'),
                          'wasm32 - WebAssembly 32-bit')
            make_fake_lld(path_from_root('tests', 'fake', 'wasm-ld'))
        else:
            make_fake_llc(path_from_root('tests', 'fake', 'llc'),
                          'js - JavaScript (asm.js, emscripten)')

        with env_modify({'EM_IGNORE_SANITY': '1'}):
            for inc_x in range(-2, 3):
                for inc_y in range(-2, 3):
                    expected_x = real_version_x + inc_x
                    expected_y = real_version_y + inc_y
                    if expected_x < 0 or expected_y < 0:
                        continue  # must be a valid llvm version
                    print("mod LLVM version: %d %d -> %d %d" %
                          (real_version_x, real_version_x, expected_x,
                           expected_y))
                    make_fake_clang(path_from_root('tests', 'fake', 'clang'),
                                    '%s.%s' % (expected_x, expected_y))
                    did_modify = inc_x != 0 or inc_y != 0
                    if did_modify:
                        output = self.check_working(EMCC, LLVM_WARNING)
                    else:
                        output = self.check_working(EMCC)
                        self.assertNotContained(LLVM_WARNING, output)
Пример #17
0
    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)
Пример #18
0
  def test_llvm(self):
    LLVM_WARNING = 'LLVM version appears incorrect'

    restore_and_set_up()

    # Clang should report the version number we expect, and emcc should not warn
    assert shared.check_clang_version()
    output = self.check_working(EMCC)
    assert LLVM_WARNING not in output, output

    # Fake a different llvm version
    restore_and_set_up()
    with open(CONFIG_FILE, 'a') as f:
      f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake') + '"')

    if not os.path.exists(path_from_root('tests', 'fake')):
      os.makedirs(path_from_root('tests', 'fake'))

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      for x in range(-2, 3):
        for y in range(-2, 3):
          f = open(path_from_root('tests', 'fake', 'clang'), 'w')
          f.write('#!/bin/sh\n')
          expected_x, expected_y = (int(x) for x in expected_llvm_version().split('.'))
          expected_x += x
          expected_y += y
          if expected_x < 0 or expected_y < 0:
            continue # must be a valid llvm version
          print(expected_llvm_version(), x, y, expected_x, expected_y)
          f.write('echo "clang version %d.%d" 1>&2\n' % (expected_x, expected_y))
          f.close()
          shutil.copyfile(path_from_root('tests', 'fake', 'clang'), path_from_root('tests', 'fake', 'clang++'))
          os.chmod(path_from_root('tests', 'fake', 'clang'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
          os.chmod(path_from_root('tests', 'fake', 'clang++'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
          if x != 0 or y != 0:
            output = self.check_working(EMCC, LLVM_WARNING)
          else:
            output = self.check_working(EMCC)
            assert LLVM_WARNING not in output, output
Пример #19
0
  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)
    assert os.path.exists(SANITY_FILE) # EMCC should have checked sanity successfully
    assert mtime(SANITY_FILE) > mtime(CONFIG_FILE)
    assert generate_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)

    # correct sanity contents mean we need not check
    open(SANITY_FILE, 'w').write(generate_sanity())
    output = self.check_working(EMCC)
    self.assertNotContained(SANITY_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)

    # 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)

    # also with -v, with or without inputs
    output = self.check_working([EMCC, '-v'], SANITY_MESSAGE)
    output = self.check_working([EMCC, '-v'] + MINIMAL_HELLO_WORLD + [], SANITY_MESSAGE)

    # 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
    time.sleep(0.1)
    restore_and_set_up()
    assert mtime(SANITY_FILE) < mtime(CONFIG_FILE)
    output = self.check_working(EMCC)
    self.assertContained(SANITY_MESSAGE, output)
    assert mtime(SANITY_FILE) >= mtime(CONFIG_FILE)
    self.assertNotContained(SANITY_FAIL_MESSAGE, output)

    # emcc should be configurable directly from EM_CONFIG without any config file
    restore_and_set_up()
    config = open(CONFIG_FILE, 'r').read()
    open('main.cpp', 'w').write('''
      #include <stdio.h>
      int main() {
        printf("hello from emcc with no config file\\n");
        return 0;
      }
    ''')

    wipe()
    with env_modify({'EM_CONFIG': config}):
      run_process([PYTHON, EMCC, 'main.cpp', '-o', 'a.out.js'])

    self.assertContained('hello from emcc with no config file', run_js('a.out.js'))
Пример #20
0
 def test_with_fake(report, expected):
     make_fake(report)
     with env_modify({'EMCC_DEBUG': '1'}):
         self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                            expected)
Пример #21
0
  def test_vanilla(self):
    restore_and_set_up()
    Cache.erase()

    with env_modify({'EMCC_DEBUG': '1'}):
      # see that we test vanilla status, and just once
      TESTING = 'testing for asm.js target'
      self.check_working(EMCC, TESTING)
      for i in range(3):
        output = self.check_working(EMCC, 'check tells us to use')
        assert TESTING not in output
      # if env var tells us, do what it says
      with env_modify({'EMCC_WASM_BACKEND': '1'}):
        self.check_working(EMCC, 'EMCC_WASM_BACKEND tells us to use wasm backend')
      with env_modify({'EMCC_WASM_BACKEND': '0'}):
        self.check_working(EMCC, 'EMCC_WASM_BACKEND tells us to use asm.js backend')

    def make_fake(report):
      with open(CONFIG_FILE, 'a') as f:
        f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake', 'bin') + '"\n')
        # BINARYEN_ROOT needs to exist in the config, even though this test
        # doesn't actually use it.
        f.write('BINARYEN_ROOT= "%s"\n' % path_from_root('tests', 'fake', 'bin'))

      with open(path_from_root('tests', 'fake', 'bin', 'llc'), 'w') as f:
        f.write('#!/bin/sh\n')
        f.write('echo "llc fake output\nRegistered Targets:\n%s"' % report)
      os.chmod(path_from_root('tests', 'fake', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
      with open(path_from_root('tests', 'fake', 'bin', 'wasm-ld'), 'w') as f:
        f.write('#!/bin/sh\n')
        f.write('exit 0\n')
      os.chmod(path_from_root('tests', 'fake', 'bin', 'wasm-ld'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

    with env_modify({'EMCC_DEBUG': '1'}):
      make_fake('wasm32-unknown-unknown-elf')
      # see that we request the right backend from llvm
      with env_modify({'EMCC_WASM_BACKEND': '1'}):
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'wasm32-unknown-unknown-elf')
      make_fake('asmjs-unknown-emscripten')
      with env_modify({'EMCC_WASM_BACKEND': '0'}):
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'asmjs-unknown-emscripten')
      # check the current installed one is ok
      restore_and_set_up()
      self.check_working(EMCC)
      output = self.check_working(EMCC, 'check tells us to use')
      if 'wasm backend' in output:
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'wasm32-unknown-unknown-elf')
      else:
        assert 'asm.js backend' in output
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'asmjs-unknown-emscripten')

    # fake llc output

    try_delete(path_from_root('tests', 'fake'))
    os.makedirs(path_from_root('tests', 'fake', 'bin'))

    def test_with_fake(report, expected):
      make_fake(report)
      with env_modify({'EMCC_DEBUG': '1'}):
        output = self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], expected)
        self.assertContained('config file changed since we checked vanilla', output)

    test_with_fake('got js backend! JavaScript (asm.js, emscripten) backend', 'check tells us to use asm.js backend')
    test_with_fake('got wasm32 backend! WebAssembly 32-bit',                  'check tells us to use wasm backend')

    # use LLVM env var to modify LLVM between vanilla checks

    assert not os.environ.get('LLVM'), 'we need to modify LLVM env var for this'

    f = open(CONFIG_FILE, 'a')
    f.write('LLVM_ROOT = os.getenv("LLVM", "' + path_from_root('tests', 'fake1', 'bin') + '")\n')
    f.close()

    safe_ensure_dirs(path_from_root('tests', 'fake1', 'bin'))
    f = open(path_from_root('tests', 'fake1', 'bin', 'llc'), 'w')
    f.write('#!/bin/sh\n')
    f.write('echo "llc fake1 output\nRegistered Targets:\n%s"' % 'got js backend! JavaScript (asm.js, emscripten) backend')
    f.close()
    os.chmod(path_from_root('tests', 'fake1', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

    safe_ensure_dirs(path_from_root('tests', 'fake2', 'bin'))
    f = open(path_from_root('tests', 'fake2', 'bin', 'llc'), 'w')
    f.write('#!/bin/sh\n')
    f.write('echo "llc fake2 output\nRegistered Targets:\n%s"' % 'got wasm32 backend! WebAssembly 32-bit')
    f.close()
    os.chmod(path_from_root('tests', 'fake2', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

    with env_modify({'EMCC_DEBUG': '1'}):
      self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'use asm.js backend')
      with env_modify({'LLVM': path_from_root('tests', 'fake2', 'bin')}):
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'regenerating vanilla check since other llvm')

    try_delete(CANONICAL_TEMP_DIR)
    return # TODO: the rest of this

    # check separate cache dirs are used

    restore_and_set_up()
    self.check_working([EMCC], '')

    root_cache = os.path.expanduser('~/.emscripten_cache')
    if os.path.exists(os.path.join(root_cache, 'asmjs')):
      shutil.rmtree(os.path.join(root_cache, 'asmjs'))
    if os.path.exists(os.path.join(root_cache, 'wasm')):
      shutil.rmtree(os.path.join(root_cache, 'wasm'))

    with env_modify({'EMCC_WASM_BACKEND': '1'}):
      self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
      assert os.path.exists(os.path.join(root_cache, 'wasm'))

    with env_modify({'EMCC_WASM_BACKEND': '0'}):
      self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
      assert os.path.exists(os.path.join(root_cache, 'asmjs'))
      shutil.rmtree(os.path.join(root_cache, 'asmjs'))

    self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
    assert os.path.exists(os.path.join(root_cache, 'asmjs'))
Пример #22
0
  def test_native_optimizer(self):
    restore_and_set_up()

    def build():
      return self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-O2', '-s', 'WASM=0'], 'running js post-opts')

    def test():
      self.assertContained('hello, world!', run_js('a.out.js'))

    with env_modify({'EMCC_DEBUG': '1'}):
      # basic usage or lack of usage
      for native in [None, 0, 1]:
        print('phase 1, part', native)
        Cache.erase()
        try:
          if native is not None:
            os.environ['EMCC_NATIVE_OPTIMIZER'] = str(native)
          output = build()
          assert ('js optimizer using native' in output) == (not not (native or native is None)), output
          test()
          if native or native is None: # None means use the default, which is to use the native optimizer
            assert 'building native optimizer' in output, output
            # compile again, no rebuild of optimizer
            output = build()
            assert 'building native optimizer' not in output
            assert 'js optimizer using native' in output
            test()
        finally:
          if native is not None:
            del os.environ['EMCC_NATIVE_OPTIMIZER']

      # force a build failure, see we fall back to non-native

      for native in [1, 'g']:
        with env_modify({'EMCC_NATIVE_OPTIMIZER': str(native)}):
          print('phase 2, part', native)
          Cache.erase()

          try:
            # break it
            f = path_from_root('tools', 'optimizer', 'optimizer-main.cpp')
            src = open(f).read()
            bad = src.replace('main', '!waka waka<')
            assert bad != src
            open(f, 'w').write(bad)
            # first try
            output = build()
            assert 'failed to build native optimizer' in output, output
            if native == 1:
              assert 'to see compiler errors, build with EMCC_NATIVE_OPTIMIZER=g' in output
              assert 'waka waka' not in output
            else:
              assert 'output from attempt' in output, output
              assert 'waka waka' in output, output
            assert 'js optimizer using native' not in output
            test() # still works, without native optimizer
            # second try, see previous failure
            output = build()
            assert 'failed to build native optimizer' not in output
            assert 'seeing that optimizer could not be built' in output
            test() # still works, without native optimizer
            # clear cache, try again
            Cache.erase()
            output = build()
            assert 'failed to build native optimizer' in output
            test() # still works, without native optimizer
          finally:
            open(f, 'w').write(src)

          Cache.erase()

          # now it should work again
          output = build()
          assert 'js optimizer using native' in output
          test() # still works

    try_delete(CANONICAL_TEMP_DIR)
Пример #23
0
    def test_vanilla(self):
        restore_and_set_up()
        Cache.erase()

        with env_modify({'EMCC_DEBUG': '1'}):
            # see that we test vanilla status, and just once
            TESTING = 'testing for asm.js target'
            print(self.check_working(EMCC, TESTING))

            for i in range(3):
                output = self.check_working(EMCC, 'check tells us to use')
                self.assertNotContained(TESTING, output)
            # if env var tells us, do what it says
            with env_modify({'EMCC_WASM_BACKEND': '1'}):
                self.check_working(
                    EMCC, 'EMCC_WASM_BACKEND tells us to use wasm backend')
            with env_modify({'EMCC_WASM_BACKEND': '0'}):
                self.check_working(
                    EMCC, 'EMCC_WASM_BACKEND tells us to use asm.js backend')

        def make_fake(report):
            with open(CONFIG_FILE, 'a') as f:
                f.write('LLVM_ROOT = "' + self.in_dir('fake', 'bin') + '"\n')
                # BINARYEN_ROOT needs to exist in the config, even though this test
                # doesn't actually use it.
                f.write('BINARYEN_ROOT= "%s"\n' % self.in_dir('fake', 'bin'))

            make_fake_clang(self.in_dir('fake', 'bin', 'clang'),
                            expected_llvm_version())
            make_fake_llc(self.in_dir('fake', 'bin', 'llc'), report)
            make_fake_lld(self.in_dir('fake', 'bin', 'wasm-ld'))

        with env_modify({'EMCC_DEBUG': '1'}):
            make_fake('wasm32-unknown-unknown-elf')
            # see that we request the right backend from llvm
            with env_modify({'EMCC_WASM_BACKEND': '1'}):
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'wasm32-unknown-unknown-elf')
            make_fake('asmjs-unknown-emscripten')
            with env_modify({'EMCC_WASM_BACKEND': '0'}):
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'asmjs-unknown-emscripten')
            # check the current installed one is ok
            restore_and_set_up()
            self.check_working(EMCC)
            output = self.check_working(EMCC, 'check tells us to use')
            if 'wasm backend' in output:
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'wasm32-unknown-unknown-elf')
            else:
                assert 'asm.js backend' in output
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'asmjs-unknown-emscripten')

        # fake llc output

        def test_with_fake(report, expected):
            make_fake(report)
            with env_modify({'EMCC_DEBUG': '1'}):
                output = self.check_working([EMCC] + MINIMAL_HELLO_WORLD +
                                            ['-c'], expected)
                self.assertContained(
                    'config file changed since we checked vanilla', output)

        test_with_fake(
            'got js backend! JavaScript (asm.js, emscripten) backend',
            'check tells us to use asm.js backend')
        test_with_fake('got wasm32 backend! WebAssembly 32-bit',
                       'check tells us to use wasm backend')

        # use LLVM env var to modify LLVM between vanilla checks

        assert not os.environ.get(
            'EM_LLVM_ROOT'), 'we need to modify EM_LLVM_ROOT env var for this'

        f = open(CONFIG_FILE, 'a')
        f.write('LLVM_ROOT = "' + self.in_dir('fake1', 'bin') + '"\n')
        f.close()

        safe_ensure_dirs(self.in_dir('fake1', 'bin'))
        f = open(self.in_dir('fake1', 'bin', 'llc'), 'w')
        f.write('#!/bin/sh\n')
        f.write('echo "llc fake1 output\nRegistered Targets:\n%s"' %
                'got js backend! JavaScript (asm.js, emscripten) backend')
        f.close()
        os.chmod(self.in_dir('fake1', 'bin', 'llc'),
                 stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

        safe_ensure_dirs(self.in_dir('fake2', 'bin'))
        f = open(self.in_dir('fake2', 'bin', 'llc'), 'w')
        f.write('#!/bin/sh\n')
        f.write('echo "llc fake2 output\nRegistered Targets:\n%s"' %
                'got wasm32 backend! WebAssembly 32-bit')
        f.close()
        os.chmod(self.in_dir('fake2', 'bin', 'llc'),
                 stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

        with env_modify({'EMCC_DEBUG': '1'}):
            self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                               'use asm.js backend')
            with env_modify({'EM_LLVM_ROOT': self.in_dir('fake2', 'bin')}):
                self.check_working(
                    [EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                    'regenerating vanilla check since other llvm')

        try_delete(CANONICAL_TEMP_DIR)
        return  # TODO: the rest of this

        # check separate cache dirs are used

        restore_and_set_up()
        self.check_working([EMCC], '')

        root_cache = os.path.expanduser('~/.emscripten_cache')
        if os.path.exists(os.path.join(root_cache, 'asmjs')):
            shutil.rmtree(os.path.join(root_cache, 'asmjs'))
        if os.path.exists(os.path.join(root_cache, 'wasm')):
            shutil.rmtree(os.path.join(root_cache, 'wasm'))

        with env_modify({'EMCC_WASM_BACKEND': '1'}):
            self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
            self.assertExists(os.path.join(root_cache, 'wasm'))

        with env_modify({'EMCC_WASM_BACKEND': '0'}):
            self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
            self.assertExists(os.path.join(root_cache, 'asmjs'))
            shutil.rmtree(os.path.join(root_cache, 'asmjs'))

        self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
        self.assertExists(os.path.join(root_cache, 'asmjs'))
Пример #24
0
    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)

        # also with -v, with or without inputs
        output = self.check_working([EMCC, '-v'], SANITY_MESSAGE)
        output = self.check_working([EMCC, '-v'] + MINIMAL_HELLO_WORLD + [],
                                    SANITY_MESSAGE)

        # 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(CONFIG_FILE, 'a').write('# extra stuff\n')
        output = self.check_working(EMCC)
        self.assertContained(SANITY_MESSAGE, output)
        self.assertNotContained(SANITY_FAIL_MESSAGE, output)

        # emcc should be configurable directly from EM_CONFIG without any config file
        restore_and_set_up()
        config = open(CONFIG_FILE, 'r').read()
        open('main.cpp', 'w').write('''
      #include <stdio.h>
      int main() {
        printf("hello from emcc with no config file\\n");
        return 0;
      }
    ''')

        wipe()
        with env_modify({'EM_CONFIG': config}):
            run_process([EMCC, 'main.cpp', '-o', 'a.out.js'])

        self.assertContained('hello from emcc with no config file',
                             run_js('a.out.js'))
Пример #25
0
 def test_with_fake(report, expected):
   make_fake(report)
   with env_modify({'EMCC_DEBUG': '1'}):
     output = self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], expected)
     self.assertContained('config file changed since we checked vanilla', output)
Пример #26
0
 def check():
   print(self.do([PYTHON, EMCC, '--clear-cache']))
   print(self.do([PYTHON, EMCC, '--clear-ports']))
   with env_modify({'EMCC_WASM_BACKEND': '1'}):
     self.check_working([EMCC, path_from_root('tests', 'hello_world.c')], '')
Пример #27
0
    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)