5a558eb09e
Backend Tests / discover-tests (push) Waiting to run
Backend Tests / ${{ matrix.name }} (push) Blocked by required conditions
Build and Publish SDK / build-and-publish (push) Waiting to run
Build Opik Docker Images / set-version (push) Waiting to run
Build Opik Docker Images / build-backend (push) Blocked by required conditions
Build Opik Docker Images / build-sandbox-executor-python (push) Blocked by required conditions
Build Opik Docker Images / build-python-backend (push) Blocked by required conditions
Build Opik Docker Images / build-frontend (push) Blocked by required conditions
Build Opik Docker Images / create-git-tag (push) Blocked by required conditions
ClickHouse Migration Cluster Check / validate-clickhouse-migrations (push) Waiting to run
Docs - Publish / run (push) Waiting to run
E2E Tests - Post Merge (v2) / 🧪 E2E v2 Tests (${{ github.event.inputs.tier || 't1' }}) (push) Waiting to run
E2E Tests - Post Merge (v2) / 📢 Slack Notification (push) Blocked by required conditions
Frontend Unit Tests / Test on Node 20 (push) Waiting to run
Guardrails E2E Tests / Select Python version matrix (push) Waiting to run
Guardrails E2E Tests / Guardrails E2E Tests ${{matrix.python_version}} (push) Blocked by required conditions
Guardrails E2E Tests / 📢 Slack Notification (push) Blocked by required conditions
Guardrails Backend Unit Tests / Guardrails Backend Unit Tests (push) Waiting to run
Guardrails Backend Unit Tests / 📢 Slack Notification (push) Blocked by required conditions
Lint Opik Helm Chart / lint-helm-chart (Helm v3.21.0) (push) Waiting to run
Lint Opik Helm Chart / lint-helm-chart (Helm v4.2.0) (push) Waiting to run
Lint Opik Helm Chart / unittest-helm-chart (push) Waiting to run
Lint Opik Helm Chart / render-equality (push) Waiting to run
Opik Optimizer - Unit Tests / Opik Optimizer Unit Tests Python ${{matrix.python_version}} (push) Waiting to run
Python BE E2E Tests / Python BE E2E (push) Waiting to run
Python Backend Tests / run-python-backend-tests (push) Waiting to run
Python SDK Unit Tests / Python SDK Unit Tests ${{matrix.python_version}} (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
SDK E2E Libraries Integration Tests / Check Secrets (push) Waiting to run
SDK E2E Libraries Integration Tests / Missed OpenAI API Key Warning (push) Blocked by required conditions
SDK E2E Libraries Integration Tests / build-opik (push) Blocked by required conditions
SDK E2E Libraries Integration Tests / E2E Lib Integration Python ${{matrix.python_version}} (push) Blocked by required conditions
TypeScript SDK Integration Build & Publish / build-and-publish (opik-gemini) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-langchain) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-openai) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-otel) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-vercel) (push) Waiting to run
TypeScript SDK Build & Publish / build-and-publish (push) Waiting to run
TypeScript SDK Unit Tests / Test on Node ${{ matrix.node-version }} (push) Waiting to run
TypeScript SDK Compatibility V1.x E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / TypeScript SDK Compatibility V1.x E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
TypeScript SDK E2E Tests / TypeScript SDK E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
Python SDK E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK E2E Tests / Python SDK E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK E2E Tests / build-opik (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Python SDK Compatibility V1.x E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK E2E Tests / build-opik (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer E2E Tests Python ${{matrix.python_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer Integration Smoke Tests (push) Has been cancelled
🐙 Code Quality / detect (push) Has been cancelled
🐙 Code Quality / lint (${{ matrix.leg.name }}) (push) Has been cancelled
🐙 Code Quality / summary (push) Has been cancelled
TypeScript SDK Library Integration Tests / Check Secrets (push) Has been cancelled
TypeScript SDK Library Integration Tests / opik-vercel (Vercel AI SDK / eve) (push) Has been cancelled
SDK Library Integration Tests Runner / Check Secrets (push) Has been cancelled
SDK Library Integration Tests Runner / Missed OpenAI API Key Warning (push) Has been cancelled
SDK Library Integration Tests Runner / Build (push) Has been cancelled
SDK Library Integration Tests Runner / openai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_legacy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / llama_index_tests (push) Has been cancelled
SDK Library Integration Tests Runner / anthropic_tests (push) Has been cancelled
SDK Library Integration Tests Runner / mistral_tests (push) Has been cancelled
SDK Library Integration Tests Runner / groq_tests (push) Has been cancelled
SDK Library Integration Tests Runner / aisuite_tests (push) Has been cancelled
SDK Library Integration Tests Runner / haystack_tests (push) Has been cancelled
SDK Library Integration Tests Runner / dspy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v1_tests (push) Has been cancelled
SDK Library Integration Tests Runner / genai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_legacy_1_3_0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / evaluation_metrics_tests (push) Has been cancelled
SDK Library Integration Tests Runner / bedrock_tests (push) Has been cancelled
SDK Library Integration Tests Runner / litellm_tests (push) Has been cancelled
SDK Library Integration Tests Runner / harbor_tests (push) Has been cancelled
SDK Library Integration Tests Runner / Slack Notification (push) Has been cancelled
446 lines
17 KiB
Python
446 lines
17 KiB
Python
"""Tests for CLI commands."""
|
|
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock, patch
|
|
from contextlib import contextmanager
|
|
|
|
from click.testing import CliRunner
|
|
|
|
from opik.cli import cli
|
|
|
|
|
|
class TestDownloadCommand:
|
|
"""Test the download CLI command."""
|
|
|
|
def test_export_group_help(self):
|
|
"""Test that the export group shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["export", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "Export data from an Opik project" in result.output
|
|
assert "dataset" in result.output
|
|
assert "traces" in result.output
|
|
assert "experiment" in result.output
|
|
|
|
def test_export_dataset_help(self):
|
|
"""Test that the export dataset command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["export", "default", "proj", "dataset", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "Export a dataset by exact name" in result.output
|
|
assert "--force" in result.output
|
|
|
|
def test_export_traces_help(self):
|
|
"""Test that the export traces command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["export", "default", "proj", "traces", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "Export the project's traces" in result.output
|
|
|
|
def test_export_experiment_help(self):
|
|
"""Test that the export experiment command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli, ["export", "default", "proj", "experiment", "--help"]
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "Export an experiment by exact name" in result.output
|
|
|
|
|
|
class TestUploadCommand:
|
|
"""Test the upload CLI command."""
|
|
|
|
def test_import_group_help(self):
|
|
"""Test that the import group shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["import", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "Import data into an Opik project" in result.output
|
|
assert "dataset" in result.output
|
|
assert "traces" in result.output
|
|
assert "experiment" in result.output
|
|
|
|
def test_import_dataset_help(self):
|
|
"""Test that the import dataset command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["import", "default", "proj", "dataset", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "Import datasets from" in result.output
|
|
assert "--dry-run" in result.output
|
|
|
|
def test_import_traces_help(self):
|
|
"""Test that the import traces command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["import", "default", "proj", "traces", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "Import the project's traces" in result.output
|
|
assert "--dry-run" in result.output
|
|
|
|
def test_import_experiment_help(self):
|
|
"""Test that the import experiment command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli, ["import", "default", "proj", "experiment", "--help"]
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "Import experiments from" in result.output
|
|
assert "--dry-run" in result.output
|
|
|
|
|
|
class TestSmokeTestCommand:
|
|
"""Test the smoke-test functionality via healthcheck command."""
|
|
|
|
def test_smoke_test_help(self):
|
|
"""Test that the healthcheck --smoke-test command shows help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["healthcheck", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "--smoke-test" in result.output
|
|
assert "--project-name" in result.output
|
|
assert "Project name for the smoke test" in result.output
|
|
assert "WORKSPACE" in result.output
|
|
assert "Run a smoke test to verify Opik integration" in result.output
|
|
|
|
def test_smoke_test_minimal_args_parsing(self):
|
|
"""Test that healthcheck --smoke-test command requires workspace value."""
|
|
runner = CliRunner()
|
|
# Test that help shows workspace is required
|
|
result = runner.invoke(cli, ["healthcheck", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "WORKSPACE" in result.output
|
|
# Test that missing workspace value causes error
|
|
result = runner.invoke(cli, ["healthcheck", "--smoke-test"])
|
|
assert result.exit_code != 0
|
|
assert "Error" in result.output or "Missing" in result.output
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik.Opik")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik.start_as_current_trace")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik_context.update_current_trace")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik_context.update_current_span")
|
|
@patch("opik.cli.healthcheck.smoke_test.create_opik_logo_image")
|
|
@patch("opik.cli.healthcheck.smoke_test.track")
|
|
def test_smoke_test_with_workspace_and_project_name(
|
|
self,
|
|
mock_track,
|
|
mock_create_logo,
|
|
mock_update_span,
|
|
mock_update_trace,
|
|
mock_start_trace,
|
|
mock_opik_class,
|
|
mock_healthcheck_run,
|
|
):
|
|
"""Test healthcheck --smoke-test command with workspace and --project-name arguments."""
|
|
# Setup mocks
|
|
mock_client = MagicMock()
|
|
# Mock search_traces to raise an exception immediately to skip verification polling
|
|
# This prevents the verification from running and triggering real client creation
|
|
mock_client.search_traces = MagicMock(
|
|
side_effect=AttributeError("Mock client - search_traces not available")
|
|
)
|
|
mock_opik_class.return_value = mock_client
|
|
|
|
# Mock the context manager for start_as_current_trace
|
|
@contextmanager
|
|
def mock_trace_context(*args, **kwargs):
|
|
yield MagicMock()
|
|
|
|
mock_start_trace.return_value = mock_trace_context()
|
|
|
|
# Mock create_opik_logo_image to return a fake path
|
|
mock_logo_path = Path("/tmp/fake_logo.png")
|
|
mock_create_logo.return_value = mock_logo_path
|
|
|
|
# Mock the track decorator to return the function unchanged
|
|
def track_decorator(*args, **kwargs):
|
|
def decorator(func):
|
|
return func
|
|
|
|
return decorator
|
|
|
|
mock_track.side_effect = track_decorator
|
|
|
|
# Run the command
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
[
|
|
"healthcheck",
|
|
"--smoke-test",
|
|
"test-workspace",
|
|
"--project-name",
|
|
"test-project",
|
|
],
|
|
catch_exceptions=False,
|
|
)
|
|
|
|
# Assertions
|
|
assert result.exit_code == 0
|
|
# Verify client was created with correct arguments
|
|
mock_opik_class.assert_called_once()
|
|
call_kwargs = mock_opik_class.call_args[1]
|
|
assert call_kwargs["workspace"] == "test-workspace"
|
|
assert call_kwargs["project_name"] == "test-project"
|
|
# Verify trace was started
|
|
mock_start_trace.assert_called_once()
|
|
# Verify explicit client was flushed and ended
|
|
mock_client.flush.assert_called_once()
|
|
mock_client.end.assert_called_once()
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik.Opik")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik.start_as_current_trace")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik_context.update_current_trace")
|
|
@patch("opik.cli.healthcheck.smoke_test.opik_context.update_current_span")
|
|
@patch("opik.cli.healthcheck.smoke_test.create_opik_logo_image")
|
|
@patch("opik.cli.healthcheck.smoke_test.track")
|
|
def test_smoke_test_with_default_project_name(
|
|
self,
|
|
mock_track,
|
|
mock_create_logo,
|
|
mock_update_span,
|
|
mock_update_trace,
|
|
mock_start_trace,
|
|
mock_opik_class,
|
|
mock_healthcheck_run,
|
|
):
|
|
"""Test healthcheck --smoke-test command with workspace only (uses default project name)."""
|
|
# Setup mocks
|
|
mock_client = MagicMock()
|
|
# Mock search_traces to raise an exception immediately to skip verification polling
|
|
# This prevents the verification from running and triggering real client creation
|
|
mock_client.search_traces = MagicMock(
|
|
side_effect=AttributeError("Mock client - search_traces not available")
|
|
)
|
|
mock_opik_class.return_value = mock_client
|
|
|
|
# Mock the context manager for start_as_current_trace
|
|
@contextmanager
|
|
def mock_trace_context(*args, **kwargs):
|
|
yield MagicMock()
|
|
|
|
mock_start_trace.return_value = mock_trace_context()
|
|
|
|
# Mock create_opik_logo_image to return a fake path
|
|
mock_logo_path = Path("/tmp/fake_logo.png")
|
|
mock_create_logo.return_value = mock_logo_path
|
|
|
|
# Mock the track decorator to return the function unchanged
|
|
def track_decorator(*args, **kwargs):
|
|
def decorator(func):
|
|
return func
|
|
|
|
return decorator
|
|
|
|
mock_track.side_effect = track_decorator
|
|
|
|
# Run the command without --project-name (should use default)
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
["healthcheck", "--smoke-test", "test-workspace"],
|
|
catch_exceptions=False,
|
|
)
|
|
|
|
# Assertions
|
|
assert result.exit_code == 0
|
|
# Verify client was created with default project name
|
|
mock_opik_class.assert_called_once()
|
|
call_kwargs = mock_opik_class.call_args[1]
|
|
assert call_kwargs["workspace"] == "test-workspace"
|
|
assert call_kwargs["project_name"] == "smoke-test-project" # Default value
|
|
# Verify trace was started with default project name
|
|
mock_start_trace.assert_called_once()
|
|
trace_call_kwargs = mock_start_trace.call_args[1]
|
|
assert trace_call_kwargs["project_name"] == "smoke-test-project"
|
|
|
|
|
|
class TestCheckPermissionsCommand:
|
|
"""Test the --check-permissions functionality via healthcheck command."""
|
|
|
|
def test_check_permissions_option__in_healthcheck_help__shown(self):
|
|
"""Test that --check-permissions option is shown in healthcheck help."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["healthcheck", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "--check-permissions" in result.output
|
|
assert "WORKSPACE" in result.output
|
|
|
|
def test_check_permissions__missing_workspace__raises_error(self):
|
|
"""Test that --check-permissions without a workspace value raises an error."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["healthcheck", "--check-permissions"])
|
|
assert result.exit_code != 0
|
|
assert "Error" in result.output or "Missing" in result.output
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.cli.check_user_permissions.run")
|
|
def test_check_permissions__workspace_provided__calls_run_with_workspace(
|
|
self,
|
|
mock_permissions_run,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that --check-permissions pass the workspace to check_user_permissions.run."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
["healthcheck", "--check-permissions", "my-workspace"],
|
|
catch_exceptions=False,
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
mock_permissions_run.assert_called_once_with(
|
|
api_key=None, workspace="my-workspace"
|
|
)
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.cli.check_user_permissions.run")
|
|
def test_check_permissions__api_key_in_cli_context__passes_api_key_to_run(
|
|
self,
|
|
mock_permissions_run,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that --check-permissions forward the api_key from CLI context."""
|
|
from opik.cli import cli as opik_cli
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
opik_cli,
|
|
[
|
|
"--api-key",
|
|
"test-api-key",
|
|
"healthcheck",
|
|
"--check-permissions",
|
|
"my-workspace",
|
|
],
|
|
catch_exceptions=False,
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
mock_permissions_run.assert_called_once_with(
|
|
api_key="test-api-key", workspace="my-workspace"
|
|
)
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.cli.check_user_permissions.run")
|
|
def test_check_permissions__empty_workspace__raises_bad_parameter(
|
|
self,
|
|
mock_permissions_run,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that --check-permissions with an empty workspace string raises BadParameter."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
["healthcheck", "--check-permissions", ""],
|
|
)
|
|
|
|
assert result.exit_code != 0
|
|
assert (
|
|
"Error" in result.output
|
|
or "requires a non-empty workspace name" in result.output
|
|
)
|
|
mock_permissions_run.assert_not_called()
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.cli.check_user_permissions.run")
|
|
def test_check_permissions__no_flag__not_called(
|
|
self,
|
|
mock_permissions_run,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that check_user_permissions.run is not called when --check-permissions is absent."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["healthcheck"], catch_exceptions=False)
|
|
|
|
assert result.exit_code == 0
|
|
mock_permissions_run.assert_not_called()
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.check_user_permissions.get_user_permissions")
|
|
@patch("opik.cli.healthcheck.check_user_permissions.config.OpikConfig")
|
|
def test_check_permissions__api_returns_user_and_workspace__displays_info(
|
|
self,
|
|
mock_opik_config,
|
|
mock_get_permissions,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that user and workspace info from API response are printed."""
|
|
mock_config = MagicMock()
|
|
mock_config.api_key = "test-api-key"
|
|
mock_config.workspace = "my-workspace"
|
|
mock_config.url_override = "https://opik.example.com"
|
|
mock_opik_config.return_value = mock_config
|
|
|
|
mock_get_permissions.return_value = {
|
|
"user_name": "alice",
|
|
"workspace_name": "my-workspace",
|
|
"permissions": [
|
|
{"permission_name": "read", "permission_value": True},
|
|
{"permission_name": "write", "permission_value": False},
|
|
],
|
|
}
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
["healthcheck", "--check-permissions", "my-workspace"],
|
|
catch_exceptions=False,
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
assert "alice" in result.output
|
|
assert "my-workspace" in result.output
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.check_user_permissions.get_user_permissions")
|
|
@patch("opik.cli.healthcheck.check_user_permissions.config.OpikConfig")
|
|
def test_check_permissions__connection_error__prints_error(
|
|
self,
|
|
mock_opik_config,
|
|
mock_get_permissions,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that a ConnectionError from the API prints an error message."""
|
|
mock_config = MagicMock()
|
|
mock_config.api_key = "test-api-key"
|
|
mock_config.workspace = "my-workspace"
|
|
mock_config.url_override = "https://opik.example.com"
|
|
mock_opik_config.return_value = mock_config
|
|
|
|
mock_get_permissions.side_effect = ConnectionError("Network error: timeout")
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
["healthcheck", "--check-permissions", "my-workspace"],
|
|
catch_exceptions=False,
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
assert "Failed to fetch user permissions" in result.output
|
|
|
|
@patch("opik.cli.healthcheck.cli.standard_check.run")
|
|
@patch("opik.cli.healthcheck.check_user_permissions.config.OpikConfig")
|
|
def test_check_permissions__missing_api_key__raises_value_error(
|
|
self,
|
|
mock_opik_config,
|
|
mock_standard_run,
|
|
):
|
|
"""Test that missing api_key (not in CLI context and not in config) raises ValueError."""
|
|
mock_config = MagicMock()
|
|
mock_config.api_key = None
|
|
mock_config.workspace = None
|
|
mock_config.url_override = "https://opik.example.com"
|
|
mock_opik_config.return_value = mock_config
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
cli,
|
|
["healthcheck", "--check-permissions", "my-workspace"],
|
|
)
|
|
|
|
assert result.exit_code != 0
|
|
assert isinstance(result.exception, ValueError)
|
|
assert "API key is required" in str(result.exception)
|