8000 TestTestgresCommon - unified tests for local and remote by dmitry-lipetsk · Pull Request #216 · postgrespro/testgres · GitHub
[go: up one dir, main page]

Skip to content

TestTestgresCommon - unified tests for local 8000 and remote #216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5488ecd
TestTestgresCommon - unified tests for local and remote
dmitry-lipetsk Mar 12, 2025
a6edd3a
TestTestgresCommon is updated
dmitry-lipetsk Mar 12, 2025
3c055af
TestTestgresCommon is updated
dmitry-lipetsk Mar 13, 2025
188b3b2
TestTestgresCommon is updated
dmitry-lipetsk Mar 13, 2025
9b137ca
Merge branch 'master' into D20250312_002--TestTestgresCommon
dmitry-lipetsk Mar 13, 2025
9bddc3b
Merge branch 'master' into D20250312_002--TestTestgresCommon
dmitry-lipetsk Mar 14, 2025
75f0326
Merge branch 'master' into D20250312_002--TestTestgresCommon
dmitry-lipetsk Mar 16, 2025
292b403
TestTestgresCommon is updated
dmitry-lipetsk Mar 16, 2025
0fb22e8
PostgresNode_Base is added
dmitry-lipetsk Mar 16, 2025
2e5bd9d
test_simple_remote.py is cleaned
dmitry-lipetsk Mar 16, 2025
7f89186
Merge branch 'master' into D20250312_002--TestTestgresCommon
dmitry-lipetsk Mar 16, 2025
48fd887
Formatting (flake8)
dmitry-lipetsk Mar 16, 2025
bf28a1a
Formatting
dmitry-lipetsk Mar 17, 2025
f64dd60
PostgresNode_Base is updated (documentation)
dmitry-lipetsk Mar 17, 2025
490130e
PostgresNode is updated (documentation)
dmitry-lipetsk Mar 17, 2025
ff9b7bc
PostgresNode_Base::_prefix is removed
dmitry-lipetsk Mar 17, 2025
9e1979f
PostgresNode::clean is corrected
dmitry-lipetsk Mar 17, 2025
3e9cad1
node_base.py is updated
dmitry-lipetsk Mar 17, 2025
12fa7f2
node_base.py is updated
dmitry-lipetsk Mar 17, 2025
cef7982
node.py is updated
dmitry-lipetsk Mar 17, 2025
61feb2c
NodeApp::make_empty is updated
dmitry-lipetsk Mar 17, 2025
84a51c7
PostgresNode::cleanup is fixed
dmitry-lipetsk Mar 17, 2025
f7f915d
PostgresNode::cleanup is updated (flake8)
dmitry-lipetsk Mar 17, 2025
882b8ec
PostgresNode_Base::clone_with_new_name_and_base_dir is added
dmitry-lipetsk Mar 17, 2025
e8e392e
PostgresNode is updated (comment)
dmitry-lipetsk Mar 17, 2025
06287f2
Merge remote-tracking branch 'origin/D20250316_003--PostgresNode_Base…
dmitry-lipetsk Mar 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
TestTestgresCommon is updated
New tests:
 - test_users
 - test_poll_query_until
 - test_logging
  • Loading branch information
dmitry-lipetsk committed Mar 13, 2025
commit 3c055aff0c7ffdd3c5a22c1993235ce39dd22aba
162 changes: 0 additions & 162 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
import os
import re
import subprocess
import tempfile
import time
import pytest
import psutil
import platform
import logging
import uuid

from contextlib import contextmanager
from shutil import rmtree
Expand All @@ -21,7 +19,6 @@
ExecUtilException, \
BackupException, \
QueryException, \
TimeoutException, \
TestgresException, \
InvalidOperationException, \
NodeApp
Expand Down Expand Up @@ -703,165 +700,6 @@ def test_dump(self):
res = node3.execute(query_select)
assert (res == [(1, ), (2, )])

def test_users(self):
with get_new_node().init().start() as node:
node.psql('create role test_user login')
value = node.safe_psql('select 1', username='test_user')
value = rm_carriage_returns(value)
assert (value == b'1\n')

def test_poll_query_until(self):
with get_new_node() as node:
node.init().start()

get_time = 'select extract(epoch from now())'
check_time = 'select extract(epoch from now()) - {} >= 5'

start_time = node.execute(get_time)[0][0]
node.poll_query_until(query=check_time.format(start_time))
end_time = node.execute(get_time)[0][0]

assert (end_time - start_time >= 5)

# check 0 columns
with pytest.raises(expected_exception=QueryException):
node.poll_query_until(
query='select from pg_catalog.pg_class limit 1')

