def test_webkit_cached_deps(): # regression test for a bug in caching deps config = copy.copy(get_global_config()) config.skipSdk = True webkit_native = targetManager.get_target_raw( "qtwebkit-native").projectClass webkit_cheri = targetManager.get_target_raw("qtwebkit-cheri").projectClass webkit_mips = targetManager.get_target_raw( "qtwebkit-mips-hybrid").projectClass # Check that the deps are not cached yet _check_deps_not_cached((webkit_native, webkit_cheri, webkit_mips)) cheri_target_names = list(sorted(webkit_cheri.allDependencyNames(config))) assert cheri_target_names == [ "icu4c-cheri", "icu4c-native", "libxml2-cheri", "qtbase-cheri", "sqlite-cheri" ] _check_deps_not_cached([webkit_native, webkit_mips]) _check_deps_cached([webkit_cheri]) mips_target_names = list(sorted(webkit_mips.allDependencyNames(config))) assert mips_target_names == [ "icu4c-mips-hybrid", "icu4c-native", "libxml2-mips-hybrid", "qtbase-mips-hybrid", "sqlite-mips-hybrid" ] _check_deps_cached([webkit_cheri, webkit_mips]) _check_deps_not_cached([webkit_native]) native_target_names = list(sorted( webkit_native.allDependencyNames(config))) assert native_target_names == [ "icu4c-native", "libxml2-native", "qtbase-native", "sqlite-native" ] _check_deps_cached([webkit_cheri, webkit_mips, webkit_native])
def test_webkit_cached_deps(): # regression test for a bug in caching deps config = copy.copy(get_global_config()) config.skipSdk = True webkit_generic = targetManager.get_target_raw("qtwebkit").projectClass webkit_native = targetManager.get_target_raw( "qtwebkit-native").projectClass webkit_cheri = targetManager.get_target_raw("qtwebkit-cheri").projectClass webkit_mips = targetManager.get_target_raw("qtwebkit-mips").projectClass # Check that the deps are not cached yet _check_deps_not_cached( (webkit_generic, webkit_native, webkit_cheri, webkit_mips)) cheri_target_names = list(sorted(webkit_cheri.allDependencyNames(config))) assert cheri_target_names == [ "icu4c-cheri", "icu4c-native", "libxml2-cheri", "qtbase-cheri", "sqlite-cheri" ] _check_deps_not_cached([webkit_generic, webkit_native, webkit_mips]) _check_deps_cached([webkit_cheri]) mips_target_names = list(sorted(webkit_mips.allDependencyNames(config))) assert mips_target_names == [ "icu4c-mips", "icu4c-native", "libxml2-mips", "qtbase-mips", "sqlite-mips" ] _check_deps_cached([webkit_cheri, webkit_mips]) _check_deps_not_cached([webkit_generic, webkit_native]) native_target_names = list(sorted( webkit_native.allDependencyNames(config))) assert native_target_names == [ "icu4c-native", "libxml2-native", "qtbase-native", "sqlite-native" ] _check_deps_cached([webkit_cheri, webkit_mips, webkit_native]) _check_deps_not_cached([webkit_generic]) def _check_generic(cross_tgt, expected): webkit_generic._cached_deps = None _check_deps_not_cached([webkit_generic]) config.crossCompileTarget = cross_tgt generic_target_names = list( sorted(webkit_generic.allDependencyNames(config))) assert generic_target_names == expected _check_deps_cached([webkit_cheri, webkit_mips, webkit_native]) _check_generic(CrossCompileTarget.CHERI, [ "icu4c-cheri", "icu4c-native", "libxml2-cheri", "qtbase-cheri", "sqlite-cheri" ]) _check_generic(CrossCompileTarget.MIPS, [ "icu4c-mips", "icu4c-native", "libxml2-mips", "qtbase-mips", "sqlite-mips" ]) _check_generic( CrossCompileTarget.NATIVE, ["icu4c-native", "libxml2-native", "qtbase-native", "sqlite-native"])
def check_libunwind_path(path, target_name): tgt = targetManager.get_target_raw(target_name).get_or_create_project(None, config) for i in tgt.configureArgs: if i.startswith("-DLIBUNWIND_PATH="): assert ("-DLIBUNWIND_PATH=" + str(path)) == i, tgt.configureArgs return assert False, "Should have found -DLIBUNWIND_PATH= in " + str(tgt.configureArgs)
def test_kernconf(): # Parse args once to ensure targetManager is initialized # check default values config = _parse_arguments([]) cheribsd_cheri = targetManager.get_target_raw( "cheribsd-cheri").get_or_create_project(None, config) # type: BuildCHERIBSD freebsd_mips = targetManager.get_target_raw( "freebsd-mips").get_or_create_project(None, config) # type: BuildCHERIBSD freebsd_native = targetManager.get_target_raw( "freebsd-native").get_or_create_project(None, config) # type: BuildCHERIBSD assert config.freebsd_kernconf is None attr = inspect.getattr_static(freebsd_mips, "kernelConfig") assert freebsd_mips.kernelConfig == "MALTA64" assert cheribsd_cheri.kernelConfig == "CHERI128_MALTA64" assert freebsd_native.kernelConfig == "GENERIC" # Check that --kernconf is used as the fallback config = _parse_arguments( ["--kernconf=LINT", "--freebsd-mips/kernel-config=NOTMALTA64"]) assert config.freebsd_kernconf == "LINT" attr = inspect.getattr_static(freebsd_mips, "kernelConfig") # previously we would replace the command line attribute with a string -> check this is no longer true assert isinstance(attr, JsonAndCommandLineConfigOption) assert freebsd_mips.kernelConfig == "NOTMALTA64" assert cheribsd_cheri.kernelConfig == "LINT" assert freebsd_native.kernelConfig == "LINT" config = _parse_arguments( ["--kernconf=LINT", "--cheribsd-cheri/kernel-config=SOMETHING"]) assert config.freebsd_kernconf == "LINT" assert freebsd_mips.kernelConfig == "LINT" assert cheribsd_cheri.kernelConfig == "SOMETHING" assert freebsd_native.kernelConfig == "LINT"
def test_cross_compile_project_inherits(): # Parse args once to ensure targetManager is initialized config = _parse_arguments(["--skip-configure"]) qtbase_class = targetManager.get_target_raw("qtbase").projectClass qtbase_default = targetManager.get_target_raw("qtbase").get_or_create_project(None, config) # type: BuildQtBase qtbase_native = targetManager.get_target_raw("qtbase-native").get_or_create_project(None, config) # type: BuildQtBase qtbase_mips = targetManager.get_target_raw("qtbase-mips").get_or_create_project(None, config) # type: BuildQtBase # Check that project name is the same: assert qtbase_default.projectName == qtbase_native.projectName assert qtbase_mips.projectName == qtbase_native.projectName # These classes were generated: assert qtbase_native.synthetic_base == qtbase_class assert qtbase_mips.synthetic_base == qtbase_class assert not hasattr(qtbase_class, "synthetic_base") # Now check a property that should be inherited: _parse_arguments(["--qtbase-native/build-tests"]) assert not qtbase_default.build_tests, "qtbase-default build-tests should default to false" assert qtbase_native.build_tests, "qtbase-native build-tests should be set on cmdline" assert not qtbase_mips.build_tests, "qtbase-mips build-tests should default to false" # If the base qtbase option is set but no per-target one use the basic one: _parse_arguments(["--qtbase/build-tests"]) assert qtbase_default.build_tests, "qtbase(default) build-tests should be set on cmdline" assert qtbase_native.build_tests, "qtbase-native should inherit build-tests from qtbase(default)" assert qtbase_mips.build_tests, "qtbase-mips should inherit build-tests from qtbase(default)" # But target-specific ones should override _parse_arguments(["--qtbase/build-tests", "--qtbase-mips/no-build-tests"]) assert qtbase_default.build_tests, "qtbase(default) build-tests should be set on cmdline" assert qtbase_native.build_tests, "qtbase-native should inherit build-tests from qtbase(default)" assert not qtbase_mips.build_tests, "qtbase-mips should have a false override for build-tests" # Check that we hav ethe same behaviour when loading from json: _parse_config_file_and_args(b'{"qtbase-native/build-tests": true }') assert not qtbase_default.build_tests, "qtbase-default build-tests should default to false" assert qtbase_native.build_tests, "qtbase-native build-tests should be set on cmdline" assert not qtbase_mips.build_tests, "qtbase-mips build-tests should default to false" # If the base qtbase option is set but no per-target one use the basic one: _parse_config_file_and_args(b'{"qtbase/build-tests": true }') assert qtbase_default.build_tests, "qtbase(default) build-tests should be set on cmdline" assert qtbase_native.build_tests, "qtbase-native should inherit build-tests from qtbase(default)" assert qtbase_mips.build_tests, "qtbase-mips should inherit build-tests from qtbase(default)" # But target-specific ones should override _parse_config_file_and_args(b'{"qtbase/build-tests": true, "qtbase-mips/build-tests": false }') assert qtbase_default.build_tests, "qtbase(default) build-tests should be set on cmdline" assert qtbase_native.build_tests, "qtbase-native should inherit build-tests from qtbase(default)" assert not qtbase_mips.build_tests, "qtbase-mips should have a false override for build-tests" # And that cmdline still overrides JSON: _parse_config_file_and_args(b'{"qtbase/build-tests": true }', "--qtbase-mips/no-build-tests") assert qtbase_default.build_tests, "qtbase(default) build-tests should be set on cmdline" assert qtbase_native.build_tests, "qtbase-native should inherit build-tests from qtbase(default)" assert not qtbase_mips.build_tests, "qtbase-mips should have a false override for build-tests" # But if a per-target option is set in the json that still overrides the default set on the cmdline _parse_config_file_and_args(b'{"qtbase-mips/build-tests": false }', "--qtbase/build-tests") assert qtbase_default.build_tests, "qtbase(default) build-tests should be set on cmdline" assert qtbase_native.build_tests, "qtbase-native should inherit build-tests from qtbase(default)" assert not qtbase_mips.build_tests, "qtbase-mips should have a JSON false override for build-tests" # However, don't inherit for buildDir since that doesn't make sense: def assertBuildDirsDifferent(): # Default should be CHERI purecap # print("Default build dir:", qtbase_default.buildDir) # print("Native build dir:", qtbase_native.buildDir) # print("Mips build dir:", qtbase_mips.buildDir) assert qtbase_default.buildDir != qtbase_native.buildDir assert qtbase_default.buildDir != qtbase_mips.buildDir assert qtbase_mips.buildDir != qtbase_native.buildDir assertBuildDirsDifferent() # overriding native build dir is fine: _parse_arguments(["--qtbase-native/build-directory=/foo/bar"]) assertBuildDirsDifferent() _parse_config_file_and_args(b'{"qtbase-native/build-directory": "/foo/bar"}') assertBuildDirsDifferent() # Should not inherit from the default one: _parse_arguments(["--qtbase/build-directory=/foo/bar"]) assertBuildDirsDifferent() _parse_config_file_and_args(b'{"qtbase/build-directory": "/foo/bar"}') assertBuildDirsDifferent() # Should not inherit from the default one: _parse_arguments(["--qtbase/build-directory=/foo/bar", "--qtbase-mips/build-directory=/bar/foo"]) assertBuildDirsDifferent() _parse_config_file_and_args(b'{"qtbase/build-directory": "/foo/bar",' b' "qtbase-mips/build-directory": "/bar/foo"}') assertBuildDirsDifferent()
def test_config_file_include(): with tempfile.TemporaryDirectory() as d: config_dir = Path(d) write_bytes(config_dir / "128-common.json", b'{ "cheri-bits": 128 }') write_bytes(config_dir / "256-common.json", b'{ "cheri-bits": 256 }') write_bytes(config_dir / "common.json", b'{ "source-root": "/this/is/a/unit/test" }') # Check that the config file is parsed: result = _get_config_with_include(config_dir, b'{ "#include": "common.json"}') assert "/this/is/a/unit/test" == str(result.sourceRoot) # Check that the current file always has precendence result = _get_config_with_include( config_dir, b'{ "#include": "256-common.json", "cheri-bits": 128}') assert 128 == result.cheriBits result = _get_config_with_include( config_dir, b'{ "#include": "128-common.json", "cheri-bits": 256}') assert 256 == result.cheriBits # order doesn't matter since the #include is only evaluated after the whole file has been parsed: result = _get_config_with_include( config_dir, b'{ "cheri-bits": 128, "#include": "256-common.json"}') assert 128 == result.cheriBits result = _get_config_with_include( config_dir, b'{ "cheri-bits": 256, "#include": "128-common.json"}') assert 256 == result.cheriBits # TODO: handled nested cases: the level closest to the initial file wins write_bytes( config_dir / "change-source-root.json", b'{ "source-root": "/source/root/override", "#include": "common.json" }' ) result = _get_config_with_include( config_dir, b'{ "#include": "change-source-root.json"}') assert "/source/root/override" == str(result.sourceRoot) # And again the root file wins: result = _get_config_with_include( config_dir, b'{ "source-root": "/override/twice", "#include": "change-source-root.json"}' ) assert "/override/twice" == str(result.sourceRoot) # no matter in which order it is written: result = _get_config_with_include( config_dir, b'{ "#include": "change-source-root.json", "source-root": "/override/again"}' ) assert "/override/again" == str(result.sourceRoot) # Test merging of objects: write_bytes( config_dir / "change-smb-dir.json", b'{ "run": { "smb-host-directory": "/some/path" }, "#include": "common.json" }' ) result = _get_config_with_include( config_dir, b'{ "run": { "ssh-forwarding-port": 12345 }, "#include": "change-smb-dir.json" }' ) run_project = targetManager.get_target_raw( "run").get_or_create_project(None, result) assert run_project.custom_qemu_smb_mount == Path("/some/path") assert run_project.sshForwardingPort == 12345 with tempfile.TemporaryDirectory() as d2: # Check that relative paths work relpath = b"../" + str(Path(d).relative_to( Path(d2).parent)).encode("utf-8") result = _get_config_with_include(config_dir, b'{ "#include": "' + relpath + b'/common.json" }', workdir=Path(d2)) assert "/this/is/a/unit/test" == str(result.sourceRoot) # Check that absolute paths work as expected: abspath = b"" + str(Path(d)).encode("utf-8") result = _get_config_with_include(config_dir, b'{ "#include": "' + abspath + b'/common.json" }', workdir=Path(d2)) assert "/this/is/a/unit/test" == str(result.sourceRoot) # Nonexistant paths should raise an error with pytest.raises(FileNotFoundError) as excinfo: _get_config_with_include(config_dir, b'{ "#include": "bad-path.json"}') assert re.search("No such file or directory", excinfo.value) # Currently only one #include per config file is allowed # TODO: this could be supported but it might be better to accept a list instead? with pytest.raises(SyntaxError) as excinfo: _get_config_with_include( config_dir, b'{ "#include": "128-common.json", "foo": "bar", "#include": "256-common.json"}' ) assert re.search("duplicate key: '#include'", excinfo.value)
def test_cheribsd_purecap_inherits_config_from_cheribsd(): # Parse args once to ensure targetManager is initialized config = _parse_arguments(["--skip-configure"]) cheribsd_class = targetManager.get_target_raw("cheribsd").projectClass cheribsd_default_tgt = targetManager.get_target_raw( "cheribsd").get_or_create_project(None, config) # type: BuildCHERIBSD assert cheribsd_default_tgt.target == "cheribsd-cheri" cheribsd_mips = targetManager.get_target_raw( "cheribsd-mips").get_or_create_project(None, config) # type: BuildCHERIBSD cheribsd_cheri = targetManager.get_target_raw( "cheribsd-cheri").get_or_create_project(None, config) # type: BuildCHERIBSD cheribsd_purecap = targetManager.get_target_raw( "cheribsd-purecap").get_or_create_project( None, config) # type: BuildCHERIBSD # Check that project name is the same: assert cheribsd_mips.projectName == cheribsd_cheri.projectName assert cheribsd_cheri.projectName == cheribsd_purecap.projectName # cheribsd-cheri is a synthetic class, but cheribsd-purecap inst: assert cheribsd_cheri.synthetic_base == cheribsd_class assert not hasattr(cheribsd_purecap, "synthetic_base") _parse_arguments(["--cheribsd-mips/build-tests"]) assert not cheribsd_purecap.build_tests, "cheribsd-purecap build-tests should default to false" assert not cheribsd_cheri.build_tests, "cheribsd-cheri build-tests should default to false" _parse_arguments(["--cheribsd-purecap/build-tests"]) assert cheribsd_purecap.build_tests, "cheribsd-purecap build-tests should be set on cmdline" assert not cheribsd_cheri.build_tests, "cheribsd-cheri build-tests should default to false" _parse_arguments(["--cheribsd-cheri/build-tests"]) assert not cheribsd_purecap.build_tests, "cheribsd-purecap build-tests should default to false" assert cheribsd_cheri.build_tests, "cheribsd-cheri build-tests should be set on cmdline" # If the base cheribsd option is set but no per-target one use both cheribsd-cheri and cheribsd-purecap should inherit basic one: _parse_arguments(["--cheribsd/build-tests"]) assert cheribsd_cheri.build_tests, "cheribsd-cheri should inherit build-tests from cheribsd(default)" assert cheribsd_purecap.build_tests, "cheribsd-purecap should inherit build-tests from cheribsd(default)" # But target-specific ones should override _parse_arguments( ["--cheribsd/build-tests", "--cheribsd-purecap/no-build-tests"]) assert cheribsd_cheri.build_tests, "cheribsd-cheri should inherit build-tests from cheribsd(default)" assert not cheribsd_purecap.build_tests, "cheribsd-purecap should have a false override for build-tests" _parse_arguments( ["--cheribsd/build-tests", "--cheribsd-cheri/no-build-tests"]) assert cheribsd_purecap.build_tests, "cheribsd-purecap should inherit build-tests from cheribsd(default)" assert not cheribsd_cheri.build_tests, "cheribsd-cheri should have a false override for build-tests" # Check that we hav ethe same behaviour when loading from json: _parse_config_file_and_args(b'{"cheribsd/build-tests": true }') assert cheribsd_purecap.build_tests, "cheribsd-purecap should inherit build-tests from cheribsd(default)" assert cheribsd_cheri.build_tests, "cheribsd-cheri should inherit build-tests from cheribsd(default)" assert cheribsd_mips.build_tests, "cheribsd-mips should inherit build-tests from cheribsd(default)" # But target-specific ones should override _parse_config_file_and_args( b'{"cheribsd/build-tests": true, "cheribsd-cheri/build-tests": false }' ) assert cheribsd_mips.build_tests, "cheribsd-mips build-tests should be inherited on cmdline" assert cheribsd_purecap.build_tests, "cheribsd-purecap should inherit build-tests from cheribsd(default)" assert not cheribsd_cheri.build_tests, "cheribsd-cheri should have a false override for build-tests" # And that cmdline still overrides JSON: _parse_config_file_and_args(b'{"cheribsd/build-tests": true }', "--cheribsd-cheri/no-build-tests") assert cheribsd_purecap.build_tests, "cheribsd-purecap should inherit build-tests from cheribsd(default)" assert cheribsd_mips.build_tests, "cheribsd-mips build-tests should be inherited from cheribsd(default)" assert not cheribsd_cheri.build_tests, "cheribsd-cheri should have a false override for build-tests" # But if a per-target option is set in the json that still overrides the default set on the cmdline _parse_config_file_and_args(b'{"cheribsd-cheri/build-tests": false }', "--cheribsd/build-tests") assert cheribsd_purecap.build_tests, "cheribsd-purecap should inherit build-tests from cheribsd(default)" assert cheribsd_mips.build_tests, "cheribsd-mips build-tests should be inherited from cheribsd(default)" assert not cheribsd_cheri.build_tests, "cheribsd-cheri should have a JSON false override for build-tests" # However, don't inherit for buildDir since that doesn't make sense: def assertBuildDirsDifferent(): assert cheribsd_cheri.buildDir != cheribsd_purecap.buildDir assert cheribsd_cheri.buildDir != cheribsd_mips.buildDir assert cheribsd_cheri.buildDir == cheribsd_default_tgt.buildDir assertBuildDirsDifferent() # overriding native build dir is fine: _parse_arguments(["--cheribsd-purecap/build-directory=/foo/bar"]) assert cheribsd_purecap.buildDir == Path("/foo/bar") assertBuildDirsDifferent() _parse_config_file_and_args( b'{"cheribsd-purecap/build-directory": "/foo/bar"}') assert cheribsd_purecap.buildDir == Path("/foo/bar") assertBuildDirsDifferent() # cheribsd-cheri should inherit from the default one, but not cheribsd-purecap: _parse_arguments(["--cheribsd/build-directory=/foo/bar"]) assert cheribsd_cheri.buildDir == Path("/foo/bar") assert cheribsd_purecap.buildDir != Path("/foo/bar") assertBuildDirsDifferent() _parse_config_file_and_args(b'{"cheribsd/build-directory": "/foo/bar"}') assert cheribsd_cheri.buildDir == Path("/foo/bar") assert cheribsd_purecap.buildDir != Path("/foo/bar") assertBuildDirsDifferent() # cheribsd-cheri/builddir should have higher prirority: _parse_arguments([ "--cheribsd/build-directory=/foo/bar", "--cheribsd-cheri/build-directory=/bar/foo" ]) assert cheribsd_cheri.buildDir == Path("/bar/foo") assertBuildDirsDifferent() _parse_config_file_and_args( b'{"cheribsd/build-directory": "/foo/bar",' b' "cheribsd-cheri/build-directory": "/bar/foo"}') assert cheribsd_cheri.buildDir == Path("/bar/foo") assertBuildDirsDifferent()