Merge branch 'manylinux'

This commit is contained in:
Daniele Varrazzo 2017-02-02 02:15:15 +00:00
commit ad6506ff69
13 changed files with 101 additions and 15 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ scripts/pypi_docs_upload.py
env env
.tox .tox
/rel /rel
/wheels

50
scripts/build-manylinux.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/bash
# Create manylinux1 wheels for psycopg2
#
# Run this script with something like:
#
# docker run --rm -v `pwd`:/psycopg2 quay.io/pypa/manylinux1_x86_64 /psycopg2/scripts/build-manylinux.sh
# docker run --rm -v `pwd`:/psycopg2 quay.io/pypa/manylinux1_i686 linux32 /psycopg2/scripts/build-manylinux.sh
#
# Tests run against a postgres on the host. Use -e PSYCOPG_TESTDB_USER=... etc
# to configure tests run.
set -e -x
# Install postgres packages for build and testing
# This doesn't work:
# rpm -Uvh "http://yum.postgresql.org/9.5/redhat/rhel-5-x86_64/pgdg-redhat95-9.5-3.noarch.rpm"
wget -O "/tmp/pgdg.rpm" "https://download.postgresql.org/pub/repos/yum/9.5/redhat/rhel-5-x86_64/pgdg-centos95-9.5-3.noarch.rpm"
rpm -Uv "/tmp/pgdg.rpm"
yum install -y postgresql95-devel
# Make pg_config available
export PGPATH=/usr/pgsql-9.5/bin/
export PATH="$PGPATH:$PATH"
# Find psycopg version
export VERSION=$(grep -e ^PSYCOPG_VERSION /psycopg2/setup.py | sed "s/.*'\(.*\)'/\1/")
export WHEELSDIR="/psycopg2/wheels/psycopg2-$VERSION"
# Create the wheel packages
for PYBIN in /opt/python/*/bin; do
"${PYBIN}/pip" wheel /psycopg2/ -w "$WHEELSDIR"
done
# Bundle external shared libraries into the wheels
for WHL in "$WHEELSDIR"/*.whl; do
auditwheel repair "$WHL" -w "$WHEELSDIR"
done
# Make sure libpq is not in the system
yum remove -y postgresql95-devel
# Connect to the host to test. Use 'docker -e' to pass other variables
export PSYCOPG2_TESTDB_HOST=$(ip route show | awk '/default/ {print $3}')
# Install packages and test
for PYBIN in /opt/python/*/bin; do
"${PYBIN}/pip" install psycopg2 --no-index -f "$WHEELSDIR"
"${PYBIN}/python" -c "from psycopg2 import tests; tests.unittest.main(defaultTest='tests.test_suite')"
done

View File

@ -23,7 +23,7 @@
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details. # License for more details.
from testutils import unittest, skip_before_postgres from testutils import unittest, skip_before_postgres, slow
import psycopg2 import psycopg2
from psycopg2 import extensions from psycopg2 import extensions
@ -318,6 +318,7 @@ class AsyncTests(ConnectingTestCase):
self.assert_(conn.async) self.assert_(conn.async)
conn.close() conn.close()
@slow
def test_flush_on_write(self): def test_flush_on_write(self):
# a very large query requires a flush loop to be sent to the backend # a very large query requires a flush loop to be sent to the backend
curs = self.conn.cursor() curs = self.conn.cursor()

View File

@ -30,7 +30,7 @@ import psycopg2.extensions
from psycopg2 import extras from psycopg2 import extras
from testconfig import dsn from testconfig import dsn
from testutils import unittest, ConnectingTestCase, skip_before_postgres from testutils import unittest, ConnectingTestCase, skip_before_postgres, slow
class CancelTests(ConnectingTestCase): class CancelTests(ConnectingTestCase):
@ -48,6 +48,7 @@ class CancelTests(ConnectingTestCase):
def test_empty_cancel(self): def test_empty_cancel(self):
self.conn.cancel() self.conn.cancel()
@slow
@skip_before_postgres(8, 2) @skip_before_postgres(8, 2)
def test_cancel(self): def test_cancel(self):
errors = [] errors = []

View File

