Skip to content

Commit

Permalink
Add GitHub worflows for testing
Browse files Browse the repository at this point in the history
Also improve the configurability of the test database.
  • Loading branch information
Cito committed Jan 29, 2022
1 parent ac66e2e commit a40443c
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 116 deletions.
File renamed without changes.
24 changes: 24 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Run PyGreSQL quality checks

on:
push:
pull_request:

jobs:
checks:
name: Quality checks run
runs-on: ubuntu-20.04

strategy:
fail-fast: false

steps:
- uses: actions/checkout@v2
- name: Install tox
run: pip install tox
- uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Run quality checks
run: tox -e flake8,docs
timeout-minutes: 5
67 changes: 67 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Run PyGreSQL test matrix

# this has been shamelessly copied from Psycopg

on:
push:
pull_request:

jobs:
tests:
name: Unit tests run
runs-on: ubuntu-18.04

strategy:
fail-fast: false
matrix:
include:
- {python: "2.7", postgres: "9.3"}
- {python: "3.5", postgres: "9.6"}
- {python: "3.6", postgres: "10"}
- {python: "3.7", postgres: "11"}
- {python: "3.8", postgres: "12"}
- {python: "3.9", postgres: "13"}
- {python: "3.10", postgres: "14"}

# Opposite extremes of the supported Py/PG range, other architecture
- {python: "2.7", postgres: "14", architecture: "x86"}
- {python: "3.5", postgres: "13", architecture: "x86"}
- {python: "3.6", postgres: "12", architecture: "x86"}
- {python: "3.7", postgres: "11", architecture: "x86"}
- {python: "3.8", postgres: "10", architecture: "x86"}
- {python: "3.9", postgres: "9.6", architecture: "x86"}
- {python: "3.10", postgres: "9.3", architecture: "x86"}

env:
PYGRESQL_DB: test
PYGRESQL_HOST: 127.0.0.1
PYGRESQL_USER: test
PYGRESQL_PASSWD: test

services:
postgresql:
image: postgres:${{ matrix.postgres }}
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v2
- name: Install tox
run: pip install tox
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
- name: Run tests
env:
MATRIX_PYTHON: ${{ matrix.python }}
run: tox -e py${MATRIX_PYTHON/./}
timeout-minutes: 5
28 changes: 28 additions & 0 deletions tests/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

from os import environ

# We need a database to test against.
# If LOCAL_PyGreSQL.py exists, we will get our information from that.
# Otherwise, we use the defaults.

# The tests should be run with various PostgreSQL versions and databases
# created with different encodings and locales. Particularly, make sure the
# tests are running against databases created with both SQL_ASCII and UTF8.

# The current user must have create schema privilege on the database.

dbname = environ.get('PYGRESQL_DB', 'unittest')
dbhost = environ.get('PYGRESQL_HOST', None)
dbport = environ.get('PYGRESQL_PORT', 5432)
dbuser = environ.get('PYGRESQL_USER', None)
dbpasswd = environ.get('PYGRESQL_PASSWD', None)

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
16 changes: 2 additions & 14 deletions tests/test_classic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,11 @@

from pg import *

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
dbname = 'unittest'
dbhost = None
dbport = 5432

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
from .config import dbname, dbhost, dbport, dbuser, dbpasswd


def open_db():
db = DB(dbname, dbhost, dbport)
db = DB(dbname, dbhost, dbport, user=dbuser, passwd=dbpasswd)
db.query("SET DATESTYLE TO 'ISO'")
db.query("SET TIME ZONE 'EST5EDT'")
db.query("SET DEFAULT_WITH_OIDS=FALSE")
Expand Down
25 changes: 6 additions & 19 deletions tests/test_classic_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,7 @@

import pg # the module under test

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
# These tests should be run with various PostgreSQL versions and databases
# created with different encodings and locales. Particularly, make sure the
# tests are running against databases created with both SQL_ASCII and UTF8.
dbname = 'unittest'
dbhost = None
dbport = 5432

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
from .config import dbname, dbhost, dbport, dbuser, dbpasswd

try: # noinspection PyUnboundLocalVariable,PyUnresolvedReferences
long
Expand All @@ -67,15 +52,17 @@
def connect():
"""Create a basic pg connection to the test database."""
# noinspection PyArgumentList
connection = pg.connect(dbname, dbhost, dbport)
connection = pg.connect(dbname, dbhost, dbport,
user=dbuser, passwd=dbpasswd)
connection.query("set client_min_messages=warning")
return connection


def connect_nowait():
"""Start a basic pg connection in a non-blocking manner."""
# noinspection PyArgumentList
return pg.connect(dbname, dbhost, dbport, nowait=True)
return pg.connect(dbname, dbhost, dbport,
user=dbuser, passwd=dbpasswd, nowait=True)


class TestCanConnect(unittest.TestCase):
Expand All @@ -102,7 +89,7 @@ def testCanConnectNoWait(self):
try:
connection = connect_nowait()
rc = connection.poll()
self.assertEqual(rc, pg.POLLING_READING)
self.assertIn(rc, (pg.POLLING_READING, pg.POLLING_WRITING))
while rc not in (pg.POLLING_OK, pg.POLLING_FAILED):
rc = connection.poll()
except pg.Error as error:
Expand Down
17 changes: 2 additions & 15 deletions tests/test_classic_dbwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,10 @@
from time import strftime
from operator import itemgetter

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
# The current user must have create schema privilege on the database.
dbname = 'unittest'
dbhost = None
dbport = 5432
from .config import dbname, dbhost, dbport, dbuser, dbpasswd

