Fix #13839: GHCi warnings do not respect the default module header
[ghc.git] / testsuite / driver / testutil.py
1 import os
2 import platform
3 import subprocess
4 import shutil
5
6 import threading
7
8 def passed():
9 return {'passFail': 'pass'}
10
11 def failBecauseStderr(reason, stderr, tag=None):
12 return failBecause(reason, tag, stderr=stderr)
13
14 def failBecause(reason, tag=None, **kwargs):
15 return (dict ({'passFail': 'fail', 'reason': reason, 'tag': tag}, **kwargs))
16
17 def strip_quotes(s):
18 # Don't wrap commands to subprocess.call/Popen in quotes.
19 return s.strip('\'"')
20
21 def str_fail(s):
22 return '\033[1m\033[31m' + s + '\033[0m'
23
24 def str_pass(s):
25 return '\033[1m\033[32m' + s + '\033[0m'
26
27 def str_warn(s):
28 return '\033[1m\033[33m' + s + '\033[0m'
29
30 def str_info(s):
31 return '\033[1m\033[34m' + s + '\033[0m'
32
33 def getStdout(cmd_and_args):
34 # Can't use subprocess.check_output, since we also verify that
35 # no stderr was produced
36 p = subprocess.Popen([strip_quotes(cmd_and_args[0])] + cmd_and_args[1:],
37 stdout=subprocess.PIPE,
38 stderr=subprocess.PIPE)
39 (stdout, stderr) = p.communicate()
40 r = p.wait()
41 if r != 0:
42 raise Exception("Command failed: " + str(cmd_and_args))
43 if stderr:
44 raise Exception("stderr from command: %s\nOutput:\n%s\n" % (cmd_and_args, stderr))
45 return stdout.decode('utf-8')
46
47 def lndir(srcdir, dstdir):
48 # Create symlinks for all files in src directory.
49 # Not all developers might have lndir installed.
50 # os.system('lndir -silent {0} {1}'.format(srcdir, dstdir))
51 for filename in os.listdir(srcdir):
52 src = os.path.join(srcdir, filename)
53 dst = os.path.join(dstdir, filename)
54 if os.path.isfile(src):
55 link_or_copy_file(src, dst)
56 else:
57 os.mkdir(dst)
58 lndir(src, dst)
59
60 # On Windows, os.symlink is not defined with Python 2.7, but is in Python 3
61 # when using msys2, as GHC does. Unfortunately, only Administrative users have
62 # the privileges necessary to create symbolic links by default. Consequently we
63 # are forced to just copy instead.
64 #
65 # We define the following function to make this magic more
66 # explicit/discoverable. You are enouraged to use it instead of os.symlink.
67 if platform.system() == 'Windows' and os.getenv('FORCE_SYMLINKS') == None:
68 link_or_copy_file = shutil.copyfile
69 else:
70 link_or_copy_file = os.symlink
71
72 class Watcher(object):
73 def __init__(self, count):
74 self.pool = count
75 self.evt = threading.Event()
76 self.sync_lock = threading.Lock()
77 if count <= 0:
78 self.evt.set()
79
80 def wait(self):
81 self.evt.wait()
82
83 def notify(self):
84 self.sync_lock.acquire()
85 self.pool -= 1
86 if self.pool <= 0:
87 self.evt.set()
88 self.sync_lock.release()