freebsd-dev/contrib/bc/tests/history.py
Stefan Eßer 4fca8e0f65 contrib/bc: uodate to version 6.2.4
This update contains only documentation changes (new main repository
URL and changed mail address of the program author) and changes to
the build system that do not affect the FreeBSD base system build.

MFC after:	3 days
2023-02-06 22:33:56 +01:00

1158 lines
26 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! /usr/bin/python
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
import os, sys
import time
import signal
import traceback
try:
import pexpect
except ImportError:
print("Could not find pexpect. Skipping...")
sys.exit(0)
# Housekeeping.
script = sys.argv[0]
testdir = os.path.dirname(script)
if "BC_TEST_OUTPUT_DIR" in os.environ:
outputdir = os.environ["BC_TEST_OUTPUT_DIR"]
else:
outputdir = testdir
prompt = ">>> "
# This array is for escaping characters that are necessary to escape when
# outputting to pexpect. Since pexpect takes regexes, these characters confuse
# it unless we escape them.
escapes = [
']',
'[',
'+',
]
# UTF-8 stress tests.
utf8_stress1 = "ᆬḰ䋔䗅㜲ತ咡䒢岤䳰稨⣡嶣㷡嶏ⵐ䄺嵕ਅ奰痚㆜䊛拂䅙૩➋䛿ቬ竳Ϳᅠ❄产翷䮊௷Ỉ䷒䳜㛠➕傎ᗋᏯਕ䆐悙癐㺨"
utf8_stress2 = "韠싧돳넨큚ꉿ뮴픷ꉲ긌<EFBFBD>최릙걆鳬낽ꪁ퍼鈴핐黙헶ꪈ뮩쭀锻끥鉗겉욞며뛯꬐<EFBFBD><EFBFBD>度錐<EFBFBD>"
utf8_stress3 = "<EFBFBD>䣹昲蜴Ὓ桢㎏⚦珢畣갴ﭱ鶶ๅ⶛뀁彻ꖒ䔾ꢚﱤ햔햞㐹<EFBFBD>鼳뵡▿ⶾ꠩<EFBFBD>纞⊐佧<EFBFBD>ⵟ霘紳㱔籠뎼⊓搧硤"
utf8_stress4 = "ᄀ𖢾🏴<EFBFBD><EFBFBD>"
# An easy array for UTF-8 tests.
utf8_stress_strs = [
utf8_stress1,
utf8_stress2,
utf8_stress3,
utf8_stress4,
]
def expect(child, data):
child.expect(data)
# Eats all of the child's data.
# @param child The child whose data should be eaten.
def eat(child):
while child.buffer is not None and len(child.buffer) > 0:
expect(child, ".+")
# Send data to a child. This makes sure the buffers are empty first.
# @param child The child to send data to.
# @param data The data to send.
def send(child, data):
eat(child)
child.send(data)
def wait(child):
if child.isalive():
child.sendeof()
time.sleep(1)
if child.isalive():
child.kill(signal.SIGTERM)
time.sleep(1)
if child.isalive():
child.kill(signal.SIGKILL)
child.wait()
# Check that the child output the expected line. If history is false, then
# the output should change.
def check_line(child, expected, prompt=">>> ", history=True):
send(child, "\n")
prefix = "\r\n" if history else ""
expect(child, prefix + expected + "\r\n" + prompt)
# Write a string to output, checking all of the characters are output,
# one-by-one.
def write_str(child, s):
for c in s:
send(child, c)
if c in escapes:
expect(child, "\\{}".format(c))
else:
expect(child, c)
# Check the bc banner.
# @param child The child process.
def bc_banner(child):
bc_banner1 = "bc [0-9]+\.[0-9]+\.[0-9]+\r\n"
bc_banner2 = "Copyright \(c\) 2018-[2-9][0-9][0-9][0-9] Gavin D. Howard and contributors\r\n"
bc_banner3 = "Report bugs at: https://git.gavinhoward.com/gavin/bc\r\n\r\n"
bc_banner4 = "This is free software with ABSOLUTELY NO WARRANTY.\r\n\r\n"
expect(child, bc_banner1)
expect(child, bc_banner2)
expect(child, bc_banner3)
expect(child, bc_banner4)
expect(child, prompt)
# Common UTF-8 testing function. The index is the index into utf8_stress_strs
# for which stress string to use.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
# @param idx The index of the UTF-8 stress string.
def test_utf8(exe, args, env, idx, bc=True):
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
child = pexpect.spawn(exe, args=args, env=env, encoding='utf-8', codec_errors='ignore')
try:
# Write the stress string.
send(child, utf8_stress_strs[idx])
send(child, "\n")
if bc:
send(child, "quit")
else:
send(child, "q")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# A random UTF-8 test with insert.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_utf8_0(exe, args, env, bc=True):
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
child = pexpect.spawn(exe, args=args, env=env, encoding='utf-8', codec_errors='ignore')
try:
# Just random UTF-8 I generated somewhow, plus ensuring that insert works.
write_str(child, "ﴪáá̵̗🈐ã")
send(child, "\x1b[D\x1b[D\x1b[D\x1b\x1b[A")
send(child, "\n")
if bc:
send(child, "quit")
else:
send(child, "q")
send(child, "\n")
eat(child)
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
def test_utf8_1(exe, args, env, bc=True):
return test_utf8(exe, args, env, 0, bc)
def test_utf8_2(exe, args, env, bc=True):
return test_utf8(exe, args, env, 1, bc)
def test_utf8_3(exe, args, env, bc=True):
return test_utf8(exe, args, env, 2, bc)
def test_utf8_4(exe, args, env, bc=True):
return test_utf8(exe, args, env, 3, bc)
# This tests a SIGINT with reset followed by a SIGQUIT.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_sigint_sigquit(exe, args, env):
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
child = pexpect.spawn(exe, args=args, env=env)
try:
send(child, "\t")
expect(child, "\t")
send(child, "\x03")
# send(child, "\x1c")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Test for EOF.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_eof(exe, args, env):
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
child = pexpect.spawn(exe, args=args, env=env)
try:
send(child, "123")
expect(child, "123")
send(child, "\x01")
send(child, "\x04")
send(child, "\x04")
send(child, "\x04")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Test for quiting SIGINT.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_sigint(exe, args, env):
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
env["BC_SIGINT_RESET"] = "0"
env["DC_SIGINT_RESET"] = "0"
child = pexpect.spawn(exe, args=args, env=env)
try:
send(child, "\t")
expect(child, "\t")
send(child, "\x03")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Test for SIGTSTP.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_sigtstp(exe, args, env):
# This test does not work on FreeBSD, so skip.
if sys.platform.startswith("freebsd"):
sys.exit(0)
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
child = pexpect.spawn(exe, args=args, env=env)
try:
send(child, "\t")
expect(child, "\t")
send(child, "\x13")
time.sleep(1)
if not child.isalive():
print("child exited early")
print(str(child))
print(str(child.buffer))
sys.exit(1)
child.kill(signal.SIGCONT)
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Test for SIGSTOP.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_sigstop(exe, args, env):
# Because both bc and dc use this, make sure the banner doesn't pop.
env["BC_BANNER"] = "0"
child = pexpect.spawn(exe, args=args, env=env)
try:
send(child, "\t")
expect(child, "\t")
send(child, "\x14")
time.sleep(1)
if not child.isalive():
print("child exited early")
print(str(child))
print(str(child.buffer))
sys.exit(1)
send(child, "\x13")
time.sleep(1)
if not child.isalive():
print("child exited early")
print(str(child))
print(str(child.buffer))
sys.exit(1)
child.kill(signal.SIGCONT)
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
def test_bc_utf8_0(exe, args, env):
return test_utf8_0(exe, args, env, True)
def test_bc_utf8_1(exe, args, env):
return test_utf8_1(exe, args, env, True)
def test_bc_utf8_2(exe, args, env):
return test_utf8_2(exe, args, env, True)
def test_bc_utf8_3(exe, args, env):
return test_utf8_3(exe, args, env, True)
def test_bc_utf8_4(exe, args, env):
return test_utf8_4(exe, args, env, True)
# Basic bc test.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc1(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
write_str(child, "1")
check_line(child, "1")
write_str(child, "1")
check_line(child, "1")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# SIGINT with no history.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc2(exe, args, env):
env["TERM"] = "dumb"
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
child.sendline("1")
check_line(child, "1", history=False)
time.sleep(1)
child.sendintr()
child.sendline("quit")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Left and right arrows.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc3(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x1b[D\x1b[D\x1b[C\x1b[C")
send(child, "\n")
expect(child, prompt)
send(child, "12\x1b[D3\x1b[C4\x1bOD5\x1bOC6")
send(child, "\n")
check_line(child, "132546")
send(child, "12\x023\x064")
send(child, "\n")
check_line(child, "1324")
send(child, "12\x1b[H3\x1bOH\x01\x1b[H45\x1bOF6\x05\x1b[F7\x1bOH8")
send(child, "\n")
check_line(child, "84531267")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Up and down arrows.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc4(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x1b[A\x1bOA\x1b[B\x1bOB")
send(child, "\n")
expect(child, prompt)
write_str(child, "15")
check_line(child, "15")
write_str(child, "2^16")
check_line(child, "65536")
send(child, "\x1b[A\x1bOA")
send(child, "\n")
check_line(child, "15")
send(child, "\x1b[A\x1bOA\x1b[A\x1b[B")
check_line(child, "65536")
send(child, "\x1b[A\x1bOA\x0e\x1b[A\x1b[A\x1b[A\x1b[B\x10\x1b[B\x1b[B\x1bOB\x1b[B\x1bOA")
send(child, "\n")
check_line(child, "65536")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Clear screen.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc5(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x0c")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Printed material without a newline.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc6(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "print \"Enter number: \"")
send(child, "\n")
expect(child, "Enter number: ")
send(child, "4\x1b[A\x1b[A")
send(child, "\n")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Word start and word end.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc7(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x1bb\x1bb\x1bf\x1bf")
send(child, "\n")
expect(child, prompt)
send(child, "\x1b[0~\x1b[3a")
send(child, "\n")
expect(child, prompt)
send(child, "\x1b[0;4\x1b[0A")
send(child, "\n")
expect(child, prompt)
send(child, "\t")
send(child, "\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb")
send(child, "\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf")
send(child, "\n")
expect(child, prompt)
write_str(child, "12 + 34 + 56 + 78 + 90")
check_line(child, "270")
send(child, "\x1b[A")
send(child, "\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb")
send(child, "\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf")
check_line(child, "270")
send(child, "\x1b[A")
send(child, "\x1bh\x1bh\x1bf + 14 ")
send(child, "\n")
check_line(child, "284")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Backspace.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc8(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "12\x1b[D3\x1b[C4\x08\x7f")
send(child, "\n")
check_line(child, "13")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Backspace and delete words.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc9(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x1b[0;5D\x1b[0;5D\x1b[0;5D\x1b[0;5C\x1b[0;5D\x1bd\x1b[3~\x1b[d\x1b[d\x1b[d\x1b[d\x7f\x7f\x7f")
send(child, "\n")
expect(child, prompt)
write_str(child, "12 + 34 + 56 + 78 + 90")
check_line(child, "270")
send(child, "\x1b[A")
send(child, "\x1b[0;5D\x1b[0;5D\x1b[0;5D\x1b[0;5C\x1b[0;5D\x1bd\x1b[3~\x1b[d\x1b[d\x1b[d\x1b[d\x7f\x7f\x7f")
send(child, "\n")
check_line(child, "102")
send(child, "\x1b[A")
send(child, "\x17\x17")
send(child, "\n")
check_line(child, "46")
send(child, "\x17\x17")
send(child, "\n")
expect(child, prompt)
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Backspace and delete words 2.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc10(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x1b[3~\x1b[3~")
send(child, "\n")
expect(child, prompt)
send(child, " \x1b[3~\x1b[3~")
send(child, "\n")
expect(child, prompt)
write_str(child, "12 + 34 + 56 + 78 + 90")
check_line(child, "270")
send(child, "\x1b[A\x1b[A\x1b[A\x1b[B\x1b[B\x1b[B\x1b[A")
send(child, "\n")
check_line(child, "270")
send(child, "\x1b[A\x1b[0;5D\x1b[0;5D\x0b")
send(child, "\n")
check_line(child, "180")
send(child, "\x1b[A\x1521")
check_line(child, "21")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Swap.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc11(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "\x1b[A\x02\x14")
send(child, "\n")
expect(child, prompt)
write_str(child, "12 + 34 + 56 + 78")
check_line(child, "180")
send(child, "\x1b[A\x02\x14")
check_line(child, "189")
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Non-fatal error.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_bc12(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
bc_banner(child)
send(child, "12 +")
send(child, "\n")
time.sleep(1)
if not child.isalive():
print("child exited early")
print(str(child))
print(str(child.buffer))
sys.exit(1)
send(child, "quit")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
def test_dc_utf8_0(exe, args, env):
return test_utf8_0(exe, args, env, False)
def test_dc_utf8_1(exe, args, env):
return test_utf8_1(exe, args, env, False)
def test_dc_utf8_2(exe, args, env):
return test_utf8_2(exe, args, env, False)
def test_dc_utf8_3(exe, args, env):
return test_utf8_3(exe, args, env, False)
def test_dc_utf8_4(exe, args, env):
return test_utf8_4(exe, args, env, False)
# Basic dc test.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_dc1(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
write_str(child, "1pR")
check_line(child, "1")
write_str(child, "1pR")
check_line(child, "1")
write_str(child, "q")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# SIGINT with quit.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_dc2(exe, args, env):
env["TERM"] = "dumb"
child = pexpect.spawn(exe, args=args, env=env)
try:
child.sendline("1pR")
check_line(child, "1", history=False)
time.sleep(1)
child.sendintr()
child.sendline("q")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# Execute string.
# @param exe The executable.
# @param args The arguments to pass to the executable.
# @param env The environment.
def test_dc3(exe, args, env):
child = pexpect.spawn(exe, args=args, env=env)
try:
write_str(child, "[1 15+pR]x")
check_line(child, "16")
write_str(child, "1pR")
check_line(child, "1")
write_str(child, "q")
send(child, "\n")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
print("timed out")
print(str(child))
sys.exit(2)
except pexpect.EOF:
print("EOF")
print(str(child))
print(str(child.buffer))
print(str(child.before))
sys.exit(2)
return child
# The array of bc tests.
bc_tests = [
test_bc_utf8_0,
test_bc_utf8_1,
test_bc_utf8_2,
test_bc_utf8_3,
test_bc_utf8_4,
test_sigint_sigquit,
test_eof,
test_sigint,
test_sigtstp,
test_sigstop,
test_bc1,
test_bc2,
test_bc3,
test_bc4,
test_bc5,
test_bc6,
test_bc7,
test_bc8,
test_bc9,
test_bc10,
test_bc11,
test_bc12,
]
# The array of dc tests.
dc_tests = [
test_dc_utf8_0,
test_dc_utf8_1,
test_dc_utf8_2,
test_dc_utf8_3,
test_dc_utf8_4,
test_sigint_sigquit,
test_eof,
test_sigint,
test_dc1,
test_dc2,
test_dc3,
]
# Print the usage and exit with an error.
def usage():
print("usage: {} [-t] dir [-a] test_idx [exe options...]".format(script))
print(" The valid values for dir are: 'bc' and 'dc'.")
print(" The max test_idx for bc is {}.".format(len(bc_tests) - 1))
print(" The max test_idx for dc is {}.".format(len(dc_tests) - 1))
print(" If -a is given, the number of tests for dir is printed.")
print(" No tests are run.")
sys.exit(1)
# Must run this script alone.
if __name__ != "__main__":
usage()
if len(sys.argv) < 2:
usage()
idx = 1
exedir = sys.argv[idx]
idx += 1
if exedir == "-t":
do_test = True
exedir = sys.argv[idx]
idx += 1
else:
do_test = False
test_idx = sys.argv[idx]
idx += 1
if test_idx == "-a":
if exedir == "bc":
l = len(bc_tests)
else:
l = len(dc_tests)
print("{}".format(l))
sys.exit(0)
test_idx = int(test_idx)
# Set a default executable unless we have one.
if len(sys.argv) >= idx + 1:
exe = sys.argv[idx]
else:
exe = testdir + "/../bin/" + exedir
exebase = os.path.basename(exe)
# Use the correct options.
if exebase == "bc":
halt = "halt\n"
options = "-l"
test_array = bc_tests
else:
halt = "q\n"
options = "-x"
test_array = dc_tests
# More command-line processing.
if len(sys.argv) > idx + 1:
exe = [ exe, sys.argv[idx + 1:], options ]
else:
exe = [ exe, options ]
# This is the environment necessary for most tests.
env = {
"BC_BANNER": "1",
"BC_PROMPT": "1",
"DC_PROMPT": "1",
"BC_TTY_MODE": "1",
"DC_TTY_MODE": "1",
"BC_SIGINT_RESET": "1",
"DC_SIGINT_RESET": "1",
}
# Make sure to include the outside environment.
env.update(os.environ)
env.pop("BC_ENV_ARGS", None)
env.pop("BC_LINE_LENGTH", None)
env.pop("DC_ENV_ARGS", None)
env.pop("DC_LINE_LENGTH", None)
# Run the correct test.
child = test_array[test_idx](exe[0], exe[1:], env)
child.close()
exit = child.exitstatus
if exit is not None and exit != 0:
print("child failed; expected exit code 0, got {}".format(exit))
print(str(child))
sys.exit(1)