debug = False # let DB wrapper print debugging output

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass

try: # noinspection PyUnboundLocalVariable,PyUnresolvedReferences
long
except NameError: # Python >= 3.0
Expand All @@ -68,7 +55,7 @@

def DB():
"""Create a DB wrapper object connecting to the test database."""
db = pg.DB(dbname, dbhost, dbport)
db = pg.DB(dbname, dbhost, dbport, user=dbuser, passwd=dbpasswd)
if debug:
db.debug = debug
db.query("set client_min_messages=warning")
Expand Down
17 changes: 3 additions & 14 deletions tests/test_classic_largeobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,16 @@

import pg # the module under test

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
dbname = 'unittest'
dbhost = None
dbport = 5432

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
from .config import dbname, dbhost, dbport, dbuser, dbpasswd

windows = os.name == 'nt'


# noinspection PyArgumentList
def connect():
"""Create a basic pg connection to the test database."""
connection = pg.connect(dbname, dbhost, dbport)
connection = pg.connect(dbname, dbhost, dbport,
user=dbuser, passwd=dbpasswd)
connection.query("set client_min_messages=warning")
return connection

Expand Down
9 changes: 2 additions & 7 deletions tests/test_classic_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@

import pg # the module under test

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
# The current user must have create schema privilege on the database.
dbname = 'unittest'
dbhost = None
dbport = 5432
from .config import dbname, dbhost, dbport, dbuser, dbpasswd

debug = False # let DB wrapper print debugging output

Expand All @@ -37,7 +32,7 @@

def DB():
"""Create a DB wrapper object connecting to the test database."""
db = pg.DB(dbname, dbhost, dbport)
db = pg.DB(dbname, dbhost, dbport, user=dbuser, passwd=dbpasswd)
if debug:
db.debug = debug
return db
Expand Down
17 changes: 3 additions & 14 deletions tests/test_dbapi20.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,7 @@
# noinspection PyUnresolvedReferences
import dbapi20

# We need a database to test against.
# If LOCAL_PyGreSQL.py exists we will get our information from that.
# Otherwise we use the defaults.
dbname = 'dbapi20_test'
dbhost = ''
dbport = 5432
try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
from .config import dbname, dbhost, dbport, dbuser, dbpasswd

try: # noinspection PyUnboundLocalVariable,PyUnresolvedReferences
long
Expand All @@ -51,7 +39,8 @@ class test_PyGreSQL(dbapi20.DatabaseAPI20Test):
driver = pgdb
connect_args = ()
connect_kw_args = {
'database': dbname, 'host': '%s:%d' % (dbhost or '', dbport or -1)}
'database': dbname, 'host': '%s:%d' % (dbhost or '', dbport or -1),
'user': dbuser, 'password': dbpasswd}

lower_func = 'lower' # For stored procedure test

Expand Down
20 changes: 4 additions & 16 deletions tests/test_dbapi20_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,7 @@

import pgdb # the module under test

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
# The current user must have create schema privilege on the database.
dbname = 'unittest'
dbhost = None
dbport = 5432

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
from .config import dbname, dbhost, dbport, dbuser, dbpasswd

try: # noinspection PyUnboundLocalVariable,PyUnresolvedReferences
unicode
Expand Down Expand Up @@ -126,8 +113,9 @@ class TestCopy(unittest.TestCase):

@staticmethod
def connect():
return pgdb.connect(
database=dbname, host='%s:%d' % (dbhost or '', dbport or -1))
host = '%s:%d' % (dbhost or '', dbport or -1)
return pgdb.connect(database=dbname, host=host,
user=dbuser, password=dbpasswd)

@classmethod
def setUpClass(cls):
Expand Down
20 changes: 4 additions & 16 deletions tests/test_tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,15 @@
from pg import DB
from pgdb import connect

# We need a database to test against. If LOCAL_PyGreSQL.py exists we will
# get our information from that. Otherwise we use the defaults.
dbname = 'unittest'
dbhost = None
dbport = 5432

try:
from .LOCAL_PyGreSQL import * # noqa: F401
except (ImportError, ValueError):
try:
from LOCAL_PyGreSQL import * # noqa: F401
except ImportError:
pass
from .config import dbname, dbhost, dbport, dbuser, dbpasswd


class TestClassicTutorial(unittest.TestCase):
"""Test the First Steps Tutorial for the classic interface."""

def setUp(self):
"""Setup test tables or empty them if they already exist."""
db = DB(dbname=dbname, host=dbhost, port=dbport)
db = DB(dbname, dbhost, dbport, user=dbuser, passwd=dbpasswd)
db.query("set datestyle to 'iso'")
db.query("set default_with_oids=false")
db.query("set standard_conforming_strings=false")
Expand Down Expand Up @@ -122,9 +110,9 @@ class TestDbApi20Tutorial(unittest.TestCase):

def setUp(self):
"""Setup test tables or empty them if they already exist."""
database = dbname
host = '%s:%d' % (dbhost or '', dbport or -1)
con = connect(database=database, host=host)
con = connect(database=dbname, host=host,
user=dbuser, password=dbpasswd)
cur = con.cursor()
cur.execute("set datestyle to 'iso'")
cur.execute("set default_with_oids=false")
Expand Down

0 comments on commit a40443c

Please sign in to comment.