Skip to content

Commit 656c39a

Browse files
committed
ci: Stop relying on Travis' version of PostgreSQL
We now install the necessary version of PostgreSQL explicitly. This allows testing on PostgreSQL versions that are not supported by Travis directly. And also, do an explicit check that the version of the server being tested corresponds to the PGVERSION environment variable.
1 parent 3f9523c commit 656c39a

File tree

6 files changed

+102
-46
lines changed

6 files changed

+102
-46
lines changed

.ci/travis-before-install.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
#!/bin/bash
22

3+
set -e -x
4+
5+
if [ -z "${PGVERSION}" ]; then
6+
echo "Missing PGVERSION environment variable."
7+
exit 1
8+
fi
9+
310
if [[ "${TRAVIS_OS_NAME}" == "linux" && "${BUILD}" == *wheels* ]]; then
411
# Allow docker guests to connect to the database
512
sudo service postgresql stop ${PGVERSION}
@@ -9,3 +16,20 @@ if [[ "${TRAVIS_OS_NAME}" == "linux" && "${BUILD}" == *wheels* ]]; then
916
sudo tee --append /etc/postgresql/${PGVERSION}/main/pg_hba.conf
1017
sudo service postgresql start ${PGVERSION}
1118
fi
19+
20+
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
21+
git clone --depth 1 https://github.com/yyuu/pyenv.git ~/.pyenv
22+
PYENV_ROOT="$HOME/.pyenv"
23+
PATH="$PYENV_ROOT/bin:$PATH"
24+
eval "$(pyenv init -)"
25+
26+
if ! (pyenv versions | grep "${PYTHON_VERSION}$"); then
27+
pyenv install ${PYTHON_VERSION}
28+
fi
29+
pyenv global ${PYTHON_VERSION}
30+
pyenv rehash
31+
32+
# Install PostgreSQL
33+
brew update
34+
brew install postgresql-${PGVERSION}
35+
fi

.ci/travis-install.sh

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,6 @@
22

33
set -e -x
44

5-
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
6-
git clone --depth 1 https://github.com/yyuu/pyenv.git ~/.pyenv
7-
PYENV_ROOT="$HOME/.pyenv"
8-
PATH="$PYENV_ROOT/bin:$PATH"
9-
eval "$(pyenv init -)"
10-
11-
if ! (pyenv versions | grep "${PYTHON_VERSION}$"); then
12-
pyenv install ${PYTHON_VERSION}
13-
fi
14-
pyenv global ${PYTHON_VERSION}
15-
pyenv rehash
16-
fi
17-
185
pip install --upgrade pip wheel
196
pip install --upgrade setuptools
207
pip install -r .ci/requirements.txt

.ci/travis-tests.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
1313
eval "$(pyenv init -)"
1414
fi
1515

16+
# Make sure we test with the correct PostgreSQL version.
17+
export PGINSTALLATION="/usr/lib/postgresql/${PGVERSION}/bin"
18+
1619
if [[ "${BUILD}" == *quicktests* ]]; then
1720
make && make quicktest
1821
else

.travis.yml

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ env:
1818

1919
- DOCS_PUSH_KEY_LABEL=0760b951e99c
2020

21+
addons:
22+
apt:
23+
sources:
24+
- sourceline: 'deb https://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main'
25+
key_url: 'https://www.postgresql.org/media/keys/ACCC4CF8.asc'
26+
2127
branches:
2228
# Avoid building PR branches.
2329
only:
@@ -31,11 +37,11 @@ matrix:
3137

3238
include:
3339
- os: osx
34-
env: BUILD=tests,wheels PYTHON_VERSION=3.5.2 PIP_USER=1
40+
env: BUILD=tests,wheels PYTHON_VERSION=3.5.2 PIP_USER=1 PGVERSION=9.6
3541

3642
- os: osx
3743
osx_image: xcode8.3
38-
env: BUILD=tests,wheels PYTHON_VERSION=3.6.0 PIP_USER=1
44+
env: BUILD=tests,wheels PYTHON_VERSION=3.6.0 PIP_USER=1 PGVERSION=9.6
3945

4046
# Do quick test runs for each supported version of PostgreSQL
4147
# minus the latest.
@@ -44,40 +50,36 @@ matrix:
4450
sudo: false
4551
language: python
4652
python: "3.5"
47-
services: postgresql
4853
env: BUILD=quicktests PGVERSION=9.2
4954
addons:
50-
postgresql: '9.2'
55+
apt: {packages: [postgresql-9.2]}
5156

5257
- os: linux
5358
dist: trusty
5459
sudo: false
5560
language: python
5661
python: "3.5"
57-
services: postgresql
5862
env: BUILD=quicktests PGVERSION=9.3
5963
addons:
60-
postgresql: '9.3'
64+
apt: {packages: [postgresql-9.3]}
6165

6266
- os: linux
6367
dist: trusty
6468
sudo: false
6569
language: python
6670
python: "3.5"
67-
services: postgresql
6871
env: BUILD=quicktests PGVERSION=9.4
6972
addons:
70-
postgresql: '9.4'
73+
apt: {packages: [postgresql-9.4]}
7174

7275
- os: linux
7376
dist: trusty
7477
sudo: false
7578
language: python
7679
python: "3.5"
77-
services: postgresql
7880
env: BUILD=quicktests PGVERSION=9.5
7981
addons:
80-
postgresql: '9.5'
82+
apt: {packages: [postgresql-9.5]}
8183