# check None, fail
with pytest.raises(expected_exception=QueryException):
node.poll_query_until(query='create table abc (val int)')

# check None, ok
node.poll_query_until(query='create table def()',
expected=None) # returns nothing

# check 0 rows equivalent to expected=None
node.poll_query_until(
query='select * from pg_catalog.pg_class where true = false',
expected=None)

# check arbitrary expected value, fail
with pytest.raises(expected_exception=TimeoutException):
node.poll_query_until(query='select 3',
expected=1,
max_attempts=3,
sleep_time=0.01)

# check arbitrary expected value, ok
node.poll_query_until(query='select 2', expected=2)

# check timeout
with pytest.raises(expected_exception=TimeoutException):
node.poll_query_until(query='select 1 > 2',
max_attempts=3,
sleep_time=0.01)

# check ProgrammingError, fail
with pytest.raises(expected_exception=testgres.ProgrammingError):
node.poll_query_until(query='dummy1')

# check ProgrammingError, ok
with pytest.raises(expected_exception=(TimeoutException)):
node.poll_query_until(query='dummy2',
max_attempts=3,
sleep_time=0.01,
suppress={testgres.ProgrammingError})

# check 1 arg, ok
node.poll_query_until('select true')

def test_logging(self):
C_MAX_ATTEMPTS = 50
# This name is used for testgres logging, too.
C_NODE_NAME = "testgres_tests." + __class__.__name__ + "test_logging-master-" + uuid.uuid4().hex

logging.info("Node name is [{0}]".format(C_NODE_NAME))

with tempfile.NamedTemporaryFile('w', delete=True) as logfile:
formatter = logging.Formatter(fmt="%(node)-5s: %(message)s")
handler = logging.FileHandler(filename=logfile.name)
handler.formatter = formatter
logger = logging.getLogger(C_NODE_NAME)
assert logger is not None
assert len(logger.handlers) == 0

try:
# It disables to log on the root level
logger.propagate = False
logger.addHandler(handler)

with scoped_config(use_python_logging=True):
with get_new_node(name=C_NODE_NAME) as master:
logging.info("Master node is initilizing")
master.init()

logging.info("Master node is starting")
master.start()

logging.info("Dummy query is executed a few times")
for _ in range(20):
master.execute('select 1')
time.sleep(0.01)

# let logging worker do the job
time.sleep(0.1)

logging.info("Master node log file is checking")
nAttempt = 0

while True:
assert nAttempt <= C_MAX_ATTEMPTS
if nAttempt == C_MAX_ATTEMPTS:
raise Exception("Test failed!")

# let logging worker do the job
time.sleep(0.1)

nAttempt += 1

logging.info("Attempt {0}".format(nAttempt))

# check that master's port is found
with open(logfile.name, 'r') as log:
lines = log.readlines()

assert lines is not None
assert type(lines) == list # noqa: E721

def LOCAL__test_lines():
for s in lines:
if any(C_NODE_NAME in s 8000 for s in lines):
logging.info("OK. We found the node_name in a line \"{0}\"".format(s))
return True
return False

if LOCAL__test_lines():
break

logging.info("Master node log file does not have an expected information.")
continue

# test logger after stop/start/restart
logging.info("Master node is stopping...")
master.stop()
logging.info("Master node is staring again...")
master.start()
logging.info("Master node is restaring...")
master.restart()
assert (master._logger.is_alive())
finally:
# It is a hack code to logging cleanup
logging._acquireLock()
assert logging.Logger.manager is not None
assert C_NODE_NAME in logging.Logger.manager.loggerDict.keys()
logging.Logger.manager.loggerDict.pop(C_NODE_NAME, None)
assert not (C_NODE_NAME in logging.Logger.manager.loggerDict.keys())
assert not (handler in logging._handlers.values())
logging._releaseLock()
# GO HOME!
return

def test_pgbench(self):
__class__.helper__skip_test_if_util_not_exist("pgbench")

Expand Down
161 changes: 0 additions & 161 deletions tests/test_simple_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
import os
import re
import subprocess
import tempfile

import time
import pytest
import psutil
import logging
import uuid

from contextlib import contextmanager

Expand All @@ -23,7 +21,6 @@
ExecUtilException, \
BackupException, \
QueryException, \
TimeoutException, \
TestgresException, \
InvalidOperationException

Expand Down Expand Up @@ -778,164 +775,6 @@ def test_dump(self):
res = node3.execute(query_select)
assert (res == [(1,), (2,)])

