diff options
Diffstat (limited to 'testsuite')
-rw-r--r-- | testsuite/config/ghc | 27 | ||||
-rw-r--r-- | testsuite/driver/runtests.py | 16 | ||||
-rw-r--r-- | testsuite/driver/testlib.py | 6 | ||||
-rw-r--r-- | testsuite/mk/ghc-config.hs | 5 | ||||
-rw-r--r-- | testsuite/mk/test.mk | 8 | ||||
-rw-r--r-- | testsuite/tests/linters/Makefile | 4 | ||||
-rw-r--r-- | testsuite/tests/linters/all.T | 1 | ||||
-rwxr-xr-x | testsuite/tests/linters/checkUniques/check-uniques.py | 49 |
8 files changed, 85 insertions, 31 deletions
diff --git a/testsuite/config/ghc b/testsuite/config/ghc index aed4c22fb0..1a73e3a547 100644 --- a/testsuite/config/ghc +++ b/testsuite/config/ghc @@ -183,18 +183,6 @@ llvm_ways = [x[0] for x in config.way_flags.items() def get_compiler_info(): - s = getStdout([config.compiler, '--info']) - s = re.sub('[\r\n]', '', s) - compilerInfoDict = dict(eval(s)) - s = getStdout([config.compiler, '+RTS', '--info']) - s = re.sub('[\r\n]', '', s) - rtsInfoDict = dict(eval(s)) - - config.have_ncg = compilerInfoDict.get("Have native code generator", "NO") == "YES" - - # Detect whether an LLVM toolhain is available - llc_path = compilerInfoDict.get("LLVM llc command") - config.have_llvm = shutil.which(llc_path) is not None if config.unregisterised: print("Unregisterised build; skipping LLVM ways...") elif config.have_llvm: @@ -212,25 +200,14 @@ def get_compiler_info(): # backend by default. config.ghc_built_by_llvm = not config.have_ncg and not config.unregisterised - config.have_RTS_linker = compilerInfoDict.get("target has RTS linker", "NO") == "YES" # external interpreter needs RTS linker support # If the field is not present (GHC 8.0 and earlier), assume we don't # have -fexternal-interpreter (though GHC 8.0 actually does) # so we can still run most tests. - config.have_ext_interp = compilerInfoDict.get("target has RTS linker", "NO") == "YES" + config.have_ext_interp = config.have_RTS_linker # See Note [Replacing backward slashes in config.libdir]. - config.libdir = compilerInfoDict['LibDir'].replace('\\', '/') - - if re.match(".*_p(_.*|$)", rtsInfoDict["RTS way"]): - config.compiler_profiled = True - else: - config.compiler_profiled = False - - try: - config.package_conf_cache_file = compilerInfoDict["Global Package DB"] + '/package.cache' - except: - config.package_conf_cache_file = '' + config.libdir = config.libdir.replace('\\', '/') # See Note [WayFlags] if config.ghc_dynamic: diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py index 6858715c7a..d2e25eaa19 100644 --- a/testsuite/driver/runtests.py +++ b/testsuite/driver/runtests.py @@ -275,12 +275,18 @@ def format_path(path): # On Windows we need to set $PATH to include the paths to all the DLLs # in order for the dynamic library tests to work. if windows: - pkginfo = getStdout([config.ghc_pkg, 'dump']) + try: + pkginfo = getStdout([config.ghc_pkg, 'dump']) + except FileNotFoundError as err: + # This can happen when we are only running tests which don't depend on ghc (ie linters) + # In that case we probably haven't built ghc-pkg yet so this query will fail. + print (err) + print ("Failed to call ghc-pkg for windows path modification... some tests might fail") + pkginfo = "" topdir = config.libdir - if windows: - mingw = os.path.abspath(os.path.join(topdir, '../mingw/bin')) - mingw = format_path(mingw) - ghc_env['PATH'] = os.pathsep.join([ghc_env.get("PATH", ""), mingw]) + mingw = os.path.abspath(os.path.join(topdir, '../mingw/bin')) + mingw = format_path(mingw) + ghc_env['PATH'] = os.pathsep.join([ghc_env.get("PATH", ""), mingw]) for line in pkginfo.split('\n'): if line.startswith('library-dirs:'): path = line.rstrip() diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py index 423cd99313..74ba9909f1 100644 --- a/testsuite/driver/testlib.py +++ b/testsuite/driver/testlib.py @@ -125,6 +125,12 @@ def setTestOpts( f ): # type TestOpt = (name :: String, opts :: Object) -> IO () def normal( name, opts ): + opts.hadrian_deps.update(["test:ghc"]) + return; + +# A test with no hadrian built dependencies, including the test compiler +# This is used for linters. +def no_deps( name, opts): return; def skip( name, opts ): diff --git a/testsuite/mk/ghc-config.hs b/testsuite/mk/ghc-config.hs index e4631f13ff..a22d9b46d1 100644 --- a/testsuite/mk/ghc-config.hs +++ b/testsuite/mk/ghc-config.hs @@ -20,12 +20,15 @@ main = do getGhcFieldOrFail fields "GhcDebugged" "Debug on" getGhcFieldOrFail fields "GhcWithNativeCodeGen" "Have native code generator" getGhcFieldOrFail fields "GhcWithInterpreter" "Have interpreter" + getGhcFieldOrFail fields "GhcWithRtsLinker" "target has RTS linker" getGhcFieldOrFail fields "GhcUnregisterised" "Unregisterised" getGhcFieldOrFail fields "GhcWithSMP" "Support SMP" getGhcFieldOrFail fields "GhcRTSWays" "RTS ways" - getGhcFieldOrFail fields "GhcLeadingUnderscore" "Leading underscore" + getGhcFieldOrFail fields "GhcLibdir" "LibDir" + getGhcFieldOrFail fields "GhcGlobalPackageDb" "Global Package DB" getGhcFieldOrDefault fields "GhcDynamic" "GHC Dynamic" "NO" getGhcFieldOrDefault fields "GhcProfiled" "GHC Profiled" "NO" + getGhcFieldOrDefault fields "LeadingUnderscore" "Leading underscore" "NO" getGhcFieldProgWithDefault fields "AR" "ar command" "ar" getGhcFieldProgWithDefault fields "CLANG" "LLVM clang command" "clang" getGhcFieldProgWithDefault fields "LLC" "LLVM llc command" "llc" diff --git a/testsuite/mk/test.mk b/testsuite/mk/test.mk index e01a76eb29..56c720f0fd 100644 --- a/testsuite/mk/test.mk +++ b/testsuite/mk/test.mk @@ -189,6 +189,14 @@ else RUNTEST_OPTS += -e ghc_with_smp=False endif +ifeq "$(GhcWithRtsLinker)" "YES" +RUNTEST_OPTS += -e config.have_RTS_linker=True +else +RUNTEST_OPTS += -e config.have_RTS_linker=False +endif + +RUNTEST_OPTS += -e config.libdir="\"$(GhcLibdir)\"" + ifeq "$(WINDOWS)" "YES" RUNTEST_OPTS += -e windows=True else diff --git a/testsuite/tests/linters/Makefile b/testsuite/tests/linters/Makefile new file mode 100644 index 0000000000..aeaef050e1 --- /dev/null +++ b/testsuite/tests/linters/Makefile @@ -0,0 +1,4 @@ +TOP=../.. + +uniques: + python3 checkUniques/check-uniques.py $(TOP)/.. diff --git a/testsuite/tests/linters/all.T b/testsuite/tests/linters/all.T new file mode 100644 index 0000000000..b4cc4bb8b3 --- /dev/null +++ b/testsuite/tests/linters/all.T @@ -0,0 +1 @@ +test('uniques', [no_deps, extra_files(["checkUniques"])], makefile_test, ['uniques']) diff --git a/testsuite/tests/linters/checkUniques/check-uniques.py b/testsuite/tests/linters/checkUniques/check-uniques.py new file mode 100755 index 0000000000..dd5891b0d8 --- /dev/null +++ b/testsuite/tests/linters/checkUniques/check-uniques.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +import os.path +import sys +import re +import glob +import io +from collections import defaultdict + +# keyed on unique type, values are lists of (unique, name) pairs +def find_uniques(source_files): + uniques = defaultdict(lambda: defaultdict(lambda: set())) + unique_re = re.compile(r"([\w\d]+)\s*=\s*mk([\w\d']+)Unique\s+(\d+)") + for f in source_files: + ms = unique_re.findall(io.open(f, encoding='utf8').read()) + for name, _type, n in ms: + uniques[_type][int(n)].add(name) + + return uniques + +def print_all(uniques): + for _type, uniqs in uniques.items(): + print('{_type} uniques'.format(**locals())) + for n,names in uniqs.items(): + all_names = ', '.join(names) + print(' {n} = {all_names}'.format(**locals())) + +def find_conflicts(uniques): + return [ (uniqueType, number, names) + for uniqueType, uniqs in uniques.items() + for number, names in uniqs.items() + if len(names) > 1 + ] + +top_dir = sys.argv[1] +uniques = find_uniques(glob.glob(os.path.join(top_dir, 'compiler', 'GHC', '**', '*.hs'), recursive=True)) +#print_all(uniques) +conflicts = find_conflicts(uniques) +if len(uniques) < 5: + print("Error: check-uniques: run from wrong directory?") + sys.exit(1) + +if len(conflicts) > 0: + print("Error: check-uniques: Found Unique conflict") + print() + for (ty, n, names) in conflicts: + print(' %s unique %d conflict: %s' % (ty, n, ', '.join(names))) + print() + sys.exit(1) |