summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kluyver <takowl@gmail.com>2015-04-25 17:26:14 -0700
committerThomas Kluyver <takowl@gmail.com>2015-04-25 17:26:14 -0700
commitd368bbb115ae0648bd1cf4fec4d795cf56e5da00 (patch)
treec886533fe9d5f9693f915a6f0751192f65616a9e
parent8dafe9ad04bf3237b1c8a7c00e9c007b446ffc33 (diff)
parent924b014c3ecc2db01d7722c0374b3934151b9c7b (diff)
downloadpexpect-git-d368bbb115ae0648bd1cf4fec4d795cf56e5da00.tar.gz
Merge pull request #181 from pexpect/freebsd-support
Freebsd support
-rw-r--r--pexpect/pty_spawn.py2
-rw-r--r--requirements-testing.txt5
-rwxr-xr-xtests/test_interact.py18
-rw-r--r--tests/test_maxcanon.py32
-rwxr-xr-xtools/display-sighandlers.py6
-rwxr-xr-xtools/teamcity-runtests.sh7
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