diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f5e6fece..8162897e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,7 @@ Changed Fixed ===== - Only redeploy when handling ``kytos/topology.link_up`` if a dynamic EVC isn't active +- Fixed possible EVCs duplication when constant delete requests are sent. [2023.2.0] - 2024-02-16 *********************** diff --git a/main.py b/main.py index 8e4f4adc..e30d8baa 100755 --- a/main.py +++ b/main.py @@ -142,9 +142,6 @@ def execute_consistency(self): log.info(f"{circuit} enabled but inactive - redeploy") with circuit.lock: circuit.deploy() - for circuit_id in stored_circuits: - log.info(f"EVC found in mongodb but unloaded {circuit_id}") - self._load_evc(stored_circuits[circuit_id]) def shutdown(self): """Execute when your napp is unloaded. @@ -430,24 +427,28 @@ def delete_circuit(self, request: Request) -> JSONResponse: result = f"circuit_id {circuit_id} not found" log.debug("delete_circuit result %s %s", result, 404) raise HTTPException(404, detail=result) from KeyError - log.info("Removing %s", evc) + with evc.lock: - evc.remove_current_flows() - evc.remove_failover_flows(sync=False) - evc.deactivate() - evc.disable() - self.sched.remove(evc) - evc.archive() - evc.remove_uni_tags() - evc.sync() + if not evc.archived: + evc.remove_current_flows() + evc.remove_failover_flows(sync=False) + evc.deactivate() + evc.disable() + self.sched.remove(evc) + evc.archive() + evc.remove_uni_tags() + evc.sync() + emit_event( + self.controller, "deleted", + content=map_evc_event_content(evc) + ) + log.info("EVC removed. %s", evc) result = {"response": f"Circuit {circuit_id} removed"} status = 200 - log.debug("delete_circuit result %s %s", result, status) - emit_event(self.controller, "deleted", - content=map_evc_event_content(evc)) + return JSONResponse(result, status_code=status) @rest("/v2/evc/{circuit_id}/metadata", methods=["GET"]) diff --git a/setup.py b/setup.py index b16e63a6..9d3ca8a7 100644 --- a/setup.py +++ b/setup.py @@ -98,7 +98,8 @@ class Test(TestCommand): def run(self): """Run tests.""" - cmd = f"python3 -m pytest tests/ {self.get_args()}" + cmd = "python3 -m pytest tests/ --cov-report term-missing" + cmd += f" {self.get_args()}" try: check_call(cmd, shell=True) except CalledProcessError as exc: @@ -114,7 +115,8 @@ class TestCoverage(Test): def run(self): """Run tests quietly and display coverage report.""" - cmd = f"python3 -m pytest --cov=. tests/ {self.get_args()}" + cmd = "python3 -m pytest --cov=. tests/ --cov-report term-missing" + cmd += f" {self.get_args()}" try: check_call(cmd, shell=True) except CalledProcessError as exc: diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 4a03c19b..7a8136c3 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -106,12 +106,11 @@ def test_execute(self, mock_execute_consistency, mock_log): mock_log.info.assert_not_called() @patch('napps.kytos.mef_eline.main.settings') - @patch('napps.kytos.mef_eline.main.Main._load_evc') @patch("napps.kytos.mef_eline.controllers.ELineController.upsert_evc") @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.check_list_traces") def test_execute_consistency(self, mock_check_list_traces, *args): """Test execute_consistency.""" - (mongo_controller_upsert_mock, mock_load_evc, mock_settings) = args + (mongo_controller_upsert_mock, mock_settings) = args stored_circuits = {'1': {'name': 'circuit_1'}, '2': {'name': 'circuit_2'}, @@ -148,7 +147,6 @@ def test_execute_consistency(self, mock_check_list_traces, *args): assert evc1.activate.call_count == 1 assert evc1.sync.call_count == 1 assert evc2.deploy.call_count == 1 - mock_load_evc.assert_called_with(stored_circuits['3']) @patch('napps.kytos.mef_eline.main.settings') @patch('napps.kytos.mef_eline.main.Main._load_evc') @@ -1776,8 +1774,8 @@ async def test_delete_archived_evc( sched_add_mock, evc_deploy_mock, remove_current_flows_mock, - mock_remove_tags, mock_use_uni, + mock_remove_tags, mock_tags_equal, mock_check_duplicate ): @@ -1787,7 +1785,6 @@ async def test_delete_archived_evc( mongo_controller_upsert_mock.return_value = True sched_add_mock.return_value = True evc_deploy_mock.return_value = True - remove_current_flows_mock.return_value = True mock_use_uni.return_value = True mock_tags_equal.return_value = True mock_check_duplicate.return_value = True @@ -1819,14 +1816,16 @@ async def test_delete_archived_evc( ) assert 201 == response.status_code assert len(self.napp.circuits) == 1 - current_data = response.json() circuit_id = current_data["circuit_id"] + self.napp.circuits[circuit_id].archive() + response = await self.api_client.delete( f"{self.base_endpoint}/v2/evc/{circuit_id}" ) assert 200 == response.status_code - assert mock_remove_tags.call_count == 1 + assert mock_remove_tags.call_count == 0 + assert remove_current_flows_mock.call_count == 0 assert len(self.napp.circuits) == 0 response = await self.api_client.delete(