]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/test/toolset-mock/src/MockProgram.py
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / tools / build / test / toolset-mock / src / MockProgram.py
CommitLineData
11fdf7f2
TL
1# Copyright 2017 Steven Watanabe
2#
3# Distributed under the Boost Software License, Version 1.0.
4# (See accompanying file LICENSE_1_0.txt or copy at
5# http://www.boost.org/LICENSE_1_0.txt)
6
7import sys
8import os
9import re
10
11# Represents a sequence of arguments that must appear
12# in a fixed order.
13class ordered:
14 def __init__(self, *args):
15 self.args = args
16 def match(self, command_line, pos, outputs):
17 for p in self.args:
18 res = try_match(command_line, pos, p, outputs)
19 if res is None:
20 return
21 pos = res
22 return pos
23
24# Represents a sequence of arguments that can appear
25# in any order.
26class unordered:
27 def __init__(self, *args):
28 self.args = list(args)
29 def match(self, command_line, pos, outputs):
30 unmatched = self.args[:]
31 while len(unmatched) > 0:
32 res = try_match_one(command_line, pos, unmatched, outputs)
33 if res is None:
34 return
35 pos = res
36 return pos
37
38# Represents a single input file.
39# If id is set, then the file must have been created
40# by a prior use of output_file.
41# If source is set, then the file must be that source file.
42class input_file:
43 def __init__(self, id=None, source=None):
44 assert((id is None) ^ (source is None))
45 self.id = id
46 self.source = source
47 def check(self, path):
48 if path.startswith("-"):
49 return
50 if self.id is not None:
51 try:
52 with open(path, "r") as f:
53 data = f.read()
54 if data == make_file_contents(self.id):
55 return True
56 else:
57 return
58 except:
59 return
60 elif self.source is not None:
61 if self.source == path:
62 return True
63 else:
64 return
65 assert(False)
66 def match(self, command_line, pos, outputs):
67 if self.check(command_line[pos]):
68 return pos + 1
69
70# Matches an output file.
71# If the full pattern is matched, The
72# file will be created.
73class output_file:
74 def __init__(self, id):
75 self.id = id
76 def match(self, command_line, pos, outputs):
77 if command_line[pos].startswith("-"):
78 return
79 outputs.append((command_line[pos], self.id))
80 return pos + 1
81
82# Matches the directory containing an input_file
83class target_path(object):
84 def __init__(self, id):
85 self.tester = input_file(id=id)
86 def match(self, command_line, pos, outputs):
87 arg = command_line[pos]
88 if arg.startswith("-"):
89 return
90 try:
91 for path in os.listdir(arg):
92 if self.tester.check(os.path.join(arg, path)):
93 return pos + 1
94 except:
95 return
96
97# Matches a single argument, which is composed of a prefix and a path
98# for example arguments of the form -ofilename.
99class arg(object):
100 def __init__(self, prefix, a):
101 # The prefix should be a string, a should be target_path or input_file.
102 self.prefix = prefix
103 self.a = a
104 def match(self, command_line, pos, outputs):
105 s = command_line[pos]
106 if s.startswith(self.prefix) and try_match([s[len(self.prefix):]], 0, self.a, outputs) == 1:
107 return pos + 1
108
109# Given a file id, returns a string that will be
110# written to the file to allow it to be recognized.
111def make_file_contents(id):
112 return id
113
114# Matches a single pattern from a list.
115# If it succeeds, the matching pattern
116# is removed from the list.
117# Returns the index after the end of the match
118def try_match_one(command_line, pos, patterns, outputs):
119 for p in patterns:
120 tmp = outputs[:]
121 res = try_match(command_line, pos, p, tmp)
122 if res is not None:
123 outputs[:] = tmp
124 patterns.remove(p)
125 return res
126
127# returns the end of the match if any
128def try_match(command_line, pos, pattern, outputs):
129 if pos == len(command_line):
130 return
131 elif type(pattern) is str:
132 if pattern == command_line[pos]:
133 return pos + 1
134 else:
135 return pattern.match(command_line, pos, outputs)
136
137known_patterns = []
138program_name = None
139
140# Registers a command
141# The arguments should be a sequence of:
142# str, ordered, unordered, arg, input_file, output_file, target_path
143# kwarg: stdout is text that will be printed on success.
144def command(*args, **kwargs):
145 global known_patterns
146 global program_name
147 stdout = kwargs.get("stdout", None)
148 pattern = ordered(*args)
149 known_patterns += [(pattern, stdout)]
150 if program_name is None:
151 program_name = args[0]
152 else:
153 assert(program_name == args[0])
154
155# Use this to filter the recognized commands, based on the properties
156# passed to b2.
157def allow_properties(*args):
158 try:
159 return all(a in os.environ["B2_PROPERTIES"].split(" ") for a in args)
160 except KeyError:
161 return True
162
163# Use this in the stdout argument of command to print the command
164# for running another script.
165def script(name):
166 return os.path.join(os.path.dirname(__file__), "bin", re.sub('\.py$', '', name))
167
168def match(command_line):
169 for (p, stdout) in known_patterns:
170 outputs = []
171 if try_match(command_line, 0, p, outputs) == len(command_line):
172 return (stdout, outputs)
173
174# Every mock program should call this after setting up all the commands.
175def main():
176 command_line = [program_name] + sys.argv[1:]
177 result = match(command_line)
178 if result is not None:
179 (stdout, outputs) = result
180 if stdout is not None:
181 print stdout
182 for (file,id) in outputs:
183 with open(file, "w") as f:
184 f.write(make_file_contents(id))
185 exit(0)
186 else:
187 print command_line
188 exit(1)
189
190# file should be the name of a file in the same directory
191# as this. Must be called after verify_setup
192def verify_file(filename):
193 global known_files
194 if filename not in known_files:
195 known_files.add(filename)
196 srcdir = os.path.dirname(__file__)
197 execfile(os.path.join(srcdir, filename), {})
198
199def verify_setup():
200 """Override the behavior of most module components
201 in order to detect whether they are being used correctly."""
202 global main
203 global allow_properties
204 global output_file
205 global input_file
206 global target_path
207 global script
208 global command
209 global verify_errors
210 global output_ids
211 global input_ids
212 global known_files
213 def allow_properties(*args):
214 return True
215 def main():
216 pass
217 def output_file(id):
218 global output_ids
219 global verify_error
220 if id in output_ids:
221 verify_error("duplicate output_file: %s" % id)
222 output_ids.add(id)
223 def input_file(id=None, source=None):
224 if id is not None:
225 input_ids.add(id)
226 def target_path(id):
227 input_ids.add(id)
228 def script(filename):
229 verify_file(filename)
230 def command(*args, **kwargs):
231 pass
232 verify_errors = []
233 output_ids = set()
234 input_ids = set()
235 known_files = set()
236
237def verify_error(message):
238 global verify_errors
239 verify_errors += [message]
240
241def verify_finalize():
242 for id in input_ids:
243 if not id in output_ids:
244 verify_error("Input file does not exist: %s" % id)
245 for error in verify_errors:
246 print "error: %s" % error
247 if len(verify_errors) != 0:
248 return 1
249 else:
250 return 0
251
252def verify():
253 srcdir = os.path.dirname(__file__)
254 if srcdir == '':
255 srcdir = '.'
256 verify_setup()
257 for f in os.listdir(srcdir):
258 if re.match(r"(gcc|clang|darwin|intel)-.*\.py", f):
259 verify_file(f)
260 exit(verify_finalize())