Skip to content

Commit 3af1fa9

Browse files
committed
testing: Add a system-postgres mode for faster testing
Postgres can be slow to spin up and down clusters for each test. This patch allows us to just test against an externally managed postgres instance. This is particularly interesting in CI, where we can run a postgres service in a separate container. The provider still uses nonce-based multitenancy. It tries to clean up, but it can fail if a test gets interrupted or teardown fails.
1 parent ad2dc97 commit 3af1fa9

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

contrib/pyln-testing/pyln/testing/db.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import subprocess
1313
import time
1414
from typing import Dict, List, Optional, Union
15+
from urllib.parse import urlparse
1516

1617

1718
class BaseDb(object):
@@ -241,3 +242,48 @@ def stop(self):
241242
self.proc.wait()
242243
shutil.rmtree(self.pgdir)
243244
drop_unused_port(self.port)
245+
246+
247+
class SystemPostgresDbProvider(PostgresDbProvider):
248+
"""A DB provider that uses an externally controlled postgres instance.
249+
250+
Spinning postgres instances up and down is costly. We are keeping
251+
tests separate by assigning them random names, so we can share a
252+
single DB cluster. This provider does just that: it talks to an
253+
externally managed cluster, creates and deletes DBs on demand, but
254+
does not manage the cluster's lifecycle.
255+
256+
The external cluster to talk to can be specified via the
257+
`CLN_TEST_POSTGRES_DSN` environment variable.
258+
259+
Please make sure that the user specified in the DSN has the
260+
permission to create new DBs.
261+
262+
Since tests, may end up interrupted, and may not clean up the
263+
databases they created, be aware that over time your cluster may
264+
accumulate quite a few databases. This mode is mostly intended for
265+
CI where a throwaway postgre cluster can be spun up and tested
266+
against.
267+
268+
"""
269+
270+
def __init__(self, directory):
271+
self.dsn = os.environ.get("CLN_TEST_POSTGRES_DSN")
272+
self.conn = None
273+
parts = urlparse(self.dsn)
274+
275+
self.hostname = parts.hostname
276+
self.username = parts.username
277+
self.port = parts.port
278+
self.dbname = parts.path
279+
280+
def stop(self):
281+
pass
282+
283+
def start(self):
284+
self.conn = psycopg2.connect(self.dsn)
285+
cur = self.conn.cursor()
286+
cur.execute("SELECT 1")
287+
cur.close()
288+
# Required for CREATE DATABASE to work
289+
self.conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

contrib/pyln-testing/pyln/testing/fixtures.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from concurrent import futures
2-
from pyln.testing.db import SqliteDbProvider, PostgresDbProvider
2+
from pyln.testing.db import SqliteDbProvider, PostgresDbProvider, SystemPostgresDbProvider
33
from pyln.testing.utils import NodeFactory, BitcoinD, ElementsD, env, LightningNode, TEST_DEBUG, TEST_NETWORK
44
from pyln.client import Millisatoshi
55
from typing import Dict
@@ -640,6 +640,7 @@ def checkMemleak(node):
640640
providers = {
641641
'sqlite3': SqliteDbProvider,
642642
'postgres': PostgresDbProvider,
643+
'system-postgres': SystemPostgresDbProvider,
643644
}
644645

645646

0 commit comments

Comments
 (0)