Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd800f48

Browse files
authored
Merge pull request#34 from funbringer/flexible_config
Initial implementation of config stack
2 parents740b8d8 +3378f28 commitd800f48

File tree

8 files changed

+252
-109
lines changed

8 files changed

+252
-109
lines changed

‎testgres/__init__.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
from .apiimportget_new_node
22
from .backupimportNodeBackup
3-
from .configimportTestgresConfig,configure_testgres
3+
4+
from .configimport \
5+
TestgresConfig, \
6+
configure_testgres, \
7+
scoped_config, \
8+
push_config, \
9+
pop_config
410

511
from .connectionimport \
612
IsolationLevel, \

‎testgres/cache.py‎

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
# coding: utf-8
22

3-
importatexit
43
importos
54
importshutil
6-
importtempfile
75

86
fromsiximportraise_from
97

10-
from .configimportTestgresConfig
8+
from .configimporttestgres_config
119

1210
from .exceptionsimport \
1311
InitNodeException, \
@@ -18,44 +16,31 @@
1816
execute_utility
1917

2018

21-
defcached_initdb(data_dir,initdb_logfile,initdb_params=[]):
19+
defcached_initdb(data_dir,logfile=None,params=None):
2220
"""
2321
Perform initdb or use cached node files.
2422
"""
2523

26-
defcall_initdb(initdb_dir):
24+
defcall_initdb(initdb_dir,log=None):
2725
try:
2826
_params= [get_bin_path("initdb"),"-D",initdb_dir,"-N"]
29-
execute_utility(_params+initdb_params,initdb_logfile)
27+
execute_utility(_params+(paramsor []),log)
3028
exceptExecUtilExceptionase:
3129
raise_from(InitNodeException("Failed to run initdb"),e)
3230

33-
defrm_cached_data_dir(cached_data_dir):
34-
shutil.rmtree(cached_data_dir,ignore_errors=True)
35-
36-
# Call initdb if we have custom params or shouldn't cache it
37-
ifinitdb_paramsornotTestgresConfig.cache_initdb:
38-
call_initdb(data_dir)
31+
ifparamsornottestgres_config.cache_initdb:
32+
call_initdb(data_dir,logfile)
3933
else:
40-
# Set default temp dir for cached initdb
41-
ifTestgresConfig.cached_initdb_dirisNone:
42-
43-
# Create default temp dir
44-
TestgresConfig.cached_initdb_dir=tempfile.mkdtemp()
45-
46-
# Schedule cleanup
47-
atexit.register(rm_cached_data_dir,
48-
TestgresConfig.cached_initdb_dir)
49-
5034
# Fetch cached initdb dir
51-
cached_data_dir=TestgresConfig.cached_initdb_dir
35+
cached_data_dir=testgres_config.cached_initdb_dir
5236

5337
# Initialize cached initdb
54-
ifnotos.listdir(cached_data_dir):
38+
ifnotos.path.exists(cached_data_dir)or \
39+
notos.listdir(cached_data_dir):
5540
call_initdb(cached_data_dir)
5641

5742
try:
5843
# Copy cached initdb to current data dir
5944
shutil.copytree(cached_data_dir,data_dir)
6045
exceptExceptionase:
61-
raise_from(InitNodeException("Failed tocopy files"),e)
46+
raise_from(InitNodeException("Failed tospawn a node"),e)

‎testgres/config.py‎

Lines changed: 138 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
# coding: utf-8
22

3+
importatexit
4+
importcopy
5+
importshutil
6+
importtempfile
37

4-
classTestgresConfig:
8+
fromcontextlibimportcontextmanager
9+
10+
11+
classGlobalConfig(object):
512
"""
613
Global config (override default settings).
714
815
Attributes:
9-
cache_initdb: shall we use cached initdb instance?
10-
cached_initdb_dir: shall we create a temp dir for cached initdb?
16+
cache_initdb:shall we use cached initdb instance?
17+
cached_initdb_dir:shall we create a temp dir for cached initdb?
1118
12-
cache_pg_config: shall we cache pg_config results?
19+
cache_pg_config:shall we cache pg_config results?
1320
14-
use_python_logging: use python logging configuration for all nodes.
15-
error_log_lines: N of log lines to beincluded into exception (0=inf).
21+
use_python_logging:use python logging configuration for all nodes.
22+
error_log_lines:N of log lines to beshown in exception (0=inf).
1623
17-
node_cleanup_full: shall we remove EVERYTHING (including logs)?
24+
node_cleanup_full:shall we remove EVERYTHING (including logs)?
1825
node_cleanup_on_good_exit: remove base_dir on nominal __exit__().
1926
node_cleanup_on_bad_exit: remove base_dir on __exit__() via exception.
27+
28+
NOTE: attributes must not be callable or begin with __.
2029
"""
2130

