pytest: Have the DB provider search for the postgres binary

This replaces the hard-coded path to the `postgres` and `initdb` binaries with
a slightly more flexible search. It'll pick the newest version installed.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2019-09-14 16:03:44 +02:00 committed by Rusty Russell
parent 136d4b2568
commit 063b319da1

View File

@ -1,9 +1,11 @@
from ephemeral_port_reserve import reserve from ephemeral_port_reserve import reserve
from glob import glob
import logging import logging
import os import os
import psycopg2 import psycopg2
import random import random
import re
import shutil import shutil
import signal import signal
import sqlite3 import sqlite3
@ -112,14 +114,40 @@ class PostgresDbProvider(object):
self.proc = None self.proc = None
print("Starting PostgresDbProvider") print("Starting PostgresDbProvider")
def locate_path(self):
prefix = '/usr/lib/postgresql/*'
matches = glob(prefix)
candidates = {}
for m in matches:
g = re.search(r'([0-9]+[\.0-9]*)', m)
if not g:
continue
candidates[float(g.group(1))] = m
if len(candidates) == 0:
raise ValueError("Could not find `postgres` and `initdb` binaries in {}. Is postgresql installed?".format(prefix))
# Now iterate in reverse order through matches
for k, v in sorted(candidates.items())[::-1]:
initdb = os.path.join(v, 'bin', 'initdb')
postgres = os.path.join(v, 'bin', 'postgres')
if os.path.isfile(initdb) and os.path.isfile(postgres):
logging.info("Found `postgres` and `initdb` in {}".format(os.path.join(v, 'bin')))
return initdb, postgres
raise ValueError("Could not find `postgres` and `initdb` in any of the possible paths: {}".format(candidates.values()))
def start(self): def start(self):
passfile = os.path.join(self.directory, "pgpass.txt") passfile = os.path.join(self.directory, "pgpass.txt")
self.pgdir = os.path.join(self.directory, 'pgsql') self.pgdir = os.path.join(self.directory, 'pgsql')
# Need to write a tiny file containing the password so `initdb` can pick it up # Need to write a tiny file containing the password so `initdb` can pick it up
with open(passfile, 'w') as f: with open(passfile, 'w') as f:
f.write('cltest\n') f.write('cltest\n')
initdb, postgres = self.locate_path()
subprocess.check_call([ subprocess.check_call([
'/usr/lib/postgresql/10/bin/initdb', initdb,
'--pwfile={}'.format(passfile), '--pwfile={}'.format(passfile),
'--pgdata={}'.format(self.pgdir), '--pgdata={}'.format(self.pgdir),
'--auth=trust', '--auth=trust',
@ -127,7 +155,7 @@ class PostgresDbProvider(object):
]) ])
self.port = reserve() self.port = reserve()
self.proc = subprocess.Popen([ self.proc = subprocess.Popen([
'/usr/lib/postgresql/10/bin/postgres', postgres,
'-k', '/tmp/', # So we don't use /var/lib/... '-k', '/tmp/', # So we don't use /var/lib/...
'-D', self.pgdir, '-D', self.pgdir,
'-p', str(self.port), '-p', str(self.port),