From b46e2cf0139cea9f4866379ac11a3f1328b1cf2b Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Fri, 3 Apr 2015 13:32:07 +0200 Subject: [PATCH] Fix issues with macos X dynamips not freeing UDP port Fix #133 --- gns3server/modules/port_manager.py | 8 +++++++- gns3server/modules/project.py | 2 +- tests/modules/test_port_manager.py | 31 ++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/gns3server/modules/port_manager.py b/gns3server/modules/port_manager.py index 52d27933..8283e5e5 100644 --- a/gns3server/modules/port_manager.py +++ b/gns3server/modules/port_manager.py @@ -16,6 +16,7 @@ # along with this program. If not, see . import socket +import sys import ipaddress from aiohttp.web import HTTPConflict from gns3server.config import Config @@ -251,14 +252,19 @@ class PortManager: project.record_udp_port(port) log.debug("UDP port {} has been reserved".format(port)) - def release_udp_port(self, port, project): + def release_udp_port(self, port, project, force_remove=False): """ Release a specific UDP port number :param port: UDP port number :param project: Project instance + :param force_remove: Force port removal even on Darwnin """ + # A bug with dynamips on darwin doesn't correctly free the port we free it only when changing project + if sys.platform.startswith("darwin") and force_remove is False: + return + if port in self._used_udp_ports: self._used_udp_ports.remove(port) project.remove_udp_port(port) diff --git a/gns3server/modules/project.py b/gns3server/modules/project.py index f308fc12..6e7281eb 100644 --- a/gns3server/modules/project.py +++ b/gns3server/modules/project.py @@ -361,7 +361,7 @@ class Project: for port in self._used_tcp_ports.copy(): port_manager.release_tcp_port(port, self) for port in self._used_udp_ports.copy(): - port_manager.release_udp_port(port, self) + port_manager.release_udp_port(port, self, force_remove=True) @asyncio.coroutine def commit(self): diff --git a/tests/modules/test_port_manager.py b/tests/modules/test_port_manager.py index 2590b826..923191b4 100644 --- a/tests/modules/test_port_manager.py +++ b/tests/modules/test_port_manager.py @@ -17,12 +17,43 @@ import aiohttp import pytest +import sys +from unittest.mock import patch from gns3server.modules.port_manager import PortManager from gns3server.modules.project import Project + def test_reserve_tcp_port(): pm = PortManager() project = Project() pm.reserve_tcp_port(4242, project) with pytest.raises(aiohttp.web.HTTPConflict): pm.reserve_tcp_port(4242, project) + + +def test_reserve_udp_port(): + pm = PortManager() + project = Project() + pm.reserve_udp_port(4242, project) + with pytest.raises(aiohttp.web.HTTPConflict): + pm.reserve_udp_port(4242, project) + + +@pytest.mark.skipif(sys.platform == 'darwin', reason="not working on darwin") +def test_release_udp_port(): + pm = PortManager() + project = Project() + pm.reserve_udp_port(4242, project) + pm.release_udp_port(4242, project) + pm.reserve_udp_port(4242, project) + + +@pytest.mark.skipif(sys.platform != 'darwin', reason="requires darwin") +def test_release_darwin_udp_port(): + """Due to dynamips / darwin bug we didn't free the port""" + pm = PortManager() + project = Project() + pm.reserve_udp_port(4242, project) + pm.release_udp_port(4242, project) + with pytest.raises(aiohttp.web.HTTPConflict): + pm.reserve_udp_port(4242, project)