2231
cache_initdb=True
23-
cached_initdb_dir=None
32+
_cached_initdb_dir=None
2433

2534
cache_pg_config=True
2635

@@ -31,12 +40,129 @@ class TestgresConfig:
3140
node_cleanup_on_good_exit=True
3241
node_cleanup_on_bad_exit=False
3342

43+
@property
44+
defcached_initdb_dir(self):
45+
returnself._cached_initdb_dir
46+
47+
@cached_initdb_dir.setter
48+
defcached_initdb_dir(self,value):
49+
self._cached_initdb_dir=value
50+
51+
ifvalue:
52+
cached_initdb_dirs.add(value)
53+
54+
def__init__(self,**options):
55+
self.update(options)
56+
57+
def__setitem__(self,key,value):
58+
setattr(self,key,value)
59+
60+
def__getitem__(self,key):
61+
returngetattr(self,key)
62+
63+
def__setattr__(self,name,value):
64+
ifnamenotinself.keys():
65+
raiseTypeError('Unknown option {}'.format(name))
66+
67+
super(GlobalConfig,self).__setattr__(name,value)
68+
69+
defkeys(self):
70+
keys= []
71+
72+
forkeyindir(GlobalConfig):
73+
ifnotkey.startswith('__')andnotcallable(self[key]):
74+
keys.append(key)
75+
76+
returnkeys
77+
78+
defitems(self):
79+
return ((key,self[key])forkeyinself.keys())
80+
81+
defupdate(self,config):
82+
forkey,valueinconfig.items():
83+
self[key]=value
84+
85+
returnself
86+
87+
defcopy(self):
88+
returncopy.copy(self)
89+
90+
91+
# cached dirs to be removed
92+
cached_initdb_dirs=set()
93+
94+
# default config object
95+
testgres_config=GlobalConfig()
96+
97+
# NOTE: for compatibility
98+
TestgresConfig=testgres_config
99+
100+
# stack of GlobalConfigs
101+
config_stack= []
102+
103+
104+
defrm_cached_initdb_dirs():
105+
fordincached_initdb_dirs:
106+
shutil.rmtree(d,ignore_errors=True)
107+
108+
109+
defpush_config(**options):
110+
"""
111+
Permanently set custom GlobalConfig options
112+
and put previous settings on top of stack.
113+
"""
114+
115+
# push current config to stack
116+
config_stack.append(testgres_config.copy())
117+
118+
returntestgres_config.update(options)
119+
120+
121+
defpop_config():
122+
"""
123+
Set previous GlobalConfig options from stack.
124+
"""
125+
126+
iflen(config_stack)==0:
127+
raiseIndexError('Reached initial config')
128+
129+
# restore popped config
130+
returntestgres_config.update(config_stack.pop())
131+
132+
133+
@contextmanager
134+
defscoped_config(**options):
135+
"""
136+
Temporarily set custom GlobalConfig options for this context.
137+
138+
Example:
139+
>>> with scoped_config(cache_initdb=False):
140+
... with get_new_node().init().start() as node:
141+
... print(node.execute('select 1'))
142+
"""
143+
144+
try:
145+
# set a new config with options
146+
config=push_config(**options)
147+
148+
# return it
149+
yieldconfig
150+
finally:
151+
# restore previous config
152+
pop_config()
153+
34154

35155
defconfigure_testgres(**options):
36156
"""
37-
Configure testgres.
38-
Look atTestgresConfig tocheck what can bechanged.
157+
Adjust current global options.
158+
Look atGlobalConfig tolearn what can beset.
39159
"""
40160

41-
forkey,optioninoptions.items():
42-
setattr(TestgresConfig,key,option)
161+
testgres_config.update(options)
162+
163+
164+
# NOTE: to be executed at exit()
165+
atexit.register(rm_cached_initdb_dirs)
166+
167+
# NOTE: assign initial cached dir for initdb
168+
testgres_config.cached_initdb_dir=tempfile.mkdtemp()