@ -35,7 +35,7 @@ from psycopg2 import extensions as ext
from testutils import ( from testutils import (
unittest, decorate_all_tests, skip_if_no_superuser, unittest, decorate_all_tests, skip_if_no_superuser,
skip_before_postgres, skip_after_postgres, skip_before_libpq, skip_before_postgres, skip_after_postgres, skip_before_libpq,
ConnectingTestCase, skip_if_tpc_disabled, skip_if_windows) ConnectingTestCase, skip_if_tpc_disabled, skip_if_windows, slow)
from testconfig import dsn, dbname from testconfig import dsn, dbname
@ -196,6 +196,7 @@ class ConnectionTests(ConnectingTestCase):
self.assertRaises(psycopg2.NotSupportedError, self.assertRaises(psycopg2.NotSupportedError,
cnn.xid, 42, "foo", "bar") cnn.xid, 42, "foo", "bar")
@slow
@skip_before_postgres(8, 2) @skip_before_postgres(8, 2)
def test_concurrent_execution(self): def test_concurrent_execution(self):
def slave(): def slave():
@ -246,6 +247,7 @@ class ConnectionTests(ConnectingTestCase):
gc.collect() gc.collect()
self.assert_(w() is None) self.assert_(w() is None)
@slow
def test_commit_concurrency(self): def test_commit_concurrency(self):
# The problem is the one reported in ticket #103. Because of bad # The problem is the one reported in ticket #103. Because of bad
# status check, we commit even when a commit is already on its way. # status check, we commit even when a commit is already on its way.
@ -899,6 +901,7 @@ class ConnectionTwoPhaseTests(ConnectingTestCase):
(dbname,)) (dbname,))
self.assertEqual('42_Z3RyaWQ=_YnF1YWw=', cur.fetchone()[0]) self.assertEqual('42_Z3RyaWQ=_YnF1YWw=', cur.fetchone()[0])
@slow
def test_xid_roundtrip(self): def test_xid_roundtrip(self):
for fid, gtrid, bqual in [ for fid, gtrid, bqual in [
(0, "", ""), (0, "", ""),
@ -921,6 +924,7 @@ class ConnectionTwoPhaseTests(ConnectingTestCase):
cnn.tpc_rollback(xid) cnn.tpc_rollback(xid)
@slow
def test_unparsed_roundtrip(self): def test_unparsed_roundtrip(self):
for tid in [ for tid in [
'', '',

View File

@ -24,8 +24,8 @@
import sys import sys
import string import string
from testutils import unittest, ConnectingTestCase, decorate_all_tests from testutils import (unittest, ConnectingTestCase, decorate_all_tests,
from testutils import skip_if_no_iobase, skip_before_postgres skip_if_no_iobase, skip_before_postgres, slow)
from cStringIO import StringIO from cStringIO import StringIO
from itertools import cycle, izip from itertools import cycle, izip
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
@ -77,6 +77,7 @@ class CopyTests(ConnectingTestCase):
data text data text
)''') )''')
@slow
def test_copy_from(self): def test_copy_from(self):
curs = self.conn.cursor() curs = self.conn.cursor()
try: try:
@ -84,6 +85,7 @@ class CopyTests(ConnectingTestCase):
finally: finally:
curs.close() curs.close()
@slow
def test_copy_from_insane_size(self): def test_copy_from_insane_size(self):
# Trying to trigger a "would block" error # Trying to trigger a "would block" error
curs = self.conn.cursor() curs = self.conn.cursor()
@ -120,6 +122,7 @@ class CopyTests(ConnectingTestCase):
self.assertRaises(ZeroDivisionError, self.assertRaises(ZeroDivisionError,
curs.copy_from, MinimalRead(f), "tcopy", columns=cols()) curs.copy_from, MinimalRead(f), "tcopy", columns=cols())
@slow
def test_copy_to(self): def test_copy_to(self):
curs = self.conn.cursor() curs = self.conn.cursor()
try: try:

View File

@ -26,8 +26,8 @@ import time
import pickle import pickle
import psycopg2 import psycopg2
import psycopg2.extensions import psycopg2.extensions
from testutils import unittest, ConnectingTestCase, skip_before_postgres from testutils import (unittest, ConnectingTestCase, skip_before_postgres,
from testutils import skip_if_no_namedtuple, skip_if_no_getrefcount skip_if_no_namedtuple, skip_if_no_getrefcount, slow)
class CursorTests(ConnectingTestCase): class CursorTests(ConnectingTestCase):
@ -331,6 +331,7 @@ class CursorTests(ConnectingTestCase):
curs.scroll(2) curs.scroll(2)
self.assertRaises(psycopg2.OperationalError, curs.scroll, -1) self.assertRaises(psycopg2.OperationalError, curs.scroll, -1)
@slow
@skip_before_postgres(8, 2) @skip_before_postgres(8, 2)
def test_iter_named_cursor_efficient(self): def test_iter_named_cursor_efficient(self):
curs = self.conn.cursor('tmp') curs = self.conn.cursor('tmp')

View File

@ -22,7 +22,7 @@
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details. # License for more details.
from testutils import unittest, ConnectingTestCase from testutils import unittest, ConnectingTestCase, slow
try: try:
reload reload
@ -34,6 +34,7 @@ from psycopg2 import errorcodes
class ErrocodeTests(ConnectingTestCase): class ErrocodeTests(ConnectingTestCase):
@slow
def test_lookup_threadsafe(self): def test_lookup_threadsafe(self):
# Increase if it does not fail with KeyError # Increase if it does not fail with KeyError

View File

@ -27,7 +27,7 @@ import psycopg2
import psycopg2.extensions import psycopg2.extensions
import psycopg2.extras import psycopg2.extras
from testutils import ConnectingTestCase from testutils import ConnectingTestCase, slow
class ConnectionStub(object): class ConnectionStub(object):
@ -61,6 +61,7 @@ class GreenTestCase(ConnectingTestCase):
lambda conn: psycopg2.extras.wait_select(stub)) lambda conn: psycopg2.extras.wait_select(stub))
return stub return stub
@slow
def test_flush_on_write(self): def test_flush_on_write(self):
# a very large query requires a flush loop to be sent to the backend # a very large query requires a flush loop to be sent to the backend
conn = self.conn conn = self.conn

