diff --git a/.builds/archlinux.yaml b/.builds/archlinux.yaml new file mode 100644 index 0000000..35a7d7a --- /dev/null +++ b/.builds/archlinux.yaml @@ -0,0 +1,39 @@ +image: archlinux +packages: + - docker + - docker-compose + # Build dependencies: + - python-pip + - python-wheel + # Runtime dependencies: + - python-atomicwrites + - python-click + - python-click-log + - python-click-threading + - python-requests + - python-requests-toolbelt + # Test dependencies: + - python-hypothesis + - python-pytest-cov + - python-pytest-localserver +sources: + - https://github.com/pimutils/vdirsyncer +environment: + BUILD: test + CI: true + CODECOV_TOKEN: b834a3c5-28fa-4808-9bdb-182210069c79 + REQUIREMENTS: release + # TODO: ETESYNC_TESTS +tasks: + - setup: | + cd vdirsyncer + sudo systemctl start docker + sudo python setup.py install + DAV_SERVER="radicale xandikos" make -e install-servers + - test: | + cd vdirsyncer + # Non-system python is used for packages: + export PATH=$PATH:~/.local/bin/ + make -e ci-test + DAV_SERVER=radicale make -e ci-test-storage + DAV_SERVER=xandikos make -e ci-test-storage diff --git a/test-requirements.txt b/test-requirements.txt index a9388a3..a2c57f0 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,4 @@ -hypothesis>=5.0.0,<6.0.0 +hypothesis>=5.0.0,<7.0.0 pytest pytest-cov pytest-localserver diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py index a2e0022..35c3d06 100644 --- a/tests/storage/__init__.py +++ b/tests/storage/__init__.py @@ -4,9 +4,8 @@ import uuid from urllib.parse import quote as urlquote from urllib.parse import unquote as urlunquote -import hypothesis.strategies as st import pytest -from hypothesis import given +from hypothesis import settings from .. import assert_item_equals from .. import EVENT_TEMPLATE @@ -299,10 +298,14 @@ class StorageTests: assert rv == x assert isinstance(rv, str) - @given(value=st.one_of( - st.none(), - printable_characters_strategy - )) + @pytest.mark.parametrize( + "value", + [None] + + [ + printable_characters_strategy.example() + for _ in range(settings.get_profile(settings._current_profile).max_examples) + ], + ) def test_metadata_normalization(self, requires_metadata, s, value): x = s.get_meta('displayname') assert x == normalize_meta_value(x) diff --git a/tests/system/cli/test_discover.py b/tests/system/cli/test_discover.py index 6355232..20b6e84 100644 --- a/tests/system/cli/test_discover.py +++ b/tests/system/cli/test_discover.py @@ -1,8 +1,7 @@ import json from textwrap import dedent -import hypothesis.strategies as st -from hypothesis import given +import pytest from vdirsyncer import exceptions from vdirsyncer.storage.base import Storage @@ -176,7 +175,15 @@ def test_null_collection_with_named_collection(tmpdir, runner): assert 'HAHA' in bar.read() -@given(a_requires=st.booleans(), b_requires=st.booleans()) +@pytest.mark.parametrize( + "a_requires,b_requires", + [ + (True, True), + (True, False), + (False, True), + (False, False), + ] +) def test_collection_required(a_requires, b_requires, tmpdir, runner, monkeypatch): diff --git a/tests/system/cli/test_sync.py b/tests/system/cli/test_sync.py index 88163ed..cc37297 100644 --- a/tests/system/cli/test_sync.py +++ b/tests/system/cli/test_sync.py @@ -4,8 +4,7 @@ from textwrap import dedent import hypothesis.strategies as st import pytest -from hypothesis import example -from hypothesis import given +from hypothesis import settings def test_simple_run(tmpdir, runner): @@ -271,13 +270,7 @@ def test_multiple_pairs(tmpdir, runner): } -hack = 0 - - -# XXX: https://github.com/pimutils/vdirsyncer/issues/617 -@pytest.mark.skipif(sys.platform == 'darwin', - reason='This test inexplicably fails') -@given(collections=st.sets( +collections_strategy = st.sets( st.text( st.characters( blacklist_characters=set( @@ -290,18 +283,28 @@ hack = 0 max_size=50 ), min_size=1 -)) -@example(collections=['persönlich']) -@example(collections={'a', 'A'}) -@example(collections={'\ufffe'}) +) + + +# XXX: https://github.com/pimutils/vdirsyncer/issues/617 +@pytest.mark.skipif(sys.platform == 'darwin', + reason='This test inexplicably fails') +@pytest.mark.parametrize( + "collections", + [ + ('persönlich',), + ('a', 'A',), + ('\ufffe',), + ] + [ + collections_strategy.example() + for _ in range(settings.get_profile(settings._current_profile).max_examples) + ] +) def test_create_collections(collections, tmpdir, runner): # Hypothesis calls this tests in a way that fixtures are not reset, to tmpdir is the # same for each call. # This horrible hack creates a new subdirectory on each run, effectively giving us a # new tmpdir each run. - global hack - hack += 1 - tmpdir = tmpdir / f"sub{hack}" runner.write_with_general(dedent(''' [pair foobar] diff --git a/tests/unit/cli/test_fetchparams.py b/tests/unit/cli/test_fetchparams.py index 664df5f..06e7ae6 100644 --- a/tests/unit/cli/test_fetchparams.py +++ b/tests/unit/cli/test_fetchparams.py @@ -1,3 +1,6 @@ +from contextlib import contextmanager +from unittest.mock import patch + import hypothesis.strategies as st import pytest from hypothesis import given @@ -17,6 +20,17 @@ def mystrategy(monkeypatch): return calls +@contextmanager +def dummy_strategy(): + def strategy(x): + calls.append(x) + return x + + calls = [] + with patch.dict(STRATEGIES, {"mystrategy": strategy}): + yield calls + + @pytest.fixture def value_cache(monkeypatch): _cache = {} @@ -45,10 +59,9 @@ def test_key_conflict(monkeypatch, mystrategy): @given(s=st.text(), t=st.text(min_size=1)) -def test_fuzzing(s, t, mystrategy): - config = expand_fetch_params({ - f'{s}.fetch': ['mystrategy', t] - }) +def test_fuzzing(s, t): + with dummy_strategy(): + config = expand_fetch_params({f"{s}.fetch": ["mystrategy", t]}) assert config[s] == t diff --git a/tests/unit/sync/test_status.py b/tests/unit/sync/test_status.py index 6d7b549..cce3e65 100644 --- a/tests/unit/sync/test_status.py +++ b/tests/unit/sync/test_status.py @@ -1,18 +1,10 @@ import hypothesis.strategies as st -import pytest from hypothesis import assume from hypothesis import given from vdirsyncer.sync.status import SqliteStatus -@pytest.fixture(params=[ - SqliteStatus -]) -def new_status(request): - return request.param - - status_dict_strategy = st.dictionaries( st.text(), st.tuples(*( @@ -26,11 +18,11 @@ status_dict_strategy = st.dictionaries( @given(status_dict=status_dict_strategy) -def test_legacy_status(new_status, status_dict): +def test_legacy_status(status_dict): hrefs_a = {meta_a['href'] for meta_a, meta_b in status_dict.values()} hrefs_b = {meta_b['href'] for meta_a, meta_b in status_dict.values()} assume(len(hrefs_a) == len(status_dict) == len(hrefs_b)) - status = new_status() + status = SqliteStatus() status.load_legacy_status(status_dict) assert dict(status.to_legacy_status()) == status_dict