‎testgres/consts.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
DATA_DIR="data"
55
LOGS_DIR="logs"
66

7+
# names for config files
78
RECOVERY_CONF_FILE="recovery.conf"
89
PG_AUTO_CONF_FILE="postgresql.auto.conf"
910
PG_CONF_FILE="postgresql.conf"

‎testgres/exceptions.py‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ class TestgresException(Exception):
99

1010
@six.python_2_unicode_compatible
1111
classExecUtilException(TestgresException):
12-
def__init__(self,
13-
message=None,
14-
command=None,
15-
exit_code=0,
16-
out=None):
12+
def__init__(self,message=None,command=None,exit_code=0,out=None):
1713
super(ExecUtilException,self).__init__(message)
1814

1915
self.message=message

‎testgres/node.py‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from .cacheimportcached_initdb
1515

16-
from .configimportTestgresConfig
16+
from .configimporttestgres_config
1717

1818
from .connectionimport \
1919
NodeConnection, \
@@ -88,8 +88,8 @@ def __init__(self, name=None, port=None, base_dir=None):
8888
self.base_dir=base_dir
8989

9090
# defaults for __exit__()
91-
self.cleanup_on_good_exit=TestgresConfig.node_cleanup_on_good_exit
92-
self.cleanup_on_bad_exit=TestgresConfig.node_cleanup_on_bad_exit
91+
self.cleanup_on_good_exit=testgres_config.node_cleanup_on_good_exit
92+
self.cleanup_on_bad_exit=testgres_config.node_cleanup_on_bad_exit
9393
self.shutdown_max_attempts=3
9494

9595
# private
@@ -150,7 +150,7 @@ def _try_shutdown(self, max_attempts):
150150
self.stop()
151151
break# OK
152152
exceptExecUtilException:
153-
pass# one more time
153+
pass# one more time
154154
exceptException:
155155
# TODO: probably kill stray instance
156156
eprint('cannot stop node {}'.format(self.name))
@@ -204,7 +204,7 @@ def _prepare_dirs(self):
204204
os.makedirs(self.logs_dir)
205205

206206
def_maybe_start_logger(self):
207-
ifTestgresConfig.use_python_logging:
207+
iftestgres_config.use_python_logging:
208208
# spawn new logger if it doesn't exist or is stopped
209209
ifnotself._loggerornotself._logger.is_alive():
210210
self._logger=TestgresLogger(self.name,self.pg_log_name)
@@ -223,7 +223,7 @@ def _collect_special_files(self):
223223
(os.path.join(self.data_dir,PG_AUTO_CONF_FILE),0),
224224
(os.path.join(self.data_dir,RECOVERY_CONF_FILE),0),
225225
(os.path.join(self.data_dir,HBA_CONF_FILE),0),
226-
(self.pg_log_name,TestgresConfig.error_log_lines)
226+
(self.pg_log_name,testgres_config.error_log_lines)
227227
]
228228

229229
forf,num_linesinfiles:
@@ -248,7 +248,7 @@ def init(self,
248248
fsync=False,
249249
unix_sockets=True,
250250
allow_streaming=True,
251-
initdb_params=[]):
251+
initdb_params=None):
252252
"""
253253
Perform initdb for this node.
254254
@@ -266,8 +266,9 @@ def init(self,
266266
self._prepare_dirs()
267267

268268
# initialize this PostgreSQL node
269-
initdb_log=os.path.join(self.logs_dir,"initdb.log")
270-
cached_initdb(self.data_dir,initdb_log,initdb_params)
269+
cached_initdb(data_dir=self.data_dir,
270+
logfile=self.utils_log_name,
271+
params=initdb_params)
271272

272273
# initialize default config files
273274
self.default_conf(fsync=fsync,
@@ -603,7 +604,7 @@ def cleanup(self, max_attempts=3):
603604
self._try_shutdown(max_attempts)
604605

605606
# choose directory to be removed
606-
ifTestgresConfig.node_cleanup_full:
607+
iftestgres_config.node_cleanup_full:
607608
rm_dir=self.base_dir# everything
608609
else:
609610
rm_dir=self.data_dir# just data, save logs

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp