diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index e1fbd573..a5be84ce 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -435,7 +435,7 @@ class Compute: return "{}://{}:{}/v2/compute{}".format(self._protocol, host, self._port, path) @asyncio.coroutine - def _run_http_query(self, method, path, data=None, timeout=10, raw=False): + def _run_http_query(self, method, path, data=None, timeout=20, raw=False): with Timeout(timeout): url = self._getUrl(path) headers = {} diff --git a/gns3server/controller/node.py b/gns3server/controller/node.py index f4a0acba..8aff659c 100644 --- a/gns3server/controller/node.py +++ b/gns3server/controller/node.py @@ -387,7 +387,7 @@ class Node: Start a node """ try: - yield from self.post("/start") + yield from self.post("/start", timeout=240) except asyncio.TimeoutError: raise aiohttp.web.HTTPRequestTimeout(text="Timeout when starting {}".format(self._name)) @@ -397,7 +397,7 @@ class Node: Stop a node """ try: - yield from self.post("/stop") + yield from self.post("/stop", timeout=240) # We don't care if a node is down at this step except (aiohttp.errors.ClientOSError, aiohttp.errors.ClientHttpProcessingError, aiohttp.web.HTTPError): pass @@ -409,27 +409,33 @@ class Node: """ Suspend a node """ - yield from self.post("/suspend") + try: + yield from self.post("/suspend", timeout=240) + except asyncio.TimeoutError: + raise aiohttp.web.HTTPRequestTimeout(text="Timeout when reloading {}".format(self._name)) @asyncio.coroutine def reload(self): """ Suspend a node """ - yield from self.post("/reload") + try: + yield from self.post("/reload", timeout=240) + except asyncio.TimeoutError: + raise aiohttp.web.HTTPRequestTimeout(text="Timeout when reloading {}".format(self._name)) @asyncio.coroutine - def post(self, path, data=None): + def post(self, path, data=None, **kwargs): """ HTTP post on the node """ if data: - return (yield from self._compute.post("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path), data=data)) + return (yield from self._compute.post("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path), data=data, **kwargs)) else: - return (yield from self._compute.post("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path))) + return (yield from self._compute.post("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path), **kwargs)) @asyncio.coroutine - def put(self, path, data=None): + def put(self, path, data=None, **kwargs): """ HTTP post on the node """ @@ -438,19 +444,19 @@ class Node: else: path = "/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path) if data: - return (yield from self._compute.put(path, data=data)) + return (yield from self._compute.put(path, data=data, **kwargs)) else: - return (yield from self._compute.put(path)) + return (yield from self._compute.put(path, **kwargs)) @asyncio.coroutine - def delete(self, path=None): + def delete(self, path=None, **kwargs): """ HTTP post on the node """ if path is None: - return (yield from self._compute.delete("/projects/{}/{}/nodes/{}".format(self._project.id, self._node_type, self._id))) + return (yield from self._compute.delete("/projects/{}/{}/nodes/{}".format(self._project.id, self._node_type, self._id), **kwargs)) else: - return (yield from self._compute.delete("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path))) + return (yield from self._compute.delete("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path), **kwargs)) @asyncio.coroutine def _upload_missing_image(self, type, img): diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index 419c9d98..12a07609 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -75,7 +75,7 @@ def test_compute_httpQuery(compute, async_run): response.status = 200 async_run(compute.post("/projects", {"a": "b"})) - mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=10) + mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=20) assert compute._auth is None @@ -87,7 +87,7 @@ def test_compute_httpQueryAuth(compute, async_run): compute.user = "root" compute.password = "toor" async_run(compute.post("/projects", {"a": "b"})) - mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=compute._auth, chunked=False, timeout=10) + mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=compute._auth, chunked=False, timeout=20) assert compute._auth.login == "root" assert compute._auth.password == "toor" @@ -100,8 +100,8 @@ def test_compute_httpQueryNotConnected(compute, controller, async_run): response.status = 200 with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: async_run(compute.post("/projects", {"a": "b"})) - mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=10) - mock.assert_any_call("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=10) + mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=20) + mock.assert_any_call("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=20) assert compute._connected assert compute._capabilities["version"] == __version__ controller.notification.emit.assert_called_with("compute.updated", compute.__json__()) @@ -122,8 +122,8 @@ def test_compute_httpQueryNotConnectedGNS3vmNotRunning(compute, controller, asyn response.status = 200 with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: async_run(compute.post("/projects", {"a": "b"})) - mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=10) - mock.assert_any_call("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=10) + mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=20) + mock.assert_any_call("POST", "https://example.com:84/v2/compute/projects", data='{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=20) assert controller.gns3vm.start.called assert compute._connected @@ -139,7 +139,7 @@ def test_compute_httpQueryNotConnectedInvalidVersion(compute, async_run): with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: with pytest.raises(aiohttp.web.HTTPConflict): async_run(compute.post("/projects", {"a": "b"})) - mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=10) + mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=20) def test_compute_httpQueryNotConnectedNonGNS3Server(compute, async_run): @@ -150,7 +150,7 @@ def test_compute_httpQueryNotConnectedNonGNS3Server(compute, async_run): with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: with pytest.raises(aiohttp.web.HTTPConflict): async_run(compute.post("/projects", {"a": "b"})) - mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=10) + mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=20) def test_compute_httpQueryNotConnectedNonGNS3Server2(compute, async_run): @@ -161,7 +161,7 @@ def test_compute_httpQueryNotConnectedNonGNS3Server2(compute, async_run): with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: with pytest.raises(aiohttp.web.HTTPConflict): async_run(compute.post("/projects", {"a": "b"})) - mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=10) + mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=False, timeout=20) def test_compute_httpQueryError(compute, async_run): @@ -190,7 +190,7 @@ def test_compute_httpQuery_project(compute, async_run): project = Project(name="Test") async_run(compute.post("/projects", project)) - mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data=json.dumps(project.__json__()), headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=10) + mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data=json.dumps(project.__json__()), headers={'content-type': 'application/json'}, auth=None, chunked=False, timeout=20) def test_connectNotification(compute, async_run): @@ -390,7 +390,7 @@ def test_interfaces(project, async_run, compute): response.status = 200 with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: assert async_run(compute.interfaces()) == res - mock.assert_any_call("GET", "https://example.com:84/v2/compute/network/interfaces", auth=None, chunked=False, data=None, headers={'content-type': 'application/json'}, timeout=10) + mock.assert_any_call("GET", "https://example.com:84/v2/compute/network/interfaces", auth=None, chunked=False, data=None, headers={'content-type': 'application/json'}, timeout=20) def test_get_ip_on_same_subnet(controller, async_run): diff --git a/tests/controller/test_node.py b/tests/controller/test_node.py index 2715b366..0b16edd1 100644 --- a/tests/controller/test_node.py +++ b/tests/controller/test_node.py @@ -343,7 +343,7 @@ def test_start(node, compute, project, async_run): compute.post = AsyncioMagicMock() async_run(node.start()) - compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/start".format(node.project.id, node.id)) + compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/start".format(node.project.id, node.id), timeout=240) def test_stop(node, compute, project, async_run): @@ -351,7 +351,7 @@ def test_stop(node, compute, project, async_run): compute.post = AsyncioMagicMock() async_run(node.stop()) - compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/stop".format(node.project.id, node.id)) + compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/stop".format(node.project.id, node.id), timeout=240) def test_suspend(node, compute, project, async_run): @@ -359,7 +359,7 @@ def test_suspend(node, compute, project, async_run): compute.post = AsyncioMagicMock() async_run(node.suspend()) - compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/suspend".format(node.project.id, node.id)) + compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/suspend".format(node.project.id, node.id), timeout=240) def test_reload(node, compute, project, async_run): @@ -367,7 +367,7 @@ def test_reload(node, compute, project, async_run): compute.post = AsyncioMagicMock() async_run(node.reload()) - compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/reload".format(node.project.id, node.id)) + compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/reload".format(node.project.id, node.id), timeout=240) def test_create_without_console(node, compute, project, async_run):