|
8 | 8 | import pytest |
9 | 9 |
|
10 | 10 | from databricks.sdk import oauth, useragent |
11 | | -from databricks.sdk.config import Config, with_product, with_user_agent_extra |
| 11 | +from databricks.sdk.config import (ClientType, Config, HostType, with_product, |
| 12 | + with_user_agent_extra) |
12 | 13 | from databricks.sdk.version import __version__ |
13 | 14 |
|
14 | 15 | from .conftest import noop_credentials, set_az_path |
@@ -260,3 +261,195 @@ def test_oauth_token_reuses_existing_provider(mocker): |
260 | 261 | # Both calls should work and use the same provider instance |
261 | 262 | assert token1 == token2 == mock_token |
262 | 263 | assert mock_oauth_provider.oauth_token.call_count == 2 |
| 264 | + |
| 265 | + |
| 266 | +def test_host_type_workspace(): |
| 267 | + """Test that a regular workspace host is identified correctly.""" |
| 268 | + config = Config(host="https://test.databricks.com", token="test-token") |
| 269 | + assert config.host_type == HostType.WORKSPACE |
| 270 | + |
| 271 | + |
| 272 | +def test_host_type_accounts(): |
| 273 | + """Test that an accounts host is identified correctly.""" |
| 274 | + config = Config(host="https://accounts.cloud.databricks.com", account_id="test-account", token="test-token") |
| 275 | + assert config.host_type == HostType.ACCOUNTS |
| 276 | + |
| 277 | + |
| 278 | +def test_host_type_accounts_dod(): |
| 279 | + """Test that an accounts-dod host is identified correctly.""" |
| 280 | + config = Config(host="https://accounts-dod.cloud.databricks.us", account_id="test-account", token="test-token") |
| 281 | + assert config.host_type == HostType.ACCOUNTS |
| 282 | + |
| 283 | + |
| 284 | +def test_host_type_unified(): |
| 285 | + """Test that a unified host is identified when experimental flag is set.""" |
| 286 | + config = Config( |
| 287 | + host="https://unified.databricks.com", |
| 288 | + workspace_id="test-workspace", |
| 289 | + experimental_is_unified_host=True, |
| 290 | + token="test-token", |
| 291 | + ) |
| 292 | + assert config.host_type == HostType.UNIFIED |
| 293 | + |
| 294 | + |
| 295 | +def test_client_type_workspace(): |
| 296 | + """Test that client type is workspace when workspace_id is set on unified host.""" |
| 297 | + config = Config( |
| 298 | + host="https://unified.databricks.com", |
| 299 | + workspace_id="test-workspace", |
| 300 | + account_id="test-account", |
| 301 | + experimental_is_unified_host=True, |
| 302 | + token="test-token", |
| 303 | + ) |
| 304 | + assert config.client_type == ClientType.WORKSPACE |
| 305 | + |
| 306 | + |
| 307 | +def test_client_type_account(): |
| 308 | + """Test that client type is account when account_id is set without workspace_id.""" |
| 309 | + config = Config( |
| 310 | + host="https://unified.databricks.com", |
| 311 | + account_id="test-account", |
| 312 | + experimental_is_unified_host=True, |
| 313 | + token="test-token", |
| 314 | + ) |
| 315 | + assert config.client_type == ClientType.ACCOUNT |
| 316 | + |
| 317 | + |
| 318 | +def test_client_type_workspace_default(): |
| 319 | + """Test that client type defaults to workspace.""" |
| 320 | + config = Config(host="https://test.databricks.com", token="test-token") |
| 321 | + assert config.client_type == ClientType.WORKSPACE |
| 322 | + |
| 323 | + |
| 324 | +def test_client_type_accounts_host(): |
| 325 | + """Test that client type is account for accounts host.""" |
| 326 | + config = Config( |
| 327 | + host="https://accounts.cloud.databricks.com", |
| 328 | + account_id="test-account", |
| 329 | + token="test-token", |
| 330 | + ) |
| 331 | + assert config.client_type == ClientType.ACCOUNT |
| 332 | + |
| 333 | + |
| 334 | +def test_client_type_unified_without_account_id(): |
| 335 | + """Test that client type raises error for unified host without account_id.""" |
| 336 | + config = Config( |
| 337 | + host="https://unified.databricks.com", |
| 338 | + experimental_is_unified_host=True, |
| 339 | + token="test-token", |
| 340 | + ) |
| 341 | + with pytest.raises(ValueError, match="Unified host requires account_id"): |
| 342 | + _ = config.client_type |
| 343 | + |
| 344 | + |
| 345 | +def test_is_account_client_backward_compatibility(): |
| 346 | + """Test that is_account_client property still works for backward compatibility.""" |
| 347 | + config_workspace = Config(host="https://test.databricks.com", token="test-token") |
| 348 | + assert not config_workspace.is_account_client |
| 349 | + |
| 350 | + config_account = Config(host="https://accounts.cloud.databricks.com", account_id="test-account", token="test-token") |
| 351 | + assert config_account.is_account_client |
| 352 | + |
| 353 | + |
| 354 | +def test_is_account_client_raises_on_unified_host(): |
| 355 | + """Test that is_account_client raises ValueError when used with unified hosts.""" |
| 356 | + config = Config( |
| 357 | + host="https://unified.databricks.com", |
| 358 | + experimental_is_unified_host=True, |
| 359 | + workspace_id="test-workspace", |
| 360 | + token="test-token", |
| 361 | + ) |
| 362 | + with pytest.raises(ValueError, match="is_account_client cannot be used with unified hosts"): |
| 363 | + _ = config.is_account_client |
| 364 | + |
| 365 | + |
| 366 | +def test_oidc_endpoints_unified_workspace(mocker, requests_mock): |
| 367 | + """Test that oidc_endpoints returns unified endpoints for workspace on unified host.""" |
| 368 | + requests_mock.get( |
| 369 | + "https://unified.databricks.com/oidc/accounts/test-account/.well-known/oauth-authorization-server", |
| 370 | + json={ |
| 371 | + "authorization_endpoint": "https://unified.databricks.com/oidc/accounts/test-account/v1/authorize", |
| 372 | + "token_endpoint": "https://unified.databricks.com/oidc/accounts/test-account/v1/token", |
| 373 | + }, |
| 374 | + ) |
| 375 | + |
| 376 | + config = Config( |
| 377 | + host="https://unified.databricks.com", |
| 378 | + workspace_id="test-workspace", |
| 379 | + account_id="test-account", |
| 380 | + experimental_is_unified_host=True, |
| 381 | + token="test-token", |
| 382 | + ) |
| 383 | + |
| 384 | + endpoints = config.oidc_endpoints |
| 385 | + assert endpoints is not None |
| 386 | + assert "accounts/test-account" in endpoints.authorization_endpoint |
| 387 | + assert "accounts/test-account" in endpoints.token_endpoint |
| 388 | + |
| 389 | + |
| 390 | +def test_oidc_endpoints_unified_account(mocker, requests_mock): |
| 391 | + """Test that oidc_endpoints returns account endpoints for account on unified host.""" |
| 392 | + requests_mock.get( |
| 393 | + "https://unified.databricks.com/oidc/accounts/test-account/.well-known/oauth-authorization-server", |
| 394 | + json={ |
| 395 | + "authorization_endpoint": "https://unified.databricks.com/oidc/accounts/test-account/v1/authorize", |
| 396 | + "token_endpoint": "https://unified.databricks.com/oidc/accounts/test-account/v1/token", |
| 397 | + }, |
| 398 | + ) |
| 399 | + |
| 400 | + config = Config( |
| 401 | + host="https://unified.databricks.com", |
| 402 | + account_id="test-account", |
| 403 | + experimental_is_unified_host=True, |
| 404 | + token="test-token", |
| 405 | + ) |
| 406 | + |
| 407 | + endpoints = config.oidc_endpoints |
| 408 | + assert endpoints is not None |
| 409 | + assert "accounts/test-account" in endpoints.authorization_endpoint |
| 410 | + assert "accounts/test-account" in endpoints.token_endpoint |
| 411 | + |
| 412 | + |
| 413 | +def test_oidc_endpoints_unified_missing_ids(): |
| 414 | + """Test that oidc_endpoints raises error when unified host lacks required account_id.""" |
| 415 | + config = Config(host="https://unified.databricks.com", experimental_is_unified_host=True, token="test-token") |
| 416 | + |
| 417 | + with pytest.raises(ValueError) as exc_info: |
| 418 | + _ = config.oidc_endpoints |
| 419 | + |
| 420 | + assert "Unified host requires account_id" in str(exc_info.value) |
| 421 | + |
| 422 | + |
| 423 | +def test_workspace_org_id_header_on_unified_host(requests_mock): |
| 424 | + """Test that X-Databricks-Org-Id header is added for workspace clients on unified hosts.""" |
| 425 | + from databricks.sdk.core import ApiClient |
| 426 | + |
| 427 | + requests_mock.get("https://unified.databricks.com/api/2.0/test", json={"result": "success"}) |
| 428 | + |
| 429 | + config = Config( |
| 430 | + host="https://unified.databricks.com", |
| 431 | + workspace_id="test-workspace-123", |
| 432 | + experimental_is_unified_host=True, |
| 433 | + token="test-token", |
| 434 | + ) |
| 435 | + |
| 436 | + api_client = ApiClient(config) |
| 437 | + api_client.do("GET", "/api/2.0/test") |
| 438 | + |
| 439 | + # Verify the request was made with the X-Databricks-Org-Id header |
| 440 | + assert requests_mock.last_request.headers.get("X-Databricks-Org-Id") == "test-workspace-123" |
| 441 | + |
| 442 | + |
| 443 | +def test_no_org_id_header_on_regular_workspace(requests_mock): |
| 444 | + """Test that X-Databricks-Org-Id header is NOT added for regular workspace hosts.""" |
| 445 | + from databricks.sdk.core import ApiClient |
| 446 | + |
| 447 | + requests_mock.get("https://test.databricks.com/api/2.0/test", json={"result": "success"}) |
| 448 | + |
| 449 | + config = Config(host="https://test.databricks.com", token="test-token") |
| 450 | + |
| 451 | + api_client = ApiClient(config) |
| 452 | + api_client.do("GET", "/api/2.0/test") |
| 453 | + |
| 454 | + # Verify the X-Databricks-Org-Id header was NOT added |
| 455 | + assert "X-Databricks-Org-Id" not in requests_mock.last_request.headers |
0 commit comments