144d4804dSStefan Eßer#! /usr/bin/python 244d4804dSStefan Eßer# 344d4804dSStefan Eßer# SPDX-License-Identifier: BSD-2-Clause 444d4804dSStefan Eßer# 5d101cdd6SStefan Eßer# Copyright (c) 2018-2023 Gavin D. Howard and contributors. 644d4804dSStefan Eßer# 744d4804dSStefan Eßer# Redistribution and use in source and binary forms, with or without 844d4804dSStefan Eßer# modification, are permitted provided that the following conditions are met: 944d4804dSStefan Eßer# 1044d4804dSStefan Eßer# * Redistributions of source code must retain the above copyright notice, this 1144d4804dSStefan Eßer# list of conditions and the following disclaimer. 1244d4804dSStefan Eßer# 1344d4804dSStefan Eßer# * Redistributions in binary form must reproduce the above copyright notice, 1444d4804dSStefan Eßer# this list of conditions and the following disclaimer in the documentation 1544d4804dSStefan Eßer# and/or other materials provided with the distribution. 1644d4804dSStefan Eßer# 1744d4804dSStefan Eßer# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1844d4804dSStefan Eßer# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1944d4804dSStefan Eßer# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2044d4804dSStefan Eßer# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2144d4804dSStefan Eßer# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2244d4804dSStefan Eßer# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2344d4804dSStefan Eßer# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2444d4804dSStefan Eßer# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2544d4804dSStefan Eßer# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2644d4804dSStefan Eßer# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2744d4804dSStefan Eßer# POSSIBILITY OF SUCH DAMAGE. 2844d4804dSStefan Eßer# 2944d4804dSStefan Eßer 3044d4804dSStefan Eßerimport os, sys 3144d4804dSStefan Eßerimport time 3244d4804dSStefan Eßerimport signal 33d43fa8efSStefan Eßerimport traceback 3444d4804dSStefan Eßer 3544d4804dSStefan Eßertry: 3644d4804dSStefan Eßer import pexpect 3744d4804dSStefan Eßerexcept ImportError: 3844d4804dSStefan Eßer print("Could not find pexpect. Skipping...") 3944d4804dSStefan Eßer sys.exit(0) 4044d4804dSStefan Eßer 4144d4804dSStefan Eßer# Housekeeping. 4244d4804dSStefan Eßerscript = sys.argv[0] 4344d4804dSStefan Eßertestdir = os.path.dirname(script) 4444d4804dSStefan Eßer 45662087dfSStefan Eßerif "BC_TEST_OUTPUT_DIR" in os.environ: 46662087dfSStefan Eßer outputdir = os.environ["BC_TEST_OUTPUT_DIR"] 47662087dfSStefan Eßerelse: 48662087dfSStefan Eßer outputdir = testdir 49662087dfSStefan Eßer 5044d4804dSStefan Eßerprompt = ">>> " 5144d4804dSStefan Eßer 5244d4804dSStefan Eßer# This array is for escaping characters that are necessary to escape when 5344d4804dSStefan Eßer# outputting to pexpect. Since pexpect takes regexes, these characters confuse 5444d4804dSStefan Eßer# it unless we escape them. 5544d4804dSStefan Eßerescapes = [ 5644d4804dSStefan Eßer ']', 5744d4804dSStefan Eßer '[', 5844d4804dSStefan Eßer '+', 5944d4804dSStefan Eßer] 6044d4804dSStefan Eßer 6144d4804dSStefan Eßer# UTF-8 stress tests. 6244d4804dSStefan Eßerutf8_stress1 = "ᆬḰ䋔䗅㜲ತ咡䒢岤䳰稨⣡嶣㷡嶏ⵐ䄺嵕ਅ奰痚㆜䊛拂䅙૩➋䛿ቬ竳Ϳᅠ❄产翷䮊௷Ỉ䷒䳜㛠➕傎ᗋᏯਕ䆐悙癐㺨" 6344d4804dSStefan Eßerutf8_stress2 = "韠싧돳넨큚ꉿ뮴픷ꉲ긌�최릙걆鳬낽ꪁ퍼鈴핐黙헶ꪈ뮩쭀锻끥鉗겉욞며뛯�ﻼ�度錐�" 6444d4804dSStefan Eßerutf8_stress3 = "곻�䣹昲蜴Ὓ桢㎏⚦珢畣갴ﭱ鶶ๅ뀁彻ꖒ䔾ꢚﱤ햔햞㐹�鼳뵡▿ⶾ꠩�纞⊐佧�ⵟ霘紳㱔籠뎼⊓搧硤" 6544d4804dSStefan Eßerutf8_stress4 = "ᄀ��" 6644d4804dSStefan Eßer 6744d4804dSStefan Eßer# An easy array for UTF-8 tests. 6844d4804dSStefan Eßerutf8_stress_strs = [ 6944d4804dSStefan Eßer utf8_stress1, 7044d4804dSStefan Eßer utf8_stress2, 7144d4804dSStefan Eßer utf8_stress3, 7244d4804dSStefan Eßer utf8_stress4, 7344d4804dSStefan Eßer] 7444d4804dSStefan Eßer 7544d4804dSStefan Eßer 76d43fa8efSStefan Eßerdef expect(child, data): 77d43fa8efSStefan Eßer child.expect(data) 78d43fa8efSStefan Eßer 79d43fa8efSStefan Eßer 80d43fa8efSStefan Eßer# Eats all of the child's data. 81d43fa8efSStefan Eßer# @param child The child whose data should be eaten. 82d43fa8efSStefan Eßerdef eat(child): 83d43fa8efSStefan Eßer while child.buffer is not None and len(child.buffer) > 0: 84d43fa8efSStefan Eßer expect(child, ".+") 85d43fa8efSStefan Eßer 86d43fa8efSStefan Eßer 87d43fa8efSStefan Eßer# Send data to a child. This makes sure the buffers are empty first. 88d43fa8efSStefan Eßer# @param child The child to send data to. 89d43fa8efSStefan Eßer# @param data The data to send. 90d43fa8efSStefan Eßerdef send(child, data): 91d43fa8efSStefan Eßer eat(child) 92d43fa8efSStefan Eßer child.send(data) 93d43fa8efSStefan Eßer 94d43fa8efSStefan Eßer 95d43fa8efSStefan Eßerdef wait(child): 96d43fa8efSStefan Eßer if child.isalive(): 97d43fa8efSStefan Eßer child.sendeof() 98d43fa8efSStefan Eßer time.sleep(1) 99d43fa8efSStefan Eßer if child.isalive(): 100d43fa8efSStefan Eßer child.kill(signal.SIGTERM) 101d43fa8efSStefan Eßer time.sleep(1) 102d43fa8efSStefan Eßer if child.isalive(): 103d43fa8efSStefan Eßer child.kill(signal.SIGKILL) 104d43fa8efSStefan Eßer child.wait() 105d43fa8efSStefan Eßer 106d43fa8efSStefan Eßer 10744d4804dSStefan Eßer# Check that the child output the expected line. If history is false, then 10844d4804dSStefan Eßer# the output should change. 10944d4804dSStefan Eßerdef check_line(child, expected, prompt=">>> ", history=True): 110d43fa8efSStefan Eßer send(child, "\n") 11144d4804dSStefan Eßer prefix = "\r\n" if history else "" 112d43fa8efSStefan Eßer expect(child, prefix + expected + "\r\n" + prompt) 11344d4804dSStefan Eßer 11444d4804dSStefan Eßer 11544d4804dSStefan Eßer# Write a string to output, checking all of the characters are output, 11644d4804dSStefan Eßer# one-by-one. 11744d4804dSStefan Eßerdef write_str(child, s): 11844d4804dSStefan Eßer for c in s: 119d43fa8efSStefan Eßer send(child, c) 12044d4804dSStefan Eßer if c in escapes: 121d43fa8efSStefan Eßer expect(child, "\\{}".format(c)) 12244d4804dSStefan Eßer else: 123d43fa8efSStefan Eßer expect(child, c) 12444d4804dSStefan Eßer 12544d4804dSStefan Eßer 12644d4804dSStefan Eßer# Check the bc banner. 12744d4804dSStefan Eßer# @param child The child process. 12844d4804dSStefan Eßerdef bc_banner(child): 12944d4804dSStefan Eßer bc_banner1 = "bc [0-9]+\.[0-9]+\.[0-9]+\r\n" 13044d4804dSStefan Eßer bc_banner2 = "Copyright \(c\) 2018-[2-9][0-9][0-9][0-9] Gavin D. Howard and contributors\r\n" 1314fca8e0fSStefan Eßer bc_banner3 = "Report bugs at: https://git.gavinhoward.com/gavin/bc\r\n\r\n" 13244d4804dSStefan Eßer bc_banner4 = "This is free software with ABSOLUTELY NO WARRANTY.\r\n\r\n" 133d43fa8efSStefan Eßer expect(child, bc_banner1) 134d43fa8efSStefan Eßer expect(child, bc_banner2) 135d43fa8efSStefan Eßer expect(child, bc_banner3) 136d43fa8efSStefan Eßer expect(child, bc_banner4) 137d43fa8efSStefan Eßer expect(child, prompt) 13844d4804dSStefan Eßer 13944d4804dSStefan Eßer 14044d4804dSStefan Eßer# Common UTF-8 testing function. The index is the index into utf8_stress_strs 14144d4804dSStefan Eßer# for which stress string to use. 14244d4804dSStefan Eßer# @param exe The executable. 14344d4804dSStefan Eßer# @param args The arguments to pass to the executable. 14444d4804dSStefan Eßer# @param env The environment. 14544d4804dSStefan Eßer# @param idx The index of the UTF-8 stress string. 14644d4804dSStefan Eßerdef test_utf8(exe, args, env, idx, bc=True): 14744d4804dSStefan Eßer 14844d4804dSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 14944d4804dSStefan Eßer env["BC_BANNER"] = "0" 15044d4804dSStefan Eßer 15144d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env, encoding='utf-8', codec_errors='ignore') 15244d4804dSStefan Eßer 15344d4804dSStefan Eßer try: 15444d4804dSStefan Eßer 15544d4804dSStefan Eßer # Write the stress string. 156d43fa8efSStefan Eßer send(child, utf8_stress_strs[idx]) 157d43fa8efSStefan Eßer send(child, "\n") 15844d4804dSStefan Eßer 15944d4804dSStefan Eßer if bc: 160d43fa8efSStefan Eßer send(child, "quit") 16144d4804dSStefan Eßer else: 162d43fa8efSStefan Eßer send(child, "q") 16344d4804dSStefan Eßer 164d43fa8efSStefan Eßer send(child, "\n") 16544d4804dSStefan Eßer 166d43fa8efSStefan Eßer wait(child) 16744d4804dSStefan Eßer 16844d4804dSStefan Eßer except pexpect.TIMEOUT: 169d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 17044d4804dSStefan Eßer print("timed out") 17144d4804dSStefan Eßer print(str(child)) 17244d4804dSStefan Eßer sys.exit(2) 17344d4804dSStefan Eßer except pexpect.EOF: 17444d4804dSStefan Eßer print("EOF") 17544d4804dSStefan Eßer print(str(child)) 17644d4804dSStefan Eßer print(str(child.buffer)) 17744d4804dSStefan Eßer print(str(child.before)) 17844d4804dSStefan Eßer sys.exit(2) 17944d4804dSStefan Eßer 18044d4804dSStefan Eßer return child 18144d4804dSStefan Eßer 18244d4804dSStefan Eßer# A random UTF-8 test with insert. 18344d4804dSStefan Eßer# @param exe The executable. 18444d4804dSStefan Eßer# @param args The arguments to pass to the executable. 18544d4804dSStefan Eßer# @param env The environment. 18644d4804dSStefan Eßerdef test_utf8_0(exe, args, env, bc=True): 18744d4804dSStefan Eßer 18844d4804dSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 18944d4804dSStefan Eßer env["BC_BANNER"] = "0" 19044d4804dSStefan Eßer 19144d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env, encoding='utf-8', codec_errors='ignore') 19244d4804dSStefan Eßer 19344d4804dSStefan Eßer try: 19444d4804dSStefan Eßer 19544d4804dSStefan Eßer # Just random UTF-8 I generated somewhow, plus ensuring that insert works. 19644d4804dSStefan Eßer write_str(child, "ﴪáá̵̗ã") 197d43fa8efSStefan Eßer send(child, "\x1b[D\x1b[D\x1b[D\x1b\x1b[Aℐ") 198d43fa8efSStefan Eßer send(child, "\n") 19944d4804dSStefan Eßer 20044d4804dSStefan Eßer if bc: 201d43fa8efSStefan Eßer send(child, "quit") 20244d4804dSStefan Eßer else: 203d43fa8efSStefan Eßer send(child, "q") 20444d4804dSStefan Eßer 205d43fa8efSStefan Eßer send(child, "\n") 206d43fa8efSStefan Eßer eat(child) 20744d4804dSStefan Eßer 208d43fa8efSStefan Eßer wait(child) 20944d4804dSStefan Eßer 21044d4804dSStefan Eßer except pexpect.TIMEOUT: 211d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 21244d4804dSStefan Eßer print("timed out") 21344d4804dSStefan Eßer print(str(child)) 21444d4804dSStefan Eßer sys.exit(2) 21544d4804dSStefan Eßer except pexpect.EOF: 21644d4804dSStefan Eßer print("EOF") 21744d4804dSStefan Eßer print(str(child)) 21844d4804dSStefan Eßer print(str(child.buffer)) 21944d4804dSStefan Eßer print(str(child.before)) 22044d4804dSStefan Eßer sys.exit(2) 22144d4804dSStefan Eßer 22244d4804dSStefan Eßer return child 22344d4804dSStefan Eßer 22444d4804dSStefan Eßer 22544d4804dSStefan Eßerdef test_utf8_1(exe, args, env, bc=True): 22644d4804dSStefan Eßer return test_utf8(exe, args, env, 0, bc) 22744d4804dSStefan Eßer 22844d4804dSStefan Eßer 22944d4804dSStefan Eßerdef test_utf8_2(exe, args, env, bc=True): 23044d4804dSStefan Eßer return test_utf8(exe, args, env, 1, bc) 23144d4804dSStefan Eßer 23244d4804dSStefan Eßer 23344d4804dSStefan Eßerdef test_utf8_3(exe, args, env, bc=True): 23444d4804dSStefan Eßer return test_utf8(exe, args, env, 2, bc) 23544d4804dSStefan Eßer 23644d4804dSStefan Eßer 23744d4804dSStefan Eßerdef test_utf8_4(exe, args, env, bc=True): 23844d4804dSStefan Eßer return test_utf8(exe, args, env, 3, bc) 23944d4804dSStefan Eßer 24044d4804dSStefan Eßer 24144d4804dSStefan Eßer# This tests a SIGINT with reset followed by a SIGQUIT. 24244d4804dSStefan Eßer# @param exe The executable. 24344d4804dSStefan Eßer# @param args The arguments to pass to the executable. 24444d4804dSStefan Eßer# @param env The environment. 24544d4804dSStefan Eßerdef test_sigint_sigquit(exe, args, env): 24644d4804dSStefan Eßer 247d43fa8efSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 248d43fa8efSStefan Eßer env["BC_BANNER"] = "0" 249d43fa8efSStefan Eßer 25044d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 25144d4804dSStefan Eßer 25244d4804dSStefan Eßer try: 253d43fa8efSStefan Eßer send(child, "\t") 25478bc019dSStefan Eßer expect(child, "\t") 255d43fa8efSStefan Eßer send(child, "\x03") 25610041e99SStefan Eßer # send(child, "\x1c") 257d43fa8efSStefan Eßer wait(child) 25844d4804dSStefan Eßer except pexpect.TIMEOUT: 259d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 26044d4804dSStefan Eßer print("timed out") 26144d4804dSStefan Eßer print(str(child)) 26244d4804dSStefan Eßer sys.exit(2) 26344d4804dSStefan Eßer except pexpect.EOF: 26444d4804dSStefan Eßer print("EOF") 26544d4804dSStefan Eßer print(str(child)) 26644d4804dSStefan Eßer print(str(child.buffer)) 26744d4804dSStefan Eßer print(str(child.before)) 26844d4804dSStefan Eßer sys.exit(2) 26944d4804dSStefan Eßer 27044d4804dSStefan Eßer return child 27144d4804dSStefan Eßer 27244d4804dSStefan Eßer 27344d4804dSStefan Eßer# Test for EOF. 27444d4804dSStefan Eßer# @param exe The executable. 27544d4804dSStefan Eßer# @param args The arguments to pass to the executable. 27644d4804dSStefan Eßer# @param env The environment. 27744d4804dSStefan Eßerdef test_eof(exe, args, env): 27844d4804dSStefan Eßer 279d43fa8efSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 280d43fa8efSStefan Eßer env["BC_BANNER"] = "0" 281d43fa8efSStefan Eßer 28244d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 28344d4804dSStefan Eßer 28444d4804dSStefan Eßer try: 285bbd60e2cSStefan Eßer send(child, "123") 286bbd60e2cSStefan Eßer expect(child, "123") 287bbd60e2cSStefan Eßer send(child, "\x01") 288bbd60e2cSStefan Eßer send(child, "\x04") 289bbd60e2cSStefan Eßer send(child, "\x04") 290d43fa8efSStefan Eßer send(child, "\x04") 291d43fa8efSStefan Eßer wait(child) 29244d4804dSStefan Eßer except pexpect.TIMEOUT: 293d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 29444d4804dSStefan Eßer print("timed out") 29544d4804dSStefan Eßer print(str(child)) 29644d4804dSStefan Eßer sys.exit(2) 29744d4804dSStefan Eßer except pexpect.EOF: 29844d4804dSStefan Eßer print("EOF") 29944d4804dSStefan Eßer print(str(child)) 30044d4804dSStefan Eßer print(str(child.buffer)) 30144d4804dSStefan Eßer print(str(child.before)) 30244d4804dSStefan Eßer sys.exit(2) 30344d4804dSStefan Eßer 30444d4804dSStefan Eßer return child 30544d4804dSStefan Eßer 30644d4804dSStefan Eßer 30744d4804dSStefan Eßer# Test for quiting SIGINT. 30844d4804dSStefan Eßer# @param exe The executable. 30944d4804dSStefan Eßer# @param args The arguments to pass to the executable. 31044d4804dSStefan Eßer# @param env The environment. 31144d4804dSStefan Eßerdef test_sigint(exe, args, env): 31244d4804dSStefan Eßer 313d43fa8efSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 314d43fa8efSStefan Eßer env["BC_BANNER"] = "0" 315d43fa8efSStefan Eßer 31644d4804dSStefan Eßer env["BC_SIGINT_RESET"] = "0" 31744d4804dSStefan Eßer env["DC_SIGINT_RESET"] = "0" 31844d4804dSStefan Eßer 31944d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 32044d4804dSStefan Eßer 32144d4804dSStefan Eßer try: 322d43fa8efSStefan Eßer send(child, "\t") 32378bc019dSStefan Eßer expect(child, "\t") 324d43fa8efSStefan Eßer send(child, "\x03") 325d43fa8efSStefan Eßer wait(child) 32644d4804dSStefan Eßer except pexpect.TIMEOUT: 327d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 32844d4804dSStefan Eßer print("timed out") 32944d4804dSStefan Eßer print(str(child)) 33044d4804dSStefan Eßer sys.exit(2) 33144d4804dSStefan Eßer except pexpect.EOF: 33244d4804dSStefan Eßer print("EOF") 33344d4804dSStefan Eßer print(str(child)) 33444d4804dSStefan Eßer print(str(child.buffer)) 33544d4804dSStefan Eßer print(str(child.before)) 33644d4804dSStefan Eßer sys.exit(2) 33744d4804dSStefan Eßer 33844d4804dSStefan Eßer return child 33944d4804dSStefan Eßer 34044d4804dSStefan Eßer 34144d4804dSStefan Eßer# Test for SIGTSTP. 34244d4804dSStefan Eßer# @param exe The executable. 34344d4804dSStefan Eßer# @param args The arguments to pass to the executable. 34444d4804dSStefan Eßer# @param env The environment. 34544d4804dSStefan Eßerdef test_sigtstp(exe, args, env): 34644d4804dSStefan Eßer 347d43fa8efSStefan Eßer # This test does not work on FreeBSD, so skip. 348d43fa8efSStefan Eßer if sys.platform.startswith("freebsd"): 349d43fa8efSStefan Eßer sys.exit(0) 350d43fa8efSStefan Eßer 351d43fa8efSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 352d43fa8efSStefan Eßer env["BC_BANNER"] = "0" 353d43fa8efSStefan Eßer 35444d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 35544d4804dSStefan Eßer 35644d4804dSStefan Eßer try: 357d43fa8efSStefan Eßer send(child, "\t") 35878bc019dSStefan Eßer expect(child, "\t") 359d43fa8efSStefan Eßer send(child, "\x13") 36044d4804dSStefan Eßer time.sleep(1) 36144d4804dSStefan Eßer if not child.isalive(): 36244d4804dSStefan Eßer print("child exited early") 36344d4804dSStefan Eßer print(str(child)) 36444d4804dSStefan Eßer print(str(child.buffer)) 36544d4804dSStefan Eßer sys.exit(1) 36644d4804dSStefan Eßer child.kill(signal.SIGCONT) 367d43fa8efSStefan Eßer send(child, "quit") 368d43fa8efSStefan Eßer send(child, "\n") 369d43fa8efSStefan Eßer wait(child) 37044d4804dSStefan Eßer except pexpect.TIMEOUT: 371d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 37244d4804dSStefan Eßer print("timed out") 37344d4804dSStefan Eßer print(str(child)) 37444d4804dSStefan Eßer sys.exit(2) 37544d4804dSStefan Eßer except pexpect.EOF: 37644d4804dSStefan Eßer print("EOF") 37744d4804dSStefan Eßer print(str(child)) 37844d4804dSStefan Eßer print(str(child.buffer)) 37944d4804dSStefan Eßer print(str(child.before)) 38044d4804dSStefan Eßer sys.exit(2) 38144d4804dSStefan Eßer 38244d4804dSStefan Eßer return child 38344d4804dSStefan Eßer 38444d4804dSStefan Eßer 38544d4804dSStefan Eßer# Test for SIGSTOP. 38644d4804dSStefan Eßer# @param exe The executable. 38744d4804dSStefan Eßer# @param args The arguments to pass to the executable. 38844d4804dSStefan Eßer# @param env The environment. 38944d4804dSStefan Eßerdef test_sigstop(exe, args, env): 39044d4804dSStefan Eßer 391d43fa8efSStefan Eßer # Because both bc and dc use this, make sure the banner doesn't pop. 392d43fa8efSStefan Eßer env["BC_BANNER"] = "0" 393d43fa8efSStefan Eßer 39444d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 39544d4804dSStefan Eßer 39644d4804dSStefan Eßer try: 397d43fa8efSStefan Eßer send(child, "\t") 39878bc019dSStefan Eßer expect(child, "\t") 399d43fa8efSStefan Eßer send(child, "\x14") 40044d4804dSStefan Eßer time.sleep(1) 40144d4804dSStefan Eßer if not child.isalive(): 40244d4804dSStefan Eßer print("child exited early") 40344d4804dSStefan Eßer print(str(child)) 40444d4804dSStefan Eßer print(str(child.buffer)) 40544d4804dSStefan Eßer sys.exit(1) 406d43fa8efSStefan Eßer send(child, "\x13") 40744d4804dSStefan Eßer time.sleep(1) 40844d4804dSStefan Eßer if not child.isalive(): 40944d4804dSStefan Eßer print("child exited early") 41044d4804dSStefan Eßer print(str(child)) 41144d4804dSStefan Eßer print(str(child.buffer)) 41244d4804dSStefan Eßer sys.exit(1) 41344d4804dSStefan Eßer child.kill(signal.SIGCONT) 414d43fa8efSStefan Eßer send(child, "quit") 415d43fa8efSStefan Eßer send(child, "\n") 416d43fa8efSStefan Eßer wait(child) 41744d4804dSStefan Eßer except pexpect.TIMEOUT: 418d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 41944d4804dSStefan Eßer print("timed out") 42044d4804dSStefan Eßer print(str(child)) 42144d4804dSStefan Eßer sys.exit(2) 42244d4804dSStefan Eßer except pexpect.EOF: 42344d4804dSStefan Eßer print("EOF") 42444d4804dSStefan Eßer print(str(child)) 42544d4804dSStefan Eßer print(str(child.buffer)) 42644d4804dSStefan Eßer print(str(child.before)) 42744d4804dSStefan Eßer sys.exit(2) 42844d4804dSStefan Eßer 42944d4804dSStefan Eßer return child 43044d4804dSStefan Eßer 43144d4804dSStefan Eßer 43244d4804dSStefan Eßerdef test_bc_utf8_0(exe, args, env): 43344d4804dSStefan Eßer return test_utf8_0(exe, args, env, True) 43444d4804dSStefan Eßer 43544d4804dSStefan Eßer 43644d4804dSStefan Eßerdef test_bc_utf8_1(exe, args, env): 43744d4804dSStefan Eßer return test_utf8_1(exe, args, env, True) 43844d4804dSStefan Eßer 43944d4804dSStefan Eßer 44044d4804dSStefan Eßerdef test_bc_utf8_2(exe, args, env): 44144d4804dSStefan Eßer return test_utf8_2(exe, args, env, True) 44244d4804dSStefan Eßer 44344d4804dSStefan Eßer 44444d4804dSStefan Eßerdef test_bc_utf8_3(exe, args, env): 44544d4804dSStefan Eßer return test_utf8_3(exe, args, env, True) 44644d4804dSStefan Eßer 44744d4804dSStefan Eßer 44844d4804dSStefan Eßerdef test_bc_utf8_4(exe, args, env): 44944d4804dSStefan Eßer return test_utf8_4(exe, args, env, True) 45044d4804dSStefan Eßer 45144d4804dSStefan Eßer 45244d4804dSStefan Eßer# Basic bc test. 45344d4804dSStefan Eßer# @param exe The executable. 45444d4804dSStefan Eßer# @param args The arguments to pass to the executable. 45544d4804dSStefan Eßer# @param env The environment. 45644d4804dSStefan Eßerdef test_bc1(exe, args, env): 45744d4804dSStefan Eßer 45844d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 45944d4804dSStefan Eßer 46044d4804dSStefan Eßer try: 46144d4804dSStefan Eßer bc_banner(child) 46244d4804dSStefan Eßer write_str(child, "1") 46344d4804dSStefan Eßer check_line(child, "1") 46444d4804dSStefan Eßer write_str(child, "1") 46544d4804dSStefan Eßer check_line(child, "1") 466d43fa8efSStefan Eßer send(child, "quit") 467d43fa8efSStefan Eßer send(child, "\n") 468d43fa8efSStefan Eßer wait(child) 46944d4804dSStefan Eßer except pexpect.TIMEOUT: 470d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 47144d4804dSStefan Eßer print("timed out") 47244d4804dSStefan Eßer print(str(child)) 47344d4804dSStefan Eßer sys.exit(2) 47444d4804dSStefan Eßer except pexpect.EOF: 47544d4804dSStefan Eßer print("EOF") 47644d4804dSStefan Eßer print(str(child)) 47744d4804dSStefan Eßer print(str(child.buffer)) 47844d4804dSStefan Eßer print(str(child.before)) 47944d4804dSStefan Eßer sys.exit(2) 48044d4804dSStefan Eßer 48144d4804dSStefan Eßer return child 48244d4804dSStefan Eßer 48344d4804dSStefan Eßer 48444d4804dSStefan Eßer# SIGINT with no history. 48544d4804dSStefan Eßer# @param exe The executable. 48644d4804dSStefan Eßer# @param args The arguments to pass to the executable. 48744d4804dSStefan Eßer# @param env The environment. 48844d4804dSStefan Eßerdef test_bc2(exe, args, env): 48944d4804dSStefan Eßer 49044d4804dSStefan Eßer env["TERM"] = "dumb" 49144d4804dSStefan Eßer 49244d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 49344d4804dSStefan Eßer 49444d4804dSStefan Eßer try: 49544d4804dSStefan Eßer bc_banner(child) 49644d4804dSStefan Eßer child.sendline("1") 49744d4804dSStefan Eßer check_line(child, "1", history=False) 49844d4804dSStefan Eßer time.sleep(1) 49944d4804dSStefan Eßer child.sendintr() 50044d4804dSStefan Eßer child.sendline("quit") 501d43fa8efSStefan Eßer wait(child) 50244d4804dSStefan Eßer except pexpect.TIMEOUT: 503d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 50444d4804dSStefan Eßer print("timed out") 50544d4804dSStefan Eßer print(str(child)) 50644d4804dSStefan Eßer sys.exit(2) 50744d4804dSStefan Eßer except pexpect.EOF: 50844d4804dSStefan Eßer print("EOF") 50944d4804dSStefan Eßer print(str(child)) 51044d4804dSStefan Eßer print(str(child.buffer)) 51144d4804dSStefan Eßer print(str(child.before)) 51244d4804dSStefan Eßer sys.exit(2) 51344d4804dSStefan Eßer 51444d4804dSStefan Eßer return child 51544d4804dSStefan Eßer 51644d4804dSStefan Eßer 51744d4804dSStefan Eßer# Left and right arrows. 51844d4804dSStefan Eßer# @param exe The executable. 51944d4804dSStefan Eßer# @param args The arguments to pass to the executable. 52044d4804dSStefan Eßer# @param env The environment. 52144d4804dSStefan Eßerdef test_bc3(exe, args, env): 52244d4804dSStefan Eßer 52344d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 52444d4804dSStefan Eßer 52544d4804dSStefan Eßer try: 52644d4804dSStefan Eßer bc_banner(child) 527d43fa8efSStefan Eßer send(child, "\x1b[D\x1b[D\x1b[C\x1b[C") 528d43fa8efSStefan Eßer send(child, "\n") 529d43fa8efSStefan Eßer expect(child, prompt) 530d43fa8efSStefan Eßer send(child, "12\x1b[D3\x1b[C4\x1bOD5\x1bOC6") 531d43fa8efSStefan Eßer send(child, "\n") 53244d4804dSStefan Eßer check_line(child, "132546") 533d43fa8efSStefan Eßer send(child, "12\x023\x064") 534d43fa8efSStefan Eßer send(child, "\n") 53544d4804dSStefan Eßer check_line(child, "1324") 536d43fa8efSStefan Eßer send(child, "12\x1b[H3\x1bOH\x01\x1b[H45\x1bOF6\x05\x1b[F7\x1bOH8") 537d43fa8efSStefan Eßer send(child, "\n") 53844d4804dSStefan Eßer check_line(child, "84531267") 539d43fa8efSStefan Eßer send(child, "quit") 540d43fa8efSStefan Eßer send(child, "\n") 541d43fa8efSStefan Eßer wait(child) 54244d4804dSStefan Eßer except pexpect.TIMEOUT: 543d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 54444d4804dSStefan Eßer print("timed out") 54544d4804dSStefan Eßer print(str(child)) 54644d4804dSStefan Eßer sys.exit(2) 54744d4804dSStefan Eßer except pexpect.EOF: 54844d4804dSStefan Eßer print("EOF") 54944d4804dSStefan Eßer print(str(child)) 55044d4804dSStefan Eßer print(str(child.buffer)) 55144d4804dSStefan Eßer print(str(child.before)) 55244d4804dSStefan Eßer sys.exit(2) 55344d4804dSStefan Eßer 55444d4804dSStefan Eßer return child 55544d4804dSStefan Eßer 55644d4804dSStefan Eßer 55744d4804dSStefan Eßer# Up and down arrows. 55844d4804dSStefan Eßer# @param exe The executable. 55944d4804dSStefan Eßer# @param args The arguments to pass to the executable. 56044d4804dSStefan Eßer# @param env The environment. 56144d4804dSStefan Eßerdef test_bc4(exe, args, env): 56244d4804dSStefan Eßer 56344d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 56444d4804dSStefan Eßer 56544d4804dSStefan Eßer try: 56644d4804dSStefan Eßer bc_banner(child) 567d43fa8efSStefan Eßer send(child, "\x1b[A\x1bOA\x1b[B\x1bOB") 568d43fa8efSStefan Eßer send(child, "\n") 569d43fa8efSStefan Eßer expect(child, prompt) 57044d4804dSStefan Eßer write_str(child, "15") 57144d4804dSStefan Eßer check_line(child, "15") 57244d4804dSStefan Eßer write_str(child, "2^16") 57344d4804dSStefan Eßer check_line(child, "65536") 574d43fa8efSStefan Eßer send(child, "\x1b[A\x1bOA") 575d43fa8efSStefan Eßer send(child, "\n") 57644d4804dSStefan Eßer check_line(child, "15") 577d43fa8efSStefan Eßer send(child, "\x1b[A\x1bOA\x1b[A\x1b[B") 57844d4804dSStefan Eßer check_line(child, "65536") 579d43fa8efSStefan Eßer send(child, "\x1b[A\x1bOA\x0e\x1b[A\x1b[A\x1b[A\x1b[B\x10\x1b[B\x1b[B\x1bOB\x1b[B\x1bOA") 580d43fa8efSStefan Eßer send(child, "\n") 58144d4804dSStefan Eßer check_line(child, "65536") 582d43fa8efSStefan Eßer send(child, "quit") 583d43fa8efSStefan Eßer send(child, "\n") 584d43fa8efSStefan Eßer wait(child) 58544d4804dSStefan Eßer except pexpect.TIMEOUT: 586d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 58744d4804dSStefan Eßer print("timed out") 58844d4804dSStefan Eßer print(str(child)) 58944d4804dSStefan Eßer sys.exit(2) 59044d4804dSStefan Eßer except pexpect.EOF: 59144d4804dSStefan Eßer print("EOF") 59244d4804dSStefan Eßer print(str(child)) 59344d4804dSStefan Eßer print(str(child.buffer)) 59444d4804dSStefan Eßer print(str(child.before)) 59544d4804dSStefan Eßer sys.exit(2) 59644d4804dSStefan Eßer 59744d4804dSStefan Eßer return child 59844d4804dSStefan Eßer 59944d4804dSStefan Eßer 60044d4804dSStefan Eßer# Clear screen. 60144d4804dSStefan Eßer# @param exe The executable. 60244d4804dSStefan Eßer# @param args The arguments to pass to the executable. 60344d4804dSStefan Eßer# @param env The environment. 60444d4804dSStefan Eßerdef test_bc5(exe, args, env): 60544d4804dSStefan Eßer 60644d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 60744d4804dSStefan Eßer 60844d4804dSStefan Eßer try: 60944d4804dSStefan Eßer bc_banner(child) 610d43fa8efSStefan Eßer send(child, "\x0c") 611d43fa8efSStefan Eßer send(child, "quit") 612d43fa8efSStefan Eßer send(child, "\n") 613d43fa8efSStefan Eßer wait(child) 61444d4804dSStefan Eßer except pexpect.TIMEOUT: 615d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 61644d4804dSStefan Eßer print("timed out") 61744d4804dSStefan Eßer print(str(child)) 61844d4804dSStefan Eßer sys.exit(2) 61944d4804dSStefan Eßer except pexpect.EOF: 62044d4804dSStefan Eßer print("EOF") 62144d4804dSStefan Eßer print(str(child)) 62244d4804dSStefan Eßer print(str(child.buffer)) 62344d4804dSStefan Eßer print(str(child.before)) 62444d4804dSStefan Eßer sys.exit(2) 62544d4804dSStefan Eßer 62644d4804dSStefan Eßer return child 62744d4804dSStefan Eßer 62844d4804dSStefan Eßer 62944d4804dSStefan Eßer# Printed material without a newline. 63044d4804dSStefan Eßer# @param exe The executable. 63144d4804dSStefan Eßer# @param args The arguments to pass to the executable. 63244d4804dSStefan Eßer# @param env The environment. 63344d4804dSStefan Eßerdef test_bc6(exe, args, env): 63444d4804dSStefan Eßer 63544d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 63644d4804dSStefan Eßer 63744d4804dSStefan Eßer try: 63844d4804dSStefan Eßer bc_banner(child) 639d43fa8efSStefan Eßer send(child, "print \"Enter number: \"") 640d43fa8efSStefan Eßer send(child, "\n") 641d43fa8efSStefan Eßer expect(child, "Enter number: ") 642d43fa8efSStefan Eßer send(child, "4\x1b[A\x1b[A") 643d43fa8efSStefan Eßer send(child, "\n") 644d43fa8efSStefan Eßer send(child, "quit") 645d43fa8efSStefan Eßer send(child, "\n") 646d43fa8efSStefan Eßer wait(child) 64744d4804dSStefan Eßer except pexpect.TIMEOUT: 648d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 64944d4804dSStefan Eßer print("timed out") 65044d4804dSStefan Eßer print(str(child)) 65144d4804dSStefan Eßer sys.exit(2) 65244d4804dSStefan Eßer except pexpect.EOF: 65344d4804dSStefan Eßer print("EOF") 65444d4804dSStefan Eßer print(str(child)) 65544d4804dSStefan Eßer print(str(child.buffer)) 65644d4804dSStefan Eßer print(str(child.before)) 65744d4804dSStefan Eßer sys.exit(2) 65844d4804dSStefan Eßer 65944d4804dSStefan Eßer return child 66044d4804dSStefan Eßer 66144d4804dSStefan Eßer 66244d4804dSStefan Eßer# Word start and word end. 66344d4804dSStefan Eßer# @param exe The executable. 66444d4804dSStefan Eßer# @param args The arguments to pass to the executable. 66544d4804dSStefan Eßer# @param env The environment. 66644d4804dSStefan Eßerdef test_bc7(exe, args, env): 66744d4804dSStefan Eßer 66844d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 66944d4804dSStefan Eßer 67044d4804dSStefan Eßer try: 67144d4804dSStefan Eßer bc_banner(child) 672d43fa8efSStefan Eßer send(child, "\x1bb\x1bb\x1bf\x1bf") 673d43fa8efSStefan Eßer send(child, "\n") 674d43fa8efSStefan Eßer expect(child, prompt) 675d43fa8efSStefan Eßer send(child, "\x1b[0~\x1b[3a") 676d43fa8efSStefan Eßer send(child, "\n") 677d43fa8efSStefan Eßer expect(child, prompt) 678d43fa8efSStefan Eßer send(child, "\x1b[0;4\x1b[0A") 679d43fa8efSStefan Eßer send(child, "\n") 680d43fa8efSStefan Eßer expect(child, prompt) 68178bc019dSStefan Eßer send(child, "\t") 682d43fa8efSStefan Eßer send(child, "\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb") 683d43fa8efSStefan Eßer send(child, "\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf") 684d43fa8efSStefan Eßer send(child, "\n") 685d43fa8efSStefan Eßer expect(child, prompt) 68644d4804dSStefan Eßer write_str(child, "12 + 34 + 56 + 78 + 90") 68744d4804dSStefan Eßer check_line(child, "270") 688d43fa8efSStefan Eßer send(child, "\x1b[A") 689d43fa8efSStefan Eßer send(child, "\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb") 690d43fa8efSStefan Eßer send(child, "\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf") 69144d4804dSStefan Eßer check_line(child, "270") 692d43fa8efSStefan Eßer send(child, "\x1b[A") 693d43fa8efSStefan Eßer send(child, "\x1bh\x1bh\x1bf + 14 ") 694d43fa8efSStefan Eßer send(child, "\n") 69544d4804dSStefan Eßer check_line(child, "284") 696d43fa8efSStefan Eßer send(child, "quit") 697d43fa8efSStefan Eßer send(child, "\n") 698d43fa8efSStefan Eßer wait(child) 69944d4804dSStefan Eßer except pexpect.TIMEOUT: 700d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 70144d4804dSStefan Eßer print("timed out") 70244d4804dSStefan Eßer print(str(child)) 70344d4804dSStefan Eßer sys.exit(2) 70444d4804dSStefan Eßer except pexpect.EOF: 70544d4804dSStefan Eßer print("EOF") 70644d4804dSStefan Eßer print(str(child)) 70744d4804dSStefan Eßer print(str(child.buffer)) 70844d4804dSStefan Eßer print(str(child.before)) 70944d4804dSStefan Eßer sys.exit(2) 71044d4804dSStefan Eßer 71144d4804dSStefan Eßer return child 71244d4804dSStefan Eßer 71344d4804dSStefan Eßer 71444d4804dSStefan Eßer# Backspace. 71544d4804dSStefan Eßer# @param exe The executable. 71644d4804dSStefan Eßer# @param args The arguments to pass to the executable. 71744d4804dSStefan Eßer# @param env The environment. 71844d4804dSStefan Eßerdef test_bc8(exe, args, env): 71944d4804dSStefan Eßer 72044d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 72144d4804dSStefan Eßer 72244d4804dSStefan Eßer try: 72344d4804dSStefan Eßer bc_banner(child) 724d43fa8efSStefan Eßer send(child, "12\x1b[D3\x1b[C4\x08\x7f") 725d43fa8efSStefan Eßer send(child, "\n") 72644d4804dSStefan Eßer check_line(child, "13") 727d43fa8efSStefan Eßer send(child, "quit") 728d43fa8efSStefan Eßer send(child, "\n") 729d43fa8efSStefan Eßer wait(child) 73044d4804dSStefan Eßer except pexpect.TIMEOUT: 731d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 73244d4804dSStefan Eßer print("timed out") 73344d4804dSStefan Eßer print(str(child)) 73444d4804dSStefan Eßer sys.exit(2) 73544d4804dSStefan Eßer except pexpect.EOF: 73644d4804dSStefan Eßer print("EOF") 73744d4804dSStefan Eßer print(str(child)) 73844d4804dSStefan Eßer print(str(child.buffer)) 73944d4804dSStefan Eßer print(str(child.before)) 74044d4804dSStefan Eßer sys.exit(2) 74144d4804dSStefan Eßer 74244d4804dSStefan Eßer return child 74344d4804dSStefan Eßer 74444d4804dSStefan Eßer 74544d4804dSStefan Eßer# Backspace and delete words. 74644d4804dSStefan Eßer# @param exe The executable. 74744d4804dSStefan Eßer# @param args The arguments to pass to the executable. 74844d4804dSStefan Eßer# @param env The environment. 74944d4804dSStefan Eßerdef test_bc9(exe, args, env): 75044d4804dSStefan Eßer 75144d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 75244d4804dSStefan Eßer 75344d4804dSStefan Eßer try: 75444d4804dSStefan Eßer bc_banner(child) 755d43fa8efSStefan Eßer 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") 756d43fa8efSStefan Eßer send(child, "\n") 757d43fa8efSStefan Eßer expect(child, prompt) 75844d4804dSStefan Eßer write_str(child, "12 + 34 + 56 + 78 + 90") 75944d4804dSStefan Eßer check_line(child, "270") 760d43fa8efSStefan Eßer send(child, "\x1b[A") 761d43fa8efSStefan Eßer 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") 762d43fa8efSStefan Eßer send(child, "\n") 76344d4804dSStefan Eßer check_line(child, "102") 764d43fa8efSStefan Eßer send(child, "\x1b[A") 765d43fa8efSStefan Eßer send(child, "\x17\x17") 766d43fa8efSStefan Eßer send(child, "\n") 76744d4804dSStefan Eßer check_line(child, "46") 768d43fa8efSStefan Eßer send(child, "\x17\x17") 769d43fa8efSStefan Eßer send(child, "\n") 770d43fa8efSStefan Eßer expect(child, prompt) 771d43fa8efSStefan Eßer send(child, "quit") 772d43fa8efSStefan Eßer send(child, "\n") 773d43fa8efSStefan Eßer wait(child) 77444d4804dSStefan Eßer except pexpect.TIMEOUT: 775d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 77644d4804dSStefan Eßer print("timed out") 77744d4804dSStefan Eßer print(str(child)) 77844d4804dSStefan Eßer sys.exit(2) 77944d4804dSStefan Eßer except pexpect.EOF: 78044d4804dSStefan Eßer print("EOF") 78144d4804dSStefan Eßer print(str(child)) 78244d4804dSStefan Eßer print(str(child.buffer)) 78344d4804dSStefan Eßer print(str(child.before)) 78444d4804dSStefan Eßer sys.exit(2) 78544d4804dSStefan Eßer 78644d4804dSStefan Eßer return child 78744d4804dSStefan Eßer 78844d4804dSStefan Eßer 78944d4804dSStefan Eßer# Backspace and delete words 2. 79044d4804dSStefan Eßer# @param exe The executable. 79144d4804dSStefan Eßer# @param args The arguments to pass to the executable. 79244d4804dSStefan Eßer# @param env The environment. 79344d4804dSStefan Eßerdef test_bc10(exe, args, env): 79444d4804dSStefan Eßer 79544d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 79644d4804dSStefan Eßer 79744d4804dSStefan Eßer try: 79844d4804dSStefan Eßer bc_banner(child) 799d43fa8efSStefan Eßer send(child, "\x1b[3~\x1b[3~") 800d43fa8efSStefan Eßer send(child, "\n") 801d43fa8efSStefan Eßer expect(child, prompt) 802d43fa8efSStefan Eßer send(child, " \x1b[3~\x1b[3~") 803d43fa8efSStefan Eßer send(child, "\n") 804d43fa8efSStefan Eßer expect(child, prompt) 80544d4804dSStefan Eßer write_str(child, "12 + 34 + 56 + 78 + 90") 80644d4804dSStefan Eßer check_line(child, "270") 807d43fa8efSStefan Eßer send(child, "\x1b[A\x1b[A\x1b[A\x1b[B\x1b[B\x1b[B\x1b[A") 808d43fa8efSStefan Eßer send(child, "\n") 80944d4804dSStefan Eßer check_line(child, "270") 810d43fa8efSStefan Eßer send(child, "\x1b[A\x1b[0;5D\x1b[0;5D\x0b") 811d43fa8efSStefan Eßer send(child, "\n") 81244d4804dSStefan Eßer check_line(child, "180") 813d43fa8efSStefan Eßer send(child, "\x1b[A\x1521") 81444d4804dSStefan Eßer check_line(child, "21") 815d43fa8efSStefan Eßer send(child, "quit") 816d43fa8efSStefan Eßer send(child, "\n") 817d43fa8efSStefan Eßer wait(child) 81844d4804dSStefan Eßer except pexpect.TIMEOUT: 819d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 82044d4804dSStefan Eßer print("timed out") 82144d4804dSStefan Eßer print(str(child)) 82244d4804dSStefan Eßer sys.exit(2) 82344d4804dSStefan Eßer except pexpect.EOF: 82444d4804dSStefan Eßer print("EOF") 82544d4804dSStefan Eßer print(str(child)) 82644d4804dSStefan Eßer print(str(child.buffer)) 82744d4804dSStefan Eßer print(str(child.before)) 82844d4804dSStefan Eßer sys.exit(2) 82944d4804dSStefan Eßer 83044d4804dSStefan Eßer return child 83144d4804dSStefan Eßer 83244d4804dSStefan Eßer 83344d4804dSStefan Eßer# Swap. 83444d4804dSStefan Eßer# @param exe The executable. 83544d4804dSStefan Eßer# @param args The arguments to pass to the executable. 83644d4804dSStefan Eßer# @param env The environment. 83744d4804dSStefan Eßerdef test_bc11(exe, args, env): 83844d4804dSStefan Eßer 83944d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 84044d4804dSStefan Eßer 84144d4804dSStefan Eßer try: 84244d4804dSStefan Eßer bc_banner(child) 843d43fa8efSStefan Eßer send(child, "\x1b[A\x02\x14") 844d43fa8efSStefan Eßer send(child, "\n") 845d43fa8efSStefan Eßer expect(child, prompt) 84644d4804dSStefan Eßer write_str(child, "12 + 34 + 56 + 78") 84744d4804dSStefan Eßer check_line(child, "180") 848d43fa8efSStefan Eßer send(child, "\x1b[A\x02\x14") 84944d4804dSStefan Eßer check_line(child, "189") 850d43fa8efSStefan Eßer send(child, "quit") 851d43fa8efSStefan Eßer send(child, "\n") 852d43fa8efSStefan Eßer wait(child) 85344d4804dSStefan Eßer except pexpect.TIMEOUT: 854d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 85544d4804dSStefan Eßer print("timed out") 85644d4804dSStefan Eßer print(str(child)) 85744d4804dSStefan Eßer sys.exit(2) 85844d4804dSStefan Eßer except pexpect.EOF: 85944d4804dSStefan Eßer print("EOF") 86044d4804dSStefan Eßer print(str(child)) 86144d4804dSStefan Eßer print(str(child.buffer)) 86244d4804dSStefan Eßer print(str(child.before)) 86344d4804dSStefan Eßer sys.exit(2) 86444d4804dSStefan Eßer 86544d4804dSStefan Eßer return child 86644d4804dSStefan Eßer 86744d4804dSStefan Eßer 86844d4804dSStefan Eßer# Non-fatal error. 86944d4804dSStefan Eßer# @param exe The executable. 87044d4804dSStefan Eßer# @param args The arguments to pass to the executable. 87144d4804dSStefan Eßer# @param env The environment. 87244d4804dSStefan Eßerdef test_bc12(exe, args, env): 87344d4804dSStefan Eßer 87444d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 87544d4804dSStefan Eßer 87644d4804dSStefan Eßer try: 87744d4804dSStefan Eßer bc_banner(child) 878d43fa8efSStefan Eßer send(child, "12 +") 879d43fa8efSStefan Eßer send(child, "\n") 88044d4804dSStefan Eßer time.sleep(1) 88144d4804dSStefan Eßer if not child.isalive(): 88244d4804dSStefan Eßer print("child exited early") 88344d4804dSStefan Eßer print(str(child)) 88444d4804dSStefan Eßer print(str(child.buffer)) 88544d4804dSStefan Eßer sys.exit(1) 886d43fa8efSStefan Eßer send(child, "quit") 887d43fa8efSStefan Eßer send(child, "\n") 888d43fa8efSStefan Eßer wait(child) 88944d4804dSStefan Eßer except pexpect.TIMEOUT: 890d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 89144d4804dSStefan Eßer print("timed out") 89244d4804dSStefan Eßer print(str(child)) 89344d4804dSStefan Eßer sys.exit(2) 89444d4804dSStefan Eßer except pexpect.EOF: 89544d4804dSStefan Eßer print("EOF") 89644d4804dSStefan Eßer print(str(child)) 89744d4804dSStefan Eßer print(str(child.buffer)) 89844d4804dSStefan Eßer print(str(child.before)) 89944d4804dSStefan Eßer sys.exit(2) 90044d4804dSStefan Eßer 90144d4804dSStefan Eßer return child 90244d4804dSStefan Eßer 90344d4804dSStefan Eßer 90444d4804dSStefan Eßerdef test_dc_utf8_0(exe, args, env): 90544d4804dSStefan Eßer return test_utf8_0(exe, args, env, False) 90644d4804dSStefan Eßer 90744d4804dSStefan Eßer 90844d4804dSStefan Eßerdef test_dc_utf8_1(exe, args, env): 90944d4804dSStefan Eßer return test_utf8_1(exe, args, env, False) 91044d4804dSStefan Eßer 91144d4804dSStefan Eßer 91244d4804dSStefan Eßerdef test_dc_utf8_2(exe, args, env): 91344d4804dSStefan Eßer return test_utf8_2(exe, args, env, False) 91444d4804dSStefan Eßer 91544d4804dSStefan Eßer 91644d4804dSStefan Eßerdef test_dc_utf8_3(exe, args, env): 91744d4804dSStefan Eßer return test_utf8_3(exe, args, env, False) 91844d4804dSStefan Eßer 91944d4804dSStefan Eßer 92044d4804dSStefan Eßerdef test_dc_utf8_4(exe, args, env): 92144d4804dSStefan Eßer return test_utf8_4(exe, args, env, False) 92244d4804dSStefan Eßer 92344d4804dSStefan Eßer 92444d4804dSStefan Eßer# Basic dc test. 92544d4804dSStefan Eßer# @param exe The executable. 92644d4804dSStefan Eßer# @param args The arguments to pass to the executable. 92744d4804dSStefan Eßer# @param env The environment. 92844d4804dSStefan Eßerdef test_dc1(exe, args, env): 92944d4804dSStefan Eßer 93044d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 93144d4804dSStefan Eßer 93244d4804dSStefan Eßer try: 93344d4804dSStefan Eßer write_str(child, "1pR") 93444d4804dSStefan Eßer check_line(child, "1") 93544d4804dSStefan Eßer write_str(child, "1pR") 93644d4804dSStefan Eßer check_line(child, "1") 93744d4804dSStefan Eßer write_str(child, "q") 938d43fa8efSStefan Eßer send(child, "\n") 939d43fa8efSStefan Eßer wait(child) 94044d4804dSStefan Eßer except pexpect.TIMEOUT: 941d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 94244d4804dSStefan Eßer print("timed out") 94344d4804dSStefan Eßer print(str(child)) 94444d4804dSStefan Eßer sys.exit(2) 94544d4804dSStefan Eßer except pexpect.EOF: 94644d4804dSStefan Eßer print("EOF") 94744d4804dSStefan Eßer print(str(child)) 94844d4804dSStefan Eßer print(str(child.buffer)) 94944d4804dSStefan Eßer print(str(child.before)) 95044d4804dSStefan Eßer sys.exit(2) 95144d4804dSStefan Eßer 95244d4804dSStefan Eßer return child 95344d4804dSStefan Eßer 95444d4804dSStefan Eßer 95544d4804dSStefan Eßer# SIGINT with quit. 95644d4804dSStefan Eßer# @param exe The executable. 95744d4804dSStefan Eßer# @param args The arguments to pass to the executable. 95844d4804dSStefan Eßer# @param env The environment. 95944d4804dSStefan Eßerdef test_dc2(exe, args, env): 96044d4804dSStefan Eßer 96144d4804dSStefan Eßer env["TERM"] = "dumb" 96244d4804dSStefan Eßer 96344d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 96444d4804dSStefan Eßer 96544d4804dSStefan Eßer try: 96644d4804dSStefan Eßer child.sendline("1pR") 96744d4804dSStefan Eßer check_line(child, "1", history=False) 96844d4804dSStefan Eßer time.sleep(1) 96944d4804dSStefan Eßer child.sendintr() 97044d4804dSStefan Eßer child.sendline("q") 971d43fa8efSStefan Eßer wait(child) 97244d4804dSStefan Eßer except pexpect.TIMEOUT: 973d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 97444d4804dSStefan Eßer print("timed out") 97544d4804dSStefan Eßer print(str(child)) 97644d4804dSStefan Eßer sys.exit(2) 97744d4804dSStefan Eßer except pexpect.EOF: 97844d4804dSStefan Eßer print("EOF") 97944d4804dSStefan Eßer print(str(child)) 98044d4804dSStefan Eßer print(str(child.buffer)) 98144d4804dSStefan Eßer print(str(child.before)) 98244d4804dSStefan Eßer sys.exit(2) 98344d4804dSStefan Eßer 98444d4804dSStefan Eßer return child 98544d4804dSStefan Eßer 98644d4804dSStefan Eßer 98744d4804dSStefan Eßer# Execute string. 98844d4804dSStefan Eßer# @param exe The executable. 98944d4804dSStefan Eßer# @param args The arguments to pass to the executable. 99044d4804dSStefan Eßer# @param env The environment. 99144d4804dSStefan Eßerdef test_dc3(exe, args, env): 99244d4804dSStefan Eßer 99344d4804dSStefan Eßer child = pexpect.spawn(exe, args=args, env=env) 99444d4804dSStefan Eßer 99544d4804dSStefan Eßer try: 99644d4804dSStefan Eßer write_str(child, "[1 15+pR]x") 99744d4804dSStefan Eßer check_line(child, "16") 99844d4804dSStefan Eßer write_str(child, "1pR") 99944d4804dSStefan Eßer check_line(child, "1") 100044d4804dSStefan Eßer write_str(child, "q") 1001d43fa8efSStefan Eßer send(child, "\n") 1002d43fa8efSStefan Eßer wait(child) 100344d4804dSStefan Eßer except pexpect.TIMEOUT: 1004d43fa8efSStefan Eßer traceback.print_tb(sys.exc_info()[2]) 100544d4804dSStefan Eßer print("timed out") 100644d4804dSStefan Eßer print(str(child)) 100744d4804dSStefan Eßer sys.exit(2) 100844d4804dSStefan Eßer except pexpect.EOF: 100944d4804dSStefan Eßer print("EOF") 101044d4804dSStefan Eßer print(str(child)) 101144d4804dSStefan Eßer print(str(child.buffer)) 101244d4804dSStefan Eßer print(str(child.before)) 101344d4804dSStefan Eßer sys.exit(2) 101444d4804dSStefan Eßer 101544d4804dSStefan Eßer return child 101644d4804dSStefan Eßer 101744d4804dSStefan Eßer 101844d4804dSStefan Eßer# The array of bc tests. 101944d4804dSStefan Eßerbc_tests = [ 102044d4804dSStefan Eßer test_bc_utf8_0, 102144d4804dSStefan Eßer test_bc_utf8_1, 102244d4804dSStefan Eßer test_bc_utf8_2, 102344d4804dSStefan Eßer test_bc_utf8_3, 102444d4804dSStefan Eßer test_bc_utf8_4, 102544d4804dSStefan Eßer test_sigint_sigquit, 102644d4804dSStefan Eßer test_eof, 102744d4804dSStefan Eßer test_sigint, 102844d4804dSStefan Eßer test_sigtstp, 102944d4804dSStefan Eßer test_sigstop, 103044d4804dSStefan Eßer test_bc1, 103144d4804dSStefan Eßer test_bc2, 103244d4804dSStefan Eßer test_bc3, 103344d4804dSStefan Eßer test_bc4, 103444d4804dSStefan Eßer test_bc5, 103544d4804dSStefan Eßer test_bc6, 103644d4804dSStefan Eßer test_bc7, 103744d4804dSStefan Eßer test_bc8, 103844d4804dSStefan Eßer test_bc9, 103944d4804dSStefan Eßer test_bc10, 104044d4804dSStefan Eßer test_bc11, 104144d4804dSStefan Eßer test_bc12, 104244d4804dSStefan Eßer] 104344d4804dSStefan Eßer 104444d4804dSStefan Eßer# The array of dc tests. 104544d4804dSStefan Eßerdc_tests = [ 104644d4804dSStefan Eßer test_dc_utf8_0, 104744d4804dSStefan Eßer test_dc_utf8_1, 104844d4804dSStefan Eßer test_dc_utf8_2, 104944d4804dSStefan Eßer test_dc_utf8_3, 105010041e99SStefan Eßer test_dc_utf8_4, 105144d4804dSStefan Eßer test_sigint_sigquit, 105244d4804dSStefan Eßer test_eof, 105344d4804dSStefan Eßer test_sigint, 105444d4804dSStefan Eßer test_dc1, 105544d4804dSStefan Eßer test_dc2, 105644d4804dSStefan Eßer test_dc3, 105744d4804dSStefan Eßer] 105844d4804dSStefan Eßer 105944d4804dSStefan Eßer 106044d4804dSStefan Eßer# Print the usage and exit with an error. 106144d4804dSStefan Eßerdef usage(): 106244d4804dSStefan Eßer print("usage: {} [-t] dir [-a] test_idx [exe options...]".format(script)) 106344d4804dSStefan Eßer print(" The valid values for dir are: 'bc' and 'dc'.") 106444d4804dSStefan Eßer print(" The max test_idx for bc is {}.".format(len(bc_tests) - 1)) 106544d4804dSStefan Eßer print(" The max test_idx for dc is {}.".format(len(dc_tests) - 1)) 1066d43fa8efSStefan Eßer print(" If -a is given, the number of tests for dir is printed.") 106744d4804dSStefan Eßer print(" No tests are run.") 106844d4804dSStefan Eßer sys.exit(1) 106944d4804dSStefan Eßer 107044d4804dSStefan Eßer 107144d4804dSStefan Eßer# Must run this script alone. 107244d4804dSStefan Eßerif __name__ != "__main__": 107344d4804dSStefan Eßer usage() 107444d4804dSStefan Eßer 107544d4804dSStefan Eßerif len(sys.argv) < 2: 107644d4804dSStefan Eßer usage() 107744d4804dSStefan Eßer 107844d4804dSStefan Eßeridx = 1 107944d4804dSStefan Eßer 108044d4804dSStefan Eßerexedir = sys.argv[idx] 108144d4804dSStefan Eßer 108244d4804dSStefan Eßeridx += 1 108344d4804dSStefan Eßer 108444d4804dSStefan Eßerif exedir == "-t": 108544d4804dSStefan Eßer do_test = True 108644d4804dSStefan Eßer exedir = sys.argv[idx] 108744d4804dSStefan Eßer idx += 1 108844d4804dSStefan Eßerelse: 108944d4804dSStefan Eßer do_test = False 109044d4804dSStefan Eßer 109144d4804dSStefan Eßertest_idx = sys.argv[idx] 109244d4804dSStefan Eßer 109344d4804dSStefan Eßeridx += 1 109444d4804dSStefan Eßer 109544d4804dSStefan Eßerif test_idx == "-a": 109644d4804dSStefan Eßer if exedir == "bc": 109744d4804dSStefan Eßer l = len(bc_tests) 109844d4804dSStefan Eßer else: 109944d4804dSStefan Eßer l = len(dc_tests) 110044d4804dSStefan Eßer print("{}".format(l)) 110144d4804dSStefan Eßer sys.exit(0) 110244d4804dSStefan Eßer 110344d4804dSStefan Eßertest_idx = int(test_idx) 110444d4804dSStefan Eßer 110544d4804dSStefan Eßer# Set a default executable unless we have one. 110644d4804dSStefan Eßerif len(sys.argv) >= idx + 1: 110744d4804dSStefan Eßer exe = sys.argv[idx] 110844d4804dSStefan Eßerelse: 110944d4804dSStefan Eßer exe = testdir + "/../bin/" + exedir 111044d4804dSStefan Eßer 111144d4804dSStefan Eßerexebase = os.path.basename(exe) 111244d4804dSStefan Eßer 111344d4804dSStefan Eßer# Use the correct options. 111444d4804dSStefan Eßerif exebase == "bc": 111544d4804dSStefan Eßer halt = "halt\n" 1116d43fa8efSStefan Eßer options = "-l" 111744d4804dSStefan Eßer test_array = bc_tests 111844d4804dSStefan Eßerelse: 111944d4804dSStefan Eßer halt = "q\n" 112044d4804dSStefan Eßer options = "-x" 112144d4804dSStefan Eßer test_array = dc_tests 112244d4804dSStefan Eßer 112344d4804dSStefan Eßer# More command-line processing. 112444d4804dSStefan Eßerif len(sys.argv) > idx + 1: 112544d4804dSStefan Eßer exe = [ exe, sys.argv[idx + 1:], options ] 112644d4804dSStefan Eßerelse: 112744d4804dSStefan Eßer exe = [ exe, options ] 112844d4804dSStefan Eßer 112944d4804dSStefan Eßer# This is the environment necessary for most tests. 113044d4804dSStefan Eßerenv = { 113144d4804dSStefan Eßer "BC_BANNER": "1", 113244d4804dSStefan Eßer "BC_PROMPT": "1", 113344d4804dSStefan Eßer "DC_PROMPT": "1", 113444d4804dSStefan Eßer "BC_TTY_MODE": "1", 113544d4804dSStefan Eßer "DC_TTY_MODE": "1", 113644d4804dSStefan Eßer "BC_SIGINT_RESET": "1", 113744d4804dSStefan Eßer "DC_SIGINT_RESET": "1", 113844d4804dSStefan Eßer} 113944d4804dSStefan Eßer 114044d4804dSStefan Eßer# Make sure to include the outside environment. 114144d4804dSStefan Eßerenv.update(os.environ) 114244d4804dSStefan Eßerenv.pop("BC_ENV_ARGS", None) 114344d4804dSStefan Eßerenv.pop("BC_LINE_LENGTH", None) 114444d4804dSStefan Eßerenv.pop("DC_ENV_ARGS", None) 114544d4804dSStefan Eßerenv.pop("DC_LINE_LENGTH", None) 114644d4804dSStefan Eßer 114744d4804dSStefan Eßer# Run the correct test. 114844d4804dSStefan Eßerchild = test_array[test_idx](exe[0], exe[1:], env) 114944d4804dSStefan Eßer 115044d4804dSStefan Eßerchild.close() 115144d4804dSStefan Eßer 115244d4804dSStefan Eßerexit = child.exitstatus 115344d4804dSStefan Eßer 1154d43fa8efSStefan Eßerif exit is not None and exit != 0: 115544d4804dSStefan Eßer print("child failed; expected exit code 0, got {}".format(exit)) 115644d4804dSStefan Eßer print(str(child)) 115744d4804dSStefan Eßer sys.exit(1) 1158