From fad186e544d54c117a64f051c44caad9e7625513 Mon Sep 17 00:00:00 2001 From: Louis Sautier Date: Tue, 27 Dec 2022 03:02:51 +0100 Subject: [PATCH] Tests: replace nose with pytest nose is no longer maintained, see https://github.com/nose-devs/nose/issues/1099#issuecomment-562394879. This was initially submitted here: https://bugs.gentoo.org/878695. This commit switches to pytest. Amongst the changes, here are the most relevant ones: * Create a conftest.py that contains fixtures. * Replace nose.with_setup with yield fixtures. * Use pytest.skip instead of print and nose.plugins.skip.SkipTest. * Use pytest.mark.slow instead of nose.plugins.attrib.attr("slow"). * Use pytest.mark.parametrize instead of parameterized, simplify parametrized tests that use both `shell` and `inverse_order`. * Update Travis config. * Update SConscript. * Update documentation. --- .travis.yml | 2 +- docs/developers.rst | 6 +- docs/install.rst | 2 +- docs/testing.rst | 23 ++++---- pytest.ini | 3 + test-requirements.txt | 3 +- tests/SConscript | 8 +-- tests/conftest.py | 21 +++++++ tests/test_formatters/test_csv.py | 4 +- tests/test_formatters/test_json.py | 4 +- tests/test_formatters/test_others.py | 4 +- tests/test_formatters/test_py.py | 11 ++-- tests/test_formatters/test_sh.py | 42 ++++---------- tests/test_mains/test_dedupe.py | 47 +++++----------- tests/test_mains/test_hash.py | 9 ++- tests/test_options/test_cache.py | 12 ++-- tests/test_options/test_clamp.py | 13 ++--- tests/test_options/test_equal.py | 22 +++----- tests/test_options/test_help.py | 7 +-- tests/test_options/test_hidden_dirs.py | 13 ++--- tests/test_options/test_keep_hardlinks.py | 4 +- tests/test_options/test_km.py | 4 +- tests/test_options/test_match_basenames.py | 13 ++--- .../test_options/test_match_with_extension.py | 7 +-- .../test_match_without_extension.py | 7 +-- tests/test_options/test_merge_directories.py | 55 +++++-------------- tests/test_options/test_mtime_window.py | 14 ++--- tests/test_options/test_newer_than.py | 10 +--- tests/test_options/test_no_backup.py | 4 +- tests/test_options/test_pass_files.py | 4 +- tests/test_options/test_perms.py | 4 +- tests/test_options/test_rankby.py | 7 +-- tests/test_options/test_replay.py | 35 ++++-------- tests/test_options/test_size.py | 10 +--- tests/test_options/test_sorting.py | 20 +++---- tests/test_options/test_stdin.py | 17 ++---- tests/test_options/test_symlinks.py | 10 +--- tests/test_robustness/test_8Mlongpathfiles.py | 8 +-- .../test_robustness/test_badlinks_as_args.py | 4 +- tests/test_robustness/test_bigfiles.py | 5 +- tests/test_robustness/test_collisions.py | 8 +-- tests/test_robustness/test_manyfiles.py | 8 +-- .../test_robustness/test_manylongpathfiles.py | 8 +-- tests/test_robustness/test_path_doubles.py | 24 ++------ tests/test_types/test_badlink.py | 4 +- tests/test_types/test_baduids.py | 4 +- tests/test_types/test_duplicate.py | 16 ++---- tests/test_types/test_empty_dirs.py | 11 +--- tests/test_types/test_empty_files.py | 4 +- tests/test_types/test_nonstripped.py | 7 +-- tests/utils.py | 11 ++++ 51 files changed, 210 insertions(+), 393 deletions(-) create mode 100644 pytest.ini create mode 100644 tests/conftest.py diff --git a/.travis.yml b/.travis.yml index 1b11f23e9..a2793eb05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,4 +21,4 @@ script: - scons config - export RM_TS_PRINT_CMD=1 - export RM_TS_PEDANTIC=0 - - sudo -E nosetests -s -v -a '!slow' + - sudo -E pytest -s -v -k 'not slow' diff --git a/docs/developers.rst b/docs/developers.rst index 02c5c8146..c3eb3d543 100644 --- a/docs/developers.rst +++ b/docs/developers.rst @@ -237,13 +237,13 @@ Notable targets :test: - Build the tests (requires ``python`` and ``nosetest`` installed). - Optionally ``valgrind`` can be installed to run the tests through + Build the tests (requires ``python`` and ``pytest`` installed). + Optionally ``valgrind`` can be installed to run the tests through valgrind: .. code-block:: bash - $ USE_VALGRIND=1 nosetests # or nosetests-3.3, python3 needed. + $ USE_VALGRIND=1 pytest :xgettext: diff --git a/docs/install.rst b/docs/install.rst index b22e22a9f..993a72013 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -97,7 +97,7 @@ Here's a list of readily prepared commands for known operating systems: .. code-block:: bash - $ apt-get install pkg-config git scons python3-sphinx python3-nose gettext build-essential + $ apt-get install pkg-config git scons python3-sphinx python3-pytest gettext build-essential # Optional dependencies for more features: $ apt-get install libelf-dev libglib2.0-dev libblkid-dev libjson-glib-1.0 libjson-glib-dev # Optional dependencies for the GUI: diff --git a/docs/testing.rst b/docs/testing.rst index 6bca75f64..f2afc33ee 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -5,7 +5,7 @@ Testsuite complete yet (and probably never will), but it's already a valuable boost of confidence in ``rmlint's`` correctness. -The tests are based on ``nosetest`` and are written in ``python>=3.0``. +The tests are based on ``pytest`` and are written in ``python>=3.0``. Every testcase just runs the (previously built) ``rmlint`` binary a and parses its json output. So they are technically blackbox-tests. @@ -34,17 +34,17 @@ variables which are: - ``RM_TS_PRINT_CMD``: Print the command that is currently run. - ``RM_TS_KEEP_TESTDIR``: If a test failed, keep the test files. -Additionally slow tests can be omitted with by appending ``-a '!slow'`` to -the commandline. More information on this syntax can be found on the `nosetest +Additionally slow tests can be omitted with by appending ``-k 'not slow'`` to +the commandline. More information on this syntax can be found on the `pytest documentation`_. -.. _`nosetest documentation`: http://nose.readthedocs.org/en/latest/plugins/attrib.html +.. _`pytest documentation`: https://docs.pytest.org/en/stable/example/markers.html Before each release we call the testsuite (at least) like this: .. code-block:: bash - $ sudo RM_TS_USE_VALGRIND=1 RM_TS_PRINT_CMD=1 RM_TS_PEDANTIC=1 nosetests-3.4 -s -a '!slow !known_issue' + $ sudo RM_TS_USE_VALGRIND=1 RM_TS_PRINT_CMD=1 RM_TS_PEDANTIC=1 pytest -s -a 'not slow and not known_issue' The ``sudo`` here is there for executing some tests that need root access (like the creating of bad user and group ids). Most tests will work without. @@ -59,7 +59,7 @@ were executed (and how often) by the testsuite. Here's a short quickstart using .. code-block:: bash $ CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs -ftest-coverage" scons -j4 DEBUG=1 - $ sudo RM_TS_USE_VALGRIND=1 RM_TS_PRINT_CMD=1 RM_TS_PEDANTIC=1 nosetests-3.4 -s -a '!slow !known_issue' + $ sudo RM_TS_USE_VALGRIND=1 RM_TS_PRINT_CMD=1 RM_TS_PEDANTIC=1 pytest -s -a 'slow and not known_issue' $ lcov --capture --directory . --output-file coverage.info $ genhtml coverage.info --output-directory out @@ -85,11 +85,9 @@ A template for a testcase looks like this: .. code-block:: python - from nose import with_setup from tests.utils import * - @with_setup(usual_setup_func, usual_teardown_func) - def test_basic(): + def test_basic(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('xxx', 'b') @@ -117,11 +115,10 @@ Rules .. code-block:: python - from nose.plugins.attrib import attr + import pytest - @attr('slow') - @with_setup(usual_setup_func, usual_teardown_func) - def test_debian_support(): + @pytest.mark.slow + def test_debian_support(usual_setup_usual_teardown): assert random.choice([True, False]): * Unresolved issues can be marked with `known_issue` attribute to avoid failing automated travis testing diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..deff39960 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +markers = + slow: slow tests. diff --git a/test-requirements.txt b/test-requirements.txt index 1882435d9..37cec9e4d 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,3 @@ -nose==1.3.7 -parameterized==0.6.1 xattr==0.9.6 psutil==5.6.6 +pytest diff --git a/tests/SConscript b/tests/SConscript index 9f421d6a5..e2de52e79 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -17,14 +17,14 @@ def cmd_exists(cmd): def run_tests(target=None, source=None, env=None): - names = ['nosetests-3.3', 'nosetests-3', 'python3-nosetests', 'nosetests3', 'nosetests'] + names = ["pytest"] exes = [exe for exe in names if cmd_exists(exe)] if any(exes): name = exes[0] - print('Found nosetests as "{}"'.format(name)) - Exit(subprocess.call(name + ' -s -v -a !slow', shell=True)) + print('Found pytest as "{}"'.format(name)) + Exit(subprocess.call(name + ' -s -v -k "not slow"', shell=True)) - print('Unable to find nosetests, tried these: ' + str(names)) + print('Unable to find pytest, tried these: ' + str(names)) Exit(-1) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..46168d68d --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,21 @@ +import pytest + +from tests.utils import mount_bind_teardown_func, usual_setup_func, usual_teardown_func + +@pytest.fixture(params=["sh", "bash", "dash"]) +def shell(request): + yield request.param + + +@pytest.fixture +def usual_setup_usual_teardown(): + usual_setup_func() + yield + usual_teardown_func() + + +@pytest.fixture +def usual_setup_mount_bind_teardown(): + usual_setup_func() + yield + mount_bind_teardown_func() diff --git a/tests/test_formatters/test_csv.py b/tests/test_formatters/test_csv.py index 271877625..9a83bb05f 100644 --- a/tests/test_formatters/test_csv.py +++ b/tests/test_formatters/test_csv.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import csv @@ -10,8 +9,7 @@ def csv_string_to_data(csv_dump): return data[1:] -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_file('1234', 'a') create_file('1234', 'b') create_file('1234', 'stupid\'file,name') diff --git a/tests/test_formatters/test_json.py b/tests/test_formatters/test_json.py index 9cacd6f8a..e420d798a 100644 --- a/tests/test_formatters/test_json.py +++ b/tests/test_formatters/test_json.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): full_path_a = create_file('x', '\t\r\"\b\f\\') full_path_b = create_file('x', '\"\t\n2134124') head, *data, footer = run_rmlint('-S a') diff --git a/tests/test_formatters/test_others.py b/tests/test_formatters/test_others.py index afeda7dea..d931b3467 100644 --- a/tests/test_formatters/test_others.py +++ b/tests/test_formatters/test_others.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_just_call_it(): +def test_just_call_it(usual_setup_usual_teardown): create_file('1234', 'a') create_file('1234', 'b') diff --git a/tests/test_formatters/test_py.py b/tests/test_formatters/test_py.py index 92b176049..6a1eb5895 100644 --- a/tests/test_formatters/test_py.py +++ b/tests/test_formatters/test_py.py @@ -1,11 +1,10 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import subprocess -from parameterized import parameterized +import pytest def _check_interpreter(interpreter): @@ -16,16 +15,14 @@ def _check_interpreter(interpreter): return False -@parameterized(["python2", "python3"]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_paranoia(interpreter): +@pytest.mark.parametrize("interpreter", ["python2", "python3"]) +def test_paranoia(usual_setup_usual_teardown, interpreter): if not _check_interpreter(interpreter): - print( + pytest.skip( "Interpreter {} does not seem to be working, skipping test".format( interpreter ) ) - return create_file('xxx', 'a') create_file('xxx', 'b') diff --git a/tests/test_formatters/test_sh.py b/tests/test_formatters/test_sh.py index f8c17a9ef..9595e3845 100644 --- a/tests/test_formatters/test_sh.py +++ b/tests/test_formatters/test_sh.py @@ -1,11 +1,10 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import subprocess -from parameterized import parameterized +import pytest def run_shell_script(shell, sh_path, *args): @@ -21,9 +20,7 @@ def filter_part_of_directory(data): return [e for e in data if e['type'] != 'part_of_directory'] -@with_setup(usual_setup_func, usual_teardown_func) -@parameterized([("sh", ), ("bash", ), ("dash", )]) -def test_basic(shell): +def test_basic(usual_setup_usual_teardown, shell): create_file('xxx', 'a') create_file('xxx', 'b') @@ -71,9 +68,7 @@ def test_basic(shell): assert '/a' in text -@parameterized([("sh", ), ("bash", ), ("dash", )]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_paranoia(shell): +def test_paranoia(usual_setup_usual_teardown, shell): create_file('xxx', 'a') create_file('xxx', 'b') create_file('xxx', 'c') @@ -124,8 +119,7 @@ def test_paranoia(shell): assert footer['duplicates'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_anon_pipe(): +def test_anon_pipe(usual_setup_usual_teardown): create_file('xxx', 'long-dummy-file-1') create_file('xxx', 'long-dummy-file-2') @@ -140,9 +134,7 @@ def test_anon_pipe(): assert b'/long-dummy-file-2' in data -@parameterized([("sh", ), ("bash", ), ("dash", )]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_hardlink_duplicate_directories(shell): +def test_hardlink_duplicate_directories(usual_setup_usual_teardown, shell): create_file('xxx', 'dir_a/x') create_file('xxx', 'dir_b/x') @@ -174,12 +166,8 @@ def _check_if_empty_dirs_deleted(shell, inverse_order, sh_path, data): assert not os.path.exists(data[1]["path"]) -@parameterized([ - ("sh", False), ("bash", False), ("dash", False), - ("sh", True), ("bash", True), ("dash", True) -]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_remove_empty_dirs(shell, inverse_order): +@pytest.mark.parametrize("inverse_order", [False, True]) +def test_remove_empty_dirs(usual_setup_usual_teardown, shell, inverse_order): create_file('xxx', 'deep/a/b/c/d/e/1') create_file('xxx', 'deep/x/2') @@ -207,12 +195,8 @@ def test_remove_empty_dirs(shell, inverse_order): _check_if_empty_dirs_deleted(shell, inverse_order, sh_path, data) -@parameterized([ - ("sh", False), ("bash", False), ("dash", False), - ("sh", True), ("bash", True), ("dash", True) -]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_remove_empty_dirs_with_dupe_dirs(shell, inverse_order): +@pytest.mark.parametrize("inverse_order", [False, True]) +def test_remove_empty_dirs_with_dupe_dirs(usual_setup_usual_teardown, shell, inverse_order): create_file('xxx', 'deep/a/b/c/d/e/1') create_file('xxx', 'deep/x/1') @@ -240,9 +224,7 @@ def test_remove_empty_dirs_with_dupe_dirs(shell, inverse_order): _check_if_empty_dirs_deleted(shell, inverse_order, sh_path, data) -@with_setup(usual_setup_func, usual_teardown_func) -@parameterized([("sh", ), ("bash", ), ("dash", )]) -def test_cleanup_emptydirs(shell): +def test_cleanup_emptydirs(usual_setup_usual_teardown, shell): create_file('xxx', 'dir1/a') # create some ugly dir names @@ -271,9 +253,7 @@ def test_cleanup_emptydirs(shell): -@with_setup(usual_setup_func, usual_teardown_func) -@parameterized([("sh", ), ("bash", ), ("dash", )]) -def test_keep_parent_timestamps(shell): +def test_keep_parent_timestamps(usual_setup_usual_teardown, shell): create_file('xxx', 'dir/a') create_file('xxx', 'dir/b') diff --git a/tests/test_mains/test_dedupe.py b/tests/test_mains/test_dedupe.py index 3a8e2a94f..bc4105812 100644 --- a/tests/test_mains/test_dedupe.py +++ b/tests/test_mains/test_dedupe.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup -from nose.tools import make_decorator -from nose.plugins.skip import SkipTest from contextlib import contextmanager import psutil +import pytest import re from tests.utils import * @@ -49,25 +47,16 @@ def is_on_reflink_fs(path): return False -# decorator for tests dependent on reflink-capable testdir -def needs_reflink_fs(test): - def no_support(*args): - raise SkipTest("btrfs not supported") - - def not_reflink_fs(*args): - raise SkipTest("testdir is not on reflink-capable filesystem") - +@pytest.fixture +# fixture for tests dependent on reflink-capable testdir +def needs_reflink_fs(): if not has_feature('btrfs-support'): - return make_decorator(test)(no_support) + pytest.skip("btrfs not supported") elif not is_on_reflink_fs(TESTDIR_NAME): - return make_decorator(test)(not_reflink_fs) - else: - return test - + pytest.skip("testdir is not on reflink-capable filesystem") + yield -@needs_reflink_fs -@with_setup(usual_setup_func, usual_teardown_func) -def test_equal_files(): +def test_equal_files(usual_setup_usual_teardown, needs_reflink_fs): path_a = create_file('1234', 'a') path_b = create_file('1234', 'b') @@ -87,9 +76,7 @@ def test_equal_files(): with_json=False) -@needs_reflink_fs -@with_setup(usual_setup_func, usual_teardown_func) -def test_different_files(): +def test_different_files(usual_setup_usual_teardown, needs_reflink_fs): path_a = create_file('1234', 'a') path_b = create_file('4321', 'b') @@ -102,9 +89,7 @@ def test_different_files(): verbosity="") -@needs_reflink_fs -@with_setup(usual_setup_func, usual_teardown_func) -def test_bad_arguments(): +def test_bad_arguments(usual_setup_usual_teardown, needs_reflink_fs): path_a = create_file('1234', 'a') path_b = create_file('1234', 'b') path_c = create_file('1234', 'c') @@ -122,9 +107,7 @@ def test_bad_arguments(): verbosity="") -@needs_reflink_fs -@with_setup(usual_setup_func, usual_teardown_func) -def test_directories(): +def test_directories(usual_setup_usual_teardown, needs_reflink_fs): path_a = os.path.dirname(create_dirs('dir_a')) path_b = os.path.dirname(create_dirs('dir_b')) @@ -137,9 +120,7 @@ def test_directories(): verbosity="") -@needs_reflink_fs -@with_setup(usual_setup_func, usual_teardown_func) -def test_dedupe_works(): +def test_dedupe_works(usual_setup_usual_teardown, needs_reflink_fs): # test files need to be larger than btrfs node size to prevent inline extents path_a = create_file('1' * 100000, 'a') @@ -183,9 +164,7 @@ def pattern_count(path, patterns): return counts -@needs_reflink_fs -@with_setup(usual_setup_func, usual_teardown_func) -def test_clone_handler(): +def test_clone_handler(usual_setup_usual_teardown, needs_reflink_fs): # test files need to be larger than btrfs node size to prevent inline extents path_a = create_file('1' * 100000, 'a') path_b = create_file('1' * 100000, 'b') diff --git a/tests/test_mains/test_hash.py b/tests/test_mains/test_hash.py index 391d2accf..9d28f36f6 100644 --- a/tests/test_mains/test_hash.py +++ b/tests/test_mains/test_hash.py @@ -1,10 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -from nose.plugins.attrib import attr -from parameterized import parameterized + +import pytest INCREMENTS = [4096, 1024, 1, 20000] @@ -29,7 +28,7 @@ def streaming_compliance_check(patterns): assert False, "{} fails streaming test with increment {}".format(algo, increment) break -@parameterized([ +@pytest.mark.parametrize("pat", [ 'murmur', 'metro', ['glib:', 'md5', 'sha1', 'sha256', 'sha512'], @@ -38,7 +37,7 @@ def streaming_compliance_check(patterns): 'xxhash', 'highway' ]) -def test_hash_function(*pat): +def test_hash_function(usual_setup_usual_teardown, pat): if(len(pat)==1): streaming_compliance_check(pat) else: diff --git a/tests/test_options/test_cache.py b/tests/test_options/test_cache.py index 9780b9500..70d911053 100644 --- a/tests/test_options/test_cache.py +++ b/tests/test_options/test_cache.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -from parameterized import parameterized + +import pytest def create_files(): @@ -56,8 +56,7 @@ def check(data, write_cache): assert path_in('4.d', dupe_files) -@with_setup(usual_setup_func, usual_teardown_func) -def test_xattr_basic(): +def test_xattr_basic(usual_setup_usual_teardown): create_files() for _ in range(2): @@ -72,9 +71,8 @@ def test_xattr_basic(): head, *data, footer = run_rmlint('-D -S pa --xattr-clear') -@parameterized([("", ), ("-D", )]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_xattr_detail(extra_opts): +@pytest.mark.parametrize("extra_opts", ["", "-D"]) +def test_xattr_detail(usual_setup_usual_teardown, extra_opts): if not runs_as_root(): # This tests need a ext4 fs which is created during the test. # The mount step sadly needs root privileges. diff --git a/tests/test_options/test_clamp.py b/tests/test_options/test_clamp.py index a79a00b41..b07ee8ad1 100644 --- a/tests/test_options/test_clamp.py +++ b/tests/test_options/test_clamp.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_file('1234567890', 'a10') create_file('x23456789x', 'b10') @@ -19,8 +17,7 @@ def test_simple(): assert len(data) == 2 -@with_setup(usual_setup_func, usual_teardown_func) -def test_almost_empty(): +def test_almost_empty(usual_setup_usual_teardown): create_file('x', 'a1') create_file('x', 'b1') @@ -33,8 +30,7 @@ def test_almost_empty(): assert footer['total_files'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_absolute(): +def test_absolute(usual_setup_usual_teardown): data1 = ['x'] * 2048 data2 = ['x'] * 2048 data2[1023] = 'y' @@ -59,8 +55,7 @@ def test_absolute(): assert len(data) == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_clamped_to_empty(): +def test_clamped_to_empty(usual_setup_usual_teardown): create_file('x', 'empties/a') create_file('x', 'empties/b') diff --git a/tests/test_options/test_equal.py b/tests/test_options/test_equal.py index 6b899e06c..99cf71913 100644 --- a/tests/test_options/test_equal.py +++ b/tests/test_options/test_equal.py @@ -3,7 +3,6 @@ import os import json -from nose import with_setup from contextlib import contextmanager from tests.utils import * @@ -25,8 +24,7 @@ def assert_exit_code(status_code): assert status_code == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_equal_files(): +def test_equal_files(usual_setup_usual_teardown): path_a = create_file('1234', 'a') path_b = create_file('1234', 'b') @@ -63,8 +61,7 @@ def test_equal_files(): ) -@with_setup(usual_setup_func, usual_teardown_func) -def test_no_arguments(): +def test_no_arguments(usual_setup_usual_teardown): with assert_exit_code(1): head, *data, footer = run_rmlint( '--equal', @@ -72,8 +69,7 @@ def test_no_arguments(): ) -@with_setup(usual_setup_func, usual_teardown_func) -def test_one_arguments(): +def test_one_arguments(usual_setup_usual_teardown): path = create_file('1234', 'a') with assert_exit_code(1): head, *data, footer = run_rmlint( @@ -94,8 +90,7 @@ def test_one_arguments(): ) -@with_setup(usual_setup_func, usual_teardown_func) -def test_equal_directories(): +def test_equal_directories(usual_setup_usual_teardown): path_a = os.path.dirname(create_file('xxx', 'dir_a/x')) path_b = os.path.dirname(create_file('xxx', 'dir_b/x')) @@ -112,8 +107,7 @@ def test_equal_directories(): ) -@with_setup(usual_setup_func, usual_teardown_func) -def test_dir_and_file(): +def test_dir_and_file(usual_setup_usual_teardown): path_a = os.path.dirname(create_file('xxx', 'dir_a/x')) path_b = create_file('xxx', 'x') @@ -127,8 +121,7 @@ def test_dir_and_file(): # Regression test for Issue #233 -@with_setup(usual_setup_func, usual_teardown_func) -def test_equal_hidden_dirs(): +def test_equal_hidden_dirs(usual_setup_usual_teardown): path_a = os.path.dirname(create_file('xxx', 'dir_a/x')) path_b = os.path.dirname(create_file('xxx', '.dir_b/.x')) @@ -142,8 +135,7 @@ def test_equal_hidden_dirs(): # Regression test for Issue #234 -@with_setup(usual_setup_func, usual_teardown_func) -def test_equal_empty_files_or_other_lint(): +def test_equal_empty_files_or_other_lint(usual_setup_usual_teardown): path_a = create_file('', 'x') path_b = create_file('', 'y') diff --git a/tests/test_options/test_help.py b/tests/test_options/test_help.py index d934724a5..5e20a376a 100644 --- a/tests/test_options/test_help.py +++ b/tests/test_options/test_help.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * # These tests are only here to check if printing help works. # Well, actually it's to increase coverage to be honest. -@with_setup(usual_setup_func, usual_teardown_func) -def test_help(): +def test_help(usual_setup_usual_teardown): yelp = subprocess.check_output( ['./rmlint', '--help'], stderr=subprocess.STDOUT ).decode('utf-8') @@ -16,8 +14,7 @@ def test_help(): assert '--show-man' in yelp -@with_setup(usual_setup_func, usual_teardown_func) -def test_man(): +def test_man(usual_setup_usual_teardown): yelp = subprocess.check_output( ['./rmlint', '--show-man'], stderr=subprocess.STDOUT ).decode('utf-8') diff --git a/tests/test_options/test_hidden_dirs.py b/tests/test_options/test_hidden_dirs.py index 0201dbc7c..c1c4aae1c 100644 --- a/tests/test_options/test_hidden_dirs.py +++ b/tests/test_options/test_hidden_dirs.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * @@ -8,8 +7,7 @@ def filter_part_of_directory(data): return [e for e in data if e['type'] != 'part_of_directory'] -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_file('xxx', '.a/1') create_file('xxx', '.b/1') create_file('xxx', '.1') @@ -22,8 +20,7 @@ def test_simple(): assert footer['duplicate_sets'] == 1 -@with_setup(usual_setup_func, usual_teardown_func) -def test_hidden(): +def test_hidden(usual_setup_usual_teardown): create_file('xxx', '.a/1') create_file('xxx', '.b/1') create_file('xxx', '.1') @@ -35,8 +32,7 @@ def test_hidden(): assert footer['duplicate_sets'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_explicit(): +def test_explicit(usual_setup_usual_teardown): create_file('xxx', '.a/1') create_file('xxx', '.a/2') head, *data, footer = run_rmlint('--no-hidden', dir_suffix='.a') @@ -47,8 +43,7 @@ def test_explicit(): assert footer['duplicate_sets'] == 1 -@with_setup(usual_setup_func, usual_teardown_func) -def test_partial_hidden(): +def test_partial_hidden(usual_setup_usual_teardown): create_file('1', 'a/.hidden') create_file('1', 'b/.hidden') create_file('1', '.hidden') diff --git a/tests/test_options/test_keep_hardlinks.py b/tests/test_options/test_keep_hardlinks.py index e9ffc44b6..e4d5d934e 100644 --- a/tests/test_options/test_keep_hardlinks.py +++ b/tests/test_options/test_keep_hardlinks.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_keep_hardlinks(): +def test_keep_hardlinks(usual_setup_usual_teardown): create_file('xxx', 'file_a') create_link('file_a', 'file_b') create_file('xxx', 'file_z') diff --git a/tests/test_options/test_km.py b/tests/test_options/test_km.py index c6cd2a62e..a24e1a4f6 100644 --- a/tests/test_options/test_km.py +++ b/tests/test_options/test_km.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_km(): +def test_km(usual_setup_usual_teardown): # create some dupes with different paths, names and mtimes: create_file('xxx', 'stuff/a') create_file('yyy', 'stuff/b') diff --git a/tests/test_options/test_match_basenames.py b/tests/test_options/test_match_basenames.py index d277003a4..c38df9c66 100644 --- a/tests/test_options/test_match_basenames.py +++ b/tests/test_options/test_match_basenames.py @@ -1,10 +1,8 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_negative_with_basename(): +def test_negative_with_basename(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('xxx', 'b') head, *data, footer = run_rmlint('-b') @@ -13,8 +11,7 @@ def test_negative_with_basename(): assert footer['duplicates'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_positive_with_basename(): +def test_positive_with_basename(usual_setup_usual_teardown): create_file('xxx', 'a/test') create_file('xxx', 'b/test') head, *data, footer = run_rmlint('-b') @@ -23,8 +20,7 @@ def test_positive_with_basename(): assert footer['duplicates'] == 1 -@with_setup(usual_setup_func, usual_teardown_func) -def test_negative_without_basename(): +def test_negative_without_basename(usual_setup_usual_teardown): create_file('xxx', 'a/test') create_file('xxx', 'b/test') head, *data, footer = run_rmlint('-B') @@ -33,8 +29,7 @@ def test_negative_without_basename(): assert footer['duplicates'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_positive_without_basename(): +def test_positive_without_basename(usual_setup_usual_teardown): create_file('xxx', 'a/test1') create_file('xxx', 'b/test2') head, *data, footer = run_rmlint('-B') diff --git a/tests/test_options/test_match_with_extension.py b/tests/test_options/test_match_with_extension.py index 092a90f1d..bd87bae9f 100644 --- a/tests/test_options/test_match_with_extension.py +++ b/tests/test_options/test_match_with_extension.py @@ -1,10 +1,8 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_negative(): +def test_negative(usual_setup_usual_teardown): create_file('xxx', 'a.png') create_file('xxx', 'b.jpg') create_file('xxx', 'b') @@ -14,8 +12,7 @@ def test_negative(): assert footer['duplicates'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_positive(): +def test_positive(usual_setup_usual_teardown): create_file('xxx', 'a.png') create_file('xxx', 'b.png') head, *data, footer = run_rmlint('-e') diff --git a/tests/test_options/test_match_without_extension.py b/tests/test_options/test_match_without_extension.py index 4c245b9df..e4c217d43 100644 --- a/tests/test_options/test_match_without_extension.py +++ b/tests/test_options/test_match_without_extension.py @@ -1,10 +1,8 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_negative(): +def test_negative(usual_setup_usual_teardown): create_file('xxx', 'b.png') create_file('xxx', 'a.png') create_file('xxx', 'a') @@ -14,8 +12,7 @@ def test_negative(): assert footer['duplicates'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_positive(): +def test_positive(usual_setup_usual_teardown): create_file('xxx', 'a.png') create_file('xxx', 'a.jpg') head, *data, footer = run_rmlint('-i') diff --git a/tests/test_options/test_merge_directories.py b/tests/test_options/test_merge_directories.py index 984d67be3..79e16fe85 100644 --- a/tests/test_options/test_merge_directories.py +++ b/tests/test_options/test_merge_directories.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * def filter_part_of_directory(data): return [entry for entry in data if entry["type"] != "part_of_directory"] -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_file('xxx', '1/a') create_file('xxx', '2/a') create_file('xxx', 'a') @@ -30,8 +28,7 @@ def test_simple(): assert data[1]['path'].endswith('1') -@with_setup(usual_setup_func, usual_teardown_func) -def test_diff(): +def test_diff(usual_setup_usual_teardown): create_file('xxx', '1/a') create_file('xxx', '2/a') create_file('xxx', '3/a') @@ -49,8 +46,7 @@ def test_diff(): assert data[1]['path'].endswith('1') -@with_setup(usual_setup_func, usual_teardown_func) -def test_same_but_not_dupe(): +def test_same_but_not_dupe(usual_setup_usual_teardown): create_file('xxx', '1/a') create_file('xxx', '2/a') create_file('xxx', '2/b') @@ -61,8 +57,7 @@ def test_same_but_not_dupe(): assert 0 == sum(find['type'] == 'duplicate_dir' for find in data) assert 3 == sum(find['type'] == 'duplicate_file' for find in data) -@with_setup(usual_setup_func, usual_teardown_func) -def test_hardlinks(): +def test_hardlinks(usual_setup_usual_teardown): create_file('xxx', '1/a') create_link('1/a', '1/link1') create_link('1/a', '1/link2') @@ -98,8 +93,7 @@ def test_hardlinks(): assert data[1]['path'].endswith('a') -@with_setup(usual_setup_func, usual_teardown_func) -def test_deep_simple(): +def test_deep_simple(usual_setup_usual_teardown): create_file('xxx', 'deep/a/b/c/d/1') create_file('xxx', 'deep/e/f/g/h/1') head, *data, footer = run_rmlint('-D -S a') @@ -112,8 +106,7 @@ def test_deep_simple(): assert len(data) == 2 -@with_setup(usual_setup_func, usual_teardown_func) -def test_deep_simple(): +def test_deep_simple(usual_setup_usual_teardown): create_file('xxx', 'd/a/1') create_file('xxx', 'd/b/empty') create_file('xxx', 'd/a/1') @@ -126,8 +119,7 @@ def test_deep_simple(): assert len(data) == 2 -@with_setup(usual_setup_func, usual_teardown_func) -def test_dirs_with_empty_files_only(): +def test_dirs_with_empty_files_only(usual_setup_usual_teardown): create_file('', 'a/empty') create_file('', 'b/empty') head, *data, footer = run_rmlint('-p -D -S a -T df,dd --size 0') @@ -162,8 +154,7 @@ def create_nested(root, letters): create_file('xxx', path) -@with_setup(usual_setup_func, usual_teardown_func) -def test_deep_full(): +def test_deep_full(usual_setup_usual_teardown): create_nested('deep', 'abcd') create_nested('deep', 'efgh') @@ -187,8 +178,7 @@ def test_deep_full(): assert data[idx + 2]['is_original'] == (idx == 0) -@with_setup(usual_setup_func, usual_teardown_func) -def test_deep_full_twice(): +def test_deep_full_twice(usual_setup_usual_teardown): create_nested('deep_a', 'abcd') create_nested('deep_a', 'efgh') create_nested('deep_b', 'abcd') @@ -233,8 +223,7 @@ def test_deep_full_twice(): assert not data[3]['is_original'] -@with_setup(usual_setup_func, usual_teardown_func) -def test_symlinks(): +def test_symlinks(usual_setup_usual_teardown): create_file('xxx', 'a/z') create_link('a/z', 'a/x', symlink=True) create_file('xxx', 'b/z') @@ -259,20 +248,7 @@ def test_symlinks(): assert not data[1]['is_original'] -def mount_bind_teardown_func(): - if runs_as_root(): - subprocess.call( - 'umount {dst}'.format( - dst=os.path.join(TESTDIR_NAME, 'a/b') - ), - shell=True - ) - - usual_teardown_func() - - -@with_setup(usual_setup_func, mount_bind_teardown_func) -def test_mount_binds(): +def test_mount_binds(usual_setup_mount_bind_teardown): if not runs_as_root(): return @@ -294,8 +270,7 @@ def test_mount_binds(): assert len(data) == 2 -@with_setup(usual_setup_func, usual_teardown_func) -def test_keepall_tagged(): +def test_keepall_tagged(usual_setup_usual_teardown): # Test for Issue #141: # https://github.com/sahib/rmlint/issues/141 # @@ -427,8 +402,7 @@ def do_test(km_opts, untagged_path, tagged_path): assert footer['duplicate_sets'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_equal_content_different_layout(): +def test_equal_content_different_layout(usual_setup_usual_teardown): # Different duplicates in different subdirs. create_file('xxx', "tree-a/sub2/x") create_file('yyy', "tree-a/sub1/y") @@ -452,8 +426,7 @@ def test_equal_content_different_layout(): assert point["type"] == "duplicate_file" -@with_setup(usual_setup_func, usual_teardown_func) -def test_nested_content_with_same_layout(): +def test_nested_content_with_same_layout(usual_setup_usual_teardown): create_nested('deep', 'xyzabc') create_nested('deep', 'uvwabc') diff --git a/tests/test_options/test_mtime_window.py b/tests/test_options/test_mtime_window.py index 1780ffa6d..1766a399c 100644 --- a/tests/test_options/test_mtime_window.py +++ b/tests/test_options/test_mtime_window.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose.plugins.attrib import attr -from nose import with_setup from tests.utils import * import os @@ -13,8 +11,7 @@ def set_mtime(path, mtime): subprocess.call(['touch', '-m', '-d', str(mtime), full_path]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_consider_mtime(): +def test_consider_mtime(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('xxx', 'b') create_file('xxx', 'c') @@ -54,8 +51,7 @@ def test_consider_mtime(): assert footer['duplicate_sets'] == 1 -@with_setup(usual_setup_func, usual_teardown_func) -def test_consider_mtime_subsecond(): +def test_consider_mtime_subsecond(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('xxx', 'b') @@ -74,8 +70,7 @@ def test_consider_mtime_subsecond(): head, *data, footer = run_rmlint('--mtime-window=0') assert len(data) == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_consider_mtime_fail_by_association(): +def test_consider_mtime_fail_by_association(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('yyy', 'b') create_file('xxx', 'c') @@ -92,8 +87,7 @@ def test_consider_mtime_fail_by_association(): assert footer['duplicates'] == 0 assert footer['duplicate_sets'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_mtime_and_unmatched_basenames(): +def test_mtime_and_unmatched_basenames(usual_setup_usual_teardown): create_file('xxx', 'dir1/a') create_file('xxx', 'dir1/c') create_file('xxx', 'dir2/a') diff --git a/tests/test_options/test_newer_than.py b/tests/test_options/test_newer_than.py index b74b50076..da5822f25 100644 --- a/tests/test_options/test_newer_than.py +++ b/tests/test_options/test_newer_than.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import time @@ -31,8 +30,7 @@ def create_set(create_stamp, iso8601=False): warp_file_to_future('c', 2) -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_set(False) now = time.time() head, *data, footer = run_rmlint_once('-S a -N ' + str(time.time())) @@ -50,8 +48,7 @@ def test_simple(): assert len(data) == expect -@with_setup(usual_setup_func, usual_teardown_func) -def test_stamp_file(): +def test_stamp_file(usual_setup_usual_teardown): create_set(True, False) # Wait 3 seconds, so the new stamp file (written by -n) @@ -66,8 +63,7 @@ def test_stamp_file(): assert len(data) == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_stamp_file_iso8601(): +def test_stamp_file_iso8601(usual_setup_usual_teardown): create_set(True, True) head, *data, footer = run_rmlint_once('-S a -n ' + os.path.join(TESTDIR_NAME, '.stamp-0')) diff --git a/tests/test_options/test_no_backup.py b/tests/test_options/test_no_backup.py index 5992ea96a..108c6e12b 100644 --- a/tests/test_options/test_no_backup.py +++ b/tests/test_options/test_no_backup.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import os @@ -9,8 +8,7 @@ import tempfile -@with_setup(usual_setup_func, usual_teardown_func) -def test_backup(): +def test_backup(usual_setup_usual_teardown): create_file('content', 'name_x') create_file('content', 'name_y') diff --git a/tests/test_options/test_pass_files.py b/tests/test_options/test_pass_files.py index 37740e6bc..e2eb0dfe7 100644 --- a/tests/test_options/test_pass_files.py +++ b/tests/test_options/test_pass_files.py @@ -1,12 +1,10 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import json -@with_setup(usual_setup_func, usual_teardown_func) -def test_stdin_read(): +def test_stdin_read(usual_setup_usual_teardown): path_a = create_file('1234', 'a') path_b = create_file('1234', 'b') path_c = create_file('1234', '.hidden') diff --git a/tests/test_options/test_perms.py b/tests/test_options/test_perms.py index b734584a9..114dce831 100644 --- a/tests/test_options/test_perms.py +++ b/tests/test_options/test_perms.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import stat @@ -23,8 +22,7 @@ def create_file_with_perms(content, path, permissions): os.chmod(os.path.join(TESTDIR_NAME, path), perms) -@with_setup(usual_setup_func, usual_teardown_func) -def test_combinations(): +def test_combinations(usual_setup_usual_teardown): # This test does not work when run as root. # root can read the files anyways. if runs_as_root(): diff --git a/tests/test_options/test_rankby.py b/tests/test_options/test_rankby.py index 8b311f282..c2ec1248c 100644 --- a/tests/test_options/test_rankby.py +++ b/tests/test_options/test_rankby.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 # encoding: utf-8 import os -from nose import with_setup from tests.utils import * @@ -9,8 +8,7 @@ def filter_part_of_directory(data): return [e for e in data if e['type'] != 'part_of_directory'] -@with_setup(usual_setup_func, usual_teardown_func) -def test_rankby_simple(): +def test_rankby_simple(usual_setup_usual_teardown): create_file('x', 'ax') create_file('x', 'ay') create_file('yyy', 'bx') @@ -25,8 +23,7 @@ def test_rankby_simple(): assert paths == ['by', 'bx', 'ay', 'ax'] -@with_setup(usual_setup_func, usual_teardown_func) -def test_rankby_dirs(): +def test_rankby_dirs(usual_setup_usual_teardown): create_file('x', 'ax') create_file('x', 'ay') create_file('yyy', 'b/x') diff --git a/tests/test_options/test_replay.py b/tests/test_options/test_replay.py index 067f14ff2..1abfdc740 100644 --- a/tests/test_options/test_replay.py +++ b/tests/test_options/test_replay.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup -from nose.plugins.attrib import attr +import pytest from tests.utils import * import time @@ -63,8 +62,7 @@ def validate_order(data, tests): assert False -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_match_basename(): +def test_replay_match_basename(usual_setup_usual_teardown): create_file('xxx', 'test1/a') create_file('xxx', 'test1/b') create_file('xxx', 'test2/a') @@ -99,8 +97,7 @@ def test_replay_match_basename(): assert len(data) == 3 -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_hidden(): +def test_replay_hidden(usual_setup_usual_teardown): create_file('xxx', 'test/.a') create_file('xxx', 'test/.b') @@ -125,8 +122,7 @@ def test_replay_hidden(): assert len(data) == 2 -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_must_match_tagged(): +def test_replay_must_match_tagged(usual_setup_usual_teardown): create_file('xxx', 'test_a/a') create_file('xxx', 'test_b/a') @@ -149,9 +145,8 @@ def test_replay_must_match_tagged(): assert (os.path.join(TESTDIR_NAME, 'test_a/a'), True) in paths -@attr('slow') -@with_setup(usual_setup_func, usual_teardown_func) -def test_sorting(): +@pytest.mark.slow +def test_sorting(usual_setup_usual_teardown): # create some dupes with different PATHS, names and mtimes: create_file('xxx', PATHS[0] + 'a') create_file('xxx', PATHS[1] + 'bb') @@ -204,8 +199,7 @@ def test_sorting(): validate_order(data, combo) -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_no_dir(): +def test_replay_no_dir(usual_setup_usual_teardown): # Regression test for #305. # --replay did not replay anything when not specifying some path. # (The current working directory was not set in this case correctly) @@ -234,8 +228,7 @@ def test_replay_no_dir(): os.chdir(current_cwd) -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_unicode_fuckup(): +def test_replay_unicode_fuckup(usual_setup_usual_teardown): names = '上野洋子, 吉野裕司, 浅井裕子 & 河越重義', '天谷大輔', 'Аркона' create_file('xxx', names[0]) @@ -253,8 +246,7 @@ def test_replay_unicode_fuckup(): assert set([os.path.basename(e['path']) for e in data]) == set(names) -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_tagged_order(): +def test_replay_tagged_order(usual_setup_usual_teardown): create_file('xxx', 'a/1') create_file('xxx', 'a/2') create_file('xxx', 'b/1') @@ -321,8 +313,7 @@ def test_replay_tagged_order(): assert data[3]['path'].endswith('a/2') -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_duplicate_directory_size(): +def test_replay_duplicate_directory_size(usual_setup_usual_teardown): create_file('xxx', 'a/xxx') create_file('xxx', 'b/xxx') @@ -422,8 +413,7 @@ def data_by_type(data): } -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_pack_directories(): +def test_replay_pack_directories(usual_setup_usual_teardown): create_pack_and_unpack_scenario() # Do a run without -D and pack it later during --replay. @@ -444,8 +434,7 @@ def test_replay_pack_directories(): assert data_by_type(data) == EXPECTED_WITH_TREEMERGE -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_unpack_directories(): +def test_replay_unpack_directories(usual_setup_usual_teardown): create_pack_and_unpack_scenario() # Do a run with -D and pack it later during --replay. diff --git a/tests/test_options/test_size.py b/tests/test_options/test_size.py index 51de398d8..e2c632242 100644 --- a/tests/test_options/test_size.py +++ b/tests/test_options/test_size.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * @@ -11,8 +10,7 @@ def create_set(): create_file('x' * 512, 'small' + suffix) -@with_setup(usual_setup_func, usual_teardown_func) -def test_valid(): +def test_valid(usual_setup_usual_teardown): create_set() # Scalar: @@ -47,8 +45,7 @@ def test_valid(): *_, footer = run_rmlint('--size 1-18446744073709551615') assert footer['duplicates'] == 6 -@with_setup(usual_setup_func, usual_teardown_func) -def test_invalid(): +def test_invalid(usual_setup_usual_teardown): create_set() def trigger(*args): @@ -80,8 +77,7 @@ def trigger(*args): -@with_setup(usual_setup_func, usual_teardown_func) -def test_replay_size(): +def test_replay_size(usual_setup_usual_teardown): create_file('', 'empty1') create_file('', 'empty2') create_file('xxx', 'a/xxx') diff --git a/tests/test_options/test_sorting.py b/tests/test_options/test_sorting.py index cbb3e28ff..726e52012 100644 --- a/tests/test_options/test_sorting.py +++ b/tests/test_options/test_sorting.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup -from nose.plugins.attrib import attr +import pytest from tests.utils import * from itertools import permutations, combinations @@ -53,9 +52,8 @@ def validate_order(data, tests): assert False -@attr('slow') -@with_setup(usual_setup_func, usual_teardown_func) -def test_sorting(): +@pytest.mark.slow +def test_sorting(usual_setup_usual_teardown): # create some dupes with different PATHS, names and mtimes: create_file('xxx', PATHS[1] + 'a', mtime='2004-02-29 16:21:42.4') create_file('xxx', PATHS[0] + 'c', mtime='2004-02-29 16:21:42.6') @@ -88,8 +86,7 @@ def test_sorting(): validate_order(data, combo) -@with_setup(usual_setup_func, usual_teardown_func) -def test_sort_by_outlyer(): +def test_sort_by_outlyer(usual_setup_usual_teardown): create_file('xxx', 'a/foo') create_file('xxx', 'b/foo') @@ -110,8 +107,7 @@ def test_sort_by_outlyer(): # https://github.com/sahib/rmlint/issues/196 # # Testsetup by "Awerick" -@with_setup(usual_setup_func, usual_teardown_func) -def test_sort_by_outlyer_hardcore(): +def test_sort_by_outlyer_hardcore(usual_setup_usual_teardown): for suffix in 'ABCD': create_file('xxx', 'inside/foo' + suffix) @@ -152,8 +148,7 @@ def run_inside_job(crit): -@with_setup(usual_setup_func, usual_teardown_func) -def test_sort_by_regex(): +def test_sort_by_regex(usual_setup_usual_teardown): create_file('xxx', 'aaaa') create_file('xxx', 'aaab') create_file('xxx', 'b') @@ -173,8 +168,7 @@ def test_sort_by_regex(): assert paths[5].endswith('c') -@with_setup(usual_setup_func, usual_teardown_func) -def test_sort_by_regex_bad_input(): +def test_sort_by_regex_bad_input(usual_setup_usual_teardown): create_file('xxx', 'aaaa') create_file('xxx', 'aaab') diff --git a/tests/test_options/test_stdin.py b/tests/test_options/test_stdin.py index c422c3958..9c9f11542 100644 --- a/tests/test_options/test_stdin.py +++ b/tests/test_options/test_stdin.py @@ -1,16 +1,14 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * from subprocess import STDOUT, check_output -from parameterized import parameterized import json import os +import pytest -@with_setup(usual_setup_func, usual_teardown_func) -def test_stdin_read(): +def test_stdin_read(usual_setup_usual_teardown): path_a = create_file('1234', 'a') + '\n' path_b = create_file('1234', 'b') + '\n' path_c = create_file('1234', '.hidden') + '\n' @@ -33,8 +31,7 @@ def test_stdin_read(): assert data[3]['path'].endswith('c') assert footer['total_lint_size'] == 12 -@with_setup(usual_setup_func, usual_teardown_func) -def test_stdin_read_newlines(): +def test_stdin_read_newlines(usual_setup_usual_teardown): path_a = create_file('1234', 'a') + '\0' path_b = create_file('1234', 'name\nwith\nnewlines') + '\0' path_c = create_file('1234', '.hidden') + '\0' @@ -57,8 +54,7 @@ def test_stdin_read_newlines(): assert data[3]['path'].endswith('newlines') assert footer['total_lint_size'] == 12 -@with_setup(usual_setup_func, usual_teardown_func) -def test_path_starting_with_dash(): +def test_path_starting_with_dash(usual_setup_usual_teardown): subdir = '-look-in-here' create_file('1234', subdir + '/a') create_file('1234', subdir + '/b') @@ -82,9 +78,8 @@ def test_path_starting_with_dash(): # Regression test for https://github.com/sahib/rmlint/issues/400 # Do not search in current directory when piped empty input. -@parameterized([("-", ), ("-0", )]) -@with_setup(usual_setup_func, usual_teardown_func) -def test_stdin_empty(stdin_opt): +@pytest.mark.parametrize("stdin_opt", ["-", "-0"]) +def test_stdin_empty(usual_setup_usual_teardown, stdin_opt): create_file('1234', 'a') create_file('1234', 'b') diff --git a/tests/test_options/test_symlinks.py b/tests/test_options/test_symlinks.py index 7cc559679..55a6ac69f 100644 --- a/tests/test_options/test_symlinks.py +++ b/tests/test_options/test_symlinks.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_default(): +def test_default(usual_setup_usual_teardown): # --see-symlinks should be on by default. create_file('xxx', 'a/z') create_link('a/z', 'a/x', symlink=True) @@ -21,8 +19,7 @@ def test_default(): '/a/z', } -@with_setup(usual_setup_func, usual_teardown_func) -def test_merge_directories_with_ignored_symlinks(): +def test_merge_directories_with_ignored_symlinks(usual_setup_usual_teardown): # Badlinks should not forbid finding duplicate directories # when being filtered out during traversing with -T dd,df. create_file('xxx', 'a/z') @@ -36,8 +33,7 @@ def test_merge_directories_with_ignored_symlinks(): '/b', } -@with_setup(usual_setup_func, usual_teardown_func) -def test_order(): +def test_order(usual_setup_usual_teardown): create_file('xxx', 'a/z') create_link('a/z', 'a/x', symlink=True) create_file('xxx', 'b/z') diff --git a/tests/test_robustness/test_8Mlongpathfiles.py b/tests/test_robustness/test_8Mlongpathfiles.py index 77b3708d5..3652147a9 100644 --- a/tests/test_robustness/test_8Mlongpathfiles.py +++ b/tests/test_robustness/test_8Mlongpathfiles.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose.plugins.attrib import attr -from nose import with_setup +import pytest from tests.utils import * import sys @@ -25,9 +24,8 @@ def branch_tree(current_path, remaining_depth): create_link(current_path + 'b' + str(i).zfill(7), current_path + 'h' + str(i).zfill(7)) -@attr('slow') -@with_setup(usual_setup_func, usual_teardown_func) -def test_manylongpathfiles(): +@pytest.mark.slow +def test_manylongpathfiles(usual_setup_usual_teardown): max_depth = 10 # will give 8M files total if NUMPAIRS = 1024+1 branch_tree ("", max_depth) diff --git a/tests/test_robustness/test_badlinks_as_args.py b/tests/test_robustness/test_badlinks_as_args.py index 981e1a004..5c6dd67c0 100644 --- a/tests/test_robustness/test_badlinks_as_args.py +++ b/tests/test_robustness/test_badlinks_as_args.py @@ -1,13 +1,11 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * # Regression test for directly passing broken symbolic links # to the command line. See https://github.com/sahib/rmlint/pull/444 -@with_setup(usual_setup_func, usual_teardown_func) -def test_bad_symlinks_as_direct_args(): +def test_bad_symlinks_as_direct_args(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('xxx', 'b') diff --git a/tests/test_robustness/test_bigfiles.py b/tests/test_robustness/test_bigfiles.py index fd2755b21..23543b04a 100644 --- a/tests/test_robustness/test_bigfiles.py +++ b/tests/test_robustness/test_bigfiles.py @@ -1,15 +1,12 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose.plugins.attrib import attr -from nose import with_setup from tests.utils import * FILE_SIZE_KB = 10000 DIFFERENT_BYTES = 1 KBYTES_FROM_END = 10 -@with_setup(usual_setup_func, usual_teardown_func) -def test_bigfiles(): +def test_bigfiles(usual_setup_usual_teardown): num_bytes = int(FILE_SIZE_KB * 1024) # create two identical files and a third one which differs near the end: diff --git a/tests/test_robustness/test_collisions.py b/tests/test_robustness/test_collisions.py index 0d729bff2..9eb8ce057 100644 --- a/tests/test_robustness/test_collisions.py +++ b/tests/test_robustness/test_collisions.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose.plugins.attrib import attr -from nose import with_setup +import pytest from tests.utils import * @@ -11,9 +10,8 @@ # which degenerates into an inefficient O(n^2) lookup with large size groups BLACKLIST = ['paranoid'] -@attr('slow') -@with_setup(usual_setup_func, usual_teardown_func) -def test_collision_resistance(): +@pytest.mark.slow +def test_collision_resistance(usual_setup_usual_teardown): # test for at least 20 bits of collision resistancel # this should detect gross errors in checksum encoding... diff --git a/tests/test_robustness/test_manyfiles.py b/tests/test_robustness/test_manyfiles.py index 6cce3773f..b3e2f0ec9 100644 --- a/tests/test_robustness/test_manyfiles.py +++ b/tests/test_robustness/test_manyfiles.py @@ -1,12 +1,10 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose.plugins.attrib import attr -from nose import with_setup +import pytest from tests.utils import * -@attr('slow') -@with_setup(usual_setup_func, usual_teardown_func) -def test_manyfiles(): +@pytest.mark.slow +def test_manyfiles(usual_setup_usual_teardown): # create heaps of identical files: numfiles = 1024 * 32 + 1 diff --git a/tests/test_robustness/test_manylongpathfiles.py b/tests/test_robustness/test_manylongpathfiles.py index 35981f0b9..2a0b19b90 100644 --- a/tests/test_robustness/test_manylongpathfiles.py +++ b/tests/test_robustness/test_manylongpathfiles.py @@ -1,12 +1,10 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose.plugins.attrib import attr -from nose import with_setup +import pytest from tests.utils import * -@attr('slow') -@with_setup(usual_setup_func, usual_teardown_func) -def test_manylongpathfiles(): +@pytest.mark.slow +def test_manylongpathfiles(usual_setup_usual_teardown): #create ~1000 character path, 4 dirs deep longpath = ("long" * (1000//4//4) + "/") * 4 diff --git a/tests/test_robustness/test_path_doubles.py b/tests/test_robustness/test_path_doubles.py index 6fee84952..f9f61aff1 100644 --- a/tests/test_robustness/test_path_doubles.py +++ b/tests/test_robustness/test_path_doubles.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_cmdline(): +def test_cmdline(usual_setup_usual_teardown): create_file('xxx', '1/a') # feed rmlint the same file twice via command line head, *data, footer = run_rmlint('{t}/1 {t}/1'.format(t=TESTDIR_NAME), use_default_dir=False) @@ -18,8 +16,7 @@ def test_cmdline(): assert 0 == sum(find['type'] == 'duplicate_file' for find in data) -@with_setup(usual_setup_func, usual_teardown_func) -def test_symlink_noloop(): +def test_symlink_noloop(usual_setup_usual_teardown): create_file('xxx', '1/a') create_link('1/a', '1/link', symlink=True) @@ -35,8 +32,7 @@ def test_symlink_noloop(): head, *data, footer = run_rmlint('{t}/1/a {t}/1/link'.format(t=TESTDIR_NAME), use_default_dir=False) assert 0 == sum(find['type'] == 'duplicate_file' for find in data) -@with_setup(usual_setup_func, usual_teardown_func) -def test_symlink_loop(): +def test_symlink_loop(usual_setup_usual_teardown): create_file('xxx', '1/a') create_link('1', '1/link', symlink=True) @@ -47,19 +43,7 @@ def test_symlink_loop(): assert 0 == sum(find['type'] == 'duplicate_file' for find in data) -def mount_bind_teardown_func(): - if runs_as_root(): - subprocess.call( - 'umount {dst}'.format( - dst=os.path.join(TESTDIR_NAME, 'a/b') - ), - shell=True - ) - - usual_teardown_func() - -@with_setup(usual_setup_func, mount_bind_teardown_func) -def test_mount_binds(): +def test_mount_binds(usual_setup_mount_bind_teardown): if not runs_as_root(): return diff --git a/tests/test_types/test_badlink.py b/tests/test_types/test_badlink.py index 7d16f097c..2baa14a02 100644 --- a/tests/test_types/test_badlink.py +++ b/tests/test_types/test_badlink.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import os @@ -17,8 +16,7 @@ def create_bad_link(link_name): os.remove(fake_target) -@with_setup(usual_setup_func, usual_teardown_func) -def test_basic(): +def test_basic(usual_setup_usual_teardown): create_bad_link('imbad') for option in ('-f', '-F', '--see-symlinks'): diff --git a/tests/test_types/test_baduids.py b/tests/test_types/test_baduids.py index f1ac5c556..41fab7791 100644 --- a/tests/test_types/test_baduids.py +++ b/tests/test_types/test_baduids.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import subprocess @@ -24,8 +23,7 @@ def exec_cmds(cmds): print(cmd, 'failed:', err) -@with_setup(usual_setup_func, usual_teardown_func) -def test_bad_ids(): +def test_bad_ids(usual_setup_usual_teardown): if not runs_as_root(): return diff --git a/tests/test_types/test_duplicate.py b/tests/test_types/test_duplicate.py index 711d24091..bace4d94d 100644 --- a/tests/test_types/test_duplicate.py +++ b/tests/test_types/test_duplicate.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import os @@ -13,8 +12,7 @@ def create_data(len, flips=None): return ''.join(data) -@with_setup(usual_setup_func, usual_teardown_func) -def test_small_diffs(): +def test_small_diffs(usual_setup_usual_teardown): if use_valgrind(): N = 32 @@ -51,8 +49,7 @@ def test_small_diffs(): assert len(data) == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_one_byte_file_negative(): +def test_one_byte_file_negative(usual_setup_usual_teardown): create_file('1', 'one') create_file('2', 'two') head, *data, footer = run_rmlint('-S a') @@ -60,16 +57,14 @@ def test_one_byte_file_negative(): assert len(data) == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_one_byte_file_positive(): +def test_one_byte_file_positive(usual_setup_usual_teardown): create_file('1', 'one') create_file('1', 'two') head, *data, footer = run_rmlint('-S a') assert len(data) == 2 -@with_setup(usual_setup_func, usual_teardown_func) -def test_two_hardlinks(): +def test_two_hardlinks(usual_setup_usual_teardown): create_file('xxx', 'a') create_link('a', 'b') head, *data, footer = run_rmlint('-S a') @@ -77,8 +72,7 @@ def test_two_hardlinks(): assert len(data) == 2 assert footer['total_lint_size'] == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_two_external_hardlinks(): +def test_two_external_hardlinks(usual_setup_usual_teardown): create_file('xxx', 'a') create_file('xxx', 'b') create_dirs('sub') diff --git a/tests/test_types/test_empty_dirs.py b/tests/test_types/test_empty_dirs.py index 1ff52fc3c..bf22714ce 100644 --- a/tests/test_types/test_empty_dirs.py +++ b/tests/test_types/test_empty_dirs.py @@ -1,11 +1,8 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * - -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_file('xxx', 'not_empty/a') create_file('', 'empty_but_with_file/a') create_dirs('really_empty') @@ -21,8 +18,7 @@ def test_simple(): assert data[1]['type'] == "emptyfile" -@with_setup(usual_setup_func, usual_teardown_func) -def test_deep(): +def test_deep(usual_setup_usual_teardown): create_dirs('1/2/3/4/5') head, *data, footer = run_rmlint('-T "none +ed"') @@ -39,8 +35,7 @@ def test_deep(): assert data[1]['path'].endswith('4') -@with_setup(usual_setup_func, usual_teardown_func) -def test_hidden(): +def test_hidden(usual_setup_usual_teardown): create_file('xxx', 'not_empty/.hidden') head, *data, footer = run_rmlint('-T "none +ed"') diff --git a/tests/test_types/test_empty_files.py b/tests/test_types/test_empty_files.py index 0bb277434..b314e268c 100644 --- a/tests/test_types/test_empty_files.py +++ b/tests/test_types/test_empty_files.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * -@with_setup(usual_setup_func, usual_teardown_func) -def test_simple(): +def test_simple(usual_setup_usual_teardown): create_file('xxx', 'not_empty') create_file('', 'very_empty') head, *data, footer = run_rmlint('-T "none +ef"') diff --git a/tests/test_types/test_nonstripped.py b/tests/test_types/test_nonstripped.py index a18648c98..7e1d1987f 100644 --- a/tests/test_types/test_nonstripped.py +++ b/tests/test_types/test_nonstripped.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # encoding: utf-8 -from nose import with_setup from tests.utils import * import os @@ -27,8 +26,7 @@ def create_binary(path, stripped=False): subprocess.call(command, shell=True) -@with_setup(usual_setup_func, usual_teardown_func) -def test_negative(): +def test_negative(usual_setup_usual_teardown): if has_feature('nonstripped') is False: return @@ -40,8 +38,7 @@ def test_negative(): assert len(data) == 0 -@with_setup(usual_setup_func, usual_teardown_func) -def test_positive(): +def test_positive(usual_setup_usual_teardown): if has_feature('nonstripped') is False: return diff --git a/tests/utils.py b/tests/utils.py index 33487f4db..b130492f6 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -357,6 +357,17 @@ def usual_teardown_func(): pass +def mount_bind_teardown_func(): + if runs_as_root(): + subprocess.call( + 'umount {dst}'.format( + dst=os.path.join(TESTDIR_NAME, 'a/b') + ), + shell=True + ) + + usual_teardown_func() + @contextlib.contextmanager def create_special_fs(name, fs_type='ext4'): """