Skip to content

Commit 66ca763

Browse files
authored
Merge pull request #48 from funbringer/extend_append_conf
Add **kwargs to append_conf()
2 parents 24a8f1a + e461f59 commit 66ca763

File tree

4 files changed

+70
-48
lines changed

4 files changed

+70
-48
lines changed

testgres/backup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ def spawn_primary(self, name=None, destroy=True):
149149
# New nodes should always remove dir tree
150150
node._should_rm_dirs = True
151151

152-
node.append_conf(PG_CONF_FILE, "\n")
153-
node.append_conf(PG_CONF_FILE, "port = {}".format(node.port))
152+
# Set a new port
153+
node.append_conf(filename=PG_CONF_FILE, line='\n')
154+
node.append_conf(filename=PG_CONF_FILE, port=node.port)
154155

155156
return node
156157

testgres/consts.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
BACKUP_LOG_FILE = "backup.log"
2727

2828
# defaults for node settings
29+
MAX_LOGICAL_REPLICATION_WORKERS = 5
2930
MAX_REPLICATION_SLOTS = 10
30-
MAX_WAL_SENDERS = 10
31+
MAX_WORKER_PROCESSES = 10
3132
WAL_KEEP_SEGMENTS = 20
33+
MAX_WAL_SENDERS = 10
3234

3335
# logical replication settings
3436
LOGICAL_REPL_MAX_CATCHUP_ATTEMPTS = 60

testgres/node.py

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88

99
from shutil import rmtree
10-
from six import raise_from, iteritems
10+
from six import raise_from, iteritems, text_type
1111
from tempfile import mkstemp, mkdtemp
1212

1313
from .enums import \
@@ -38,8 +38,10 @@
3838
PG_PID_FILE
3939

4040
from .consts import \
41-
MAX_WAL_SENDERS, \
41+
MAX_LOGICAL_REPLICATION_WORKERS, \
4242
MAX_REPLICATION_SLOTS, \
43+
MAX_WORKER_PROCESSES, \
44+
MAX_WAL_SENDERS, \
4345
WAL_KEEP_SEGMENTS
4446

4547
from .decorators import \
@@ -329,25 +331,27 @@ def _create_recovery_conf(self, username, slot=None):
329331
# Connect to master for some additional actions
330332
with master.connect(username=username) as con:
331333
# check if slot already exists
332-
res = con.execute("""
334+
res = con.execute(
335+
"""
333336
select exists (
334337
select from pg_catalog.pg_replication_slots
335338
where slot_name = %s
336339
)
337-
""", slot)
340+
""", slot)
338341

339342
if res[0][0]:
340343
raise TestgresException(
341344
"Slot '{}' already exists".format(slot))
342345

343346
# TODO: we should drop this slot after replica's cleanup()
344-
con.execute("""
347+
con.execute(
348+
"""
345349
select pg_catalog.pg_create_physical_replication_slot(%s)
346-
""", slot)
350+
""", slot)
347351

348352
line += "primary_slot_name={}\n".format(slot)
349353

350-
self.append_conf(RECOVERY_CONF_FILE, line)
354+
self.append_conf(filename=RECOVERY_CONF_FILE, line=line)
351355

352356
def _maybe_start_logger(self):
353357
if testgres_config.use_python_logging:
@@ -475,65 +479,80 @@ def get_auth_method(t):
475479

476480
# overwrite config file
477481
with io.open(postgres_conf, "w") as conf:
478-
# remove old lines
479482
conf.truncate()
480483

481-
if not fsync:
482-
conf.write(u"fsync = off\n")
484+
self.append_conf(fsync=fsync,
485+
max_worker_processes=MAX_WORKER_PROCESSES,
486+
log_statement=log_statement,
487+
listen_addresses=self.host,
488+
port=self.port) # yapf:disable
483489

