Skip to content

Commit e18fade

Browse files
authored
tests: migrate from nosetests to pytest (#1134)
* Dockerfile: replace pipenv with python3-pytest; quote pyroute2 version - drop pipenv (unused) - add python3-pytest from apt (available in bullseye at 6.0.2) - quote 'pyroute2>=0.5.17' so the shell does not strip the >= operator * tests: switch test runner from nosetests to pytest python3-nose crashes on Python 3.11+ (collections.Callable removed in 3.10; nose/suite.py still uses it). pytest is the modern replacement and is now installed via apt alongside python3-nose (kept for the nose.tools helpers that a few tests still use). Makefile changes: - NOSETESTS → PYTEST variable using `which pytest` - TEST_ARGUMENT format: nose --where/--tests style → pytest path style (tests/*.py for all, tests/foo.py for a named test) - Use tests/*.py glob (not tests/) to avoid descending into tests/tablespaces/ which has its own import layout and make target Makefile.citus: apply the same TEST_ARGUMENT pattern update that the main Makefile received. * tests: fix pytest compatibility — binary path, CI gating, network locale, conftest, autocommit 1. Makefile: use 'python3 -m pytest' instead of 'which pytest' Debian's python3-pytest package does not install a 'pytest' binary in PATH (only 'py.test-3' and 'pytest-3'); 'python3 -m pytest' is the reliable invocation regardless of binary name. 2. .github/workflows/run-tests.yml: gate build_images on style_checker so a style failure stops CI before any image builds start. 3. tests/network.py: two fixes for pyroute2 >= 0.5.17 strict UTF-8: - replace universal_newlines=True with encoding='utf-8', errors='replace' in both NSPopen calls so non-ASCII bytes from pg_autoctl are replaced rather than raising UnicodeDecodeError. - add LC_ALL=C LANG=C to subprocess env so PostgreSQL produces ASCII-only error messages inside network namespaces. 4. tests/tablespaces/conftest.py: add project root to sys.path so the tablespace tests can import as 'from tests.tablespaces.xxx'. nosetests did this implicitly; pytest does not. 5. tests/pgautofailover_utils.py: fix run_sql_query when autocommit=True. psycopg2's 'with conn:' context manager wraps an implicit BEGIN even when autocommit is on (behaviour varies by psycopg2 version), blocking DDL like CREATE TABLESPACE. Use explicit commit/rollback/finally.
1 parent 5e91db1 commit e18fade

7 files changed

Lines changed: 36 additions & 19 deletions

File tree

.github/workflows/run-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ jobs:
3030

3131
build_images:
3232
name: Build test image (PG${{ matrix.PGVERSION }})
33+
needs: style_checker
3334
runs-on: ubuntu-latest
3435
strategy:
3536
fail-fast: false

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ RUN apt-get update \
4444
make \
4545
autoconf \
4646
openssl \
47-
pipenv \
4847
python3-nose \
48+
python3-pytest \
4949
python3 \
5050
python3-setuptools \
5151
python3-psycopg2 \
@@ -74,7 +74,7 @@ RUN apt-get update \
7474
postgresql-${PGVERSION} \
7575
&& rm -rf /var/lib/apt/lists/*
7676

77-
RUN pip3 install pyroute2>=0.5.17
77+
RUN pip3 install 'pyroute2>=0.5.17'
7878

7979
RUN adduser --disabled-password --gecos '' docker
8080
RUN adduser docker sudo

Makefile

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ include Makefile.azure
3939
#
4040
# LIST TESTS
4141
#
42-
NOSETESTS = $(shell which nosetests3 || which nosetests)
42+
PYTEST = python3 -m pytest
4343

4444
# Tests for the monitor
4545
TESTS_MONITOR = test_extension_update
@@ -78,17 +78,17 @@ TESTS_MULTI += test_multi_standbys
7878
# Included Makefile may define TEST_ARGUMENT (like for citus)
7979
TEST ?=
8080
ifeq ($(TEST),)
81-
TEST_ARGUMENT = --where=tests
81+
TEST_ARGUMENT = tests/*.py
8282
else ifeq ($(TEST),multi)
83-
TEST_ARGUMENT = --where=tests --tests=$(TESTS_MULTI)
83+
TEST_ARGUMENT = $(TESTS_MULTI:%=tests/%.py)
8484
else ifeq ($(TEST),single)
85-
TEST_ARGUMENT = --where=tests --tests=$(TESTS_SINGLE)
85+
TEST_ARGUMENT = $(TESTS_SINGLE:%=tests/%.py)
8686
else ifeq ($(TEST),monitor)
87-
TEST_ARGUMENT = --where=tests --tests=$(TESTS_MONITOR)
87+
TEST_ARGUMENT = $(TESTS_MONITOR:%=tests/%.py)
8888
else ifeq ($(TEST),ssl)
89-
TEST_ARGUMENT = --where=tests --tests=$(TESTS_SSL)
89+
TEST_ARGUMENT = $(TESTS_SSL:%=tests/%.py)
9090
else
91-
TEST_ARGUMENT = $(TEST:%=tests/%.py)
91+
TEST_ARGUMENT = tests/$(TEST).py
9292
endif
9393

9494
#
@@ -167,11 +167,10 @@ ifeq ($(TEST),tablespaces)
167167
$(MAKE) -C tests/tablespaces run-test
168168
else
169169
sudo -E env "PATH=${PATH}" USER=$(shell whoami) \
170-
$(NOSETESTS) \
171-
--verbose \
172-
--nologcapture \
173-
--nocapture \
174-
--stop \
170+
$(PYTEST) \
171+
-v \
172+
-s \
173+
-x \
175174
${TEST_ARGUMENT}
176175
endif
177176

Makefile.citus

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ifeq ($(TEST),citus)
1919
TESTS_CITUS += test_nonha_citus_operation
2020
TESTS_CITUS += test_citus_skip_pg_hba
2121

22-
TEST_ARGUMENT = --where=tests --tests=$(TESTS_CITUS)
22+
TEST_ARGUMENT = $(TESTS_CITUS:%=tests/%.py)
2323
endif
2424

2525
# this target is defined and used later in the main Makefile

tests/network.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ def run(self, command, user=os.getenv("USER")):
153153
user,
154154
"env",
155155
"PATH=" + os.getenv("PATH"),
156+
"LC_ALL=C",
157+
"LANG=C",
156158
] + command
157159
return managed_nspopen(
158160
self.namespace,
@@ -179,6 +181,8 @@ def run_unmanaged(self, command, user=os.getenv("USER")):
179181
user,
180182
"env",
181183
"PATH=" + os.getenv("PATH"),
184+
"LC_ALL=C",
185+
"LANG=C",
182186
] + command
183187
return NSPopen(
184188
self.namespace,

tests/pgautofailover_utils.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,21 @@ def run_sql_query(self, query, autocommit, *args):
271271
conn = psycopg2.connect(self.connection_string())
272272
conn.autocommit = autocommit
273273

274-
with conn:
274+
try:
275275
with conn.cursor() as cur:
276276
cur.execute(query, args)
277277
try:
278278
result = cur.fetchall()
279279
except psycopg2.ProgrammingError:
280280
pass
281-
# leaving contexts closes the cursor, however
282-
# leaving contexts doesn't close the connection
283-
conn.close()
281+
if not autocommit:
282+
conn.commit()
283+
except Exception:
284+
if not autocommit:
285+
conn.rollback()
286+
raise
287+
finally:
288+
conn.close()
284289

285290
return result
286291

tests/tablespaces/conftest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import sys
2+
import os
3+
4+
# tablespace tests import as "from tests.tablespaces.xxx import ..." which
5+
# requires the project root (parent of tests/) on sys.path. pytest does not
6+
# add it automatically; nosetests used to, by treating tests/__init__.py as a
7+
# package root. Add it here so both test runners work.
8+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))

0 commit comments

Comments
 (0)