/ server / tests / test_main_api_key_guard.py
test_main_api_key_guard.py
  1  # Copyright 2026 Alibaba Group Holding Ltd.
  2  #
  3  # Licensed under the Apache License, Version 2.0 (the "License");
  4  # you may not use this file except in compliance with the License.
  5  # You may obtain a copy of the License at
  6  #
  7  #     http://www.apache.org/licenses/LICENSE-2.0
  8  #
  9  # Unless required by applicable law or agreed to in writing, software
 10  # distributed under the License is distributed on an "AS IS" BASIS,
 11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  # See the License for the specific language governing permissions and
 13  # limitations under the License.
 14  
 15  import pytest
 16  import time
 17  
 18  from opensandbox_server.startup_guard import (
 19      ALLOW_NO_API_KEY_CONFIRMATION,
 20      ALLOW_NO_API_KEY_ENV,
 21      api_key_confirm,
 22  )
 23  
 24  
 25  class _TTY:
 26      def isatty(self) -> bool:
 27          return True
 28  
 29  
 30  class _NonTTY:
 31      def isatty(self) -> bool:
 32          return False
 33  
 34  
 35  def test_api_key_configured_skips_confirmation(monkeypatch):
 36      monkeypatch.delenv(ALLOW_NO_API_KEY_ENV, raising=False)
 37  
 38      def _fail_prompt(_: str) -> str:
 39          raise AssertionError("prompt should not be called when api_key is configured")
 40  
 41      api_key_confirm(
 42          configured_api_key="secret",
 43          stdin=_NonTTY(),
 44          input_func=_fail_prompt,
 45      )
 46  
 47  
 48  def test_non_interactive_requires_env_ack(monkeypatch):
 49      monkeypatch.delenv(ALLOW_NO_API_KEY_ENV, raising=False)
 50  
 51      with pytest.raises(RuntimeError) as exc_info:
 52          api_key_confirm(
 53              configured_api_key=None,
 54              stdin=_NonTTY(),
 55          )
 56  
 57      assert "Startup blocked" in str(exc_info.value)
 58      assert ALLOW_NO_API_KEY_ENV in str(exc_info.value)
 59  
 60  
 61  def test_env_ack_allows_non_interactive_start(monkeypatch):
 62      monkeypatch.setenv(ALLOW_NO_API_KEY_ENV, ALLOW_NO_API_KEY_CONFIRMATION)
 63  
 64      api_key_confirm(
 65          configured_api_key=None,
 66          stdin=_NonTTY(),
 67      )
 68  
 69  
 70  def test_tty_requires_exact_yes(monkeypatch):
 71      monkeypatch.delenv(ALLOW_NO_API_KEY_ENV, raising=False)
 72  
 73      with pytest.raises(RuntimeError) as exc_info:
 74          api_key_confirm(
 75              configured_api_key=None,
 76              stdin=_TTY(),
 77              input_func=lambda _: "yes",
 78          )
 79  
 80      assert "Startup aborted" in str(exc_info.value)
 81  
 82  
 83  def test_tty_yes_allows_start(monkeypatch):
 84      monkeypatch.delenv(ALLOW_NO_API_KEY_ENV, raising=False)
 85  
 86      api_key_confirm(
 87          configured_api_key=None,
 88          stdin=_TTY(),
 89          input_func=lambda _: ALLOW_NO_API_KEY_CONFIRMATION,
 90      )
 91  
 92  
 93  def test_tty_confirmation_timeout(monkeypatch):
 94      monkeypatch.delenv(ALLOW_NO_API_KEY_ENV, raising=False)
 95      monkeypatch.setattr(
 96          "opensandbox_server.startup_guard.API_KEY_CONFIRM_TIMEOUT_SECONDS",
 97          1,
 98      )
 99  
100      def _slow_input(_: str) -> str:
101          time.sleep(2)
102          return ALLOW_NO_API_KEY_CONFIRMATION
103  
104      with pytest.raises(RuntimeError) as exc_info:
105          api_key_confirm(
106              configured_api_key=None,
107              stdin=_TTY(),
108              input_func=_slow_input,
109          )
110  
111      assert "timed out" in str(exc_info.value)