From e3168fe90b0a41b3271ff3c3a7646fdaf7d50f3f Mon Sep 17 00:00:00 2001 From: yaelibarg Date: Wed, 29 Jan 2025 12:25:20 +0200 Subject: [PATCH 1/4] added new integration setting - calculate entities diff , to control if we want to calcualte diff or just upsert all --- port_ocean/config/settings.py | 1 + .../core/integrations/mixins/sync_raw.py | 44 ++++++++------- .../core/handlers/mixins/test_sync_raw.py | 54 ++++++++++++++++--- 3 files changed, 72 insertions(+), 27 deletions(-) diff --git a/port_ocean/config/settings.py b/port_ocean/config/settings.py index 6ca685a1b8..181803686b 100644 --- a/port_ocean/config/settings.py +++ b/port_ocean/config/settings.py @@ -46,6 +46,7 @@ class IntegrationSettings(BaseOceanModel, extra=Extra.allow): identifier: str type: str config: Any = Field(default_factory=dict) + calculate_entities_diff: bool = True @root_validator(pre=True) def root_validator(cls, values: dict[str, Any]) -> dict[str, Any]: diff --git a/port_ocean/core/integrations/mixins/sync_raw.py b/port_ocean/core/integrations/mixins/sync_raw.py index c91754f869..7c10cdc2fc 100644 --- a/port_ocean/core/integrations/mixins/sync_raw.py +++ b/port_ocean/core/integrations/mixins/sync_raw.py @@ -220,26 +220,32 @@ async def _register_resource_raw( ) modified_objects = [] - try: - changed_entities = await self._map_entities_compared_with_port( - objects_diff[0].entity_selector_diff.passed, - resource, - user_agent_type - ) - if changed_entities: - logger.info("Upserting changed entities", changed_entities=len(changed_entities), - total_entities=len(objects_diff[0].entity_selector_diff.passed)) - await self.entities_state_applier.upsert( - changed_entities, user_agent_type - ) - else: - logger.info("Entities in batch didn't changed since last sync, skipping", total_entities=len(objects_diff[0].entity_selector_diff.passed)) - modified_objects = [ocean.port_client._reduce_entity(entity) for entity in objects_diff[0].entity_selector_diff.passed] - except Exception as e: - logger.warning(f"Failed to resolve batch entities with Port, falling back to upserting all entities: {str(e)}") - modified_objects = await self.entities_state_applier.upsert( - objects_diff[0].entity_selector_diff.passed, user_agent_type + if ocean.config.integration.calculate_entities_diff: + try: + changed_entities = await self._map_entities_compared_with_port( + objects_diff[0].entity_selector_diff.passed, + resource, + user_agent_type ) + if changed_entities: + logger.info("Upserting changed entities", changed_entities=len(changed_entities), + total_entities=len(objects_diff[0].entity_selector_diff.passed)) + await self.entities_state_applier.upsert( + changed_entities, user_agent_type + ) + else: + logger.info("Entities in batch didn't changed since last sync, skipping", total_entities=len(objects_diff[0].entity_selector_diff.passed)) + modified_objects = [ocean.port_client._reduce_entity(entity) for entity in objects_diff[0].entity_selector_diff.passed] + except Exception as e: + logger.warning(f"Failed to resolve batch entities with Port, falling back to upserting all entities: {str(e)}") + modified_objects = await self.entities_state_applier.upsert( + objects_diff[0].entity_selector_diff.passed, user_agent_type + ) + else: + modified_objects = await self.entities_state_applier.upsert( + objects_diff[0].entity_selector_diff.passed, user_agent_type + ) + return CalculationResult( objects_diff[0].entity_selector_diff._replace(passed=modified_objects), diff --git a/port_ocean/tests/core/handlers/mixins/test_sync_raw.py b/port_ocean/tests/core/handlers/mixins/test_sync_raw.py index b0143a7fb4..f9afabfca7 100644 --- a/port_ocean/tests/core/handlers/mixins/test_sync_raw.py +++ b/port_ocean/tests/core/handlers/mixins/test_sync_raw.py @@ -435,8 +435,8 @@ async def test_register_raw( mock_sync_raw_mixin_with_jq_processor: SyncRawMixin, mock_resource_config: ResourceConfig, ) -> None: - # Mock the integration settings with skip_check_diff - with patch.object(ocean.config.integration, "skip_check_diff", False): + # Mock the integration settings with calculate_entities_diff + with patch.object(ocean.config.integration, "calculate_entities_diff", True): kind = "service" user_agent_type = UserAgentType.exporter raw_entity = [ @@ -689,8 +689,8 @@ async def test_register_resource_raw_no_changes_upsert_not_called_entitiy_is_ret mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig, ) -> None: - # Mock the integration settings with skip_check_diff - with patch.object(ocean.config.integration, "skip_check_diff", False): + # Mock the integration settings with calculate_entities_diff + with patch.object(ocean.config.integration, "calculate_entities_diff", True): entity = Entity(identifier="1", blueprint="service") mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), errors=[], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([])) # type: ignore @@ -720,8 +720,8 @@ async def test_register_resource_raw_with_changes_upsert_called_and_entities_are mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig, ) -> None: - # Mock the integration settings with skip_check_diff - with patch.object(ocean.config.integration, "skip_check_diff", False): + # Mock the integration settings with calculate_entities_diff + with patch.object(ocean.config.integration, "calculate_entities_diff", True): entity = Entity(identifier="1", blueprint="service") mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), errors=[], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([entity])) # type: ignore @@ -748,8 +748,8 @@ async def test_register_resource_raw_with_changes_upsert_called_and_entities_are async def test_register_resource_raw_with_errors( mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig ) -> None: - # Mock the integration settings with skip_check_diff - with patch.object(ocean.config.integration, "skip_check_diff", False): + # Mock the integration settings with calculate_entities_diff + with patch.object(ocean.config.integration, "calculate_entities_diff", True): failed_entity = Entity(identifier="1", blueprint="service") error = Exception("Test error") mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[], failed=[failed_entity]), errors=[error], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore @@ -774,3 +774,41 @@ async def test_register_resource_raw_with_errors( mock_sync_raw_mixin._calculate_raw.assert_called_once() mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() mock_sync_raw_mixin.entities_state_applier.upsert.assert_not_called() + + +@pytest.mark.asyncio +async def test_register_resource_raw_skip_calculate_entities_diff_upsert_called_and_no_entitites_diff_calculation( + mock_sync_raw_mixin: SyncRawMixin, + mock_port_app_config: PortAppConfig, + mock_context: PortOceanContext, + monkeypatch: pytest.MonkeyPatch, +) -> None: + # Mock ocean.app.is_saas() + with patch.object(ocean.config.integration, "calculate_entities_diff", False): + # Mock dependencies + entity = Entity(identifier="1", blueprint="service") + calculation_result = CalculationResult( + entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), + errors=[], + misconfigurations=[], + misonfigured_entity_keys=[], + ) + mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[calculation_result]) # type: ignore + mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock() # type: ignore + mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock(return_value=[entity]) # type: ignore + + async with event_context(EventType.RESYNC, trigger_type="machine") as event: + event.port_app_config = mock_port_app_config + + # Test execution + result = await mock_sync_raw_mixin._register_resource_raw( + mock_port_app_config.resources[0], + [{"some": "data"}], + UserAgentType.exporter, + ) + + # Assertions + assert len(result.entity_selector_diff.passed) == 1 + mock_sync_raw_mixin._calculate_raw.assert_called_once() + mock_sync_raw_mixin._map_entities_compared_with_port.assert_not_called() + mock_sync_raw_mixin.entities_state_applier.upsert.assert_called_once() From ac26f527e4168c80cefaa321786f8bf6c9891fc6 Mon Sep 17 00:00:00 2001 From: yaelibarg Date: Wed, 29 Jan 2025 15:32:41 +0200 Subject: [PATCH 2/4] bumped version --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1e2fa3303..ef587b954a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.18.6 (2025-01-29) + +### Improvements + +- Entity diff calculation as optional feature + ## 0.18.5 (2025-01-28) ### Bug Fixes diff --git a/pyproject.toml b/pyproject.toml index b895f6699a..fc23e6971d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "port-ocean" -version = "0.18.5" +version = "0.18.6" description = "Port Ocean is a CLI tool for managing your Port projects." readme = "README.md" homepage = "https://app.getport.io" From ee0e2006178a477f52a36b33eab2d8a3314f21a7 Mon Sep 17 00:00:00 2001 From: yaelibarg Date: Wed, 29 Jan 2025 18:24:50 +0200 Subject: [PATCH 3/4] fixed the pr - only on resync --- CHANGELOG.md | 2 +- port_ocean/config/settings.py | 1 - .../core/handlers/port_app_config/models.py | 2 +- .../core/integrations/mixins/sync_raw.py | 2 +- .../core/handlers/mixins/test_sync_raw.py | 291 +++++++++--------- 5 files changed, 142 insertions(+), 156 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef587b954a..5d50ec9fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Improvements -- Entity diff calculation as optional feature +- Entity diff calculation only on resync ## 0.18.5 (2025-01-28) diff --git a/port_ocean/config/settings.py b/port_ocean/config/settings.py index 181803686b..6ca685a1b8 100644 --- a/port_ocean/config/settings.py +++ b/port_ocean/config/settings.py @@ -46,7 +46,6 @@ class IntegrationSettings(BaseOceanModel, extra=Extra.allow): identifier: str type: str config: Any = Field(default_factory=dict) - calculate_entities_diff: bool = True @root_validator(pre=True) def root_validator(cls, values: dict[str, Any]) -> dict[str, Any]: diff --git a/port_ocean/core/handlers/port_app_config/models.py b/port_ocean/core/handlers/port_app_config/models.py index bb37fd0598..7729f520c0 100644 --- a/port_ocean/core/handlers/port_app_config/models.py +++ b/port_ocean/core/handlers/port_app_config/models.py @@ -50,7 +50,7 @@ class ResourceConfig(BaseModel): port: PortResourceConfig -class PortAppConfig(BaseModel): +class PortAppConfig(BaseModel): # add here entityDeletionThreshold enable_merge_entity: bool = Field(alias="enableMergeEntity", default=True) delete_dependent_entities: bool = Field( alias="deleteDependentEntities", default=True diff --git a/port_ocean/core/integrations/mixins/sync_raw.py b/port_ocean/core/integrations/mixins/sync_raw.py index 7c10cdc2fc..87e26b8491 100644 --- a/port_ocean/core/integrations/mixins/sync_raw.py +++ b/port_ocean/core/integrations/mixins/sync_raw.py @@ -220,7 +220,7 @@ async def _register_resource_raw( ) modified_objects = [] - if ocean.config.integration.calculate_entities_diff: + if event.event_type == EventType.RESYNC: try: changed_entities = await self._map_entities_compared_with_port( objects_diff[0].entity_selector_diff.passed, diff --git a/port_ocean/tests/core/handlers/mixins/test_sync_raw.py b/port_ocean/tests/core/handlers/mixins/test_sync_raw.py index f9afabfca7..917c9ff155 100644 --- a/port_ocean/tests/core/handlers/mixins/test_sync_raw.py +++ b/port_ocean/tests/core/handlers/mixins/test_sync_raw.py @@ -435,66 +435,63 @@ async def test_register_raw( mock_sync_raw_mixin_with_jq_processor: SyncRawMixin, mock_resource_config: ResourceConfig, ) -> None: - # Mock the integration settings with calculate_entities_diff - with patch.object(ocean.config.integration, "calculate_entities_diff", True): - kind = "service" - user_agent_type = UserAgentType.exporter - raw_entity = [ - {"id": "entity_1", "name": "entity_1", "web_url": "https://example.com"}, - ] - expected_result = [ - { - "identifier": "entity_1", - "blueprint": "service", - "name": "entity_1", - "properties": {}, - }, - ] - async with event_context( - EventType.HTTP_REQUEST, trigger_type="machine" - ) as event: - # Use patch to mock the method instead of direct assignment + kind = "service" + user_agent_type = UserAgentType.exporter + raw_entity = [ + {"id": "entity_1", "name": "entity_1", "web_url": "https://example.com"}, + ] + expected_result = [ + { + "identifier": "entity_1", + "blueprint": "service", + "name": "entity_1", + "properties": {"url": "https://example.com"}, + }, + ] + + async with event_context(EventType.HTTP_REQUEST, trigger_type="machine") as event: + # Use patch to mock the method instead of direct assignment + with patch.object( + mock_sync_raw_mixin_with_jq_processor.port_app_config_handler, + "get_port_app_config", + return_value=PortAppConfig( + enable_merge_entity=True, + delete_dependent_entities=True, + create_missing_related_entities=False, + resources=[mock_resource_config], + ), + ): + # Ensure the event.port_app_config is set correctly + event.port_app_config = await mock_sync_raw_mixin_with_jq_processor.port_app_config_handler.get_port_app_config( + use_cache=False + ) + + def upsert_side_effect( + entities: list[Entity], user_agent_type: UserAgentType + ) -> list[Entity]: + # Simulate returning the passed entities + return entities + + # Patch the upsert method with the side effect with patch.object( - mock_sync_raw_mixin_with_jq_processor.port_app_config_handler, - "get_port_app_config", - return_value=PortAppConfig( - enable_merge_entity=True, - delete_dependent_entities=True, - create_missing_related_entities=False, - resources=[mock_resource_config], - ), + mock_sync_raw_mixin_with_jq_processor.entities_state_applier, + "upsert", + side_effect=upsert_side_effect, ): - # Ensure the event.port_app_config is set correctly - event.port_app_config = await mock_sync_raw_mixin_with_jq_processor.port_app_config_handler.get_port_app_config( - use_cache=False - ) - - def upsert_side_effect( - entities: list[Entity], user_agent_type: UserAgentType - ) -> list[Entity]: - # Simulate returning the passed entities - return entities - - # Patch the upsert method with the side effect - with patch.object( - mock_sync_raw_mixin_with_jq_processor.entities_state_applier, - "upsert", - side_effect=upsert_side_effect, - ): - # Call the register_raw method - registered_entities = ( - await mock_sync_raw_mixin_with_jq_processor.register_raw( - kind, raw_entity, user_agent_type - ) + # Call the register_raw method + registered_entities = ( + await mock_sync_raw_mixin_with_jq_processor.register_raw( + kind, raw_entity, user_agent_type ) + ) - # Assert that the registered entities match the expected results - assert len(registered_entities) == len(expected_result) - for entity, result in zip(registered_entities, expected_result): - assert entity.identifier == result["identifier"] - assert entity.blueprint == result["blueprint"] - assert entity.properties == result["properties"] + # Assert that the registered entities match the expected results + assert len(registered_entities) == len(expected_result) + for entity, result in zip(registered_entities, expected_result): + assert entity.identifier == result["identifier"] + assert entity.blueprint == result["blueprint"] + assert entity.properties == result["properties"] @pytest.mark.asyncio @@ -689,30 +686,26 @@ async def test_register_resource_raw_no_changes_upsert_not_called_entitiy_is_ret mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig, ) -> None: - # Mock the integration settings with calculate_entities_diff - with patch.object(ocean.config.integration, "calculate_entities_diff", True): - entity = Entity(identifier="1", blueprint="service") - mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), errors=[], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore - mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([])) # type: ignore - mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock() # type: ignore - - async with event_context(EventType.RESYNC, trigger_type="machine") as event: - event.port_app_config = mock_port_app_config - - # Test execution - result = await mock_sync_raw_mixin._register_resource_raw( - mock_port_app_config.resources[ - 0 - ], # Use the first resource from the config - [{"some": "data"}], - UserAgentType.exporter, - ) + entity = Entity(identifier="1", blueprint="service") + mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), errors=[], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore + mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([])) # type: ignore + mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock() # type: ignore - # Assertions - assert len(result.entity_selector_diff.passed) == 1 - mock_sync_raw_mixin._calculate_raw.assert_called_once() - mock_sync_raw_mixin.entities_state_applier.upsert.assert_not_called() - mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() + async with event_context(EventType.RESYNC, trigger_type="machine") as event: + event.port_app_config = mock_port_app_config + + # Test execution + result = await mock_sync_raw_mixin._register_resource_raw( + mock_port_app_config.resources[0], # Use the first resource from the config + [{"some": "data"}], + UserAgentType.exporter, + ) + + # Assertions + assert len(result.entity_selector_diff.passed) == 1 + mock_sync_raw_mixin._calculate_raw.assert_called_once() + mock_sync_raw_mixin.entities_state_applier.upsert.assert_not_called() + mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() @pytest.mark.asyncio @@ -720,95 +713,89 @@ async def test_register_resource_raw_with_changes_upsert_called_and_entities_are mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig, ) -> None: - # Mock the integration settings with calculate_entities_diff - with patch.object(ocean.config.integration, "calculate_entities_diff", True): - entity = Entity(identifier="1", blueprint="service") - mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), errors=[], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore - mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([entity])) # type: ignore - mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock(return_value=[entity]) # type: ignore - - async with event_context(EventType.RESYNC, trigger_type="machine") as event: - event.port_app_config = mock_port_app_config - - # Test execution - result = await mock_sync_raw_mixin._register_resource_raw( - mock_port_app_config.resources[0], - [{"some": "data"}], - UserAgentType.exporter, - ) + entity = Entity(identifier="1", blueprint="service") + mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), errors=[], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore + mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([entity])) # type: ignore + mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock(return_value=[entity]) # type: ignore - # Assertions - assert len(result.entity_selector_diff.passed) == 1 - mock_sync_raw_mixin._calculate_raw.assert_called_once() - mock_sync_raw_mixin.entities_state_applier.upsert.assert_called_once() - mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() + async with event_context(EventType.RESYNC, trigger_type="machine") as event: + event.port_app_config = mock_port_app_config + + # Test execution + result = await mock_sync_raw_mixin._register_resource_raw( + mock_port_app_config.resources[0], + [{"some": "data"}], + UserAgentType.exporter, + ) + + # Assertions + assert len(result.entity_selector_diff.passed) == 1 + mock_sync_raw_mixin._calculate_raw.assert_called_once() + mock_sync_raw_mixin.entities_state_applier.upsert.assert_called_once() + mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() @pytest.mark.asyncio async def test_register_resource_raw_with_errors( mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig ) -> None: - # Mock the integration settings with calculate_entities_diff - with patch.object(ocean.config.integration, "calculate_entities_diff", True): - failed_entity = Entity(identifier="1", blueprint="service") - error = Exception("Test error") - mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[], failed=[failed_entity]), errors=[error], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore - mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([])) # type: ignore - mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock() # type: ignore - - async with event_context(EventType.RESYNC, trigger_type="machine") as event: - event.port_app_config = mock_port_app_config - - # Test execution - result = await mock_sync_raw_mixin._register_resource_raw( - mock_port_app_config.resources[0], - [{"some": "data"}], - UserAgentType.exporter, - ) + failed_entity = Entity(identifier="1", blueprint="service") + error = Exception("Test error") + mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[CalculationResult(entity_selector_diff=EntitySelectorDiff(passed=[], failed=[failed_entity]), errors=[error], misconfigurations=[], misonfigured_entity_keys=[])]) # type: ignore + mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock(return_value=([])) # type: ignore + mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock() # type: ignore + + async with event_context(EventType.RESYNC, trigger_type="machine") as event: + event.port_app_config = mock_port_app_config - # Assertions - assert len(result.entity_selector_diff.passed) == 0 - assert len(result.entity_selector_diff.failed) == 1 - assert len(result.errors) == 1 - assert result.errors[0] == error - mock_sync_raw_mixin._calculate_raw.assert_called_once() - mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() - mock_sync_raw_mixin.entities_state_applier.upsert.assert_not_called() + # Test execution + result = await mock_sync_raw_mixin._register_resource_raw( + mock_port_app_config.resources[0], + [{"some": "data"}], + UserAgentType.exporter, + ) + + # Assertions + assert len(result.entity_selector_diff.passed) == 0 + assert len(result.entity_selector_diff.failed) == 1 + assert len(result.errors) == 1 + assert result.errors[0] == error + mock_sync_raw_mixin._calculate_raw.assert_called_once() + mock_sync_raw_mixin._map_entities_compared_with_port.assert_called_once() + mock_sync_raw_mixin.entities_state_applier.upsert.assert_not_called() @pytest.mark.asyncio -async def test_register_resource_raw_skip_calculate_entities_diff_upsert_called_and_no_entitites_diff_calculation( +async def test_register_resource_raw_skip_event_type_http_request_upsert_called_and_no_entitites_diff_calculation( mock_sync_raw_mixin: SyncRawMixin, mock_port_app_config: PortAppConfig, mock_context: PortOceanContext, monkeypatch: pytest.MonkeyPatch, ) -> None: - # Mock ocean.app.is_saas() - with patch.object(ocean.config.integration, "calculate_entities_diff", False): - # Mock dependencies - entity = Entity(identifier="1", blueprint="service") - calculation_result = CalculationResult( - entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), - errors=[], - misconfigurations=[], - misonfigured_entity_keys=[], + # Mock dependencies + entity = Entity(identifier="1", blueprint="service") + calculation_result = CalculationResult( + entity_selector_diff=EntitySelectorDiff(passed=[entity], failed=[]), + errors=[], + misconfigurations=[], + misonfigured_entity_keys=[], + ) + mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[calculation_result]) # type: ignore + mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock() # type: ignore + mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock(return_value=[entity]) # type: ignore + + async with event_context(EventType.HTTP_REQUEST, trigger_type="machine") as event: + event.port_app_config = mock_port_app_config + + # Test execution + result = await mock_sync_raw_mixin._register_resource_raw( + mock_port_app_config.resources[0], + [{"some": "data"}], + UserAgentType.exporter, ) - mock_sync_raw_mixin._calculate_raw = AsyncMock(return_value=[calculation_result]) # type: ignore - mock_sync_raw_mixin._map_entities_compared_with_port = AsyncMock() # type: ignore - mock_sync_raw_mixin.entities_state_applier.upsert = AsyncMock(return_value=[entity]) # type: ignore - - async with event_context(EventType.RESYNC, trigger_type="machine") as event: - event.port_app_config = mock_port_app_config - - # Test execution - result = await mock_sync_raw_mixin._register_resource_raw( - mock_port_app_config.resources[0], - [{"some": "data"}], - UserAgentType.exporter, - ) - # Assertions - assert len(result.entity_selector_diff.passed) == 1 - mock_sync_raw_mixin._calculate_raw.assert_called_once() - mock_sync_raw_mixin._map_entities_compared_with_port.assert_not_called() - mock_sync_raw_mixin.entities_state_applier.upsert.assert_called_once() + # Assertions + assert len(result.entity_selector_diff.passed) == 1 + mock_sync_raw_mixin._calculate_raw.assert_called_once() + mock_sync_raw_mixin._map_entities_compared_with_port.assert_not_called() + mock_sync_raw_mixin.entities_state_applier.upsert.assert_called_once() From 2daf67b87062a041ee83748a6329a143613b16f7 Mon Sep 17 00:00:00 2001 From: yaelibarg Date: Wed, 29 Jan 2025 18:29:13 +0200 Subject: [PATCH 4/4] deleted a comment --- port_ocean/core/handlers/port_app_config/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port_ocean/core/handlers/port_app_config/models.py b/port_ocean/core/handlers/port_app_config/models.py index 7729f520c0..bb37fd0598 100644 --- a/port_ocean/core/handlers/port_app_config/models.py +++ b/port_ocean/core/handlers/port_app_config/models.py @@ -50,7 +50,7 @@ class ResourceConfig(BaseModel): port: PortResourceConfig -class PortAppConfig(BaseModel): # add here entityDeletionThreshold +class PortAppConfig(BaseModel): enable_merge_entity: bool = Field(alias="enableMergeEntity", default=True) delete_dependent_entities: bool = Field( alias="deleteDependentEntities", default=True