From b5b370c7cb2805ff3cab85c042e4ccab4d16f5f9 Mon Sep 17 00:00:00 2001 From: Brendan Clement Date: Fri, 9 Oct 2026 22:45:49 -0700 Subject: [PATCH] test(docs): use a deployment in the Function test only when asked test_function_enterprise ran against a deployment whenever LANCEDB_URI, LANCEDB_HOST_OVERRIDE and LANCEDB_API_KEY were set. Like the quickstart tests, it now also needs LANCEDB_DOCS_TEST_DEPLOYMENT=1, and fails rather than skips when that is set without the settings. New tests drive it with lancedb.connect stubbed: without the exact opt-in it skips before connecting, with the opt-in but missing settings it fails naming them, and with both it reaches the connection. The examples are unchanged. --- docs/web-tests/py/test_function.py | 127 +++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 17 deletions(-) diff --git a/docs/web-tests/py/test_function.py b/docs/web-tests/py/test_function.py index 629ab89bc..f66a50aec 100644 --- a/docs/web-tests/py/test_function.py +++ b/docs/web-tests/py/test_function.py @@ -4,16 +4,18 @@ """Examples for docs/web/management/function.mdx. Registering a Function and filling its column need a LanceDB Enterprise -deployment, so `test_function_enterprise` runs only when the connection -variables the Enterprise examples already use are set: LANCEDB_URI, -LANCEDB_API_KEY and LANCEDB_HOST_OVERRIDE, plus LANCEDB_REGION if the -deployment needs one. The walkthrough calls its table `function_demo` and its -Function `double`; the test creates both under names unique to its run, never -replaces an existing object, and drops only what it created. +deployment, so `test_function_enterprise` runs only when +LANCEDB_DOCS_TEST_DEPLOYMENT=1 asks for one, with the connection variables the +Enterprise examples already use: LANCEDB_URI, LANCEDB_API_KEY and +LANCEDB_HOST_OVERRIDE, plus LANCEDB_REGION if the deployment needs one. The +walkthrough calls its table `function_demo` and its Function `double`; the test +creates both under names unique to its run, never replaces an existing object, +and drops only what it created. The other tests run locally and check the client side of the same code: what -`@udf` sends for registration, how a registered version binds a column, and -where a local connection stops. They do not run a Function remotely. +`@udf` sends for registration, how a registered version binds a column, where a +local connection stops, and when the Enterprise test connects. They do not run +a Function remotely. """ import json @@ -70,12 +72,17 @@ def registered_version(definition) -> FunctionVersion: return FunctionVersion.from_json(json.dumps(reply)) -def require_env(var_name: str) -> str: - """Skip the test unless the required environment variable is provided.""" - value = os.environ.get(var_name) - if not value: - pytest.skip(f"Set {var_name} to run this Enterprise example") - return value +DEPLOYMENT = ("LANCEDB_URI", "LANCEDB_HOST_OVERRIDE", "LANCEDB_API_KEY") +# The connection settings alone never send this test to a deployment. +OPT_IN = "LANCEDB_DOCS_TEST_DEPLOYMENT" + + +def require_deployment(): + if os.environ.get(OPT_IN) != "1": + pytest.skip(f"set {OPT_IN}=1 and {', '.join(DEPLOYMENT)} to use a deployment") + missing = [name for name in DEPLOYMENT if not os.environ.get(name)] + if missing: + pytest.fail(f"{OPT_IN}=1 needs {', '.join(missing)}") def test_function_runs_locally_as_python(): @@ -160,9 +167,7 @@ def test_function_version_binds_a_column(tmp_path): def test_function_enterprise(monkeypatch): - require_env("LANCEDB_URI") - require_env("LANCEDB_API_KEY") - require_env("LANCEDB_HOST_OVERRIDE") + require_deployment() # --8<-- [start:function_connect] import os @@ -240,3 +245,91 @@ def test_function_enterprise(monkeypatch): db.drop_table(table_name) if version is not None: db.drop_function(version.name, version=version.version) + + +class ReachedConnection(Exception): + pass + + +SETTINGS = { + "LANCEDB_URI": "db://docs-test", + "LANCEDB_HOST_OVERRIDE": "https://deployment.invalid", + "LANCEDB_API_KEY": "docs-test-key", +} + + +@pytest.fixture +def connect_attempts(monkeypatch): + """`lancedb.connect`, replaced so that it records each call and stops.""" + attempts = [] + + def connect(**kwargs): + attempts.append(kwargs) + raise ReachedConnection + + monkeypatch.setattr(lancedb, "connect", connect) + for name in (OPT_IN, *DEPLOYMENT, "LANCEDB_REGION"): + monkeypatch.delenv(name, raising=False) + return attempts + + +def enterprise_outcome(monkeypatch): + try: + test_function_enterprise(monkeypatch) + except (pytest.skip.Exception, pytest.fail.Exception, ReachedConnection) as outcome: + return outcome + + +@pytest.mark.parametrize( + "opt_in", + [None, "", "0", "true", "TRUE", "yes", "on", " 1", "1 ", "01", "1.0", "11"], +) +def test_function_enterprise_needs_the_exact_opt_in( + monkeypatch, connect_attempts, opt_in +): + for name, value in SETTINGS.items(): + monkeypatch.setenv(name, value) + if opt_in is not None: + monkeypatch.setenv(OPT_IN, opt_in) + outcome = enterprise_outcome(monkeypatch) + assert isinstance(outcome, pytest.skip.Exception), outcome + assert str(outcome).startswith(f"set {OPT_IN}=1 ") + assert connect_attempts == [] + + +@pytest.mark.parametrize("blank", ["unset", "empty"]) +@pytest.mark.parametrize( + "missing", [*([name] for name in DEPLOYMENT), list(DEPLOYMENT)] +) +def test_function_enterprise_fails_when_asked_without_settings( + monkeypatch, connect_attempts, missing, blank +): + monkeypatch.setenv(OPT_IN, "1") + for name, value in SETTINGS.items(): + if name not in missing: + monkeypatch.setenv(name, value) + elif blank == "empty": + monkeypatch.setenv(name, "") + outcome = enterprise_outcome(monkeypatch) + assert isinstance(outcome, pytest.fail.Exception), outcome + assert str(outcome) == f"{OPT_IN}=1 needs {', '.join(missing)}" + assert connect_attempts == [] + + +@pytest.mark.parametrize("region", [None, "eu-west-1"]) +def test_function_enterprise_connects_when_asked(monkeypatch, connect_attempts, region): + monkeypatch.setenv(OPT_IN, "1") + for name, value in SETTINGS.items(): + monkeypatch.setenv(name, value) + if region: + monkeypatch.setenv("LANCEDB_REGION", region) + outcome = enterprise_outcome(monkeypatch) + assert isinstance(outcome, ReachedConnection), outcome + assert connect_attempts == [ + { + "uri": "db://docs-test", + "api_key": "docs-test-key", + "region": region or "us-east-1", + "host_override": "https://deployment.invalid", + } + ]