diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py index e9b5687461d7c524802ce28687ae950d40bcb57c..12be1b4e80cf1b09f4eac196f4b9a3dcb49a7886 100644 --- a/lib/client/gnt_instance.py +++ b/lib/client/gnt_instance.py @@ -1239,12 +1239,11 @@ def _ConvertNicDiskModifications(mods): else: action = constants.DDM_MODIFY + elif add is _MISSING and remove is _MISSING: + action = constants.DDM_MODIFY else: - if add is _MISSING and remove is _MISSING: - action = constants.DDM_MODIFY - else: - raise errors.OpPrereqError("Cannot modify and add/remove at the" - " same time", errors.ECODE_INVAL) + raise errors.OpPrereqError("Cannot modify and add/remove at the" + " same time", errors.ECODE_INVAL) assert not (constants.DDMS_VALUES_WITH_MODIFY & set(params.keys())) diff --git a/lib/http/__init__.py b/lib/http/__init__.py index 2719a38f0ff5722f80089f03ec875151f9c491ee..e7adcbfe1948c507e1cea74b2d9fc9d35a5bb593 100644 --- a/lib/http/__init__.py +++ b/lib/http/__init__.py @@ -323,6 +323,15 @@ class HttpVersionNotSupported(HttpException): code = 505 +def ParseHeaders(buf): + """Parses HTTP headers. + + @note: This is just a trivial wrapper around C{mimetools.Message} + + """ + return mimetools.Message(buf, 0) + + def SocketOperation(sock, op, arg1, timeout): """Wrapper around socket functions. @@ -998,7 +1007,7 @@ class HttpMessageReader(object): """ # Parse headers self.header_buffer.seek(0, 0) - self.msg.headers = mimetools.Message(self.header_buffer, 0) + self.msg.headers = ParseHeaders(self.header_buffer) self.peer_will_close = self._WillPeerCloseConnection() diff --git a/lib/rapi/testutils.py b/lib/rapi/testutils.py index 2de5a3c60a854b7f33459f13b541bccdfe169f7b..ccb8b632f9d886f3b1802a52c67f4f11510f8ce4 100644 --- a/lib/rapi/testutils.py +++ b/lib/rapi/testutils.py @@ -25,7 +25,6 @@ import logging import re -import mimetools import base64 import pycurl from cStringIO import StringIO @@ -135,6 +134,17 @@ def _GetPathFromUri(uri): return None +def _FormatHeaders(headers): + """Formats HTTP headers. + + @type headers: sequence of strings + @rtype: string + + """ + assert compat.all(": " in header for header in headers) + return "\n".join(headers) + + class FakeCurl: """Fake cURL object. @@ -168,11 +178,11 @@ class FakeCurl: writefn = self._opts[pycurl.WRITEFUNCTION] if pycurl.HTTPHEADER in self._opts: - baseheaders = "\n".join(self._opts[pycurl.HTTPHEADER]) + baseheaders = _FormatHeaders(self._opts[pycurl.HTTPHEADER]) else: baseheaders = "" - headers = mimetools.Message(StringIO(baseheaders), 0) + headers = http.ParseHeaders(StringIO(baseheaders)) if request_body: headers[http.HTTP_CONTENT_LENGTH] = str(len(request_body)) @@ -188,7 +198,7 @@ class FakeCurl: "%s %s" % (http.auth.HTTP_BASIC_AUTH, base64.b64encode(userpwd)) path = _GetPathFromUri(url) - (code, resp_body) = \ + (code, _, resp_body) = \ self._handler.FetchResponse(path, method, headers, request_body) self._info[pycurl.RESPONSE_CODE] = code @@ -224,7 +234,7 @@ class _RapiMock: @param request_body: Request body @type headers: mimetools.Message @param headers: Request headers - @return: Tuple containing status code and response body + @return: Tuple containing status code, response headers and response body """ req_msg = http.HttpMessage() @@ -236,7 +246,7 @@ class _RapiMock: (_, _, _, resp_msg) = \ http.server.HttpResponder(self.handler)(lambda: (req_msg, None)) - return (resp_msg.start_line.code, resp_msg.body) + return (resp_msg.start_line.code, resp_msg.headers, resp_msg.body) class _TestLuxiTransport: diff --git a/test/ganeti.client.gnt_instance_unittest.py b/test/ganeti.client.gnt_instance_unittest.py index 7cbd0de976a7845a7b970d17cbb862c7330f4540..4e65e99b57636790e1753cea7d0e025d592ff06b 100755 --- a/test/ganeti.client.gnt_instance_unittest.py +++ b/test/ganeti.client.gnt_instance_unittest.py @@ -149,6 +149,12 @@ class TestConvertNicDiskModifications(unittest.TestCase): ]), [ (action, -1, {}), ]) + self.assertRaises(errors.OpPrereqError, fn, [ + (0, { + action: True, + constants.DDM_MODIFY: True, + }), + ]) self.assertEqual(fn([ (constants.DDM_ADD, { @@ -190,6 +196,17 @@ class TestConvertNicDiskModifications(unittest.TestCase): (constants.DDM_REMOVE, -1, {}), ]) + self.assertEqual(fn([ + (-1, { + constants.DDM_MODIFY: True, + constants.IDISK_SIZE: 1024, + }), + ]), [ + (constants.DDM_MODIFY, -1, { + constants.IDISK_SIZE: 1024, + }), + ]) + class TestParseDiskSizes(unittest.TestCase): def test(self): diff --git a/test/ganeti.rapi.client_unittest.py b/test/ganeti.rapi.client_unittest.py index a87aa1cd86aed955ea6f82ee948e7b1e9ae28c84..da8409393df9af86558ef75975677c821b37221a 100755 --- a/test/ganeti.rapi.client_unittest.py +++ b/test/ganeti.rapi.client_unittest.py @@ -97,7 +97,7 @@ class RapiMock(object): (code, response) = self._responses.pop() - return code, response + return (code, NotImplemented, response) class TestConstants(unittest.TestCase): @@ -138,14 +138,20 @@ class TestConstants(unittest.TestCase): class RapiMockTest(unittest.TestCase): - def test(self): + def test404(self): + (code, _, body) = RapiMock().FetchResponse("/foo", "GET", None, None) + self.assertEqual(code, 404) + self.assertTrue(body is None) + + def test501(self): + (code, _, body) = RapiMock().FetchResponse("/version", "POST", None, None) + self.assertEqual(code, 501) + self.assertEqual(body, "Method not implemented") + + def test200(self): rapi = RapiMock() - path = "/version" - self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None, None)) - self.assertEqual((501, "Method not implemented"), - rapi.FetchResponse("/version", "POST", None, None)) rapi.AddResponse("2") - code, response = rapi.FetchResponse("/version", "GET", None, None) + (code, _, response) = rapi.FetchResponse("/version", "GET", None, None) self.assertEqual(200, code) self.assertEqual("2", response) self.failUnless(isinstance(rapi.GetLastHandler(), rlib2.R_version))