From 177c8da4805f1755f9f4303c10995e62c79f4caa Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 14 Dec 2025 23:03:34 +0800 Subject: [PATCH 1/4] Test-only improvements --- pyproject.toml | 1 + tests/conftest.py | 27 +++++++++++++++++++++++++-- tests/static/cluster-3.11.conf | 14 -------------- tests/static/single-3.11.conf | 12 ------------ tests/test_aql.py | 8 +++----- tests/test_backup.py | 23 ++++++----------------- tests/test_client.py | 5 +++-- tests/test_foxx.py | 5 ++++- tests/test_transaction.py | 5 ++++- 9 files changed, 46 insertions(+), 54 deletions(-) delete mode 100644 tests/static/cluster-3.11.conf delete mode 100644 tests/static/single-3.11.conf diff --git a/pyproject.toml b/pyproject.toml index ef00aea..b01c76f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,6 +60,7 @@ dev = [ "pytest-cov>=5.0", "sphinx>=7.3", "sphinx_rtd_theme>=2.0", + "allure-pytest>=2.15", "types-setuptools", ] diff --git a/tests/conftest.py b/tests/conftest.py index 295b946..1c13e6b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,7 +28,8 @@ class GlobalData: username: str = generate_username() cluster: bool = False enterprise: bool = False - db_version: version = version.parse("0.0.0") + skip: list[str] = None + db_version: version.Version = version.parse("0.0.0") global_data = GlobalData() @@ -54,7 +55,23 @@ def pytest_addoption(parser): "--cluster", action="store_true", help="Run tests in a cluster setup" ) parser.addoption( - "--enterprise", action="store_true", help="Run tests in an enterprise setup" + "--enterprise", + action="store_true", + default=True, + help="Run tests in an enterprise setup", + ) + parser.addoption( + "--skip", + action="store", + nargs="*", + choices=[ + "backup", # backup tests + "jwt-secret-keyfile", # server was not configured with a keyfile + "foxx", # foxx is not supported + "js-transactions", # javascript transactions are not supported + ], + default=[], + help="Skip specific tests", ) @@ -70,6 +87,7 @@ def pytest_configure(config): global_data.token = JwtToken.generate_token(global_data.secret) global_data.cluster = config.getoption("cluster") global_data.enterprise = config.getoption("enterprise") + global_data.skip = config.getoption("skip") global_data.graph_name = generate_graph_name() async def get_db_version(): @@ -111,6 +129,11 @@ def cluster(): return global_data.cluster +@pytest.fixture +def skip_tests(): + return global_data.skip + + @pytest.fixture def enterprise(): return global_data.enterprise diff --git a/tests/static/cluster-3.11.conf b/tests/static/cluster-3.11.conf deleted file mode 100644 index 86f7855..0000000 --- a/tests/static/cluster-3.11.conf +++ /dev/null @@ -1,14 +0,0 @@ -[starter] -mode = cluster -local = true -address = 0.0.0.0 -port = 8528 - -[auth] -jwt-secret = /tests/static/keyfile - -[args] -all.database.password = passwd -all.database.extended-names = true -all.log.api-enabled = true -all.javascript.allow-admin-execute = true diff --git a/tests/static/single-3.11.conf b/tests/static/single-3.11.conf deleted file mode 100644 index df45cb7..0000000 --- a/tests/static/single-3.11.conf +++ /dev/null @@ -1,12 +0,0 @@ -[starter] -mode = single -address = 0.0.0.0 -port = 8528 - -[auth] -jwt-secret = /tests/static/keyfile - -[args] -all.database.password = passwd -all.database.extended-names = true -all.javascript.allow-admin-execute = true diff --git a/tests/test_aql.py b/tests/test_aql.py index 24f233f..28fa91c 100644 --- a/tests/test_aql.py +++ b/tests/test_aql.py @@ -279,17 +279,15 @@ async def test_cache_plan_management(db, bad_db, doc_col, docs, db_version): entries = await cache.plan_entries() assert isinstance(entries, list) assert len(entries) > 0 - with pytest.raises(AQLCacheEntriesError) as err: - _ = await bad_db.aql.cache.plan_entries() - assert err.value.error_code == FORBIDDEN + with pytest.raises(AQLCacheEntriesError): + await bad_db.aql.cache.plan_entries() # Clear the cache await cache.clear_plan() entries = await cache.plan_entries() assert len(entries) == 0 - with pytest.raises(AQLCacheClearError) as err: + with pytest.raises(AQLCacheClearError): await bad_db.aql.cache.clear_plan() - assert err.value.error_code == FORBIDDEN @pytest.mark.asyncio diff --git a/tests/test_backup.py b/tests/test_backup.py index d2fb07e..7cbe6ba 100644 --- a/tests/test_backup.py +++ b/tests/test_backup.py @@ -2,18 +2,13 @@ from packaging import version from arangoasync.client import ArangoClient -from arangoasync.exceptions import ( - BackupCreateError, - BackupDeleteError, - BackupDownloadError, - BackupGetError, - BackupRestoreError, - BackupUploadError, -) +from arangoasync.exceptions import BackupDeleteError, BackupRestoreError @pytest.mark.asyncio -async def test_backup(url, sys_db_name, bad_db, token, enterprise, cluster, db_version): +async def test_backup( + url, sys_db_name, bad_db, token, enterprise, cluster, db_version, skip_tests +): if not enterprise: pytest.skip("Backup API is only available in ArangoDB Enterprise Edition") if not cluster: @@ -22,19 +17,13 @@ async def test_backup(url, sys_db_name, bad_db, token, enterprise, cluster, db_v pytest.skip( "For simplicity, the backup API is only tested in the latest versions" ) + if "backup" in skip_tests: + pytest.skip("Skipping backup tests") - with pytest.raises(BackupCreateError): - await bad_db.backup.create() - with pytest.raises(BackupGetError): - await bad_db.backup.get() with pytest.raises(BackupRestoreError): await bad_db.backup.restore("foobar") with pytest.raises(BackupDeleteError): await bad_db.backup.delete("foobar") - with pytest.raises(BackupUploadError): - await bad_db.backup.upload() - with pytest.raises(BackupDownloadError): - await bad_db.backup.download() async with ArangoClient(hosts=url) as client: db = await client.db( diff --git a/tests/test_client.py b/tests/test_client.py index cb488a7..cb64d6e 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -121,7 +121,7 @@ async def test_client_jwt_auth(url, sys_db_name, basic_auth_root): @pytest.mark.asyncio async def test_client_jwt_superuser_auth( - url, sys_db_name, basic_auth_root, token, enterprise + url, sys_db_name, basic_auth_root, token, enterprise, skip_tests ): # successful authentication async with ArangoClient(hosts=url) as client: @@ -130,7 +130,8 @@ async def test_client_jwt_superuser_auth( ) if enterprise: await db.jwt_secrets() - await db.reload_jwt_secrets() + if "jwt-secret-keyfile" not in skip_tests: + await db.reload_jwt_secrets() # Get TLS data tls = await db.tls() diff --git a/tests/test_foxx.py b/tests/test_foxx.py index 065530d..c407215 100644 --- a/tests/test_foxx.py +++ b/tests/test_foxx.py @@ -35,7 +35,10 @@ @pytest.mark.asyncio -async def test_foxx(db, bad_db): +async def test_foxx(db, bad_db, skip_tests): + if "foxx" in skip_tests: + pytest.skip("Skipping Foxx tests") + # Test errors with pytest.raises(FoxxServiceGetError): await bad_db.foxx.service(service_name) diff --git a/tests/test_transaction.py b/tests/test_transaction.py index f7d7f76..1a7363c 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -14,7 +14,10 @@ @pytest.mark.asyncio -async def test_transaction_execute_raw(db, doc_col, docs): +async def test_transaction_execute_raw(db, doc_col, docs, skip_tests): + if "js-transactions" in skip_tests: + pytest.skip("Skipping JS transaction tests") + # Test a valid JS transaction doc = docs[0] key = doc["_key"] From 8b1e9440b28ce4688c6dd3745fc6571bc7a913e3 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 14 Dec 2025 23:16:32 +0800 Subject: [PATCH 2/4] enterprise option is obsolete --- tests/conftest.py | 14 +------------- tests/test_analyzer.py | 4 ++-- tests/test_backup.py | 6 ++---- tests/test_client.py | 4 ++-- tests/test_cluster.py | 4 ++-- tests/test_database.py | 4 ++-- tests/test_graph.py | 4 ++-- 7 files changed, 13 insertions(+), 27 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1c13e6b..c09292d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,7 +27,6 @@ class GlobalData: graph_name: str = "test_graph" username: str = generate_username() cluster: bool = False - enterprise: bool = False skip: list[str] = None db_version: version.Version = version.parse("0.0.0") @@ -54,12 +53,6 @@ def pytest_addoption(parser): parser.addoption( "--cluster", action="store_true", help="Run tests in a cluster setup" ) - parser.addoption( - "--enterprise", - action="store_true", - default=True, - help="Run tests in an enterprise setup", - ) parser.addoption( "--skip", action="store", @@ -69,6 +62,7 @@ def pytest_addoption(parser): "jwt-secret-keyfile", # server was not configured with a keyfile "foxx", # foxx is not supported "js-transactions", # javascript transactions are not supported + "enterprise", # skip what used to be "enterprise-only" before 3.12 ], default=[], help="Skip specific tests", @@ -86,7 +80,6 @@ def pytest_configure(config): global_data.secret = config.getoption("secret") global_data.token = JwtToken.generate_token(global_data.secret) global_data.cluster = config.getoption("cluster") - global_data.enterprise = config.getoption("enterprise") global_data.skip = config.getoption("skip") global_data.graph_name = generate_graph_name() @@ -134,11 +127,6 @@ def skip_tests(): return global_data.skip -@pytest.fixture -def enterprise(): - return global_data.enterprise - - @pytest.fixture def username(): return global_data.username diff --git a/tests/test_analyzer.py b/tests/test_analyzer.py index 856b6d7..0557f64 100644 --- a/tests/test_analyzer.py +++ b/tests/test_analyzer.py @@ -11,7 +11,7 @@ @pytest.mark.asyncio -async def test_analyzer_management(db, bad_db, enterprise, db_version): +async def test_analyzer_management(db, bad_db, skip_tests, db_version): analyzer_name = generate_analyzer_name() full_analyzer_name = db.name + "::" + analyzer_name bad_analyzer_name = generate_analyzer_name() @@ -68,7 +68,7 @@ async def test_analyzer_management(db, bad_db, enterprise, db_version): assert await db.delete_analyzer(analyzer_name, ignore_missing=True) is False # Test create geo_s2 analyzer - if enterprise: + if "enterprise" not in skip_tests: analyzer_name = generate_analyzer_name() result = await db.create_analyzer(analyzer_name, "geo_s2", properties={}) assert result["type"] == "geo_s2" diff --git a/tests/test_backup.py b/tests/test_backup.py index 7cbe6ba..3bb5492 100644 --- a/tests/test_backup.py +++ b/tests/test_backup.py @@ -6,10 +6,8 @@ @pytest.mark.asyncio -async def test_backup( - url, sys_db_name, bad_db, token, enterprise, cluster, db_version, skip_tests -): - if not enterprise: +async def test_backup(url, sys_db_name, bad_db, token, cluster, db_version, skip_tests): + if "enterprise" in skip_tests: pytest.skip("Backup API is only available in ArangoDB Enterprise Edition") if not cluster: pytest.skip("For simplicity, the backup API is only tested in cluster setups") diff --git a/tests/test_client.py b/tests/test_client.py index cb64d6e..cbd96d4 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -121,14 +121,14 @@ async def test_client_jwt_auth(url, sys_db_name, basic_auth_root): @pytest.mark.asyncio async def test_client_jwt_superuser_auth( - url, sys_db_name, basic_auth_root, token, enterprise, skip_tests + url, sys_db_name, basic_auth_root, token, skip_tests ): # successful authentication async with ArangoClient(hosts=url) as client: db = await client.db( sys_db_name, auth_method="superuser", token=token, verify=True ) - if enterprise: + if "enterprise" not in skip_tests: await db.jwt_secrets() if "jwt-secret-keyfile" not in skip_tests: await db.reload_jwt_secrets() diff --git a/tests/test_cluster.py b/tests/test_cluster.py index d5b0b75..9a68a6b 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -15,11 +15,11 @@ @pytest.mark.asyncio async def test_cluster( - url, sys_db_name, bad_db, token, enterprise, cluster, db_version + url, sys_db_name, bad_db, token, skip_tests, cluster, db_version ): if not cluster: pytest.skip("Cluster API is only tested in cluster setups") - if not enterprise or db_version < version.parse("3.12.0"): + if "enterprise" in skip_tests or db_version < version.parse("3.12.0"): pytest.skip( "For simplicity, the cluster API is only tested in the latest versions" ) diff --git a/tests/test_database.py b/tests/test_database.py index 33dcc56..519d0ce 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -59,7 +59,7 @@ @pytest.mark.asyncio async def test_database_misc_methods( - sys_db, db, bad_db, cluster, db_version, url, sys_db_name, token, enterprise + sys_db, db, bad_db, cluster, db_version, url, sys_db_name, token, skip_tests ): # Status status = await sys_db.status() @@ -181,7 +181,7 @@ async def test_database_misc_methods( response = await sys_db.request(request) assert json.loads(response.raw_body) == 1 - if enterprise and db_version >= version.parse("3.12.0"): + if "enterprise" not in skip_tests and db_version >= version.parse("3.12.0"): # API calls with pytest.raises(ServerApiCallsError): await bad_db.api_calls() diff --git a/tests/test_graph.py b/tests/test_graph.py index 6d5fcbe..9916b53 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -56,10 +56,10 @@ async def test_graph_basic(db, bad_db): @pytest.mark.asyncio -async def test_graph_properties(db, bad_graph, cluster, enterprise): +async def test_graph_properties(db, bad_graph, cluster, skip_tests): # Create a graph name = generate_graph_name() - is_smart = cluster and enterprise + is_smart = cluster and "enterprise" in skip_tests options = GraphOptions(number_of_shards=3) graph = await db.create_graph(name, is_smart=is_smart, options=options) From f6799e575de733d8a6a6e5e89e30dbc76a831958 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 14 Dec 2025 23:22:35 +0800 Subject: [PATCH 3/4] Updating circleci config --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 836c418..b71ba0b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -86,8 +86,8 @@ jobs: args+=("--cluster" "--port=8539" "--port=8549") fi - if [ << parameters.arangodb_license >> = "enterprise" ]; then - args+=("--enterprise") + if [ << parameters.arangodb_license >> != "enterprise" ]; then + args+=("--skip enterprise") fi echo "Running pytest with args: ${args[@]}" From ea2004d7ad69651811eb8b4ca76ae1fb34fbf08e Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 14 Dec 2025 23:23:26 +0800 Subject: [PATCH 4/4] Fix smartgraph --- tests/test_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_graph.py b/tests/test_graph.py index 9916b53..5d70255 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -59,7 +59,7 @@ async def test_graph_basic(db, bad_db): async def test_graph_properties(db, bad_graph, cluster, skip_tests): # Create a graph name = generate_graph_name() - is_smart = cluster and "enterprise" in skip_tests + is_smart = cluster and "enterprise" not in skip_tests options = GraphOptions(number_of_shards=3) graph = await db.create_graph(name, is_smart=is_smart, options=options)