8284
# Do a full test run on the latest supported version of PostgreSQL
8385
# on each supported version of Python.
@@ -86,30 +88,27 @@ matrix:
8688
sudo: false
8789
language: python
8890
python: "3.5"
89-
services: postgresql
9091
env: BUILD=tests PGVERSION=9.6
9192
addons:
92-
postgresql: '9.6'
93+
apt: {packages: [postgresql-9.6]}
9394

9495
- os: linux
9596
dist: trusty
9697
sudo: false
9798
language: python
9899
python: "3.6"
99-
services: postgresql
100100
env: BUILD=tests PGVERSION=9.6
101101
addons:
102-
postgresql: '9.6'
102+
apt: {packages: [postgresql-9.6]}
103103

104104
- os: linux
105105
dist: trusty
106106
sudo: false
107107
language: python
108108
python: "3.7-dev"
109-
services: postgresql
110109
env: BUILD=tests PGVERSION=9.6
111110
addons:
112-
postgresql: '9.6'
111+
apt: {packages: [postgresql-9.6]}
113112

114113
# Build manylinux wheels. Each wheel will be tested,
115114
# so there is no need for BUILD=tests here.
@@ -121,9 +120,9 @@ matrix:
121120
language: python
122121
python: "3.5"
123122
env: BUILD=wheels,docs,release PGVERSION=9.6
124-
services: [postgresql, docker]
123+
services: [docker]
125124
addons:
126-
postgresql: '9.6'
125+
apt: {packages: [postgresql-9.6]}
127126

128127
allow_failures:
129128
- python: "3.7-dev"

asyncpg/cluster.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ class Cluster:
8484
def __init__(self, data_dir, *, pg_config_path=None):
8585
self._data_dir = data_dir
8686
self._pg_config_path = pg_config_path
87-
self._pg_config = None
88-
self._pg_config_data = None
87+
self._pg_bin_dir = os.environ.get('PGINSTALLATION')
8988
self._pg_ctl = None
9089
self._daemon_pid = None
9190
self._daemon_process = None
@@ -374,11 +373,18 @@ def trust_local_replication_by(self, user):
374373
self.reload()
375374

376375
def _init_env(self):
377-
self._pg_config = self._find_pg_config(self._pg_config_path)
378-
self._pg_config_data = self._run_pg_config(self._pg_config)
379-
self._pg_version = self._get_pg_version()
376+
if not self._pg_bin_dir:
377+
pg_config = self._find_pg_config(self._pg_config_path)
378+
pg_config_data = self._run_pg_config(pg_config)
379+
380+
self._pg_bin_dir = pg_config_data.get('bindir')
381+
if not self._pg_bin_dir:
382+
raise ClusterError(
383+
'pg_config output did not provide the BINDIR value')
384+
380385
self._pg_ctl = self._find_pg_binary('pg_ctl')
381386
self._postgres = self._find_pg_binary('postgres')
387+
self._pg_version = self._get_pg_version()
382388

383389
def _connection_addr_from_pidfile(self):
384390
pidfile = os.path.join(self._data_dir, 'postmaster.pid')
@@ -505,13 +511,7 @@ def _find_pg_config(self, pg_config_path):
505511
return pg_config_path
506512

507513
def _find_pg_binary(self, binary):
508-
bindir = self._pg_config_data.get('bindir')
509-
if not bindir:
510-
raise ClusterError(
511-
'could not find {} executable: '.format(binary) +
512-
'pg_config output did not provide the BINDIR value')
513-
514-
bpath = platform_exe(os.path.join(bindir, binary))
514+
bpath = platform_exe(os.path.join(self._pg_bin_dir, binary))
515515

516516
if not os.path.isfile(bpath):
517517
raise ClusterError(
@@ -521,9 +521,23 @@ def _find_pg_binary(self, binary):
521521
return bpath
522522

523523
def _get_pg_version(self):
524-
version_string = self._pg_config_data.get('version')
525-
if not version_string:
526-
raise ClusterError('could not determine PostgreSQL version')
524+
process = subprocess.run(
525+
[self._postgres, '--version'],
526+
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
527+
stdout, stderr = process.stdout, process.stderr
528+
529+
if process.returncode != 0:
530+
raise ClusterError(
531+
'postgres --version exited with status {:d}: {}'.format(
532+
process.returncode, stderr))
533+
534+
version_string = stdout.decode('utf-8').strip(' \n')
535+
prefix = 'postgres (PostgreSQL) '
536+
if not version_string.startswith(prefix):
537+
raise ClusterError(
538+
'could not determine server version from {!r}'.format(
539+
version_string))
540+
version_string = version_string[len(prefix):]
527541

528542
return serverversion.split_server_version_string(version_string)
529543

tests/test__environment.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (C) 2016-present the asyncpg authors and contributors
2+
# <see AUTHORS file>
3+
#
4+
# This module is part of asyncpg and is released under
5+
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
6+
7+
8+
import os
9+
import unittest
10+
11+
import asyncpg
12+
import asyncpg.serverversion
13+
14+
from asyncpg import _testbase as tb
15+
16+
17+
class TestEnvironment(tb.ConnectedTestCase):
18+
@unittest.skipIf(not os.environ.get('PGVERSION'),
19+
"environ[PGVERSION] is not set")
20+
async def test_environment_server_version(self):
21+
pgver = os.environ.get('PGVERSION')
22+
env_ver = asyncpg.serverversion.split_server_version_string(pgver)
23+
srv_ver = self.con.get_server_version()
24+
25+
self.assertEqual(
26+
env_ver[:2], srv_ver[:2],
27+
'Expecting PostgreSQL version {pgver}, got {maj}.{min}.'.format(
28+
pgver=pgver, maj=srv_ver.major, min=srv_ver.minor)
29+
)

0 commit comments

Comments
 (0)