From 252a6d12f91c4c8561bd27ce9c5b8fcdf2e5689f Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sat, 20 Dec 2025 23:55:33 +0800 Subject: [PATCH 1/3] Preparing tests to run against development build --- .circleci/config.yml | 76 ++++++++++------------- docs/contributing.rst | 4 +- pyproject.toml | 1 + tests/conftest.py | 110 ++++++++++++++++++++++++--------- tests/static/cluster-3.11.conf | 14 ----- tests/static/setup.sh | 7 --- tests/static/single-3.11.conf | 12 ---- tests/test_analyzer.py | 4 +- tests/test_aql.py | 4 +- tests/test_backup.py | 6 +- tests/test_client.py | 46 +++++++------- tests/test_collection.py | 7 ++- tests/test_database.py | 6 +- tests/test_foxx.py | 45 +++++++++----- tests/test_index.py | 4 +- tests/test_task.py | 7 ++- tests/test_transaction.py | 5 +- tests/test_view.py | 10 +-- 18 files changed, 199 insertions(+), 169 deletions(-) delete mode 100644 tests/static/cluster-3.11.conf delete mode 100644 tests/static/setup.sh delete mode 100644 tests/static/single-3.11.conf diff --git a/.circleci/config.yml b/.circleci/config.yml index fb535db4..ccb9cf98 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,14 @@ version: 2.1 -orbs: - codecov: codecov/codecov@3.3.0 +executors: + python-container: + docker: + - image: cimg/python:3.12 + resource_class: small + python-vm: + machine: + image: ubuntu-2404:current + resource_class: medium workflows: ci: @@ -14,98 +21,81 @@ workflows: python_version: ["3.10", "3.11", "3.12"] arangodb_config: ["single", "cluster"] arangodb_license: ["enterprise"] - arangodb_version: ["latest"] + arangodb_version: ["3.12"] jobs: lint: - docker: - - image: python:latest + executor: python-container + resource_class: small steps: - checkout - run: name: Install Dependencies command: pip install .[dev] - - run: - name: Run black - command: black --check --verbose --diff --color --config=pyproject.toml ./arango ./tests/ - + name: Run black + command: black --check --verbose --diff --color --config=pyproject.toml ./arango ./tests/ - run: name: Run flake8 command: flake8 ./arango ./tests - - run: name: Run isort command: isort --check ./arango ./tests - - run: name: Run mypy command: mypy ./arango - test: parameters: - python_version: - type: string - arangodb_config: - type: string - arangodb_license: - type: string - arangodb_version: - type: string - # TODO: Reconsider using a docker image instead of a machine - # i.e cimg/python:<< parameters.python_version >> - machine: - image: ubuntu-2204:current + python_version: + type: string + arangodb_config: + type: string + arangodb_license: + type: string + arangodb_version: + type: string + executor: python-vm steps: - checkout - - run: - name: Set Up ArangoDB + name: Setup ArangoDB command: | chmod +x starter.sh ./starter.sh << parameters.arangodb_config >> << parameters.arangodb_license >> << parameters.arangodb_version >> - - restore_cache: key: pip-and-local-cache - - # TODO: Revisit this bottleneck - run: name: Setup Python command: | pyenv --version pyenv install -f << parameters.python_version >> pyenv global << parameters.python_version >> - - run: - name: "Install Dependencies" + name: Install Dependencies command: pip install -e .[dev] - - run: docker ps -a - - run: docker logs arango - - run: - name: "Run pytest" + name: Run pytest command: | mkdir test-results + mkdir htmlcov args=("--junitxml=test-results/junit.xml" "--log-cli-level=DEBUG" "--host" "localhost" "--port=8529") if [ << parameters.arangodb_config >> = "cluster" ]; then 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[@]}" - pytest --cov=arango --cov-report=xml --cov-report term-missing --color=yes --code-highlight=yes "${args[@]}" - + pytest --cov=arango --cov-report=html:htmlcov --color=yes --code-highlight=yes "${args[@]}" + - store_artifacts: + path: htmlcov + destination: coverage-report - store_artifacts: path: test-results - - store_test_results: path: test-results - - - codecov/upload: - file: coverage.xml diff --git a/docs/contributing.rst b/docs/contributing.rst index 2093f72f..09332329 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -59,7 +59,7 @@ To run the test suite (use your own host, port and root password): ~$ pip install pytest ~$ git clone https://github.com/arangodb/python-arango.git ~$ cd python-arango - ~$ py.test --complete --host=127.0.0.1 --port=8529 --passwd=passwd + ~$ pytest --cluster --host=127.0.0.1 --port=8529 --password=passwd To run the test suite with coverage report: @@ -68,7 +68,7 @@ To run the test suite with coverage report: ~$ pip install coverage pytest pytest-cov ~$ git clone https://github.com/arangodb/python-arango.git ~$ cd python-arango - ~$ py.test --complete --host=127.0.0.1 --port=8529 --passwd=passwd --cov=kq + ~$ pytest --cluster --host=127.0.0.1 --port=8529 --password=passwd --cov=kq As the test suite creates real databases and jobs, it should only be run in development environments. diff --git a/pyproject.toml b/pyproject.toml index 8ed943be..c7bf486d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,6 +57,7 @@ dev = [ "sphinx", "sphinx_rtd_theme", "types-requests", + "allure-pytest>=2.15", "types-setuptools", ] diff --git a/tests/conftest.py b/tests/conftest.py index ee5a0cd3..a6068056 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,7 +39,9 @@ class GlobalData: cluster: bool = None complete: bool = None replication: bool = None - enterprise: bool = None + skip: list[str] = None + foxx_path: str = None + backup_path: str = None secret: str = None root_password: str = None db_version: version = version.parse("0.0.0") @@ -49,24 +51,70 @@ class GlobalData: def pytest_addoption(parser): - parser.addoption("--host", action="store", default="127.0.0.1") - parser.addoption("--port", action="append", default=None) - parser.addoption("--passwd", action="store", default="passwd") - parser.addoption("--complete", action="store_true") - parser.addoption("--cluster", action="store_true") - parser.addoption("--replication", action="store_true") - parser.addoption("--enterprise", action="store_true") - parser.addoption("--secret", action="store", default="secret") + parser.addoption( + "--host", action="store", default="127.0.0.1", help="ArangoDB host address" + ) + parser.addoption( + "--port", action="append", default=None, help="ArangoDB coordinator ports" + ) + parser.addoption( + "--root", action="store", default="root", help="ArangoDB root user" + ) + parser.addoption( + "--password", action="store", default="passwd", help="ArangoDB password" + ) + parser.addoption( + "--secret", action="store", default="secret", help="ArangoDB JWT secret" + ) + parser.addoption( + "--cluster", action="store_true", help="Run tests in a cluster setup" + ) + parser.addoption( + "--complete", + action="store_true", + help="Run extra async and transaction tests (not supported)", + ) + parser.addoption("--replication", action="store_true", help="Run replication tests") + parser.addoption( + "--foxx-path", + action="store", + default="/tests/static/service.zip", + help="Foxx tests service path", + ) + parser.addoption( + "--backup-path", + action="store", + default="local://tmp", + help="Backup tests repository path", + ) + parser.addoption( + "--skip", + action="store", + nargs="*", + choices=[ + "backup", # backup tests + "batch", # batch API tests (deprecated) + "jwt-secret-keyfile", # server was not configured with a keyfile + "foxx", # foxx is not supported + "js-transactions", # javascript transactions are not supported + "task", # tasks API + "enterprise", # skip what used to be "enterprise-only" before 3.12 + ], + default=[], + help="Skip specific tests", + ) def pytest_configure(config): ports = config.getoption("port") if ports is None: ports = ["8529"] - hosts = [f"http://{config.getoption('host')}:{p}" for p in ports] + hosts = [f"http://{config.getoption('host')}:{p}" for p in ports] # noqa: E231 url = hosts[0] secret = config.getoption("secret") cluster = config.getoption("cluster") + root_password = config.getoption("password") + root_user = config.getoption("root") host_resolver = "fallback" http_client = DefaultHTTPClient(request_timeout=120) @@ -76,8 +124,8 @@ def pytest_configure(config): ) sys_db = client.db( name="_system", - username="root", - password=config.getoption("passwd"), + username=root_user, + password=root_password, superuser_token=generate_jwt(secret), verify=True, ) @@ -148,9 +196,11 @@ def pytest_configure(config): global_data.cluster = cluster global_data.complete = config.getoption("complete") global_data.replication = config.getoption("replication") - global_data.enterprise = config.getoption("enterprise") global_data.secret = secret - global_data.root_password = config.getoption("passwd") + global_data.root_password = root_password + global_data.skip = config.getoption("skip") + global_data.backup_path = config.getoption("backup_path") + global_data.foxx_path = config.getoption("foxx_path") # noinspection PyShadowingNames @@ -186,7 +236,7 @@ def pytest_unconfigure(*_): # pragma: no cover sys_db.delete_collection(col_name, ignore_missing=True) # # Remove all backups. - if global_data.enterprise: + if "backup" not in global_data.skip and "enterprise" not in global_data.skip: for backup_id in sys_db.backup.get()["list"].keys(): sys_db.backup.delete(backup_id) @@ -223,16 +273,6 @@ def pytest_generate_tests(metafunc): bad_async_db._executor = TestAsyncApiExecutor(bad_conn) bad_dbs.append(bad_async_db) - # Skip test batch databases, as they are deprecated. - """ - tst_batch_db = StandardDatabase(tst_conn) - tst_batch_db._executor = TestBatchExecutor(tst_conn) - tst_dbs.append(tst_batch_db) - bad_batch_bdb = StandardDatabase(bad_conn) - bad_batch_bdb._executor = TestBatchExecutor(bad_conn) - bad_dbs.append(bad_batch_bdb) - """ - if "db" in metafunc.fixturenames and "bad_db" in metafunc.fixturenames: metafunc.parametrize("db,bad_db", zip(tst_dbs, bad_dbs)) @@ -431,11 +471,21 @@ def replication(): return global_data.replication -@pytest.fixture(autouse=False) -def enterprise(): - return global_data.enterprise - - @pytest.fixture(autouse=False) def secret(): return global_data.secret + + +@pytest.fixture +def backup_path(): + return global_data.backup_path + + +@pytest.fixture +def foxx_path(): + return global_data.foxx_path + + +@pytest.fixture +def skip_tests(): + return global_data.skip diff --git a/tests/static/cluster-3.11.conf b/tests/static/cluster-3.11.conf deleted file mode 100644 index 86f78556..00000000 --- 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/setup.sh b/tests/static/setup.sh deleted file mode 100644 index 0d2189ba..00000000 --- a/tests/static/setup.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -mkdir -p /tests/static -wget -O /tests/static/service.zip "http://localhost:8000/$PROJECT/tests/static/service.zip" -wget -O /tests/static/keyfile "http://localhost:8000/$PROJECT/tests/static/keyfile" -wget -O /tests/static/arangodb.conf "http://localhost:8000/$PROJECT/tests/static/$ARANGODB_CONF" -arangodb --configuration=/tests/static/arangodb.conf diff --git a/tests/static/single-3.11.conf b/tests/static/single-3.11.conf deleted file mode 100644 index df45cb76..00000000 --- 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_analyzer.py b/tests/test_analyzer.py index a7573bd6..6e6744e7 100644 --- a/tests/test_analyzer.py +++ b/tests/test_analyzer.py @@ -9,7 +9,7 @@ from tests.helpers import assert_raises, generate_analyzer_name -def test_analyzer_management(db, bad_db, cluster, enterprise, db_version): +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() @@ -70,7 +70,7 @@ def test_analyzer_management(db, bad_db, cluster, enterprise, db_version): assert db.delete_analyzer(analyzer_name, ignore_missing=True) is False # Test create geo_s2 analyzer (EE only) - if enterprise: + if "enterprise" not in skip_tests: analyzer_name = generate_analyzer_name() result = db.create_analyzer(analyzer_name, "geo_s2", {}) assert result["type"] == "geo_s2" diff --git a/tests/test_aql.py b/tests/test_aql.py index f4074d63..2672887c 100644 --- a/tests/test_aql.py +++ b/tests/test_aql.py @@ -254,8 +254,8 @@ def test_aql_query_management(db_version, db, sys_db, bad_db, col, docs): assert err.value.error_code in {11, 1228} -def test_aql_query_force_one_shard_attribute_value(db, db_version, enterprise, cluster): - if not enterprise or not cluster: +def test_aql_query_force_one_shard_attribute_value(db, skip_tests, cluster): + if "enterprise" in skip_tests or not cluster: return name = generate_col_name() diff --git a/tests/test_backup.py b/tests/test_backup.py index e030c5e6..00470758 100644 --- a/tests/test_backup.py +++ b/tests/test_backup.py @@ -12,9 +12,11 @@ from tests.helpers import assert_raises -def test_backup_management(sys_db, bad_db, enterprise, cluster): - if not enterprise: +def test_backup_management(sys_db, bad_db, cluster, skip_tests): + if "enterprise" in skip_tests: pytest.skip("Only for ArangoDB enterprise edition") + if "backup" in skip_tests: + pytest.skip("Skipping backup tests") # Test create backup "foo". result = sys_db.backup.create( diff --git a/tests/test_client.py b/tests/test_client.py index a196a8fd..4da61e47 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -19,21 +19,21 @@ ) -def test_client_attributes(): +def test_client_attributes(url): http_client = DefaultHTTPClient() - client = ArangoClient(hosts="http://127.0.0.1:8529", http_client=http_client) + client = ArangoClient(hosts=url, http_client=http_client) assert client.version == importlib_metadata.version("python-arango") - assert client.hosts == ["http://127.0.0.1:8529"] + assert client.hosts == [url] - assert repr(client) == "" + assert repr(client) == f"" assert isinstance(client._host_resolver, SingleHostResolver) - client_repr = "" - client_hosts = ["http://127.0.0.1:8529", "http://localhost:8529"] + client_repr = f"" # noqa: E231 + client_hosts = [url, url] client = ArangoClient( - hosts="http://127.0.0.1:8529,http://localhost" ":8529", + hosts=f"{url},{url}", # noqa: E231 http_client=http_client, serializer=json.dumps, deserializer=json.loads, @@ -59,8 +59,8 @@ def test_client_attributes(): assert client.request_timeout == client._http.request_timeout == 120 -def test_client_good_connection(db, username, password): - client = ArangoClient(hosts="http://127.0.0.1:8529") +def test_client_good_connection(db, username, password, url): + client = ArangoClient(hosts=url) # Test connection with verify flag on and off for verify in (True, False): @@ -71,8 +71,8 @@ def test_client_good_connection(db, username, password): assert db.context == "default" -def test_client_bad_connection(db, username, password, cluster): - client = ArangoClient(hosts="http://127.0.0.1:8529") +def test_client_bad_connection(db, username, password, cluster, url): + client = ArangoClient(hosts=url) bad_db_name = generate_db_name() bad_username = generate_username() @@ -94,7 +94,7 @@ def test_client_bad_connection(db, username, password, cluster): assert "bad connection" in str(err.value) -def test_client_http_client_attributes(db, username, password): +def test_client_http_client_attributes(db, username, password, url): http_client = DefaultHTTPClient( request_timeout=80, retry_attempts=5, @@ -103,15 +103,13 @@ def test_client_http_client_attributes(db, username, password): pool_maxsize=12, pool_timeout=120, ) - client = ArangoClient( - hosts="http://127.0.0.1:8529", http_client=http_client, request_timeout=30 - ) + client = ArangoClient(hosts=url, http_client=http_client, request_timeout=30) client.db(db.name, username, password, verify=True) assert http_client.request_timeout == 80 assert client.request_timeout == http_client.request_timeout -def test_client_custom_http_client(db, username, password): +def test_client_custom_http_client(db, username, password, url): # Define custom HTTP client which increments the counter on any API call. class MyHTTPClient(DefaultHTTPClient): def __init__(self) -> None: @@ -127,13 +125,13 @@ def send_request( ) http_client = MyHTTPClient() - client = ArangoClient(hosts="http://127.0.0.1:8529", http_client=http_client) + client = ArangoClient(hosts=url, http_client=http_client) # Set verify to True to send a test API call on initialization. client.db(db.name, username, password, verify=True) assert http_client.counter == 1 -def test_client_override_validate() -> None: +def test_client_override_validate(url) -> None: # custom http client that manipulates the underlying session class MyHTTPClient(DefaultHTTPClient): def __init__(self, verify: Union[None, bool, str]) -> None: @@ -152,7 +150,7 @@ def assert_verify( ) -> None: http_client = MyHTTPClient(verify=http_client_verify) client = ArangoClient( - hosts="http://127.0.0.1:8529", + hosts=url, http_client=http_client, verify_override=arango_override, ) @@ -184,14 +182,14 @@ def assert_verify( assert_verify("test", "foo", "foo") -def test_can_serialize_deserialize_client() -> None: - client = ArangoClient(hosts="http://127.0.0.1:8529") +def test_can_serialize_deserialize_client(url) -> None: + client = ArangoClient(hosts=url) client_pstr = pickle.dumps(client) client2 = pickle.loads(client_pstr) assert len(client2._sessions) > 0 -def test_client_compression(db, username, password): +def test_client_compression(db, username, password, url): class CheckCompression: def __init__(self, should_compress: bool): self.should_compress = should_compress @@ -219,7 +217,7 @@ def send_request( # should not compress, as threshold is 0 client = ArangoClient( - hosts="http://127.0.0.1:8529", + hosts=url, http_client=MyHTTPClient(compression_checker=checker), response_compression="gzip", ) @@ -230,7 +228,7 @@ def send_request( # should not compress, as size of payload is less than threshold checker = CheckCompression(should_compress=False) client = ArangoClient( - hosts="http://127.0.0.1:8529", + hosts=url, http_client=MyHTTPClient(compression_checker=checker), request_compression=DeflateRequestCompression(250, level=7), response_compression="deflate", diff --git a/tests/test_collection.py b/tests/test_collection.py index c11a6541..c1b2c2f0 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -199,7 +199,8 @@ def test_collection_management(db, bad_db, cluster): assert key_options["key_generator"] == "autoincrement" assert key_options["key_increment"] == 9 assert key_options["key_offset"] == 100 - db.delete_collection(col_name) + + col_name = generate_col_name() col = db.create_collection( name=col_name, @@ -338,9 +339,9 @@ def test_collection_utf8(db, special_collection_names): # Not sure if this belongs in here or in `test_database.py`... def test_database_and_collection_utf8( - sys_db, special_collection_names, special_db_names + sys_db, special_collection_names, special_db_names, url ): - client = ArangoClient(hosts="http://127.0.0.1:8529") + client = ArangoClient(hosts=url) for db_name in special_db_names: username = generate_username() password = generate_string() diff --git a/tests/test_database.py b/tests/test_database.py index 1006df3b..1b9cf958 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -311,7 +311,7 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_v assert isinstance(sys_db.reset_log_levels(server_id), dict) result = sys_db.reset_log_levels() - assert result == default_log_levels + assert result.keys() == default_log_levels.keys() with assert_raises(ServerLogLevelResetError): bad_db.reset_log_levels() @@ -459,7 +459,7 @@ def test_database_utf8(sys_db, special_db_names): assert sys_db.delete_database(name) -def test_license(sys_db, enterprise, db_version): +def test_license(sys_db, skip_tests, db_version): license = sys_db.license() assert isinstance(license, dict) @@ -474,7 +474,7 @@ def test_license(sys_db, enterprise, db_version): "status", } - if enterprise: + if "enterprise" not in skip_tests: assert set(license.keys()) == expected_keys else: assert license == {"license": "none"} diff --git a/tests/test_foxx.py b/tests/test_foxx.py index b096d2e8..f20fc909 100644 --- a/tests/test_foxx.py +++ b/tests/test_foxx.py @@ -33,12 +33,16 @@ service_name = "test" -def test_foxx_attributes(db): +def test_foxx_attributes(db, skip_tests): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") assert isinstance(db.foxx, Foxx) assert repr(db.foxx) == f"" -def test_foxx_service_management_json(db, bad_db, cluster): +def test_foxx_service_management_json(db, bad_db, cluster, skip_tests, foxx_path): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") @@ -62,7 +66,7 @@ def test_foxx_service_management_json(db, bad_db, cluster): # Test create service service = db.foxx.create_service( mount=service_mount, - source=service_file, + source=foxx_path, config={}, dependencies={}, development=True, @@ -121,7 +125,7 @@ def test_foxx_service_management_json(db, bad_db, cluster): # Test replace service service = db.foxx.replace_service( mount=service_mount, - source=service_file, + source=foxx_path, config={}, dependencies={}, teardown=True, @@ -147,11 +151,12 @@ def test_foxx_service_management_json(db, bad_db, cluster): assert err.value.error_code == 3009 -def test_foxx_service_management_file(db, cluster): +def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") - path = os.path.join(os.path.dirname(__file__), "static", "service.zip") bad_path = os.path.join(os.path.dirname(__file__), "static", "service") service_mount = generate_service_mount() @@ -164,7 +169,7 @@ def test_foxx_service_management_file(db, cluster): # Test create service by file service = db.foxx.create_service_with_file( mount=service_mount, - filename=path, + filename=foxx_path, development=True, setup=True, legacy=True, @@ -180,7 +185,7 @@ def test_foxx_service_management_file(db, cluster): # Test create duplicate service with assert_raises(FoxxServiceCreateError) as err: - db.foxx.create_service_with_file(service_mount, path) + db.foxx.create_service_with_file(service_mount, foxx_path) assert err.value.error_code == 3011 # Update config and dependencies @@ -190,7 +195,7 @@ def test_foxx_service_management_file(db, cluster): # Test update service by file service = db.foxx.update_service_with_file( mount=service_mount, - filename=path, + filename=foxx_path, teardown=False, setup=False, legacy=False, @@ -206,13 +211,13 @@ def test_foxx_service_management_file(db, cluster): # Test update missing service with assert_raises(FoxxServiceUpdateError) as err: - db.foxx.update_service_with_file(missing_mount, path) + db.foxx.update_service_with_file(missing_mount, foxx_path) assert err.value.error_code == 3009 # Test replace service by file service = db.foxx.replace_service_with_file( mount=service_mount, - filename=path, + filename=foxx_path, teardown=True, setup=True, legacy=True, @@ -228,14 +233,16 @@ def test_foxx_service_management_file(db, cluster): # Test replace missing service with assert_raises(FoxxServiceReplaceError) as err: - db.foxx.replace_service_with_file(missing_mount, path) + db.foxx.replace_service_with_file(missing_mount, foxx_path) assert err.value.error_code == 3009 assert db.foxx.delete_service(service_mount, teardown=False) is True assert service_mount not in extract("mount", db.foxx.services()) -def test_foxx_config_management(db, cluster): +def test_foxx_config_management(db, cluster, skip_tests): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") @@ -274,7 +281,9 @@ def test_foxx_config_management(db, cluster): assert err.value.error_code == 3009 -def test_foxx_dependency_management(db, cluster): +def test_foxx_dependency_management(db, cluster, skip_tests): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") @@ -309,7 +318,9 @@ def test_foxx_dependency_management(db, cluster): assert err.value.error_code == 3009 -def test_foxx_development_toggle(db, cluster): +def test_foxx_development_toggle(db, cluster, skip_tests): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") @@ -346,7 +357,9 @@ def test_foxx_development_toggle(db, cluster): assert err.value.error_code == 3009 -def test_foxx_misc_functions(db, bad_db, cluster): +def test_foxx_misc_functions(db, bad_db, cluster, skip_tests): + if "foxx" in skip_tests: + pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") diff --git a/tests/test_index.py b/tests/test_index.py index a5d0f5eb..04708d9d 100644 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -250,7 +250,7 @@ def test_add_ttl_index(icol): icol.delete_index(result["id"]) -def test_add_inverted_index(icol, enterprise): +def test_add_inverted_index(icol, skip_tests): parameters = dict( fields=[{"name": "attr1", "cache": True}], name="c0_cached", @@ -261,7 +261,7 @@ def test_add_inverted_index(icol, enterprise): ) expected_keys = ["primarySort", "analyzer", "includeAllFields", "searchField"] - if enterprise: + if "enterprise" not in skip_tests: parameters["cache"] = True parameters["primaryKeyCache"] = True expected_keys.extend(["cache", "primaryKeyCache"]) diff --git a/tests/test_task.py b/tests/test_task.py index 85837a4e..9bfa48f6 100644 --- a/tests/test_task.py +++ b/tests/test_task.py @@ -1,3 +1,5 @@ +import pytest + from arango.exceptions import ( TaskCreateError, TaskDeleteError, @@ -7,7 +9,10 @@ from tests.helpers import assert_raises, extract, generate_task_id, generate_task_name -def test_task_management(sys_db, db, bad_db): +def test_task_management(sys_db, db, bad_db, skip_tests): + if "task" in skip_tests: + pytest.skip("Skipping task tests") + test_command = 'require("@arangodb").print(params);' # Test create task with random ID diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 75ec28a2..15bf5e6d 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -13,7 +13,10 @@ from tests.helpers import extract, generate_db_name -def test_transaction_execute_raw(db, col, docs): +def test_transaction_execute_raw(db, col, docs, skip_tests): + if "js-transactions" in skip_tests: + pytest.skip("Skipping JS transaction tests") + # Test execute raw transaction doc = docs[0] key = doc["_key"] diff --git a/tests/test_view.py b/tests/test_view.py index 778f87e6..4aae2946 100644 --- a/tests/test_view.py +++ b/tests/test_view.py @@ -12,7 +12,7 @@ from tests.helpers import assert_raises, generate_view_name -def test_view_management(db, bad_db, col, cluster, db_version, enterprise): +def test_view_management(db, bad_db, col, cluster, db_version, skip_tests): # Test create view view_name = generate_view_name() bad_view_name = generate_view_name() @@ -124,7 +124,7 @@ def test_view_management(db, bad_db, col, cluster, db_version, enterprise): # Test delete missing view with ignore_missing set to True assert db.delete_view(view_name, ignore_missing=True) is False - if enterprise and db_version >= version.parse("3.12"): + if "enterprise" not in skip_tests and db_version >= version.parse("3.12"): res = db.create_view( view_name, view_type, @@ -194,11 +194,11 @@ def test_arangosearch_view_management(db, bad_db, cluster): assert db.delete_view(view_name, ignore_missing=False) is True -def test_arangosearch_view_properties(db, col, enterprise): +def test_arangosearch_view_properties(db, col, skip_tests): view_name = generate_view_name() params = {"consolidationIntervalMsec": 50000} - if enterprise: + if "enterprise" not in skip_tests: params.update( { "links": { @@ -221,7 +221,7 @@ def test_arangosearch_view_properties(db, col, enterprise): assert result["name"] == view_name assert result["type"].lower() == "arangosearch" - if enterprise: + if "enterprise" not in skip_tests: assert "links" in result assert col.name in result["links"] From 2a5ccb397df16700028d738ffa440ad9b8d1c8f5 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 21 Dec 2025 00:09:38 +0800 Subject: [PATCH 2/3] Foxx tests --- tests/test_foxx.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/test_foxx.py b/tests/test_foxx.py index f20fc909..266599f1 100644 --- a/tests/test_foxx.py +++ b/tests/test_foxx.py @@ -29,7 +29,6 @@ from arango.foxx import Foxx from tests.helpers import assert_raises, extract, generate_service_mount -service_file = "/tests/static/service.zip" service_name = "test" @@ -105,7 +104,7 @@ def test_foxx_service_management_json(db, bad_db, cluster, skip_tests, foxx_path # Test update service service = db.foxx.update_service( mount=service_mount, - source=service_file, + source=foxx_path, config={}, dependencies={}, teardown=True, @@ -240,7 +239,7 @@ def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): assert service_mount not in extract("mount", db.foxx.services()) -def test_foxx_config_management(db, cluster, skip_tests): +def test_foxx_config_management(db, cluster, skip_tests, foxx_path): if "foxx" in skip_tests: pytest.skip("Skipping foxx tests") if cluster: @@ -252,7 +251,7 @@ def test_foxx_config_management(db, cluster, skip_tests): # Prep the test service db.foxx.create_service( mount=service_mount, - source=service_file, + source=foxx_path, config={}, ) @@ -281,7 +280,7 @@ def test_foxx_config_management(db, cluster, skip_tests): assert err.value.error_code == 3009 -def test_foxx_dependency_management(db, cluster, skip_tests): +def test_foxx_dependency_management(db, cluster, skip_tests, foxx_path): if "foxx" in skip_tests: pytest.skip("Skipping foxx tests") if cluster: @@ -291,7 +290,7 @@ def test_foxx_dependency_management(db, cluster, skip_tests): missing_mount = generate_service_mount() # Prep the test service - db.foxx.create_service(mount=service_mount, source=service_file, dependencies={}) + db.foxx.create_service(mount=service_mount, source=foxx_path, dependencies={}) # Test get service dependencies assert db.foxx.dependencies(service_mount) == {} @@ -318,7 +317,7 @@ def test_foxx_dependency_management(db, cluster, skip_tests): assert err.value.error_code == 3009 -def test_foxx_development_toggle(db, cluster, skip_tests): +def test_foxx_development_toggle(db, cluster, skip_tests, foxx_path): if "foxx" in skip_tests: pytest.skip("Skipping foxx tests") if cluster: @@ -330,7 +329,7 @@ def test_foxx_development_toggle(db, cluster, skip_tests): # Prep the test service db.foxx.create_service( mount=service_mount, - source=service_file, + source=foxx_path, development=False, ) @@ -357,7 +356,7 @@ def test_foxx_development_toggle(db, cluster, skip_tests): assert err.value.error_code == 3009 -def test_foxx_misc_functions(db, bad_db, cluster, skip_tests): +def test_foxx_misc_functions(db, bad_db, cluster, skip_tests, foxx_path): if "foxx" in skip_tests: pytest.skip("Skipping foxx tests") if cluster: @@ -369,7 +368,7 @@ def test_foxx_misc_functions(db, bad_db, cluster, skip_tests): # Prep the test service db.foxx.create_service( mount=service_mount, - source=service_file, + source=foxx_path, ) # Test get service readme From 3c5f378a09b13a3afd34d4c6081f659c0f576135 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 21 Dec 2025 00:21:06 +0800 Subject: [PATCH 3/3] Foxx tests --- tests/test_foxx.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/test_foxx.py b/tests/test_foxx.py index 266599f1..892cfc60 100644 --- a/tests/test_foxx.py +++ b/tests/test_foxx.py @@ -150,12 +150,13 @@ def test_foxx_service_management_json(db, bad_db, cluster, skip_tests, foxx_path assert err.value.error_code == 3009 -def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): +def test_foxx_service_management_file(db, cluster, skip_tests): if "foxx" in skip_tests: pytest.skip("Skipping foxx tests") if cluster: pytest.skip("Not tested in a cluster setup") + path = os.path.join(os.path.dirname(__file__), "static", "service.zip") bad_path = os.path.join(os.path.dirname(__file__), "static", "service") service_mount = generate_service_mount() @@ -168,7 +169,7 @@ def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): # Test create service by file service = db.foxx.create_service_with_file( mount=service_mount, - filename=foxx_path, + filename=path, development=True, setup=True, legacy=True, @@ -184,7 +185,7 @@ def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): # Test create duplicate service with assert_raises(FoxxServiceCreateError) as err: - db.foxx.create_service_with_file(service_mount, foxx_path) + db.foxx.create_service_with_file(service_mount, path) assert err.value.error_code == 3011 # Update config and dependencies @@ -194,7 +195,7 @@ def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): # Test update service by file service = db.foxx.update_service_with_file( mount=service_mount, - filename=foxx_path, + filename=path, teardown=False, setup=False, legacy=False, @@ -210,13 +211,13 @@ def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): # Test update missing service with assert_raises(FoxxServiceUpdateError) as err: - db.foxx.update_service_with_file(missing_mount, foxx_path) + db.foxx.update_service_with_file(missing_mount, path) assert err.value.error_code == 3009 # Test replace service by file service = db.foxx.replace_service_with_file( mount=service_mount, - filename=foxx_path, + filename=path, teardown=True, setup=True, legacy=True, @@ -232,7 +233,7 @@ def test_foxx_service_management_file(db, cluster, skip_tests, foxx_path): # Test replace missing service with assert_raises(FoxxServiceReplaceError) as err: - db.foxx.replace_service_with_file(missing_mount, foxx_path) + db.foxx.replace_service_with_file(missing_mount, path) assert err.value.error_code == 3009 assert db.foxx.delete_service(service_mount, teardown=False) is True