diff options
author | Thomas Kluyver <takowl@gmail.com> | 2015-04-25 17:26:14 -0700 |
---|---|---|
committer | Thomas Kluyver <takowl@gmail.com> | 2015-04-25 17:26:14 -0700 |
commit | d368bbb115ae0648bd1cf4fec4d795cf56e5da00 (patch) | |
tree | c886533fe9d5f9693f915a6f0751192f65616a9e | |
parent | 8dafe9ad04bf3237b1c8a7c00e9c007b446ffc33 (diff) | |
parent | 924b014c3ecc2db01d7722c0374b3934151b9c7b (diff) | |
download | pexpect-git-d368bbb115ae0648bd1cf4fec4d795cf56e5da00.tar.gz |
Merge pull request #181 from pexpect/freebsd-support
Freebsd support
-rw-r--r-- | pexpect/pty_spawn.py | 2 | ||||
-rw-r--r-- | requirements-testing.txt | 5 | ||||
-rwxr-xr-x | tests/test_interact.py | 18 | ||||
-rw-r--r-- | tests/test_maxcanon.py | 32 | ||||
-rwxr-xr-x | tools/display-sighandlers.py | 6 | ||||
-rwxr-xr-x | tools/teamcity-runtests.sh | 7 |
6 files changed, 56 insertions, 14 deletions
diff --git a/pexpect/pty_spawn.py b/pexpect/pty_spawn.py index 0663926..0ba1e0c 100644 --- a/pexpect/pty_spawn.py +++ b/pexpect/pty_spawn.py @@ -475,7 +475,7 @@ class spawn(SpawnBase): On Linux systems, this is 4096 (defined by N_TTY_BUF_SIZE). All other systems honor the POSIX.1 definition PC_MAX_CANON -- 1024 - on OSX, 256 on OpenSolaris, 255 on FreeBSD. + on OSX, 256 on OpenSolaris, and 1920 on FreeBSD. This value may be discovered using fpathconf(3):: diff --git a/requirements-testing.txt b/requirements-testing.txt new file mode 100644 index 0000000..1894122 --- /dev/null +++ b/requirements-testing.txt @@ -0,0 +1,5 @@ +pytest +pytest-cov +coverage +coveralls +pytest-capturelog diff --git a/tests/test_interact.py b/tests/test_interact.py index 06fc44a..e635cb0 100755 --- a/tests/test_interact.py +++ b/tests/test_interact.py @@ -66,9 +66,12 @@ class InteractTestCase (PexpectTestCase.PexpectTestCase): p.expect(b'<out>alpha') p.expect(b'<out>beta') p.sendeof() - p.expect_exact('<eof>') - p.expect_exact('Escaped interact') - p.expect(pexpect.EOF) + # strangely, on travis-ci, sendeof() terminates the subprocess, + # it doesn't receive ^D, just immediately throws EOF. + idx = p.expect_exact(['<eof>', pexpect.EOF]) + if idx == 0: + p.expect_exact('Escaped interact') + p.expect(pexpect.EOF) assert not p.isalive() assert p.exitstatus == 0 @@ -81,9 +84,12 @@ class InteractTestCase (PexpectTestCase.PexpectTestCase): p.expect('<out>ɑlpha') p.expect('<out>Βeta') p.sendeof() - p.expect_exact('<eof>') - p.expect_exact('Escaped interact') - p.expect(pexpect.EOF) + # strangely, on travis-ci, sendeof() terminates the subprocess, + # it doesn't receive ^D, just immediately throws EOF. + idx = p.expect_exact(['<eof>', pexpect.EOF]) + if idx == 0: + p.expect_exact('Escaped interact') + p.expect(pexpect.EOF) assert not p.isalive() assert p.exitstatus == 0 diff --git a/tests/test_maxcanon.py b/tests/test_maxcanon.py index bbd08f3..772a3b7 100644 --- a/tests/test_maxcanon.py +++ b/tests/test_maxcanon.py @@ -1,18 +1,23 @@ """ Module for canonical-mode tests. """ +# std imports import sys import os - +# local import pexpect from . import PexpectTestCase +# 3rd-party +import pytest + class TestCaseCanon(PexpectTestCase.PexpectTestCase): """ Test expected Canonical mode behavior (limited input line length). All systems use the value of MAX_CANON which can be found using - fpathconf(3) value PC_MAX_CANON -- with the exception of Linux. + fpathconf(3) value PC_MAX_CANON -- with the exception of Linux + and FreeBSD. Linux, though defining a value of 255, actually honors the value of 4096 from linux kernel include file tty.h definition @@ -22,6 +27,10 @@ class TestCaseCanon(PexpectTestCase.PexpectTestCase): implement this bit, and acts as if it is always set." Although these tests ensure it is enabled, this is a non-op for Linux. + FreeBSD supports neither, and instead uses a fraction (1/5) of the tty + speed which is always 9600. Therefor, the maximum limited input line + length is 9600 / 5 = 1920. + These tests only ensure the correctness of the behavior described by the sendline() docstring. pexpect is not particularly involved in these scenarios, though if we wish to expose some kind of interface @@ -43,10 +52,17 @@ class TestCaseCanon(PexpectTestCase.PexpectTestCase): # SunOS allows PC_MAX_CANON + 1; see # https://bitbucket.org/illumos/illumos-gate/src/d07a59219ab7fd2a7f39eb47c46cf083c88e932f/usr/src/uts/common/io/ldterm.c?at=default#cl-1888 self.max_input = os.fpathconf(0, 'PC_MAX_CANON') + 1 + elif sys.platform.lower().startswith('freebsd'): + # http://lists.freebsd.org/pipermail/freebsd-stable/2009-October/052318.html + self.max_input = 9600 / 5 else: # All others (probably) limit exactly at PC_MAX_CANON self.max_input = os.fpathconf(0, 'PC_MAX_CANON') + @pytest.mark.skipif( + sys.platform.lower().startswith('freebsd'), + reason='os.write to BLOCK indefinitely on FreeBSD in this case' + ) def test_under_max_canon(self): " BEL is not sent by terminal driver at maximum bytes - 1. " # given, @@ -71,8 +87,8 @@ class TestCaseCanon(PexpectTestCase.PexpectTestCase): child.expect_exact('_' * send_bytes) # BEL is not found, - with self.assertRaises(pexpect.TIMEOUT, timeout=5): - child.expect_exact('\a') + with self.assertRaises(pexpect.TIMEOUT): + child.expect_exact('\a', timeout=1) # cleanup, child.sendeof() # exit cat(1) @@ -81,6 +97,10 @@ class TestCaseCanon(PexpectTestCase.PexpectTestCase): assert not child.isalive() assert child.exitstatus == 0 + @pytest.mark.skipif( + sys.platform.lower().startswith('freebsd'), + reason='os.write to BLOCK indefinitely on FreeBSD in this case' + ) def test_beyond_max_icanon(self): " a single BEL is sent when maximum bytes is reached. " # given, @@ -116,6 +136,10 @@ class TestCaseCanon(PexpectTestCase.PexpectTestCase): assert not child.isalive() assert child.exitstatus == 0 + @pytest.mark.skipif( + sys.platform.lower().startswith('freebsd'), + reason='os.write to BLOCK indefinitely on FreeBSD in this case' + ) def test_max_no_icanon(self): " may exceed maximum input bytes if canonical mode is disabled. " # given, diff --git a/tools/display-sighandlers.py b/tools/display-sighandlers.py index 98445e9..f3559f7 100755 --- a/tools/display-sighandlers.py +++ b/tools/display-sighandlers.py @@ -12,7 +12,11 @@ for name, value in [(signal_name, getattr(signal, signal_name)) for signal_name in dir(signal) if signal_name.startswith('SIG') and not signal_name.startswith('SIG_')]: - handler = signal.getsignal(value) + try: + handler = signal.getsignal(value) + except ValueError: + # FreeBSD: signal number out of range + handler = 'out of range' description = { signal.SIG_IGN: "ignored(SIG_IGN)", signal.SIG_DFL: "default(SIG_DFL)" diff --git a/tools/teamcity-runtests.sh b/tools/teamcity-runtests.sh index b74f179..bcb28f7 100755 --- a/tools/teamcity-runtests.sh +++ b/tools/teamcity-runtests.sh @@ -14,6 +14,7 @@ export PYTHONIOENCODING=UTF8 export LANG=en_US.UTF-8 pyversion=$1 +shift here=$(cd `dirname $0`; pwd) osrel=$(uname -s) venv=teamcity-pexpect @@ -25,7 +26,9 @@ if [ -z $venv_wrapper ]; then fi . ${venv_wrapper} -workon ${venv} || mkvirtualenv -p `which python${pyversion}` ${venv} || true +rmvirtualenv ${venv} || true +mkvirtualenv -p `which python${pyversion}` ${venv} || true +workon ${venv} # install ptyprocess cd $here/../../ptyprocess @@ -44,7 +47,7 @@ py.test \ --junit-xml=results.${osrel}.py${pyversion}.xml \ --verbose \ --verbose \ - || ret=$? + "$@" || ret=$? if [ $ret -ne 0 ]; then # we always exit 0, preferring instead the jUnit XML |