def test_users(self):
with __class__.helper__get_node().init().start() as node:
node.psql('create role test_user login')
value = node.safe_psql('select 1', username='test_user')
assert (b'1\n' == value)

def test_poll_query_until(self):
with __class__.helper__get_node() as node:
node.init().start()

get_time = 'select extract(epoch from now())'
check_time = 'select extract(epoch from now()) - {} >= 5'

start_time = node.execute(get_time)[0][0]
node.poll_query_until(query=check_time.format(start_time))
end_time = node.execute(get_time)[0][0]

assert (end_time - start_time >= 5)

# check 0 columns
with pytest.raises(expected_exception=QueryException):
node.poll_query_until(
query='select from pg_catalog.pg_class limit 1')

# check None, fail
with pytest.raises(expected_exception=QueryException):
node.poll_query_until(query='create table abc (val int)')

# check None, ok
node.poll_query_until(query='create table def()',
expected=None) # returns nothing

# check 0 rows equivalent to expected=None
node.poll_query_until(
query='select * from pg_catalog.pg_class where true = false',
expected=None)

# check arbitrary expected value, fail
with pytest.raises(expected_exception=TimeoutException):
node.poll_query_until(query='select 3',
expected=1,
max_attempts=3,
sleep_time=0.01)

# check arbitrary expected value, ok
node.poll_query_until(query='select 2', expected=2)

# check timeout
with pytest.raises(expected_exception=TimeoutException):
node.poll_query_until(query='select 1 > 2',
max_attempts=3,
sleep_time=0.01)

# check ProgrammingError, fail
with pytest.raises(expected_exception=testgres.ProgrammingError):
node.poll_query_until(query='dummy1')

# check ProgrammingError, ok
with pytest.raises(expected_exception=TimeoutException):
node.poll_query_until(query='dummy2',
max_attempts=3,
sleep_time=0.01,
suppress={testgres.ProgrammingError})

# check 1 arg, ok
node.poll_query_until('select true')

def test_logging(self):
C_MAX_ATTEMPTS = 50
# This name is used for testgres logging, too.
C_NODE_NAME = "testgres_tests." + __class__.__name__ + "test_logging-master-" + uuid.uuid4().hex

logging.info("Node name is [{0}]".format(C_NODE_NAME))

with tempfile.NamedTemporaryFile('w', delete=True) as logfile:
formatter = logging.Formatter(fmt="%(node)-5s: %(message)s")
handler = logging.FileHandler(filename=logfile.name)
handler.formatter = formatter
logger = logging.getLogger(C_NODE_NAME)
assert logger is not None
assert len(logger.handlers) == 0

try:
# It disables to log on the root level
logger.propagate = False
logger.addHandler(handler)

with scoped_config(use_python_logging=True):
with __class__.helper__get_node(name=C_NODE_NAME) as master:
logging.info("Master node is initilizing")
master.init()

logging.info("Master node is starting")
master.start()

logging.info("Dummy query is executed a few times")
for _ in range(20):
master.execute('select 1')
time.sleep(0.01)

# let logging worker do the job
time.sleep(0.1)

logging.info("Master node log file is checking")
nAttempt = 0

while True:
assert nAttempt <= C_MAX_ATTEMPTS
if nAttempt == C_MAX_ATTEMPTS:
raise Exception("Test failed!")

# let logging worker do the job
time.sleep(0.1)

nAttempt += 1

logging.info("Attempt {0}".format(nAttempt))

# check that master's port is found
with open(logfile.name, 'r') as log:
lines = log.readlines()

assert lines is not None
assert type(lines) == list # noqa: E721

def LOCAL__test_lines():
for s in lines:
if any(C_NODE_NAME in s for s in lines):
logging.info("OK. We found the node_name in a line \"{0}\"".format(s))
return True
return False

if LOCAL__test_lines():
break

logging.info("Master node log file does not have an expected information.")
continue

# test logger after stop/start/restart
logging.info("Master node is stopping...")
master.stop()
logging.info("Master node is staring again...")
master.start()
logging.info("Master node is restaring...")
master.restart()
assert (master._logger.is_alive())
finally:
# It is a hack code to logging cleanup
logging._acquireLock()
assert logging.Logger.manager is not None
assert C_NODE_NAME in logging.Logger.manager.loggerDict.keys()
logging.Logger.manager.loggerDict.pop(C_NODE_NAME, None)
assert not (C_NODE_NAME in logging.Logger.manager.loggerDict.keys())
assert not (handler in logging._handlers.values())
logging._releaseLock()
# GO HOME!
return

def test_pgbench(self):
__class__.helper__skip_test_if_util_not_exist("pgbench")

Expand Down
Loading
0