484-
conf.write(u"log_statement = {}\n"
485-
u"listen_addresses = '{}'\n"
486-
u"port = {}\n".format(log_statement,
487-
self.host,
488-
self.port)) # yapf: disable
490+
# common replication settings
491+
if allow_streaming or allow_logical:
492+
self.append_conf(max_replication_slots=MAX_REPLICATION_SLOTS,
493+
max_wal_senders=MAX_WAL_SENDERS) # yapf: disable
489494

490-
# replication-related settings
491-
if allow_streaming:
495+
# binary replication
496+
if allow_streaming:
497+
# select a proper wal_level for PostgreSQL
498+
wal_level = 'replica' if self._pg_version >= '9.6' else 'hot_standby'
492499

493-
# select a proper wal_level for PostgreSQL
494-
if self._pg_version >= '9.6':
495-
wal_level = "replica"
496-
else:
497-
wal_level = "hot_standby"
498-
499-
conf.write(u"hot_standby = on\n"
500-
u"max_wal_senders = {}\n"
501-
u"max_replication_slots = {}\n"
502-
u"wal_keep_segments = {}\n"
503-
u"wal_level = {}\n".format(MAX_WAL_SENDERS,
504-
MAX_REPLICATION_SLOTS,
505-
WAL_KEEP_SEGMENTS,
506-
wal_level)) # yapf: disable
507-
508-
if allow_logical:
509-
if self._pg_version < '10':
510-
raise InitNodeException(
511-
"Logical replication is only available for Postgres 10 "
512-
"and newer")
513-
conf.write(u"wal_level = logical\n")
514-
515-
# disable UNIX sockets if asked to
516-
if not unix_sockets:
517-
conf.write(u"unix_socket_directories = ''\n")
500+
self.append_conf(hot_standby=True,
501+
wal_keep_segments=WAL_KEEP_SEGMENTS,
502+
wal_level=wal_level) # yapf: disable
503+
504+
# logical replication
505+
if allow_logical:
506+
if self._pg_version < '10':
507+
raise InitNodeException("Logical replication is only "
508+
"available on PostgreSQL 10 and newer")
509+
510+
self.append_conf(
511+
max_logical_replication_workers=MAX_LOGICAL_REPLICATION_WORKERS,
512+
wal_level='logical')
513+
514+
# disable UNIX sockets if asked to
515+
if not unix_sockets:
516+
self.append_conf(unix_socket_directories='')
518517

519518
return self
520519

521520
@method_decorator(positional_args_hack(['filename', 'line']))
522-
def append_conf(self, line, filename=PG_CONF_FILE):
521+
def append_conf(self, line='', filename=PG_CONF_FILE, **kwargs):
523522
"""
524523
Append line to a config file.
525524
526525
Args:
527526
line: string to be appended to config.
528527
filename: config file (postgresql.conf by default).
528+
**kwargs: named config options.
529529
530530
Returns:
531531
This instance of :class:`.PostgresNode`.
532+
533+
Examples:
534+
append_conf(fsync=False)
535+
append_conf('log_connections = yes')
536+
append_conf(random_page_cost=1.5, fsync=True, ...)
537+
append_conf('postgresql.conf', 'synchronous_commit = off')
532538
"""
533539

540+
lines = [line]
541+
542+
for option, value in iteritems(kwargs):
543+
if isinstance(value, bool):
544+
value = 'on' if value else 'off'
545+
elif not str(value).replace('.', '', 1).isdigit():
546+
value = "'{}'".format(value)
547+
548+
# format a new config line
549+
lines.append('{} = {}'.format(option, value))
550+
534551
config_name = os.path.join(self.data_dir, filename)
535552
with io.open(config_name, 'a') as conf:
536-
conf.write(u''.join([line, '\n']))
553+
for line in lines:
554+
conf.write(text_type(line))
555+
conf.write(text_type('\n'))
537556

538557
return self
539558

tests/test_simple.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def test_reload(self):
195195

196196
# change client_min_messages and save old value
197197
cmm_old = node.execute('show client_min_messages')
198-
node.append_conf('client_min_messages = DEBUG1')
198+
node.append_conf(client_min_messages='DEBUG1')
199199

200200
# reload config
201201
node.reload()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy