3 # SPDX-License-Identifier: BSD-2-Clause
5 # Copyright (c) 2018-2020 Gavin D. Howard and contributors.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
10 # * Redistributions of source code must retain the above copyright notice, this
11 # list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
36 return random.randint(0, 2 ** (8 * limit))
39 return random.randint(0, 1) == 1
42 return random.randint(0, 2 ** (8) - 1) == 0
44 def num(op, neg, real, z, limit=4):
59 if real and negative():
63 n = ("0" * (length - len(n))) + n
85 def compare(exe, options, p, test, halt, expected, op, do_add=True):
89 print(" {} returned an error ({})".format(exe, p.returncode))
92 print(" adding to checklist...")
97 actual = p.stdout.decode()
99 if actual != expected:
103 indata = "scale += 10; {}; {}".format(test, halt)
104 args = [ exe, options ]
105 p2 = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
106 expected = p2.stdout[:-10].decode()
108 if actual == expected:
109 print(" failed because of bug in other {}".format(exe))
110 print(" continuing...")
114 print(" failed; adding to checklist...")
117 print(" failed {}".format(test))
119 print(" {}".format(expected))
121 print(" {}".format(actual))
126 scale = num(op, False, False, True, 5 / 8)
129 s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, True))
130 elif op == div or op == mod:
131 s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, False))
133 s = fmts[op].format(scale, num(op, True, True, True, 7 / 8), num(op, True, False, True, 6 / 8))
135 s = fmts[op].format(scale, num(op, True, False, True), num(op, True, False, True),
136 num(op, True, False, False))
140 s = num(op, False, True, True, 1)
141 s = fmts[op].format(scale, s)
145 first = num(op, True, True, True, 6 / 8)
147 first = num(op, False, True, True, 6 / 8)
149 first = num(op, True, True, True)
152 s = fmts[op].format(scale, first)
154 s = fmts[op].format(scale, first, 6 / 8)
160 op = random.randrange(bessel + 1)
173 if "c(0)" in test or "scale = 4; j(4" in test:
176 bcexe = exedir + "/" + exe
177 indata = test + "\n" + halt
179 print("Test {}: {}".format(t, test))
182 args = [ exe, options ]
186 p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
188 output1 = p.stdout.decode()
190 if p.returncode != 0 or output1 == "":
191 print(" other {} returned an error ({}); continuing...".format(exe, p.returncode))
195 print(" other {} has a bug; continuing...".format(exe))
198 if output1 == "-0\n":
200 elif output1 == "-0":
203 args = [ bcexe, options ]
205 p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
206 compare(exe, options, p, test, halt, output1, op)
209 if __name__ != "__main__":
213 testdir = os.path.dirname(script)
215 exedir = testdir + "/../bin"
217 ops = [ '+', '-', '*', '/', '%', '^', '|' ]
218 files = [ "add", "subtract", "multiply", "divide", "modulus", "power", "modexp",
219 "sqrt", "exponent", "log", "arctangent", "sine", "cosine", "bessel" ]
220 funcs = [ "sqrt", "e", "l", "a", "s", "c", "j" ]
222 fmts = [ "scale = {}; {} + {}", "scale = {}; {} - {}", "scale = {}; {} * {}",
223 "scale = {}; {} / {}", "scale = {}; {} % {}", "scale = {}; {} ^ {}",
224 "{}k {} {} {}|pR", "scale = {}; sqrt({})", "scale = {}; e({})",
225 "scale = {}; l({})", "scale = {}; a({})", "scale = {}; s({})",
226 "scale = {}; c({})", "scale = {}; j({}, {})" ]
244 except KeyboardInterrupt:
248 print("\nNo items in checklist.")
252 print("\nGoing through the checklist...\n")
254 if len(tests) != len(gen_ops):
255 print("Corrupted checklist!")
259 for i in range(0, len(tests)):
261 print("\n{}".format(tests[i]))
274 indata = tests[i] + "\n" + halt
276 args = [ exe, options ]
278 p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
280 expected = p.stdout.decode()
282 bcexe = exedir + "/" + exe
283 args = [ bcexe, options ]
285 p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
287 compare(exe, options, p, tests[i], halt, expected, op, False)
289 answer = input("\nAdd test ({}/{}) to test suite? [y/N]: ".format(i + 1, len(tests)))
291 if 'Y' in answer or 'y' in answer:
295 name = testdir + "/" + exe + "/" + files[op]
297 with open(name + ".txt", "a") as f:
298 f.write(tests[i] + "\n")
300 with open(name + "_results.txt", "a") as f: