summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Miedema <thomasmiedema@gmail.com>2015-08-29 15:52:43 +0200
committerThomas Miedema <thomasmiedema@gmail.com>2016-05-17 18:06:05 +0200
commit3f3dc23ea64573a12e2f4bfdaaa3aa536ad3188d (patch)
tree19caf96220f19094efca6171fa980829f4b9794d
parentdc94914eb0da985a2f006e2bd390fa1fdbafcc33 (diff)
downloadhaskell-3f3dc23ea64573a12e2f4bfdaaa3aa536ad3188d.tar.gz
Testsuite: run tests in /tmp after copying required files
Major change to the testsuite driver. For each TEST: * create a directory `<testdir>` inside `/tmp`. * link/copy all source files that the test needs into `<testdir>`. * run the test inside `<testdir>`. * delete `<testdir>` Extra files are (temporarily) tracked in `testsuite/driver/extra_files.py`, but can also be specified using the `extra_files` setup function. Differential Revision: https://phabricator.haskell.org/D1187 Reviewed by: Rufflewind, bgamari Trac: #11980
-rw-r--r--testsuite/driver/extra_files.py535
-rw-r--r--testsuite/driver/runtests.py30
-rw-r--r--testsuite/driver/testglobals.py3
-rw-r--r--testsuite/driver/testlib.py151
-rw-r--r--testsuite/driver/testutil.py32
-rw-r--r--testsuite/tests/plugins/all.T17
-rw-r--r--testsuite/tests/simplCore/should_compile/all.T2
7 files changed, 743 insertions, 27 deletions
diff --git a/testsuite/driver/extra_files.py b/testsuite/driver/extra_files.py
new file mode 100644
index 0000000000..d6e639dd28
--- /dev/null
+++ b/testsuite/driver/extra_files.py
@@ -0,0 +1,535 @@
+# Extra files that tests depend on.
+# Maybe move this information to .T files at some point.
+
+extra_src_files = {
+ '10queens': ['Main.hs'],
+ 'Capi_Ctype_001': ['Capi_Ctype_A_001.hsc', 'capi_ctype_001.h', 'capi_ctype_001_c.c'],
+ 'Capi_Ctype_002': ['Capi_Ctype_A_002.hsc', 'capi_ctype_002_A.h', 'capi_ctype_002_B.h'],
+ 'Defer02': ['../../typecheck/should_run/Defer01.hs'],
+ 'DeprU': ['DeprM.hs'],
+ 'ExportSyntaxImport': ['ExportSyntax.hs'],
+ 'ExtraConstraintsWildcardInTypeSpliceUsed': ['ExtraConstraintsWildcardInTypeSplice.hs'],
+ 'GFunctor1': ['GFunctor.hs', 'Main.hs'],
+ 'GMap1': ['GMap.hs', 'Main.hs'],
+ 'GShow1': ['GShow.hs', 'Main.hs'],
+ 'GUniplate1': ['GUniplate.hs', 'Main.hs'],
+ 'ImpExp_Imp': ['ImpExp_Exp.hs'],
+ 'ImpSafeOnly01': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly02': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly03': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly04': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly05': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly06': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly07': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly08': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly09': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'ImpSafeOnly10': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'SplicesUsed': ['Splices.hs'],
+ 'T10138': ['.keepme.hpc.T10138/'],
+ 'T10255': ['Test10255.hs'],
+ 'T10268': ['Test10268.hs'],
+ 'T10269': ['Test10269.hs'],
+ 'T10276': ['Test10276.hs'],
+ 'T10278': ['Test10278.hs'],
+ 'T10280': ['Test10280.hs'],
+ 'T10294': ['annotation-plugin/'],
+ 'T10294a': ['annotation-plugin/'],
+ 'T10307': ['Test10307.hs'],
+ 'T10309': ['Test10309.hs'],
+ 'T10312': ['Test10312.hs'],
+ 'T10313': ['Test10313.hs', 'stringSource.hs'],
+ 'T10354': ['Test10354.hs'],
+ 'T10357': ['Test10357.hs'],
+ 'T10358': ['Test10358.hs'],
+ 'T10396': ['Test10396.hs'],
+ 'T10399': ['Test10399.hs'],
+ 'T10420': ['rule-defining-plugin/'],
+ 'T10458': ['A.c'],
+ 'T10529a': ['hpc_sample_non_existing_module.tix'],
+ 'T10529b': ['.hpc/Main.mix', 'hpc_sample_incompatible_hash.tix'],
+ 'T10529c': ['.hpc/NoParse.mix', 'hpc_sample_no_parse.tix'],
+ 'T10576a': ['T10576.hs'],
+ 'T10576b': ['T10576.hs'],
+ 'T10637': ['A.hs', 'A.hs-boot'],
+ 'T10672_x64': ['Main.hs', 'Printf.hs', 'cxxy.cpp'],
+ 'T10672_x86': ['Main.hs', 'Printf.hs', 'cxxy.cpp'],
+ 'T10890': ['A.hs', 'B.hs'],
+ 'T10890_1': ['Base.hs', 'Extends.hs'],
+ 'T10955': ['A.c', 'B.c'],
+ 'T10955dyn': ['A.c', 'B.c'],
+ 'T10971d': ['T10971c.hs'],
+ 'T11018': ['Test11018.hs'],
+ 'T11072gcc': ['A.c', 'T11072.hs'],
+ 'T11072msvc': ['A.c', 'T11072.hs', 'libAS.def', 'i686/', 'x86_64/'],
+ 'T11223_link_order_a_b_2_fail': ['bar.c', 'foo.c', 'foo3.hs'],
+ 'T11223_link_order_a_b_succeed': ['bar.c', 'foo.c', 'foo2.hs'],
+ 'T11223_link_order_b_a_2_succeed': ['bar.c', 'foo.c', 'foo3.hs'],
+ 'T11223_link_order_b_a_succeed': ['bar.c', 'foo.c', 'foo2.hs'],
+ 'T11223_simple_duplicate_lib': ['bar.c', 'foo.c', 'foo.hs'],
+ 'T11223_simple_link': ['foo.c', 'foo.hs'],
+ 'T11223_simple_link_lib': ['foo.c', 'foo.hs'],
+ 'T11223_simple_unused_duplicate_lib': ['bar.c', 'foo.c', 'foo.hs'],
+ 'T11223_weak_both_link_order_a_b_succeed': ['power.c', 'power3.hs', 'power_slow.c'],
+ 'T11223_weak_both_link_order_b_a_succeed': ['power.c', 'power3.hs', 'power_slow.c'],
+ 'T11223_weak_only_link_fail': ['power.c', 'power.hs'],
+ 'T11223_weak_only_link_succeed': ['power3.hs', 'power_slow.c'],
+ 'T11223_weak_single_link_order_a_b_succeed': ['power.c', 'power3.hs', 'power_slow.c'],
+ 'T11223_weak_single_link_order_b_a_succeed': ['power.c', 'power3.hs', 'power_slow.c'],
+ 'T11244': ['rule-defining-plugin/'],
+ 'T11321': ['Test11321.hs'],
+ 'T11332': ['Test11332.hs'],
+ 'T11430': ['Test11430.hs', 't11430.hs'],
+ 'T11824': ['TyCon.hs', 'Type.hs', 'Type.hs-boot', 'Unbound/'],
+ 'T11827': ['A.hs', 'A.hs-boot', 'B.hs'],
+ 'T1372': ['p1/', 'p2/'],
+ 'T1407': ['A.c'],
+ 'T1959': ['B.hs', 'C.hs', 'D.hs', 'E1.hs', 'E2.hs'],
+ 'T2014': ['A.hs', 'A.hs-boot', 'B.hs', 'C.hs'],
+ 'T2615': ['libfoo_T2615.c', 'libfoo_script_T2615.so'],
+ 'T3007': ['A/', 'B/'],
+ 'T3103': ['Foreign/', 'GHC/'],
+ 'T4198': ['exitminus1.c'],
+ 'T437': ['Test.hs', 'Test2.hs'],
+ 'T4491': ['A.hs'],
+ 'T4891': ['X.hs'],
+ 'T5147': ['A.hs', 'B1.hs', 'B2.hs'],
+ 'T5250': ['spalign.c'],
+ 'T5435_dyn_asm': ['T5435.hs', 'T5435_asm.c'],
+ 'T5435_dyn_gcc': ['T5435.hs', 'T5435_gcc.c'],
+ 'T5435_v_asm': ['T5435.hs', 'T5435_asm.c'],
+ 'T5435_v_gcc': ['T5435.hs', 'T5435_gcc.c'],
+ 'T5442a': ['test.pkg'],
+ 'T5442b': ['test.pkg'],
+ 'T5442c': ['test.pkg'],
+ 'T5442d': ['shadow1.pkg', 'shadow2.pkg', 'shadow4.pkg'],
+ 'T5462No1': ['GFunctor/'],
+ 'T5462Yes1': ['GEnum/', 'GEq/', 'GFunctor/'],
+ 'T5462Yes2': ['GFunctor/'],
+ 'T5644': ['Conf.hs', 'ManyQueue.hs', 'Util.hs', 'heap-overflow.hs'],
+ 'T6018fail': ['T6018Afail.hs', 'T6018Bfail.hs', 'T6018Cfail.hs', 'T6018Dfail.hs'],
+ 'T6106': ['../shell.hs'],
+ 'T7040_ghci': ['T7040_c.h'],
+ 'T7354a': ['T7354b.hs'],
+ 'T7373': ['D.hs', 'pkg/'],
+ 'T7478': ['A.hs', 'B.hs', 'C.hs'],
+ 'T7702': ['T7702plugin'],
+ 'T7835': ['Test.hs', 'TestPrim.hs', 'test-prims.cmm'],
+ 'T8184': ['A.hs', 'B.hs', 'B.hs-boot', 'C.hs'],
+ 'T8353': ['Defer03.hs'],
+ 'T8425': ['Arr.hs', 'Base.hs', 'BuggyOpt.hs', 'Good.hs', 'M.hs', 'Main.hs'],
+ 'T8526': ['A.hs'],
+ 'T8602': ['A.hs'],
+ 'T9293': ['ghci057.hs'],
+ 'T9562': ['A.hs', 'B.hs', 'B.hs-boot', 'C.hs', 'D.hs', 'Main.hs'],
+ 'T9579_outofheap_rtsall': ['OutOfHeap.hs'],
+ 'T9579_outofheap_rtsall_no_suggestions': ['OutOfHeap.hs'],
+ 'T9579_outofheap_rtsnone': ['OutOfHeap.hs'],
+ 'T9579_outofheap_rtssome': ['OutOfHeap.hs'],
+ 'T9579_stackoverflow_rtsall': ['StackOverflow.hs'],
+ 'T9579_stackoverflow_rtsall_no_suggestions': ['StackOverflow.hs'],
+ 'T9579_stackoverflow_rtsnone': ['StackOverflow.hs'],
+ 'T9579_stackoverflow_rtssome': ['StackOverflow.hs'],
+ 'T9619': ['.hpc', '.hpc.copy', 'hpc_sample.tix'],
+ 'T9646': ['Main.hs', 'Natural.hs', 'StrictPrim.hs', 'Type.hs'],
+ 'T9930fail': ['T9930'],
+ 'TH_import_loop': ['Main.hs', 'ModuleA.hs', 'ModuleA.hs-boot', 'ModuleB.hs', 'ModuleC.hs'],
+ 'TH_spliceViewPat': ['A.hs', 'Main.hs'],
+ 'andre_monad': ['Main.hs'],
+ 'andy_cherry': ['DataTypes.hs', 'GenUtils.hs', 'Interp.hs', 'InterpUtils.hs', 'Main.hs', 'Parser.hs', 'PrintTEX.hs', 'mygames.pgn'],
+ 'annfail04': ['Annfail04_Help.hs'],
+ 'annfail05': ['Annfail05_Help.hs'],
+ 'annfail06': ['Annfail06_Help.hs'],
+ 'annotations': ['AnnotationLet.hs'],
+ 'annrun01': ['Annrun01_Help.hs'],
+ 'annth_compunits': ['AnnHelper.hs', 'TestModule.hs', 'TestModuleTH.hs', 'annth.hs'],
+ 'annth_make': ['AnnHelper.hs', 'TestModule.hs', 'TestModuleTH.hs', 'annth.hs'],
+ 'apirecomp001': ['A.hs', 'B.hs', 'myghc.hs'],
+ 'barton-mangler-bug': ['Basic.hs', 'Expected.hs', 'Main.hs', 'Physical.hs', 'Plot.lhs', 'PlotExample.lhs', 'TypesettingTricks.hs'],
+ 'base01': ['GHC'],
+ 'boolFormula': ['TestBoolFormula.hs'],
+ 'break001': ['../Test2.hs'],
+ 'break002': ['../Test2.hs'],
+ 'break003': ['../Test3.hs'],
+ 'break005': ['../QSort.hs'],
+ 'break006': ['../Test3.hs'],
+ 'break007': ['Break007.hs'],
+ 'break008': ['../Test3.hs'],
+ 'break009': ['../Test6.hs'],
+ 'break010': ['../Test6.hs'],
+ 'break011': ['../Test7.hs'],
+ 'break017': ['../QSort.hs'],
+ 'break018': ['../mdo.hs'],
+ 'break019': ['../Test2.hs'],
+ 'break020': ['Break020b.hs'],
+ 'break021': ['Break020b.hs', 'break020.hs'],
+ 'break022': ['A1.hs', 'B.hs', 'B.hs-boot', 'C.hs'],
+ 'break023': ['A1.hs', 'B.hs', 'B.hs-boot', 'C.hs'],
+ 'break027': ['../QSort.hs'],
+ 'bug1465': ['B1.hs', 'B2.hs', 'C.hs', 'v1/', 'v2/'],
+ 'bug1677': ['Bar.hs', 'Foo.hs'],
+ 'bundle-export': ['BundleExport.hs'],
+ 'cabal01': ['A.hs', 'B/', 'MainA.hs', 'Setup.lhs', 'c_src/', 'hello.c', 'test.cabal'],
+ 'cabal03': ['Setup.lhs', 'p/', 'q/', 'r/'],
+ 'cabal04': ['Library.hs', 'Setup.lhs', 'TH.hs', 'thtest.cabal'],
+ 'cabal05': ['Setup.hs', 'p/', 'q/', 'r/', 's/', 't/'],
+ 'cabal06': ['Setup.hs', 'p-1.0/', 'p-1.1/', 'q/', 'r/'],
+ 'cabal08': ['Main.hs', 'Setup.hs', 'p1/', 'p2/'],
+ 'cabal09': ['Main.hs', 'Setup.hs', 'reexport.cabal'],
+ 'ccfail004': ['Ccfail004A.hs'],
+ 'cgrun067': ['Cgrun067A.hs'],
+ 'cholewo-eval': ['Arr.lhs', 'Main.lhs'],
+ 'comments': ['CommentsTest.hs'],
+ 'concio001.thr': ['concio001.hs'],
+ 'concprog001': ['Arithmetic.hs', 'Converter.hs', 'Mult.hs', 'Stream.hs', 'Thread.hs', 'Trit.hs', 'Utilities.hs'],
+ 'concprog002': ['Event.hs', 'Scheduler.hs', 'Server.hs', 'Thread.hs'],
+ 'concprog003': ['CASList.hs', 'Collection.hs', 'IOList.lhs', 'ImmList.hs', 'MVarListLockCoupling.hs', 'Main.lhs', 'RefInterface.hs', 'TestData.hs', 'TestDataParser.hs', 'TestRun.hs', 'test-8-3000-3000-2-1-4'],
+ 'cvh_unboxing': ['Append.lhs', 'Main.lhs', 'Types.lhs'],
+ 'determ002': ['A.hs'],
+ 'determ003': ['A.hs'],
+ 'determ005': ['A.hs'],
+ 'determ006': ['spec-inline-determ.hs'],
+ 'determ010': ['A.hs'],
+ 'dodgy': ['DodgyA.hs'],
+ 'driver011': ['A011.hs'],
+ 'driver012': ['A012.hs'],
+ 'driver013': ['A013.hs'],
+ 'driver014': ['A014.hs'],
+ 'driver015': ['A015.hs'],
+ 'driver016': ['F016.hs'],
+ 'driver017': ['F017.hs'],
+ 'driver018': ['F018.hs'],
+ 'driver018a': ['F018a.hs'],
+ 'driver019': ['F019.hs'],
+ 'driver021': ['B021/'],
+ 'driver022': ['B022/'],
+ 'driver023': ['B023/'],
+ 'driver024': ['B024/'],
+ 'driver025': ['B025/'],
+ 'driver026': ['d026/'],
+ 'driver027': ['B027/'],
+ 'driver028': ['B028/'],
+ 'driver031': ['A031.hs'],
+ 'driver032': ['A032.hs'],
+ 'driver033': ['A033.hs'],
+ 'driver034': ['F034.hs'],
+ 'driver035': ['F035.hs'],
+ 'driver041': ['B041/'],
+ 'driver042': ['B042/'],
+ 'driver042stub': ['B042stub/'],
+ 'driver043': ['B043/'],
+ 'driver044': ['B044/'],
+ 'driver045': ['B045/'],
+ 'driver051': ['d051_1/', 'd051_2/'],
+ 'driver052': ['d052_1/', 'd052_2/'],
+ 'driver053': ['d053_1/', 'd053_2/'],
+ 'driver061a': ['A061a.hs'],
+ 'driver061b': ['A061b.hs'],
+ 'driver063': ['D063.hs'],
+ 'driver064': ['A064.hs'],
+ 'driver065': ['A065.hs'],
+ 'driver066': ['A066.hs'],
+ 'driver067': ['A067.hs'],
+ 'driver070': ['A070.hs'],
+ 'driver071': ['A071.hs'],
+ 'driver100': ['overlap/'],
+ 'driver200': ['A200.hs', 'B200/', 'D200.hs'],
+ 'dynamicToo001': ['A.hs', 'B.hs', 'B1.hs', 'B2.hs', 'C.hs'],
+ 'dynamicToo002': ['A.hs', 'B.hs', 'C.hs'],
+ 'dynamicToo003': ['A003.hs'],
+ 'dynamicToo004': ['Setup.hs', 'pkg1/', 'pkg1dyn/', 'pkg2/', 'prog.hs'],
+ 'dynamicToo005': ['A005.hsig'],
+ 'dynamicToo006': ['A.hsig', 'B.hs'],
+ 'dynamic_flags_001': ['A.hs', 'B.hs', 'C.hs'],
+ 'dynamic_flags_002A': ['A_First.hs', 'A_Main.hs', 'A_Second.hs'],
+ 'dynamic_flags_002B': ['B_First.hs', 'B_Main.hs', 'B_Second.hs'],
+ 'dynamic_flags_002C': ['C_Child.hs', 'C_Main.hs'],
+ 'dynamic_flags_002D': ['D_Child.hs', 'D_Main.hs'],
+ 'dynamic_flags_002Many': ['ManyFirst.hs', 'ManySecond.hs', 'ManyThird.hs'],
+ 'dynbrk001': ['../QSort.hs'],
+ 'dynbrk002': ['../QSort.hs'],
+ 'dynbrk004': ['../mdo.hs'],
+ 'dynbrk005': ['TupleN.hs'],
+ 'encoding004': ['encoded-data/'],
+ 'enum01': ['enum_processor.py'],
+ 'enum02': ['enum_processor.py'],
+ 'enum03': ['enum_processor.py'],
+ 'exampleTest': ['AnnotationTuple.hs'],
+ 'fast2haskell': ['Fast2haskell.hs', 'Main.hs'],
+ 'ffi018_ghci': ['ffi018.h'],
+ 'frontend01': ['FrontendPlugin.hs'],
+ 'fun_insts': ['Main.hs'],
+ 'gadt17': ['Gadt17_help.hs'],
+ 'gadt23': ['Gadt23_AST.hs'],
+ 'galois_raytrace': ['CSG.hs', 'Construct.hs', 'Data.hs', 'Eval.hs', 'Geometry.hs', 'Illumination.hs', 'Intersections.hs', 'Interval.hs', 'Main.hs', 'Misc.hs', 'Parse.hs', 'Primitives.hs', 'Surface.hs', 'galois.gml'],
+ 'getargs': ['../getargs.hs'],
+ 'ghci.prog007': ['A.hs', 'B.hs', 'C.hs', 'C.hs-boot'],
+ 'ghci.prog008': ['A.hs'],
+ 'ghci.prog009': ['A1.hs', 'A2.hs', 'A3.hs', 'B.hs'],
+ 'ghci025': ['Ghci025B.hs', 'Ghci025C.hs', 'Ghci025D.hs'],
+ 'ghci026': ['../prog002'],
+ 'ghci038': ['../shell.hs'],
+ 'ghci058': ['../shell.hs'],
+ 'ghcilink001': ['TestLink.hs', 'f.c'],
+ 'ghcilink002': ['TestLink.hs', 'f.c'],
+ 'ghcilink004': ['TestLink.hs', 'f.c'],
+ 'ghcilink005': ['TestLink.hs', 'f.c'],
+ 'ghcpkg01': ['test.pkg', 'test2.pkg', 'test3.pkg'],
+ 'ghcpkg03': ['test.pkg', 'test2.pkg', 'test4.pkg'],
+ 'ghcpkg04': ['test.pkg', 'test5.pkg'],
+ 'ghcpkg05': ['test2.pkg', 'test3.pkg'],
+ 'ghcpkg06': ['test.pkg', 'testdup.pkg'],
+ 'ghcpkg07': ['test.pkg', 'test7a.pkg', 'test7b.pkg'],
+ 'haddock.Cabal': ['../../../../libraries/Cabal/Cabal/dist-install/haddock.t'],
+ 'haddock.Test': ['Hidden.hs', 'Test.hs', 'Visible.hs'],
+ 'haddock.base': ['../../../../libraries/base/dist-install/haddock.t'],
+ 'haddock.compiler': ['../../../../compiler/stage2/haddock.t'],
+ 'heapprof002': ['heapprof001.hs'],
+ 'hist001': ['../Test3.hs'],
+ 'hpc001': ['../hpcrun.pl'],
+ 'hpc_draft': ['.hpc/Main.mix', 'hpc001.hs', 'hpc_sample.tix'],
+ 'hpc_fork': ['../hpcrun.pl'],
+ 'hpc_ghc_ghci': ['A.hs', 'B.hs'],
+ 'hpc_hand_overlay': ['.hpc/Main.mix', 'hand_overlay.ovr', 'hpc001.hs', 'hpc_sample.tix'],
+ 'hpc_markup_001': ['.hpc/Main.mix', 'hpc001.hs', 'hpc_sample.tix'],
+ 'hpc_markup_002': ['.hpc/Main.mix', 'hpc001.hs', 'hpc_sample.tix'],
+ 'hpc_markup_multi_001': ['../Geometry.hs', '.hpc/', 'hpc_sample.tix'],
+ 'hpc_markup_multi_002': ['../CSG.hs', '../Construct.hs', '../Data.hs', '../Eval.hs', '../Geometry.hs', '../Illumination.hs', '../Intersections.hs', '../Interval.hs', '../Main.hs', '../Misc.hs', '../Parse.hs', '../Pixmap.hs', '../Primitives.hs', '../RayTrace.hs', '../Surface.hs', '.hpc/', 'hpc_sample.tix'],
+ 'hpc_markup_multi_003': ['../CSG.hs', '../Construct.hs', '../Data.hs', '../Eval.hs', '../Geometry.hs', '../Illumination.hs', '../Intersections.hs', '../Interval.hs', '../Main.hs', '../Misc.hs', '../Parse.hs', '../Pixmap.hs', '../Primitives.hs', '../RayTrace.hs', '../Surface.hs', '.hpc/', 'hpc_sample.tix'],
+ 'hpc_overlay': ['.hpc/Main.mix', 'hpc001.hs', 'hpc_sample.tix', 'sample_overlay.ovr'],
+ 'hpc_overlay2': ['.hpc/Main.mix', 'hpc001.hs', 'hpc_sample.tix', 'sample_overlay.ovr'],
+ 'hpc_raytrace': ['../hpcrun.pl', 'CSG.hs', 'Construct.hs', 'Data.hs', 'Eval.hs', 'Geometry.hs', 'Illumination.hs', 'Intersections.hs', 'Interval.hs', 'Main.hs', 'Misc.hs', 'Parse.hs', 'Primitives.hs', 'Surface.hs', 'galois.gml', 'galois.sample'],
+ 'hpc_report_001': ['.hpc/Main.mix', 'hpc_sample.tix'],
+ 'hpc_report_002': ['.hpc/Main.mix', 'hpc_sample.tix'],
+ 'hpc_report_003': ['.hpc/Main.mix', 'hpc_sample.tix'],
+ 'hpc_report_multi_001': ['.hpc/Geometry.mix', 'hpc_sample.tix'],
+ 'hpc_report_multi_002': ['.hpc/', 'hpc_sample.tix'],
+ 'hpc_report_multi_003': ['.hpc/Geometry.mix', 'hpc_sample.tix'],
+ 'hpc_show': ['.hpc/Main.mix', 'hpc_sample.tix'],
+ 'hpc_show_multi_001': ['.hpc/', 'hpc_sample.tix'],
+ 'hpc_show_multi_002': ['.hpc/Geometry.mix', 'hpc_sample.tix'],
+ 'hs-boot': ['A.hs', 'A.hs-boot', 'B.hs', 'C.hs', 'Main.hs'],
+ 'impexp': ['Exp.hs', 'Imp.hs'],
+ 'ind2': ['Ind2_help.hs'],
+ 'jl_defaults': ['Main.hs'],
+ 'joao-circular': ['Data_Lazy.hs', 'Funcs_Lexer.hs', 'Funcs_Parser_Lazy.hs', 'LrcPrelude.hs', 'Main.hs', 'Visfun_Lazy.hs', 'inp'],
+ 'jq_readsPrec': ['Main.hs'],
+ 'jtod_circint': ['Bit.hs', 'LogFun.hs', 'Main.hs', 'Signal.hs'],
+ 'jules_xref': ['Main.hs'],
+ 'jules_xref2': ['Main.hs'],
+ 'landmines': ['MineFixity.hs', 'MineKind.hs', 'MineNames.hs', 'MineType.hs'],
+ 'launchbury': ['Main.hs'],
+ 'lazy-bs-alloc': ['../../numeric/should_run/arith011.stdout'],
+ 'lennart_range': ['Main.hs'],
+ 'lex': ['Main.hs'],
+ 'life_space_leak': ['Main.hs'],
+ 'linker_error1': ['linker_error.c'],
+ 'linker_error2': ['linker_error.c'],
+ 'linker_error3': ['linker_error.c'],
+ 'linker_unload': ['LinkerUnload.hs', 'Test.hs'],
+ 'listCommand001': ['../Test3.hs'],
+ 'listcomps': ['ListComprehensions.hs'],
+ 'literals': ['LiteralsTest.hs'],
+ 'load_short_name': ['A.c'],
+ 'maessen_hashtab': ['Data/', 'HashTest.hs'],
+ 'memo001': ['Memo1.lhs'],
+ 'memo002': ['Memo2.lhs'],
+ 'mod101': ['Mod101_AuxA.hs', 'Mod101_AuxB.hs'],
+ 'mod102': ['Mod102_AuxA.hs', 'Mod102_AuxB.hs'],
+ 'mod114': ['Mod114_Help.hs'],
+ 'mod115': ['Mod115_A.hs', 'Mod115_B.hs'],
+ 'mod117': ['Mod117_A.hs', 'Mod117_B.hs'],
+ 'mod118': ['Mod118_A.hs', 'Mod118_B.hs'],
+ 'mod119': ['Mod119_A.hs', 'Mod119_B.hs'],
+ 'mod120': ['Mod120_A.hs'],
+ 'mod121': ['Mod121_A.hs'],
+ 'mod122': ['Mod122_A.hs'],
+ 'mod123': ['Mod123_A.hs'],
+ 'mod124': ['Mod124_A.hs'],
+ 'mod125': ['Mod125_A.hs'],
+ 'mod126': ['Mod126_A.hs'],
+ 'mod127': ['Mod127_A.hs'],
+ 'mod128': ['Mod128_A.hs'],
+ 'mod131': ['Mod131_A.hs', 'Mod131_B.hs'],
+ 'mod132': ['Mod132_A.hs', 'Mod132_B.hs'],
+ 'mod136': ['Mod136_A.hs'],
+ 'mod137': ['Mod137_A.hs'],
+ 'mod138': ['Mod138_A.hs'],
+ 'mod139': ['Mod139_A.hs', 'Mod139_B.hs'],
+ 'mod140': ['Mod140_A.hs'],
+ 'mod141': ['Mod141_A.hs'],
+ 'mod142': ['Mod142_A.hs'],
+ 'mod143': ['Mod143_A.hs'],
+ 'mod144': ['Mod144_A.hs'],
+ 'mod145': ['Mod145_A.hs'],
+ 'mod146': ['Mod145_A.hs'],
+ 'mod147': ['Mod147_A.hs'],
+ 'mod157': ['Mod157_A.hs', 'Mod157_B.hs', 'Mod157_C.hs', 'Mod157_D.hs'],
+ 'mod158': ['Mod157_A.hs', 'Mod157_B.hs', 'Mod157_C.hs', 'Mod157_D.hs'],
+ 'mod159': ['Mod159_A.hs', 'Mod159_B.hs', 'Mod159_C.hs', 'Mod159_D.hs'],
+ 'mod160': ['Mod159_A.hs', 'Mod159_B.hs', 'Mod159_C.hs', 'Mod159_D.hs'],
+ 'mod162': ['Mod162_A.hs'],
+ 'mod163': ['Mod163_A.hs'],
+ 'mod164': ['Mod164_A.hs', 'Mod164_B.hs'],
+ 'mod165': ['Mod164_A.hs', 'Mod164_B.hs'],
+ 'mod166': ['Mod164_A.hs', 'Mod164_B.hs'],
+ 'mod167': ['Mod164_A.hs', 'Mod164_B.hs'],
+ 'mod170': ['Mod170_A.hs'],
+ 'mod171': ['Mod171_A.hs', 'Mod171_B.hs'],
+ 'mod172': ['Mod172_B.hs', 'Mod172_C.hs'],
+ 'mod173': ['Mod173_Aux.hs'],
+ 'mod175': ['Test.hs', 'Test2.hs'],
+ 'mod178': ['Mod178_2.hs'],
+ 'mod179': ['Mod179_A.hs'],
+ 'mod180': ['Mod180_A.hs', 'Mod180_B.hs'],
+ 'north_array': ['Main.hs'],
+ 'okeefe_neural': ['Main.hs'],
+ 'overloadedlabelsrun04': ['OverloadedLabelsRun04_A.hs'],
+ 'overloadedrecfldsfail04': ['OverloadedRecFldsFail04_A.hs'],
+ 'overloadedrecfldsfail06': ['OverloadedRecFldsFail06_A.hs'],
+ 'overloadedrecfldsfail10': ['OverloadedRecFldsFail10_A.hs', 'OverloadedRecFldsFail10_B.hs', 'OverloadedRecFldsFail10_C.hs'],
+ 'overloadedrecfldsfail11': ['OverloadedRecFldsFail11_A.hs'],
+ 'overloadedrecfldsfail12': ['OverloadedRecFldsFail12_A.hs'],
+ 'overloadedrecfldsrun02': ['OverloadedRecFldsRun02_A.hs'],
+ 'p10': ['D.hs'],
+ 'p11': ['E.hs'],
+ 'p13': ['P13_A.hs'],
+ 'p7': ['A.hs'],
+ 'p8': ['B.hs'],
+ 'p9': ['C.hs'],
+ 'parseTree': ['AnnotationTuple.hs'],
+ 'parsed': ['LiteralsTest2.hs'],
+ 'parser.prog001': ['Read006.hs', 'Read007.hs'],
+ 'pat-syn-bundle': ['Bundle1.hs', 'BundleInternal1.hs'],
+ 'pat-syn-trans-bundle': ['Bundle.hs', 'BundleInternal.hs', 'TransBundle.hs'],
+ 'pkg02': ['A.hs', 'Foreign.hs'],
+ 'plugins01': ['simple-plugin/'],
+ 'plugins02': ['simple-plugin/'],
+ 'plugins03': ['simple-plugin/'],
+ 'plugins04': ['HomePackagePlugin.hs'],
+ 'plugins05': ['HomePackagePlugin.hs'],
+ 'plugins06': ['LinkerTicklingPlugin.hs'],
+ 'plugins07': ['rule-defining-plugin/'],
+ 'print002': ['../Test.hs'],
+ 'print003': ['../Test.hs'],
+ 'print005': ['../QSort.hs'],
+ 'print006': ['../Test.hs'],
+ 'print007': ['../Test.hs'],
+ 'print008': ['../Test.hs'],
+ 'print010': ['../Test.hs'],
+ 'print011': ['../Test.hs'],
+ 'print012': ['../GADT.hs', '../Test.hs'],
+ 'print013': ['../GADT.hs'],
+ 'print014': ['../GADT.hs'],
+ 'print016': ['../Test.hs'],
+ 'print017': ['../Test.hs'],
+ 'print018': ['../Test.hs'],
+ 'print019': ['../Test.hs'],
+ 'print020': ['../HappyTest.hs'],
+ 'print023': ['../Test.hs'],
+ 'print024': ['../Test.hs'],
+ 'print030': ['print029.hs'],
+ 'print032': ['print029.hs'],
+ 'print034': ['../GADT.hs', '../Test.hs'],
+ 'print035': ['../Unboxed.hs'],
+ 'prog001': ['../shell.hs', 'A.hs', 'B.hs', 'C1.hs', 'D1.hs', 'D2.hs'],
+ 'prog002': ['../shell.hs', 'A1.hs', 'A2.hs', 'B.hs', 'C.hs', 'D.hs'],
+ 'prog003': ['../shell.hs', 'A.hs', 'B.hs', 'C.hs', 'D1.hs', 'D2.hs'],
+ 'prog005': ['A1.hs', 'B.hs'],
+ 'prog006': ['A.hs', 'Boot.hs-boot', 'Boot1.hs', 'Boot2.hs'],
+ 'prog012': ['../shell.hs', 'Bar1.hs', 'Bar2.hs', 'Foo.hs', 'FooBar.hs'],
+ 'prog013': ['Bad.hs', 'Good.hs'],
+ 'prog014': ['Primop.hs', 'dummy.c'],
+ 'prog015': ['Level1.hs', 'Level2/', 'TopLevel.hs'],
+ 'prog016': ['Level1.hs', 'Level2/', 'TopLevel.hs'],
+ 'prog017': ['Level1.hs', 'Level2/', 'TopLevel.hs'],
+ 'qq005': ['Expr.hs', 'Main.hs'],
+ 'qq006': ['Expr.hs', 'Main.hs'],
+ 'qq007': ['QQ.hs', 'Test.hs'],
+ 'qq008': ['QQ.hs', 'Test.hs'],
+ 'qq009': ['QQ.hs', 'Test.hs'],
+ 'recomp001': ['A.hs', 'B1.hs', 'B2.hs', 'C.hs'],
+ 'recomp002': ['Q.hs', 'W.hs', 'W.hs-boot'],
+ 'recomp003': ['A.hs'],
+ 'recomp004': ['Main.hs', 'c.h', 'c1.c', 'c2.c'],
+ 'recomp005': ['A.hs', 'B.hs', 'C1.hs', 'C2.hs', 'D.hs', 'E.hs'],
+ 'recomp006': ['A.hs', 'B1.hs', 'B2.hs'],
+ 'recomp007': ['Setup.hs', 'a1/', 'a2/', 'b/'],
+ 'recomp008': ['A1.hs', 'A2.hs', 'B.hs', 'Main.hs'],
+ 'recomp009': ['Main.hs', 'Sub1.hs', 'Sub2.hs'],
+ 'recomp010': ['Main.hs', 'X1.hs', 'X2.hs'],
+ 'recomp011': ['Main.hs'],
+ 'recomp015': ['Generate.hs'],
+ 'record_upd': ['Main.hs'],
+ 'rename.prog001': ['Rn037Help.hs', 'rn037.hs'],
+ 'rename.prog002': ['Rn037Help.hs', 'rnfail037.hs'],
+ 'rename.prog003': ['A.hs', 'B.hs'],
+ 'rename.prog004': ['A.hs', 'B.hs', 'C.hs'],
+ 'rename.prog005': ['VersionGraphClient.hs', 'VersionGraphClient.hs-boot', 'View.hs', 'ViewType.hs'],
+ 'retc001': ['A.hs', 'B1.hs', 'B2.hs', 'C.hs'],
+ 'retc002': ['Q.hs', 'W.hs', 'W.hs-boot'],
+ 'retc003': ['A.hs'],
+ 'rittri': ['Main.hs'],
+ 'rn.prog006': ['A.hs', 'B/', 'Main.hs', 'pwd.hs'],
+ 'rn009': ['Imp10Aux.hs', 'Imp10Aux.hs-boot'],
+ 'rn011': ['Imp100Aux.hs', 'Imp100Aux.hs-boot'],
+ 'rn012': ['Imp500Aux.hs', 'Imp500Aux.hs-boot'],
+ 'rn017': ['RnAux017.hs', 'RnAux017.hs-boot'],
+ 'rn042': ['Rn042_A.hs'],
+ 'rn043': ['Rn043_A.hs', 'Rn043_B.hs'],
+ 'rn044': ['Rn044_A.hs', 'Rn044_B.hs'],
+ 'rn050': ['Rn050_A.hs'],
+ 'rn052': ['Rn052Aux.hs'],
+ 'rn053': ['Rn053_A.hs', 'Rn053_B.hs'],
+ 'rn059': ['Rn059_A.hs', 'Rn059_B.hs'],
+ 'rn065': ['Rn065A.hs'],
+ 'rn066': ['Rn066_A.hs'],
+ 'rn067': ['Rn067_A.hs'],
+ 'rnfail040': ['Rnfail040_A.hs'],
+ 'rnfail047': ['RnFail047_A.hs', 'RnFail047_A.hs-boot'],
+ 'rnfail055': ['RnFail055.hs', 'RnFail055.hs-boot', 'RnFail055_aux.hs'],
+ 'rtsopts001': ['rtsOpts.hs'],
+ 'safePkg01': ['M_SafePkg.hs', 'M_SafePkg2.hs', 'M_SafePkg3.hs', 'M_SafePkg4.hs', 'M_SafePkg5.hs', 'M_SafePkg6.hs', 'M_SafePkg7.hs', 'M_SafePkg8.hs', 'Setup.hs', 'p.cabal'],
+ 'sanders_array': ['Main.hs'],
+ 'seward-space-leak': ['Main.lhs'],
+ 'shared001': ['Shared001.hs'],
+ 'sigcabal01': ['Main.hs', 'Setup.hs', 'p/'],
+ 'sigof01': ['A.hs', 'B.hsig', 'Main.hs'],
+ 'sigof01m': ['A.hs', 'B.hsig', 'Main.hs'],
+ 'sigof02': ['Main.hs', 'Map.hsig'],
+ 'sigof02d': ['Double.hs', 'Map.hsig', 'MapAsSet.hsig'],
+ 'sigof02dm': ['Double.hs', 'Map.hsig', 'MapAsSet.hsig'],
+ 'sigof02dmt': ['Double.hs', 'Map.hsig', 'MapAsSet.hsig'],
+ 'sigof02dt': ['Double.hs', 'Map.hsig', 'MapAsSet.hsig'],
+ 'sigof02m': ['Main.hs', 'Map.hsig'],
+ 'sigof02mt': ['Main.hs', 'Map.hsig'],
+ 'sigof02t': ['Main.hs', 'Map.hsig'],
+ 'sigof03': ['A.hs', 'ASig1.hsig', 'ASig2.hsig', 'Main.hs'],
+ 'sigof03m': ['A.hs', 'ASig1.hsig', 'ASig2.hsig', 'Main.hs'],
+ 'sigof04': ['Sig.hsig'],
+ 'simpl020': ['Simpl020_A.hs'],
+ 'simpl021': ['Simpl021A.hs', 'Simpl021B.hs'],
+ 'simplCore.oneShot': ['OneShot1.hs', 'OneShot2.hs'],
+ 'simplCore.prog001': ['Simpl006Help.hs', 'simpl006.hs'],
+ 'simplCore.prog002': ['Simpl009Help.hs', 'simpl009.hs'],
+ 'stack002': ['stack001.hs'],
+ 'static001': ['Static001.hs'],
+ 'strict_anns': ['Main.hs'],
+ 'tc170': ['Tc170_Aux.hs'],
+ 'tc173': ['Tc173a.hs', 'Tc173b.hs'],
+ 'tc239': ['Tc239_Help.hs'],
+ 'tc245': ['Tc245_A.hs'],
+ 'tc251': ['Tc251_Help.hs'],
+ 'tc263': ['Tc263_Help.hs'],
+ 'tcfail186': ['Tcfail186_Help.hs'],
+ 'tcrun025': ['TcRun025_B.hs'],
+ 'tcrun038': ['TcRun038_B.hs'],
+ 'testwsdeque': ['../../../rts/WSDeque.h'],
+ 'thurston-modular-arith': ['Main.hs', 'TypeVal.hs'],
+ 'tough': ['../hpcrun.pl'],
+ 'tough2': ['../hpcrun.pl', 'subdir/'],
+ 'typecheck.prog001': ['A.hs', 'B.hs', 'C.hs'],
+ 'typecheck.prog002': ['A.hs', 'B.hs'],
+ 'typecheck.testeq1': ['FakePrelude.hs', 'Main.hs', 'TypeCast.hs', 'TypeEq.hs'],
+ 'write_interface_make': ['A011.hs'],
+ 'write_interface_oneshot': ['A011.hs'],
+}
diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py
index 0f751f2151..496fb35d3b 100644
--- a/testsuite/driver/runtests.py
+++ b/testsuite/driver/runtests.py
@@ -9,6 +9,8 @@ import os
import string
import getopt
import platform
+import shutil
+import tempfile
import time
import re
@@ -277,10 +279,31 @@ else:
# set stdout to unbuffered (is this the best way to do it?)
sys.stdout = os.fdopen(sys.__stdout__.fileno(), "w", 0)
+# Create a unique temporary directory inside '/tmp/ghctest'.
+ghctestdir = os.path.join(tempfile.gettempdir(), 'ghctest')
+# Don't start from scratch (i.e. don't rmtree(ghctestdir)). Running
+# 'make test' while another 'make test' hasn't completed yet should work.
+#shutil.rmtree(ghctestdir, ignore_errors=True)
+mkdirp(ghctestdir)
+tempdir = normalise_slashes_(tempfile.mkdtemp('', '', dir=ghctestdir))
+
+def cleanup_and_exit(exitcode):
+ if config.cleanup:
+ shutil.rmtree(tempdir, ignore_errors=True)
+ try:
+ os.rmdir(ghctestdir)
+ except OSError as e:
+ if e.errno == errno.ENOTEMPTY:
+ # Only delete ghctestdir if it is empty.
+ pass
+ else:
+ raise
+ exit(exitcode)
+
# First collect all the tests to be run
for file in t_files:
if_verbose(2, '====> Scanning %s' % file)
- newTestDir(os.path.dirname(file))
+ newTestDir(tempdir, os.path.dirname(file))
try:
exec(open(file).read())
except Exception:
@@ -291,7 +314,7 @@ for file in t_files:
if config.only:
# See Note [Mutating config.only]
sys.stderr.write("ERROR: tests not found: {0}\n".format(list(config.only)))
- sys.exit(1)
+ cleanup_and_exit(1)
if config.list_broken:
global brokens
@@ -327,5 +350,4 @@ else:
if config.summary_file != '':
summary(t, open(config.summary_file, 'w'))
-sys.exit(0)
-
+cleanup_and_exit(0)
diff --git a/testsuite/driver/testglobals.py b/testsuite/driver/testglobals.py
index d1976923a0..9f88acf445 100644
--- a/testsuite/driver/testglobals.py
+++ b/testsuite/driver/testglobals.py
@@ -210,6 +210,9 @@ class TestOptions:
# extra files to clean afterward
self.clean_files = []
+ # extra files to copy to the testdir
+ self.extra_files = []
+
# which -t numeric fields do we want to look at, and what bounds must
# they fall within?
# Elements of these lists should be things like
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index a7221847a7..f2e8a3d7d1 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -22,6 +22,7 @@ import subprocess
from testglobals import *
from testutil import *
+from extra_files import extra_src_files
try:
basestring
@@ -275,6 +276,12 @@ def extra_clean( files ):
def _extra_clean( name, opts, v ):
opts.clean_files = v
+def extra_files(files):
+ return lambda name, opts: _extra_files(name, opts, files)
+
+def _extra_files(name, opts, files):
+ opts.extra_files.extend(files)
+
# -----
def stats_num_field( field, expecteds ):
@@ -543,13 +550,27 @@ def executeSetups(fs, name, opts):
# -----------------------------------------------------------------------------
# The current directory of tests
-def newTestDir( dir ):
+def newTestDir(tempdir, dir):
+ # Hack. A few tests depend on files in ancestor directories
+ # (e.g. extra_files(['../../../../libraries/base/dist-install/haddock.t']))
+ # Make sure tempdir is sufficiently "deep", such that copying/linking those
+ # files won't cause any problems.
+ #
+ # If you received a framework failure about adding an extra level:
+ # * add one extra '../' to the startswith('../../../../../') in do_test
+ # * add one more number here:
+ tempdir = os.path.join(tempdir, '1', '2', '3')
+
global thisdir_settings
# reset the options for this test directory
- thisdir_settings = lambda name, opts, dir=dir: _newTestDir( name, opts, dir )
+ def settings(name, opts, tempdir=tempdir, dir=dir):
+ return _newTestDir(name, opts, tempdir, dir)
+ thisdir_settings = settings
-def _newTestDir( name, opts, dir ):
- opts.testdir = dir
+
+def _newTestDir(name, opts, tempdir, dir):
+ opts.srcdir = os.path.join(os.getcwd(), dir)
+ opts.testdir = os.path.join(tempdir, dir, name)
opts.compiler_always_flags = config.compiler_always_flags
# -----------------------------------------------------------------------------
@@ -683,18 +704,48 @@ def test_common_work (name, opts, func, args):
other_ways = list(filter(lambda way: way not in opts.extra_ways, do_ways))
do_ways = other_ways[:1] + explicit_ways
+ # Find all files in the source directory that this test
+ # depends on. Do this only once for all ways.
+ # Generously add all filenames that start with the name of
+ # the test to this set, as a convenience to test authors.
+ # They will have to use the `extra_files` setup function to
+ # specify all other files that their test depends on (but
+ # this seems to be necessary for only about 10% of all
+ # tests).
+ files = set((f for f in os.listdir(opts.srcdir)
+ if f.startswith(name)))
+ for filename in (opts.extra_files + extra_src_files.get(name, [])):
+ if filename.startswith('../../../../../'):
+ framework_fail(name, 'whole-test',
+ 'add extra level to testlib.py:newTestDir for: ' + filename)
+
+ elif filename.startswith('/'):
+ framework_fail(name, 'whole-test',
+ 'no absolute paths in extra_files please: ' + filename)
+
+ elif '*' in filename:
+ # Don't use wildcards in extra_files too much, as
+ # globbing is slow.
+ files.update((os.path.relpath(f, opts.srcdir)
+ for f in glob.iglob(in_srcdir(filename))))
+
+ else:
+ files.add(filename)
+
if not config.clean_only:
# Run the required tests...
for way in do_ways:
if stopping():
break
- do_test (name, way, func, args)
+ do_test(name, way, func, args, files)
for way in all_ways:
if way not in do_ways:
skiptest (name,way)
if config.cleanup and (config.clean_only or do_ways):
+ cleanup()
+ elif False: # TODO. Delete this code.
pretest_cleanup(name)
clean([name + suff for suff in [
'', '.exe', '.exe.manifest', '.genscript',
@@ -755,6 +806,7 @@ def test_common_work (name, opts, func, args):
framework_fail(name, 'runTest', 'Unhandled exception: ' + str(e))
def clean(strs):
+ return # TODO. Delete this function.
for str in strs:
if (str.endswith('.package.conf') or
str.startswith('package.conf.') and not str.endswith('/*')):
@@ -782,7 +834,9 @@ def clean_full_path(name):
if e2.errno != errno.ENOENT:
print(e2)
-def do_test(name, way, func, args):
+def do_test(name, way, func, args, files):
+ opts = getTestOpts()
+
full_name = name + '(' + way + ')'
try:
@@ -792,6 +846,66 @@ def do_test(name, way, func, args):
t.n_unexpected_failures, \
t.n_framework_failures]))
+ # Clean up prior to the test, so that we can't spuriously conclude
+ # that it passed on the basis of old run outputs.
+ cleanup()
+
+ # Link all source files for this test into a new directory in
+ # /tmp, and run the test in that directory. This makes it
+ # possible to run tests in parallel, without modification, that
+ # would otherwise (accidentally) write to the same output file.
+ # It also makes it easier to keep the testsuite clean.
+
+ for filename in files:
+ src = in_srcdir(filename)
+ dst = in_testdir(filename)
+
+ if os.path.isfile(src):
+ dirname = os.path.dirname(dst)
+ if dirname:
+ mkdirp(dirname)
+ try:
+ link_or_copy_file(src, dst)
+ except OSError as e:
+ if e.errno == errno.EEXIST and os.path.isfile(dst):
+ # Some tests depend on files from ancestor
+ # directories (e.g. '../shell.hs'). It is
+ # possible such a file was already copied over
+ # for another test, since cleanup() doesn't
+ # delete them.
+ pass
+ else:
+ raise
+ elif os.path.isdir(src):
+ os.makedirs(dst)
+ lndir(src, dst)
+ else:
+ if not config.haddock and os.path.splitext(filename)[1] == '.t':
+ # When using a ghc built without haddock support, .t
+ # files are rightfully missing. Don't
+ # framework_fail. Test will be skipped later.
+ pass
+ else:
+ framework_fail(name, way,
+ 'extra_file does not exist: ' + filename)
+
+ if not files:
+ # Always create the testdir, even when no files were copied
+ # (because user forgot to specify extra_files setup function), to
+ # prevent the confusing error: can't cd to <testdir>.
+ os.makedirs(opts.testdir)
+
+ if func.__name__ == 'run_command' or opts.pre_cmd:
+ # When running 'MAKE' make sure 'TOP' still points to the
+ # root of the testsuite.
+ src_makefile = in_srcdir('Makefile')
+ dst_makefile = in_testdir('Makefile')
+ if os.path.exists(src_makefile):
+ with open(src_makefile, 'r') as src:
+ makefile = re.sub('TOP=.*', 'TOP=' + config.top, src.read(), 1)
+ with open(dst_makefile, 'w') as dst:
+ dst.write(makefile)
+
if config.use_threads:
t.lock.release()
@@ -1262,7 +1376,7 @@ def simple_run(name, way, prog, extra_run_opts):
use_stdin = opts.stdin
else:
stdin_file = add_suffix(name, 'stdin')
- if os.path.exists(in_testdir(stdin_file)):
+ if os.path.exists(in_srcdir(stdin_file)):
use_stdin = stdin_file
else:
use_stdin = '/dev/null'
@@ -1393,9 +1507,9 @@ def interpreter_run( name, way, extra_hc_opts, compile_only, top_mod ):
# figure out what to use for stdin
if getTestOpts().stdin != '':
- stdin_file = in_testdir(getTestOpts().stdin)
+ stdin_file = in_srcdir(opts.stdin)
else:
- stdin_file = qualify(name, 'stdin')
+ stdin_file = in_srcdir(name, 'stdin')
if os.path.exists(stdin_file):
os.system('cat ' + stdin_file + ' >>' + qscriptname)
@@ -1603,11 +1717,12 @@ def check_prof_ok(name, way):
def compare_outputs(way, kind, normaliser, expected_file, actual_file,
whitespace_normaliser=lambda x:x):
- expected_path = in_testdir(expected_file)
+ expected_path = in_srcdir(expected_file)
actual_path = in_testdir(actual_file)
if os.path.exists(expected_path):
expected_str = normaliser(read_no_crs(expected_path))
+ # Create the .normalised file in the testdir, not in the srcdir.
expected_normalised_file = add_suffix(expected_file, 'normalised')
expected_normalised_path = in_testdir(expected_normalised_file)
else:
@@ -1651,7 +1766,7 @@ def compare_outputs(way, kind, normaliser, expected_file, actual_file,
return 1
elif config.accept:
if_verbose(1, 'No output. Deleting {0}.'.format(expected_path))
- rm_no_fail(expected_path)
+ os.remove(expected_path)
return 1
else:
return 0
@@ -2108,6 +2223,7 @@ if config.have_profiling:
gsNotWorking();
def rm_no_fail( file ):
+ return # TODO. Delete this function.
try:
os.remove( file )
finally:
@@ -2138,11 +2254,13 @@ def replace_suffix( name, suffix ):
return base + '.' + suffix
def in_testdir(name, suffix=''):
- return getTestOpts().testdir + '/' + add_suffix(name, suffix)
+ return os.path.join(getTestOpts().testdir, add_suffix(name, suffix))
def qualify( name, suff ):
return in_testdir(add_suffix(name, suff))
+def in_srcdir(name, suffix=''):
+ return os.path.join(getTestOpts().srcdir, add_suffix(name, suffix))
# Finding the sample output. The filename is of the form
#
@@ -2150,7 +2268,7 @@ def qualify( name, suff ):
#
def find_expected_file(name, suff):
basename = add_suffix(name, suff)
- basepath = in_testdir(basename)
+ basepath = in_srcdir(basename)
files = [(platformSpecific, basename + ws + plat)
for (platformSpecific, plat) in [(1, '-' + config.platform),
@@ -2162,7 +2280,7 @@ def find_expected_file(name, suff):
dir = [normalise_slashes_(d) for d in dir]
for (platformSpecific, f) in files:
- if in_testdir(f) in dir:
+ if in_srcdir(f) in dir:
return (platformSpecific,f)
return (0, basename)
@@ -2170,6 +2288,7 @@ def find_expected_file(name, suff):
# Clean up prior to the test, so that we can't spuriously conclude
# that it passed on the basis of old run outputs.
def pretest_cleanup(name):
+ return # TODO. Delete this function.
if getTestOpts().outputdir != None:
odir = in_testdir(getTestOpts().outputdir)
try:
@@ -2191,6 +2310,10 @@ def pretest_cleanup(name):
# rm_nofail(qualify(""))
# not interested in the return code
+def cleanup():
+ shutil.rmtree(getTestOpts().testdir, ignore_errors=True)
+
+
# -----------------------------------------------------------------------------
# Return a list of all the files ending in '.T' below directories roots.
diff --git a/testsuite/driver/testutil.py b/testsuite/driver/testutil.py
index 029a3b6cb9..563ba3646c 100644
--- a/testsuite/driver/testutil.py
+++ b/testsuite/driver/testutil.py
@@ -1,7 +1,10 @@
# -----------------------------------------------------------------------------
# Utils
+import errno
+import os
import subprocess
+import shutil
def version_to_ints(v):
return [ int(x) for x in v.split('.') ]
@@ -36,3 +39,32 @@ def getStdout(cmd_and_args):
if stderr:
raise Exception("stderr from command: " + str(cmd_and_args))
return stdout
+
+def mkdirp(path):
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno == errno.EEXIST and os.path.isdir(path):
+ pass
+ else:
+ raise
+
+def lndir(srcdir, dstdir):
+ # Create symlinks for all files in src directory.
+ # Not all developers might have lndir installed.
+ # os.system('lndir -silent {0} {1}'.format(srcdir, dstdir))
+ for filename in os.listdir(srcdir):
+ src = os.path.join(srcdir, filename)
+ dst = os.path.join(dstdir, filename)
+ if os.path.isfile(src):
+ link_or_copy_file(src, dst)
+ else:
+ os.mkdir(dst)
+ lndir(src, dst)
+
+# On Windows, os.symlink is not defined. Except when using msys2, as ghc
+# does. Then it copies the source file, instead of creating a symbolic
+# link to it. We define the following function to make this magic more
+# explicit/discoverable. You are enouraged to use it instead of
+# os.symlink.
+link_or_copy_file = getattr(os, "symlink", shutil.copyfile)
diff --git a/testsuite/tests/plugins/all.T b/testsuite/tests/plugins/all.T
index 7cf412c260..caa831efc6 100644
--- a/testsuite/tests/plugins/all.T
+++ b/testsuite/tests/plugins/all.T
@@ -5,18 +5,19 @@ def f(name, opts):
setTestOpts(f)
test('plugins01',
- [pre_cmd('$MAKE -s --no-print-directory -C simple-plugin package.plugins01'),
+ [pre_cmd('$MAKE -s --no-print-directory -C simple-plugin package.plugins01 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C simple-plugin clean.plugins01')],
run_command,
['$MAKE -s --no-print-directory plugins01'])
+
test('plugins02',
- [pre_cmd('$MAKE -s --no-print-directory -C simple-plugin package.plugins02'),
+ [pre_cmd('$MAKE -s --no-print-directory -C simple-plugin package.plugins02 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C simple-plugin clean.plugins02')],
compile_fail,
['-package-db simple-plugin/pkg.plugins02/local.package.conf -fplugin Simple.BadlyTypedPlugin -package simple-plugin ' + config.plugin_way_flags])
test('plugins03',
- [pre_cmd('$MAKE -s --no-print-directory -C simple-plugin package.plugins03'),
+ [pre_cmd('$MAKE -s --no-print-directory -C simple-plugin package.plugins03 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C simple-plugin clean.plugins03')],
compile_fail,
['-package-db simple-plugin/pkg.plugins03/local.package.conf -fplugin Simple.NonExistantPlugin -package simple-plugin'])
@@ -38,26 +39,26 @@ test('plugins06',
multimod_compile_and_run, ['plugins06', '-package ghc'])
test('plugins07',
- [pre_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin package.plugins07'),
+ [pre_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin package.plugins07 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin clean.plugins07')],
run_command,
['$MAKE -s --no-print-directory plugins07'])
test('T10420',
- [pre_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin package.T10420'),
+ [pre_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin package.T10420 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin clean.T10420')],
run_command,
['$MAKE -s --no-print-directory T10420'])
test('T10294',
- [pre_cmd('$MAKE -s --no-print-directory -C annotation-plugin package.T10294'),
+ [pre_cmd('$MAKE -s --no-print-directory -C annotation-plugin package.T10294 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C annotation-plugin clean.T10294'),
unless(have_dynamic(),expect_broken(10301))],
run_command,
['$MAKE -s --no-print-directory T10294'])
test('T10294a',
- [pre_cmd('$MAKE -s --no-print-directory -C annotation-plugin package.T10294a'),
+ [pre_cmd('$MAKE -s --no-print-directory -C annotation-plugin package.T10294a TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C annotation-plugin clean.T10294a')],
run_command,
['$MAKE -s --no-print-directory T10294a'])
@@ -69,7 +70,7 @@ test('frontend01',
run_command, ['$MAKE -s --no-print-directory frontend01'])
test('T11244',
- [pre_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin package.T11244'),
+ [pre_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin package.T11244 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C rule-defining-plugin clean.T11244')],
run_command,
['$MAKE -s --no-print-directory T11244'])
diff --git a/testsuite/tests/simplCore/should_compile/all.T b/testsuite/tests/simplCore/should_compile/all.T
index 7aba48508f..0e03b1696c 100644
--- a/testsuite/tests/simplCore/should_compile/all.T
+++ b/testsuite/tests/simplCore/should_compile/all.T
@@ -170,7 +170,7 @@ test('T5550', omit_ways(prof_ways), compile, [''])
test('T7865', normal, run_command, ['$MAKE -s --no-print-directory T7865'])
test('T7785', only_ways(['optasm']), compile, ['-ddump-rules'])
test('T7702',
- [pre_cmd('$MAKE -s --no-print-directory -C T7702plugin package.T7702'),
+ [pre_cmd('$MAKE -s --no-print-directory -C T7702plugin package.T7702 TOP={top}'),
clean_cmd('$MAKE -s --no-print-directory -C T7702plugin clean.T7702'),
# we say 18mb peak allocated +/- 70% because other compiler flags have
# a large effect on allocation which is hard to separate from the