Skip to content

Commit 6b957f1

Browse files
author
Oleg Gurev
committed
[PBCKP-2775] Make auth_test.py multithreaded
1 parent ebf7144 commit 6b957f1

File tree

1 file changed

+62
-46
lines changed

1 file changed

+62
-46
lines changed

tests/auth_test.py

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -174,51 +174,36 @@ def test_backup_via_unprivileged_user(self):
174174
class AuthTest(unittest.TestCase):
175175
pb = None
176176
node = None
177+
test_path = None
177178

178-
# TODO move to object scope, replace module_name
179-
@classmethod
180-
def setUpClass(cls):
179+
@unittest.skipIf(skip_test, "Module pexpect isn't installed. You need to install it.")
180+
def setUp(self):
181181

182-
super(AuthTest, cls).setUpClass()
182+
super().setUp()
183183

184-
cls.pb = ProbackupTest()
185-
cls.backup_dir = os.path.join(cls.pb.tmp_path, module_name, 'backup')
184+
self.pb = ProbackupTest()
185+
self.test_path = os.path.join(self.pb.tmp_path, module_name, self._testMethodName)
186+
self.backup_dir = os.path.join(self.test_path, 'backup')
186187

187-
cls.node = cls.pb.make_simple_node(
188-
base_dir="{}/node".format(module_name),
188+
self.node = self.pb.make_simple_node(
189+
base_dir=os.path.join(self.test_path, 'node'),
189190
set_replication=True,
190191
initdb_params=['--data-checksums', '--auth-host=md5']
191192
)
192193

193-
cls.username = cls.pb.get_username()
194+
self.modify_pg_hba(self.node, self.pb.get_username())
194195

195-
cls.modify_pg_hba(cls.node)
196-
197-
cls.pb.init_pb(cls.backup_dir)
198-
cls.pb.add_instance(cls.backup_dir, cls.node.name, cls.node)
199-
cls.pb.set_archiving(cls.backup_dir, cls.node.name, cls.node)
196+
self.pb.init_pb(self.backup_dir)
197+
self.pb.add_instance(self.backup_dir, self.node.name, self.node)
198+
self.pb.set_archiving(self.backup_dir, self.node.name, self.node)
200199
try:
201-
cls.node.slow_start()
200+
self.node.slow_start()
202201
except StartNodeException:
203202
raise unittest.skip("Node hasn't started")
204203

205-
if cls.pb.get_version(cls.node) < 100000:
206-
cls.node.safe_psql(
207-
"postgres",
208-
"CREATE ROLE backup WITH LOGIN PASSWORD 'password'; "
209-
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
210-
"GRANT EXECUTE ON FUNCTION current_setting(text) TO backup; "
211-
"GRANT EXECUTE ON FUNCTION pg_is_in_recovery() TO backup; "
212-
"GRANT EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) TO backup; "
213-
"GRANT EXECUTE ON FUNCTION pg_stop_backup() TO backup; "
214-
"GRANT EXECUTE ON FUNCTION pg_stop_backup(boolean) TO backup; "
215-
"GRANT EXECUTE ON FUNCTION pg_create_restore_point(text) TO backup; "
216-
"GRANT EXECUTE ON FUNCTION pg_switch_xlog() TO backup; "
217-
"GRANT EXECUTE ON FUNCTION txid_current() TO backup; "
218-
"GRANT EXECUTE ON FUNCTION txid_current_snapshot() TO backup; "
219-
"GRANT EXECUTE ON FUNCTION txid_snapshot_xmax(txid_snapshot) TO backup;")
220-
elif cls.pb.get_version(cls.node) < 150000:
221-
cls.node.safe_psql(
204+
version = self.pb.get_version(self.node)
205+
if version < 150000:
206+
self.node.safe_psql(
222207
"postgres",
223208
"CREATE ROLE backup WITH LOGIN PASSWORD 'password'; "
224209
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
@@ -233,7 +218,7 @@ def setUpClass(cls):
233218
"GRANT EXECUTE ON FUNCTION txid_current_snapshot() TO backup; "
234219
"GRANT EXECUTE ON FUNCTION txid_snapshot_xmax(txid_snapshot) TO backup;")
235220
else:
236-
cls.node.safe_psql(
221+
self.node.safe_psql(
237222
"postgres",
238223
"CREATE ROLE backup WITH LOGIN PASSWORD 'password'; "
239224
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
@@ -247,16 +232,29 @@ def setUpClass(cls):
247232
"GRANT EXECUTE ON FUNCTION txid_current_snapshot() TO backup; "
248233
"GRANT EXECUTE ON FUNCTION txid_snapshot_xmax(txid_snapshot) TO backup;")
249234

250-
cls.pgpass_file = os.path.join(os.path.expanduser('~'), '.pgpass')
251-
252-
# TODO move to object scope, replace module_name
253-
@classmethod
254-
def tearDownClass(cls):
255-
cls.node.cleanup()
256-
cls.pb.del_test_dir(module_name, '')
235+
if version >= 150000:
236+
home_dir = os.path.join(self.test_path, "home")
237+
os.makedirs(home_dir, exist_ok=True)
238+
self.pb.test_env['HOME'] = home_dir
239+
self.pgpass_file = os.path.join(home_dir, '.pgpass')
240+
self.pgpass_file_lock = None
241+
else:
242+
# before PGv15 only true home dir were inspected.
243+
# Since we can't have separate file per test, we have to serialize
244+
# tests.
245+
self.pgpass_file = os.path.join(os.path.expanduser('~'), '.pgpass')
246+
self.pgpass_file_lock = self.pgpass_file + '~probackup_test_lock'
247+
# have to lock pgpass by creating file in exclusive mode
248+
for i in range(120):
249+
try:
250+
open(self.pgpass_file_lock, "x").close()
251+
except FileExistsError:
252+
time.sleep(1)
253+
else:
254+
break
255+
else:
256+
raise TimeoutError("can't create ~/.pgpass~probackup_test_lock for 120 seconds")
257257

258-
@unittest.skipIf(skip_test, "Module pexpect isn't installed. You need to install it.")
259-
def setUp(self):
260258
self.pb_cmd = ['backup',
261259
'-B', self.backup_dir,
262260
'--instance', self.node.name,
@@ -268,6 +266,19 @@ def setUp(self):
268266
]
269267

270268
def tearDown(self):
269+
if (self.pgpass_file_lock
270+
and hasattr(self, "pgpass_line")
271+
and os.path.exists(self.pgpass_file)):
272+
with open(self.pgpass_file, 'r', encoding="utf-8") as fl:
273+
lines = fl.readlines()
274+
if self.pgpass_line in lines:
275+
lines.remove(self.pgpass_line)
276+
if len(lines) == 0:
277+
os.remove(self.pgpass_file)
278+
else:
279+
with open(self.pgpass_file, 'w', encoding="utf-8") as fl:
280+
fl.writelines(lines)
281+
271282
if "PGPASSWORD" in self.pb.test_env.keys():
272283
del self.pb.test_env["PGPASSWORD"]
273284

@@ -279,6 +290,10 @@ def tearDown(self):
279290
except OSError:
280291
pass
281292

293+
test_path = os.path.join(self.pb.tmp_path, module_name)
294+
self.node.cleanup()
295+
self.pb.del_test_dir(test_path, self._testMethodName)
296+
282297
def test_empty_password(self):
283298
""" Test case: PGPB_AUTH03 - zero password length """
284299
try:
@@ -313,7 +328,7 @@ def test_ctrl_c_event(self):
313328

314329
def test_pgpassfile_env(self):
315330
""" Test case: PGPB_AUTH06 - set environment var PGPASSFILE """
316-
path = os.path.join(self.pb.tmp_path, module_name, 'pgpass.conf')
331+
path = os.path.join(self.test_path, 'pgpass.conf')
317332
line = ":".join(['127.0.0.1', str(self.node.port), 'postgres', 'backup', 'password'])
318333
self.create_pgpass(path, line)
319334
self.pb.test_env["PGPASSFILE"] = path
@@ -367,7 +382,7 @@ def run_pb_with_auth(self, password=None, add_args = [], kill=False):
367382

368383

369384
@classmethod
370-
def modify_pg_hba(cls, node):
385+
def modify_pg_hba(self, node, username):
371386
"""
372387
Description:
373388
Add trust authentication for user postgres. Need for add new role and set grant.
@@ -378,11 +393,12 @@ def modify_pg_hba(cls, node):
378393
with open(hba_conf, 'r+') as fio:
379394
data = fio.read()
380395
fio.seek(0)
381-
fio.write('host\tall\t%s\t127.0.0.1/0\ttrust\n%s' % (cls.username, data))
396+
fio.write('host\tall\t%s\t127.0.0.1/0\ttrust\n%s' % (username, data))
382397

383398

384399
def create_pgpass(self, path, line):
400+
self.pgpass_line = line+"\n"
385401
with open(path, 'w') as passfile:
386402
# host:port:db:username:password
387-
passfile.write(line)
403+
passfile.write(self.pgpass_line)
388404
os.chmod(path, 0o600)

0 commit comments

Comments
 (0)