From 312e4b0133efe84fc591dc8622b2a82adf4a20cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20M=C3=BCller?= Date: Thu, 22 Oct 2026 12:49:56 +0200 Subject: [PATCH 1/2] tests: forget dclab API keys before testing anonymous access dclab remembers all API keys used in a process (`APIHandler.api_keys`), so the subsequent anonymous access in `test_access_private_data` actually used the API key of the test user and did not raise. Co-Authored-By: Claude Opus 5.5 --- tests/test_dcserv.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_dcserv.py b/tests/test_dcserv.py index 6c3db05..c9ae2de 100644 --- a/tests/test_dcserv.py +++ b/tests/test_dcserv.py @@ -23,7 +23,7 @@ def test_access_public_data(): assert res is True -def test_access_private_data(): +def test_access_private_data(monkeypatch): """Upload a private dataset and try to access it""" # create some metadata dataset_dict = make_dataset_dict() @@ -92,7 +92,10 @@ def test_access_private_data(): 0.011666297, atol=0, rtol=1e-5) - # Try to access the private dataset as a public user + # Try to access the private dataset as a public user. dclab remembers + # all API keys used in this process, so we have to forget them first. + monkeypatch.setattr(dclab.rtdc_dataset.fmt_dcor.api.APIHandler, + "api_keys", []) with pytest.raises(dclab.rtdc_dataset.fmt_dcor.api.DCORAccessError): dclab.new_dataset(res_id, host=api.server, dcserv_api_version=2) From 34ab2f655198c0899948d18c3bacc8e6e891ca4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20M=C3=BCller?= Date: Thu, 22 Oct 2026 12:49:56 +0200 Subject: [PATCH 2/2] tests: automatically create test users on DCOR-dev - `get_api_key` uses `DCOR_API_KEY` if set; otherwise it uses the key in `tests/api_key` if it is still valid or creates a new user via `dcoraid.api.create_dcor_dev_user` and stores its key there - prefix the default circle names with the name of the test user, because circle names are unique and test users are created on the fly Co-Authored-By: Claude Opus 5.5 --- .gitignore | 1 + README.rst | 9 +++++---- tests/helper.py | 35 ++++++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 083d732..5b5b88a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__ .idea +tests/api_key diff --git a/README.rst b/README.rst index 257b115..61fb864 100644 --- a/README.rst +++ b/README.rst @@ -9,17 +9,18 @@ The tests are run regularly on travis-ci.com. Running the tests ----------------- -You need to have Python 3 installed. Either define the environment variable +You need to have Python 3 installed. You may define the environment variable `DCOR_API_KEY` or create the file `api_key` containing your API key in the -`tests` directory. Then run: +`tests` directory. Otherwise, a test user is created automatically on DCOR-dev +and its API key is stored in `tests/api_key`. Then run: :: pip install -r requirements py.test tests -Note that datasets, collections, and circles created during testing are -only purged for registered testing users (e.g. "remote_tester"). +Note that all users, datasets, collections, and circles on DCOR-dev are +purged regularly. .. |Tests Status| image:: https://img.shields.io/github/actions/workflow/status/DCOR-dev/dcor-remote-tests/check.yml diff --git a/tests/helper.py b/tests/helper.py index 5b40a0a..26393b7 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -1,9 +1,10 @@ +import functools import inspect import os import pathlib import time -from dcoraid.api import CKANAPI +from dcoraid.api import CKANAPI, create_dcor_dev_user, is_valid_api_key SERVER = "dcor-dev.mpl.mpg.de" @@ -14,24 +15,43 @@ def get_api(): return api +@functools.lru_cache def get_api_key(): + """Return the API key of the test user + + The API key is taken from the `DCOR_API_KEY` environment variable. + If that is not set, the key stored in the file `tests/api_key` is + used. If that file does not exist or the key is invalid (users on + DCOR-dev are purged regularly), a new user is created on DCOR-dev + and its API key is written to `tests/api_key`. + """ key = os.environ.get("DCOR_API_KEY") if not key: - # local file kp = pathlib.Path(__file__).parent / "api_key" - if not kp.exists(): - raise ValueError("No DCOR_API_KEY variable or api_key file!") - key = kp.read_text().strip() + if kp.exists(): + key = kp.read_text().strip() + if not is_valid_api_key(server=SERVER, api_key=key): + key = create_dcor_dev_user(server=SERVER, + fullname="DCOR remote tester") + kp.write_text(key) return key +@functools.lru_cache +def get_user_name(): + """Return the name of the test user""" + return get_api().get_user_dict()["name"] + + def make_dataset_dict(circle=None, hint=None): """Generate a test dataset in a test circle Parameters ---------- circle: str or None - circle name; if None, the calling functions module is used + circle name; if None, the calling functions module is used, + prefixed with the name of the test user (circle names are + unique on DCOR and test users are created on the fly) hint: str descriptive dataset title string; if None, the calling function is used; the time since the epoch is added to the dataset title @@ -41,7 +61,8 @@ def make_dataset_dict(circle=None, hint=None): hint = "test " + inspect.currentframe().f_back.f_code.co_name if circle is None: filename = inspect.currentframe().f_back.f_code.co_filename - circle = filename.split("/")[-1].rsplit(".", 1)[0] + module = filename.split("/")[-1].rsplit(".", 1)[0] + circle = f"{get_user_name()}-{module}".replace("_", "-") dataset_dict = { "title": "{} {}".format(hint, time.time()), "private": True,