8000 [#266] OsOperations::build_path is added (#273) · postgrespro/testgres@9da8981 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9da8981

Browse files
[#266] OsOperations::build_path is added (#273)
This thing must be used instead os.path.join(...). LocalOperations uses os.path.join RemoteOperations uses posixpath.join We updated: - utils.get_bin_path2 - utils.get_pg_config2 - utils.get_pg_version2 (note: new restrictions/asserts are added) - RemoteOperations::find_executable - RemoteOperations::copytree - PostgresNode::logs_dir - PostgresNode::data_dir - PostgresNode::utils_log_file - PostgresNode::pg_log_file - PostgresNode::_create_recovery_conf - PostgresNode::_collect_special_files - PostgresNode::default_conf - PostgresNode::append_conf - PostgresNode::set_auto_conf - PostgresNode::upgrade_from - PostgresNode::_get_bin_path - NodeApp::__init__ - NodeApp::make_simple - cache.cached_initdb - cache.call_initdb - NodeBackup.log_file - NodeBackup.__init__ - NodeBackup._prepare_dir
1 parent 20d390a commit 9da8981

File tree

7 files changed

+109
-34
lines changed

7 files changed

+109
-34
lines changed

testgres/backup.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# coding: utf-8
22

3-
import os
4-
53
from six import raise_from
64

75
from .enums import XLogMethod
@@ -29,7 +27,9 @@ class NodeBackup(object):
2927
"""
3028
@property
3129
def log_file(self):
32-
return os.path.join(self.base_dir, BACKUP_LOG_FILE)
30+
assert self.os_ops is not None
31+
assert isinstance(self.os_ops, OsOperations)
32+
return self.os_ops.build_path(self.base_dir, BACKUP_LOG_FILE)
3333

3434
def __init__(self,
3535
node,
@@ -75,7 +75,7 @@ def __init__(self,
7575
# private
7676
self._available = True
7777

78-
data_dir = os.path.join(self.base_dir, DATA_DIR)
78+
data_dir = self.os_ops.build_path(self.base_dir, DATA_DIR)
7979

8080
_params = [
8181
get_bin_path2(self.os_ops, "pg_basebackup"),
@@ -112,10 +112,13 @@ def _prepare_dir(self, destroy):
112112
available = not destroy
113113

114114
if available:
115+
assert self.os_ops is not None
116+
assert isinstance(self.os_ops, OsOperations)
117+
115118
dest_base_dir = self.os_ops.mkdtemp(prefix=TMP_NODE)
116119

117-
data1 = os.path.join(self.base_dir, DATA_DIR)
118-
data2 = os.path.join(dest_base_dir, DATA_DIR)
120+
data1 = self.os_ops.build_path(self.base_dir, DATA_DIR)
121+
data2 = self.os_ops.build_path(dest_base_dir, DATA_DIR)
119122

120123
try:
121124
# Copy backup to new data dir

testgres/cache.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# coding: utf-8
22

3-
import os
4-
53
from six import raise_from
64

75
from .config import testgres_config
@@ -39,7 +37,7 @@ def make_utility_path(name):
3937
assert type(name) == str # noqa: E721
4038

4139
if bin_path:
42-
return os.path.join(bin_path, name)
40+
return os_ops.build_path(bin_path, name)
4341

4442
return get_bin_path2(os_ops, name)
4543

@@ -72,7 +70,7 @@ def call_initdb(initdb_dir, log=logfile):
7270
# XXX: write new unique system id to control file
7371
# Some users might rely upon unique system ids, but
7472
# our initdb caching mechanism breaks this contract.
75-
pg_control = os.path.join(data_dir, XLOG_CONTROL_FILE)
73+
pg_control = os_ops.build_path(data_dir, XLOG_CONTROL_FILE)
7674
system_id = generate_system_id()
7775
cur_pg_control = os_ops.read(pg_control, binary=True)
7876
new_pg_control = system_id + cur_pg_control[len(system_id):]

testgres/node.py

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,11 @@ def bin_dir(self):
573573

574574
@property
575575
def logs_dir(self):
576-
path = os.path.join(self.base_dir, LOGS_DIR)
576+
assert self._os_ops is not None
577+
assert isinstance(self._os_ops, OsOperations)
578+
579+
path = self._os_ops.build_path(self.base_dir, LOGS_DIR)
580+
assert type(path) == str # noqa: E721
577581

578582
# NOTE: it's safe to create a new dir
579583
if not self.os_ops.path_exists(path):
@@ -583,16 +587,31 @@ def logs_dir(self):
583587

584588
@property
585589
def data_dir(self):
590+
assert self._os_ops is not None
591+
assert isinstance(self._os_ops, OsOperations)
592+
586593
# NOTE: we can't run initdb without user's args
587-
return os.path.join(self.base_dir, DATA_DIR)
594+
path = self._os_ops.build_path(self.base_dir, DATA_DIR)
595+
assert type(path) == str # noqa: E721
596+
return path
588597

589598
@property
590599
def utils_log_file(self):
591-
return os.path.join(self.logs_dir, UTILS_LOG_FILE)
600+
assert self._os_ops is not None
601+
assert isinstance(self._os_ops, OsOperations)
602+
603+
path = self._os_ops.build_path(self.logs_dir, UTILS_LOG_FILE)
604+
assert type(path) == str # noqa: E721
605+
return path
592606

593607
@property
594608
def pg_log_file(self):
595-
return os.path.join(self.logs_dir, PG_LOG_FILE)
609+
assert self._os_ops is not None
610+
assert isinstance(self._os_ops, OsOperations)
611+
612+
path = self._os_ops.build_path(self.logs_dir, PG_LOG_FILE)
613+
assert type(path) == str # noqa: E721
614+
return path
596615

597616
@property
598617
def version(self):
@@ -719,7 +738,11 @@ def _create_recovery_conf(self, username, slot=None):
719738
).format(options_string(**conninfo)) # yapf: disable
720739
# Since 12 recovery.conf had disappeared
721740
if self.version >= PgVer('12'):
722-
signal_name = os.path.join(self.data_dir, "standby.signal")
741+
assert self._os_ops is not None
742+
assert isinstance(self._os_ops, OsOperations)
743+
744+
signal_name = self._os_ops.build_path(self.data_dir, "standby.signal")
745+
assert type(signal_name) == str # noqa: E721
723746
self.os_ops.touch(signal_name)
724747
else:
725748
line += "standby_mode=on\n"
@@ -768,11 +791,14 @@ def _collect_special_files(self):
768791
result = []
769792

770793
# list of important files + last N lines
794+
assert self._os_ops is not None
795+
assert isinstance(self._os_ops, OsOperations)
796+
771797
files = [
772-
(os.path.join(self.data_dir, PG_CONF_FILE), 0),
773-
(os.path.join(self.data_dir, PG_AUTO_CONF_FILE), 0),
774-
(os.path.join(self.data_dir, RECOVERY_CONF_FILE), 0),
775-
(os.path.join(self.data_dir, HBA_CONF_FILE), 0),
798+
(self._os_ops.build_path(self.data_dir, PG_CONF_FILE), 0),
799+
(self._os_ops.build_path(self.data_dir, PG_AUTO_CONF_FILE), 0),
800+
(self._os_ops.build_path(self.data_dir, RECOVERY_CONF_FILE), 0),
801+
(self._os_ops.build_path(self.data_dir, HBA_CONF_FILE), 0),
776802
(self.pg_log_file, testgres_config.error_log_lines)
777803
] # yapf: disable
778804

@@ -840,8 +866,11 @@ def default_conf(self,
840866
This instance of :class:`.PostgresNode`.
841867
"""
842868

843-
postgres_conf = os.path.join(self.data_dir, PG_CONF_FILE)
844-
hba_conf = os.path.join(self.data_dir, HBA_CONF_FILE)
869+
assert self._os_ops is not None
870+
assert isinstance(self._os_ops, OsOperations)
871+
872+
postgres_conf = self._os_ops.build_path(self.data_dir, PG_CONF_FILE)
873+
hba_conf = self._os_ops.build_path(self.data_dir, HBA_CONF_FILE)
845874

846875
# filter lines in hba file
847876
# get rid of comments and blank lines
@@ -956,7 +985,7 @@ def append_conf(self, line='', filename=PG_CONF_FILE, **kwargs):
956985
# format a new config line
957986
lines.append('{} = {}'.format(option, value))
958987

959-
config_name = os.path.join(self.data_dir, filename)
988+
config_name = self._os_ops.build_path(self.data_dir, filename)
960989
conf_text = ''
961990
for line in lines:
962991
conf_text += text_type(line) + '\n'
@@ -2040,8 +2069,11 @@ def set_auto_conf(self, options, config='postgresql.auto.conf', rm_options={}):
20402069
rm_options (set, optional): A set containing the names of the options to remove.
20412070
Defaults to an empty set.
20422071
"""
2072+
assert self._os_ops is not None
2073+
assert isinstance(self._os_ops, OsOperations)
2074+
20432075
# parse postgresql.auto.conf
2044-
path = os.path.join(self.data_dir, config)
2076+
path = self.os_ops.build_path(self.data_dir, config)
20452077

20462078
lines = self.os_ops.readlines(path)
20472079
current_options = {}
@@ -2127,8 +2159,11 @@ def upgrade_from(self, old_node, options=None, expect_error=False):
21272159
return self.os_ops.exec_command(upgrade_command, expect_error=expect_error)
21282160

21292161
def _get_bin_path(self, filename):
2162+
assert self._os_ops is not None
2163+
assert isinstance(self._os_ops, OsOperations)
2164+
21302165
if self.bin_dir:
2131-
bin_path = os.path.join(self.bin_dir, filename)
2166+
bin_path = self._os_ops.build_path(self.bin_dir, filename)
21322167
else:
21332168
bin_path = get_bin_path2(self.os_ops, filename)
21342169
return bin_path
@@ -2333,7 +2368,7 @@ def __init__(self, test_path=None, nodes_to_cleanup=None, os_ops=None):
23332368
if os.path.isabs(test_path):
23342369
self.test_path = test_path
23352370
else:
2336-
self.test_path = os.path.join(os_ops.cwd(), test_path)
2371+
self.test_path = os_ops.build_path(os_ops.cwd(), test_path)
23372372
else:
23382373
self.test_path = os_ops.cwd()
23392374
self.nodes_to_cleanup = nodes_to_cleanup if nodes_to_cleanup else []
@@ -2344,7 +2379,7 @@ def make_empty(
23442379
base_dir=None,
23452380
port=None,
23462381
bin_dir=None):
2347-
real_base_dir = os.path.join(self.test_path, base_dir)
2382+
real_base_dir = self.os_ops.build_path(self.test_path, base_dir)
23482383
self.os_ops.rmdirs(real_base_dir, ignore_errors=True)
23492384
self.os_ops.makedirs(real_base_dir)
23502385

@@ -2373,7 +2408,7 @@ def make_simple(
23732408
initdb_params=initdb_params, allow_streaming=set_replication)
23742409

23752410
# set major version
2376-
pg_version_file = self.os_ops.read(os.path.join(node.data_dir, 'PG_VERSION'))
2411+
pg_version_file = self.os_ops.read(self.os_ops.build_path(node.data_dir, 'PG_VERSION'))
23772412
node.major_version_str = str(pg_version_file.rstrip())
23782413
node.major_version = float(node.major_version_str)
23792414

testgres/operations/local_ops.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,13 @@ def exec_command(self, cmd, wait_exit=False, verbose=False, expect_error=False,
219219

220220
return output
221221

222+
def build_path(self, a: str, *parts: str) -> str:
223+
assert a is not None
224+
assert parts is not None
225+
assert type(a) == str # noqa: E721
226+
assert type(parts) == tuple # noqa: E721
227+
return os.path.join(a, *parts)
228+
222229
# Environment setup
223230
def environ(self, var_name):
224231
return os.environ.get(var_name)

testgres/operations/os_ops.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ def __init__(self, username=None):
2525
def exec_command(self, cmd, **kwargs):
2626
raise NotImplementedError()
2727

28+
def build_path(self, a: str, *parts: str) -> str:
29+
assert a is not None
30+
assert parts is not None
31+
assert type(a) == str # noqa: E721
32+
assert type(parts) == tuple # noqa: E721
33+
raise NotImplementedError()
34+
2835
# Environment setup
2936
def environ(self, var_name):
3037
raise NotImplementedError()

testgres/operations/remote_ops.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import getpass
22
import os
3+
import posixpath
34
import platform
45
import subprocess
56
import tempfile
@@ -138,6 +139,13 @@ def exec_command(self, cmd, wait_exit=False, verbose=False, expect_error=False,
138139

139140
return output
140141

142+
def build_path(self, a: str, *parts: str) -> str:
143+ assert a is not None
144+
assert parts is not None
145+
assert type(a) == str # noqa: E721
146+
assert type(parts) == tuple # noqa: E721
147+
return __class__._build_path(a, *parts)
148+
141149
# Environment setup
142150
def environ(self, var_name: str) -> str:
143151
"""
@@ -159,7 +167,7 @@ def find_executable(self, executable):
159167

160168
search_paths = search_paths.split(self.pathsep)
161169
for path in search_paths:
162-
remote_file = os.path.join(path, executable)
170+
remote_file = __class__._build_path(path, executable)
163171
if self.isfile(remote_file):
164172
return remote_file
165173

@@ -383,7 +391,7 @@ def mkstemp(self, prefix=None):
383391

384392
def copytree(self, src, dst):
385393
if not os.path.isabs(dst):
386-
dst = os.path.join('~', dst)
394+
dst = __class__._build_path('~', dst)
387395
if self.isdir(dst):
388396
raise FileExistsError("Directory {} already exists.".format(dst))
389397
return self.exec_command("cp -r {} {}".format(src, dst))
@@ -772,6 +780,14 @@ def _quote_envvar(value: str) -> str:
772780
result += "\""
773781
return result
774782

783+
@staticmethod
784+
def _build_path(a: str, *parts: str) -> str:
785+
assert a is not None
786+
assert parts is not None
787+
assert type(a) == str # noqa: E721
788+
assert type(parts) == tuple # noqa: E721
789+
return posixpath.join(a, *parts)
790+
775791

776792
def normalize_error(error):
777793
if isinstance(error, bytes):

testgres/utils.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,17 @@ def get_bin_path2(os_ops: OsOperations, filename):
141141

142142
if pg_config:
143143
bindir = get_pg_config(pg_config, os_ops)["BINDIR"]
144-
return os.path.join(bindir, filename)
144+
return os_ops.build_path(bindir, filename)
145145

146146
# try PG_BIN
147147
pg_bin = os_ops.environ("PG_BIN")
148148
if pg_bin:
149-
return os.path.join(pg_bin, filename)
149+
return os_ops.build_path(pg_bin, filename)
150150

151151
pg_config_path = os_ops.find_executable('pg_config')
152152
if pg_config_path:
153153
bindir = get_pg_config(pg_config_path)["BINDIR"]
154-
return os.path.join(bindir, filename)
154+
return os_ops.build_path(bindir, filename)
155155

156156
return filename
157157

@@ -213,7 +213,7 @@ def cache_pg_config_data(cmd):
213213
# try PG_BIN
214214
pg_bin = os.environ.get("PG_BIN")
215215
if pg_bin:
216-
cmd = os.path.join(pg_bin, "pg_config")
216+
cmd = os_ops.build_path(pg_bin, "pg_config")
217217
return cache_pg_config_data(cmd)
218218

219219
# try plain name
@@ -227,8 +227,17 @@ def get_pg_version2(os_ops: OsOperations, bin_dir=None):
227227
assert os_ops is not None
228228
assert isinstance(os_ops, OsOperations)
229229

230+
C_POSTGRES_BINARY = "postgres"
231+
230232
# Get raw version (e.g., postgres (PostgreSQL) 9.5.7)
231-
postgres_path = os.path.join(bin_dir, 'postgres') if bin_dir else get_bin_path2(os_ops, 'postgres')
233+
if bin_dir is None:
234+
postgres_path = get_bin_path2(os_ops, C_POSTGRES_BINARY)
235+
else:
236+
5F8F # [2025-06-25] OK ?
237+
assert type(bin_dir) == str # noqa: E721
238+
assert bin_dir != ""
239+
postgres_path = os_ops.build_path(bin_dir, 'postgres')
240+
232241
cmd = [postgres_path, '--version']
233242
raw_ver = os_ops.exec_command(cmd, encoding='utf-8')
234243

0 commit comments

Comments
 (0)
0