From 58d2a5d4b00b5b78ccf09b3b0326477d840bb7a0 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 9 Nov 2015 10:25:20 +0100 Subject: [PATCH] Support VPCS 0.6.1 Fix #347 --- gns3server/modules/vpcs/vpcs_vm.py | 13 +++-- tests/modules/vpcs/test_vpcs_vm.py | 89 ++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 22 deletions(-) diff --git a/gns3server/modules/vpcs/vpcs_vm.py b/gns3server/modules/vpcs/vpcs_vm.py index de68996f..8413bc5e 100644 --- a/gns3server/modules/vpcs/vpcs_vm.py +++ b/gns3server/modules/vpcs/vpcs_vm.py @@ -28,9 +28,9 @@ import re import asyncio import shutil -from gns3server.utils.asyncio import wait_for_process_termination -from gns3server.utils.asyncio import monitor_process -from gns3server.utils.asyncio import subprocess_check_output +from ...utils.asyncio import wait_for_process_termination +from ...utils.asyncio import monitor_process +from ...utils.asyncio import subprocess_check_output from pkg_resources import parse_version from .vpcs_error import VPCSError from ..adapters.ethernet_adapter import EthernetAdapter @@ -62,6 +62,7 @@ class VPCSVM(BaseVM): self._command = [] self._process = None self._vpcs_stdout_file = "" + self._vpcs_version = None self._started = False # VPCS settings @@ -203,7 +204,8 @@ class VPCSVM(BaseVM): match = re.search("Welcome to Virtual PC Simulator, version ([0-9a-z\.]+)", output) if match: version = match.group(1) - if parse_version(version) < parse_version("0.8b"): + self._vpcs_version = parse_version(version) + if self._vpcs_version < parse_version("0.8b"): raise VPCSError("VPCS executable version must be >= 0.8b") else: raise VPCSError("Could not determine the VPCS version for {}".format(self.vpcs_path)) @@ -416,7 +418,8 @@ class VPCSVM(BaseVM): command.extend(["-m", str(self._manager.get_mac_id(self.id))]) # the unique ID is used to set the MAC address offset command.extend(["-i", "1"]) # option to start only one VPC instance command.extend(["-F"]) # option to avoid the daemonization of VPCS - command.extend(["-R"]) # disable relay feature of VPCS (starting with VPCS 0.8) + if self._vpcs_version > parse_version("0.8"): + command.extend(["-R"]) # disable relay feature of VPCS (starting with VPCS 0.8) nio = self._ethernet_adapter.get_nio(0) if nio: diff --git a/tests/modules/vpcs/test_vpcs_vm.py b/tests/modules/vpcs/test_vpcs_vm.py index 15808990..86994c1b 100644 --- a/tests/modules/vpcs/test_vpcs_vm.py +++ b/tests/modules/vpcs/test_vpcs_vm.py @@ -20,10 +20,11 @@ import aiohttp import asyncio import os import sys + from tests.utils import asyncio_patch - - +from pkg_resources import parse_version from unittest.mock import patch, MagicMock + from gns3server.modules.vpcs.vpcs_vm import VPCSVM from gns3server.modules.vpcs.vpcs_error import VPCSError from gns3server.modules.vpcs import VPCS @@ -38,7 +39,9 @@ def manager(port_manager): @pytest.fixture(scope="function") def vm(project, manager): - return VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager) + vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager) + vm._vpcs_version = parse_version("0.9") + return vm def test_vm(project, manager): @@ -47,26 +50,30 @@ def test_vm(project, manager): assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f" -def test_vm_invalid_vpcs_version(loop, project, manager): - with asyncio_patch("gns3server.utils.asyncio.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.1"): +def test_vm_check_vpcs_version(loop, vm, manager): + with asyncio_patch("gns3server.modules.vpcs.vpcs_vm.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.9"): + loop.run_until_complete(asyncio.async(vm._check_vpcs_version())) + assert vm._vpcs_version == parse_version("0.9") + + +def test_vm_invalid_vpcs_version(loop, manager, vm): + with asyncio_patch("gns3server.modules.vpcs.vpcs_vm.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.1"): with pytest.raises(VPCSError): - vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager) nio = manager.create_nio(vm.vpcs_path, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"}) vm.port_add_nio_binding(0, nio) - loop.run_until_complete(asyncio.async(vm.start())) + loop.run_until_complete(asyncio.async(vm._check_vpcs_version())) assert vm.name == "test" assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f" -@patch("gns3server.config.Config.get_section_config", return_value={"vpcs_path": "/bin/test_fake"}) -def test_vm_invalid_vpcs_path(project, manager, loop): - with pytest.raises(VPCSError): - vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0e", project, manager) - nio = manager.create_nio(vm.vpcs_path, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"}) - vm.port_add_nio_binding(0, nio) - loop.run_until_complete(asyncio.async(vm.start())) - assert vm.name == "test" - assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e" +def test_vm_invalid_vpcs_path(vm, manager, loop): + with asyncio_patch("gns3server.modules.vpcs.vpcs_vm.VPCSVM.vpcs_path", return_value="/tmp/fake/path/vpcs"): + with pytest.raises(VPCSError): + nio = manager.create_nio(vm.vpcs_path, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"}) + vm.port_add_nio_binding(0, nio) + loop.run_until_complete(asyncio.async(vm.start())) + assert vm.name == "test" + assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e" def test_start(loop, vm): @@ -75,10 +82,58 @@ def test_start(loop, vm): queue = vm.project.get_listen_queue() with asyncio_patch("gns3server.modules.vpcs.vpcs_vm.VPCSVM._check_requirements", return_value=True): - with asyncio_patch("asyncio.create_subprocess_exec", return_value=process): + with asyncio_patch("asyncio.create_subprocess_exec", return_value=process) as mock_exec: nio = VPCS.instance().create_nio(vm.vpcs_path, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"}) vm.port_add_nio_binding(0, nio) loop.run_until_complete(asyncio.async(vm.start())) + assert mock_exec.call_args[0] == (vm.vpcs_path, + '-p', + str(vm.console), + '-m', '1', + '-i', + '1', + '-F', + '-R', + '-s', + '4242', + '-c', + '4243', + '-t', + '127.0.0.1') + assert vm.is_running() + (action, event) = queue.get_nowait() + assert action == "vm.started" + assert event == vm + + +def test_start_0_6_1(loop, vm): + """ + Version 0.6.1 doesn't have the -R options. It's not require + because GNS3 provide a patch for this. + """ + process = MagicMock() + process.returncode = None + queue = vm.project.get_listen_queue() + vm._vpcs_version = parse_version("0.6.1") + + with asyncio_patch("gns3server.modules.vpcs.vpcs_vm.VPCSVM._check_requirements", return_value=True): + with asyncio_patch("asyncio.create_subprocess_exec", return_value=process) as mock_exec: + nio = VPCS.instance().create_nio(vm.vpcs_path, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"}) + vm.port_add_nio_binding(0, nio) + loop.run_until_complete(asyncio.async(vm.start())) + assert mock_exec.call_args[0] == (vm.vpcs_path, + '-p', + str(vm.console), + '-m', '1', + '-i', + '1', + '-F', + '-s', + '4242', + '-c', + '4243', + '-t', + '127.0.0.1') assert vm.is_running() (action, event) = queue.get_nowait() assert action == "vm.started"