View File

@ -26,7 +26,7 @@ from testutils import unittest
import psycopg2 import psycopg2
from psycopg2 import extensions from psycopg2 import extensions
from testutils import ConnectingTestCase, script_to_py3 from testutils import ConnectingTestCase, script_to_py3, slow
from testconfig import dsn from testconfig import dsn
import sys import sys
@ -72,6 +72,7 @@ conn.close()
return Popen([sys.executable, '-c', script_to_py3(script)], stdout=PIPE) return Popen([sys.executable, '-c', script_to_py3(script)], stdout=PIPE)
@slow
def test_notifies_received_on_poll(self): def test_notifies_received_on_poll(self):
self.autocommit(self.conn) self.autocommit(self.conn)
self.listen('foo') self.listen('foo')
@ -90,6 +91,7 @@ conn.close()
self.assertEqual(pid, self.conn.notifies[0][0]) self.assertEqual(pid, self.conn.notifies[0][0])
self.assertEqual('foo', self.conn.notifies[0][1]) self.assertEqual('foo', self.conn.notifies[0][1])
@slow
def test_many_notifies(self): def test_many_notifies(self):
self.autocommit(self.conn) self.autocommit(self.conn)
for name in ['foo', 'bar', 'baz']: for name in ['foo', 'bar', 'baz']:
@ -119,6 +121,7 @@ conn.close()
self.assertEqual(pid, self.conn.notifies[0][0]) self.assertEqual(pid, self.conn.notifies[0][0])
self.assertEqual('foo', self.conn.notifies[0][1]) self.assertEqual('foo', self.conn.notifies[0][1])
@slow
def test_notify_object(self): def test_notify_object(self):
self.autocommit(self.conn) self.autocommit(self.conn)
self.listen('foo') self.listen('foo')
@ -128,6 +131,7 @@ conn.close()
notify = self.conn.notifies[0] notify = self.conn.notifies[0]
self.assert_(isinstance(notify, psycopg2.extensions.Notify)) self.assert_(isinstance(notify, psycopg2.extensions.Notify))
@slow
def test_notify_attributes(self): def test_notify_attributes(self):
self.autocommit(self.conn) self.autocommit(self.conn)
self.listen('foo') self.listen('foo')
@ -140,6 +144,7 @@ conn.close()
self.assertEqual('foo', notify.channel) self.assertEqual('foo', notify.channel)
self.assertEqual('', notify.payload) self.assertEqual('', notify.payload)
@slow
def test_notify_payload(self): def test_notify_payload(self):
if self.conn.server_version < 90000: if self.conn.server_version < 90000:
return self.skipTest("server version %s doesn't support notify payload" return self.skipTest("server version %s doesn't support notify payload"
@ -155,6 +160,7 @@ conn.close()
self.assertEqual('foo', notify.channel) self.assertEqual('foo', notify.channel)
self.assertEqual('Hello, world!', notify.payload) self.assertEqual('Hello, world!', notify.payload)
@slow
def test_notify_deque(self): def test_notify_deque(self):
from collections import deque from collections import deque
self.autocommit(self.conn) self.autocommit(self.conn)
@ -167,6 +173,7 @@ conn.close()
self.assert_(isinstance(notify, psycopg2.extensions.Notify)) self.assert_(isinstance(notify, psycopg2.extensions.Notify))
self.assertEqual(len(self.conn.notifies), 0) self.assertEqual(len(self.conn.notifies), 0)
@slow
def test_notify_noappend(self): def test_notify_noappend(self):
self.autocommit(self.conn) self.autocommit(self.conn)
self.conn.notifies = None self.conn.notifies = None

View File

@ -23,7 +23,7 @@
# License for more details. # License for more details.
import threading import threading
from testutils import unittest, ConnectingTestCase, skip_before_postgres from testutils import unittest, ConnectingTestCase, skip_before_postgres, slow
import psycopg2 import psycopg2
from psycopg2.extensions import ( from psycopg2.extensions import (
@ -131,6 +131,7 @@ class DeadlockSerializationTests(ConnectingTestCase):
ConnectingTestCase.tearDown(self) ConnectingTestCase.tearDown(self)
@slow
def test_deadlock(self): def test_deadlock(self):
self.thread1_error = self.thread2_error = None self.thread1_error = self.thread2_error = None
step1 = threading.Event() step1 = threading.Event()
@ -178,6 +179,7 @@ class DeadlockSerializationTests(ConnectingTestCase):
self.assertTrue(isinstance( self.assertTrue(isinstance(
error, psycopg2.extensions.TransactionRollbackError)) error, psycopg2.extensions.TransactionRollbackError))
@slow
def test_serialisation_failure(self): def test_serialisation_failure(self):
self.thread1_error = self.thread2_error = None self.thread1_error = self.thread2_error = None
step1 = threading.Event() step1 = threading.Event()

View File

@ -22,9 +22,8 @@ from datetime import date, datetime
from functools import wraps from functools import wraps
from pickle import dumps, loads from pickle import dumps, loads
from testutils import unittest, skip_if_no_uuid, skip_before_postgres from testutils import (unittest, skip_if_no_uuid, skip_before_postgres,
from testutils import ConnectingTestCase, decorate_all_tests ConnectingTestCase, decorate_all_tests, py3_raises_typeerror, slow)
from testutils import py3_raises_typeerror
import psycopg2 import psycopg2
import psycopg2.extras import psycopg2.extras
@ -708,6 +707,7 @@ class AdaptTypeTestCase(ConnectingTestCase):
curs.execute("select (1,2)::type_ii") curs.execute("select (1,2)::type_ii")
self.assertRaises(psycopg2.DataError, curs.fetchone) self.assertRaises(psycopg2.DataError, curs.fetchone)
@slow
@skip_if_no_composite @skip_if_no_composite
@skip_before_postgres(8, 4) @skip_before_postgres(8, 4)
def test_from_tables(self): def test_from_tables(self):

View File

@ -447,7 +447,6 @@ def script_to_py3(script):
class py3_raises_typeerror(object): class py3_raises_typeerror(object):
def __enter__(self): def __enter__(self):
pass pass
@ -455,3 +454,18 @@ class py3_raises_typeerror(object):
if sys.version_info[0] >= 3: if sys.version_info[0] >= 3:
assert type is TypeError assert type is TypeError
return True return True
def slow(f):
"""Decorator to mark slow tests we may want to skip
Note: in order to find slow tests you can run:
make check 2>&1 | ts -i "%.s" | sort -n
"""
@wraps(f)
def slow_(self):
if os.environ.get('PSYCOPG2_TEST_FAST'):
return self.skipTest("slow test")
return f(self)
return slow_