From c75424d48458cb81a5e3ed832dc5197f843dd166 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 5 Mar 2018 15:56:45 +0300 Subject: [PATCH 1/2] replace function _prepare_dirs() with smart properties --- testgres/api.py | 18 +++------ testgres/consts.py | 1 + testgres/node.py | 96 +++++++++++++++++++++++++--------------------- 3 files changed, 58 insertions(+), 57 deletions(-) diff --git a/testgres/api.py b/testgres/api.py index fd4f1bf2..a697c1fc 100644 --- a/testgres/api.py +++ b/testgres/api.py @@ -33,19 +33,11 @@ Copyright (c) 2016, Postgres Professional """ -from .node import PostgresNode - +from functools import wraps -def get_new_node(name=None, base_dir=None): - """ - Create a new node (select port automatically). - - Args: - name: node's application name. - base_dir: path to node's data directory. +from .node import PostgresNode - Returns: - An instance of PostgresNode. - """ - return PostgresNode(name=name, base_dir=base_dir) +@wraps(PostgresNode.__init__) +def get_new_node(**kwargs): + return PostgresNode(**kwargs) diff --git a/testgres/consts.py b/testgres/consts.py index 1e719703..15400311 100644 --- a/testgres/consts.py +++ b/testgres/consts.py @@ -17,6 +17,7 @@ RECOVERY_CONF_FILE = "recovery.conf" PG_AUTO_CONF_FILE = "postgresql.auto.conf" PG_CONF_FILE = "postgresql.conf" +PG_PID_FILE = 'postmaster.pid' HBA_CONF_FILE = "pg_hba.conf" # names for log files diff --git a/testgres/node.py b/testgres/node.py index b4d6c8a9..5022f89f 100644 --- a/testgres/node.py +++ b/testgres/node.py @@ -31,7 +31,8 @@ HBA_CONF_FILE, \ RECOVERY_CONF_FILE, \ PG_LOG_FILE, \ - UTILS_LOG_FILE + UTILS_LOG_FILE, \ + PG_PID_FILE from .decorators import \ method_decorator, \ @@ -66,7 +67,7 @@ class PostgresNode(object): def __init__(self, name=None, port=None, base_dir=None): """ - Create a new node manually. + Create a new node. Args: name: node's application name. @@ -74,24 +75,25 @@ def __init__(self, name=None, port=None, base_dir=None): base_dir: path to node's data directory. """ + # private + self._should_free_port = port is None + self._base_dir = base_dir + self._logger = None + self._master = None + # basic self.host = '127.0.0.1' self.name = name or generate_app_name() self.port = port or reserve_port() - self.base_dir = base_dir # defaults for __exit__() self.cleanup_on_good_exit = testgres_config.node_cleanup_on_good_exit self.cleanup_on_bad_exit = testgres_config.node_cleanup_on_bad_exit self.shutdown_max_attempts = 3 - # private - self._should_free_port = port is None - self._logger = None - self._master = None - - # create directories if needed - self._prepare_dirs() + # NOTE: for compatibility + self.utils_log_name = self.utils_log_file + self.pg_log_name = self.pg_log_file def __enter__(self): return self @@ -121,19 +123,37 @@ def master(self): return self._master @property - def data_dir(self): - return os.path.join(self.base_dir, DATA_DIR) + def base_dir(self): + if not self._base_dir: + self._base_dir = mkdtemp(prefix=TMP_NODE) + + # NOTE :it's safe to create a new dir + if not os.path.exists(self._base_dir): + os.makedirs(self._base_dir) + + return self._base_dir @property def logs_dir(self): - return os.path.join(self.base_dir, LOGS_DIR) + path = os.path.join(self.base_dir, LOGS_DIR) + + # NOTE: it's safe to create a new dir + if not os.path.exists(path): + os.makedirs(path) + + return path + + @property + def data_dir(self): + # NOTE: we can't run initdb without user's args + return os.path.join(self.base_dir, DATA_DIR) @property - def utils_log_name(self): + def utils_log_file(self): return os.path.join(self.logs_dir, UTILS_LOG_FILE) @property - def pg_log_name(self): + def pg_log_file(self): return os.path.join(self.logs_dir, PG_LOG_FILE) def _try_shutdown(self, max_attempts): @@ -189,21 +209,11 @@ def _create_recovery_conf(self, username): self.append_conf(RECOVERY_CONF_FILE, line) - def _prepare_dirs(self): - if not self.base_dir: - self.base_dir = mkdtemp(prefix=TMP_NODE) - - if not os.path.exists(self.base_dir): - os.makedirs(self.base_dir) - - if not os.path.exists(self.logs_dir): - os.makedirs(self.logs_dir) - def _maybe_start_logger(self): if testgres_config.use_python_logging: # spawn new logger if it doesn't exist or is stopped if not self._logger or not self._logger.is_alive(): - self._logger = TestgresLogger(self.name, self.pg_log_name) + self._logger = TestgresLogger(self.name, self.pg_log_file) self._logger.start() def _maybe_stop_logger(self): @@ -219,7 +229,7 @@ def _collect_special_files(self): (os.path.join(self.data_dir, PG_AUTO_CONF_FILE), 0), (os.path.join(self.data_dir, RECOVERY_CONF_FILE), 0), (os.path.join(self.data_dir, HBA_CONF_FILE), 0), - (self.pg_log_name, testgres_config.error_log_lines) + (self.pg_log_file, testgres_config.error_log_lines) ] for f, num_lines in files: @@ -254,12 +264,9 @@ def init(self, initdb_params=None, **kwargs): This instance of PostgresNode. """ - # create directories if needed - self._prepare_dirs() - # initialize this PostgreSQL node cached_initdb(data_dir=self.data_dir, - logfile=self.utils_log_name, + logfile=self.utils_log_file, params=initdb_params) # initialize default config files @@ -398,7 +405,7 @@ def status(self): "-D", self.data_dir, "status" ] - execute_utility(_params, self.utils_log_name) + execute_utility(_params, self.utils_log_file) return NodeStatus.Running except ExecUtilException as e: @@ -416,7 +423,7 @@ def get_pid(self): """ if self.status(): - pid_file = os.path.join(self.data_dir, 'postmaster.pid') + pid_file = os.path.join(self.data_dir, PG_PID_FILE) with io.open(pid_file) as f: return int(f.readline()) @@ -433,7 +440,7 @@ def get_control_data(self): _params += ["-D"] if pg_version_ge('9.5') else [] _params += [self.data_dir] - data = execute_utility(_params, self.utils_log_name) + data = execute_utility(_params, self.utils_log_file) out_dict = {} @@ -458,13 +465,13 @@ def start(self, params=[]): _params = [ get_bin_path("pg_ctl"), "-D", self.data_dir, - "-l", self.pg_log_name, + "-l", self.pg_log_file, "-w", # wait "start" ] + params try: - execute_utility(_params, self.utils_log_name) + execute_utility(_params, self.utils_log_file) except ExecUtilException as e: msg = 'Cannot start node' files = self._collect_special_files() @@ -493,7 +500,7 @@ def stop(self, params=[]): "stop" ] + params - execute_utility(_params, self.utils_log_name) + execute_utility(_params, self.utils_log_file) self._maybe_stop_logger() @@ -514,13 +521,13 @@ def restart(self, params=[]): _params = [ get_bin_path("pg_ctl"), "-D", self.data_dir, - "-l", self.pg_log_name, + "-l", self.pg_log_file, "-w", # wait "restart" ] + params try: - execute_utility(_params, self.utils_log_name) + execute_utility(_params, self.utils_log_file) except ExecUtilException as e: msg = 'Cannot restart node' files = self._collect_special_files() @@ -549,7 +556,7 @@ def reload(self, params=[]): "reload" ] + params - execute_utility(_params, self.utils_log_name) + execute_utility(_params, self.utils_log_file) def pg_ctl(self, params): """ @@ -569,7 +576,7 @@ def pg_ctl(self, params): "-w" # wait ] + params - return execute_utility(_params, self.utils_log_name) + return execute_utility(_params, self.utils_log_file) def free_port(self): """ @@ -578,6 +585,7 @@ def free_port(self): """ if self._should_free_port: + self._should_free_port = False release_port(self.port) def cleanup(self, max_attempts=3): @@ -717,7 +725,7 @@ def tmpfile(): "-d", dbname ] - execute_utility(_params, self.utils_log_name) + execute_utility(_params, self.utils_log_file) return filename @@ -953,7 +961,7 @@ def pgbench_run(self, **kwargs): """ Run pgbench with some options. - This event is logged (see self.utils_log_name). + This event is logged (see self.utils_log_file). Args: dbname: database name to connect to. @@ -996,7 +1004,7 @@ def pgbench_run(self, # should be the last one _params.append(dbname) - return execute_utility(_params, self.utils_log_name) + return execute_utility(_params, self.utils_log_file) def connect(self, dbname=None, username=None, password=None): """ From ec94f99c71f8e12e68127b8d4ac71e23b8183edf Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 5 Mar 2018 16:10:19 +0300 Subject: [PATCH 2/2] fix typo --- testgres/node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testgres/node.py b/testgres/node.py index 5022f89f..02cc0f52 100644 --- a/testgres/node.py +++ b/testgres/node.py @@ -127,7 +127,7 @@ def base_dir(self): if not self._base_dir: self._base_dir = mkdtemp(prefix=TMP_NODE) - # NOTE :it's safe to create a new dir + # NOTE: it's safe to create a new dir if not os.path.exists(self._base_dir): os.makedirs(self._base_dir)