diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ea76e7..85d42c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,13 @@ This project should more or less adhere to [Semantic Versioning](https://semver. ### Changed -* Test framework has been refactored a bit. Code for setting up and rigging down xandikos/radicale servers have been moved from `tests/test_caldav.py` to `tests/conf.py`. This allows for: +#### Test framework + +* Functional test framework has been refactored - code for setting up and rigging down xandikos/radicale servers have been moved from `tests/test_caldav.py` to `tests/conf.py`. This allows for: * Adding code (including system calls or remote API calls) for Setting up and tearing down calendar servers in `conf_private.py` * Creating a local xandikos or radicale server in the `tests.client`-method, which is also used in the `examples`-section. * Allows offline testing of my upcoming `check_server_compatibility`-script +* Also added the possibility to tag test servers with a name ### Added diff --git a/tests/compatibility_issues.py b/tests/compatibility_issues.py index fbfbb8f..e8d532c 100644 --- a/tests/compatibility_issues.py +++ b/tests/compatibility_issues.py @@ -13,7 +13,7 @@ ## * Consider how to get this into the documentation incompatibility_description = { 'rate_limited': - """Pause a bit between each request""", + """It may be needed to pause a bit between each request when doing tests""", 'cleanup_calendar': """Remove everything on the calendar for every test""", @@ -228,8 +228,10 @@ 'text_search_is_exact_match_only', - ## This one is fixed in master branch - 'category_search_yields_nothing', ## https://github.com/jelmer/xandikos/pull/194 + ## This one is fixed - but still breaks our test code for python 3.7 + ## TODO: remove this when shredding support for python 3.7 + ## https://github.com/jelmer/xandikos/pull/194 + 'category_search_yields_nothing', ## scheduling is not supported "no_scheduling", @@ -240,7 +242,6 @@ ## "weird" on radicale "broken_expand", "no_default_calendar", - "non_existing_calendar_found", ## freebusy is not supported yet, but on the long-term road map "no_freebusy_rfc4791", diff --git a/tests/conf.py b/tests/conf.py index b34f35e..14e4926 100644 --- a/tests/conf.py +++ b/tests/conf.py @@ -133,6 +133,7 @@ def teardown_radicale(self): caldav_servers.append( { "url": url, + "name": "LocalRadicale", "username": "user1", "password": "any-password-seems-to-work", "backwards_compatibility_url": url + "user1", @@ -218,6 +219,7 @@ def silly_request(): url = "http://%s:%i/" % (xandikos_host, xandikos_port) caldav_servers.append( { + "name": "LocalXandikos", "url": url, "backwards_compatibility_url": url + "sometestuser", "incompatibilities": compatibility_issues.xandikos, @@ -234,15 +236,24 @@ def silly_request(): ) -def client(idx=None, setup=lambda conn: None, teardown=lambda conn: None, **kwargs): +def client( + idx=None, name=None, setup=lambda conn: None, teardown=lambda conn: None, **kwargs +): ## No parameters given - find the first server in caldav_servers list - if idx is None and not kwargs: + if idx is None and not kwargs and caldav_servers: idx = 0 while idx < len(caldav_servers) and not caldav_servers[idx].get("enable", True): idx += 1 + if idx == len(caldav_servers): + return None return client(idx=idx) elif idx is not None and not kwargs and caldav_servers: return client(**caldav_servers[idx]) + elif name is not None and not kwargs and caldav_servers: + for s in caldav_servers: + if caldav_servers["name"] == s: + return s + return None elif not kwargs: return None for bad_param in ( diff --git a/tests/conf_private.py.EXAMPLE b/tests/conf_private.py.EXAMPLE index 39ecac9..f6478da 100644 --- a/tests/conf_private.py.EXAMPLE +++ b/tests/conf_private.py.EXAMPLE @@ -10,6 +10,11 @@ from tests import compatibility_issues ## Define your primary caldav server here caldav_servers = [ { + ## A friendly identifiter for the server. Should be a CamelCase name + ## Not needed, but may be nice if you have several servers to test towards. + ## Should not affect test runs in any other way than improved verbosity. + 'name': 'MyExampleServer' + ## Set enable to False if you don't want to use a server 'enable': True, diff --git a/tests/test_caldav.py b/tests/test_caldav.py index 2e78874..829345f 100644 --- a/tests/test_caldav.py +++ b/tests/test_caldav.py @@ -848,7 +848,7 @@ def testProxy(self): threadobj = threading.Thread(target=proxy_httpd.serve_forever) conn_params = self.server_params.copy() - for special in ("setup", "teardown"): + for special in ("setup", "teardown", "name"): if special in conn_params: conn_params.pop(special) try: @@ -1688,7 +1688,7 @@ def testWrongPassword(self): "Testing with wrong password skipped as calendar server does not require a password" ) connect_params = self.server_params.copy() - for delme in ("url", "setup", "teardown", "name"): + for delme in ("setup", "teardown", "name"): if delme in connect_params: connect_params.pop(delme) connect_params["password"] = ( @@ -2836,23 +2836,26 @@ def testObjects(self): # (maybe a custom nose test loader really would be the better option?) # -- Tobias Brox , 2013-10-10 -## TODO: can we use @pytest.mark.parametrize to run the collection of tests -## above on each of the servers defined in caldav_servers? +## TODO: The better way is probably to use @pytest.mark.parametrize ## -- Tobias Brox , 2024-11-15 _servernames = set() for _caldav_server in caldav_servers: - # create a unique identifier out of the server domain name - _parsed_url = urlparse(_caldav_server["url"]) - _servername = _parsed_url.hostname.replace(".", "_").replace("-", "_") + str( - _parsed_url.port or "" - ) - while _servername in _servernames: - _servername = _servername + "_" - _servernames.add(_servername) + if "name" in _caldav_server: + _servername = _caldav_server["name"] + else: + # create a unique identifier out of the server domain name + _parsed_url = urlparse(_caldav_server["url"]) + _servername = _parsed_url.hostname.replace(".", "_").replace("-", "_") + str( + _parsed_url.port or "" + ) + while _servername in _servernames: + _servername = _servername + "_" + _servername = _servername.capitalize() + _servernames.add(_servername) # create a classname and a class - _classname = "TestForServer_" + _servername + _classname = "TestForServer" + _servername # inject the new class into this namespace vars()[_classname] = type(