Repository navigation
fix: keep tests and one-off commands off other checkouts' Open WebUI - #97
Merged
Merged
Conversation
Chat tests patch chat.config.ENABLED on while UPSTREAM keeps its default, http://127.0.0.1:8080/chat, where a local manage.py dev serves Open WebUI. 23 tests pushed unmocked agent/KB/tool syncs there, overwriting the live instance's workspace models (test agent pk 1 -> studio.agent-1). - simpleaudit_studio/no_live_chat.py: socket guard refusing every test connection to the chat upstream or loopback :8080 (stub servers the test process listens on stay reachable). Installed by conftest.py and by manage.py test, so local runs behave like CI, where nothing listens there. - pytest.ini and manage.py test force SIMPLEAUDIT_CHAT=off so a shell-sourced or loaded .env cannot enable chat for the whole run. - manage.py one-off commands: with chat on and no explicit upstream, use this checkout's live dev stack's Open WebUI port, or turn chat off for the command when :8080 belongs to another checkout's live stack. - Tests for the guard, the original agent-sync leak and the routing; docs.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
test_private_connection_not_in_picker asserted no 'value="<pk>"' anywhere on the New Experiment page, so a scenario set or prompt version with the same pk failed it depending on test order (CI: value="6"). Assert on the model pickers' name="<role>_model" checkbox instead.
ChatPrecedenceTests asserted chat-mode defaults while pytest.ini sets SIMPLEAUDIT_CHAT=off, and two of them popped the variable in a finally, deleting the guard for every later test in the worker; the outcome depended on test order (CI: 'off' != 'docker'). - ChatPrecedenceTests clear the variable inside mock.patch.dict(os.environ) per test, so it is restored afterwards. - conftest.py: after each test's teardown, a test that changed SIMPLEAUDIT_CHAT fails and the value is put back. - test_ports: listen backlog 8, so the probe connection cannot fill the queue and get the next connect reset under parallel load.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A full
pytest -m "not embedded_hatchet"run overwrote the workspace modelstudio.agent-1of the Open WebUI that a localmanage.py devserves on127.0.0.1:8080(name "Prompted Agent", base model1.model-123, fromAgentUITest::test_agent_prompt_picker_renders_as_list_and_resolves_version).Root cause:
.envis not loaded under pytest (onlymanage.pycallsload_dotenv). 23 tests patchchat.config.ENABLED = Truewithout mocking the HTTP layer, whilechat.config.UPSTREAMkeeps its defaulthttp://127.0.0.1:8080/chat. Agent/KB/tool syncs,ChatAPI.sign_inandtrace_target._owui_get_jwtthen hit whatever listens there. In CI nothing does, so the connection is refused and the tests pass, which is why it went unnoticed.A related path: one-off
manage.pycommands in a worktree read the same.envbut not the per-checkoutSIMPLEAUDIT_CHAT_UPSTREAMthatmanage.py devexports, so they fall back to:8080, which is the main checkout's Open WebUI.What changed
simpleaudit_studio/no_live_chat.py: a socket guard that, during tests, refuses every TCP connect to the chat upstream or to loopback:8080. Ports the test process listens on itself (stub servers, e.g.chat/tests/test_proxy.py) stay reachable.conftest.pyandmanage.py testinstall it.pytest.iniandmanage.py testforceSIMPLEAUDIT_CHAT=off, so neither a sourced nor a loaded.envcan turn chat on for a whole run. Chat tests keep enabling it themselves.lifecycle.route_one_off_chat(called frommanage.pyfor non-dev, non-test commands): with chat on and no explicit upstream, it uses this checkout's live dev stack's chat port. When:8080belongs to another checkout's live stack, it turns chat off for that command and prints a note. An explicitSIMPLEAUDIT_CHAT_UPSTREAM(compose, the dev stack's own children) is left alone.simpleaudit_studio/tests/test_no_live_chat.pycovers the guard, plus the original leak (an unmocked agent sync against a foreign listener receives no connection).tests/test_lifecycle.pycovers the routing. There is also a short section indocs/chat.md.Reviewer notes
_CHAT_DISABLED_VALUESinlifecycle.pymirrorschat.config.DISABLED_VALUESand is not imported from it, because importingchat.configbeforedjango.setup()would freeze its settings. A test asserts the two sets match.Checks
SIMPLEAUDIT_CHAT=embeddedin.envand exported in the shell, andSIMPLEAUDIT_CHAT_UPSTREAMpointed at a recording server:uv run pytest -m "not embedded_hatchet" -n autogave 1822 passed and 3 skipped, and the recorder logged 0 requests.uv run manage.py test simpleaudit_studio.tests.test_no_live_chatpasses with chat enabled in.env.uv run ruff check .is clean.-m embedded_hatchet(infra/worker.pyandinfra/minimal_config.pyare untouched).