From 4d256b938ae5275dca1527e3c3a4f85bcb094afa Mon Sep 17 00:00:00 2001 From: Karan Shukla Date: Tue, 16 Jun 2026 00:14:26 +0700 Subject: [PATCH 1/3] fix(dms): remove instance_name from BindingData and auto-create test repositories --- pyproject.toml | 2 +- src/sap_cloud_sdk/dms/config.py | 12 +++++---- tests/dms/integration/conftest.py | 44 +++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a0c575f1..33eb66a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "sap-cloud-sdk" -version = "0.26.0" +version = "0.26.1" description = "SAP Cloud SDK for Python" readme = "README.md" license = "Apache-2.0" diff --git a/src/sap_cloud_sdk/dms/config.py b/src/sap_cloud_sdk/dms/config.py index f7ad14cc..3c7e66a7 100644 --- a/src/sap_cloud_sdk/dms/config.py +++ b/src/sap_cloud_sdk/dms/config.py @@ -19,7 +19,6 @@ class BindingData: uaa: JSON string containing XSUAA authentication credentials """ - instance_name: str uri: str uaa: str @@ -78,12 +77,15 @@ def _validate_uaa(self) -> None: f"UAA credentials missing required fields: {', '.join(sorted(missing_fields))}" ) - def to_credentials(self) -> DMSCredentials: + def to_credentials(self, instance_name: str) -> DMSCredentials: """Convert the binding data to DMSCredentials. Parses the UAA JSON and constructs a DMSCredentials object with the necessary information for authenticating and connecting to the DMS service. + Args: + instance_name: The logical instance name for these credentials. + Returns: DMSCredentials: The credentials extracted from the binding data """ @@ -91,7 +93,7 @@ def to_credentials(self) -> DMSCredentials: token_url = uaa_data["url"].rstrip("/") + "/oauth/token" return DMSCredentials( - instance_name=self.instance_name, + instance_name=instance_name, uri=self.uri, client_id=uaa_data["clientid"], client_secret=uaa_data["clientsecret"], @@ -114,7 +116,7 @@ def load_sdm_config_from_env_or_mount(instance: Optional[str] = None) -> DMSCred """ inst = instance or "default" binding = BindingData( - uri="", uaa="", instance_name="" + uri="", uaa="" ) # Initialize with empty values; will be populated by resolver try: @@ -129,7 +131,7 @@ def load_sdm_config_from_env_or_mount(instance: Optional[str] = None) -> DMSCred ) binding.validate() - return binding.to_credentials() + return binding.to_credentials(inst) except Exception as e: # Rely on the central secret resolver to provide aggregated, generic guidance diff --git a/tests/dms/integration/conftest.py b/tests/dms/integration/conftest.py index e26d4dec..632d5afe 100644 --- a/tests/dms/integration/conftest.py +++ b/tests/dms/integration/conftest.py @@ -1,8 +1,14 @@ from sap_cloud_sdk.dms import create_client +from sap_cloud_sdk.dms.model import InternalRepoRequest import pytest +import logging from pathlib import Path from dotenv import load_dotenv +logger = logging.getLogger(__name__) + +_SDK_TEST_REPO_PREFIX = "sdk-integration-test-" + @pytest.fixture(scope="session") def dms_client(): @@ -17,6 +23,44 @@ def dms_client(): pytest.skip(f"DMS integration tests require credentials: {e}") +@pytest.fixture(scope="session", autouse=True) +def _setup_test_repositories(dms_client): + """Create test repositories for integration tests and clean up after. + + Always onboards a standard and a version-enabled repository for the test + session, then deletes them on teardown. + """ + created_repos = [] + + logger.info("Onboarding test repositories") + repo = dms_client.onboard_repository( + InternalRepoRequest( + displayName=f"{_SDK_TEST_REPO_PREFIX}standard", + description="Auto-created by SDK integration tests", + ) + ) + created_repos.append(repo.id) + + repo = dms_client.onboard_repository( + InternalRepoRequest( + displayName=f"{_SDK_TEST_REPO_PREFIX}versioned", + description="Auto-created by SDK integration tests (versioning)", + isVersionEnabled=True, + ) + ) + created_repos.append(repo.id) + + yield + + # Cleanup: delete repositories we created + for repo_id in created_repos: + try: + dms_client.delete_repository(repo_id) + logger.info("Cleaned up test repository %s", repo_id) + except Exception as e: + logger.warning("Failed to clean up test repository %s: %s", repo_id, e) + + def _setup_cloud_mode(): """Common setup for cloud mode integration tests.""" env_file = Path(__file__).parents[3] / ".env_integration_tests" From f8a5f6e114f08e54f275c508cee29edd62c0101a Mon Sep 17 00:00:00 2001 From: Karan Shukla Date: Tue, 16 Jun 2026 00:33:40 +0700 Subject: [PATCH 2/3] chore: retrigger CI From 66c86a4d07a665c39d31ca2ecd2a10ddd0a676d2 Mon Sep 17 00:00:00 2001 From: Karan Shukla Date: Tue, 16 Jun 2026 15:09:09 +0700 Subject: [PATCH 3/3] fix(dms): remove instance_name from DMSCredentials and update INTEGRATION_TESTS.md --- docs/INTEGRATION_TESTS.md | 13 +++++++++++++ src/sap_cloud_sdk/dms/client.py | 4 +--- src/sap_cloud_sdk/dms/config.py | 8 ++------ src/sap_cloud_sdk/dms/model.py | 1 - tests/dms/unit/test_client_admin.py | 1 - tests/dms/unit/test_client_cmis.py | 1 - 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/INTEGRATION_TESTS.md b/docs/INTEGRATION_TESTS.md index a5ca3c77..3fb9294d 100644 --- a/docs/INTEGRATION_TESTS.md +++ b/docs/INTEGRATION_TESTS.md @@ -96,6 +96,18 @@ CLOUD_SDK_CFG_DATA_ANONYMIZATION_DEFAULT_DESTINATION_NAME=your-client-certificat The destination must be configured with `ClientCertificateAuthentication` and reference a certificate bundle containing the client certificate and private key. +### DMS Integration Tests + +For DMS (Document Management Service) integration tests, configure the following variables in `.env_integration_tests`: + +```bash +# DMS Configuration +CLOUD_SDK_CFG_SDM_DEFAULT_URI=https://your-sdm-api-uri-here +CLOUD_SDK_CFG_SDM_DEFAULT_UAA='{"url":"https://your-auth-url","clientid":"your-client-id","clientsecret":"your-client-secret","identityzone":"your-identity-zone"}' +``` + +**Note**: The test fixture automatically onboards test repositories (standard and version-enabled) at session start and cleans them up on teardown. No pre-existing repositories are required. + ### ADMS Integration Tests For ADMS (Advanced Document Management Service) integration tests, configure the following variables in `.env_integration_tests`: @@ -145,6 +157,7 @@ uv run pytest tests/core/integration/auditlog -v uv run pytest tests/core/integration/data_anonymization -v uv run pytest tests/objectstore/integration/ -v uv run pytest tests/destination/integration/ -v +uv run pytest tests/dms/integration/ -v uv run pytest tests/agent_memory/integration/ -v uv run pytest tests/adms/integration/ -v uv run pytest tests/agentgateway/integration/ -v diff --git a/src/sap_cloud_sdk/dms/client.py b/src/sap_cloud_sdk/dms/client.py index 0f1c4abd..61f7b3ec 100644 --- a/src/sap_cloud_sdk/dms/client.py +++ b/src/sap_cloud_sdk/dms/client.py @@ -110,9 +110,7 @@ def __init__( read_timeout=read_timeout, ) self._telemetry_source: Optional[Module] = None - logger.debug( - "DMSClient initialized for instance '%s'", credentials.instance_name - ) + logger.debug("DMSClient initialized") @record_metrics(Module.DMS, Operation.DMS_ONBOARD_REPOSITORY) def onboard_repository( diff --git a/src/sap_cloud_sdk/dms/config.py b/src/sap_cloud_sdk/dms/config.py index 3c7e66a7..8a396e16 100644 --- a/src/sap_cloud_sdk/dms/config.py +++ b/src/sap_cloud_sdk/dms/config.py @@ -77,15 +77,12 @@ def _validate_uaa(self) -> None: f"UAA credentials missing required fields: {', '.join(sorted(missing_fields))}" ) - def to_credentials(self, instance_name: str) -> DMSCredentials: + def to_credentials(self) -> DMSCredentials: """Convert the binding data to DMSCredentials. Parses the UAA JSON and constructs a DMSCredentials object with the necessary information for authenticating and connecting to the DMS service. - Args: - instance_name: The logical instance name for these credentials. - Returns: DMSCredentials: The credentials extracted from the binding data """ @@ -93,7 +90,6 @@ def to_credentials(self, instance_name: str) -> DMSCredentials: token_url = uaa_data["url"].rstrip("/") + "/oauth/token" return DMSCredentials( - instance_name=instance_name, uri=self.uri, client_id=uaa_data["clientid"], client_secret=uaa_data["clientsecret"], @@ -131,7 +127,7 @@ def load_sdm_config_from_env_or_mount(instance: Optional[str] = None) -> DMSCred ) binding.validate() - return binding.to_credentials(inst) + return binding.to_credentials() except Exception as e: # Rely on the central secret resolver to provide aggregated, generic guidance diff --git a/src/sap_cloud_sdk/dms/model.py b/src/sap_cloud_sdk/dms/model.py index f84a7a50..b08f1d0f 100644 --- a/src/sap_cloud_sdk/dms/model.py +++ b/src/sap_cloud_sdk/dms/model.py @@ -30,7 +30,6 @@ def _to_dict_drop_none(obj: Any) -> dict[str, Any]: class DMSCredentials: """Credentials for authenticating with the DMS service.""" - instance_name: str uri: str client_id: str client_secret: str diff --git a/tests/dms/unit/test_client_admin.py b/tests/dms/unit/test_client_admin.py index 5b783c21..fcdb8009 100644 --- a/tests/dms/unit/test_client_admin.py +++ b/tests/dms/unit/test_client_admin.py @@ -72,7 +72,6 @@ def client(): mock_http = Mock() MockHttp.return_value = mock_http creds = DMSCredentials( - instance_name="test-instance", uri="https://api.example.com", client_id="test-client", client_secret="test-secret", diff --git a/tests/dms/unit/test_client_cmis.py b/tests/dms/unit/test_client_cmis.py index 1d9c59cc..80a08931 100644 --- a/tests/dms/unit/test_client_cmis.py +++ b/tests/dms/unit/test_client_cmis.py @@ -100,7 +100,6 @@ def _mock_response(data): def client(): """Create a DMSClient with a mocked HttpInvoker.""" creds = DMSCredentials( - instance_name="test-instance", uri="https://api.example.com", client_id="test-client", client_secret="test-secret",